chore: non mutable btree when building specs (#8969)
This commit is contained in:
parent
fceae86581
commit
e9c548c65e
1 changed files with 442 additions and 423 deletions
|
|
@ -137,70 +137,72 @@ impl From<JsonSchema> for AdditionalProperties {
|
|||
}
|
||||
|
||||
fn create_exec_command_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"cmd".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Shell command to execute.".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"workdir".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional working directory to run the command in; defaults to the turn cwd."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"shell".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Shell binary to launch. Defaults to /bin/bash.".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"login".to_string(),
|
||||
JsonSchema::Boolean {
|
||||
description: Some(
|
||||
"Whether to run the shell with -l/-i semantics. Defaults to true.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"yield_time_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"How long to wait (in milliseconds) for output before yielding.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"max_output_tokens".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Maximum number of tokens to return. Excess output will be truncated.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"sandbox_permissions".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Sandbox permissions for the command. Set to \"require_escalated\" to request running without sandbox restrictions; defaults to \"use_default\"."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"justification".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Only set if sandbox_permissions is \"require_escalated\". 1-sentence explanation of why we want to run this command."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"cmd".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Shell command to execute.".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"workdir".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional working directory to run the command in; defaults to the turn cwd."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"shell".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Shell binary to launch. Defaults to /bin/bash.".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"login".to_string(),
|
||||
JsonSchema::Boolean {
|
||||
description: Some(
|
||||
"Whether to run the shell with -l/-i semantics. Defaults to true.".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"yield_time_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"How long to wait (in milliseconds) for output before yielding.".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"max_output_tokens".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Maximum number of tokens to return. Excess output will be truncated."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"sandbox_permissions".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Sandbox permissions for the command. Set to \"require_escalated\" to request running without sandbox restrictions; defaults to \"use_default\"."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"justification".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Only set if sandbox_permissions is \"require_escalated\". 1-sentence explanation of why we want to run this command."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "exec_command".to_string(),
|
||||
|
|
@ -217,35 +219,37 @@ fn create_exec_command_tool() -> ToolSpec {
|
|||
}
|
||||
|
||||
fn create_write_stdin_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"session_id".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("Identifier of the running unified exec session.".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"chars".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Bytes to write to stdin (may be empty to poll).".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"yield_time_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"How long to wait (in milliseconds) for output before yielding.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"max_output_tokens".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Maximum number of tokens to return. Excess output will be truncated.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"session_id".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("Identifier of the running unified exec session.".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"chars".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Bytes to write to stdin (may be empty to poll).".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"yield_time_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"How long to wait (in milliseconds) for output before yielding.".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"max_output_tokens".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Maximum number of tokens to return. Excess output will be truncated."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "write_stdin".to_string(),
|
||||
|
|
@ -262,39 +266,39 @@ fn create_write_stdin_tool() -> ToolSpec {
|
|||
}
|
||||
|
||||
fn create_shell_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"command".to_string(),
|
||||
JsonSchema::Array {
|
||||
items: Box::new(JsonSchema::String { description: None }),
|
||||
description: Some("The command to execute".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"workdir".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("The working directory to execute the command in".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"timeout_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("The timeout for the command in milliseconds".to_string()),
|
||||
},
|
||||
);
|
||||
|
||||
properties.insert(
|
||||
"sandbox_permissions".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Sandbox permissions for the command. Set to \"require_escalated\" to request running without sandbox restrictions; defaults to \"use_default\".".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"justification".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Only set if sandbox_permissions is \"require_escalated\". 1-sentence explanation of why we want to run this command.".to_string()),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"command".to_string(),
|
||||
JsonSchema::Array {
|
||||
items: Box::new(JsonSchema::String { description: None }),
|
||||
description: Some("The command to execute".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"workdir".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("The working directory to execute the command in".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"timeout_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("The timeout for the command in milliseconds".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"sandbox_permissions".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Sandbox permissions for the command. Set to \"require_escalated\" to request running without sandbox restrictions; defaults to \"use_default\".".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"justification".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Only set if sandbox_permissions is \"require_escalated\". 1-sentence explanation of why we want to run this command.".to_string()),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
let description = if cfg!(windows) {
|
||||
r#"Runs a Powershell command (Windows) and returns its output. Arguments to `shell` will be passed to CreateProcessW(). Most commands should be prefixed with ["powershell.exe", "-Command"].
|
||||
|
|
@ -326,48 +330,49 @@ Examples of valid command strings:
|
|||
}
|
||||
|
||||
fn create_shell_command_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"command".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"The shell script to execute in the user's default shell".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"workdir".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("The working directory to execute the command in".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"login".to_string(),
|
||||
JsonSchema::Boolean {
|
||||
description: Some(
|
||||
"Whether to run the shell with login shell semantics. Defaults to true."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"timeout_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("The timeout for the command in milliseconds".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"sandbox_permissions".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Sandbox permissions for the command. Set to \"require_escalated\" to request running without sandbox restrictions; defaults to \"use_default\".".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"justification".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Only set if sandbox_permissions is \"require_escalated\". 1-sentence explanation of why we want to run this command.".to_string()),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"command".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"The shell script to execute in the user's default shell".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"workdir".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("The working directory to execute the command in".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"login".to_string(),
|
||||
JsonSchema::Boolean {
|
||||
description: Some(
|
||||
"Whether to run the shell with login shell semantics. Defaults to true."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"timeout_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("The timeout for the command in milliseconds".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"sandbox_permissions".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Sandbox permissions for the command. Set to \"require_escalated\" to request running without sandbox restrictions; defaults to \"use_default\".".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"justification".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Only set if sandbox_permissions is \"require_escalated\". 1-sentence explanation of why we want to run this command.".to_string()),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
let description = if cfg!(windows) {
|
||||
r#"Runs a Powershell command (Windows) and returns its output.
|
||||
|
|
@ -399,13 +404,12 @@ Examples of valid command strings:
|
|||
|
||||
fn create_view_image_tool() -> ToolSpec {
|
||||
// Support only local filesystem path.
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
let properties = BTreeMap::from([(
|
||||
"path".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Local filesystem path to an image file".to_string()),
|
||||
},
|
||||
);
|
||||
)]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "view_image".to_string(),
|
||||
|
|
@ -520,54 +524,59 @@ fn create_close_agent_tool() -> ToolSpec {
|
|||
}
|
||||
|
||||
fn create_test_sync_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"sleep_before_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("Optional delay in milliseconds before any other action".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"sleep_after_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Optional delay in milliseconds after completing the barrier".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let barrier_properties = BTreeMap::from([
|
||||
(
|
||||
"id".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Identifier shared by concurrent calls that should rendezvous".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"participants".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Number of tool calls that must arrive before the barrier opens".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"timeout_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Maximum time in milliseconds to wait at the barrier".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
let mut barrier_properties = BTreeMap::new();
|
||||
barrier_properties.insert(
|
||||
"id".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Identifier shared by concurrent calls that should rendezvous".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
barrier_properties.insert(
|
||||
"participants".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Number of tool calls that must arrive before the barrier opens".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
barrier_properties.insert(
|
||||
"timeout_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("Maximum time in milliseconds to wait at the barrier".to_string()),
|
||||
},
|
||||
);
|
||||
|
||||
properties.insert(
|
||||
"barrier".to_string(),
|
||||
JsonSchema::Object {
|
||||
properties: barrier_properties,
|
||||
required: Some(vec!["id".to_string(), "participants".to_string()]),
|
||||
additional_properties: Some(false.into()),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"sleep_before_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Optional delay in milliseconds before any other action".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"sleep_after_ms".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Optional delay in milliseconds after completing the barrier".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"barrier".to_string(),
|
||||
JsonSchema::Object {
|
||||
properties: barrier_properties,
|
||||
required: Some(vec!["id".to_string(), "participants".to_string()]),
|
||||
additional_properties: Some(false.into()),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "test_sync_tool".to_string(),
|
||||
|
|
@ -582,40 +591,41 @@ fn create_test_sync_tool() -> ToolSpec {
|
|||
}
|
||||
|
||||
fn create_grep_files_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"pattern".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Regular expression pattern to search for.".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"include".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional glob that limits which files are searched (e.g. \"*.rs\" or \
|
||||
\"*.{ts,tsx}\")."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"path".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Directory or file path to search. Defaults to the session's working directory."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"limit".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Maximum number of file paths to return (defaults to 100).".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"pattern".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Regular expression pattern to search for.".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"include".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional glob that limits which files are searched (e.g. \"*.rs\" or \
|
||||
\"*.{ts,tsx}\")."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"path".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Directory or file path to search. Defaults to the session's working directory."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"limit".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Maximum number of file paths to return (defaults to 100).".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "grep_files".to_string(),
|
||||
|
|
@ -632,88 +642,93 @@ fn create_grep_files_tool() -> ToolSpec {
|
|||
}
|
||||
|
||||
fn create_read_file_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"file_path".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Absolute path to the file".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"offset".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"The line number to start reading from. Must be 1 or greater.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"limit".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("The maximum number of lines to return.".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"mode".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional mode selector: \"slice\" for simple ranges (default) or \"indentation\" \
|
||||
to expand around an anchor line."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let indentation_properties = BTreeMap::from([
|
||||
(
|
||||
"anchor_line".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Anchor line to center the indentation lookup on (defaults to offset)."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"max_levels".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"How many parent indentation levels (smaller indents) to include.".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"include_siblings".to_string(),
|
||||
JsonSchema::Boolean {
|
||||
description: Some(
|
||||
"When true, include additional blocks that share the anchor indentation."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"include_header".to_string(),
|
||||
JsonSchema::Boolean {
|
||||
description: Some(
|
||||
"Include doc comments or attributes directly above the selected block."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"max_lines".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Hard cap on the number of lines returned when using indentation mode."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
let mut indentation_properties = BTreeMap::new();
|
||||
indentation_properties.insert(
|
||||
"anchor_line".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Anchor line to center the indentation lookup on (defaults to offset).".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
indentation_properties.insert(
|
||||
"max_levels".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"How many parent indentation levels (smaller indents) to include.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
indentation_properties.insert(
|
||||
"include_siblings".to_string(),
|
||||
JsonSchema::Boolean {
|
||||
description: Some(
|
||||
"When true, include additional blocks that share the anchor indentation."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
indentation_properties.insert(
|
||||
"include_header".to_string(),
|
||||
JsonSchema::Boolean {
|
||||
description: Some(
|
||||
"Include doc comments or attributes directly above the selected block.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
indentation_properties.insert(
|
||||
"max_lines".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"Hard cap on the number of lines returned when using indentation mode.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"indentation".to_string(),
|
||||
JsonSchema::Object {
|
||||
properties: indentation_properties,
|
||||
required: None,
|
||||
additional_properties: Some(false.into()),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"file_path".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Absolute path to the file".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"offset".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"The line number to start reading from. Must be 1 or greater.".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"limit".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("The maximum number of lines to return.".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"mode".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional mode selector: \"slice\" for simple ranges (default) or \"indentation\" \
|
||||
to expand around an anchor line."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"indentation".to_string(),
|
||||
JsonSchema::Object {
|
||||
properties: indentation_properties,
|
||||
required: None,
|
||||
additional_properties: Some(false.into()),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "read_file".to_string(),
|
||||
|
|
@ -730,35 +745,36 @@ fn create_read_file_tool() -> ToolSpec {
|
|||
}
|
||||
|
||||
fn create_list_dir_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"dir_path".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Absolute path to the directory to list.".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"offset".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"The entry number to start listing from. Must be 1 or greater.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"limit".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("The maximum number of entries to return.".to_string()),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"depth".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"The maximum directory depth to traverse. Must be 1 or greater.".to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"dir_path".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some("Absolute path to the directory to list.".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"offset".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"The entry number to start listing from. Must be 1 or greater.".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"limit".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some("The maximum number of entries to return.".to_string()),
|
||||
},
|
||||
),
|
||||
(
|
||||
"depth".to_string(),
|
||||
JsonSchema::Number {
|
||||
description: Some(
|
||||
"The maximum directory depth to traverse. Must be 1 or greater.".to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "list_dir".to_string(),
|
||||
|
|
@ -775,25 +791,26 @@ fn create_list_dir_tool() -> ToolSpec {
|
|||
}
|
||||
|
||||
fn create_list_mcp_resources_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"server".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional MCP server name. When omitted, lists resources from every configured server."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"cursor".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Opaque cursor returned by a previous list_mcp_resources call for the same server."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"server".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional MCP server name. When omitted, lists resources from every configured server."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"cursor".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Opaque cursor returned by a previous list_mcp_resources call for the same server."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "list_mcp_resources".to_string(),
|
||||
|
|
@ -808,25 +825,26 @@ fn create_list_mcp_resources_tool() -> ToolSpec {
|
|||
}
|
||||
|
||||
fn create_list_mcp_resource_templates_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"server".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional MCP server name. When omitted, lists resource templates from all configured servers."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"cursor".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Opaque cursor returned by a previous list_mcp_resource_templates call for the same server."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"server".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Optional MCP server name. When omitted, lists resource templates from all configured servers."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"cursor".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Opaque cursor returned by a previous list_mcp_resource_templates call for the same server."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "list_mcp_resource_templates".to_string(),
|
||||
|
|
@ -841,25 +859,26 @@ fn create_list_mcp_resource_templates_tool() -> ToolSpec {
|
|||
}
|
||||
|
||||
fn create_read_mcp_resource_tool() -> ToolSpec {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert(
|
||||
"server".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"MCP server name exactly as configured. Must match the 'server' field returned by list_mcp_resources."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
properties.insert(
|
||||
"uri".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Resource URI to read. Must be one of the URIs returned by list_mcp_resources."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
);
|
||||
let properties = BTreeMap::from([
|
||||
(
|
||||
"server".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"MCP server name exactly as configured. Must match the 'server' field returned by list_mcp_resources."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
(
|
||||
"uri".to_string(),
|
||||
JsonSchema::String {
|
||||
description: Some(
|
||||
"Resource URI to read. Must be one of the URIs returned by list_mcp_resources."
|
||||
.to_string(),
|
||||
),
|
||||
},
|
||||
),
|
||||
]);
|
||||
|
||||
ToolSpec::Function(ResponsesApiTool {
|
||||
name: "read_mcp_resource".to_string(),
|
||||
|
|
@ -1356,7 +1375,7 @@ mod tests {
|
|||
// Build actual map name -> spec
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashSet;
|
||||
let mut actual: BTreeMap<String, ToolSpec> = BTreeMap::new();
|
||||
let mut actual: BTreeMap<String, ToolSpec> = BTreeMap::from([]);
|
||||
let mut duplicate_names = Vec::new();
|
||||
for t in &tools {
|
||||
let name = tool_name(&t.spec).to_string();
|
||||
|
|
@ -1370,7 +1389,7 @@ mod tests {
|
|||
);
|
||||
|
||||
// Build expected from the same helpers used by the builder.
|
||||
let mut expected: BTreeMap<String, ToolSpec> = BTreeMap::new();
|
||||
let mut expected: BTreeMap<String, ToolSpec> = BTreeMap::from([]);
|
||||
for spec in [
|
||||
create_exec_command_tool(),
|
||||
create_write_stdin_tool(),
|
||||
|
|
@ -2292,8 +2311,8 @@ Examples of valid command strings:
|
|||
|
||||
#[test]
|
||||
fn chat_tools_include_top_level_name() {
|
||||
let mut properties = BTreeMap::new();
|
||||
properties.insert("foo".to_string(), JsonSchema::String { description: None });
|
||||
let properties =
|
||||
BTreeMap::from([("foo".to_string(), JsonSchema::String { description: None })]);
|
||||
let tools = vec![ToolSpec::Function(ResponsesApiTool {
|
||||
name: "demo".to_string(),
|
||||
description: "A demo tool".to_string(),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue