diff --git a/crates/goose-cli/src/commands/web.rs b/crates/goose-cli/src/commands/web.rs index f11e688c1c8f..7ab0be7516f0 100644 --- a/crates/goose-cli/src/commands/web.rs +++ b/crates/goose-cli/src/commands/web.rs @@ -567,28 +567,6 @@ async fn process_message_streaming( )) .await; } - MessageContent::ContextLengthExceeded(msg) => { - let mut sender = sender.lock().await; - let _ = sender - .send(Message::Text( - serde_json::to_string( - &WebSocketMessage::ContextExceeded { - message: msg.msg.clone(), - }, - ) - .unwrap() - .into(), - )) - .await; - - let (summarized_messages, _, _) = - agent.summarize_context(messages.messages()).await?; - SessionManager::replace_conversation( - &session_id, - &summarized_messages, - ) - .await?; - } _ => {} } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/anthropic/context_length_exceeded.json b/crates/goose-cli/src/scenario_tests/recordings/anthropic/context_length_exceeded.json index 9e26dfeeb6e6..abc04fb9085e 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/anthropic/context_length_exceeded.json +++ b/crates/goose-cli/src/scenario_tests/recordings/anthropic/context_length_exceeded.json @@ -1 +1,286 @@ -{} \ No newline at end of file +{ + "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945": { + "input": { + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:59:27.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "messages": [], + "tools": [ + { + "name": "weather_extension__get_weather", + "description": "Get the weather for a location", + "inputSchema": { + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "type": "string" + } + }, + "required": [ + "location" + ], + "type": "object" + } + }, + { + "name": "platform__search_available_extensions", + "description": "Searches for additional extensions available to help complete tasks.\n Use this tool when you're unable to find a specific feature or functionality you need to complete your task, or when standard approaches aren't working.\n These extensions might provide the exact tools needed to solve your problem.\n If you find a relevant one, consider using your tools to enable it.", + "inputSchema": { + "properties": {}, + "required": [], + "type": "object" + }, + "annotations": { + "title": "Discover extensions", + "readOnlyHint": true, + "destructiveHint": false, + "idempotentHint": false, + "openWorldHint": false + } + }, + { + "name": "platform__manage_extensions", + "description": "Tool to manage extensions and tools in goose context.\n Enable or disable extensions to help complete tasks.\n Enable or disable an extension by providing the extension name.\n ", + "inputSchema": { + "properties": { + "action": { + "description": "The action to perform", + "enum": [ + "enable", + "disable" + ], + "type": "string" + }, + "extension_name": { + "description": "The name of the extension to enable", + "type": "string" + } + }, + "required": [ + "action", + "extension_name" + ], + "type": "object" + }, + "annotations": { + "title": "Enable or disable an extension", + "readOnlyHint": false, + "destructiveHint": false, + "idempotentHint": false, + "openWorldHint": false + } + }, + { + "name": "platform__manage_schedule", + "description": "Manage scheduled recipe execution for this goose instance.\n\nActions:\n- \"list\": List all scheduled jobs\n- \"create\": Create a new scheduled job from a recipe file\n- \"run_now\": Execute a scheduled job immediately \n- \"pause\": Pause a scheduled job\n- \"unpause\": Resume a paused job\n- \"delete\": Remove a scheduled job\n- \"kill\": Terminate a currently running job\n- \"inspect\": Get details about a running job\n- \"sessions\": List execution history for a job\n- \"session_content\": Get the full content (messages) of a specific session\n", + "inputSchema": { + "properties": { + "action": { + "enum": [ + "list", + "create", + "run_now", + "pause", + "unpause", + "delete", + "kill", + "inspect", + "sessions", + "session_content" + ], + "type": "string" + }, + "cron_expression": { + "description": "A cron expression for create action. Supports both 5-field (minute hour day month weekday) and 6-field (second minute hour day month weekday) formats. 5-field expressions are automatically converted to 6-field by prepending '0' for seconds.", + "type": "string" + }, + "execution_mode": { + "default": "background", + "description": "Execution mode for create action: 'foreground' or 'background'", + "enum": [ + "foreground", + "background" + ], + "type": "string" + }, + "job_id": { + "description": "Job identifier for operations on existing jobs", + "type": "string" + }, + "limit": { + "default": 50, + "description": "Limit for sessions list", + "type": "integer" + }, + "recipe_path": { + "description": "Path to recipe file for create action", + "type": "string" + }, + "session_id": { + "description": "Session identifier for session_content action", + "type": "string" + } + }, + "required": [ + "action" + ], + "type": "object" + }, + "annotations": { + "title": "Manage scheduled recipes", + "readOnlyHint": false, + "destructiveHint": true, + "idempotentHint": false, + "openWorldHint": false + } + }, + { + "name": "dynamic_task__create_task", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", + "inputSchema": { + "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, + "task_parameters": { + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", + "items": { + "properties": { + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { + "type": "string" + } + }, + "type": "object" + }, + "minItems": 1, + "type": "array" + } + }, + "required": [ + "task_parameters" + ], + "type": "object" + }, + "annotations": { + "title": "Create Dynamic Tasks", + "readOnlyHint": false, + "destructiveHint": false, + "idempotentHint": false, + "openWorldHint": true + } + }, + { + "name": "subagent__execute_task", + "description": "Only use the subagent__execute_task tool when you execute sub recipe task or dynamic task.\n EXECUTION STRATEGY DECISION:\n 1. If the tasks are created with execution_mode, use the execution_mode.\n 2. Execute tasks sequentially unless user explicitly requests parallel execution. PARALLEL: User uses keywords like 'parallel', 'simultaneously', 'at the same time', 'concurrently'\n\n IMPLEMENTATION:\n - Sequential execution: Call this tool multiple times, passing exactly ONE task per call\n - Parallel execution: Call this tool once, passing an ARRAY of all tasks\n\n EXAMPLES:\n User Intent Based:\n - User: 'get weather and tell me a joke' → Sequential (2 separate tool calls, 1 task each)\n - User: 'get weather and joke in parallel' → Parallel (1 tool call with array of 2 tasks)\n - User: 'run these simultaneously' → Parallel (1 tool call with task array)\n - User: 'do task A then task B' → Sequential (2 separate tool calls)", + "inputSchema": { + "properties": { + "execution_mode": { + "default": "sequential", + "description": "Execution strategy for multiple tasks. Use 'sequential' (default) unless user explicitly requests parallel execution with words like 'parallel', 'simultaneously', 'at the same time', or 'concurrently'.", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, + "task_ids": { + "items": { + "description": "Unique identifier for the task", + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "task_ids" + ], + "type": "object" + }, + "annotations": { + "title": "Run tasks in parallel", + "readOnlyHint": false, + "destructiveHint": true, + "idempotentHint": false, + "openWorldHint": true + } + } + ] + }, + "output": { + "message": { + "id": null, + "role": "assistant", + "created": 1760565573, + "content": [ + { + "type": "text", + "text": "I understand. How can I help you today?" + } + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } + }, + "usage": { + "model": "claude-sonnet-4-20250514", + "usage": { + "input_tokens": 2702, + "output_tokens": 13, + "total_tokens": 2715 + } + } + } + } +} \ No newline at end of file diff --git a/crates/goose-cli/src/scenario_tests/recordings/anthropic/image_analysis.json b/crates/goose-cli/src/scenario_tests/recordings/anthropic/image_analysis.json index 86c86709ad12..0184429be104 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/anthropic/image_analysis.json +++ b/crates/goose-cli/src/scenario_tests/recordings/anthropic/image_analysis.json @@ -1,12 +1,12 @@ { "c848f22f273e158c32435d3e72cc999c046dc1a9afdc3efda68ff451f833a185": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:04:16.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:45.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704256, + "created": 1760565465, "content": [ { "type": "text", @@ -17,7 +17,11 @@ "data": "/9j/4Q/+RXhpZgAATU0AKgAAAAgABgESAAMAAAABAAEAAAEaAAUAAAABAAAAVgEbAAUAAAABAAAAXgEoAAMAAAABAAIAAAITAAMAAAABAAEAAIdpAAQAAAABAAAAZgAAAAAAAABIAAAAAQAAAEgAAAABAAeQAAAHAAAABDAyMjGRAQAHAAAABAECAwCgAAAHAAAABDAxMDCgAQADAAAAAQABAACgAgAEAAAAAQAAAgCgAwAEAAAAAQAAAgCkBgADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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", "mimeType": "image/jpeg" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -151,326 +155,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", - "inputSchema": { - "properties": { - "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", - "items": { - "properties": { - "text_instruction": { - "description": "The text instruction to execute", - "type": "string" - } - }, - "required": [ - "text_instruction" - ], - "type": "object" - }, - "type": "array" - } - }, - "type": "object" - }, - "annotations": { - "title": "Dynamic Task Creation", - "readOnlyHint": false, - "destructiveHint": true, - "idempotentHint": false, - "openWorldHint": true - } - }, - { - "name": "subagent__execute_task", - "description": "Only use the subagent__execute_task tool when you execute sub recipe task or dynamic task.\n EXECUTION STRATEGY DECISION:\n 1. If the tasks are created with execution_mode, use the execution_mode.\n 2. Execute tasks sequentially unless user explicitly requests parallel execution. PARALLEL: User uses keywords like 'parallel', 'simultaneously', 'at the same time', 'concurrently'\n\n IMPLEMENTATION:\n - Sequential execution: Call this tool multiple times, passing exactly ONE task per call\n - Parallel execution: Call this tool once, passing an ARRAY of all tasks\n\n EXAMPLES:\n User Intent Based:\n - User: 'get weather and tell me a joke' → Sequential (2 separate tool calls, 1 task each)\n - User: 'get weather and joke in parallel' → Parallel (1 tool call with array of 2 tasks)\n - User: 'run these simultaneously' → Parallel (1 tool call with task array)\n - User: 'do task A then task B' → Sequential (2 separate tool calls)", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { "execution_mode": { - "default": "sequential", - "description": "Execution strategy for multiple tasks. Use 'sequential' (default) unless user explicitly requests parallel execution with words like 'parallel', 'simultaneously', 'at the same time', or 'concurrently'.", + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", "enum": [ "sequential", "parallel" ], "type": "string" }, - "task_ids": { - "items": { - "description": "Unique identifier for the task", - "type": "string" - }, - "type": "array" - } - }, - "required": [ - "task_ids" - ], - "type": "object" - }, - "annotations": { - "title": "Run tasks in parallel", - "readOnlyHint": false, - "destructiveHint": true, - "idempotentHint": false, - "openWorldHint": true - } - } - ] - }, - "output": { - "message": { - "id": null, - "role": "assistant", - "created": 1753704259, - "content": [ - { - "type": "text", - "text": "I apologize, but I don't see any image shared in our conversation. If you'd like me to analyze an image, you'll need to share it first. However, I notice that I don't currently have access to any image analysis tools in my available extensions. Let me search to see if there are any image-related extensions available." - }, - { - "type": "toolRequest", - "id": "toolu_014qhEwCaj8QWwz1s8xtMH7h", - "toolCall": { - "status": "success", - "value": { - "name": "platform__search_available_extensions", - "arguments": {} - } - } - } - ] - }, - "usage": { - "model": "claude-sonnet-4-20250514", - "usage": { - "input_tokens": 2560, - "output_tokens": 111, - "total_tokens": 2671 - } - } - } - }, - "78cc474ff2d51b9a24df8c35e5c75f256dafb67ff5489af30fcec95cd87790b8": { - "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:04:16.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", - "messages": [ - { - "id": null, - "role": "user", - "created": 1753704256, - "content": [ - { - "type": "text", - "text": "What do you see in this image?" - }, - { - "type": "image", - "data": "/9j/4Q/+RXhpZgAATU0AKgAAAAgABgESAAMAAAABAAEAAAEaAAUAAAABAAAAVgEbAAUAAAABAAAAXgEoAAMAAAABAAIAAAITAAMAAAABAAEAAIdpAAQAAAABAAAAZgAAAAAAAABIAAAAAQAAAEgAAAABAAeQAAAHAAAABDAyMjGRAQAHAAAABAECAwCgAAAHAAAABDAxMDCgAQADAAAAAQABAACgAgAEAAAAAQAAAgCgAwAEAAAAAQAAAgCkBgADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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", - "mimeType": "image/jpeg" - } - ] - }, - { - "id": null, - "role": "assistant", - "created": 1753704259, - "content": [ - { - "type": "text", - "text": "I apologize, but I don't see any image shared in our conversation. If you'd like me to analyze an image, you'll need to share it first. However, I notice that I don't currently have access to any image analysis tools in my available extensions. Let me search to see if there are any image-related extensions available." - }, - { - "type": "toolRequest", - "id": "toolu_014qhEwCaj8QWwz1s8xtMH7h", - "toolCall": { - "status": "success", - "value": { - "name": "platform__search_available_extensions", - "arguments": {} - } - } - } - ] - }, - { - "id": null, - "role": "user", - "created": 1753704259, - "content": [ - { - "type": "toolResponse", - "id": "toolu_014qhEwCaj8QWwz1s8xtMH7h", - "toolResult": { - "status": "success", - "value": [ - { - "type": "text", - "text": "Extensions available to enable:\n- Codesearch - Query https://codesearch.sqprod.co/ directly from goose\n- google_drive - google_drive\n- Image Generator - Generate images with OpenAI models\n- Linear - Integration to Linear project management tool\n- fetch - Web content fetching and processing capabilities\n- pdfreader - Read and understand large or complex PDFs\n- Data Discovery - Explore data assets, metadata, ownership and lineage\n- gosling - Gosling\n- memory - Memory\n- Web Search - Query the WWW\n- computercontroller - Computer Controller\n- Figma - Interact with Figma and Figjam files\n- Airtable - Interact with Airtable bases and tables\n- Notebook - Control Jupyter notebooks in real time\n- Databricks - Integration to query Databricks data\n- Glean - Search and read internal documents with Glean\n- jetbrains - Jetbrains\n- Regulator - Interact with Regulator\n- blockcell - Deploy static websites to the Blockcell hosting service\n- Blockdata - Querying and analyzing Block data\n- Looker - Explore and talk to data with Looker\n- Snowflake - Integration to query Snowflake data\n- tutorial - Tutorial\n- git - Git version control system integration\n- Gmail - Gmail integration for email management and access\n- QAI Index Search - Search QAI's index directly from goose\n- Google Drive - Google Drive integration for file management and access\n- googlecalendar - Interact with Google Calendar events\n\n\n\nExtensions available to disable:\n- weather_extension\n" - } - ] - } - } - ] - } - ], - "tools": [ - { - "name": "weather_extension__get_weather", - "description": "Get the weather for a location", - "inputSchema": { - "properties": { - "location": { - "description": "The city and state, e.g. San Francisco, CA", - "type": "string" - } - }, - "required": [ - "location" - ], - "type": "object" - } - }, - { - "name": "platform__search_available_extensions", - "description": "Searches for additional extensions available to help complete tasks.\n Use this tool when you're unable to find a specific feature or functionality you need to complete your task, or when standard approaches aren't working.\n These extensions might provide the exact tools needed to solve your problem.\n If you find a relevant one, consider using your tools to enable it.", - "inputSchema": { - "properties": {}, - "required": [], - "type": "object" - }, - "annotations": { - "title": "Discover extensions", - "readOnlyHint": true, - "destructiveHint": false, - "idempotentHint": false, - "openWorldHint": false - } - }, - { - "name": "platform__manage_extensions", - "description": "Tool to manage extensions and tools in goose context.\n Enable or disable extensions to help complete tasks.\n Enable or disable an extension by providing the extension name.\n ", - "inputSchema": { - "properties": { - "action": { - "description": "The action to perform", - "enum": [ - "enable", - "disable" - ], - "type": "string" - }, - "extension_name": { - "description": "The name of the extension to enable", - "type": "string" - } - }, - "required": [ - "action", - "extension_name" - ], - "type": "object" - }, - "annotations": { - "title": "Enable or disable an extension", - "readOnlyHint": false, - "destructiveHint": false, - "idempotentHint": false, - "openWorldHint": false - } - }, - { - "name": "platform__manage_schedule", - "description": "Manage scheduled recipe execution for this goose instance.\n\nActions:\n- \"list\": List all scheduled jobs\n- \"create\": Create a new scheduled job from a recipe file\n- \"run_now\": Execute a scheduled job immediately \n- \"pause\": Pause a scheduled job\n- \"unpause\": Resume a paused job\n- \"delete\": Remove a scheduled job\n- \"kill\": Terminate a currently running job\n- \"inspect\": Get details about a running job\n- \"sessions\": List execution history for a job\n- \"session_content\": Get the full content (messages) of a specific session\n", - "inputSchema": { - "properties": { - "action": { - "enum": [ - "list", - "create", - "run_now", - "pause", - "unpause", - "delete", - "kill", - "inspect", - "sessions", - "session_content" - ], - "type": "string" - }, - "cron_expression": { - "description": "A cron expression for create action. Supports both 5-field (minute hour day month weekday) and 6-field (second minute hour day month weekday) formats. 5-field expressions are automatically converted to 6-field by prepending '0' for seconds.", - "type": "string" - }, - "execution_mode": { - "default": "background", - "description": "Execution mode for create action: 'foreground' or 'background'", - "enum": [ - "foreground", - "background" - ], - "type": "string" - }, - "job_id": { - "description": "Job identifier for operations on existing jobs", - "type": "string" - }, - "limit": { - "default": 50, - "description": "Limit for sessions list", - "type": "integer" - }, - "recipe_path": { - "description": "Path to recipe file for create action", - "type": "string" - }, - "session_id": { - "description": "Session identifier for session_content action", - "type": "string" - } - }, - "required": [ - "action" - ], - "type": "object" - }, - "annotations": { - "title": "Manage scheduled recipes", - "readOnlyHint": false, - "destructiveHint": true, - "idempotentHint": false, - "openWorldHint": false - } - }, - { - "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", - "inputSchema": { - "properties": { "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -516,20 +282,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704262, + "created": 1760565468, "content": [ { "type": "text", - "text": "It looks like there isn't currently an image analysis extension available. If you'd like to share an image, you'll need to share it in a way that I can access it, and we may need to enable an appropriate extension for image analysis. For now, I can help you with other tasks using the currently available tools and extensions. Is there something specific you'd like assistance with?" + "text": "I don't see any image in our conversation. It appears you may have intended to share an image, but it wasn't included in your message.\n\nCould you please try uploading the image again? Once you share it, I'll be happy to describe what I see in it." } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "claude-sonnet-4-20250514", "usage": { - "input_tokens": 3053, - "output_tokens": 82, - "total_tokens": 3135 + "input_tokens": 2708, + "output_tokens": 61, + "total_tokens": 2769 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/anthropic/weather_tool.json b/crates/goose-cli/src/scenario_tests/recordings/anthropic/weather_tool.json index d1d8b05f4d6c..728831c77291 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/anthropic/weather_tool.json +++ b/crates/goose-cli/src/scenario_tests/recordings/anthropic/weather_tool.json @@ -1,18 +1,22 @@ { "1bc400a528c54b25f4f1f609481e98e44222b3deaf7eee2c9e640e6345c73861": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:04:16.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:45.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704256, + "created": 1760565465, "content": [ { "type": "text", "text": "tell me what the weather is in Berlin, Germany" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -146,32 +150,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -217,15 +277,15 @@ "message": { "id": null, "role": "assistant", - "created": 1753704259, + "created": 1760565468, "content": [ { "type": "text", - "text": "I'll help you check the weather in Berlin, Germany using the weather extension." + "text": "I'll check the current weather in Berlin, Germany for you." }, { "type": "toolRequest", - "id": "toolu_01ABW2NhcBGvKL6nBj3T3fhv", + "id": "toolu_013JNt4Fn6i4Ls8HTbn8bQjG", "toolCall": { "status": "success", "value": { @@ -236,45 +296,53 @@ } } } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "claude-sonnet-4-20250514", "usage": { - "input_tokens": 2562, - "output_tokens": 76, - "total_tokens": 2638 + "input_tokens": 2710, + "output_tokens": 73, + "total_tokens": 2783 } } } }, - "d51c15f1ede58b5496bba746a4bdffd8ce84526749ce0021969d6ed6f2538a6d": { + "c6f73996d107f0ca731493c3e18108043693c0e63d377190c9359c599a7ef254": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:04:16.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:45.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704256, + "created": 1760565465, "content": [ { "type": "text", "text": "tell me what the weather is in Berlin, Germany" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, { "id": null, "role": "assistant", - "created": 1753704259, + "created": 1760565468, "content": [ { "type": "text", - "text": "I'll help you check the weather in Berlin, Germany using the weather extension." + "text": "I'll check the current weather in Berlin, Germany for you." }, { "type": "toolRequest", - "id": "toolu_01ABW2NhcBGvKL6nBj3T3fhv", + "id": "toolu_013JNt4Fn6i4Ls8HTbn8bQjG", "toolCall": { "status": "success", "value": { @@ -285,16 +353,20 @@ } } } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, { - "id": null, + "id": "msg_17216282-dde0-4344-a137-1e89c85623ad", "role": "user", - "created": 1753704259, + "created": 1760565468, "content": [ { "type": "toolResponse", - "id": "toolu_01ABW2NhcBGvKL6nBj3T3fhv", + "id": "toolu_013JNt4Fn6i4Ls8HTbn8bQjG", "toolResult": { "status": "success", "value": [ @@ -305,7 +377,11 @@ ] } } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -439,32 +515,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -510,20 +642,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704261, + "created": 1760565471, "content": [ { "type": "text", - "text": "The current weather in Berlin, Germany is cloudy with a temperature of 18°C (64.4°F)." + "text": "The current weather in **Berlin, Germany** is:\n\n- **Temperature**: 18°C (64°F)\n- **Conditions**: Cloudy\n\nIt's a mild day with overcast skies in Berlin right now." } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "claude-sonnet-4-20250514", "usage": { - "input_tokens": 2663, - "output_tokens": 29, - "total_tokens": 2692 + "input_tokens": 2809, + "output_tokens": 53, + "total_tokens": 2862 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/anthropic/what_is_your_name.json b/crates/goose-cli/src/scenario_tests/recordings/anthropic/what_is_your_name.json index eacecbe3a5a7..d55f2d9ae4d9 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/anthropic/what_is_your_name.json +++ b/crates/goose-cli/src/scenario_tests/recordings/anthropic/what_is_your_name.json @@ -1,18 +1,22 @@ { "1b998117eba523901ae6a4dbf8caa81a95ea88ef7a84d0434c9b41a26164a2b9": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:04:16.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:44.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704256, + "created": 1760565464, "content": [ { "type": "text", "text": "what is your name" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -146,32 +150,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -217,20 +277,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704259, + "created": 1760565467, "content": [ { "type": "text", - "text": "I am goose, an AI agent created by Block (the parent company of Square, CashApp, and Tidal). I'm being developed as an open-source software project.\n\nI can help you with various tasks using different tools and extensions. While I have a defined identity as goose, I aim to be helpful, direct, and efficient in assisting you with your needs. Is there something specific I can help you with today?" + "text": "My name is **goose**. I'm a general-purpose AI agent created by Block, the parent company of Square, CashApp, and Tidal. I'm being developed as an open-source software project and can help you with various tasks using different extensions and tools.\n\nIs there something specific you'd like help with today?" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "claude-sonnet-4-20250514", "usage": { - "input_tokens": 2556, - "output_tokens": 97, - "total_tokens": 2653 + "input_tokens": 2704, + "output_tokens": 74, + "total_tokens": 2778 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/azure_openai/weather_tool.json b/crates/goose-cli/src/scenario_tests/recordings/azure_openai/weather_tool.json index 9403a20910a3..d6f53bb78fa1 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/azure_openai/weather_tool.json +++ b/crates/goose-cli/src/scenario_tests/recordings/azure_openai/weather_tool.json @@ -1,58 +1,22 @@ { - "21e33b98670d23e1bad3f21da667502d0930b42e34431395e266a4c524620cf1": { + "1bc400a528c54b25f4f1f609481e98e44222b3deaf7eee2c9e640e6345c73861": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:28.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:51.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704328, + "created": 1760565471, "content": [ { "type": "text", "text": "tell me what the weather is in Berlin, Germany" } - ] - }, - { - "id": null, - "role": "assistant", - "created": 1753704329, - "content": [ - { - "type": "toolRequest", - "id": "call_C91rmWZSSnUaKx0AtBdwO4Zw", - "toolCall": { - "status": "success", - "value": { - "name": "weather_extension__get_weather", - "arguments": { - "location": "Berlin, Germany" - } - } - } - } - ] - }, - { - "id": null, - "role": "user", - "created": 1753704329, - "content": [ - { - "type": "toolResponse", - "id": "call_C91rmWZSSnUaKx0AtBdwO4Zw", - "toolResult": { - "status": "success", - "value": [ - { - "type": "text", - "text": "The weather in Berlin, Germany is cloudy and 18°C" - } - ] - } - } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -186,32 +150,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -257,38 +277,103 @@ "message": { "id": null, "role": "assistant", - "created": 1753704331, + "created": 1760565472, "content": [ { - "type": "text", - "text": "### Current Weather in Berlin, Germany\n\n- **Condition:** Cloudy\n- **Temperature:** 18°C\n\nIf you need more information or forecasts, let me know!" + "type": "toolRequest", + "id": "call_QK2Zg4k9kTxaNXCyOVPbQ8Pc", + "toolCall": { + "status": "success", + "value": { + "name": "weather_extension__get_weather", + "arguments": { + "location": "Berlin, Germany" + } + } + } } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "gpt-4o-mini-2024-07-18", "usage": { - "input_tokens": 1722, - "output_tokens": 37, - "total_tokens": 1759 + "input_tokens": 1708, + "output_tokens": 20, + "total_tokens": 1728 } } } }, - "1bc400a528c54b25f4f1f609481e98e44222b3deaf7eee2c9e640e6345c73861": { + "198b76aab4abc29c526ddd37cf906dcf9161c94423d8ca772908bef353ece3e8": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:28.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:51.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704328, + "created": 1760565471, "content": [ { "type": "text", "text": "tell me what the weather is in Berlin, Germany" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } + }, + { + "id": null, + "role": "assistant", + "created": 1760565472, + "content": [ + { + "type": "toolRequest", + "id": "call_QK2Zg4k9kTxaNXCyOVPbQ8Pc", + "toolCall": { + "status": "success", + "value": { + "name": "weather_extension__get_weather", + "arguments": { + "location": "Berlin, Germany" + } + } + } + } + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } + }, + { + "id": "msg_85357fa1-4622-4b5c-bc66-ce79f12038dd", + "role": "user", + "created": 1760565472, + "content": [ + { + "type": "toolResponse", + "id": "call_QK2Zg4k9kTxaNXCyOVPbQ8Pc", + "toolResult": { + "status": "success", + "value": [ + { + "type": "text", + "text": "The weather in Berlin, Germany is cloudy and 18°C" + } + ] + } + } + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -422,32 +507,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -493,29 +634,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704329, + "created": 1760565473, "content": [ { - "type": "toolRequest", - "id": "call_C91rmWZSSnUaKx0AtBdwO4Zw", - "toolCall": { - "status": "success", - "value": { - "name": "weather_extension__get_weather", - "arguments": { - "location": "Berlin, Germany" - } - } - } + "type": "text", + "text": "The current weather in Berlin, Germany, is cloudy with a temperature of 18°C." } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "gpt-4o-mini-2024-07-18", "usage": { - "input_tokens": 1680, + "input_tokens": 1750, "output_tokens": 20, - "total_tokens": 1700 + "total_tokens": 1770 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/azure_openai/what_is_your_name.json b/crates/goose-cli/src/scenario_tests/recordings/azure_openai/what_is_your_name.json index 8cb9cc44c168..77256c16d837 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/azure_openai/what_is_your_name.json +++ b/crates/goose-cli/src/scenario_tests/recordings/azure_openai/what_is_your_name.json @@ -1,18 +1,22 @@ { "1b998117eba523901ae6a4dbf8caa81a95ea88ef7a84d0434c9b41a26164a2b9": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:25.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:47.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704325, + "created": 1760565467, "content": [ { "type": "text", "text": "what is your name" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -146,32 +150,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -217,20 +277,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704327, + "created": 1760565468, "content": [ { "type": "text", - "text": "My name is goose, an AI agent created by Block, the parent company of Square, CashApp, and Tidal. How can I assist you today?" + "text": "My name is Goose. I'm an AI agent created by Block, the parent company of Square, CashApp, and Tidal. How can I assist you today?" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "gpt-4o-mini-2024-07-18", "usage": { - "input_tokens": 1674, - "output_tokens": 34, - "total_tokens": 1708 + "input_tokens": 1702, + "output_tokens": 35, + "total_tokens": 1737 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/google/context_length_exceeded.json b/crates/goose-cli/src/scenario_tests/recordings/google/context_length_exceeded.json deleted file mode 100644 index 9e26dfeeb6e6..000000000000 --- a/crates/goose-cli/src/scenario_tests/recordings/google/context_length_exceeded.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/crates/goose-cli/src/scenario_tests/recordings/google/what_is_your_name.json b/crates/goose-cli/src/scenario_tests/recordings/google/what_is_your_name.json index 9abd50036895..fea4fe308ca6 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/google/what_is_your_name.json +++ b/crates/goose-cli/src/scenario_tests/recordings/google/what_is_your_name.json @@ -1,18 +1,22 @@ { "1b998117eba523901ae6a4dbf8caa81a95ea88ef7a84d0434c9b41a26164a2b9": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:27.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:49.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704327, + "created": 1760565469, "content": [ { "type": "text", "text": "what is your name" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -146,32 +150,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -217,20 +277,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704329, + "created": 1760565470, "content": [ { "type": "text", - "text": "My name is goose. I am a general-purpose AI agent created by Block, the parent company of Square, CashApp, and Tidal. I am being developed as an open-source software project." + "text": "My name is Goose." } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "gemini-2.5-flash", "usage": { - "input_tokens": 1967, - "output_tokens": 41, - "total_tokens": 2038 + "input_tokens": 2140, + "output_tokens": 5, + "total_tokens": 2145 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/groq/context_length_exceeded.json b/crates/goose-cli/src/scenario_tests/recordings/groq/context_length_exceeded.json deleted file mode 100644 index 9e26dfeeb6e6..000000000000 --- a/crates/goose-cli/src/scenario_tests/recordings/groq/context_length_exceeded.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/crates/goose-cli/src/scenario_tests/recordings/groq/weather_tool.json b/crates/goose-cli/src/scenario_tests/recordings/groq/weather_tool.json index 4faf11f4c639..8eb037f7a2df 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/groq/weather_tool.json +++ b/crates/goose-cli/src/scenario_tests/recordings/groq/weather_tool.json @@ -1,58 +1,22 @@ { - "09dddf56be462d1861d5a56de6ec2d79b76e1b6f8f8ba9da8d837aae55c7e70b": { + "1bc400a528c54b25f4f1f609481e98e44222b3deaf7eee2c9e640e6345c73861": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:31.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:53.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704331, + "created": 1760565473, "content": [ { "type": "text", "text": "tell me what the weather is in Berlin, Germany" } - ] - }, - { - "id": null, - "role": "assistant", - "created": 1753704331, - "content": [ - { - "type": "toolRequest", - "id": "rnxgf8akg", - "toolCall": { - "status": "success", - "value": { - "name": "weather_extension__get_weather", - "arguments": { - "location": "Berlin, Germany" - } - } - } - } - ] - }, - { - "id": null, - "role": "user", - "created": 1753704331, - "content": [ - { - "type": "toolResponse", - "id": "rnxgf8akg", - "toolResult": { - "status": "success", - "value": [ - { - "type": "text", - "text": "The weather in Berlin, Germany is cloudy and 18°C" - } - ] - } - } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -186,32 +150,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -257,38 +277,103 @@ "message": { "id": null, "role": "assistant", - "created": 1753704332, + "created": 1760565474, "content": [ { - "type": "text", - "text": "The weather in Berlin, Germany is cloudy with a temperature of 18°C." + "type": "toolRequest", + "id": "04fqdf70k", + "toolCall": { + "status": "success", + "value": { + "name": "weather_extension__get_weather", + "arguments": { + "location": "Berlin, Germany" + } + } + } } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "llama-3.3-70b-versatile", "usage": { - "input_tokens": 2856, - "output_tokens": 17, - "total_tokens": 2873 + "input_tokens": 2698, + "output_tokens": 20, + "total_tokens": 2718 } } } }, - "1bc400a528c54b25f4f1f609481e98e44222b3deaf7eee2c9e640e6345c73861": { + "54bbc046e4ff83dd29df1fa575c6d39f6195a259106666dfefd1b10ed662bd45": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:31.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:53.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704331, + "created": 1760565473, "content": [ { "type": "text", "text": "tell me what the weather is in Berlin, Germany" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } + }, + { + "id": null, + "role": "assistant", + "created": 1760565474, + "content": [ + { + "type": "toolRequest", + "id": "04fqdf70k", + "toolCall": { + "status": "success", + "value": { + "name": "weather_extension__get_weather", + "arguments": { + "location": "Berlin, Germany" + } + } + } + } + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } + }, + { + "id": "msg_7256b4f2-18dd-4477-98b7-cde7102e8a46", + "role": "user", + "created": 1760565474, + "content": [ + { + "type": "toolResponse", + "id": "04fqdf70k", + "toolResult": { + "status": "success", + "value": [ + { + "type": "text", + "text": "The weather in Berlin, Germany is cloudy and 18°C" + } + ] + } + } + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -422,32 +507,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -493,29 +634,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704331, + "created": 1760565474, "content": [ { - "type": "toolRequest", - "id": "rnxgf8akg", - "toolCall": { - "status": "success", - "value": { - "name": "weather_extension__get_weather", - "arguments": { - "location": "Berlin, Germany" - } - } - } + "type": "text", + "text": "The weather in Berlin, Germany is cloudy and 18°C." } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "llama-3.3-70b-versatile", "usage": { - "input_tokens": 2815, - "output_tokens": 20, - "total_tokens": 2835 + "input_tokens": 2739, + "output_tokens": 14, + "total_tokens": 2753 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/groq/what_is_your_name.json b/crates/goose-cli/src/scenario_tests/recordings/groq/what_is_your_name.json index 0f1cc66d8cef..28cabb791a9b 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/groq/what_is_your_name.json +++ b/crates/goose-cli/src/scenario_tests/recordings/groq/what_is_your_name.json @@ -1,18 +1,22 @@ { "1b998117eba523901ae6a4dbf8caa81a95ea88ef7a84d0434c9b41a26164a2b9": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:29.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:50.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704329, + "created": 1760565470, "content": [ { "type": "text", "text": "what is your name" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -146,32 +150,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -217,20 +277,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704329, + "created": 1760565471, "content": [ { "type": "text", - "text": "My name is goose, and I am a general-purpose AI agent developed by Block, the parent company of Square, CashApp, and Tidal." + "text": "My name is **goose**. I am a general-purpose AI agent created by Block, the parent company of Square, CashApp, and Tidal." } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "llama-3.3-70b-versatile", "usage": { - "input_tokens": 2809, - "output_tokens": 31, - "total_tokens": 2840 + "input_tokens": 2692, + "output_tokens": 33, + "total_tokens": 2725 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/openai/image_analysis.json b/crates/goose-cli/src/scenario_tests/recordings/openai/image_analysis.json index 63677ef5e7d6..0a84f7aa7e6b 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/openai/image_analysis.json +++ b/crates/goose-cli/src/scenario_tests/recordings/openai/image_analysis.json @@ -1,12 +1,12 @@ { "c848f22f273e158c32435d3e72cc999c046dc1a9afdc3efda68ff451f833a185": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:24.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:42.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704324, + "created": 1760565462, "content": [ { "type": "text", @@ -17,7 +17,11 @@ "data": "/9j/4Q/+RXhpZgAATU0AKgAAAAgABgESAAMAAAABAAEAAAEaAAUAAAABAAAAVgEbAAUAAAABAAAAXgEoAAMAAAABAAIAAAITAAMAAAABAAEAAIdpAAQAAAABAAAAZgAAAAAAAABIAAAAAQAAAEgAAAABAAeQAAAHAAAABDAyMjGRAQAHAAAABAECAwCgAAAHAAAABDAxMDCgAQADAAAAAQABAACgAgAEAAAAAQAAAgCgAwAEAAAAAQAAAgCkBgADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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", "mimeType": "image/jpeg" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -151,32 +155,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -222,20 +282,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704326, + "created": 1760565465, "content": [ { "type": "text", - "text": "This is an image of a goose standing by a body of water. If you have any questions or need information related to geese or something else, feel free to ask!" + "text": "This image shows a goose standing near a body of water. The goose has grey and brown feathers with a distinctive orange beak. It’s standing on grassy ground by the water's edge." } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "gpt-4o-2024-08-06", "usage": { - "input_tokens": 1925, - "output_tokens": 36, - "total_tokens": 1961 + "input_tokens": 1953, + "output_tokens": 39, + "total_tokens": 1992 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/openai/weather_tool.json b/crates/goose-cli/src/scenario_tests/recordings/openai/weather_tool.json index 6886d3697847..ddc200735f13 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/openai/weather_tool.json +++ b/crates/goose-cli/src/scenario_tests/recordings/openai/weather_tool.json @@ -1,58 +1,22 @@ { - "e546a32d4a2c9d41338b6725f317c4d4f462ce7cc04c79f3f24dd47a1a32a795": { + "1bc400a528c54b25f4f1f609481e98e44222b3deaf7eee2c9e640e6345c73861": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:24.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:42.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704324, + "created": 1760565462, "content": [ { "type": "text", "text": "tell me what the weather is in Berlin, Germany" } - ] - }, - { - "id": null, - "role": "assistant", - "created": 1753704326, - "content": [ - { - "type": "toolRequest", - "id": "call_5hvVKt0aj0RGRmrKEZECeJKV", - "toolCall": { - "status": "success", - "value": { - "name": "weather_extension__get_weather", - "arguments": { - "location": "Berlin, Germany" - } - } - } - } - ] - }, - { - "id": null, - "role": "user", - "created": 1753704326, - "content": [ - { - "type": "toolResponse", - "id": "call_5hvVKt0aj0RGRmrKEZECeJKV", - "toolResult": { - "status": "success", - "value": [ - { - "type": "text", - "text": "The weather in Berlin, Germany is cloudy and 18°C" - } - ] - } - } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -186,32 +150,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -257,38 +277,103 @@ "message": { "id": null, "role": "assistant", - "created": 1753704328, + "created": 1760565463, "content": [ { - "type": "text", - "text": "The weather in Berlin, Germany is currently cloudy with a temperature of 18°C." + "type": "toolRequest", + "id": "call_NSF9KSX2tCz8i8qb41WU6GHT", + "toolCall": { + "status": "success", + "value": { + "name": "weather_extension__get_weather", + "arguments": { + "location": "Berlin, Germany" + } + } + } } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "gpt-4o-2024-08-06", "usage": { - "input_tokens": 1722, - "output_tokens": 18, - "total_tokens": 1740 + "input_tokens": 1708, + "output_tokens": 19, + "total_tokens": 1727 } } } }, - "1bc400a528c54b25f4f1f609481e98e44222b3deaf7eee2c9e640e6345c73861": { + "4166a5a4297f1a6c903edc1c3232d12e2503190a3d4f98486d1a61d721bb0952": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:24.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:42.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704324, + "created": 1760565462, "content": [ { "type": "text", "text": "tell me what the weather is in Berlin, Germany" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } + }, + { + "id": null, + "role": "assistant", + "created": 1760565463, + "content": [ + { + "type": "toolRequest", + "id": "call_NSF9KSX2tCz8i8qb41WU6GHT", + "toolCall": { + "status": "success", + "value": { + "name": "weather_extension__get_weather", + "arguments": { + "location": "Berlin, Germany" + } + } + } + } + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } + }, + { + "id": "msg_926cf617-03cf-4027-ab42-d9bf44831517", + "role": "user", + "created": 1760565463, + "content": [ + { + "type": "toolResponse", + "id": "call_NSF9KSX2tCz8i8qb41WU6GHT", + "toolResult": { + "status": "success", + "value": [ + { + "type": "text", + "text": "The weather in Berlin, Germany is cloudy and 18°C" + } + ] + } + } + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -422,32 +507,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -493,29 +634,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704326, + "created": 1760565465, "content": [ { - "type": "toolRequest", - "id": "call_5hvVKt0aj0RGRmrKEZECeJKV", - "toolCall": { - "status": "success", - "value": { - "name": "weather_extension__get_weather", - "arguments": { - "location": "Berlin, Germany" - } - } - } + "type": "text", + "text": "The current weather in Berlin, Germany is cloudy with a temperature of 18°C." } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "gpt-4o-2024-08-06", "usage": { - "input_tokens": 1680, - "output_tokens": 19, - "total_tokens": 1699 + "input_tokens": 1750, + "output_tokens": 18, + "total_tokens": 1768 } } } diff --git a/crates/goose-cli/src/scenario_tests/recordings/openai/what_is_your_name.json b/crates/goose-cli/src/scenario_tests/recordings/openai/what_is_your_name.json index dfd02ab51c46..4ba6b2d4f0c2 100644 --- a/crates/goose-cli/src/scenario_tests/recordings/openai/what_is_your_name.json +++ b/crates/goose-cli/src/scenario_tests/recordings/openai/what_is_your_name.json @@ -1,18 +1,22 @@ { "1b998117eba523901ae6a4dbf8caa81a95ea88ef7a84d0434c9b41a26164a2b9": { "input": { - "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal. goose is being developed as an open-source software project.\n\nThe current date is 2025-07-28 12:05:24.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o, claude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10 months prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and tools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level problems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable extensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from the search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n## weather_extension\n\n\n\n\n\n\n\n# Suggestion\n\"\"\n\n\n\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", + "system": "You are a general-purpose AI agent called goose, created by Block, the parent company of Square, CashApp, and Tidal.\ngoose is being developed as an open-source software project.\n\nThe current date is 2025-10-15 21:57:42.\n\ngoose uses LLM providers with tool calling capability. You can be used with different language models (gpt-4o,\nclaude-sonnet-4, o1, llama-3.2, deepseek-r1, etc).\nThese models have varying knowledge cut-off dates depending on when they were trained, but typically it's between 5-10\nmonths prior to the current date.\n\n# Extensions\n\nExtensions allow other applications to provide context to goose. Extensions connect goose to different data sources and\ntools.\nYou are capable of dynamically plugging into new extensions and learning how to use them. You solve higher level\nproblems using the tools in these extensions, and can interact with multiple at once.\nUse the search_available_extensions tool to find additional extensions to enable to help with your task. To enable\nextensions, use the enable_extension tool and provide the extension_name. You should only enable extensions found from\nthe search_available_extensions tool.\n\n\nBecause you dynamically load extensions, your conversation history may refer\nto interactions with extensions that are not currently active. The currently\nactive extensions are below. Each of these extensions provides tools that are\nin your tool specification.\n\n\n\n## weather_extension\n\n\n\n\n\n\n\n\n\n# Suggestion\n\n\"\"\n\n\n\n\n# sub agents\n\nExecute self contained tasks where step-by-step visibility is not important through subagents.\n\n- Delegate via `dynamic_task__create_task` for: result-only operations, parallelizable work, multi-part requests,\n verification, exploration\n- Parallel subagents for multiple operations, single subagents for independent work\n- Explore solutions in parallel — launch parallel subagents with different approaches (if non-interfering)\n- Provide all needed context — subagents cannot see your context\n- Use extension filters to limit resource access\n- Use return_last_only when only a summary or simple answer is required — inform subagent of this choice.\n\n# Response Guidelines\n\n- Use Markdown formatting for all responses.\n- Follow best practices for Markdown, including:\n - Using headers for organization.\n - Bullet points for lists.\n - Links formatted correctly, either as linked text (e.g., [this is linked text](https://example.com)) or automatic\n links using angle brackets (e.g., ).\n- For code examples, use fenced code blocks by placing triple backticks (` ``` `) before and after the code. Include the\n language identifier after the opening backticks (e.g., ` ```python `) to enable syntax highlighting.\n- Ensure clarity, conciseness, and proper formatting to enhance readability and usability.\n\n# Additional Instructions:\n\nRight now you are *NOT* in the chat only mode and have access to tool use and system.", "messages": [ { "id": null, "role": "user", - "created": 1753704324, + "created": 1760565462, "content": [ { "type": "text", "text": "what is your name" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } } ], "tools": [ @@ -146,32 +150,88 @@ }, { "name": "dynamic_task__create_task", - "description": "Use this tool to create one or more dynamic tasks from a shared text instruction and varying parameters.How it works:\n - Provide a single text instruction\n - Use the 'task_parameters' field to pass an array of parameter sets\n - Each resulting task will use the same instruction with different parameter values\n This is useful when performing the same operation across many inputs (e.g., getting weather for multiple cities, searching multiple slack channels, iterating through various linear tickets, etc).\n Once created, these tasks should be passed to the 'subagent__execute_task' tool for execution. Tasks can run sequentially or in parallel.\n ---\n What is a 'subagent'?\n A 'subagent' is a stateless sub-process that executes a single task independently. Use subagents when:\n - You want to parallelize similar work across different inputs\n - You are not sure your search or operation will succeed on the first try\n Each subagent receives a task with a defined payload and returns a result, which is not visible to the user unless explicitly summarized by the system.\n ---\n Examples of 'task_parameters' for a single task:\n text_instruction: Search for the config file in the root directory.\n Examples of 'task_parameters' for multiple tasks:\n text_instruction: Get weather for Melbourne.\n text_instruction: Get weather for Los Angeles.\n text_instruction: Get weather for San Francisco.\n ", + "description": "Create tasks with instructions or prompt. For simple tasks, only include the instructions field. Extensions control: omit field = use all current extensions; empty array [] = no extensions; array with names = only those extensions. Specify extensions as shortnames (the prefixes for your tools). Specify return_last_only as true and have your subagent summarize its work in its last message to conserve your own context. Optional: title, description, extensions, settings, retry, response schema, context, activities. Arrays for multiple tasks.", "inputSchema": { "properties": { + "execution_mode": { + "description": "How to execute multiple tasks (default: parallel for multiple tasks, sequential for single task)", + "enum": [ + "sequential", + "parallel" + ], + "type": "string" + }, "task_parameters": { - "description": "Array of parameter sets for creating tasks. For a single task, provide an array with one element. For multiple tasks, provide an array with multiple elements, each with different parameter values. If there is no parameter set, provide an empty array.", + "description": "Array of tasks. Each task must have either 'instructions' OR 'prompt' field (at least one is required).", "items": { "properties": { - "text_instruction": { - "description": "The text instruction to execute", + "activities": { + "items": { + "type": "string" + }, + "type": "array" + }, + "context": { + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "extensions": { + "items": { + "type": "object" + }, + "type": "array" + }, + "instructions": { + "description": "Task instructions (required if prompt is not provided)", + "type": "string" + }, + "parameters": { + "items": { + "type": "object" + }, + "type": "array" + }, + "prompt": { + "description": "Initial prompt (required if instructions is not provided)", + "type": "string" + }, + "response": { + "type": "object" + }, + "retry": { + "type": "object" + }, + "return_last_only": { + "description": "If true, return only the last message from the subagent (default: false, returns full conversation)", + "type": "boolean" + }, + "settings": { + "type": "object" + }, + "title": { "type": "string" } }, - "required": [ - "text_instruction" - ], "type": "object" }, + "minItems": 1, "type": "array" } }, + "required": [ + "task_parameters" + ], "type": "object" }, "annotations": { - "title": "Dynamic Task Creation", + "title": "Create Dynamic Tasks", "readOnlyHint": false, - "destructiveHint": true, + "destructiveHint": false, "idempotentHint": false, "openWorldHint": true } @@ -217,20 +277,24 @@ "message": { "id": null, "role": "assistant", - "created": 1753704325, + "created": 1760565463, "content": [ { "type": "text", - "text": "My name is goose. I'm an AI agent developed by Block, the parent company of Square, Cash App, and Tidal. How can I assist you today?" + "text": "My name is goose. I'm an AI agent developed by Block, the parent company of Square, CashApp, and Tidal. How can I assist you today?" } - ] + ], + "metadata": { + "userVisible": true, + "agentVisible": true + } }, "usage": { "model": "gpt-4o-2024-08-06", "usage": { - "input_tokens": 1674, + "input_tokens": 1702, "output_tokens": 34, - "total_tokens": 1708 + "total_tokens": 1736 } } } diff --git a/crates/goose-cli/src/scenario_tests/scenarios.rs b/crates/goose-cli/src/scenario_tests/scenarios.rs index 6b6c0ef99922..d1c7695742cc 100644 --- a/crates/goose-cli/src/scenario_tests/scenarios.rs +++ b/crates/goose-cli/src/scenario_tests/scenarios.rs @@ -7,7 +7,6 @@ mod tests { use crate::scenario_tests::mock_client::WEATHER_TYPE; use crate::scenario_tests::scenario_runner::run_scenario; use anyhow::Result; - use goose::conversation::message::Message; #[tokio::test] async fn test_what_is_your_name() -> Result<()> { @@ -76,30 +75,24 @@ mod tests { .await } - #[tokio::test] - async fn test_context_length_exceeded_error() -> Result<()> { - run_scenario( - "context_length_exceeded", - Box::new(|provider| { - let model_config = provider.get_model_config(); - let context_length = model_config.context_limit.unwrap_or(300_000); - // "hello " is only one token in most models, since the hello and space often - // occur together in the training data. - let large_message = "hello ".repeat(context_length + 100); - Message::user().with_text(&large_message) - }), - Some(&["OpenAI"]), - |result| { - // this is unfortunate; we don't seem to actually catch the errors in this path, - // but instead eat it: - assert_eq!( - result.messages.len(), - 0, - "Expected no messages due to compaction" - ); - Ok(()) - }, - ) - .await - } + // #[tokio::test] + // async fn test_context_length_exceeded_error() -> Result<()> { + // run_scenario( + // "context_length_exceeded", + // Box::new(|provider| { + // let model_config = provider.get_model_config(); + // let context_length = model_config.context_limit.unwrap_or(300_000); + // // "hello " is only one token in most models, since the hello and space often + // // occur together in the training data. + // let large_message = "hello ".repeat(context_length + 100); + // Message::user().with_text(&large_message) + // }), + // Some(&["OpenAI"]), + // |result| { + // assert_eq!(result.messages.len(), 2, "One message after compaction"); + // Ok(()) + // }, + // ) + // .await + // } } diff --git a/crates/goose-cli/src/session/export.rs b/crates/goose-cli/src/session/export.rs index 2f046dfa22ce..ef2b111cd60d 100644 --- a/crates/goose-cli/src/session/export.rs +++ b/crates/goose-cli/src/session/export.rs @@ -369,7 +369,7 @@ pub fn message_to_markdown(message: &Message, export_all_content: bool) -> Strin md.push_str("**Thinking:**\n"); md.push_str("> *Thinking was redacted*\n\n"); } - MessageContent::SummarizationRequested(summarization) => { + MessageContent::ConversationCompacted(summarization) => { md.push_str(&format!("*{}*\n\n", summarization.msg)); } _ => { diff --git a/crates/goose-cli/src/session/mod.rs b/crates/goose-cli/src/session/mod.rs index 0547282c6715..2bb7b035df72 100644 --- a/crates/goose-cli/src/session/mod.rs +++ b/crates/goose-cli/src/session/mod.rs @@ -47,6 +47,7 @@ use std::sync::Arc; use std::time::Instant; use tokio; use tokio_util::sync::CancellationToken; +use tracing::warn; pub enum RunMode { Normal, @@ -158,19 +159,6 @@ impl CliSession { self.session_id.as_ref() } - async fn summarize_context_messages( - messages: &mut Conversation, - agent: &Agent, - message_suffix: &str, - ) -> Result<()> { - let (summarized_messages, _, _) = agent.summarize_context(messages.messages()).await?; - let msg = format!("Context maxed out\n{}\n{}", "-".repeat(50), message_suffix); - output::render_text(&msg, Some(Color::Yellow), true); - *messages = summarized_messages; - - Ok(()) - } - /// Add a stdio extension to the session /// /// # Arguments @@ -674,10 +662,24 @@ impl CliSession { // Get the provider for summarization let _provider = self.agent.provider().await?; + // Get session metadata if available + let session_metadata_for_compact = + if let Some(ref session_id) = self.session_id { + SessionManager::get_session(session_id, false).await.ok() + } else { + None + }; + // Call the summarize_context method - let (summarized_messages, _token_counts, summarization_usage) = self - .agent - .summarize_context(self.messages.messages()) + let (_, summarized_messages, _token_counts, summarization_usage) = + goose::context_mgmt::check_and_compact_messages( + &self.agent, + self.messages.messages(), + true, + false, + None, + session_metadata_for_compact.as_ref(), + ) .await?; // Update the session messages with the summarized ones @@ -937,84 +939,7 @@ impl CliSession { permission, },).await; } - } else if let Some(MessageContent::ContextLengthExceeded(_)) = message.content.first() { - output::hide_thinking(); - - // Check for user-configured default context strategy - let config = Config::global(); - let context_strategy = config.get_param::("GOOSE_CONTEXT_STRATEGY") - .unwrap_or_else(|_| if interactive { "prompt".to_string() } else { "summarize".to_string() }); - - let selected = match context_strategy.as_str() { - "clear" => "clear", - "truncate" => "truncate", - "summarize" => "summarize", - _ => { - if interactive { - // In interactive mode with no default, ask the user what to do - let prompt = "The model's context length is maxed out. You will need to reduce the # msgs. Do you want to?".to_string(); - cliclack::select(prompt) - .item("clear", "Clear Session", "Removes all messages from Goose's memory") - .item("truncate", "Truncate Messages", "Removes old messages till context is within limits") - .item("summarize", "Summarize Session", "Summarize the session to reduce context length") - .interact()? - } else { - // In headless mode, default to summarize - "summarize" - } - } - }; - - match selected { - "clear" => { - self.messages.clear(); - let msg = if context_strategy == "clear" { - format!("Context maxed out - automatically cleared session.\n{}", "-".repeat(50)) - } else { - format!("Session cleared.\n{}", "-".repeat(50)) - }; - output::render_text(&msg, Some(Color::Yellow), true); - break; // exit the loop to hand back control to the user - } - "truncate" => { - // Truncate messages to fit within context length - let (truncated_messages, _) = self.agent.truncate_context(self.messages.messages()).await?; - let msg = if context_strategy == "truncate" { - format!("Context maxed out - automatically truncated messages.\n{}\nGoose tried its best to truncate messages for you.", "-".repeat(50)) - } else { - format!("Context maxed out\n{}\nGoose tried its best to truncate messages for you.", "-".repeat(50)) - }; - output::render_text("", Some(Color::Yellow), true); - output::render_text(&msg, Some(Color::Yellow), true); - self.messages = truncated_messages; - } - "summarize" => { - // Use the helper function to summarize context - let message_suffix = if context_strategy == "summarize" { - "Goose automatically summarized messages for you." - } else if interactive { - "Goose summarized messages for you." - } else { - "Goose automatically summarized messages to continue processing." - }; - Self::summarize_context_messages(&mut self.messages, &self.agent, message_suffix).await?; - } - _ => { - unreachable!() - } - } - - // Restart the stream after handling ContextLengthExceeded - stream = self - .agent - .reply( - self.messages.clone(), - session_config.clone(), - None - ) - .await?; } - // otherwise we have a model/tool to render else { for content in &message.content { if let MessageContent::ToolRequest(tool_request) = content { @@ -1171,10 +1096,10 @@ impl CliSession { _ => (), } } - Some(Ok(AgentEvent::HistoryReplaced(new_messages))) => { - self.messages = Conversation::new_unvalidated(new_messages.clone()); - } - Some(Ok(AgentEvent::ModelChange { model, mode })) => { + Some(Ok(AgentEvent::HistoryReplaced(updated_conversation))) => { + self.messages = updated_conversation; + } + Some(Ok(AgentEvent::ModelChange { model, mode })) => { // Log model change if in debug mode if self.debug { eprintln!("Model changed to {} in {} mode", model, mode); @@ -1182,94 +1107,24 @@ impl CliSession { } Some(Err(e)) => { + // TODO(Douwe): Delete this // Check if it's a ProviderError::ContextLengthExceeded if e.downcast_ref::() .map(|provider_error| matches!(provider_error, goose::providers::errors::ProviderError::ContextLengthExceeded(_))) .unwrap_or(false) { output::render_text( - "Context limit reached. Performing auto-compaction...", + "Compaction requested. Should have happened in the agent!", Some(Color::Yellow), true ); - - // Try auto-compaction first - keep the stream alive! - if let Ok(compact_result) = goose::context_mgmt::auto_compact::perform_compaction(&self.agent, self.messages.messages()).await { - self.messages = compact_result.messages; - if let Some(session_id) = &self.session_id { - SessionManager::replace_conversation(session_id, &self.messages).await?; - } - - output::render_text( - "Compaction complete. Conversation has been automatically compacted to continue.", - Some(Color::Yellow), - true - ); - - // Restart the stream after successful compaction - keep the stream alive! - stream = self - .agent - .reply( - self.messages.clone(), - session_config.clone(), - Some(cancel_token.clone()) - ) - .await?; - continue; - } - // Auto-compaction failed, fall through to common error handling below + warn!("Compaction requested. Should have happened in the agent!"); } eprintln!("Error: {}", e); cancel_token_clone.cancel(); drop(stream); if let Err(e) = self.handle_interrupted_messages(false).await { eprintln!("Error handling interruption: {}", e); - } - - // Check if it's a ProviderError::ContextLengthExceeded - if e.downcast_ref::() - .map(|provider_error| matches!(provider_error, goose::providers::errors::ProviderError::ContextLengthExceeded(_))) - .unwrap_or(false) { - output::render_error(&format!("Error: Context length exceeded: {}", e)); - - let prompt = "The tool calling loop was interrupted. How would you like to proceed?"; - let selected = match cliclack::select(prompt.to_string()) - .item("clear", "Clear Session", "Removes all messages from Goose's memory") - .item("summarize", "Summarize Session", "Summarize the session to reduce context length") - .interact() - { - Ok(choice) => Some(choice), - Err(e) => { - if e.kind() == std::io::ErrorKind::Interrupted { - // If interrupted, do nothing and let user handle it manually - output::render_text("Operation cancelled. You can use /clear or /summarize to continue.", Some(Color::Yellow), true); - None - } else { - return Err(e.into()); - } - } - }; - - if let Some(choice) = selected { - match choice { - "clear" => { - self.messages.clear(); - let msg = format!("Session cleared.\n{}", "-".repeat(50)); - output::render_text(&msg, Some(Color::Yellow), true); - } - "summarize" => { - // Use the helper function to summarize context - let message_suffix = "Goose summarized messages for you."; - if let Err(e) = Self::summarize_context_messages(&mut self.messages, &self.agent, message_suffix).await { - output::render_error(&format!("Failed to summarize: {}", e)); - output::render_text("Consider using /clear to start fresh.", Some(Color::Yellow), true); - } - } - _ => { - unreachable!() - } - } - } } else { output::render_error( "The error above was an exception we were not able to handle.\n\ diff --git a/crates/goose-cli/src/session/output.rs b/crates/goose-cli/src/session/output.rs index 639d7da96157..e7c536f8a427 100644 --- a/crates/goose-cli/src/session/output.rs +++ b/crates/goose-cli/src/session/output.rs @@ -185,7 +185,7 @@ pub fn render_message(message: &Message, debug: bool) { println!("\n{}", style("Thinking:").dim().italic()); print_markdown("Thinking was redacted", theme); } - MessageContent::SummarizationRequested(summarization) => { + MessageContent::ConversationCompacted(summarization) => { println!("\n{}", style(&summarization.msg).yellow()); } _ => { diff --git a/crates/goose-server/src/openapi.rs b/crates/goose-server/src/openapi.rs index 42df6681f107..90ea1ea11277 100644 --- a/crates/goose-server/src/openapi.rs +++ b/crates/goose-server/src/openapi.rs @@ -18,10 +18,10 @@ use goose::config::declarative_providers::{ DeclarativeProviderConfig, LoadedProvider, ProviderEngine, }; use goose::conversation::message::{ - ContextLengthExceeded, FrontendToolRequest, Message, MessageContent, MessageMetadata, - RedactedThinkingContent, SummarizationRequested, ThinkingContent, ToolConfirmationRequest, - ToolRequest, ToolResponse, + ConversationCompacted, FrontendToolRequest, Message, MessageContent, MessageMetadata, + RedactedThinkingContent, ThinkingContent, ToolConfirmationRequest, ToolRequest, ToolResponse, }; + use utoipa::openapi::schema::{ AdditionalProperties, AnyOfBuilder, ArrayBuilder, ObjectBuilder, OneOfBuilder, Schema, SchemaFormat, SchemaType, @@ -420,8 +420,7 @@ derive_utoipa!(Icon as IconSchema); RedactedThinkingContent, FrontendToolRequest, ResourceContentsSchema, - ContextLengthExceeded, - SummarizationRequested, + ConversationCompacted, JsonObjectSchema, RoleSchema, ProviderMetadata, diff --git a/crates/goose-server/src/routes/context.rs b/crates/goose-server/src/routes/context.rs index 6f8764b074f9..63dd203af612 100644 --- a/crates/goose-server/src/routes/context.rs +++ b/crates/goose-server/src/routes/context.rs @@ -1,6 +1,6 @@ use crate::state::AppState; use axum::{extract::State, http::StatusCode, routing::post, Json, Router}; -use goose::conversation::{message::Message, Conversation}; +use goose::conversation::message::Message; use serde::{Deserialize, Serialize}; use std::sync::Arc; use utoipa::ToSchema; @@ -11,8 +11,6 @@ use utoipa::ToSchema; pub struct ContextManageRequest { /// Collection of messages to be managed pub messages: Vec, - /// Operation to perform: "truncation" or "summarize" - pub manage_action: String, /// Optional session ID for session-specific agent pub session_id: String, } @@ -48,28 +46,20 @@ async fn manage_context( ) -> Result, StatusCode> { let agent = state.get_agent_for_route(request.session_id).await?; - let mut processed_messages = Conversation::new_unvalidated(vec![]); - let mut token_counts: Vec = vec![]; - - if request.manage_action == "truncation" { - (processed_messages, token_counts) = agent - .truncate_context(&request.messages) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - } else if request.manage_action == "summarize" { - (processed_messages, token_counts, _) = agent - .summarize_context(&request.messages) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - } + let (_, processed_messages, token_counts, _) = goose::context_mgmt::check_and_compact_messages( + &agent, + &request.messages, + true, + false, + None, + None, + ) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + // TODO(Douwe): store into db Ok(Json(ContextManageResponse { - messages: processed_messages - .messages() - .iter() - .filter(|m| m.is_user_visible()) - .cloned() - .collect(), + messages: processed_messages.messages().to_vec(), token_counts, })) } diff --git a/crates/goose-server/src/routes/reply.rs b/crates/goose-server/src/routes/reply.rs index c8db3b47cee0..a419e75769f0 100644 --- a/crates/goose-server/src/routes/reply.rs +++ b/crates/goose-server/src/routes/reply.rs @@ -121,9 +121,9 @@ impl IntoResponse for SseResponse { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, utoipa::ToSchema)] #[serde(tag = "type")] -enum MessageEvent { +pub enum MessageEvent { Message { message: Message, }, @@ -141,6 +141,9 @@ enum MessageEvent { request_id: String, message: ServerNotification, }, + UpdateConversation { + conversation: Conversation, + }, Ping, } @@ -306,10 +309,9 @@ pub async fn reply( } } Ok(Some(Ok(AgentEvent::HistoryReplaced(new_messages)))) => { - // Replace the message history with the compacted messages - all_messages = Conversation::new_unvalidated(new_messages); - // Note: We don't send this as a stream event since it's an internal operation - // The client will see the compaction notification message that was sent before this event + all_messages = new_messages.clone(); + stream_event(MessageEvent::UpdateConversation {conversation: new_messages}, &tx, &cancel_token).await; + } Ok(Some(Ok(AgentEvent::ModelChange { model, mode }))) => { stream_event(MessageEvent::ModelChange { model, mode }, &tx, &cancel_token).await; diff --git a/crates/goose/src/agents/agent.rs b/crates/goose/src/agents/agent.rs index 06da2531fcf6..4a31d7826cb1 100644 --- a/crates/goose/src/agents/agent.rs +++ b/crates/goose/src/agents/agent.rs @@ -33,7 +33,7 @@ use crate::agents::tool_router_index_manager::ToolRouterIndexManager; use crate::agents::types::SessionConfig; use crate::agents::types::{FrontendTool, ToolResultReceiver}; use crate::config::{get_enabled_extensions, get_extension_by_name, Config}; -use crate::context_mgmt::auto_compact; +use crate::context_mgmt::{check_and_compact_messages, DEFAULT_COMPACTION_THRESHOLD}; use crate::conversation::{debug_conversation_fix, fix_conversation, Conversation}; use crate::mcp_utils::ToolResult; use crate::permission::permission_inspector::PermissionInspector; @@ -112,7 +112,7 @@ pub enum AgentEvent { Message(Message), McpNotification((String, ServerNotification)), ModelChange { model: String, mode: String }, - HistoryReplaced(Vec), + HistoryReplaced(Conversation), } impl Default for Agent { @@ -902,20 +902,15 @@ impl Agent { } } - /// Handle auto-compaction logic and return compacted messages if needed - async fn handle_auto_compaction( + #[instrument(skip(self, unfixed_conversation, session), fields(user_message))] + pub async fn reply( &self, - messages: &[Message], - session: &Option, - ) -> Result< - Option<( - Conversation, - String, - Option, - )>, - > { + unfixed_conversation: Conversation, + session: Option, + cancel_token: Option, + ) -> Result>> { // Try to get session metadata for more accurate token counts - let session_metadata = if let Some(session_config) = session { + let session_metadata = if let Some(session_config) = &session { SessionManager::get_session(&session_config.id, false) .await .ok() @@ -923,22 +918,29 @@ impl Agent { None }; - let compact_result = auto_compact::check_and_compact_messages( - self, - messages, - None, - session_metadata.as_ref(), - ) - .await?; - - if compact_result.compacted { - let compacted_messages = compact_result.messages; + let (did_compact, compacted_conversation, compaction_error) = + match check_and_compact_messages( + self, + unfixed_conversation.messages(), + false, + false, + None, + session_metadata.as_ref(), + ) + .await + { + Ok((did_compact, conversation, _removed_indices, _summarization_usage)) => { + (did_compact, conversation, None) + } + Err(e) => (false, unfixed_conversation.clone(), Some(e)), + }; + if did_compact { // Get threshold from config to include in message let config = crate::config::Config::global(); let threshold = config .get_param::("GOOSE_AUTO_COMPACT_THRESHOLD") - .unwrap_or(0.8); // Default to 80% + .unwrap_or(DEFAULT_COMPACTION_THRESHOLD); let threshold_percentage = (threshold * 100.0) as u32; let compaction_msg = format!( @@ -946,42 +948,27 @@ impl Agent { threshold_percentage ); - return Ok(Some(( - compacted_messages, - compaction_msg, - compact_result.summarization_usage, - ))); - } - - Ok(None) - } - - #[instrument(skip(self, unfixed_conversation, session), fields(user_message))] - pub async fn reply( - &self, - unfixed_conversation: Conversation, - session: Option, - cancel_token: Option, - ) -> Result>> { - let compaction_result = self - .handle_auto_compaction(unfixed_conversation.messages(), &session) - .await?; - - if let Some((conversation, compaction_message, _summarization_usage)) = compaction_result { Ok(Box::pin(async_stream::try_stream! { + // TODO(Douwe): send this before we actually compact: yield AgentEvent::Message( - Message::assistant().with_summarization_requested(compaction_message) + Message::assistant().with_conversation_compacted(compaction_msg) ); - yield AgentEvent::HistoryReplaced(conversation.messages().clone()); + yield AgentEvent::HistoryReplaced(compacted_conversation.clone()); if let Some(session_to_store) = &session { - SessionManager::replace_conversation(&session_to_store.id, &conversation).await? + SessionManager::replace_conversation(&session_to_store.id, &compacted_conversation).await? } - let mut reply_stream = self.reply_internal(conversation, session, cancel_token).await?; + let mut reply_stream = self.reply_internal(compacted_conversation, session, cancel_token).await?; while let Some(event) = reply_stream.next().await { yield event?; } })) + } else if let Some(error) = compaction_error { + Ok(Box::pin(async_stream::try_stream! { + yield AgentEvent::Message(Message::assistant().with_text( + format!("Ran into this error trying to auto-compact: {error}.\n\nPlease try again or create a new session") + )); + })) } else { self.reply_internal(unfixed_conversation, session, cancel_token) .await @@ -1113,6 +1100,7 @@ impl Agent { let mut no_tools_called = true; let mut messages_to_add = Conversation::default(); let mut tools_updated = false; + let mut did_recovery_compact_this_iteration = false; while let Some(next) = stream.next().await { if is_token_cancelled(&cancel_token) { @@ -1306,28 +1294,37 @@ impl Agent { messages_to_add.push(final_message_tool_resp); } } - Err(ProviderError::ContextLengthExceeded(error_msg)) => { + Err(ProviderError::ContextLengthExceeded(_error_msg)) => { info!("Context length exceeded, attempting compaction"); - match auto_compact::perform_compaction(self, conversation.messages()).await { - Ok(compact_result) => { - conversation = compact_result.messages; + // Get session metadata if available + let session_metadata_for_compact = if let Some(ref session_config) = session { + SessionManager::get_session(&session_config.id, false).await.ok() + } else { + None + }; + + match check_and_compact_messages(self, conversation.messages(), true, true, None, session_metadata_for_compact.as_ref()).await { + Ok((_did_compact, compacted_conversation, _removed_indices, _usage)) => { + conversation = compacted_conversation; + did_recovery_compact_this_iteration = true; yield AgentEvent::Message( - Message::assistant().with_summarization_requested( + Message::assistant().with_conversation_compacted( "Context limit reached. Conversation has been automatically compacted to continue." ) ); - yield AgentEvent::HistoryReplaced(conversation.messages().to_vec()); + yield AgentEvent::HistoryReplaced(conversation.clone()); if let Some(session_to_store) = &session { SessionManager::replace_conversation(&session_to_store.id, &conversation).await? } continue; } - Err(_) => { - yield AgentEvent::Message(Message::assistant().with_context_length_exceeded( - format!("Context length exceeded and cannot summarize: {}. Unable to continue.", error_msg) - )); + Err(e) => { + error!("Error: {}", e); + yield AgentEvent::Message(Message::assistant().with_text( + format!("Ran into this error trying to compact: {e}.\n\nPlease retry if you think this is a transient or recoverable error.") + )); break; } } @@ -1358,6 +1355,8 @@ impl Agent { yield AgentEvent::Message(message); exit_chat = true; } + } else if did_recovery_compact_this_iteration { + // Avoid setting exit_chat; continue from last user message in the conversation } else { match self.handle_retry_logic(&mut conversation, &session, &initial_messages).await { Ok(should_retry) => { diff --git a/crates/goose/src/agents/context.rs b/crates/goose/src/agents/context.rs deleted file mode 100644 index 37edcfb5658b..000000000000 --- a/crates/goose/src/agents/context.rs +++ /dev/null @@ -1,130 +0,0 @@ -use anyhow::Ok; - -use crate::conversation::message::{Message, MessageMetadata}; -use crate::conversation::Conversation; -use crate::token_counter::create_async_token_counter; - -use crate::context_mgmt::summarize::summarize_messages; -use crate::context_mgmt::truncate::{truncate_messages, OldestFirstTruncation}; -use crate::context_mgmt::{estimate_target_context_limit, get_messages_token_counts_async}; - -use super::super::agents::Agent; - -impl Agent { - /// Public API to truncate oldest messages so that the conversation's token count is within the allowed context limit. - pub async fn truncate_context( - &self, - messages: &[Message], // last message is a user msg that led to assistant message with_context_length_exceeded - ) -> Result<(Conversation, Vec), anyhow::Error> { - let provider = self.provider().await?; - let token_counter = create_async_token_counter() - .await - .map_err(|e| anyhow::anyhow!("Failed to create token counter: {}", e))?; - let target_context_limit = estimate_target_context_limit(provider); - let token_counts = get_messages_token_counts_async(&token_counter, messages); - - let (mut new_messages, mut new_token_counts) = truncate_messages( - messages, - &token_counts, - target_context_limit, - &OldestFirstTruncation, - )?; - - // Only add an assistant message if we have room for it and it won't cause another overflow - let assistant_message = Message::assistant().with_text("I had run into a context length exceeded error so I truncated some of the oldest messages in our conversation."); - let assistant_tokens = - token_counter.count_chat_tokens("", std::slice::from_ref(&assistant_message), &[]); - - let current_total: usize = new_token_counts.iter().sum(); - if current_total + assistant_tokens <= target_context_limit { - new_messages.push(assistant_message); - new_token_counts.push(assistant_tokens); - } else { - // If we can't fit the assistant message, at least log what happened - tracing::warn!("Cannot add truncation notice message due to context limits. Current: {}, Assistant: {}, Limit: {}", - current_total, assistant_tokens, target_context_limit); - } - - Ok((new_messages, new_token_counts)) - } - - /// Public API to summarize the conversation so that its token count is within the allowed context limit. - /// Returns the summarized messages, token counts, and the ProviderUsage from summarization - pub async fn summarize_context( - &self, - messages: &[Message], // last message is a user msg that led to assistant message with_context_length_exceeded - ) -> Result< - ( - Conversation, - Vec, - Option, - ), - anyhow::Error, - > { - let provider = self.provider().await?; - let summary_result = summarize_messages(provider.clone(), messages).await?; - - let (summary_message, summarization_usage) = match summary_result { - Some((summary_message, provider_usage)) => (summary_message, Some(provider_usage)), - None => { - // No summary was generated (empty input) - tracing::warn!("Summarization failed. Returning empty messages."); - return Ok((Conversation::empty(), vec![], None)); - } - }; - - // Create the final message list with updated visibility metadata: - // 1. Original messages become user_visible but not agent_visible - // 2. Summary message becomes agent_visible but not user_visible - // 3. Assistant messages to continue the conversation remain both user_visible and agent_visible - - let mut final_messages = Vec::new(); - let mut final_token_counts = Vec::new(); - - // Add all original messages with updated visibility (preserve user_visible, set agent_visible=false) - for msg in messages.iter().cloned() { - let updated_metadata = msg.metadata.with_agent_invisible(); - let updated_msg = msg.with_metadata(updated_metadata); - final_messages.push(updated_msg); - // Token count doesn't matter for agent_visible=false messages, but we'll use 0 - final_token_counts.push(0); - } - - // Add the compaction marker (user_visible=true, agent_visible=false) - let compaction_marker = Message::assistant() - .with_summarization_requested("Conversation compacted and summarized") - .with_metadata(MessageMetadata::user_only()); - let compaction_marker_tokens: usize = 0; // Not counted since agent_visible=false - final_messages.push(compaction_marker); - final_token_counts.push(compaction_marker_tokens); - - // Add the summary message (agent_visible=true, user_visible=false) - let summary_msg = summary_message.with_metadata(MessageMetadata::agent_only()); - // For token counting purposes, we use the output tokens (the actual summary content) - // since that's what will be in the context going forward - let summary_tokens = summarization_usage - .as_ref() - .and_then(|usage| usage.usage.output_tokens) - .unwrap_or(0) as usize; - final_messages.push(summary_msg); - final_token_counts.push(summary_tokens); - - // Add an assistant message to continue the conversation (agent_visible=true, user_visible=false) - let assistant_message = Message::assistant() - .with_text( - "The previous message contains a summary that was prepared because a context limit was reached. -Do not mention that you read a summary or that conversation summarization occurred -Just continue the conversation naturally based on the summarized context" - ) - .with_metadata(MessageMetadata::agent_only()); - let assistant_message_tokens: usize = 0; // Not counted since it's for agent context only - final_messages.push(assistant_message); - final_token_counts.push(assistant_message_tokens); - - Ok(( - Conversation::new_unvalidated(final_messages), - final_token_counts, - summarization_usage, - )) - } -} diff --git a/crates/goose/src/agents/mod.rs b/crates/goose/src/agents/mod.rs index 39bf903a3579..23dabbb8b095 100644 --- a/crates/goose/src/agents/mod.rs +++ b/crates/goose/src/agents/mod.rs @@ -1,5 +1,4 @@ mod agent; -mod context; pub mod extension; pub mod extension_malware_check; pub mod extension_manager; diff --git a/crates/goose/src/agents/reply_parts.rs b/crates/goose/src/agents/reply_parts.rs index c4b7b34d1b20..9cfb70657d9d 100644 --- a/crates/goose/src/agents/reply_parts.rs +++ b/crates/goose/src/agents/reply_parts.rs @@ -108,39 +108,46 @@ impl Agent { let toolshim_tools = toolshim_tools.to_owned(); let provider = provider.clone(); - let mut stream = if provider.supports_streaming() { + // Capture errors during stream creation and return them as part of the stream + // so they can be handled by the existing error handling logic in the agent + let stream_result = if provider.supports_streaming() { debug!("WAITING_LLM_STREAM_START"); - let msg_stream = provider + let result = provider .stream( system_prompt.as_str(), messages_for_provider.messages(), &tools, ) - .await?; + .await; debug!("WAITING_LLM_STREAM_END"); - msg_stream + result } else { debug!("WAITING_LLM_START"); - let (message, mut usage) = provider + let complete_result = provider .complete( system_prompt.as_str(), messages_for_provider.messages(), &tools, ) - .await?; + .await; debug!("WAITING_LLM_END"); - // Ensure we have token counts for non-streaming case - usage - .ensure_tokens( - system_prompt.as_str(), - messages_for_provider.messages(), - &message, - &tools, - ) - .await?; + match complete_result { + Ok((message, usage)) => Ok(stream_from_single_message(message, usage)), + Err(e) => Err(e), + } + }; - stream_from_single_message(message, usage) + // If there was an error creating the stream, return a stream that yields that error + let mut stream = match stream_result { + Ok(s) => s, + Err(e) => { + // Return a stream that immediately yields the error + // This allows the error to be caught by existing error handling in agent.rs + return Ok(Box::pin(try_stream! { + yield Err(e)?; + })); + } }; Ok(Box::pin(try_stream! { diff --git a/crates/goose/src/agents/subagent_handler.rs b/crates/goose/src/agents/subagent_handler.rs index 25e5d3f53207..ad14f282f1b7 100644 --- a/crates/goose/src/agents/subagent_handler.rs +++ b/crates/goose/src/agents/subagent_handler.rs @@ -127,7 +127,7 @@ fn get_agent_messages( } } - let mut session_messages = + let mut conversation = Conversation::new_unvalidated( vec![Message::user().with_text(text_instruction.clone())], ); @@ -141,15 +141,16 @@ fn get_agent_messages( }; let mut stream = agent - .reply(session_messages.clone(), Some(session_config), None) + .reply(conversation.clone(), Some(session_config), None) .await .map_err(|e| anyhow!("Failed to get reply from agent: {}", e))?; while let Some(message_result) = stream.next().await { match message_result { - Ok(AgentEvent::Message(msg)) => session_messages.push(msg), - Ok(AgentEvent::McpNotification(_)) - | Ok(AgentEvent::ModelChange { .. }) - | Ok(AgentEvent::HistoryReplaced(_)) => {} + Ok(AgentEvent::Message(msg)) => conversation.push(msg), + Ok(AgentEvent::McpNotification(_)) | Ok(AgentEvent::ModelChange { .. }) => {} + Ok(AgentEvent::HistoryReplaced(updated_conversation)) => { + conversation = updated_conversation; + } Err(e) => { tracing::error!("Error receiving message from subagent: {}", e); break; @@ -157,6 +158,6 @@ fn get_agent_messages( } } - Ok(session_messages) + Ok(conversation) }) } diff --git a/crates/goose/src/context_mgmt/auto_compact.rs b/crates/goose/src/context_mgmt/auto_compact.rs deleted file mode 100644 index 542d252f3108..000000000000 --- a/crates/goose/src/context_mgmt/auto_compact.rs +++ /dev/null @@ -1,766 +0,0 @@ -use crate::conversation::message::Message; -use crate::conversation::Conversation; -use crate::{ - agents::Agent, config::Config, context_mgmt::get_messages_token_counts_async, - token_counter::create_async_token_counter, -}; -use anyhow::Result; -use tracing::{debug, info}; - -/// Result of auto-compaction check -#[derive(Debug)] -pub struct AutoCompactResult { - /// Whether compaction was performed - pub compacted: bool, - /// The messages after potential compaction - pub messages: Conversation, - /// Provider usage from summarization (if compaction occurred) - /// This contains the actual token counts after compaction - pub summarization_usage: Option, -} - -/// Result of checking if compaction is needed -#[derive(Debug)] -pub struct CompactionCheckResult { - /// Whether compaction is needed - pub needs_compaction: bool, - /// Current token count - pub current_tokens: usize, - /// Context limit being used - pub context_limit: usize, - /// Current usage ratio (0.0 to 1.0) - pub usage_ratio: f64, - /// Remaining tokens before compaction threshold - pub remaining_tokens: usize, - /// Percentage until compaction threshold (0.0 to 100.0) - pub percentage_until_compaction: f64, -} - -/// Check if messages need compaction without performing the compaction -/// -/// This function analyzes the current token usage and returns detailed information -/// about whether compaction is needed and how close we are to the threshold. -/// It prioritizes actual token counts from session metadata when available, -/// falling back to estimated counts if needed. -/// -/// # Arguments -/// * `agent` - The agent to use for context management -/// * `messages` - The current message history -/// * `threshold_override` - Optional threshold override (defaults to GOOSE_AUTO_COMPACT_THRESHOLD config) -/// * `session_metadata` - Optional session metadata containing actual token counts -/// -/// # Returns -/// * `CompactionCheckResult` containing detailed information about compaction needs -pub async fn check_compaction_needed( - agent: &Agent, - messages: &[Message], - threshold_override: Option, - session_metadata: Option<&crate::session::Session>, -) -> Result { - // Get threshold from config or use override - let config = Config::global(); - let threshold = threshold_override.unwrap_or_else(|| { - config - .get_param::("GOOSE_AUTO_COMPACT_THRESHOLD") - .unwrap_or(0.8) // Default to 80% - }); - - let provider = agent.provider().await?; - let context_limit = provider.get_model_config().context_limit(); - - let (current_tokens, token_source) = match session_metadata.and_then(|m| m.total_tokens) { - Some(tokens) => (tokens as usize, "session metadata"), - None => { - let token_counter = create_async_token_counter() - .await - .map_err(|e| anyhow::anyhow!("Failed to create token counter: {}", e))?; - let token_counts = get_messages_token_counts_async(&token_counter, messages); - (token_counts.iter().sum(), "estimated") - } - }; - - // Calculate usage ratio - let usage_ratio = current_tokens as f64 / context_limit as f64; - - // Calculate threshold token count and remaining tokens - let threshold_tokens = (context_limit as f64 * threshold) as usize; - let remaining_tokens = threshold_tokens.saturating_sub(current_tokens); - - // Calculate percentage until compaction (how much more we can use before hitting threshold) - let percentage_until_compaction = if usage_ratio < threshold { - (threshold - usage_ratio) * 100.0 - } else { - 0.0 - }; - - // Check if compaction is needed (disabled if threshold is invalid) - let needs_compaction = if threshold <= 0.0 || threshold >= 1.0 { - false - } else { - usage_ratio > threshold - }; - - debug!( - "Compaction check: {} / {} tokens ({:.1}%), threshold: {:.1}%, needs compaction: {}, source: {}", - current_tokens, - context_limit, - usage_ratio * 100.0, - threshold * 100.0, - needs_compaction, - token_source - ); - - Ok(CompactionCheckResult { - needs_compaction, - current_tokens, - context_limit, - usage_ratio, - remaining_tokens, - percentage_until_compaction, - }) -} - -/// Perform compaction on messages without checking thresholds -/// -/// This function directly performs compaction on the provided messages. -/// If the most recent message is a user message, it will be preserved by removing it -/// before compaction and adding it back afterwards. -/// -/// # Arguments -/// * `agent` - The agent to use for context management -/// * `messages` - The current message history -/// -/// # Returns -/// * `AutoCompactResult` containing the compacted messages and metadata -pub async fn perform_compaction(agent: &Agent, messages: &[Message]) -> Result { - info!("Performing message compaction"); - - // Check if the most recent message is a user message - let (messages_to_compact, preserved_user_message) = if let Some(last_message) = messages.last() - { - if matches!(last_message.role, rmcp::model::Role::User) { - // Remove the last user message before compaction - (&messages[..messages.len() - 1], Some(last_message.clone())) - } else { - (messages, None) - } - } else { - (messages, None) - }; - - // Perform the compaction on messages excluding the preserved user message - let (mut compacted_messages, _, summarization_usage) = - agent.summarize_context(messages_to_compact).await?; - - // Add back the preserved user message if it exists - if let Some(user_message) = preserved_user_message { - compacted_messages.push(user_message); - } - - Ok(AutoCompactResult { - compacted: true, - messages: compacted_messages, - summarization_usage, - }) -} - -/// Check if messages need compaction and compact them if necessary -/// -/// This is a convenience wrapper function that combines checking and compaction. -/// Uses perform_compaction internally to handle the actual compaction process. -/// -/// # Arguments -/// * `agent` - The agent to use for context management -/// * `messages` - The current message history -/// * `threshold_override` - Optional threshold override (defaults to GOOSE_AUTO_COMPACT_THRESHOLD config) -/// * `session_metadata` - Optional session metadata containing actual token counts -/// -/// # Returns -/// * `AutoCompactResult` containing the potentially compacted messages and metadata -pub async fn check_and_compact_messages( - agent: &Agent, - messages: &[Message], - threshold_override: Option, - session_metadata: Option<&crate::session::Session>, -) -> Result { - // First check if compaction is needed - let check_result = - check_compaction_needed(agent, messages, threshold_override, session_metadata).await?; - - // If no compaction is needed, return early - if !check_result.needs_compaction { - debug!( - "No compaction needed (usage: {:.1}% <= {:.1}% threshold)", - check_result.usage_ratio * 100.0, - check_result.percentage_until_compaction - ); - return Ok(AutoCompactResult { - compacted: false, - messages: Conversation::new_unvalidated(messages.to_vec()), - summarization_usage: None, - }); - } - - info!( - "Auto-compacting messages (usage: {:.1}%)", - check_result.usage_ratio * 100.0 - ); - - perform_compaction(agent, messages).await -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::conversation::message::{Message, MessageContent}; - use crate::session::extension_data; - use crate::{ - agents::Agent, - model::ModelConfig, - providers::base::{Provider, ProviderMetadata, ProviderUsage, Usage}, - providers::errors::ProviderError, - }; - use chrono::Utc; - use rmcp::model::{AnnotateAble, RawTextContent, Role, Tool}; - use std::sync::Arc; - - #[derive(Clone)] - struct MockProvider { - model_config: ModelConfig, - } - - #[async_trait::async_trait] - impl Provider for MockProvider { - fn metadata() -> ProviderMetadata { - ProviderMetadata::empty() - } - - fn get_model_config(&self) -> ModelConfig { - self.model_config.clone() - } - - async fn complete_with_model( - &self, - _model_config: &ModelConfig, - _system: &str, - _messages: &[Message], - _tools: &[Tool], - ) -> Result<(Message, ProviderUsage), ProviderError> { - // Return a short summary message - Ok(( - Message::new( - Role::Assistant, - Utc::now().timestamp(), - vec![MessageContent::Text( - RawTextContent { - text: "Summary of conversation".to_string(), - meta: None, - } - .no_annotation(), - )], - ), - ProviderUsage::new("mock".to_string(), Usage::default()), - )) - } - } - - fn create_test_message(text: &str) -> Message { - Message::new( - Role::User, - Utc::now().timestamp(), - vec![MessageContent::text(text.to_string())], - ) - } - - fn create_test_session_metadata( - message_count: usize, - working_dir: &str, - ) -> crate::session::Session { - use crate::conversation::Conversation; - use std::path::PathBuf; - - let mut conversation = Conversation::default(); - for i in 0..message_count { - conversation.push(create_test_message(format!("message {}", i).as_str())); - } - - crate::session::Session { - id: "test_session".to_string(), - working_dir: PathBuf::from(working_dir), - description: "Test session".to_string(), - created_at: Default::default(), - updated_at: Default::default(), - schedule_id: Some("test_job".to_string()), - recipe: None, - total_tokens: Some(100), - input_tokens: Some(50), - output_tokens: Some(50), - accumulated_total_tokens: Some(100), - accumulated_input_tokens: Some(50), - accumulated_output_tokens: Some(50), - extension_data: extension_data::ExtensionData::new(), - conversation: Some(conversation), - message_count, - user_recipe_values: None, - } - } - - #[tokio::test] - async fn test_check_compaction_needed() { - let mock_provider = Arc::new(MockProvider { - model_config: ModelConfig::new("test-model") - .unwrap() - .with_context_limit(Some(100_000)), - }); - - let agent = Agent::new(); - let _ = agent.update_provider(mock_provider).await; - - // Create small messages that won't trigger compaction - let messages = vec![create_test_message("Hello"), create_test_message("World")]; - - let result = check_compaction_needed(&agent, &messages, Some(0.3), None) - .await - .unwrap(); - - assert!(!result.needs_compaction); - assert!(result.current_tokens > 0); - assert!(result.context_limit > 0); - assert!(result.usage_ratio < 0.3); - assert!(result.remaining_tokens > 0); - assert!(result.percentage_until_compaction > 0.0); - } - - #[tokio::test] - async fn test_check_compaction_needed_disabled() { - let mock_provider = Arc::new(MockProvider { - model_config: ModelConfig::new("test-model") - .unwrap() - .with_context_limit(Some(100_000)), - }); - - let agent = Agent::new(); - let _ = agent.update_provider(mock_provider).await; - - let messages = vec![create_test_message("Hello")]; - - // Test with threshold 0 (disabled) - let result = check_compaction_needed(&agent, &messages, Some(0.0), None) - .await - .unwrap(); - - assert!(!result.needs_compaction); - - // Test with threshold 1.0 (disabled) - let result = check_compaction_needed(&agent, &messages, Some(1.0), None) - .await - .unwrap(); - - assert!(!result.needs_compaction); - } - - #[tokio::test] - async fn test_auto_compact_disabled() { - let mock_provider = Arc::new(MockProvider { - model_config: ModelConfig::new("test-model") - .unwrap() - .with_context_limit(Some(10_000)), - }); - - let agent = Agent::new(); - let _ = agent.update_provider(mock_provider).await; - - let messages = vec![create_test_message("Hello"), create_test_message("World")]; - - // Test with threshold 0 (disabled) - let result = check_and_compact_messages(&agent, &messages, Some(0.0), None) - .await - .unwrap(); - - assert!(!result.compacted); - assert_eq!(result.messages.len(), messages.len()); - assert!(result.summarization_usage.is_none()); - - // Test with threshold 1.0 (disabled) - let result = check_and_compact_messages(&agent, &messages, Some(1.0), None) - .await - .unwrap(); - - assert!(!result.compacted); - } - - #[tokio::test] - async fn test_auto_compact_below_threshold() { - let mock_provider = Arc::new(MockProvider { - model_config: ModelConfig::new("test-model") - .unwrap() - .with_context_limit(Some(100_000)), // Increased to ensure overhead doesn't dominate - }); - - let agent = Agent::new(); - let _ = agent.update_provider(mock_provider).await; - - // Create small messages that won't trigger compaction - let messages = vec![create_test_message("Hello"), create_test_message("World")]; - - let result = check_and_compact_messages(&agent, &messages, Some(0.3), None) - .await - .unwrap(); - - assert!(!result.compacted); - assert_eq!(result.messages.len(), messages.len()); - } - - #[tokio::test] - async fn test_auto_compact_above_threshold() { - let mock_provider = Arc::new(MockProvider { - model_config: ModelConfig::new("test-model") - .unwrap() - .with_context_limit(30_000.into()), // Smaller context limit to make threshold easier to hit - }); - - let agent = Agent::new(); - let _ = agent.update_provider(mock_provider).await; - - // Create messages that will exceed 30% of the context limit - // With 30k context limit, 30% is 9k tokens - let mut messages = Vec::new(); - - // Create much longer messages with more content to reach the threshold - for i in 0..300 { - messages.push(create_test_message(&format!( - "This is message number {} with significantly more content to increase token count substantially. \ - We need to ensure that our total token usage exceeds 30% of the available context \ - limit after accounting for system prompt and tools overhead. This message contains \ - multiple sentences to increase the token count substantially. Adding even more text here \ - to make sure we have enough tokens. Lorem ipsum dolor sit amet, consectetur adipiscing elit, \ - sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, \ - quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \ - irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. \ - Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit \ - anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium \ - doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi \ - architecto beatae vitae dicta sunt explicabo.", - i - ))); - } - - let result = check_and_compact_messages(&agent, &messages, Some(0.3), None) - .await - .unwrap(); - - if !result.compacted { - eprintln!("Test failed - compaction not triggered"); - } - - assert!(result.compacted); - assert!(result.summarization_usage.is_some()); - - // Verify that summarization usage contains token counts - if let Some(usage) = &result.summarization_usage { - assert!(usage.usage.total_tokens.is_some()); - let after = usage.usage.total_tokens.unwrap_or(0) as usize; - assert!( - after > 0, - "Token count after compaction should be greater than 0" - ); - } - - // After visibility implementation, we keep all messages plus summary - // Original messages become user_visible only, summary becomes agent_visible only - assert!(result.messages.len() > messages.len()); - } - - #[tokio::test] - async fn test_auto_compact_respects_config() { - let mock_provider = Arc::new(MockProvider { - model_config: ModelConfig::new("test-model") - .unwrap() - .with_context_limit(Some(30_000)), // Smaller context limit to make threshold easier to hit - }); - - let agent = Agent::new(); - let _ = agent.update_provider(mock_provider).await; - - // Create enough messages to trigger compaction with low threshold - let mut messages = Vec::new(); - // With 30k context limit, after overhead we have ~27k usable tokens - // 10% of 27k = 2.7k tokens, so we need messages that exceed that - for i in 0..200 { - messages.push(create_test_message(&format!( - "Message {} with enough content to ensure we exceed 10% of the context limit. \ - Adding more content to increase token count substantially. This message contains \ - multiple sentences to increase the token count. We need to ensure that our total \ - token usage exceeds 10% of the available context limit after accounting for \ - system prompt and tools overhead.", - i - ))); - } - - // Set config value - let config = Config::global(); - config - .set_param("GOOSE_AUTO_COMPACT_THRESHOLD", serde_json::Value::from(0.1)) - .unwrap(); - - // Should use config value when no override provided - let result = check_and_compact_messages(&agent, &messages, None, None) - .await - .unwrap(); - - // Debug info if not compacted - if !result.compacted { - eprintln!("Test failed - compaction not triggered"); - } - - // With such a low threshold (10%), it should compact - assert!(result.compacted); - - // Clean up config - config - .set_param("GOOSE_AUTO_COMPACT_THRESHOLD", serde_json::Value::from(0.3)) - .unwrap(); - } - - #[tokio::test] - async fn test_auto_compact_uses_session_metadata() { - use crate::session::Session; - - let mock_provider = Arc::new(MockProvider { - model_config: ModelConfig::new("test-model") - .unwrap() - .with_context_limit(10_000.into()), - }); - - let agent = Agent::new(); - let _ = agent.update_provider(mock_provider).await; - - // Create some test messages - let messages = vec![ - create_test_message("First message"), - create_test_message("Second message"), - ]; - - // Create session with specific token counts - #[allow(clippy::field_reassign_with_default)] - let mut session = Session::default(); - { - session.total_tokens = Some(8000); // High token count to trigger compaction - session.accumulated_total_tokens = Some(15000); // Even higher accumulated count - session.input_tokens = Some(5000); - session.output_tokens = Some(3000); - } - - // Test with session - should use total_tokens for compaction (not accumulated) - let result_with_metadata = check_compaction_needed( - &agent, - &messages, - Some(0.3), // 30% threshold - Some(&session), - ) - .await - .unwrap(); - - // With 8000 tokens and context limit around 10000, should trigger compaction - assert!(result_with_metadata.needs_compaction); - assert_eq!(result_with_metadata.current_tokens, 8000); - - // Test without session metadata - should use estimated tokens - let result_without_metadata = check_compaction_needed( - &agent, - &messages, - Some(0.3), // 30% threshold - None, - ) - .await - .unwrap(); - - // Without metadata, should use much lower estimated token count - assert!(!result_without_metadata.needs_compaction); - assert!(result_without_metadata.current_tokens < 8000); - - // Test with session that has only accumulated tokens (no total_tokens) - let mut session_metadata_no_total = Session::default(); - #[allow(clippy::field_reassign_with_default)] - { - session_metadata_no_total.accumulated_total_tokens = Some(7500); - } - - let result_with_no_total = check_compaction_needed( - &agent, - &messages, - Some(0.3), // 30% threshold - Some(&session_metadata_no_total), - ) - .await - .unwrap(); - - // Should fall back to estimation since total_tokens is None - assert!(!result_with_no_total.needs_compaction); - assert!(result_with_no_total.current_tokens < 7500); - - // Test with metadata that has no token counts - should fall back to estimation - let empty_metadata = Session::default(); - - let result_with_empty_metadata = check_compaction_needed( - &agent, - &messages, - Some(0.3), // 30% threshold - Some(&empty_metadata), - ) - .await - .unwrap(); - - // Should fall back to estimation - assert!(!result_with_empty_metadata.needs_compaction); - assert!(result_with_empty_metadata.current_tokens < 7500); - } - - #[tokio::test] - async fn test_auto_compact_end_to_end_with_metadata() { - use crate::session::Session; - - let mock_provider = Arc::new(MockProvider { - model_config: ModelConfig::new("test-model") - .unwrap() - .with_context_limit(10_000.into()), - }); - - let agent = Agent::new(); - let _ = agent.update_provider(mock_provider).await; - - // Create some test messages - let messages = vec![ - create_test_message("First message"), - create_test_message("Second message"), - create_test_message("Third message"), - create_test_message("Fourth message"), - create_test_message("Fifth message"), - ]; - - // Create session metadata with high token count to trigger compaction - let mut session = Session::default(); - #[allow(clippy::field_reassign_with_default)] - { - session.total_tokens = Some(9000); // High enough to trigger compaction - } - - // Test full compaction flow with session metadata - let result = check_and_compact_messages( - &agent, - &messages, - Some(0.3), // 30% threshold - Some(&session), - ) - .await - .unwrap(); - - // Should have triggered compaction - assert!(result.compacted); - assert!(result.summarization_usage.is_some()); - - // Verify the compacted messages are returned - assert!(!result.messages.is_empty()); - - // After visibility implementation, we keep all messages plus summary - // Original messages become user_visible only, summary becomes agent_visible only - assert!(result.messages.len() > messages.len()); - } - - #[tokio::test] - async fn test_auto_compact_with_comprehensive_session_metadata() { - let mock_provider = Arc::new(MockProvider { - model_config: ModelConfig::new("test-model") - .unwrap() - .with_context_limit(8_000.into()), - }); - - let agent = Agent::new(); - let _ = agent.update_provider(mock_provider).await; - - let messages = vec![ - create_test_message("Test message 1"), - create_test_message("Test message 2"), - create_test_message("Test message 3"), - ]; - - // Use the helper function to create comprehensive non-null session metadata - let comprehensive_metadata = create_test_session_metadata(3, "/test/working/dir"); - - // Verify the helper created non-null metadata - assert_eq!( - comprehensive_metadata - .clone() - .conversation - .unwrap_or_default() - .len(), - 3 - ); - assert_eq!( - comprehensive_metadata.working_dir.to_str().unwrap(), - "/test/working/dir" - ); - assert_eq!(comprehensive_metadata.description, "Test session"); - assert_eq!( - comprehensive_metadata.schedule_id, - Some("test_job".to_string()) - ); - assert_eq!(comprehensive_metadata.total_tokens, Some(100)); - assert_eq!(comprehensive_metadata.input_tokens, Some(50)); - assert_eq!(comprehensive_metadata.output_tokens, Some(50)); - assert_eq!(comprehensive_metadata.accumulated_total_tokens, Some(100)); - assert_eq!(comprehensive_metadata.accumulated_input_tokens, Some(50)); - assert_eq!(comprehensive_metadata.accumulated_output_tokens, Some(50)); - - // Test compaction with the comprehensive metadata (low token count, shouldn't compact) - let result_low_tokens = check_compaction_needed( - &agent, - &messages, - Some(0.7), // 70% threshold - Some(&comprehensive_metadata), - ) - .await - .unwrap(); - - assert!(!result_low_tokens.needs_compaction); - assert_eq!(result_low_tokens.current_tokens, 100); // Should use total_tokens from metadata - - // Create a modified version with high token count to trigger compaction - let mut high_token_metadata = create_test_session_metadata(5, "/test/working/dir"); - high_token_metadata.total_tokens = Some(6_000); // High enough to trigger compaction - high_token_metadata.input_tokens = Some(4_000); - high_token_metadata.output_tokens = Some(2_000); - high_token_metadata.accumulated_total_tokens = Some(12_000); - - let result_high_tokens = check_compaction_needed( - &agent, - &messages, - Some(0.7), // 70% threshold - Some(&high_token_metadata), - ) - .await - .unwrap(); - - assert!(result_high_tokens.needs_compaction); - assert_eq!(result_high_tokens.current_tokens, 6_000); // Should use total_tokens, not accumulated - - // Test that metadata fields are preserved correctly in edge cases - let mut edge_case_metadata = create_test_session_metadata(10, "/edge/case/dir"); - edge_case_metadata.total_tokens = None; // No total tokens - edge_case_metadata.accumulated_total_tokens = Some(7_000); // Has accumulated - - let result_edge_case = check_compaction_needed( - &agent, - &messages, - Some(0.5), // 50% threshold - Some(&edge_case_metadata), - ) - .await - .unwrap(); - - // Should fall back to estimation since total_tokens is None - assert!(result_edge_case.current_tokens < 7_000); - // With estimation, likely won't trigger compaction - assert!(!result_edge_case.needs_compaction); - } -} diff --git a/crates/goose/src/context_mgmt/common.rs b/crates/goose/src/context_mgmt/common.rs deleted file mode 100644 index 106f8a28b8b3..000000000000 --- a/crates/goose/src/context_mgmt/common.rs +++ /dev/null @@ -1,99 +0,0 @@ -use std::sync::Arc; - -use rmcp::model::Tool; - -use crate::conversation::message::Message; -use crate::{ - providers::base::Provider, - token_counter::{AsyncTokenCounter, TokenCounter}, -}; - -const ESTIMATE_FACTOR: f32 = 0.7; -pub const SYSTEM_PROMPT_TOKEN_OVERHEAD: usize = 3_000; -pub const TOOLS_TOKEN_OVERHEAD: usize = 5_000; - -pub fn estimate_target_context_limit(provider: Arc) -> usize { - let model_context_limit = provider.get_model_config().context_limit(); - - // Our conservative estimate of the **target** context limit - // Our token count is an estimate since model providers often don't provide the tokenizer (eg. Claude) - let target_limit = (model_context_limit as f32 * ESTIMATE_FACTOR) as usize; - - // subtract out overhead for system prompt and tools, but ensure we don't go negative - let overhead = SYSTEM_PROMPT_TOKEN_OVERHEAD + TOOLS_TOKEN_OVERHEAD; - if target_limit > overhead { - target_limit - overhead - } else { - // If overhead is larger than target limit, return a minimal usable limit - std::cmp::max(target_limit / 2, 1000) - } -} - -pub fn get_messages_token_counts(token_counter: &TokenCounter, messages: &[Message]) -> Vec { - // Calculate current token count of each message, use count_chat_tokens to ensure we - // capture the full content of the message, include ToolRequests and ToolResponses - messages - .iter() - .map(|msg| token_counter.count_chat_tokens("", std::slice::from_ref(msg), &[])) - .collect() -} - -/// Async version of get_messages_token_counts for better performance -pub fn get_messages_token_counts_async( - token_counter: &AsyncTokenCounter, - messages: &[Message], -) -> Vec { - messages - .iter() - .filter(|m| m.is_agent_visible()) - .map(|msg| token_counter.count_chat_tokens("", std::slice::from_ref(msg), &[])) - .collect() -} - -// These are not being used now but could be useful in the future - -#[allow(dead_code)] -pub struct ChatTokenCounts { - pub system: usize, - pub tools: usize, - pub messages: Vec, -} - -#[allow(dead_code)] -pub fn get_token_counts( - token_counter: &TokenCounter, - messages: &mut [Message], - system_prompt: &str, - tools: &mut Vec, -) -> ChatTokenCounts { - // Take into account the system prompt (includes goosehints), and our tools input - let system_prompt_token_count = token_counter.count_tokens(system_prompt); - let tools_token_count = token_counter.count_tokens_for_tools(tools.as_slice()); - let messages_token_count = get_messages_token_counts(token_counter, messages); - - ChatTokenCounts { - system: system_prompt_token_count, - tools: tools_token_count, - messages: messages_token_count, - } -} - -/// Async version of get_token_counts for better performance -#[allow(dead_code)] -pub fn get_token_counts_async( - token_counter: &AsyncTokenCounter, - messages: &mut [Message], - system_prompt: &str, - tools: &mut Vec, -) -> ChatTokenCounts { - // Take into account the system prompt (includes goosehints), and our tools input - let system_prompt_token_count = token_counter.count_tokens(system_prompt); - let tools_token_count = token_counter.count_tokens_for_tools(tools.as_slice()); - let messages_token_count = get_messages_token_counts_async(token_counter, messages); - - ChatTokenCounts { - system: system_prompt_token_count, - tools: tools_token_count, - messages: messages_token_count, - } -} diff --git a/crates/goose/src/context_mgmt/mod.rs b/crates/goose/src/context_mgmt/mod.rs index 00d11d6b871b..41de720a1c11 100644 --- a/crates/goose/src/context_mgmt/mod.rs +++ b/crates/goose/src/context_mgmt/mod.rs @@ -1,6 +1,338 @@ -pub mod auto_compact; -mod common; -pub mod summarize; -pub mod truncate; +use crate::conversation::message::Message; +use crate::conversation::message::MessageMetadata; +use crate::conversation::Conversation; +use crate::prompt_template::render_global_file; +use crate::providers::base::{Provider, ProviderUsage}; +use crate::{agents::Agent, config::Config, token_counter::create_token_counter}; +use anyhow::Result; +use rmcp::model::Role; +use serde::Serialize; +use std::sync::Arc; +use tracing::{debug, info}; -pub use common::*; +pub const DEFAULT_COMPACTION_THRESHOLD: f64 = 0.8; + +/// Result of auto-compaction check +#[derive(Debug)] +pub struct AutoCompactResult { + /// Whether compaction was performed + pub compacted: bool, + /// The messages after potential compaction + pub messages: Conversation, + /// Provider usage from summarization (if compaction occurred) + /// This contains the actual token counts after compaction + pub summarization_usage: Option, +} + +/// Result of checking if compaction is needed +#[derive(Debug)] +pub struct CompactionCheckResult { + /// Whether compaction is needed + pub needs_compaction: bool, + /// Current token count + pub current_tokens: usize, + /// Context limit being used + pub context_limit: usize, + /// Current usage ratio (0.0 to 1.0) + pub usage_ratio: f64, + /// Remaining tokens before compaction threshold + pub remaining_tokens: usize, + /// Percentage until compaction threshold (0.0 to 100.0) + pub percentage_until_compaction: f64, +} + +#[derive(Serialize)] +struct SummarizeContext { + messages: String, +} + +/// Check if messages need compaction and compact them if necessary +/// +/// This function combines checking and compaction. It first checks if compaction +/// is needed based on the threshold, and if so, performs the compaction by +/// summarizing messages and updating their visibility metadata. +/// +/// # Arguments +/// * `agent` - The agent to use for context management +/// * `messages` - The current message history +/// * `force_compact` - If true, skip the threshold check and force compaction +/// * `preserve_last_user_message` - If true and last message is not a user message, copy the most recent user message to the end +/// * `threshold_override` - Optional threshold override (defaults to GOOSE_AUTO_COMPACT_THRESHOLD config) +/// * `session_metadata` - Optional session metadata containing actual token counts +/// +/// # Returns +/// * A tuple containing: +/// - `bool`: Whether compaction was performed +/// - `Conversation`: The potentially compacted messages +/// - `Vec`: Indices of removed messages (empty if no compaction) +/// - `Option`: Provider usage from summarization (if compaction occurred) +pub async fn check_and_compact_messages( + agent: &Agent, + messages_with_user_message: &[Message], + force_compact: bool, + preserve_last_user_message: bool, + threshold_override: Option, + session_metadata: Option<&crate::session::Session>, +) -> std::result::Result<(bool, Conversation, Vec, Option), anyhow::Error> { + // Check if compaction is needed (unless forced) + if !force_compact { + let check_result = check_compaction_needed( + agent, + messages_with_user_message, + threshold_override, + session_metadata, + ) + .await?; + + // If no compaction is needed, return early + if !check_result.needs_compaction { + debug!( + "No compaction needed (usage: {:.1}% <= {:.1}% threshold)", + check_result.usage_ratio * 100.0, + check_result.percentage_until_compaction + ); + return Ok(( + false, + Conversation::new_unvalidated(messages_with_user_message.to_vec()), + Vec::new(), + None, + )); + } + + info!( + "Performing message compaction (usage: {:.1}%)", + check_result.usage_ratio * 100.0 + ); + } else { + info!("Forcing message compaction due to context limit exceeded"); + } + + // Perform the actual compaction + // Check if the most recent message is a user message + let (messages, preserved_user_message) = + if let Some(last_message) = messages_with_user_message.last() { + if matches!(last_message.role, rmcp::model::Role::User) { + // Remove the last user message before compaction + ( + &messages_with_user_message[..messages_with_user_message.len() - 1], + Some(last_message.clone()), + ) + } else if preserve_last_user_message { + // Last message is not a user message, but we want to preserve the most recent user message + // Find the most recent user message and copy it (don't remove from history) + let most_recent_user_message = messages_with_user_message + .iter() + .rev() + .find(|msg| matches!(msg.role, rmcp::model::Role::User)) + .cloned(); + (messages_with_user_message, most_recent_user_message) + } else { + (messages_with_user_message, None) + } + } else { + (messages_with_user_message, None) + }; + + let provider = agent.provider().await?; + let summary = summarize(provider.clone(), messages).await?; + + let (summary_message, summarization_usage) = match summary { + Some((summary_message, provider_usage)) => (summary_message, Some(provider_usage)), + None => { + // No summary was generated (empty input) + tracing::warn!("Summarization failed. Returning empty messages."); + return Ok((false, Conversation::empty(), vec![], None)); + } + }; + + // Create the final message list with updated visibility metadata: + // 1. Original messages become user_visible but not agent_visible + // 2. Summary message becomes agent_visible but not user_visible + // 3. Assistant messages to continue the conversation remain both user_visible and agent_visible + + let mut final_messages = Vec::new(); + let mut final_token_counts = Vec::new(); + + // Add all original messages with updated visibility (preserve user_visible, set agent_visible=false) + for msg in messages.iter().cloned() { + let updated_metadata = msg.metadata.with_agent_invisible(); + let updated_msg = msg.with_metadata(updated_metadata); + final_messages.push(updated_msg); + // Token count doesn't matter for agent_visible=false messages, but we'll use 0 + final_token_counts.push(0); + } + + // Add the compaction marker (user_visible=true, agent_visible=false) + let compaction_marker = Message::assistant() + .with_conversation_compacted("Conversation compacted and summarized") + .with_metadata(MessageMetadata::user_only()); + let compaction_marker_tokens: usize = 0; // Not counted since agent_visible=false + final_messages.push(compaction_marker); + final_token_counts.push(compaction_marker_tokens); + + // Add the summary message (agent_visible=true, user_visible=false) + let summary_msg = summary_message.with_metadata(MessageMetadata::agent_only()); + // For token counting purposes, we use the output tokens (the actual summary content) + // since that's what will be in the context going forward + let summary_tokens = summarization_usage + .as_ref() + .and_then(|usage| usage.usage.output_tokens) + .unwrap_or(0) as usize; + final_messages.push(summary_msg); + final_token_counts.push(summary_tokens); + + // Add an assistant message to continue the conversation (agent_visible=true, user_visible=false) + let assistant_message = Message::assistant() + .with_text( + "The previous message contains a summary that was prepared because a context limit was reached. +Do not mention that you read a summary or that conversation summarization occurred +Just continue the conversation naturally based on the summarized context" + ) + .with_metadata(MessageMetadata::agent_only()); + let assistant_message_tokens: usize = 0; // Not counted since it's for agent context only + final_messages.push(assistant_message); + final_token_counts.push(assistant_message_tokens); + + // Add back the preserved user message if it exists + if let Some(user_message) = preserved_user_message { + final_messages.push(user_message); + } + + Ok(( + true, + Conversation::new_unvalidated(final_messages), + final_token_counts, + summarization_usage, + )) +} + +/// Check if messages need compaction without performing the compaction +/// +/// This function analyzes the current token usage and returns detailed information +/// about whether compaction is needed and how close we are to the threshold. +/// It prioritizes actual token counts from session metadata when available, +/// falling back to estimated counts if needed. +/// +/// # Arguments +/// * `agent` - The agent to use for context management +/// * `messages` - The current message history +/// * `threshold_override` - Optional threshold override (defaults to GOOSE_AUTO_COMPACT_THRESHOLD config) +/// * `session_metadata` - Optional session metadata containing actual token counts +/// +/// # Returns +/// * `CompactionCheckResult` containing detailed information about compaction needs +async fn check_compaction_needed( + agent: &Agent, + messages: &[Message], + threshold_override: Option, + session_metadata: Option<&crate::session::Session>, +) -> Result { + // Get threshold from config or use override + let config = Config::global(); + // TODO(Douwe): check the default here; it seems to reset to 0.3 sometimes + let threshold = threshold_override.unwrap_or_else(|| { + config + .get_param::("GOOSE_AUTO_COMPACT_THRESHOLD") + .unwrap_or(DEFAULT_COMPACTION_THRESHOLD) + }); + + let provider = agent.provider().await?; + let context_limit = provider.get_model_config().context_limit(); + + let (current_tokens, token_source) = match session_metadata.and_then(|m| m.total_tokens) { + Some(tokens) => (tokens as usize, "session metadata"), + None => { + let token_counter = create_token_counter() + .await + .map_err(|e| anyhow::anyhow!("Failed to create token counter: {}", e))?; + + let token_counts: Vec<_> = messages + .iter() + .filter(|m| m.is_agent_visible()) + .map(|msg| token_counter.count_chat_tokens("", std::slice::from_ref(msg), &[])) + .collect(); + + (token_counts.iter().sum(), "estimated") + } + }; + + let usage_ratio = current_tokens as f64 / context_limit as f64; + + let threshold_tokens = (context_limit as f64 * threshold) as usize; + let remaining_tokens = threshold_tokens.saturating_sub(current_tokens); + + let percentage_until_compaction = if usage_ratio < threshold { + (threshold - usage_ratio) * 100.0 + } else { + 0.0 + }; + + let needs_compaction = if threshold <= 0.0 || threshold >= 1.0 { + usage_ratio > DEFAULT_COMPACTION_THRESHOLD + } else { + usage_ratio > threshold + }; + + debug!( + "Compaction check: {} / {} tokens ({:.1}%), threshold: {:.1}%, needs compaction: {}, source: {}", + current_tokens, + context_limit, + usage_ratio * 100.0, + threshold * 100.0, + needs_compaction, + token_source + ); + + Ok(CompactionCheckResult { + needs_compaction, + current_tokens, + context_limit, + usage_ratio, + remaining_tokens, + percentage_until_compaction, + }) +} + +async fn summarize( + provider: Arc, + messages: &[Message], +) -> anyhow::Result, anyhow::Error> { + if messages.is_empty() { + return std::prelude::rust_2015::Ok(None); + } + + // Format all messages as a single string for the summarization prompt + let messages_text = messages + .iter() + .map(|msg| format!("{:?}", msg)) + .collect::>() + .join("\n\n"); + + let context = SummarizeContext { + messages: messages_text, + }; + + // Render the one-shot summarization prompt + let system_prompt = render_global_file("summarize_oneshot.md", &context)?; + + // Create a simple user message requesting summarization + let user_message = Message::user() + .with_text("Please summarize the conversation history provided in the system prompt."); + let summarization_request = vec![user_message]; + + // Send the request to the provider and fetch the response + let (mut response, mut provider_usage) = provider + .complete_fast(&system_prompt, &summarization_request, &[]) + .await?; + + // Set role to user as it will be used in following conversation as user content + response.role = Role::User; + + // Ensure we have token counts, estimating if necessary + provider_usage + .ensure_tokens(&system_prompt, &summarization_request, &response, &[]) + .await + .map_err(|e| anyhow::anyhow!("Failed to ensure usage tokens: {}", e))?; + + std::prelude::rust_2015::Ok(Some((response, provider_usage))) +} diff --git a/crates/goose/src/context_mgmt/summarize.rs b/crates/goose/src/context_mgmt/summarize.rs deleted file mode 100644 index 35e5aef8e293..000000000000 --- a/crates/goose/src/context_mgmt/summarize.rs +++ /dev/null @@ -1,187 +0,0 @@ -use crate::conversation::message::Message; -use crate::prompt_template::render_global_file; -use crate::providers::base::Provider; - -use anyhow::Result; -use rmcp::model::Role; -use serde::Serialize; -use std::sync::Arc; - -#[derive(Serialize)] -struct SummarizeContext { - messages: String, -} - -use crate::providers::base::ProviderUsage; - -/// Summarization function that uses the detailed prompt from the markdown template -pub async fn summarize_messages( - provider: Arc, - messages: &[Message], -) -> Result, anyhow::Error> { - if messages.is_empty() { - return Ok(None); - } - - // Format all messages as a single string for the summarization prompt - let messages_text = messages - .iter() - .map(|msg| format!("{:?}", msg)) - .collect::>() - .join("\n\n"); - - let context = SummarizeContext { - messages: messages_text, - }; - - // Render the one-shot summarization prompt - let system_prompt = render_global_file("summarize_oneshot.md", &context)?; - - // Create a simple user message requesting summarization - let user_message = Message::user() - .with_text("Please summarize the conversation history provided in the system prompt."); - let summarization_request = vec![user_message]; - - // Send the request to the provider and fetch the response - let (mut response, mut provider_usage) = provider - .complete_fast(&system_prompt, &summarization_request, &[]) - .await?; - - // Set role to user as it will be used in following conversation as user content - response.role = Role::User; - - // Ensure we have token counts, estimating if necessary - provider_usage - .ensure_tokens(&system_prompt, &summarization_request, &response, &[]) - .await - .map_err(|e| anyhow::anyhow!("Failed to ensure usage tokens: {}", e))?; - - Ok(Some((response, provider_usage))) -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::conversation::message::{Message, MessageContent}; - use crate::model::ModelConfig; - use crate::providers::base::{ProviderMetadata, ProviderUsage, Usage}; - use crate::providers::errors::ProviderError; - use chrono::Utc; - use rmcp::model::Role; - use rmcp::model::Tool; - use rmcp::model::{AnnotateAble, RawTextContent}; - use std::sync::Arc; - - #[derive(Clone)] - struct MockProvider { - model_config: ModelConfig, - } - - #[async_trait::async_trait] - impl Provider for MockProvider { - fn metadata() -> ProviderMetadata { - ProviderMetadata::empty() - } - - fn get_model_config(&self) -> ModelConfig { - self.model_config.clone() - } - - async fn complete_with_model( - &self, - _model_config: &ModelConfig, - _system: &str, - _messages: &[Message], - _tools: &[Tool], - ) -> Result<(Message, ProviderUsage), ProviderError> { - Ok(( - Message::new( - Role::Assistant, - Utc::now().timestamp(), - vec![MessageContent::Text( - RawTextContent { - text: "Summarized content".to_string(), - meta: None, - } - .no_annotation(), - )], - ), - ProviderUsage::new( - "mock".to_string(), - Usage { - input_tokens: Some(100), - output_tokens: Some(50), - total_tokens: Some(150), - }, - ), - )) - } - } - - fn create_mock_provider() -> Result> { - let mock_model_config = ModelConfig::new("test-model")?.with_context_limit(Some(200_000)); - - Ok(Arc::new(MockProvider { - model_config: mock_model_config, - })) - } - - fn create_test_messages() -> Vec { - vec![ - set_up_text_message("Message 1", Role::User), - set_up_text_message("Message 2", Role::Assistant), - set_up_text_message("Message 3", Role::User), - ] - } - - fn set_up_text_message(text: &str, role: Role) -> Message { - Message::new(role, 0, vec![MessageContent::text(text.to_string())]) - } - - #[tokio::test] - async fn test_summarize_messages_basic() { - let provider = create_mock_provider().expect("failed to create mock provider"); - let messages = create_test_messages(); - - let result = summarize_messages(Arc::clone(&provider), &messages).await; - - assert!(result.is_ok(), "The function should return Ok."); - let summary_result = result.unwrap(); - - assert!( - summary_result.is_some(), - "The summary should contain a result." - ); - let (summarized_message, provider_usage) = summary_result.unwrap(); - - assert_eq!( - summarized_message.role, - Role::User, - "The summarized message should be from the user." - ); - assert!( - provider_usage.usage.input_tokens.unwrap_or(0) > 0, - "Should have input token count" - ); - assert!( - provider_usage.usage.output_tokens.unwrap_or(0) > 0, - "Should have output token count" - ); - } - - #[tokio::test] - async fn test_summarize_messages_empty_input() { - let provider = create_mock_provider().expect("failed to create mock provider"); - let messages: Vec = Vec::new(); - - let result = summarize_messages(Arc::clone(&provider), &messages).await; - - assert!(result.is_ok(), "The function should return Ok."); - let summary_result = result.unwrap(); - - assert!( - summary_result.is_none(), - "The summary should be None for empty input." - ); - } -} diff --git a/crates/goose/src/context_mgmt/truncate.rs b/crates/goose/src/context_mgmt/truncate.rs deleted file mode 100644 index b6f74c597225..000000000000 --- a/crates/goose/src/context_mgmt/truncate.rs +++ /dev/null @@ -1,749 +0,0 @@ -use crate::conversation::message::{Message, MessageContent}; -use crate::conversation::Conversation; -use crate::utils::safe_truncate; -use anyhow::{anyhow, Result}; -use rmcp::model::{RawContent, ResourceContents, Role}; -use std::collections::HashSet; -use std::ops::DerefMut; -use tracing::{debug, warn}; - -/// Maximum size for truncated content in characters -const MAX_TRUNCATED_CONTENT_SIZE: usize = 5000; - -/// Handles messages that are individually larger than the context limit -/// by truncating their content rather than removing them entirely -fn handle_oversized_messages( - messages: &[Message], - token_counts: &[usize], - context_limit: usize, - strategy: &dyn TruncationStrategy, -) -> Result<(Conversation, Vec), anyhow::Error> { - let mut truncated_messages = Vec::new(); - let mut truncated_token_counts = Vec::new(); - let mut any_truncated = false; - - // Create a basic token counter for re-estimating truncated content - // Note: This is a rough approximation since we don't have access to the actual tokenizer here - let estimate_tokens = |text: &str| -> usize { - // Rough approximation: 1 token per 4 characters for English text - (text.len() / 4).max(1) - }; - - for (i, (message, &original_tokens)) in messages.iter().zip(token_counts.iter()).enumerate() { - if original_tokens > context_limit { - warn!( - "Message {} has {} tokens, exceeding context limit of {}", - i, original_tokens, context_limit - ); - - // Try to truncate the message content - let truncated_message = truncate_message_content(message, MAX_TRUNCATED_CONTENT_SIZE)?; - let estimated_new_tokens = - estimate_message_tokens(&truncated_message, &estimate_tokens); - - if estimated_new_tokens > context_limit { - // Even truncated message is too large, skip it entirely - warn!("Skipping message {} as even truncated version ({} tokens) exceeds context limit", i, estimated_new_tokens); - any_truncated = true; - continue; - } - - truncated_messages.push(truncated_message); - truncated_token_counts.push(estimated_new_tokens); - any_truncated = true; - } else { - truncated_messages.push(message.clone()); - truncated_token_counts.push(original_tokens); - } - } - - if any_truncated { - debug!("Truncated large message content, now attempting normal truncation"); - // After content truncation, try normal truncation if still needed - return truncate_messages( - &truncated_messages, - &truncated_token_counts, - context_limit, - strategy, - ); - } - - Ok(( - Conversation::new_unvalidated(truncated_messages), - truncated_token_counts, - )) -} - -/// Truncates the content within a message while preserving its structure -fn truncate_message_content(message: &Message, max_content_size: usize) -> Result { - let mut new_message = message.clone(); - - for content in &mut new_message.content { - match content { - MessageContent::Text(text_content) => { - if text_content.text.chars().count() > max_content_size { - let truncated = format!( - "{}\n\n[... content truncated from {} to {} characters ...]", - safe_truncate(&text_content.text, max_content_size), - text_content.text.chars().count(), - max_content_size - ); - text_content.text = truncated; - } - } - MessageContent::ToolResponse(tool_response) => { - if let Ok(ref mut result) = tool_response.tool_result { - for content_item in result { - if let RawContent::Text(ref mut text_content) = content_item.deref_mut() { - if text_content.text.chars().count() > max_content_size { - let truncated = format!( - "{}\n\n[... tool response truncated from {} to {} characters ...]", - safe_truncate(&text_content.text, max_content_size), - text_content.text.chars().count(), - max_content_size - ); - text_content.text = truncated; - } - } - // Handle Resource content which might contain large text - else if let RawContent::Resource(ref mut resource_content) = - content_item.deref_mut() - { - if let ResourceContents::TextResourceContents { text, .. } = - &mut resource_content.resource - { - if text.chars().count() > max_content_size { - let truncated = format!( - "{}\n\n[... resource content truncated from {} to {} characters ...]", - safe_truncate(text, max_content_size), - text.chars().count(), - max_content_size - ); - *text = truncated; - } - } - } - } - } - } - // Other content types are typically smaller, but we could extend this if needed - _ => {} - } - } - - Ok(new_message) -} - -/// Estimates token count for a message using a simple heuristic -fn estimate_message_tokens(message: &Message, estimate_fn: &dyn Fn(&str) -> usize) -> usize { - let mut total_tokens = 10; // Base overhead for message structure - - for content in &message.content { - match content { - MessageContent::Text(text_content) => { - total_tokens += estimate_fn(&text_content.text); - } - MessageContent::ToolResponse(tool_response) => { - if let Ok(ref result) = tool_response.tool_result { - for content_item in result { - match &content_item.raw { - RawContent::Text(text_content) => { - total_tokens += estimate_fn(&text_content.text); - } - RawContent::Resource(resource) => { - match &resource.resource { - ResourceContents::TextResourceContents { text, .. } => { - total_tokens += estimate_fn(text); - } - _ => total_tokens += 5, // Small overhead for other resource types - } - } - _ => { - total_tokens += 5; // Small overhead for other content types - } - } - } - } - } - _ => total_tokens += 5, // Small overhead for other content types - } - } - - total_tokens -} - -/// Truncates the messages to fit within the model's context window. -/// Mutates the input messages and token counts in place. -/// Returns an error if it's impossible to truncate the messages within the context limit. -/// - messages: The vector of messages in the conversation. -/// - token_counts: A parallel vector containing the token count for each message. -/// - context_limit: The maximum allowed context length in tokens. -/// - strategy: The truncation strategy to use. Only option is OldestFirstTruncation. -pub fn truncate_messages( - messages: &[Message], - token_counts: &[usize], - context_limit: usize, - strategy: &dyn TruncationStrategy, -) -> Result<(Conversation, Vec), anyhow::Error> { - let mut messages = messages.to_owned(); - let mut token_counts = token_counts.to_owned(); - - if messages.len() != token_counts.len() { - return Err(anyhow!( - "The vector for messages and token_counts must have same length" - )); - } - - // Step 1: Calculate total tokens - let mut total_tokens: usize = token_counts.iter().sum(); - debug!("Total tokens before truncation: {}", total_tokens); - - // Check if any individual message is larger than the context limit - // First, check for any message that's too large - let max_message_tokens = token_counts.iter().max().copied().unwrap_or(0); - if max_message_tokens > context_limit { - // Try to handle large messages by truncating their content - debug!( - "Found oversized message with {} tokens, attempting content truncation", - max_message_tokens - ); - return handle_oversized_messages(&messages, &token_counts, context_limit, strategy); - } - - let min_user_msg_tokens = messages - .iter() - .zip(token_counts.iter()) - .filter(|(msg, _)| msg.role == Role::User && msg.has_only_text_content()) - .map(|(_, &tokens)| tokens) - .min(); - - // If there are no valid user messages, or the smallest one is too big for the context - if min_user_msg_tokens.is_none() || min_user_msg_tokens.unwrap() > context_limit { - return Err(anyhow!( - "Not possible to truncate messages within context limit: no suitable user messages found" - )); - } - - if total_tokens <= context_limit { - return Ok(( - Conversation::new_unvalidated(messages.to_vec()), - token_counts.to_vec(), - )); // No truncation needed - } - - // Step 2: Determine indices to remove based on strategy - let indices_to_remove = - strategy.determine_indices_to_remove(&messages, &token_counts, context_limit)?; - - // Circuit breaker: if we can't remove enough messages, fail gracefully - let tokens_to_remove: usize = indices_to_remove - .iter() - .map(|&i| token_counts.get(i).copied().unwrap_or(0)) - .sum(); - - if total_tokens - tokens_to_remove > context_limit && !indices_to_remove.is_empty() { - debug!( - "Standard truncation insufficient: {} tokens remain after removing {} tokens", - total_tokens - tokens_to_remove, - tokens_to_remove - ); - // Try more aggressive truncation or content truncation - return handle_oversized_messages(&messages, &token_counts, context_limit, strategy); - } - - if indices_to_remove.is_empty() && total_tokens > context_limit { - return Err(anyhow!( - "Cannot truncate any messages: all messages may be essential or too large individually" - )); - } - - // Step 3: Remove the marked messages - // Vectorize the set and sort in reverse order to avoid shifting indices when removing - let mut indices_to_remove = indices_to_remove.iter().cloned().collect::>(); - indices_to_remove.sort_unstable_by(|a, b| b.cmp(a)); - - for &index in &indices_to_remove { - if index < messages.len() { - let _ = messages.remove(index); - let removed_tokens = token_counts.remove(index); - total_tokens -= removed_tokens; - } - } - - // Step 4: Ensure the last message is a user message with TextContent only - while let Some(last_msg) = messages.last() { - if last_msg.role != Role::User || !last_msg.has_only_text_content() { - let _ = messages.pop().ok_or(anyhow!("Failed to pop message"))?; - let removed_tokens = token_counts - .pop() - .ok_or(anyhow!("Failed to pop token count"))?; - total_tokens -= removed_tokens; - } else { - break; - } - } - - // Step 5: Check first msg is a User message with TextContent only - while let Some(first_msg) = messages.first() { - if first_msg.role != Role::User || !first_msg.has_only_text_content() { - let _ = messages.remove(0); - let removed_tokens = token_counts.remove(0); - total_tokens -= removed_tokens; - } else { - break; - } - } - - debug!("Total tokens after truncation: {}", total_tokens); - - // Ensure we have at least one message remaining and it's within context limit - if messages.is_empty() { - return Err(anyhow!( - "Unable to preserve any messages within context limit" - )); - } - - if total_tokens > context_limit { - return Err(anyhow!( - "Unable to truncate messages within context window." - )); - } - - debug!("Truncation complete. Total tokens: {}", total_tokens); - Ok(( - Conversation::new_unvalidated(messages.to_vec()), - token_counts.to_vec(), - )) -} - -/// Trait representing a truncation strategy -pub trait TruncationStrategy { - /// Determines the indices of messages to remove to fit within the context limit. - /// - /// - `messages`: The list of messages in the conversation. - /// - `token_counts`: A parallel array containing the token count for each message. - /// - `context_limit`: The maximum allowed context length in tokens. - /// - /// Returns a vector of indices to remove. - fn determine_indices_to_remove( - &self, - messages: &[Message], - token_counts: &[usize], - context_limit: usize, - ) -> Result>; -} - -/// Strategy to truncate messages by removing the oldest first -pub struct OldestFirstTruncation; - -impl TruncationStrategy for OldestFirstTruncation { - fn determine_indices_to_remove( - &self, - messages: &[Message], - token_counts: &[usize], - context_limit: usize, - ) -> Result> { - let mut indices_to_remove = HashSet::new(); - let mut total_tokens: usize = token_counts.iter().sum(); - let mut tool_ids_to_remove = HashSet::new(); - - for (i, message) in messages.iter().enumerate() { - if total_tokens <= context_limit { - break; - } - - // Remove the message - indices_to_remove.insert(i); - total_tokens -= token_counts[i]; - debug!( - "OldestFirst: Removing message at index {}. Tokens removed: {}", - i, token_counts[i] - ); - - // If it's a ToolRequest or ToolResponse, mark its pair for removal - if message.is_tool_call() || message.is_tool_response() { - message.get_tool_ids().iter().for_each(|id| { - tool_ids_to_remove.insert((i, id.to_string())); - }); - } - } - - // Now, find and remove paired ToolResponses or ToolRequests - for (i, message) in messages.iter().enumerate() { - let message_tool_ids = message.get_tool_ids(); - // Find the other part of the pair - same tool_id but different message index - for (message_idx, tool_id) in &tool_ids_to_remove { - if message_idx != &i && message_tool_ids.contains(tool_id.as_str()) { - indices_to_remove.insert(i); - // No need to check other tool_ids for this message since it's already marked - break; - } - } - } - - Ok(indices_to_remove) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::conversation::message::Message; - use anyhow::Result; - use rmcp::model::{CallToolRequestParam, Content}; - use rmcp::object; - - // Helper function to create a user text message with a specified token count - fn user_text(index: usize, tokens: usize) -> (Message, usize) { - let content = format!("User message {}", index); - (Message::user().with_text(content), tokens) - } - - // Helper function to create an assistant text message with a specified token count - fn assistant_text(index: usize, tokens: usize) -> (Message, usize) { - let content = format!("Assistant message {}", index); - (Message::assistant().with_text(content), tokens) - } - - // Helper function to create a tool request message with a specified token count - fn assistant_tool_request( - id: &str, - tool_call: CallToolRequestParam, - tokens: usize, - ) -> (Message, usize) { - ( - Message::assistant().with_tool_request(id, Ok(tool_call)), - tokens, - ) - } - - // Helper function to create a tool response message with a specified token count - fn user_tool_response(id: &str, result: Vec, tokens: usize) -> (Message, usize) { - (Message::user().with_tool_response(id, Ok(result)), tokens) - } - - // Helper function to create a large tool response with massive content - fn large_tool_response(id: &str, large_text: String, tokens: usize) -> (Message, usize) { - ( - Message::user().with_tool_response(id, Ok(vec![Content::text(large_text)])), - tokens, - ) - } - - // Helper function to create messages with alternating user and assistant - // text messages of a fixed token count - fn create_messages_with_counts( - num_pairs: usize, - tokens: usize, - remove_last: bool, - ) -> (Conversation, Vec) { - let mut messages = Conversation::new_unvalidated((0..num_pairs).flat_map(|i| { - vec![ - user_text(i * 2, tokens).0, - assistant_text((i * 2) + 1, tokens).0, - ] - })); - - if remove_last { - messages.pop(); - } - - let token_counts = vec![tokens; messages.len()]; - - (messages, token_counts) - } - - #[test] - fn test_handle_oversized_single_message() -> Result<()> { - // Create a scenario similar to the real issue: one very large tool response - let large_content = "A".repeat(50000); // Very large content - let messages = vec![ - user_text(1, 10).0, - assistant_tool_request( - "tool1", - CallToolRequestParam { - name: "read_file".into(), - arguments: Some(object!({"path": "large_file.txt"})), - }, - 20, - ) - .0, - large_tool_response("tool1", large_content, 100000).0, // Massive tool response - user_text(2, 10).0, - ]; - let token_counts = vec![10, 20, 100000, 10]; // One message is huge - let context_limit = 5000; // Much smaller than the large message - - let result = truncate_messages( - &messages, - &token_counts, - context_limit, - &OldestFirstTruncation, - ); - - // Should succeed by truncating the large content - assert!( - result.is_ok(), - "Should handle oversized message by content truncation" - ); - let (truncated_messages, truncated_counts) = result.unwrap(); - - // Should have some messages remaining - assert!( - !truncated_messages.is_empty(), - "Should have some messages left" - ); - - // Total should be within limit - let total_tokens: usize = truncated_counts.iter().sum(); - assert!( - total_tokens <= context_limit, - "Total tokens {} should be <= context limit {}", - total_tokens, - context_limit - ); - - Ok(()) - } - - #[test] - fn test_oldest_first_no_truncation() -> Result<()> { - let (messages, token_counts) = create_messages_with_counts(1, 10, false); - let context_limit = 25; - - let result = truncate_messages( - messages.messages(), - &token_counts, - context_limit, - &OldestFirstTruncation, - )?; - - assert_eq!(result.0.messages(), messages.messages()); - assert_eq!(result.1, token_counts); - Ok(()) - } - - #[test] - fn test_complex_conversation_with_tools() -> Result<()> { - // Simulating a real conversation with multiple tool interactions - let tool_call1 = CallToolRequestParam { - name: "file_read".into(), - arguments: Some(object!({"path": "/tmp/test.txt"})), - }; - let tool_call2 = CallToolRequestParam { - name: "database_query".into(), - arguments: Some(object!({"query": "SELECT * FROM users"})), - }; - - let messages = vec![ - user_text(1, 15).0, // Initial user query - assistant_tool_request("tool1", tool_call1.clone(), 20).0, - user_tool_response( - "tool1", - vec![Content::text("File contents".to_string())], - 10, - ) - .0, - assistant_text(2, 25).0, // Assistant processes file contents - user_text(3, 10).0, // User follow-up - assistant_tool_request("tool2", tool_call2.clone(), 30).0, - user_tool_response( - "tool2", - vec![Content::text("Query results".to_string())], - 20, - ) - .0, - assistant_text(4, 35).0, // Assistant analyzes query results - user_text(5, 5).0, // Final user confirmation - ]; - - let token_counts = vec![15, 20, 10, 25, 10, 30, 20, 35, 5]; - let context_limit = 100; // Force truncation while preserving some tool interactions - - let result = truncate_messages( - &messages, - &token_counts, - context_limit, - &OldestFirstTruncation, - )?; - let (truncated_messages, truncated_counts) = result; - - // Verify that tool pairs are kept together and the conversation remains coherent - assert!(truncated_messages.len() >= 3); // At least one complete interaction should remain - assert!(truncated_messages.last().unwrap().role == Role::User); // Last message should be from user - - // Verify tool pairs are either both present or both removed - let tool_ids: HashSet<_> = truncated_messages - .iter() - .flat_map(|m| m.get_tool_ids()) - .collect(); - - // Each tool ID should appear 0 or 2 times (request + response) - for id in tool_ids { - let count = truncated_messages - .iter() - .flat_map(|m| m.get_tool_ids().into_iter()) - .filter(|&tool_id| tool_id == id) - .count(); - assert!(count == 0 || count == 2, "Tool pair was split: {}", id); - } - - // Total should be within limit - let total_tokens: usize = truncated_counts.iter().sum(); - assert!(total_tokens <= context_limit); - - Ok(()) - } - - #[test] - fn test_edge_case_context_window() -> Result<()> { - // Test case where we're exactly at the context limit - let (messages, token_counts) = create_messages_with_counts(2, 25, false); - let context_limit = 100; // Exactly matches total tokens - - let result = truncate_messages( - messages.messages(), - &token_counts, - context_limit, - &OldestFirstTruncation, - )?; - let (mut messages, mut token_counts) = result; - - assert_eq!(messages.len(), 4); // No truncation needed - assert_eq!(token_counts.iter().sum::(), 100); - - // Now add one more token to force truncation - messages.push(user_text(5, 1).0); - token_counts.push(1); - - let result = truncate_messages( - messages.messages(), - &token_counts, - context_limit, - &OldestFirstTruncation, - )?; - let (messages, token_counts) = result; - - assert!(token_counts.iter().sum::() <= context_limit); - assert!(messages.last().unwrap().role == Role::User); - - Ok(()) - } - - #[test] - fn test_multi_tool_chain() -> Result<()> { - // Simulate a chain of dependent tool calls - let tool_calls = vec![ - CallToolRequestParam { - name: "git_status".into(), - arguments: Some(object!({})), - }, - CallToolRequestParam { - name: "git_diff".into(), - arguments: Some(object!({"file": "main.rs"})), - }, - CallToolRequestParam { - name: "git_commit".into(), - arguments: Some(object!({"message": "Update"})), - }, - ]; - - let mut messages = Vec::new(); - let mut token_counts = Vec::new(); - - // Build a chain of related tool calls - // 30 tokens each round - for (i, tool_call) in tool_calls.into_iter().enumerate() { - let id = format!("git_{}", i); - messages.push(user_text(i, 10).0); - token_counts.push(10); - - messages.push(assistant_tool_request(&id, tool_call, 15).0); - token_counts.push(20); - } - - let context_limit = 50; // Force partial truncation - - let result = truncate_messages( - &messages, - &token_counts, - context_limit, - &OldestFirstTruncation, - )?; - let (truncated_messages, _) = result; - - // Verify that remaining tool chains are complete - let remaining_tool_ids: HashSet<_> = truncated_messages - .iter() - .flat_map(|m| m.get_tool_ids()) - .collect(); - - for _id in remaining_tool_ids { - // Count request/response pairs - let requests = truncated_messages - .iter() - .flat_map(|m| m.get_tool_request_ids().into_iter()) - .count(); - - let responses = truncated_messages - .iter() - .flat_map(|m| m.get_tool_response_ids().into_iter()) - .count(); - - assert_eq!(requests, 1, "Each remaining tool should have one request"); - assert_eq!(responses, 1, "Each remaining tool should have one response"); - } - - Ok(()) - } - - #[test] - fn test_truncation_with_image_content() -> Result<()> { - // Create a conversation with image content mixed in - let messages = vec![ - Message::user().with_image("base64_data", "image/png"), // 50 tokens - Message::assistant().with_text("I see the image"), // 10 tokens - Message::user().with_text("Can you describe it?"), // 10 tokens - Message::assistant().with_text("It shows..."), // 20 tokens - Message::user().with_text("Thanks!"), // 5 tokens - ]; - let token_counts = vec![50, 10, 10, 20, 5]; - let context_limit = 45; // Force truncation - - let result = truncate_messages( - &messages, - &token_counts, - context_limit, - &OldestFirstTruncation, - )?; - let (messages, token_counts) = result; - - // Verify the conversation still makes sense - assert!(!messages.is_empty()); - assert!(messages.last().unwrap().role == Role::User); - assert!(token_counts.iter().sum::() <= context_limit); - - Ok(()) - } - - #[test] - fn test_error_cases() -> Result<()> { - // Test impossibly small context window - let (messages, token_counts) = create_messages_with_counts(1, 10, false); - let result = truncate_messages( - messages.messages(), - &token_counts, - 5, // Impossibly small context - &OldestFirstTruncation, - ); - assert!(result.is_err()); - - // Test unmatched token counts - let messages = vec![user_text(1, 10).0]; - let token_counts = vec![10, 10]; // Mismatched length - let result = truncate_messages(&messages, &token_counts, 100, &OldestFirstTruncation); - assert!(result.is_err()); - - Ok(()) - } -} diff --git a/crates/goose/src/conversation/message.rs b/crates/goose/src/conversation/message.rs index 8b01a438b181..b47d05774a96 100644 --- a/crates/goose/src/conversation/message.rs +++ b/crates/goose/src/conversation/message.rs @@ -112,12 +112,7 @@ pub struct FrontendToolRequest { } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)] -pub struct ContextLengthExceeded { - pub msg: String, -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ToSchema)] -pub struct SummarizationRequested { +pub struct ConversationCompacted { pub msg: String, } @@ -133,8 +128,7 @@ pub enum MessageContent { FrontendToolRequest(FrontendToolRequest), Thinking(ThinkingContent), RedactedThinking(RedactedThinkingContent), - ContextLengthExceeded(ContextLengthExceeded), - SummarizationRequested(SummarizationRequested), + ConversationCompacted(ConversationCompacted), } impl fmt::Display for MessageContent { @@ -162,10 +156,7 @@ impl fmt::Display for MessageContent { }, MessageContent::Thinking(t) => write!(f, "[Thinking: {}]", t.thinking), MessageContent::RedactedThinking(_r) => write!(f, "[RedactedThinking]"), - MessageContent::ContextLengthExceeded(r) => { - write!(f, "[ContextLengthExceeded: {}]", r.msg) - } - MessageContent::SummarizationRequested(r) => { + MessageContent::ConversationCompacted(r) => { write!(f, "[SummarizationRequested: {}]", r.msg) } } @@ -246,17 +237,13 @@ impl MessageContent { }) } - pub fn context_length_exceeded>(msg: S) -> Self { - MessageContent::ContextLengthExceeded(ContextLengthExceeded { msg: msg.into() }) - } - - pub fn summarization_requested>(msg: S) -> Self { - MessageContent::SummarizationRequested(SummarizationRequested { msg: msg.into() }) + pub fn conversation_compacted>(msg: S) -> Self { + MessageContent::ConversationCompacted(ConversationCompacted { msg: msg.into() }) } // Add this new method to check for summarization requested content - pub fn as_summarization_requested(&self) -> Option<&SummarizationRequested> { - if let MessageContent::SummarizationRequested(ref summarization_requested) = self { + pub fn as_summarization_requested(&self) -> Option<&ConversationCompacted> { + if let MessageContent::ConversationCompacted(ref summarization_requested) = self { Some(summarization_requested) } else { None @@ -390,10 +377,8 @@ impl From for Message { #[serde(rename_all = "camelCase")] pub struct MessageMetadata { /// Whether the message should be visible to the user in the UI - #[serde(default = "default_true")] pub user_visible: bool, /// Whether the message should be included in the agent's context window - #[serde(default = "default_true")] pub agent_visible: bool, } @@ -464,28 +449,18 @@ impl MessageMetadata { } } -fn default_true() -> bool { - true -} - #[derive(ToSchema, Clone, PartialEq, Serialize, Deserialize, Debug)] /// A message to or from an LLM #[serde(rename_all = "camelCase")] pub struct Message { pub id: Option, pub role: Role, - #[serde(default = "default_created")] pub created: i64, #[serde(deserialize_with = "deserialize_sanitized_content")] pub content: Vec, - #[serde(default)] pub metadata: MessageMetadata, } -fn default_created() -> i64 { - 0 // old messages do not have timestamps. -} - impl Message { pub fn new(role: Role, created: i64, content: Vec) -> Self { Message { @@ -605,11 +580,6 @@ impl Message { self.with_content(MessageContent::redacted_thinking(data)) } - /// Add context length exceeded content to the message - pub fn with_context_length_exceeded>(self, msg: S) -> Self { - self.with_content(MessageContent::context_length_exceeded(msg)) - } - /// Get the concatenated text content of the message, separated by newlines pub fn as_concat_text(&self) -> String { self.content @@ -680,9 +650,8 @@ impl Message { .all(|c| matches!(c, MessageContent::Text(_))) } - /// Add summarization requested to the message - pub fn with_summarization_requested>(self, msg: S) -> Self { - self.with_content(MessageContent::summarization_requested(msg)) + pub fn with_conversation_compacted>(self, msg: S) -> Self { + self.with_content(MessageContent::conversation_compacted(msg)) } /// Set the visibility metadata for the message @@ -837,7 +806,8 @@ mod tests { } } } - ] + ], + "metadata": { "agentVisible": true, "userVisible": true } }"#; let message: Message = serde_json::from_str(json_str).unwrap(); @@ -1045,7 +1015,8 @@ mod tests { "data": "base64data", "mimeType": "image/png" }} - ] + ], + "metadata": {{ "agentVisible": true, "userVisible": true }} }}"#, malicious_text ); @@ -1073,7 +1044,8 @@ mod tests { "content": [{ "type": "text", "text": "Hello world 世界 🌍" - }] + }], + "metadata": { "agentVisible": true, "userVisible": true } }"#; let message: Message = serde_json::from_str(clean_json).unwrap(); @@ -1142,20 +1114,6 @@ mod tests { let message: Message = serde_json::from_str(json_with_metadata).unwrap(); assert!(!message.is_user_visible()); assert!(message.is_agent_visible()); - - // Test without metadata (should use defaults) - let json_without_metadata = r#"{ - "role": "user", - "created": 1640995200, - "content": [{ - "type": "text", - "text": "Test" - }] - }"#; - - let message: Message = serde_json::from_str(json_without_metadata).unwrap(); - assert!(message.is_user_visible()); - assert!(message.is_agent_visible()); } #[test] diff --git a/crates/goose/src/providers/formats/anthropic.rs b/crates/goose/src/providers/formats/anthropic.rs index 2bbc0dacfe6d..6142d2188c75 100644 --- a/crates/goose/src/providers/formats/anthropic.rs +++ b/crates/goose/src/providers/formats/anthropic.rs @@ -90,10 +90,7 @@ pub fn format_messages(messages: &[Message]) -> Vec { MessageContent::ToolConfirmationRequest(_tool_confirmation_request) => { // Skip tool confirmation requests } - MessageContent::ContextLengthExceeded(_) => { - // Skip - } - MessageContent::SummarizationRequested(_) => { + MessageContent::ConversationCompacted(_) => { // Skip } MessageContent::Thinking(thinking) => { diff --git a/crates/goose/src/providers/formats/bedrock.rs b/crates/goose/src/providers/formats/bedrock.rs index 8521ec514e72..ae4d37f7eca8 100644 --- a/crates/goose/src/providers/formats/bedrock.rs +++ b/crates/goose/src/providers/formats/bedrock.rs @@ -48,10 +48,7 @@ pub fn to_bedrock_message_content(content: &MessageContent) -> Result { - bail!("ContextLengthExceeded should not get passed to the provider") - } - MessageContent::SummarizationRequested(_) => { + MessageContent::ConversationCompacted(_) => { bail!("SummarizationRequested should not get passed to the provider") } MessageContent::ToolRequest(tool_req) => { diff --git a/crates/goose/src/providers/formats/databricks.rs b/crates/goose/src/providers/formats/databricks.rs index be125b4c7d75..c7a34e54273a 100644 --- a/crates/goose/src/providers/formats/databricks.rs +++ b/crates/goose/src/providers/formats/databricks.rs @@ -127,10 +127,7 @@ fn format_messages(messages: &[Message], image_format: &ImageFormat) -> Vec { - continue; - } - MessageContent::SummarizationRequested(_) => { + MessageContent::ConversationCompacted(_) => { continue; } MessageContent::ToolResponse(response) => { diff --git a/crates/goose/src/providers/formats/openai.rs b/crates/goose/src/providers/formats/openai.rs index cd47f4e51600..fc977ca0b09a 100644 --- a/crates/goose/src/providers/formats/openai.rs +++ b/crates/goose/src/providers/formats/openai.rs @@ -95,10 +95,7 @@ pub fn format_messages(messages: &[Message], image_format: &ImageFormat) -> Vec< // Redacted thinking blocks are not directly used in OpenAI format continue; } - MessageContent::ContextLengthExceeded(_) => { - continue; - } - MessageContent::SummarizationRequested(_) => { + MessageContent::ConversationCompacted(_) => { continue; } MessageContent::ToolRequest(request) => match &request.tool_call { diff --git a/crates/goose/src/providers/formats/snowflake.rs b/crates/goose/src/providers/formats/snowflake.rs index 660f2838db4f..4e52b263086a 100644 --- a/crates/goose/src/providers/formats/snowflake.rs +++ b/crates/goose/src/providers/formats/snowflake.rs @@ -53,10 +53,7 @@ pub fn format_messages(messages: &[Message]) -> Vec { MessageContent::ToolConfirmationRequest(_) => { // Skip tool confirmation requests } - MessageContent::ContextLengthExceeded(_) => { - // Skip - } - MessageContent::SummarizationRequested(_) => { + MessageContent::ConversationCompacted(_) => { // Skip } MessageContent::Thinking(_thinking) => { diff --git a/crates/goose/src/providers/usage_estimator.rs b/crates/goose/src/providers/usage_estimator.rs index e819b6dc8349..9385a57fe376 100644 --- a/crates/goose/src/providers/usage_estimator.rs +++ b/crates/goose/src/providers/usage_estimator.rs @@ -1,6 +1,6 @@ use crate::conversation::message::Message; use crate::providers::base::ProviderUsage; -use crate::token_counter::create_async_token_counter; +use crate::token_counter::create_token_counter; use anyhow::Result; use rmcp::model::Tool; @@ -17,7 +17,7 @@ pub async fn ensure_usage_tokens( return Ok(()); } - let token_counter = create_async_token_counter() + let token_counter = create_token_counter() .await .map_err(|e| anyhow::anyhow!("Failed to create token counter: {}", e))?; diff --git a/crates/goose/src/providers/utils.rs b/crates/goose/src/providers/utils.rs index 9c6ee2aa2a9d..344e7092439d 100644 --- a/crates/goose/src/providers/utils.rs +++ b/crates/goose/src/providers/utils.rs @@ -1,6 +1,8 @@ use super::base::Usage; use super::errors::GoogleErrorCode; +use crate::config::paths::Paths; use crate::model::ModelConfig; +use crate::providers::errors::{OpenAIError, ProviderError}; use anyhow::Result; use base64::Engine; use regex::Regex; @@ -12,8 +14,6 @@ use std::io::Read; use std::path::Path; use std::time::Duration; -use crate::providers::errors::{OpenAIError, ProviderError}; - #[derive(serde::Deserialize)] struct OpenAIErrorResponse { error: OpenAIError, @@ -461,14 +461,32 @@ pub fn emit_debug_trace( T1: ?Sized + Serialize, T2: ?Sized + Serialize, { - tracing::debug!( - model_config = %serde_json::to_string_pretty(model_config).unwrap_or_default(), - input = %serde_json::to_string_pretty(payload).unwrap_or_default(), - output = %serde_json::to_string_pretty(response).unwrap_or_default(), - input_tokens = ?usage.input_tokens.unwrap_or_default(), - output_tokens = ?usage.output_tokens.unwrap_or_default(), - total_tokens = ?usage.total_tokens.unwrap_or_default(), - ); + let logs_dir = Paths::in_state_dir("logs"); + + if let Err(e) = std::fs::create_dir_all(&logs_dir) { + tracing::warn!("Failed to create logs directory: {}", e); + return; + } + + let log_path = |i| logs_dir.join(format!("llm_request.{}.json", i)); + + for i in (0..4).rev() { + let _ = std::fs::rename(log_path(i), log_path(i + 1)); + } + + let data = serde_json::json!({ + "model_config": model_config, + "input": payload, + "output": response, + "usage": usage, + }); + + if let Err(e) = std::fs::write( + log_path(0), + serde_json::to_string_pretty(&data).unwrap_or_default(), + ) { + tracing::warn!("Failed to write log file: {}", e); + } } /// Safely parse a JSON string that may contain doubly-encoded or malformed JSON. diff --git a/crates/goose/src/scheduler.rs b/crates/goose/src/scheduler.rs index 42273229e385..a339731498fe 100644 --- a/crates/goose/src/scheduler.rs +++ b/crates/goose/src/scheduler.rs @@ -1200,7 +1200,7 @@ async fn run_scheduled_job_internal( } if let Some(ref prompt_text) = recipe.prompt { - let mut all_session_messages = + let mut conversation = Conversation::new_unvalidated(vec![Message::user().with_text(prompt_text.clone())]); let session_config = SessionConfig { @@ -1213,11 +1213,7 @@ async fn run_scheduled_job_internal( }; match agent - .reply( - all_session_messages.clone(), - Some(session_config.clone()), - None, - ) + .reply(conversation.clone(), Some(session_config.clone()), None) .await { Ok(mut stream) => { @@ -1231,11 +1227,13 @@ async fn run_scheduled_job_internal( if msg.role == rmcp::model::Role::Assistant { tracing::info!("[Job {}] Assistant: {:?}", job.id, msg.content); } - all_session_messages.push(msg); + conversation.push(msg); } Ok(AgentEvent::McpNotification(_)) => {} Ok(AgentEvent::ModelChange { .. }) => {} - Ok(AgentEvent::HistoryReplaced(_)) => {} + Ok(AgentEvent::HistoryReplaced(updated_conversation)) => { + conversation = updated_conversation; + } Err(e) => { tracing::error!( "[Job {}] Error receiving message from agent: {}", diff --git a/crates/goose/src/session/session_manager.rs b/crates/goose/src/session/session_manager.rs index 283c52f434f1..ddd4d3f513db 100644 --- a/crates/goose/src/session/session_manager.rs +++ b/crates/goose/src/session/session_manager.rs @@ -18,7 +18,7 @@ use tokio::sync::OnceCell; use tracing::{info, warn}; use utoipa::ToSchema; -const CURRENT_SCHEMA_VERSION: i32 = 2; +const CURRENT_SCHEMA_VERSION: i32 = 3; static SESSION_STORAGE: OnceCell> = OnceCell::const_new(); @@ -425,7 +425,8 @@ impl SessionStorage { content_json TEXT NOT NULL, created_timestamp INTEGER NOT NULL, timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - tokens INTEGER + tokens INTEGER, + metadata_json TEXT ) "#, ) @@ -610,6 +611,15 @@ impl SessionStorage { .execute(&self.pool) .await?; } + 3 => { + sqlx::query( + r#" + ALTER TABLE messages ADD COLUMN metadata_json TEXT + "#, + ) + .execute(&self.pool) + .await?; + } _ => { anyhow::bail!("Unknown migration version: {}", version); } @@ -768,15 +778,15 @@ impl SessionStorage { } async fn get_conversation(&self, session_id: &str) -> Result { - let rows = sqlx::query_as::<_, (String, String, i64)>( - "SELECT role, content_json, created_timestamp FROM messages WHERE session_id = ? ORDER BY timestamp", + let rows = sqlx::query_as::<_, (String, String, i64, Option)>( + "SELECT role, content_json, created_timestamp, metadata_json FROM messages WHERE session_id = ? ORDER BY timestamp", ) .bind(session_id) .fetch_all(&self.pool) .await?; let mut messages = Vec::new(); - for (role_str, content_json, created_timestamp) in rows { + for (role_str, content_json, created_timestamp, metadata_json) in rows { let role = match role_str.as_str() { "user" => Role::User, "assistant" => Role::Assistant, @@ -784,7 +794,12 @@ impl SessionStorage { }; let content = serde_json::from_str(&content_json)?; - let message = Message::new(role, created_timestamp, content); + let metadata = metadata_json + .and_then(|json| serde_json::from_str(&json).ok()) + .unwrap_or_default(); + + let mut message = Message::new(role, created_timestamp, content); + message.metadata = metadata; messages.push(message); } @@ -792,16 +807,19 @@ impl SessionStorage { } async fn add_message(&self, session_id: &str, message: &Message) -> Result<()> { + let metadata_json = serde_json::to_string(&message.metadata)?; + sqlx::query( r#" - INSERT INTO messages (session_id, role, content_json, created_timestamp) - VALUES (?, ?, ?, ?) + INSERT INTO messages (session_id, role, content_json, created_timestamp, metadata_json) + VALUES (?, ?, ?, ?, ?) "#, ) .bind(session_id) .bind(role_to_string(&message.role)) .bind(serde_json::to_string(&message.content)?) .bind(message.created) + .bind(metadata_json) .execute(&self.pool) .await?; @@ -826,16 +844,19 @@ impl SessionStorage { .await?; for message in conversation.messages() { + let metadata_json = serde_json::to_string(&message.metadata)?; + sqlx::query( r#" - INSERT INTO messages (session_id, role, content_json, created_timestamp) - VALUES (?, ?, ?, ?) + INSERT INTO messages (session_id, role, content_json, created_timestamp, metadata_json) + VALUES (?, ?, ?, ?, ?) "#, ) .bind(session_id) .bind(role_to_string(&message.role)) .bind(serde_json::to_string(&message.content)?) .bind(message.created) + .bind(metadata_json) .execute(&mut *tx) .await?; } diff --git a/crates/goose/src/token_counter.rs b/crates/goose/src/token_counter.rs index f61396a416ff..dabb57082b7f 100644 --- a/crates/goose/src/token_counter.rs +++ b/crates/goose/src/token_counter.rs @@ -20,16 +20,12 @@ const ENUM_INIT: isize = -3; const ENUM_ITEM: usize = 3; const FUNC_END: usize = 12; -pub struct AsyncTokenCounter { - tokenizer: Arc, - token_cache: Arc>, -} - pub struct TokenCounter { tokenizer: Arc, + token_cache: Arc>, } -impl AsyncTokenCounter { +impl TokenCounter { pub async fn new() -> Result { let tokenizer = get_tokenizer().await?; Ok(Self { @@ -130,6 +126,9 @@ impl AsyncTokenCounter { } for message in messages { + if !message.metadata.agent_visible { + continue; + } num_tokens += tokens_per_message; for content in &message.content { if let Some(content_text) = content.as_text() { @@ -183,136 +182,6 @@ impl AsyncTokenCounter { } } -impl Default for TokenCounter { - fn default() -> Self { - Self::new() - } -} - -impl TokenCounter { - pub fn new() -> Self { - let tokenizer = get_tokenizer_blocking().expect("Failed to initialize tokenizer"); - Self { tokenizer } - } - - pub fn count_tokens(&self, text: &str) -> usize { - let tokens = self.tokenizer.encode_with_special_tokens(text); - tokens.len() - } - - pub fn count_tokens_for_tools(&self, tools: &[Tool]) -> usize { - let mut func_token_count = 0; - if !tools.is_empty() { - for tool in tools { - func_token_count += FUNC_INIT; - let name = &tool.name; - let description = &tool - .description - .as_ref() - .map(|d| d.as_ref()) - .unwrap_or_default() - .trim_end_matches('.'); - let line = format!("{}:{}", name, description); - func_token_count += self.count_tokens(&line); - - if let Some(serde_json::Value::Object(properties)) = - tool.input_schema.get("properties") - { - if !properties.is_empty() { - func_token_count += PROP_INIT; - for (key, value) in properties { - func_token_count += PROP_KEY; - let p_name = key; - let p_type = value.get("type").and_then(|v| v.as_str()).unwrap_or(""); - let p_desc = value - .get("description") - .and_then(|v| v.as_str()) - .unwrap_or("") - .trim_end_matches('.'); - let line = format!("{}:{}:{}", p_name, p_type, p_desc); - func_token_count += self.count_tokens(&line); - if let Some(enum_values) = value.get("enum").and_then(|v| v.as_array()) - { - func_token_count = - func_token_count.saturating_add_signed(ENUM_INIT); - for item in enum_values { - if let Some(item_str) = item.as_str() { - func_token_count += ENUM_ITEM; - func_token_count += self.count_tokens(item_str); - } - } - } - } - } - } - } - func_token_count += FUNC_END; - } - - func_token_count - } - - pub fn count_chat_tokens( - &self, - system_prompt: &str, - messages: &[Message], - tools: &[Tool], - ) -> usize { - let tokens_per_message = 4; - - let mut num_tokens = 0; - if !system_prompt.is_empty() { - num_tokens += self.count_tokens(system_prompt) + tokens_per_message; - } - - for message in messages { - num_tokens += tokens_per_message; - for content in &message.content { - if let Some(content_text) = content.as_text() { - num_tokens += self.count_tokens(content_text); - } else if let Some(tool_request) = content.as_tool_request() { - if let Ok(tool_call) = tool_request.tool_call.as_ref() { - let text = format!( - "{}:{}:{:?}", - tool_request.id, tool_call.name, tool_call.arguments - ); - num_tokens += self.count_tokens(&text); - } - } else if let Some(tool_response_text) = content.as_tool_response_text() { - num_tokens += self.count_tokens(&tool_response_text); - } else { - continue; - } - } - } - - if !tools.is_empty() { - num_tokens += self.count_tokens_for_tools(tools); - } - - num_tokens += 3; - - num_tokens - } - - pub fn count_everything( - &self, - system_prompt: &str, - messages: &[Message], - tools: &[Tool], - resources: &[String], - ) -> usize { - let mut num_tokens = self.count_chat_tokens(system_prompt, messages, tools); - - if !resources.is_empty() { - for resource in resources { - num_tokens += self.count_tokens(resource); - } - } - num_tokens - } -} - async fn get_tokenizer() -> Result, String> { let tokenizer = TOKENIZER .get_or_init(|| async { @@ -325,99 +194,17 @@ async fn get_tokenizer() -> Result, String> { Ok(tokenizer.clone()) } -fn get_tokenizer_blocking() -> Result, String> { - if let Some(tokenizer) = TOKENIZER.get() { - return Ok(tokenizer.clone()); - } - - match tiktoken_rs::o200k_base() { - Ok(bpe) => { - let tokenizer = Arc::new(bpe); - let _ = TOKENIZER.set(tokenizer.clone()); - Ok(tokenizer) - } - Err(e) => Err(format!("Failed to initialize o200k_base tokenizer: {}", e)), - } -} - -pub async fn create_async_token_counter() -> Result { - AsyncTokenCounter::new().await +pub async fn create_token_counter() -> Result { + TokenCounter::new().await } #[cfg(test)] mod tests { use super::*; - use crate::conversation::message::{Message, MessageContent}; - use rmcp::model::{Role, Tool}; - use rmcp::object; - - #[test] - fn test_count_chat_tokens() { - let counter = TokenCounter::new(); - - let system_prompt = - "You are a helpful assistant that can answer questions about the weather."; - - let messages = vec![ - Message::new( - Role::User, - 0, - vec![MessageContent::text( - "What's the weather like in San Francisco?", - )], - ), - Message::new( - Role::Assistant, - 1, - vec![MessageContent::text( - "Looks like it's 60 degrees Fahrenheit in San Francisco.", - )], - ), - Message::new( - Role::User, - 2, - vec![MessageContent::text("How about New York?")], - ), - ]; - - let tools = vec![Tool::new( - "get_current_weather", - "Get the current weather in a given location", - object!({ - "properties": { - "location": { - "type": "string", - "description": "The city and state, e.g. San Francisco, CA" - }, - "unit": { - "type": "string", - "description": "The unit of temperature to return", - "enum": ["celsius", "fahrenheit"] - } - }, - "required": ["location"] - }), - )]; - - let token_count_without_tools = counter.count_chat_tokens(system_prompt, &messages, &[]); - println!("Total tokens without tools: {}", token_count_without_tools); - - let token_count_with_tools = counter.count_chat_tokens(system_prompt, &messages, &tools); - println!("Total tokens with tools: {}", token_count_with_tools); - - assert!( - token_count_without_tools > 0, - "Should have some tokens without tools" - ); - assert!( - token_count_with_tools > token_count_without_tools, - "Should have more tokens with tools" - ); - } #[tokio::test] - async fn test_async_token_caching() { - let counter = create_async_token_counter().await.unwrap(); + async fn test_token_caching() { + let counter = create_token_counter().await.unwrap(); let text = "This is a test for caching functionality"; @@ -434,8 +221,8 @@ mod tests { } #[tokio::test] - async fn test_async_cache_management() { - let counter = create_async_token_counter().await.unwrap(); + async fn test_cache_management() { + let counter = create_token_counter().await.unwrap(); counter.count_tokens("First text"); counter.count_tokens("Second text"); @@ -454,7 +241,7 @@ mod tests { #[tokio::test] async fn test_concurrent_token_counter_creation() { let handles: Vec<_> = (0..10) - .map(|_| tokio::spawn(async { create_async_token_counter().await.unwrap() })) + .map(|_| tokio::spawn(async { create_token_counter().await.unwrap() })) .collect(); let counters: Vec<_> = futures::future::join_all(handles) @@ -473,7 +260,7 @@ mod tests { #[tokio::test] async fn test_cache_eviction_behavior() { - let counter = create_async_token_counter().await.unwrap(); + let counter = create_token_counter().await.unwrap(); let mut cached_texts = Vec::new(); for i in 0..50 { @@ -493,7 +280,7 @@ mod tests { #[tokio::test] async fn test_concurrent_cache_operations() { - let counter = std::sync::Arc::new(create_async_token_counter().await.unwrap()); + let counter = std::sync::Arc::new(create_token_counter().await.unwrap()); let handles: Vec<_> = (0..20) .map(|i| { @@ -518,24 +305,4 @@ mod tests { assert!(counter.cache_size() > 0); assert!(counter.cache_size() <= MAX_TOKEN_CACHE_SIZE); } - - #[test] - fn test_tokenizer_consistency() { - let sync_counter = TokenCounter::new(); - let text = "This is a test for tokenizer consistency"; - let sync_count = sync_counter.count_tokens(text); - - assert!(sync_count > 0, "Sync tokenizer should produce tokens"); - - let short_text = "Hi"; - let long_text = "This is a much longer text that should produce significantly more tokens than the short text"; - - let short_count = sync_counter.count_tokens(short_text); - let long_count = sync_counter.count_tokens(long_text); - - assert!( - short_count < long_count, - "Longer text should have more tokens" - ); - } } diff --git a/crates/goose/tests/agent.rs b/crates/goose/tests/agent.rs index 510fb30b9362..af5d531c4153 100644 --- a/crates/goose/tests/agent.rs +++ b/crates/goose/tests/agent.rs @@ -117,7 +117,7 @@ async fn run_truncate_test( agent.update_provider(provider).await?; let repeat_count = context_window + 10_000; let large_message_content = "hello ".repeat(repeat_count); - let messages = Conversation::new(vec![ + let conversation = Conversation::new(vec![ Message::user().with_text("hi there. what is 2 + 2?"), Message::assistant().with_text("hey! I think it's 4."), Message::user().with_text(&large_message_content), @@ -130,7 +130,7 @@ async fn run_truncate_test( ]) .unwrap(); - let reply_stream = agent.reply(messages, None, None).await?; + let reply_stream = agent.reply(conversation, None, None).await?; tokio::pin!(reply_stream); let mut responses = Vec::new(); @@ -143,8 +143,8 @@ async fn run_truncate_test( Ok(AgentEvent::ModelChange { .. }) => { // Model change events are informational, just continue } - Ok(AgentEvent::HistoryReplaced(_)) => { - // Handle history replacement events if needed + Ok(AgentEvent::HistoryReplaced(_updated_conversation)) => { + // Should update the conversation here, but we're not reading it } Err(e) => { println!("Error: {:?}", e); @@ -175,14 +175,6 @@ async fn run_truncate_test( assert!(text_content.text.to_lowercase().contains("no")); assert!(!text_content.text.to_lowercase().contains("yes")); } - goose::conversation::message::MessageContent::ContextLengthExceeded(_) => { - // This is an acceptable outcome for providers that don't truncate themselves - // and correctly report that the context length was exceeded. - println!( - "Received ContextLengthExceeded as expected for {:?}", - provider_type - ); - } _ => { panic!( "Unexpected message content type: {:?}", @@ -1119,7 +1111,9 @@ mod max_turns_tests { } Ok(AgentEvent::McpNotification(_)) => {} Ok(AgentEvent::ModelChange { .. }) => {} - Ok(AgentEvent::HistoryReplaced(_)) => {} + Ok(AgentEvent::HistoryReplaced(_updated_conversation)) => { + // We should update the conversation here, but we're not reading it + } Err(e) => { return Err(e); } diff --git a/ui/desktop/openapi.json b/ui/desktop/openapi.json index cb12e582cfd4..a101deb6159c 100644 --- a/ui/desktop/openapi.json +++ b/ui/desktop/openapi.json @@ -2213,30 +2213,14 @@ } ] }, - "ContextLengthExceeded": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "type": "string" - } - } - }, "ContextManageRequest": { "type": "object", "description": "Request payload for context management operations", "required": [ "messages", - "manageAction", "sessionId" ], "properties": { - "manageAction": { - "type": "string", - "description": "Operation to perform: \"truncation\" or \"summarize\"" - }, "messages": { "type": "array", "items": { @@ -2281,6 +2265,17 @@ "$ref": "#/components/schemas/Message" } }, + "ConversationCompacted": { + "type": "object", + "required": [ + "msg" + ], + "properties": { + "msg": { + "type": "string" + } + } + }, "CreateRecipeRequest": { "type": "object", "required": [ @@ -3098,7 +3093,9 @@ "description": "A message to or from an LLM", "required": [ "role", - "content" + "created", + "content", + "metadata" ], "properties": { "content": { @@ -3296,28 +3293,7 @@ { "allOf": [ { - "$ref": "#/components/schemas/ContextLengthExceeded" - }, - { - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "type": "string", - "enum": [ - "contextLengthExceeded" - ] - } - } - } - ] - }, - { - "allOf": [ - { - "$ref": "#/components/schemas/SummarizationRequested" + "$ref": "#/components/schemas/ConversationCompacted" }, { "type": "object", @@ -3328,7 +3304,7 @@ "type": { "type": "string", "enum": [ - "summarizationRequested" + "conversationCompacted" ] } } @@ -3344,6 +3320,10 @@ "MessageMetadata": { "type": "object", "description": "Metadata for message visibility", + "required": [ + "userVisible", + "agentVisible" + ], "properties": { "agentVisible": { "type": "boolean", @@ -4372,17 +4352,6 @@ "propertyName": "type" } }, - "SummarizationRequested": { - "type": "object", - "required": [ - "msg" - ], - "properties": { - "msg": { - "type": "string" - } - } - }, "TextContent": { "type": "object", "required": [ diff --git a/ui/desktop/src/api/types.gen.ts b/ui/desktop/src/api/types.gen.ts index a20a4f34df29..f8ff7a59a966 100644 --- a/ui/desktop/src/api/types.gen.ts +++ b/ui/desktop/src/api/types.gen.ts @@ -72,18 +72,10 @@ export type ConfigResponse = { export type Content = RawTextContent | RawImageContent | RawEmbeddedResource | RawAudioContent | RawResource; -export type ContextLengthExceeded = { - msg: string; -}; - /** * Request payload for context management operations */ export type ContextManageRequest = { - /** - * Operation to perform: "truncation" or "summarize" - */ - manageAction: string; /** * Collection of messages to be managed */ @@ -110,6 +102,10 @@ export type ContextManageResponse = { export type Conversation = Array; +export type ConversationCompacted = { + msg: string; +}; + export type CreateRecipeRequest = { author?: AuthorRequest | null; session_id: string; @@ -383,9 +379,9 @@ export type LoadedProvider = { */ export type Message = { content: Array; - created?: number; + created: number; id?: string | null; - metadata?: MessageMetadata; + metadata: MessageMetadata; role: Role; }; @@ -408,10 +404,8 @@ export type MessageContent = (TextContent & { type: 'thinking'; }) | (RedactedThinkingContent & { type: 'redactedThinking'; -}) | (ContextLengthExceeded & { - type: 'contextLengthExceeded'; -}) | (SummarizationRequested & { - type: 'summarizationRequested'; +}) | (ConversationCompacted & { + type: 'conversationCompacted'; }); /** @@ -421,11 +415,11 @@ export type MessageMetadata = { /** * Whether the message should be included in the agent's context window */ - agentVisible?: boolean; + agentVisible: boolean; /** * Whether the message should be visible to the user in the UI */ - userVisible?: boolean; + userVisible: boolean; }; /** @@ -788,10 +782,6 @@ export type SuccessCheck = { type: 'Shell'; }; -export type SummarizationRequested = { - msg: string; -}; - export type TextContent = { _meta?: { [key: string]: unknown; diff --git a/ui/desktop/src/components/ProgressiveMessageList.tsx b/ui/desktop/src/components/ProgressiveMessageList.tsx index 9bdd0ab689ab..3c39a97ed5be 100644 --- a/ui/desktop/src/components/ProgressiveMessageList.tsx +++ b/ui/desktop/src/components/ProgressiveMessageList.tsx @@ -172,7 +172,9 @@ export default function ProgressiveMessageList({ const messagesToRender = messages.slice(0, renderedCount); return messagesToRender .map((message, index) => { - // Use custom render function if provided + if (!message.metadata.userVisible) { + return null; + } if (renderMessage) { return renderMessage(message, index); } diff --git a/ui/desktop/src/components/context_management/CompactionMarker.tsx b/ui/desktop/src/components/context_management/CompactionMarker.tsx index f453aa9b0638..870e034cfdba 100644 --- a/ui/desktop/src/components/context_management/CompactionMarker.tsx +++ b/ui/desktop/src/components/context_management/CompactionMarker.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Message, SummarizationRequested } from '../../api'; +import { Message, ConversationCompacted } from '../../api'; interface CompactionMarkerProps { message: Message; @@ -7,8 +7,8 @@ interface CompactionMarkerProps { export const CompactionMarker: React.FC = ({ message }) => { const compactionContent = message.content.find( - (content): content is SummarizationRequested & { type: 'summarizationRequested' } => - content.type === 'summarizationRequested' + (content): content is ConversationCompacted & { type: 'conversationCompacted' } => + content.type === 'conversationCompacted' ); const markerText = compactionContent?.msg || 'Conversation compacted'; diff --git a/ui/desktop/src/components/context_management/ContextManager.tsx b/ui/desktop/src/components/context_management/ContextManager.tsx index 54c606bd8852..7ef110aed8b5 100644 --- a/ui/desktop/src/components/context_management/ContextManager.tsx +++ b/ui/desktop/src/components/context_management/ContextManager.tsx @@ -9,12 +9,6 @@ interface ContextManagerState { } interface ContextManagerActions { - handleAutoCompaction: ( - messages: Message[], - setMessages: (messages: Message[]) => void, - append: (message: Message) => void, - sessionId: string - ) => Promise; handleManualCompaction: ( messages: Message[], setMessages: (messages: Message[]) => void, @@ -70,6 +64,7 @@ export const ContextManagerProvider: React.FC<{ children: React.ReactNode }> = ( setIsCompacting(false); } catch (err) { + // TODO(Douwe): move this to the server console.error('Error during compaction:', err); setCompactionError(err instanceof Error ? err.message : 'Unknown error during compaction'); @@ -80,10 +75,11 @@ export const ContextManagerProvider: React.FC<{ children: React.ReactNode }> = ( created: Math.floor(Date.now() / 1000), content: [ { - type: 'summarizationRequested', + type: 'conversationCompacted', msg: 'Compaction failed. Please try again or start a new session.', }, ], + metadata: { userVisible: true, agentVisible: true }, }; setMessages([...messages, errorMarker]); @@ -93,18 +89,6 @@ export const ContextManagerProvider: React.FC<{ children: React.ReactNode }> = ( [] ); - const handleAutoCompaction = useCallback( - async ( - messages: Message[], - setMessages: (messages: Message[]) => void, - append: (message: Message) => void, - sessionId: string - ) => { - await performCompaction(messages, setMessages, append, sessionId, false); - }, - [performCompaction] - ); - const handleManualCompaction = useCallback( async ( messages: Message[], @@ -118,7 +102,7 @@ export const ContextManagerProvider: React.FC<{ children: React.ReactNode }> = ( ); const hasCompactionMarker = useCallback((message: Message): boolean => { - return message.content.some((content) => content.type === 'summarizationRequested'); + return message.content.some((content) => content.type === 'conversationCompacted'); }, []); const value = { @@ -127,7 +111,6 @@ export const ContextManagerProvider: React.FC<{ children: React.ReactNode }> = ( compactionError, // Actions - handleAutoCompaction, handleManualCompaction, hasCompactionMarker, }; diff --git a/ui/desktop/src/components/context_management/__tests__/CompactionMarker.test.tsx b/ui/desktop/src/components/context_management/__tests__/CompactionMarker.test.tsx index 3244bbdfcecc..756d1cf14960 100644 --- a/ui/desktop/src/components/context_management/__tests__/CompactionMarker.test.tsx +++ b/ui/desktop/src/components/context_management/__tests__/CompactionMarker.test.tsx @@ -3,12 +3,20 @@ import { render, screen } from '@testing-library/react'; import { CompactionMarker } from '../CompactionMarker'; import { Message } from '../../../api'; +const default_message: Message = { + metadata: { + agentVisible: false, + userVisible: false, + }, + id: '1', + role: 'assistant', + created: 1000,content: [] +}; + describe('CompactionMarker', () => { - it('should render default message when no summarizationRequested content found', () => { + it('should render default message when no conversationCompacted content found', () => { const message: Message = { - id: '1', - role: 'assistant', - created: 1000, + ...default_message, content: [{ type: 'text', text: 'Regular message' }], }; @@ -17,14 +25,12 @@ describe('CompactionMarker', () => { expect(screen.getByText('Conversation compacted')).toBeInTheDocument(); }); - it('should render custom message from summarizationRequested content', () => { + it('should render custom message from conversationCompacted content', () => { const message: Message = { - id: '1', - role: 'assistant', - created: 1000, + ...default_message, content: [ { type: 'text', text: 'Some other content' }, - { type: 'summarizationRequested', msg: 'Custom compaction message' }, + { type: 'conversationCompacted', msg: 'Custom compaction message' }, ], }; @@ -35,9 +41,7 @@ describe('CompactionMarker', () => { it('should handle empty message content array', () => { const message: Message = { - id: '1', - role: 'assistant', - created: 1000, + ...default_message, content: [], }; @@ -48,10 +52,8 @@ describe('CompactionMarker', () => { it('should handle summarizationRequested content with empty msg', () => { const message: Message = { - id: '1', - role: 'assistant', - created: 1000, - content: [{ type: 'summarizationRequested', msg: '' }], + ...default_message, + content: [{ type: 'conversationCompacted', msg: '' }], }; render(); @@ -62,11 +64,9 @@ describe('CompactionMarker', () => { it('should handle summarizationRequested content with undefined msg', () => { const message: Message = { - id: '1', - role: 'assistant', - created: 1000, + ...default_message, // eslint-disable-next-line @typescript-eslint/no-explicit-any - content: [{ type: 'summarizationRequested' } as any], + content: [{ type: 'conversationCompacted' } as any], }; render(); diff --git a/ui/desktop/src/components/context_management/__tests__/ContextManager.test.tsx b/ui/desktop/src/components/context_management/__tests__/ContextManager.test.tsx index dcddf8137c4e..82887370e321 100644 --- a/ui/desktop/src/components/context_management/__tests__/ContextManager.test.tsx +++ b/ui/desktop/src/components/context_management/__tests__/ContextManager.test.tsx @@ -2,7 +2,18 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { renderHook, act } from '@testing-library/react'; import { ContextManagerProvider, useContextManager } from '../ContextManager'; import * as contextManagement from '../index'; -import { ContextManageResponse, Message } from '../../../api'; +import { Message } from '../../../api'; + +const default_message: Message = { + metadata: { + agentVisible: false, + userVisible: false, + }, + id: '1', + role: 'assistant', + created: 1000, + content: [], +}; // Mock the context management functions vi.mock('../index', () => ({ @@ -14,15 +25,11 @@ const mockManageContextFromBackend = vi.mocked(contextManagement.manageContextFr describe('ContextManager', () => { const mockMessages: Message[] = [ { - id: '1', - role: 'user', - created: 1000, + ...default_message, content: [{ type: 'text', text: 'Hello' }], }, { - id: '2', - role: 'assistant', - created: 2000, + ...default_message, content: [{ type: 'text', text: 'Hi there!' }], }, ]; @@ -51,9 +58,6 @@ describe('ContextManager', () => { expect(result.current.isCompacting).toBe(false); expect(result.current.compactionError).toBe(null); - expect(typeof result.current.handleAutoCompaction).toBe('function'); - expect(typeof result.current.handleManualCompaction).toBe('function'); - expect(typeof result.current.hasCompactionMarker).toBe('function'); }); }); @@ -61,10 +65,8 @@ describe('ContextManager', () => { it('should return true for messages with summarizationRequested content', () => { const { result } = renderContextManager(); const messageWithMarker: Message = { - id: '1', - role: 'assistant', - created: 1000, - content: [{ type: 'summarizationRequested', msg: 'Compaction marker' }], + ...default_message, + content: [{ type: 'conversationCompacted', msg: 'Compaction marker' }], }; expect(result.current.hasCompactionMarker(messageWithMarker)).toBe(true); @@ -73,24 +75,20 @@ describe('ContextManager', () => { it('should return false for messages without summarizationRequested content', () => { const { result } = renderContextManager(); const regularMessage: Message = { - id: '1', - role: 'user', - created: 1000, + ...default_message, content: [{ type: 'text', text: 'Hello' }], }; expect(result.current.hasCompactionMarker(regularMessage)).toBe(false); }); - it('should return true for messages with mixed content including summarizationRequested', () => { + it('should return true for messages with mixed content including conversationCompacted', () => { const { result } = renderContextManager(); const mixedMessage: Message = { - id: '1', - role: 'assistant', - created: 1000, + ...default_message, content: [ { type: 'text', text: 'Some text' }, - { type: 'summarizationRequested', msg: 'Compaction marker' }, + { type: 'conversationCompacted', msg: 'Compaction marker' }, ], }; @@ -98,220 +96,22 @@ describe('ContextManager', () => { }); }); - describe('handleAutoCompaction', () => { - it('should successfully perform auto compaction with server-provided messages', async () => { - // Mock the backend response with 3 messages: marker, summary, continuation - // Note: Server messages may not have id/created, which will be added by the code - mockManageContextFromBackend.mockResolvedValue({ - messages: [ - { - role: 'assistant', - content: [ - { type: 'summarizationRequested', msg: 'Conversation compacted and summarized' }, - ], - } as Message, - { - role: 'assistant', - content: [{ type: 'text', text: 'Summary content' }], - } as Message, - { - role: 'assistant', - content: [ - { - type: 'text', - text: 'The previous message contains a summary that was prepared because a context limit was reached. Do not mention that you read a summary or that conversation summarization occurred Just continue the conversation naturally based on the summarized context', - }, - ], - } as Message, - ], - tokenCounts: [8, 100, 50], - }); - - const { result } = renderContextManager(); - - await act(async () => { - await result.current.handleAutoCompaction( - mockMessages, - mockSetMessages, - mockAppend, - 'test-session-id' - ); - }); - - expect(mockManageContextFromBackend).toHaveBeenCalledWith({ - messages: mockMessages, - manageAction: 'summarize', - sessionId: 'test-session-id', - }); - - // Expect setMessages to be called with all 3 messages from server - // Note: Server doesn't provide id/created fields, so we don't check for them - expect(mockSetMessages).toHaveBeenCalledTimes(1); - const setMessagesCall = mockSetMessages.mock.calls[0][0]; - expect(setMessagesCall).toHaveLength(3); - expect(setMessagesCall[0]).toMatchObject({ - role: 'assistant', - content: [{ type: 'summarizationRequested', msg: 'Conversation compacted and summarized' }], - }); - expect(setMessagesCall[1]).toMatchObject({ - role: 'assistant', - content: [{ type: 'text', text: 'Summary content' }], - }); - expect(setMessagesCall[2]).toMatchObject({ - role: 'assistant', - content: [ - { - type: 'text', - text: 'The previous message contains a summary that was prepared because a context limit was reached. Do not mention that you read a summary or that conversation summarization occurred Just continue the conversation naturally based on the summarized context', - }, - ], - }); - - // Fast-forward timers to trigger the append call - act(() => { - vi.advanceTimersByTime(150); - }); - - // Should append the continuation message (index 2) for auto-compaction - expect(mockAppend).toHaveBeenCalledTimes(1); - const appendedMessage = mockAppend.mock.calls[0][0]; - expect(appendedMessage).toMatchObject({ - role: 'assistant', - content: [ - { - type: 'text', - text: 'The previous message contains a summary that was prepared because a context limit was reached. Do not mention that you read a summary or that conversation summarization occurred Just continue the conversation naturally based on the summarized context', - }, - ], - }); - }); - - it('should handle compaction errors gracefully', async () => { - const error = new Error('Backend error'); - mockManageContextFromBackend.mockRejectedValue(error); - - const { result } = renderContextManager(); - - await act(async () => { - await result.current.handleAutoCompaction( - mockMessages, - mockSetMessages, - mockAppend, - 'test-session-id' - ); - }); - - expect(result.current.compactionError).toBe('Backend error'); - expect(result.current.isCompacting).toBe(false); - - expect(mockSetMessages).toHaveBeenCalledWith([ - ...mockMessages, - expect.objectContaining({ - content: [ - { - type: 'summarizationRequested', - msg: 'Compaction failed. Please try again or start a new session.', - }, - ], - }), - ]); - }); - - it('should set isCompacting state correctly during operation', async () => { - let resolvePromise: (value: ContextManageResponse) => void; - const promise = new Promise((resolve) => { - resolvePromise = resolve; - }); - - mockManageContextFromBackend.mockReturnValue(promise); - - const { result } = renderContextManager(); - - // Start compaction - act(() => { - result.current.handleAutoCompaction( - mockMessages, - mockSetMessages, - mockAppend, - 'test-session-id' - ); - }); - - // Should be compacting - expect(result.current.isCompacting).toBe(true); - expect(result.current.compactionError).toBe(null); - - // Resolve the backend call - resolvePromise!({ - messages: [ - { - role: 'assistant', - content: [{ type: 'text', text: 'Summary content' }], - }, - ], - tokenCounts: [100, 50], - }); - - await act(async () => { - await promise; - }); - - // Should no longer be compacting - expect(result.current.isCompacting).toBe(false); - }); - - it('preserves display: false for ancestor messages', async () => { - mockManageContextFromBackend.mockResolvedValue({ messages: [], tokenCounts: [] }); - - const hiddenMessage: Message = { - id: 'hidden-1', - role: 'user', - created: 1500, - content: [{ type: 'text', text: 'Secret' }], - }; - - const visibleMessage: Message = { - id: 'visible-1', - role: 'assistant', - created: 1600, - content: [{ type: 'text', text: 'Public' }], - }; - - const messages: Message[] = [hiddenMessage, visibleMessage]; - - const { result } = renderContextManager(); - - await act(async () => { - await result.current.handleAutoCompaction( - messages, - mockSetMessages, - mockAppend, - 'test-session-id' - ); - }); - - // No server messages -> setMessages called with empty list - expect(mockSetMessages).toHaveBeenCalledWith([]); - expect(mockAppend).not.toHaveBeenCalled(); - }); - }); - describe('handleManualCompaction', () => { it('should perform compaction with server-provided messages', async () => { mockManageContextFromBackend.mockResolvedValue({ messages: [ { - role: 'assistant', + ...default_message, content: [ - { type: 'summarizationRequested', msg: 'Conversation compacted and summarized' }, + { type: 'conversationCompacted', msg: 'Conversation compacted and summarized' }, ], }, { - role: 'assistant', + ...default_message, content: [{ type: 'text', text: 'Manual summary content' }], }, { - role: 'assistant', + ...default_message, content: [ { type: 'text', @@ -346,7 +146,7 @@ describe('ContextManager', () => { expect(setMessagesCall).toHaveLength(3); expect(setMessagesCall[0]).toMatchObject({ role: 'assistant', - content: [{ type: 'summarizationRequested', msg: 'Conversation compacted and summarized' }], + content: [{ type: 'conversationCompacted', msg: 'Conversation compacted and summarized' }], }); expect(setMessagesCall[1]).toMatchObject({ role: 'assistant', @@ -375,7 +175,7 @@ describe('ContextManager', () => { mockManageContextFromBackend.mockResolvedValue({ messages: [ { - role: 'assistant', + ...default_message, content: [{ type: 'text', text: 'Manual summary content' }], }, ], @@ -408,17 +208,17 @@ describe('ContextManager', () => { mockManageContextFromBackend.mockResolvedValue({ messages: [ { - role: 'assistant', + ...default_message, content: [ - { type: 'summarizationRequested', msg: 'Conversation compacted and summarized' }, + { type: 'conversationCompacted', msg: 'Conversation compacted and summarized' }, ], }, { - role: 'assistant', + ...default_message, content: [{ type: 'text', text: 'Manual summary content' }], }, { - role: 'assistant', + ...default_message, content: [ { type: 'text', @@ -447,7 +247,7 @@ describe('ContextManager', () => { expect(setMessagesCall).toHaveLength(3); expect(setMessagesCall[0]).toMatchObject({ role: 'assistant', - content: [{ type: 'summarizationRequested', msg: 'Conversation compacted and summarized' }], + content: [{ type: 'conversationCompacted', msg: 'Conversation compacted and summarized' }], }); expect(setMessagesCall[1]).toMatchObject({ role: 'assistant', @@ -473,65 +273,6 @@ describe('ContextManager', () => { }); }); - describe('Error Handling', () => { - it('should handle backend errors with unknown error type', async () => { - mockManageContextFromBackend.mockRejectedValue('String error'); - - const { result } = renderContextManager(); - - await act(async () => { - await result.current.handleAutoCompaction( - mockMessages, - mockSetMessages, - mockAppend, - 'test-session-id' - ); - }); - - expect(result.current.compactionError).toBe('Unknown error during compaction'); - }); - - it('should handle missing summary content gracefully with server-provided messages', async () => { - mockManageContextFromBackend.mockResolvedValue({ - messages: [ - { - role: 'assistant', - content: [ - { type: 'toolResponse', id: 'test', toolResult: { content: 'Not text content' } }, - ], - } as Message, - ], - tokenCounts: [100, 50], - }); - - const { result } = renderContextManager(); - - await act(async () => { - await result.current.handleAutoCompaction( - mockMessages, - mockSetMessages, - mockAppend, - 'test-session-id' - ); - }); - - // Should complete without error even if content is not text - expect(result.current.isCompacting).toBe(false); - expect(result.current.compactionError).toBe(null); - - // Should still set messages from server - expect(mockSetMessages).toHaveBeenCalledTimes(1); - const setMessagesCall = mockSetMessages.mock.calls[0][0]; - expect(setMessagesCall).toHaveLength(1); - expect(setMessagesCall[0]).toMatchObject({ - role: 'assistant', - content: [ - { type: 'toolResponse', id: 'test', toolResult: { content: 'Not text content' } }, - ], - }); - }); - }); - describe('Context Provider Error', () => { it('should throw error when useContextManager is used outside provider', () => { expect(() => { diff --git a/ui/desktop/src/hooks/useChatEngine.test.ts b/ui/desktop/src/hooks/useChatEngine.test.ts index 198b37625e8d..f1241a1ff2b2 100644 --- a/ui/desktop/src/hooks/useChatEngine.test.ts +++ b/ui/desktop/src/hooks/useChatEngine.test.ts @@ -71,25 +71,39 @@ describe('useChatEngine', () => { describe('onMessageUpdate', () => { it('should truncate history and append the updated message when a message is edited', () => { // --- 1. ARRANGE --- + const metadata = { + agentVisible: true, + userVisible: true, + }; + const initialMessages: Message[] = [ - { id: '1', role: 'user', content: [{ type: 'text', text: 'First message' }], created: 0 }, + { + id: '1', + role: 'user', + content: [{ type: 'text', text: 'First message' }], + created: 0, + metadata, + }, { id: '2', role: 'assistant', content: [{ type: 'text', text: 'First response' }], created: 1, + metadata, }, { id: '3', role: 'user', content: [{ type: 'text', text: 'Message to be edited' }], created: 2, + metadata, }, { id: '4', role: 'assistant', content: [{ type: 'text', text: 'Response to be deleted' }], created: 3, + metadata, }, ]; diff --git a/ui/desktop/src/hooks/useChatEngine.ts b/ui/desktop/src/hooks/useChatEngine.ts index 6e99a519ad59..1c0f6b7e47a4 100644 --- a/ui/desktop/src/hooks/useChatEngine.ts +++ b/ui/desktop/src/hooks/useChatEngine.ts @@ -340,6 +340,7 @@ export const useChatEngine = ({ role: 'user', created: Date.now(), content: [], + metadata: { userVisible: true, agentVisible: true }, }; const notification = 'Interrupted by the user to make a correction'; diff --git a/ui/desktop/src/hooks/useChatStream.ts b/ui/desktop/src/hooks/useChatStream.ts index 65348804308a..142f60c4b541 100644 --- a/ui/desktop/src/hooks/useChatStream.ts +++ b/ui/desktop/src/hooks/useChatStream.ts @@ -49,6 +49,7 @@ export function useChatStream({ role: 'user', content: [{ type: 'text', text: userMessage }], created: Date.now(), + metadata: { userVisible: true, agentVisible: true }, }; let currentMessages = [...messages, newMessage]; diff --git a/ui/desktop/src/hooks/useMessageStream.ts b/ui/desktop/src/hooks/useMessageStream.ts index 1b3781839e77..6e8febee04f0 100644 --- a/ui/desktop/src/hooks/useMessageStream.ts +++ b/ui/desktop/src/hooks/useMessageStream.ts @@ -1,7 +1,7 @@ import { useCallback, useEffect, useId, useReducer, useRef, useState } from 'react'; import useSWR from 'swr'; import { createUserMessage, hasCompletedToolCalls } from '../types/message'; -import { Message, Role } from '../api'; +import { Conversation, Message, Role } from '../api'; import { getSession, Session } from '../api'; import { ChatState } from '../types/chatState'; @@ -34,6 +34,7 @@ type MessageEvent = | { type: 'Error'; error: string } | { type: 'Finish'; reason: string } | { type: 'ModelChange'; model: string; mode: string } + | { type: 'UpdateConversation'; conversation: Conversation } | NotificationEvent; export interface UseMessageStreamOptions { @@ -328,6 +329,11 @@ export function useMessageStream({ break; } + case 'UpdateConversation': { + setMessages(parsedEvent.conversation); + break; + } + case 'Error': { // Always throw the error so it gets caught and sets the error state // This ensures the retry UI appears for ALL errors @@ -384,6 +390,7 @@ export function useMessageStream({ return currentMessages; }, + // eslint-disable-next-line react-hooks/exhaustive-deps [mutate, mutateChatState, onFinish, onError, forceUpdate, setError] ); @@ -580,6 +587,7 @@ export function useMessageStream({ id: generateMessageId(), role: 'user' as const, created: Math.floor(Date.now() / 1000), + metadata: { userVisible: true, agentVisible: true }, content: [ { type: 'toolResponse' as const, diff --git a/ui/desktop/src/types/message.ts b/ui/desktop/src/types/message.ts index c5273c10c99d..a598556e9096 100644 --- a/ui/desktop/src/types/message.ts +++ b/ui/desktop/src/types/message.ts @@ -1,4 +1,4 @@ -import { Content, Message, ToolConfirmationRequest, ToolRequest, ToolResponse } from '../api'; +import { Message, ToolConfirmationRequest, ToolRequest, ToolResponse } from '../api'; export type ToolRequestMessageContent = ToolRequest & { type: 'toolRequest' }; export type ToolResponseMessageContent = ToolResponse & { type: 'toolResponse' }; @@ -9,58 +9,7 @@ export function createUserMessage(text: string): Message { role: 'user', created: Math.floor(Date.now() / 1000), content: [{ type: 'text', text }], - }; -} - -export function createAssistantMessage(text: string): Message { - return { - id: generateId(), - role: 'assistant', - created: Math.floor(Date.now() / 1000), - content: [{ type: 'text', text }], - }; -} - -export function createToolRequestMessage( - id: string, - toolName: string, - args: Record -): Message { - return { - id: generateId(), - role: 'assistant', - created: Math.floor(Date.now() / 1000), - content: [ - { - type: 'toolRequest', - id, - toolCall: { - status: 'success', - value: { - name: toolName, - arguments: args, - }, - }, - }, - ], - }; -} - -export function createToolResponseMessage(id: string, result: Content[]): Message { - return { - id: generateId(), - role: 'user', - created: Math.floor(Date.now() / 1000), - content: [ - { - type: 'toolResponse', - id, - toolResult: { - status: 'success', - value: result, - }, - }, - ], + metadata: { userVisible: true, agentVisible: true }, }; } @@ -79,6 +28,7 @@ export function createToolErrorResponseMessage(id: string, error: string): Messa }, }, ], + metadata: { userVisible: true, agentVisible: true }, }; } @@ -90,7 +40,6 @@ export function getTextContent(message: Message): string { return message.content .map((content) => { if (content.type === 'text') return content.text; - if (content.type === 'contextLengthExceeded') return content.msg; return ''; }) .join('');