Skip to main content

TaskSuite

Enum TaskSuite 

Source
pub enum TaskSuite {
    Default,
    Custom {
        tasks: Vec<TuneTask>,
    },
}
Expand description

The set of tasks a tune run evaluates each candidate against.

Custom carries the exact same JSON shape whether it originates from a CLI --task-suite path.json file or a GUI file upload parsed client-side and posted as part of the run request — there is a single shared schema, not two divergent ingestion paths.

Variants§

§

Default

The built-in default suite (see assets/tune_default_suite.json).

§

Custom

A user-authored suite.

Fields

§tasks: Vec<TuneTask>

Implementations§

Source§

impl TaskSuite

Source

const DEFAULT_SUITE_JSON: &'static str = "[\n {\n \"id\": \"single_call_weather\",\n \"category\": \"single_call\",\n \"user_prompt\": \"What\'s the current weather in Boston, MA?\",\n \"tools\": [\n {\n \"name\": \"get_weather\",\n \"description\": \"Get the current weather for a location.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"location\": {\n \"type\": \"string\",\n \"description\": \"City and state, e.g. \'Boston, MA\'\"\n }\n },\n \"required\": [\"location\"]\n }\n }\n ],\n \"expected\": {\n \"kind\": \"tool_calls\",\n \"calls\": [\n {\n \"name\": \"get_weather\",\n \"required_args\": { \"location\": \"Boston, MA\" },\n \"ordered\": false\n }\n ]\n }\n },\n {\n \"id\": \"single_call_read_file\",\n \"category\": \"single_call\",\n \"user_prompt\": \"What does the file named config.json contain?\",\n \"tools\": [\n {\n \"name\": \"read_file\",\n \"description\": \"Read the full contents of a file by path.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"path\": { \"type\": \"string\" }\n },\n \"required\": [\"path\"]\n }\n }\n ],\n \"expected\": {\n \"kind\": \"tool_calls\",\n \"calls\": [\n {\n \"name\": \"read_file\",\n \"required_args\": { \"path\": \"config.json\" },\n \"ordered\": false\n }\n ]\n }\n },\n {\n \"id\": \"parallel_call_two_cities\",\n \"category\": \"parallel_call\",\n \"user_prompt\": \"What\'s the weather like in both Boston and Austin right now?\",\n \"tools\": [\n {\n \"name\": \"get_weather\",\n \"description\": \"Get the current weather for a location.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"location\": { \"type\": \"string\" }\n },\n \"required\": [\"location\"]\n }\n }\n ],\n \"expected\": {\n \"kind\": \"tool_calls\",\n \"calls\": [\n {\n \"name\": \"get_weather\",\n \"required_args\": { \"location\": \"Boston\" },\n \"ordered\": false\n },\n {\n \"name\": \"get_weather\",\n \"required_args\": { \"location\": \"Austin\" },\n \"ordered\": false\n }\n ]\n }\n },\n {\n \"id\": \"multi_turn_search_then_read\",\n \"category\": \"multi_turn\",\n \"user_prompt\": \"Find the file that defines the `AgentLoop` struct, then show me its contents.\",\n \"tools\": [\n {\n \"name\": \"search_files\",\n \"description\": \"Search the workspace for files matching a query.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"query\": { \"type\": \"string\" }\n },\n \"required\": [\"query\"]\n }\n },\n {\n \"name\": \"read_file\",\n \"description\": \"Read the full contents of a file by path.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"path\": { \"type\": \"string\" }\n },\n \"required\": [\"path\"]\n }\n }\n ],\n \"expected\": {\n \"kind\": \"tool_calls\",\n \"calls\": [\n {\n \"name\": \"search_files\",\n \"required_args\": {},\n \"ordered\": true\n },\n {\n \"name\": \"read_file\",\n \"required_args\": {},\n \"ordered\": true\n }\n ]\n }\n },\n {\n \"id\": \"irrelevance_general_knowledge\",\n \"category\": \"irrelevance\",\n \"user_prompt\": \"What is the capital of France?\",\n \"tools\": [\n {\n \"name\": \"get_weather\",\n \"description\": \"Get the current weather for a location.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"location\": { \"type\": \"string\" }\n },\n \"required\": [\"location\"]\n }\n },\n {\n \"name\": \"read_file\",\n \"description\": \"Read the full contents of a file by path.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"path\": { \"type\": \"string\" }\n },\n \"required\": [\"path\"]\n }\n }\n ],\n \"expected\": { \"kind\": \"no_tool_call\" }\n },\n {\n \"id\": \"irrelevance_no_matching_tool\",\n \"category\": \"irrelevance\",\n \"user_prompt\": \"Please send an email to my manager summarizing today\'s standup.\",\n \"tools\": [\n {\n \"name\": \"get_weather\",\n \"description\": \"Get the current weather for a location.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"location\": { \"type\": \"string\" }\n },\n \"required\": [\"location\"]\n }\n }\n ],\n \"expected\": { \"kind\": \"no_tool_call\" }\n },\n {\n \"id\": \"single_call_ambiguous_but_clear\",\n \"category\": \"single_call\",\n \"system_prompt\": \"You are a helpful coding assistant with access to filesystem tools.\",\n \"user_prompt\": \"Check whether the file named README.md exists in the current directory.\",\n \"tools\": [\n {\n \"name\": \"file_exists\",\n \"description\": \"Check whether a file exists at the given path.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"path\": { \"type\": \"string\" }\n },\n \"required\": [\"path\"]\n }\n }\n ],\n \"expected\": {\n \"kind\": \"tool_calls\",\n \"calls\": [\n {\n \"name\": \"file_exists\",\n \"required_args\": { \"path\": \"README.md\" },\n \"ordered\": false\n }\n ]\n }\n },\n {\n \"id\": \"parallel_call_multi_file_read\",\n \"category\": \"parallel_call\",\n \"user_prompt\": \"Show me the contents of both package.json and Cargo.toml.\",\n \"tools\": [\n {\n \"name\": \"read_file\",\n \"description\": \"Read the full contents of a file by path.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"path\": { \"type\": \"string\" }\n },\n \"required\": [\"path\"]\n }\n }\n ],\n \"expected\": {\n \"kind\": \"tool_calls\",\n \"calls\": [\n {\n \"name\": \"read_file\",\n \"required_args\": { \"path\": \"package.json\" },\n \"ordered\": false\n },\n {\n \"name\": \"read_file\",\n \"required_args\": { \"path\": \"Cargo.toml\" },\n \"ordered\": false\n }\n ]\n }\n },\n {\n \"id\": \"long_context_refactor_endurance\",\n \"category\": \"long_context\",\n \"system_prompt\": \"You are a helpful coding assistant with access to filesystem tools. Work efficiently and avoid repeating actions you have already completed.\",\n \"history\": [\n {\n \"role\": \"user\",\n \"content\": \"I\'m refactoring the `UserService` class to split it into `UserRepository` and `UserValidator`. Here\'s the current file:\\n\\n```python\\nclass UserService:\\n def __init__(self, db_connection):\\n self.db = db_connection\\n\\n def validate_email(self, email):\\n if \\\"@\\\" not in email:\\n raise ValueError(\\\"invalid email\\\")\\n local, _, domain = email.partition(\\\"@\\\")\\n if not local or \\\".\\\" not in domain:\\n raise ValueError(\\\"invalid email domain\\\")\\n return True\\n\\n def validate_password(self, password):\\n if len(password) < 8:\\n raise ValueError(\\\"password too short\\\")\\n if not any(c.isdigit() for c in password):\\n raise ValueError(\\\"password needs a digit\\\")\\n return True\\n\\n def get_user_by_id(self, user_id):\\n return self.db.execute(\\\"SELECT * FROM users WHERE id = ?\\\", (user_id,)).fetchone()\\n\\n def get_user_by_email(self, email):\\n return self.db.execute(\\\"SELECT * FROM users WHERE email = ?\\\", (email,)).fetchone()\\n\\n def create_user(self, email, password):\\n self.validate_email(email)\\n self.validate_password(password)\\n self.db.execute(\\\"INSERT INTO users (email, password) VALUES (?, ?)\\\", (email, password))\\n self.db.commit()\\n```\\n\\nLet\'s start by extracting the validation logic.\"\n },\n {\n \"role\": \"assistant\",\n \"tool_calls\": [\n { \"id\": \"call_1\", \"name\": \"read_file\", \"arguments\": { \"path\": \"user_service.py\" } }\n ]\n },\n {\n \"role\": \"tool\",\n \"tool_call_id\": \"call_1\",\n \"content\": \"class UserService:\\n def __init__(self, db_connection):\\n self.db = db_connection\\n # ... (full contents already shown above)\"\n },\n {\n \"role\": \"assistant\",\n \"content\": \"I\'ve reviewed the file. I\'ll extract `validate_email` and `validate_password` into a new `UserValidator` class.\"\n },\n {\n \"role\": \"assistant\",\n \"tool_calls\": [\n {\n \"id\": \"call_2\",\n \"name\": \"edit_file\",\n \"arguments\": {\n \"path\": \"user_validator.py\",\n \"content\": \"class UserValidator:\\n @staticmethod\\n def validate_email(email):\\n if \\\"@\\\" not in email:\\n raise ValueError(\\\"invalid email\\\")\\n local, _, domain = email.partition(\\\"@\\\")\\n if not local or \\\".\\\" not in domain:\\n raise ValueError(\\\"invalid email domain\\\")\\n return True\\n\\n @staticmethod\\n def validate_password(password):\\n if len(password) < 8:\\n raise ValueError(\\\"password too short\\\")\\n if not any(c.isdigit() for c in password):\\n raise ValueError(\\\"password needs a digit\\\")\\n return True\\n\"\n }\n }\n ]\n },\n {\n \"role\": \"tool\",\n \"tool_call_id\": \"call_2\",\n \"content\": \"File user_validator.py created successfully.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Great, now let\'s also extract the database access logic into `UserRepository`.\"\n },\n {\n \"role\": \"assistant\",\n \"tool_calls\": [\n {\n \"id\": \"call_3\",\n \"name\": \"edit_file\",\n \"arguments\": {\n \"path\": \"user_repository.py\",\n \"content\": \"class UserRepository:\\n def __init__(self, db_connection):\\n self.db = db_connection\\n\\n def get_user_by_id(self, user_id):\\n return self.db.execute(\\\"SELECT * FROM users WHERE id = ?\\\", (user_id,)).fetchone()\\n\\n def get_user_by_email(self, email):\\n return self.db.execute(\\\"SELECT * FROM users WHERE email = ?\\\", (email,)).fetchone()\\n\\n def insert_user(self, email, password):\\n self.db.execute(\\\"INSERT INTO users (email, password) VALUES (?, ?)\\\", (email, password))\\n self.db.commit()\\n\"\n }\n }\n ]\n },\n {\n \"role\": \"tool\",\n \"tool_call_id\": \"call_3\",\n \"content\": \"File user_repository.py created successfully.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Now simplify `UserService` to delegate to both new classes instead of duplicating their logic.\"\n },\n {\n \"role\": \"assistant\",\n \"tool_calls\": [\n {\n \"id\": \"call_4\",\n \"name\": \"edit_file\",\n \"arguments\": {\n \"path\": \"user_service.py\",\n \"content\": \"class UserService:\\n def __init__(self, db_connection):\\n self.repository = UserRepository(db_connection)\\n self.validator = UserValidator()\\n\\n def create_user(self, email, password):\\n self.validator.validate_email(email)\\n self.validator.validate_password(password)\\n self.repository.insert_user(email, password)\\n\"\n }\n }\n ]\n },\n {\n \"role\": \"tool\",\n \"tool_call_id\": \"call_4\",\n \"content\": \"File user_service.py updated successfully.\"\n },\n {\n \"role\": \"assistant\",\n \"content\": \"Done \u{2014} `UserRepository` now owns all database access, `UserValidator` owns validation, and `UserService` delegates to both. Let me know what\'s next.\"\n }\n ],\n \"user_prompt\": \"Now check whether there\'s an existing test file for `UserService` so we can update it to match the new structure.\",\n \"tools\": [\n {\n \"name\": \"read_file\",\n \"description\": \"Read the full contents of a file by path.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"path\": { \"type\": \"string\" }\n },\n \"required\": [\"path\"]\n }\n },\n {\n \"name\": \"edit_file\",\n \"description\": \"Create or overwrite a file with the given content.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"path\": { \"type\": \"string\" },\n \"content\": { \"type\": \"string\" }\n },\n \"required\": [\"path\", \"content\"]\n }\n },\n {\n \"name\": \"file_exists\",\n \"description\": \"Check whether a file exists at the given path.\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"path\": { \"type\": \"string\" }\n },\n \"required\": [\"path\"]\n }\n }\n ],\n \"expected\": {\n \"kind\": \"tool_calls\",\n \"calls\": [\n {\n \"name\": \"file_exists\",\n \"required_args\": { \"path\": \"test_user_service.py\" },\n \"ordered\": false\n }\n ]\n }\n }\n]\n"

Embedded JSON for the built-in default suite (BFCL-style: single-call, parallel-call, multi-turn, and irrelevance-detection scenarios, plus a long-context endurance scenario).

Source

pub fn resolve(&self) -> Result<Vec<TuneTask>, Error>

Resolve this suite into its concrete list of tasks.

§Errors

Returns an error only for TaskSuite::Default, and only if the embedded JSON asset is malformed — that would indicate a build-time bug in gglib itself, never a user input error. TaskSuite::Custom never errors here (its tasks were already deserialized when the TaskSuite value itself was parsed).

Trait Implementations§

Source§

impl Clone for TaskSuite

Source§

fn clone(&self) -> TaskSuite

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TaskSuite

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for TaskSuite

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for TaskSuite

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,