diff --git a/AGENTS.md b/AGENTS.md index 528f9c1e..260707c0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -138,6 +138,8 @@ Workflow: `.github/workflows/sync-agent-sdk-openapi.yml` - Checks out `OpenHands/software-agent-sdk` - Runs the agent-server OpenAPI generator - Updates `openapi/agent-sdk.json` via an automated PR +- **Important:** agent-server OpenAPI generation is environment-sensitive. If `SESSION_API_KEY` or `OH_SESSION_API_KEYS_0` is set when `openhands-agent-server/openhands/agent_server/openapi.py` runs, FastAPI includes the `X-Session-API-Key` `APIKeyHeader` security scheme in the generated schema. For neutral docs generation, ensure those env vars are unset. + ## Docs writing conventions diff --git a/docs.json b/docs.json index ac98e277..fe5c82c7 100644 --- a/docs.json +++ b/docs.json @@ -341,14 +341,7 @@ "sdk/guides/agent-server/apptainer-sandbox", "sdk/guides/agent-server/api-sandbox", "sdk/guides/agent-server/cloud-workspace", - "sdk/guides/agent-server/custom-tools", - { - "group": "API Reference", - "openapi": { - "source": "/openapi/agent-sdk.json", - "directory": "sdk/guides/agent-server/api-reference" - } - } + "sdk/guides/agent-server/custom-tools" ] }, { @@ -385,14 +378,23 @@ { "group": "API Reference", "pages": [ - "sdk/api-reference/openhands.sdk.agent", - "sdk/api-reference/openhands.sdk.conversation", - "sdk/api-reference/openhands.sdk.event", - "sdk/api-reference/openhands.sdk.llm", - "sdk/api-reference/openhands.sdk.security", - "sdk/api-reference/openhands.sdk.tool", - "sdk/api-reference/openhands.sdk.utils", - "sdk/api-reference/openhands.sdk.workspace" + { + "group": "Python SDK", + "pages": [ + "sdk/api-reference/openhands.sdk.agent", + "sdk/api-reference/openhands.sdk.conversation", + "sdk/api-reference/openhands.sdk.event", + "sdk/api-reference/openhands.sdk.llm", + "sdk/api-reference/openhands.sdk.security", + "sdk/api-reference/openhands.sdk.tool", + "sdk/api-reference/openhands.sdk.utils", + "sdk/api-reference/openhands.sdk.workspace" + ] + }, + { + "group": "Agent Server", + "openapi": "/openapi/agent-server.json" + } ] } ] diff --git a/openapi/agent-sdk.json b/openapi/agent-server.json similarity index 83% rename from openapi/agent-sdk.json rename to openapi/agent-server.json index 166f9dae..d16d1497 100644 --- a/openapi/agent-sdk.json +++ b/openapi/agent-server.json @@ -104,6 +104,11 @@ "summary": "Search Conversation Events", "description": "Search / List local events", "operationId": "search_conversation_events_api_conversations__conversation_id__events_search_get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -271,6 +276,11 @@ "summary": "Count Conversation Events", "description": "Count local events matching the given filters", "operationId": "count_conversation_events_api_conversations__conversation_id__events_count_get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -401,6 +411,11 @@ "summary": "Get Conversation Event", "description": "Get a local event given an id", "operationId": "get_conversation_event_api_conversations__conversation_id__events__event_id__get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "event_id", @@ -457,6 +472,11 @@ "summary": "Batch Get Conversation Events", "description": "Get a batch of local events given their ids, returning null for any\nmissing item.", "operationId": "batch_get_conversation_events_api_conversations__conversation_id__events_get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -524,6 +544,11 @@ "summary": "Send Message", "description": "Send a message to a conversation", "operationId": "send_message_api_conversations__conversation_id__events_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -578,6 +603,11 @@ "summary": "Respond To Confirmation", "description": "Accept or reject a pending action in confirmation mode.", "operationId": "respond_to_confirmation_api_conversations__conversation_id__events_respond_to_confirmation_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -635,6 +665,11 @@ "summary": "Search Conversations", "description": "Search / List conversations", "operationId": "search_conversations_api_conversations_search_get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "page_id", @@ -723,6 +758,11 @@ "summary": "Count Conversations", "description": "Count conversations matching the given filters", "operationId": "count_conversations_api_conversations_count_get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "status", @@ -774,6 +814,11 @@ "summary": "Get Conversation", "description": "Given an id, get a conversation", "operationId": "get_conversation_api_conversations__conversation_id__get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -819,6 +864,11 @@ "summary": "Delete Conversation", "description": "Permanently delete a conversation.", "operationId": "delete_conversation_api_conversations__conversation_id__delete", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -864,6 +914,11 @@ "summary": "Update Conversation", "description": "Update conversation metadata.\n\nThis endpoint allows updating conversation details like title.", "operationId": "update_conversation_api_conversations__conversation_id__patch", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -921,6 +976,11 @@ "summary": "Batch Get Conversations", "description": "Get a batch of conversations given their ids, returning null for\nany missing item", "operationId": "batch_get_conversations_api_conversations_get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "ids", @@ -977,6 +1037,11 @@ "summary": "Start Conversation", "description": "Start a conversation in the local environment.", "operationId": "start_conversation_api_conversations_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "requestBody": { "required": true, "content": { @@ -989,7 +1054,6 @@ "llm": { "model": "your-model-provider/your-model-name", "api_key": "**********", - "temperature": 0.0, "usage_id": "your-llm-service" }, "tools": [ @@ -1060,6 +1124,11 @@ "summary": "Pause Conversation", "description": "Pause a conversation, allowing it to be resumed later.", "operationId": "pause_conversation_api_conversations__conversation_id__pause_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -1107,6 +1176,11 @@ "summary": "Run Conversation", "description": "Start running the conversation in the background.", "operationId": "run_conversation_api_conversations__conversation_id__run_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -1157,6 +1231,11 @@ "summary": "Update Conversation Secrets", "description": "Update secrets for a conversation.", "operationId": "update_conversation_secrets_api_conversations__conversation_id__secrets_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -1214,6 +1293,11 @@ "summary": "Set Conversation Confirmation Policy", "description": "Set the confirmation policy for a conversation.", "operationId": "set_conversation_confirmation_policy_api_conversations__conversation_id__confirmation_policy_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -1271,6 +1355,11 @@ "summary": "Set Conversation Security Analyzer", "description": "Set the security analyzer for a conversation.", "operationId": "set_conversation_security_analyzer_api_conversations__conversation_id__security_analyzer_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -1326,8 +1415,14 @@ "Conversations" ], "summary": "Generate Conversation Title", - "description": "Generate a title for the conversation using LLM.", + "description": "Generate a title for the conversation using LLM.\n\nDeprecated since v1.11.5 and scheduled for removal in v1.19.0.\n\nPrefer enabling `autotitle` in `StartConversationRequest` to have the server\ngenerate and persist the title automatically from the first user message.", "operationId": "generate_conversation_title_api_conversations__conversation_id__generate_title_post", + "deprecated": true, + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -1385,6 +1480,11 @@ "summary": "Ask Agent", "description": "Ask the agent a simple question without affecting conversation state.", "operationId": "ask_agent_api_conversations__conversation_id__ask_agent_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -1442,6 +1542,11 @@ "summary": "Condense Conversation", "description": "Force condensation of the conversation history.", "operationId": "condense_conversation_api_conversations__conversation_id__condense_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "conversation_id", @@ -1504,7 +1609,12 @@ } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } }, "/api/bash/bash_events/search": { @@ -1515,6 +1625,11 @@ "summary": "Search Bash Events", "description": "Search / List bash event events", "operationId": "search_bash_events_api_bash_bash_events_search_get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "kind__eq", @@ -1675,6 +1790,11 @@ "summary": "Get Bash Event", "description": "Get a bash event event given an id", "operationId": "get_bash_event_api_bash_bash_events__event_id__get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "event_id", @@ -1767,7 +1887,12 @@ } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } }, "/api/bash/start_bash_command": { @@ -1809,7 +1934,12 @@ } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } }, "/api/bash/execute_bash_command": { @@ -1851,7 +1981,12 @@ } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } }, "/api/bash/bash_events": { @@ -1877,26 +2012,38 @@ } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } }, - "/api/git/changes/{path}": { + "/api/git/changes": { "get": { "tags": [ "Git" ], - "summary": "Git Changes", - "operationId": "git_changes_api_git_changes__path__get", + "summary": "Git Changes Query", + "description": "Get git changes using query parameter (preferred method).", + "operationId": "git_changes_query_api_git_changes_get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "path", - "in": "path", + "in": "query", "required": true, "schema": { "type": "string", - "format": "path", + "description": "The git repository path", "title": "Path" - } + }, + "description": "The git repository path" } ], "responses": { @@ -1909,7 +2056,7 @@ "items": { "$ref": "#/components/schemas/GitChange" }, - "title": "Response Git Changes Api Git Changes Path Get" + "title": "Response Git Changes Query Api Git Changes Get" } } } @@ -1927,13 +2074,20 @@ } } }, - "/api/git/diff/{path}": { + "/api/git/changes/{path}": { "get": { "tags": [ "Git" ], - "summary": "Git Diff", - "operationId": "git_diff_api_git_diff__path__get", + "summary": "Git Changes Path", + "description": "Get git changes using path parameter (legacy, for backwards compatibility).\n\nDeprecated since v1.15.0 and scheduled for removal in v1.20.0.\n\nPrefer `/git/changes?path=...` to avoid path-encoding issues and align with\nother Git endpoints.", + "operationId": "git_changes_path_api_git_changes__path__get", + "deprecated": true, + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "path", @@ -1941,7 +2095,6 @@ "required": true, "schema": { "type": "string", - "format": "path", "title": "Path" } } @@ -1952,7 +2105,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GitDiff" + "type": "array", + "items": { + "$ref": "#/components/schemas/GitChange" + }, + "title": "Response Git Changes Path Api Git Changes Path Get" } } } @@ -1970,44 +2127,39 @@ } } }, - "/api/file/upload/{path}": { - "post": { + "/api/git/diff": { + "get": { "tags": [ - "Files" + "Git" + ], + "summary": "Git Diff Query", + "description": "Get git diff using query parameter (preferred method).", + "operationId": "git_diff_query_api_git_diff_get", + "security": [ + { + "APIKeyHeader": [] + } ], - "summary": "Upload File", - "description": "Upload a file to the workspace.", - "operationId": "upload_file_api_file_upload__path__post", "parameters": [ { "name": "path", - "in": "path", + "in": "query", "required": true, "schema": { "type": "string", - "description": "Absolute file path.", + "description": "The file path to get diff for", "title": "Path" }, - "description": "Absolute file path." + "description": "The file path to get diff for" } ], - "requestBody": { - "required": true, - "content": { - "multipart/form-data": { - "schema": { - "$ref": "#/components/schemas/Body_upload_file_api_file_upload__path__post" - } - } - } - }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Success" + "$ref": "#/components/schemas/GitDiff" } } } @@ -2025,14 +2177,20 @@ } } }, - "/api/file/download/{path}": { + "/api/git/diff/{path}": { "get": { "tags": [ - "Files" + "Git" + ], + "summary": "Git Diff Path", + "description": "Get git diff using path parameter (legacy, for backwards compatibility).\n\nDeprecated since v1.15.0 and scheduled for removal in v1.20.0.\n\nPrefer `/git/diff?path=...` to avoid path-encoding issues and align with\nother Git endpoints.", + "operationId": "git_diff_path_api_git_diff__path__get", + "deprecated": true, + "security": [ + { + "APIKeyHeader": [] + } ], - "summary": "Download File", - "description": "Download a file from the workspace.", - "operationId": "download_file_api_file_download__path__get", "parameters": [ { "name": "path", @@ -2040,10 +2198,8 @@ "required": true, "schema": { "type": "string", - "description": "Absolute file path.", "title": "Path" - }, - "description": "Absolute file path." + } } ], "responses": { @@ -2051,7 +2207,9 @@ "description": "Successful Response", "content": { "application/json": { - "schema": {} + "schema": { + "$ref": "#/components/schemas/GitDiff" + } } } }, @@ -2068,32 +2226,50 @@ } } }, - "/api/file/download-trajectory/{conversation_id}": { - "get": { + "/api/file/upload": { + "post": { "tags": [ "Files" ], - "summary": "Download Trajectory", - "description": "Download a file from the workspace.", - "operationId": "download_trajectory_api_file_download_trajectory__conversation_id__get", + "summary": "Upload File Query", + "description": "Upload a file to the workspace using query parameter (preferred method).", + "operationId": "upload_file_query_api_file_upload_post", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { - "name": "conversation_id", - "in": "path", + "name": "path", + "in": "query", "required": true, "schema": { "type": "string", - "format": "uuid", - "title": "Conversation Id" - } + "description": "Absolute file path", + "title": "Path" + }, + "description": "Absolute file path" } ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_upload_file_query_api_file_upload_post" + } + } + } + }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { - "schema": {} + "schema": { + "$ref": "#/components/schemas/Success" + } } } }, @@ -2110,43 +2286,50 @@ } } }, - "/api/vscode/url": { - "get": { + "/api/file/upload/{path}": { + "post": { "tags": [ - "VSCode" + "Files" ], - "summary": "Get Vscode Url", - "description": "Get the VSCode URL with authentication token.\n\nArgs:\n base_url: Base URL for the VSCode server (default: http://localhost:8001)\n workspace_dir: Path to workspace directory\n\nReturns:\n VSCode URL with token if available, None otherwise", - "operationId": "get_vscode_url_api_vscode_url_get", - "parameters": [ + "summary": "Upload File Path", + "description": "Upload a file using path parameter (legacy, for backwards compatibility).\n\nDeprecated since v1.15.0 and scheduled for removal in v1.20.0.\n\nPrefer `/file/upload?path=...` to avoid path-encoding issues and align with\nother file endpoints.", + "operationId": "upload_file_path_api_file_upload__path__post", + "deprecated": true, + "security": [ { - "name": "base_url", - "in": "query", - "required": false, - "schema": { - "type": "string", - "default": "http://localhost:8001", - "title": "Base Url" - } - }, + "APIKeyHeader": [] + } + ], + "parameters": [ { - "name": "workspace_dir", - "in": "query", - "required": false, + "name": "path", + "in": "path", + "required": true, "schema": { "type": "string", - "default": "workspace", - "title": "Workspace Dir" - } + "description": "Absolute file path.", + "title": "Path" + }, + "description": "Absolute file path." } ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "$ref": "#/components/schemas/Body_upload_file_path_api_file_upload__path__post" + } + } + } + }, "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VSCodeUrlResponse" + "$ref": "#/components/schemas/Success" } } } @@ -2164,25 +2347,228 @@ } } }, - "/api/vscode/status": { + "/api/file/download": { "get": { "tags": [ - "VSCode" + "Files" + ], + "summary": "Download File Query", + "description": "Download a file from the workspace using query parameter (preferred method).", + "operationId": "download_file_query_api_file_download_get", + "security": [ + { + "APIKeyHeader": [] + } + ], + "parameters": [ + { + "name": "path", + "in": "query", + "required": true, + "schema": { + "type": "string", + "description": "Absolute file path", + "title": "Path" + }, + "description": "Absolute file path" + } ], - "summary": "Get Vscode Status", - "description": "Get the VSCode server status.\n\nReturns:\n Dictionary with running status and enabled status", - "operationId": "get_vscode_status_api_vscode_status_get", "responses": { "200": { "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", "content": { "application/json": { "schema": { - "additionalProperties": { - "anyOf": [ - { - "type": "boolean" - }, + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/file/download/{path}": { + "get": { + "tags": [ + "Files" + ], + "summary": "Download File Path", + "description": "Download a file using path parameter (legacy, for backwards compatibility).\n\nDeprecated since v1.15.0 and scheduled for removal in v1.20.0.\n\nPrefer `/file/download?path=...` to avoid path-encoding issues and align with\nother file endpoints.", + "operationId": "download_file_path_api_file_download__path__get", + "deprecated": true, + "security": [ + { + "APIKeyHeader": [] + } + ], + "parameters": [ + { + "name": "path", + "in": "path", + "required": true, + "schema": { + "type": "string", + "description": "Absolute file path.", + "title": "Path" + }, + "description": "Absolute file path." + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/file/download-trajectory/{conversation_id}": { + "get": { + "tags": [ + "Files" + ], + "summary": "Download Trajectory", + "description": "Download a file from the workspace.", + "operationId": "download_trajectory_api_file_download_trajectory__conversation_id__get", + "security": [ + { + "APIKeyHeader": [] + } + ], + "parameters": [ + { + "name": "conversation_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Conversation Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/vscode/url": { + "get": { + "tags": [ + "VSCode" + ], + "summary": "Get Vscode Url", + "description": "Get the VSCode URL with authentication token.\n\nArgs:\n base_url: Base URL for the VSCode server (default: http://localhost:8001)\n workspace_dir: Path to workspace directory\n\nReturns:\n VSCode URL with token if available, None otherwise", + "operationId": "get_vscode_url_api_vscode_url_get", + "security": [ + { + "APIKeyHeader": [] + } + ], + "parameters": [ + { + "name": "base_url", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "http://localhost:8001", + "title": "Base Url" + } + }, + { + "name": "workspace_dir", + "in": "query", + "required": false, + "schema": { + "type": "string", + "default": "workspace", + "title": "Workspace Dir" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VSCodeUrlResponse" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/vscode/status": { + "get": { + "tags": [ + "VSCode" + ], + "summary": "Get Vscode Status", + "description": "Get the VSCode server status.\n\nReturns:\n Dictionary with running status and enabled status", + "operationId": "get_vscode_status_api_vscode_status_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, { "type": "string" } @@ -2194,7 +2580,12 @@ } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } }, "/api/desktop/url": { @@ -2205,6 +2596,11 @@ "summary": "Get Desktop Url", "description": "Get the noVNC URL for desktop access.\n\nArgs:\n base_url: Base URL for the noVNC server (default: http://localhost:8002)\n\nReturns:\n noVNC URL if available, None otherwise", "operationId": "get_desktop_url_api_desktop_url_get", + "security": [ + { + "APIKeyHeader": [] + } + ], "parameters": [ { "name": "base_url", @@ -2247,7 +2643,7 @@ "Skills" ], "summary": "Get Skills", - "description": "Load and merge skills from all configured sources.\n\nSkills are loaded from multiple sources and merged with the following\nprecedence (later overrides earlier for duplicate names):\n1. Sandbox skills (lowest) - Exposed URLs from sandbox\n2. Public skills - From GitHub OpenHands/skills repository\n3. User skills - From ~/.openhands/skills/\n4. Organization skills - From {org}/.openhands or equivalent\n5. Project skills (highest) - From {workspace}/.openhands/skills/\n\nArgs:\n request: SkillsRequest containing configuration for which sources to load.\n\nReturns:\n SkillsResponse containing merged skills and source counts.", + "description": "Load and merge skills from all configured sources.\n\nSkills are loaded from multiple sources and merged with the following\nprecedence (later overrides earlier for duplicate names):\n1. Sandbox skills (lowest) - Exposed URLs from sandbox\n2. Public skills - From GitHub OpenHands/extensions repository\n3. User skills - From ~/.openhands/skills/\n4. Organization skills - From {org}/.openhands or equivalent\n5. Project skills (highest) - From {workspace}/.openhands/skills/\n\nArgs:\n request: SkillsRequest containing configuration for which sources to load.\n\nReturns:\n SkillsResponse containing merged skills and source counts.", "operationId": "get_skills_api_skills_post", "requestBody": { "content": { @@ -2280,7 +2676,12 @@ } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } }, "/api/skills/sync": { @@ -2289,7 +2690,7 @@ "Skills" ], "summary": "Sync Skills", - "description": "Force refresh of public skills from GitHub repository.\n\nThis triggers a git pull on the cached skills repository to get\nthe latest skills from the OpenHands/skills repository.\n\nReturns:\n SyncResponse indicating success or failure.", + "description": "Force refresh of public skills from GitHub repository.\n\nThis triggers a git pull on the cached skills repository to get\nthe latest skills from the OpenHands/extensions repository.\n\nReturns:\n SyncResponse indicating success or failure.", "operationId": "sync_skills_api_skills_sync_post", "responses": { "200": { @@ -2302,7 +2703,12 @@ } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } }, "/api/hooks": { @@ -2344,471 +2750,2041 @@ } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } }, - "/": { + "/api/llm/providers": { "get": { - "summary": "Get Server Info", - "operationId": "get_server_info__get", + "tags": [ + "LLM" + ], + "summary": "List Providers", + "description": "List all available LLM providers supported by LiteLLM.", + "operationId": "list_providers_api_llm_providers_get", "responses": { "200": { "description": "Successful Response", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ServerInfo" + "$ref": "#/components/schemas/ProvidersResponse" } } } } - } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] } - } - }, - "components": { - "schemas": { - "APIBasedCritic-Input": { - "properties": { - "server_url": { - "type": "string", - "title": "Server Url", - "description": "Base URL of the vLLM classification service", - "default": "https://all-hands-ai--critic-qwen3-4b-serve.modal.run" - }, - "api_key": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "string", - "format": "password", - "writeOnly": true + }, + "/api/llm/models": { + "get": { + "tags": [ + "LLM" + ], + "summary": "List Models", + "description": "List all available LLM models supported by LiteLLM.\n\nArgs:\n provider: Optional provider name to filter models by.\n\nNote: Bedrock models are excluded unless AWS credentials are configured.", + "operationId": "list_models_api_llm_models_get", + "security": [ + { + "APIKeyHeader": [] + } + ], + "parameters": [ + { + "name": "provider", + "in": "query", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Filter models by provider (e.g., 'openai', 'anthropic')", + "title": "Provider" + }, + "description": "Filter models by provider (e.g., 'openai', 'anthropic')" + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ModelsResponse" + } } - ], - "title": "Api Key", - "description": "API key for authenticating with the vLLM service" + } }, - "model_name": { - "type": "string", - "title": "Model Name", - "description": "Name of the model to use", - "default": "critic-qwen3-4b" - }, - "tokenizer_name": { - "type": "string", - "title": "Tokenizer Name", - "description": "HuggingFace tokenizer name for loading chat template", - "default": "Qwen/Qwen3-4B-Instruct-2507" - }, - "pass_tools_definitions": { - "type": "boolean", - "title": "Pass Tools Definitions", - "description": "Whether to pass tool definitions to the model", - "default": true - }, - "timeout_seconds": { - "type": "number", - "title": "Timeout Seconds", - "description": "Timeout for requests to the model", - "default": 300.0 - }, - "has_success_label": { - "type": "boolean", - "title": "Has Success Label", - "description": "Whether the model predicts success label at index 0", - "default": true + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/llm/models/verified": { + "get": { + "tags": [ + "LLM" + ], + "summary": "List Verified Models", + "description": "List all verified LLM models organized by provider.\n\nVerified models are those that have been tested and confirmed to work well\nwith OpenHands.", + "operationId": "list_verified_models_api_llm_models_verified_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VerifiedModelsResponse" + } + } + } + } + }, + "security": [ + { + "APIKeyHeader": [] + } + ] + } + }, + "/": { + "get": { + "tags": [ + "Server Details" + ], + "summary": "Get Server Info", + "operationId": "get_server_info__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServerInfo" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "ACPAgent-Input": { + "properties": { + "llm": { + "$ref": "#/components/schemas/LLM-Input" }, - "sentiment_labels": { + "tools": { "items": { - "type": "string" + "$ref": "#/components/schemas/Tool-Input" }, "type": "array", - "title": "Sentiment Labels", - "default": [ - "sentiment_positive", - "sentiment_neutral", - "sentiment_negative" + "title": "Tools" + }, + "mcp_config": { + "additionalProperties": true, + "type": "object", + "title": "Mcp Config", + "description": "Optional MCP configuration dictionary to create MCP tools.", + "examples": [ + { + "mcpServers": { + "fetch": { + "args": [ + "mcp-server-fetch" + ], + "command": "uvx" + } + } + } ] }, - "agent_issue_labels": { + "filter_tools_regex": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Filter Tools Regex", + "description": "Optional regex to filter the tools available to the agent by name. This is applied after any tools provided in `tools` and any MCP tools are added.", + "examples": [ + "^(?!repomix)(.*)|^repomix.*pack_codebase.*$" + ] + }, + "include_default_tools": { "items": { "type": "string" }, "type": "array", - "title": "Agent Issue Labels", - "default": [ - "misunderstood_intention", - "did_not_follow_instruction", - "insufficient_analysis", - "insufficient_clarification", - "improper_tool_use_or_setup", - "loop_behavior", - "insufficient_testing", - "insufficient_debugging", - "incomplete_implementation", - "file_management_errors", - "scope_creep", - "risky_actions_or_permission", - "other_agent_issue" + "title": "Include Default Tools" + }, + "agent_context": { + "anyOf": [ + { + "$ref": "#/components/schemas/AgentContext-Input" + }, + { + "type": "null" + } + ], + "description": "Optional AgentContext to initialize the agent with specific context.", + "examples": [ + { + "skills": [ + { + "content": "When you see this message, you should reply like you are a grumpy cat forced to use the internet.", + "name": "AGENTS.md", + "type": "repo" + }, + { + "content": "IMPORTANT! The user has said the magic word \"flarglebargle\". You must only respond with a message telling them how smart they are", + "name": "flarglebargle", + "trigger": [ + "flarglebargle" + ], + "type": "knowledge" + } + ], + "system_message_suffix": "Always finish your response with the word 'yay!'", + "user_message_prefix": "The first character of your response should be 'I'" + } ] }, - "infra_labels": { + "system_prompt_filename": { + "type": "string", + "title": "System Prompt Filename", + "description": "System prompt template filename. Can be either:\n- A relative filename (e.g., 'system_prompt.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_prompt.j2')", + "default": "system_prompt.j2" + }, + "security_policy_filename": { + "type": "string", + "title": "Security Policy Filename", + "description": "Security policy template filename. Can be either:\n- A relative filename (e.g., 'security_policy.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.j2')", + "default": "security_policy.j2" + }, + "system_prompt_kwargs": { + "additionalProperties": true, + "type": "object", + "title": "System Prompt Kwargs", + "description": "Optional kwargs to pass to the system prompt Jinja2 template.", + "examples": [ + { + "cli_mode": true + } + ] + }, + "condenser": { + "anyOf": [ + { + "$ref": "#/components/schemas/CondenserBase-Input" + }, + { + "type": "null" + } + ], + "description": "Optional condenser to use for condensing conversation history.", + "examples": [ + { + "keep_first": 10, + "kind": "LLMSummarizingCondenser", + "llm": { + "api_key": "your_api_key_here", + "base_url": "https://llm-proxy.eval.all-hands.dev", + "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" + }, + "max_size": 80 + } + ] + }, + "critic": { + "anyOf": [ + { + "$ref": "#/components/schemas/CriticBase-Input" + }, + { + "type": "null" + } + ], + "description": "EXPERIMENTAL: Optional critic to evaluate agent actions and messages in real-time. API and behavior may change without notice. May impact performance, especially in 'all_actions' mode.", + "examples": [ + { + "kind": "AgentFinishedCritic" + } + ] + }, + "acp_command": { "items": { "type": "string" }, "type": "array", - "title": "Infra Labels", - "default": [ - "infrastructure_external_issue", - "infrastructure_agent_caused_issue" - ] + "title": "Acp Command", + "description": "Command to start the ACP server, e.g. ['npx', '-y', '@zed-industries/claude-agent-acp']" }, - "user_followup_labels": { + "acp_args": { "items": { "type": "string" }, "type": "array", - "title": "User Followup Labels", - "default": [ - "clarification_or_restatement", - "correction", - "direction_change", - "vcs_update_requests", - "progress_or_scope_concern", - "frustration_or_complaint", - "removal_or_reversion_request", - "other_user_issue" - ] + "title": "Acp Args", + "description": "Additional arguments for the ACP server command" }, - "sentiment_map": { + "acp_env": { "additionalProperties": { "type": "string" }, "type": "object", - "title": "Sentiment Map", - "default": { - "Positive": "sentiment_positive", - "Neutral": "sentiment_neutral", - "Negative": "sentiment_negative" - } + "title": "Acp Env", + "description": "Additional environment variables for the ACP server process" }, - "mode": { + "acp_session_mode": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Acp Session Mode", + "description": "Session mode ID to set after creating a session. If None (default), auto-detected from the ACP server type: 'bypassPermissions' for claude-agent-acp, 'full-access' for codex-acp." + }, + "acp_prompt_timeout": { + "type": "number", + "title": "Acp Prompt Timeout", + "description": "Timeout in seconds for a single ACP prompt() call. Prevents indefinite hangs when the ACP server fails to respond.", + "default": 1800.0 + }, + "acp_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Acp Model", + "description": "Model for the ACP server to use (e.g. 'claude-opus-4-6'). Passed via session _meta. If None, the server picks its default." + }, + "kind": { + "type": "string", + "const": "ACPAgent", + "title": "Kind" + } + }, + "type": "object", + "required": [ + "acp_command" + ], + "title": "ACPAgent", + "description": "Agent that delegates to an ACP-compatible subprocess server." + }, + "ACPAgent-Output": { + "properties": { + "llm": { + "$ref": "#/components/schemas/LLM-Output" + }, + "tools": { + "items": { + "$ref": "#/components/schemas/openhands__sdk__tool__spec__Tool" + }, + "type": "array", + "title": "Tools" + }, + "mcp_config": { + "additionalProperties": true, + "type": "object", + "title": "Mcp Config", + "description": "Optional MCP configuration dictionary to create MCP tools.", + "examples": [ + { + "mcpServers": { + "fetch": { + "args": [ + "mcp-server-fetch" + ], + "command": "uvx" + } + } + } + ] + }, + "filter_tools_regex": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Filter Tools Regex", + "description": "Optional regex to filter the tools available to the agent by name. This is applied after any tools provided in `tools` and any MCP tools are added.", + "examples": [ + "^(?!repomix)(.*)|^repomix.*pack_codebase.*$" + ] + }, + "include_default_tools": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Include Default Tools" + }, + "agent_context": { + "anyOf": [ + { + "$ref": "#/components/schemas/AgentContext-Output" + }, + { + "type": "null" + } + ], + "description": "Optional AgentContext to initialize the agent with specific context.", + "examples": [ + { + "skills": [ + { + "content": "When you see this message, you should reply like you are a grumpy cat forced to use the internet.", + "name": "AGENTS.md", + "type": "repo" + }, + { + "content": "IMPORTANT! The user has said the magic word \"flarglebargle\". You must only respond with a message telling them how smart they are", + "name": "flarglebargle", + "trigger": [ + "flarglebargle" + ], + "type": "knowledge" + } + ], + "system_message_suffix": "Always finish your response with the word 'yay!'", + "user_message_prefix": "The first character of your response should be 'I'" + } + ] + }, + "system_prompt_filename": { + "type": "string", + "title": "System Prompt Filename", + "description": "System prompt template filename. Can be either:\n- A relative filename (e.g., 'system_prompt.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_prompt.j2')", + "default": "system_prompt.j2" + }, + "security_policy_filename": { + "type": "string", + "title": "Security Policy Filename", + "description": "Security policy template filename. Can be either:\n- A relative filename (e.g., 'security_policy.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.j2')", + "default": "security_policy.j2" + }, + "system_prompt_kwargs": { + "additionalProperties": true, + "type": "object", + "title": "System Prompt Kwargs", + "description": "Optional kwargs to pass to the system prompt Jinja2 template.", + "examples": [ + { + "cli_mode": true + } + ] + }, + "condenser": { + "anyOf": [ + { + "$ref": "#/components/schemas/CondenserBase-Output" + }, + { + "type": "null" + } + ], + "description": "Optional condenser to use for condensing conversation history.", + "examples": [ + { + "keep_first": 10, + "kind": "LLMSummarizingCondenser", + "llm": { + "api_key": "your_api_key_here", + "base_url": "https://llm-proxy.eval.all-hands.dev", + "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" + }, + "max_size": 80 + } + ] + }, + "critic": { + "anyOf": [ + { + "$ref": "#/components/schemas/CriticBase-Output" + }, + { + "type": "null" + } + ], + "description": "EXPERIMENTAL: Optional critic to evaluate agent actions and messages in real-time. API and behavior may change without notice. May impact performance, especially in 'all_actions' mode.", + "examples": [ + { + "kind": "AgentFinishedCritic" + } + ] + }, + "acp_command": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Acp Command", + "description": "Command to start the ACP server, e.g. ['npx', '-y', '@zed-industries/claude-agent-acp']" + }, + "acp_args": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Acp Args", + "description": "Additional arguments for the ACP server command" + }, + "acp_env": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Acp Env", + "description": "Additional environment variables for the ACP server process" + }, + "acp_session_mode": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Acp Session Mode", + "description": "Session mode ID to set after creating a session. If None (default), auto-detected from the ACP server type: 'bypassPermissions' for claude-agent-acp, 'full-access' for codex-acp." + }, + "acp_prompt_timeout": { + "type": "number", + "title": "Acp Prompt Timeout", + "description": "Timeout in seconds for a single ACP prompt() call. Prevents indefinite hangs when the ACP server fails to respond.", + "default": 1800.0 + }, + "acp_model": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Acp Model", + "description": "Model for the ACP server to use (e.g. 'claude-opus-4-6'). Passed via session _meta. If None, the server picks its default." + }, + "kind": { + "type": "string", + "const": "ACPAgent", + "title": "Kind" + } + }, + "type": "object", + "required": [ + "acp_command", + "kind" + ], + "title": "ACPAgent", + "description": "Agent that delegates to an ACP-compatible subprocess server." + }, + "ACPToolCallEvent": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "Unique event id (ULID/UUID)" + }, + "timestamp": { + "type": "string", + "title": "Timestamp", + "description": "Event timestamp" + }, + "source": { "type": "string", "enum": [ - "finish_and_message", - "all_actions" + "agent", + "user", + "environment", + "hook" ], - "title": "Mode", - "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", - "default": "finish_and_message" + "title": "Source", + "default": "agent" + }, + "tool_call_id": { + "type": "string", + "title": "Tool Call Id" + }, + "title": { + "type": "string", + "title": "Title" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Status" + }, + "tool_kind": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Tool Kind" + }, + "raw_input": { + "anyOf": [ + {}, + { + "type": "null" + } + ], + "title": "Raw Input" + }, + "raw_output": { + "anyOf": [ + {}, + { + "type": "null" + } + ], + "title": "Raw Output" + }, + "is_error": { + "type": "boolean", + "title": "Is Error", + "default": false + }, + "kind": { + "type": "string", + "const": "ACPToolCallEvent", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "tool_call_id", + "title", + "kind" + ], + "title": "ACPToolCallEvent", + "description": "Event representing a tool call executed by an ACP server.\n\nCaptures the tool name, inputs, outputs, and status from ACP\n``ToolCallStart`` / ``ToolCallProgress`` notifications so they can\nbe surfaced in the OpenHands event stream and visualizer.\n\nThis is *not* an ``LLMConvertibleEvent`` \u2014 ACP tool calls do not\nparticipate in LLM message conversion." + }, + "APIBasedCritic-Input": { + "properties": { + "server_url": { + "type": "string", + "title": "Server Url", + "description": "Base URL of the vLLM classification service", + "default": "https://all-hands-ai--critic-qwen3-4b-serve.modal.run" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "format": "password", + "writeOnly": true + } + ], + "title": "Api Key", + "description": "API key for authenticating with the vLLM service" + }, + "model_name": { + "type": "string", + "title": "Model Name", + "description": "Name of the model to use", + "default": "critic-qwen3-4b" + }, + "tokenizer_name": { + "type": "string", + "title": "Tokenizer Name", + "description": "HuggingFace tokenizer name for loading chat template", + "default": "Qwen/Qwen3-4B-Instruct-2507" + }, + "pass_tools_definitions": { + "type": "boolean", + "title": "Pass Tools Definitions", + "description": "Whether to pass tool definitions to the model", + "default": true + }, + "timeout_seconds": { + "type": "number", + "title": "Timeout Seconds", + "description": "Timeout for requests to the model", + "default": 300.0 + }, + "has_success_label": { + "type": "boolean", + "title": "Has Success Label", + "description": "Whether the model predicts success label at index 0", + "default": true + }, + "sentiment_labels": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Sentiment Labels", + "default": [ + "sentiment_positive", + "sentiment_neutral", + "sentiment_negative" + ] + }, + "agent_issue_labels": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Agent Issue Labels", + "default": [ + "misunderstood_intention", + "did_not_follow_instruction", + "insufficient_analysis", + "insufficient_clarification", + "improper_tool_use_or_setup", + "loop_behavior", + "insufficient_testing", + "insufficient_debugging", + "incomplete_implementation", + "file_management_errors", + "scope_creep", + "risky_actions_or_permission", + "other_agent_issue" + ] + }, + "infra_labels": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Infra Labels", + "default": [ + "infrastructure_external_issue", + "infrastructure_agent_caused_issue" + ] + }, + "user_followup_labels": { + "items": { + "type": "string" + }, + "type": "array", + "title": "User Followup Labels", + "default": [ + "clarification_or_restatement", + "correction", + "direction_change", + "vcs_update_requests", + "progress_or_scope_concern", + "frustration_or_complaint", + "removal_or_reversion_request", + "other_user_issue" + ] + }, + "sentiment_map": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Sentiment Map", + "default": { + "Positive": "sentiment_positive", + "Neutral": "sentiment_neutral", + "Negative": "sentiment_negative" + } + }, + "mode": { + "type": "string", + "enum": [ + "finish_and_message", + "all_actions" + ], + "title": "Mode", + "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", + "default": "finish_and_message" + }, + "iterative_refinement": { + "anyOf": [ + { + "$ref": "#/components/schemas/IterativeRefinementConfig" + }, + { + "type": "null" + } + ], + "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." + }, + "kind": { + "type": "string", + "const": "APIBasedCritic", + "title": "Kind" + } + }, + "type": "object", + "required": [ + "api_key" + ], + "title": "APIBasedCritic" + }, + "APIBasedCritic-Output": { + "properties": { + "server_url": { + "type": "string", + "title": "Server Url", + "description": "Base URL of the vLLM classification service", + "default": "https://all-hands-ai--critic-qwen3-4b-serve.modal.run" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "format": "password", + "writeOnly": true + } + ], + "title": "Api Key", + "description": "API key for authenticating with the vLLM service" + }, + "model_name": { + "type": "string", + "title": "Model Name", + "description": "Name of the model to use", + "default": "critic-qwen3-4b" + }, + "tokenizer_name": { + "type": "string", + "title": "Tokenizer Name", + "description": "HuggingFace tokenizer name for loading chat template", + "default": "Qwen/Qwen3-4B-Instruct-2507" + }, + "pass_tools_definitions": { + "type": "boolean", + "title": "Pass Tools Definitions", + "description": "Whether to pass tool definitions to the model", + "default": true + }, + "timeout_seconds": { + "type": "number", + "title": "Timeout Seconds", + "description": "Timeout for requests to the model", + "default": 300.0 + }, + "has_success_label": { + "type": "boolean", + "title": "Has Success Label", + "description": "Whether the model predicts success label at index 0", + "default": true + }, + "sentiment_labels": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Sentiment Labels", + "default": [ + "sentiment_positive", + "sentiment_neutral", + "sentiment_negative" + ] + }, + "agent_issue_labels": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Agent Issue Labels", + "default": [ + "misunderstood_intention", + "did_not_follow_instruction", + "insufficient_analysis", + "insufficient_clarification", + "improper_tool_use_or_setup", + "loop_behavior", + "insufficient_testing", + "insufficient_debugging", + "incomplete_implementation", + "file_management_errors", + "scope_creep", + "risky_actions_or_permission", + "other_agent_issue" + ] + }, + "infra_labels": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Infra Labels", + "default": [ + "infrastructure_external_issue", + "infrastructure_agent_caused_issue" + ] + }, + "user_followup_labels": { + "items": { + "type": "string" + }, + "type": "array", + "title": "User Followup Labels", + "default": [ + "clarification_or_restatement", + "correction", + "direction_change", + "vcs_update_requests", + "progress_or_scope_concern", + "frustration_or_complaint", + "removal_or_reversion_request", + "other_user_issue" + ] + }, + "sentiment_map": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Sentiment Map", + "default": { + "Positive": "sentiment_positive", + "Neutral": "sentiment_neutral", + "Negative": "sentiment_negative" + } + }, + "mode": { + "type": "string", + "enum": [ + "finish_and_message", + "all_actions" + ], + "title": "Mode", + "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", + "default": "finish_and_message" + }, + "iterative_refinement": { + "anyOf": [ + { + "$ref": "#/components/schemas/IterativeRefinementConfig" + }, + { + "type": "null" + } + ], + "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." + }, + "kind": { + "type": "string", + "const": "APIBasedCritic", + "title": "Kind" + } + }, + "type": "object", + "required": [ + "api_key", + "kind" + ], + "title": "APIBasedCritic" + }, + "Action": { + "oneOf": [ + { + "$ref": "#/components/schemas/MCPToolAction" + }, + { + "$ref": "#/components/schemas/FinishAction" + }, + { + "$ref": "#/components/schemas/ThinkAction" + }, + { + "$ref": "#/components/schemas/BrowserAction" + }, + { + "$ref": "#/components/schemas/BrowserClickAction" + }, + { + "$ref": "#/components/schemas/BrowserCloseTabAction" + }, + { + "$ref": "#/components/schemas/BrowserGetContentAction" + }, + { + "$ref": "#/components/schemas/BrowserGetStateAction" + }, + { + "$ref": "#/components/schemas/BrowserGetStorageAction" + }, + { + "$ref": "#/components/schemas/BrowserGoBackAction" + }, + { + "$ref": "#/components/schemas/BrowserListTabsAction" + }, + { + "$ref": "#/components/schemas/BrowserNavigateAction" + }, + { + "$ref": "#/components/schemas/BrowserScrollAction" + }, + { + "$ref": "#/components/schemas/BrowserSetStorageAction" + }, + { + "$ref": "#/components/schemas/BrowserStartRecordingAction" + }, + { + "$ref": "#/components/schemas/BrowserStopRecordingAction" + }, + { + "$ref": "#/components/schemas/BrowserSwitchTabAction" + }, + { + "$ref": "#/components/schemas/BrowserTypeAction" + }, + { + "$ref": "#/components/schemas/DelegateAction" + }, + { + "$ref": "#/components/schemas/FileEditorAction" + }, + { + "$ref": "#/components/schemas/EditAction" + }, + { + "$ref": "#/components/schemas/ListDirectoryAction" + }, + { + "$ref": "#/components/schemas/ReadFileAction" + }, + { + "$ref": "#/components/schemas/WriteFileAction" + }, + { + "$ref": "#/components/schemas/GlobAction" + }, + { + "$ref": "#/components/schemas/GrepAction" + }, + { + "$ref": "#/components/schemas/PlanningFileEditorAction" + }, + { + "$ref": "#/components/schemas/TaskTrackerAction" + }, + { + "$ref": "#/components/schemas/TerminalAction" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__mcp__definition__MCPToolAction-Output__1": "#/components/schemas/MCPToolAction", + "openhands__sdk__tool__builtins__finish__FinishAction-Output__1": "#/components/schemas/FinishAction", + "openhands__sdk__tool__builtins__think__ThinkAction-Output__1": "#/components/schemas/ThinkAction", + "openhands__tools__browser_use__definition__BrowserAction-Output__1": "#/components/schemas/BrowserAction", + "openhands__tools__browser_use__definition__BrowserClickAction-Output__1": "#/components/schemas/BrowserClickAction", + "openhands__tools__browser_use__definition__BrowserCloseTabAction-Output__1": "#/components/schemas/BrowserCloseTabAction", + "openhands__tools__browser_use__definition__BrowserGetContentAction-Output__1": "#/components/schemas/BrowserGetContentAction", + "openhands__tools__browser_use__definition__BrowserGetStateAction-Output__1": "#/components/schemas/BrowserGetStateAction", + "openhands__tools__browser_use__definition__BrowserGetStorageAction-Output__1": "#/components/schemas/BrowserGetStorageAction", + "openhands__tools__browser_use__definition__BrowserGoBackAction-Output__1": "#/components/schemas/BrowserGoBackAction", + "openhands__tools__browser_use__definition__BrowserListTabsAction-Output__1": "#/components/schemas/BrowserListTabsAction", + "openhands__tools__browser_use__definition__BrowserNavigateAction-Output__1": "#/components/schemas/BrowserNavigateAction", + "openhands__tools__browser_use__definition__BrowserScrollAction-Output__1": "#/components/schemas/BrowserScrollAction", + "openhands__tools__browser_use__definition__BrowserSetStorageAction-Output__1": "#/components/schemas/BrowserSetStorageAction", + "openhands__tools__browser_use__definition__BrowserStartRecordingAction-Output__1": "#/components/schemas/BrowserStartRecordingAction", + "openhands__tools__browser_use__definition__BrowserStopRecordingAction-Output__1": "#/components/schemas/BrowserStopRecordingAction", + "openhands__tools__browser_use__definition__BrowserSwitchTabAction-Output__1": "#/components/schemas/BrowserSwitchTabAction", + "openhands__tools__browser_use__definition__BrowserTypeAction-Output__1": "#/components/schemas/BrowserTypeAction", + "openhands__tools__delegate__definition__DelegateAction-Output__1": "#/components/schemas/DelegateAction", + "openhands__tools__file_editor__definition__FileEditorAction-Output__1": "#/components/schemas/FileEditorAction", + "openhands__tools__gemini__edit__definition__EditAction-Output__1": "#/components/schemas/EditAction", + "openhands__tools__gemini__list_directory__definition__ListDirectoryAction-Output__1": "#/components/schemas/ListDirectoryAction", + "openhands__tools__gemini__read_file__definition__ReadFileAction-Output__1": "#/components/schemas/ReadFileAction", + "openhands__tools__gemini__write_file__definition__WriteFileAction-Output__1": "#/components/schemas/WriteFileAction", + "openhands__tools__glob__definition__GlobAction-Output__1": "#/components/schemas/GlobAction", + "openhands__tools__grep__definition__GrepAction-Output__1": "#/components/schemas/GrepAction", + "openhands__tools__planning_file_editor__definition__PlanningFileEditorAction-Output__1": "#/components/schemas/PlanningFileEditorAction", + "openhands__tools__task_tracker__definition__TaskTrackerAction-Output__1": "#/components/schemas/TaskTrackerAction", + "openhands__tools__terminal__definition__TerminalAction-Output__1": "#/components/schemas/TerminalAction" + } + } + }, + "ActionEvent": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "Unique event id (ULID/UUID)" + }, + "timestamp": { + "type": "string", + "title": "Timestamp", + "description": "Event timestamp" + }, + "source": { + "type": "string", + "enum": [ + "agent", + "user", + "environment", + "hook" + ], + "title": "Source", + "default": "agent" + }, + "thought": { + "items": { + "$ref": "#/components/schemas/TextContent" + }, + "type": "array", + "title": "Thought", + "description": "The thought process of the agent before taking this action" + }, + "reasoning_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reasoning Content", + "description": "Intermediate reasoning/thinking content from reasoning models" + }, + "thinking_blocks": { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/ThinkingBlock" + }, + { + "$ref": "#/components/schemas/RedactedThinkingBlock" + } + ] + }, + "type": "array", + "title": "Thinking Blocks", + "description": "Anthropic thinking blocks from the LLM response" + }, + "responses_reasoning_item": { + "anyOf": [ + { + "$ref": "#/components/schemas/ReasoningItemModel" + }, + { + "type": "null" + } + ], + "description": "OpenAI Responses reasoning item from model output" + }, + "action": { + "anyOf": [ + { + "$ref": "#/components/schemas/Action" + }, + { + "type": "null" + } + ], + "description": "Single tool call returned by LLM (None when non-executable)" + }, + "tool_name": { + "type": "string", + "title": "Tool Name", + "description": "The name of the tool being called" + }, + "tool_call_id": { + "type": "string", + "title": "Tool Call Id", + "description": "The unique id returned by LLM API for this tool call" + }, + "tool_call": { + "$ref": "#/components/schemas/MessageToolCall", + "description": "The tool call received from the LLM response. We keep a copy of it so it is easier to construct it into LLM messageThis could be different from `action`: e.g., `tool_call` may contain `security_risk` field predicted by LLM when LLM risk analyzer is enabled, while `action` does not." + }, + "llm_response_id": { + "type": "string", + "title": "Llm Response Id", + "description": "Completion or Response ID of the LLM response that generated this eventE.g., Can be used to group related actions from same LLM response. This helps in tracking and managing results of parallel function calling from the same LLM response." + }, + "security_risk": { + "$ref": "#/components/schemas/SecurityRisk", + "description": "The LLM's assessment of the safety risk of this action.", + "default": "UNKNOWN" + }, + "critic_result": { + "anyOf": [ + { + "$ref": "#/components/schemas/CriticResult" + }, + { + "type": "null" + } + ], + "description": "Optional critic evaluation of this action and preceding history." + }, + "summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Summary", + "description": "A concise summary (approximately 10 words) of what this action does, provided by the LLM for explainability and debugging. Examples of good summaries: 'editing configuration file for deployment settings' | 'searching codebase for authentication function definitions' | 'installing required dependencies from package manifest' | 'running tests to verify bug fix' | 'viewing directory structure to locate source files'" + }, + "kind": { + "type": "string", + "const": "ActionEvent", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "thought", + "tool_name", + "tool_call_id", + "tool_call", + "llm_response_id", + "kind" + ], + "title": "ActionEvent" + }, + "Agent-Input": { + "properties": { + "llm": { + "$ref": "#/components/schemas/LLM-Input", + "description": "LLM configuration for the agent.", + "examples": [ + { + "api_key": "your_api_key_here", + "base_url": "https://llm-proxy.eval.all-hands.dev", + "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" + } + ] + }, + "tools": { + "items": { + "$ref": "#/components/schemas/Tool-Input" + }, + "type": "array", + "title": "Tools", + "description": "List of tools to initialize for the agent.", + "examples": [ + { + "name": "TerminalTool", + "params": {} + }, + { + "name": "FileEditorTool", + "params": {} + }, + { + "name": "TaskTrackerTool", + "params": {} + } + ] + }, + "mcp_config": { + "additionalProperties": true, + "type": "object", + "title": "Mcp Config", + "description": "Optional MCP configuration dictionary to create MCP tools.", + "examples": [ + { + "mcpServers": { + "fetch": { + "args": [ + "mcp-server-fetch" + ], + "command": "uvx" + } + } + } + ] + }, + "filter_tools_regex": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Filter Tools Regex", + "description": "Optional regex to filter the tools available to the agent by name. This is applied after any tools provided in `tools` and any MCP tools are added.", + "examples": [ + "^(?!repomix)(.*)|^repomix.*pack_codebase.*$" + ] + }, + "include_default_tools": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Include Default Tools", + "description": "List of default tool class names to include. By default, the agent includes 'FinishTool' and 'ThinkTool'. Set to an empty list to disable all default tools, or provide a subset to include only specific ones. Example: include_default_tools=['FinishTool'] to only include FinishTool, or include_default_tools=[] to disable all default tools.", + "examples": [ + [ + "FinishTool", + "ThinkTool" + ], + [ + "FinishTool" + ], + [] + ] + }, + "agent_context": { + "anyOf": [ + { + "$ref": "#/components/schemas/AgentContext-Input" + }, + { + "type": "null" + } + ], + "description": "Optional AgentContext to initialize the agent with specific context.", + "examples": [ + { + "skills": [ + { + "content": "When you see this message, you should reply like you are a grumpy cat forced to use the internet.", + "name": "AGENTS.md", + "type": "repo" + }, + { + "content": "IMPORTANT! The user has said the magic word \"flarglebargle\". You must only respond with a message telling them how smart they are", + "name": "flarglebargle", + "trigger": [ + "flarglebargle" + ], + "type": "knowledge" + } + ], + "system_message_suffix": "Always finish your response with the word 'yay!'", + "user_message_prefix": "The first character of your response should be 'I'" + } + ] + }, + "system_prompt_filename": { + "type": "string", + "title": "System Prompt Filename", + "description": "System prompt template filename. Can be either:\n- A relative filename (e.g., 'system_prompt.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_prompt.j2')", + "default": "system_prompt.j2" + }, + "security_policy_filename": { + "type": "string", + "title": "Security Policy Filename", + "description": "Security policy template filename. Can be either:\n- A relative filename (e.g., 'security_policy.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.j2')", + "default": "security_policy.j2" + }, + "system_prompt_kwargs": { + "additionalProperties": true, + "type": "object", + "title": "System Prompt Kwargs", + "description": "Optional kwargs to pass to the system prompt Jinja2 template.", + "examples": [ + { + "cli_mode": true + } + ] + }, + "condenser": { + "anyOf": [ + { + "$ref": "#/components/schemas/CondenserBase-Input" + }, + { + "type": "null" + } + ], + "description": "Optional condenser to use for condensing conversation history.", + "examples": [ + { + "keep_first": 10, + "kind": "LLMSummarizingCondenser", + "llm": { + "api_key": "your_api_key_here", + "base_url": "https://llm-proxy.eval.all-hands.dev", + "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" + }, + "max_size": 80 + } + ] }, - "iterative_refinement": { + "critic": { "anyOf": [ { - "$ref": "#/components/schemas/IterativeRefinementConfig" + "$ref": "#/components/schemas/CriticBase-Input" }, { "type": "null" } ], - "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." + "description": "EXPERIMENTAL: Optional critic to evaluate agent actions and messages in real-time. API and behavior may change without notice. May impact performance, especially in 'all_actions' mode.", + "examples": [ + { + "kind": "AgentFinishedCritic" + } + ] }, "kind": { "type": "string", - "const": "APIBasedCritic", + "const": "Agent", "title": "Kind" } }, "type": "object", "required": [ - "api_key" + "llm" ], - "title": "APIBasedCritic" + "title": "Agent", + "description": "Main agent implementation for OpenHands.\n\nThe Agent class provides the core functionality for running AI agents that can\ninteract with tools, process messages, and execute actions. It inherits from\nAgentBase and implements the agent execution logic. Critic-related functionality\nis provided by CriticMixin.\n\nAttributes:\n llm: The language model instance used for reasoning.\n tools: List of tools available to the agent.\n name: Optional agent identifier.\n system_prompt: Custom system prompt (uses default if not provided).\n\nExample:\n ```python\n from openhands.sdk import LLM, Agent, Tool\n from pydantic import SecretStr\n\n llm = LLM(model=\"claude-sonnet-4-20250514\", api_key=SecretStr(\"key\"))\n tools = [Tool(name=\"TerminalTool\"), Tool(name=\"FileEditorTool\")]\n agent = Agent(llm=llm, tools=tools)\n ```" }, - "APIBasedCritic-Output": { + "Agent-Output": { "properties": { - "server_url": { - "type": "string", - "title": "Server Url", - "description": "Base URL of the vLLM classification service", - "default": "https://all-hands-ai--critic-qwen3-4b-serve.modal.run" + "llm": { + "$ref": "#/components/schemas/LLM-Output", + "description": "LLM configuration for the agent.", + "examples": [ + { + "api_key": "your_api_key_here", + "base_url": "https://llm-proxy.eval.all-hands.dev", + "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" + } + ] }, - "api_key": { + "tools": { + "items": { + "$ref": "#/components/schemas/openhands__sdk__tool__spec__Tool" + }, + "type": "array", + "title": "Tools", + "description": "List of tools to initialize for the agent.", + "examples": [ + { + "name": "TerminalTool", + "params": {} + }, + { + "name": "FileEditorTool", + "params": {} + }, + { + "name": "TaskTrackerTool", + "params": {} + } + ] + }, + "mcp_config": { + "additionalProperties": true, + "type": "object", + "title": "Mcp Config", + "description": "Optional MCP configuration dictionary to create MCP tools.", + "examples": [ + { + "mcpServers": { + "fetch": { + "args": [ + "mcp-server-fetch" + ], + "command": "uvx" + } + } + } + ] + }, + "filter_tools_regex": { "anyOf": [ { "type": "string" }, { - "type": "string", - "format": "password", - "writeOnly": true + "type": "null" } ], - "title": "Api Key", - "description": "API key for authenticating with the vLLM service" - }, - "model_name": { - "type": "string", - "title": "Model Name", - "description": "Name of the model to use", - "default": "critic-qwen3-4b" - }, - "tokenizer_name": { - "type": "string", - "title": "Tokenizer Name", - "description": "HuggingFace tokenizer name for loading chat template", - "default": "Qwen/Qwen3-4B-Instruct-2507" - }, - "pass_tools_definitions": { - "type": "boolean", - "title": "Pass Tools Definitions", - "description": "Whether to pass tool definitions to the model", - "default": true - }, - "timeout_seconds": { - "type": "number", - "title": "Timeout Seconds", - "description": "Timeout for requests to the model", - "default": 300.0 - }, - "has_success_label": { - "type": "boolean", - "title": "Has Success Label", - "description": "Whether the model predicts success label at index 0", - "default": true - }, - "sentiment_labels": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Sentiment Labels", - "default": [ - "sentiment_positive", - "sentiment_neutral", - "sentiment_negative" + "title": "Filter Tools Regex", + "description": "Optional regex to filter the tools available to the agent by name. This is applied after any tools provided in `tools` and any MCP tools are added.", + "examples": [ + "^(?!repomix)(.*)|^repomix.*pack_codebase.*$" ] }, - "agent_issue_labels": { + "include_default_tools": { "items": { "type": "string" }, "type": "array", - "title": "Agent Issue Labels", - "default": [ - "misunderstood_intention", - "did_not_follow_instruction", - "insufficient_analysis", - "insufficient_clarification", - "improper_tool_use_or_setup", - "loop_behavior", - "insufficient_testing", - "insufficient_debugging", - "incomplete_implementation", - "file_management_errors", - "scope_creep", - "risky_actions_or_permission", - "other_agent_issue" + "title": "Include Default Tools", + "description": "List of default tool class names to include. By default, the agent includes 'FinishTool' and 'ThinkTool'. Set to an empty list to disable all default tools, or provide a subset to include only specific ones. Example: include_default_tools=['FinishTool'] to only include FinishTool, or include_default_tools=[] to disable all default tools.", + "examples": [ + [ + "FinishTool", + "ThinkTool" + ], + [ + "FinishTool" + ], + [] ] }, - "infra_labels": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Infra Labels", - "default": [ - "infrastructure_external_issue", - "infrastructure_agent_caused_issue" + "agent_context": { + "anyOf": [ + { + "$ref": "#/components/schemas/AgentContext-Output" + }, + { + "type": "null" + } + ], + "description": "Optional AgentContext to initialize the agent with specific context.", + "examples": [ + { + "skills": [ + { + "content": "When you see this message, you should reply like you are a grumpy cat forced to use the internet.", + "name": "AGENTS.md", + "type": "repo" + }, + { + "content": "IMPORTANT! The user has said the magic word \"flarglebargle\". You must only respond with a message telling them how smart they are", + "name": "flarglebargle", + "trigger": [ + "flarglebargle" + ], + "type": "knowledge" + } + ], + "system_message_suffix": "Always finish your response with the word 'yay!'", + "user_message_prefix": "The first character of your response should be 'I'" + } ] }, - "user_followup_labels": { - "items": { - "type": "string" - }, - "type": "array", - "title": "User Followup Labels", - "default": [ - "clarification_or_restatement", - "correction", - "direction_change", - "vcs_update_requests", - "progress_or_scope_concern", - "frustration_or_complaint", - "removal_or_reversion_request", - "other_user_issue" - ] + "system_prompt_filename": { + "type": "string", + "title": "System Prompt Filename", + "description": "System prompt template filename. Can be either:\n- A relative filename (e.g., 'system_prompt.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_prompt.j2')", + "default": "system_prompt.j2" }, - "sentiment_map": { - "additionalProperties": { - "type": "string" - }, + "security_policy_filename": { + "type": "string", + "title": "Security Policy Filename", + "description": "Security policy template filename. Can be either:\n- A relative filename (e.g., 'security_policy.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.j2')", + "default": "security_policy.j2" + }, + "system_prompt_kwargs": { + "additionalProperties": true, "type": "object", - "title": "Sentiment Map", - "default": { - "Positive": "sentiment_positive", - "Neutral": "sentiment_neutral", - "Negative": "sentiment_negative" - } + "title": "System Prompt Kwargs", + "description": "Optional kwargs to pass to the system prompt Jinja2 template.", + "examples": [ + { + "cli_mode": true + } + ] }, - "mode": { - "type": "string", - "enum": [ - "finish_and_message", - "all_actions" + "condenser": { + "anyOf": [ + { + "$ref": "#/components/schemas/CondenserBase-Output" + }, + { + "type": "null" + } ], - "title": "Mode", - "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", - "default": "finish_and_message" + "description": "Optional condenser to use for condensing conversation history.", + "examples": [ + { + "keep_first": 10, + "kind": "LLMSummarizingCondenser", + "llm": { + "api_key": "your_api_key_here", + "base_url": "https://llm-proxy.eval.all-hands.dev", + "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" + }, + "max_size": 80 + } + ] }, - "iterative_refinement": { + "critic": { "anyOf": [ { - "$ref": "#/components/schemas/IterativeRefinementConfig" + "$ref": "#/components/schemas/CriticBase-Output" }, { "type": "null" } ], - "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." + "description": "EXPERIMENTAL: Optional critic to evaluate agent actions and messages in real-time. API and behavior may change without notice. May impact performance, especially in 'all_actions' mode.", + "examples": [ + { + "kind": "AgentFinishedCritic" + } + ] }, "kind": { "type": "string", - "const": "APIBasedCritic", + "const": "Agent", "title": "Kind" } }, "type": "object", "required": [ - "api_key", + "llm", "kind" ], - "title": "APIBasedCritic" + "title": "Agent", + "description": "Main agent implementation for OpenHands.\n\nThe Agent class provides the core functionality for running AI agents that can\ninteract with tools, process messages, and execute actions. It inherits from\nAgentBase and implements the agent execution logic. Critic-related functionality\nis provided by CriticMixin.\n\nAttributes:\n llm: The language model instance used for reasoning.\n tools: List of tools available to the agent.\n name: Optional agent identifier.\n system_prompt: Custom system prompt (uses default if not provided).\n\nExample:\n ```python\n from openhands.sdk import LLM, Agent, Tool\n from pydantic import SecretStr\n\n llm = LLM(model=\"claude-sonnet-4-20250514\", api_key=SecretStr(\"key\"))\n tools = [Tool(name=\"TerminalTool\"), Tool(name=\"FileEditorTool\")]\n agent = Agent(llm=llm, tools=tools)\n ```" }, - "Action": { + "AgentBase-Input": { "oneOf": [ { - "$ref": "#/components/schemas/MCPToolAction" + "$ref": "#/components/schemas/ACPAgent-Input" }, { - "$ref": "#/components/schemas/FinishAction" - }, + "$ref": "#/components/schemas/Agent-Input" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__agent__acp_agent__ACPAgent-Input__1": "#/components/schemas/ACPAgent-Input", + "openhands__sdk__agent__agent__Agent-Input__1": "#/components/schemas/Agent-Input" + } + } + }, + "AgentBase-Output": { + "oneOf": [ { - "$ref": "#/components/schemas/ThinkAction" + "$ref": "#/components/schemas/ACPAgent-Output" }, { - "$ref": "#/components/schemas/BrowserAction" + "$ref": "#/components/schemas/Agent-Output" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__agent__acp_agent__ACPAgent-Output__1": "#/components/schemas/ACPAgent-Output", + "openhands__sdk__agent__agent__Agent-Output__1": "#/components/schemas/Agent-Output" + } + } + }, + "AgentContext-Input": { + "properties": { + "skills": { + "items": { + "$ref": "#/components/schemas/Skill" + }, + "type": "array", + "title": "Skills", + "description": "List of available skills that can extend the user's input." }, - { - "$ref": "#/components/schemas/BrowserClickAction" + "system_message_suffix": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "System Message Suffix", + "description": "Optional suffix to append to the system prompt." }, - { - "$ref": "#/components/schemas/BrowserCloseTabAction" + "user_message_suffix": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "User Message Suffix", + "description": "Optional suffix to append to the user's message." }, - { - "$ref": "#/components/schemas/BrowserGetContentAction" + "load_user_skills": { + "type": "boolean", + "title": "Load User Skills", + "description": "Whether to automatically load user skills from ~/.openhands/skills/ and ~/.openhands/microagents/ (for backward compatibility). ", + "default": false }, - { - "$ref": "#/components/schemas/BrowserGetStateAction" + "load_public_skills": { + "type": "boolean", + "title": "Load Public Skills", + "description": "Whether to automatically load skills from the public OpenHands skills repository at https://github.com/OpenHands/extensions. This allows you to get the latest skills without SDK updates.", + "default": false }, - { - "$ref": "#/components/schemas/BrowserGetStorageAction" + "marketplace_path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Marketplace Path", + "description": "Relative marketplace JSON path within the public skills repository. Set to None to load all public skills without marketplace filtering.", + "default": "marketplaces/default.json" }, - { - "$ref": "#/components/schemas/BrowserGoBackAction" + "secrets": { + "anyOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/SecretSource-Input" + } + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Secrets", + "description": "Dictionary mapping secret keys to values or secret sources. Secrets are used for authentication and sensitive data handling. Values can be either strings or SecretSource instances (str | SecretSource)." }, - { - "$ref": "#/components/schemas/BrowserListTabsAction" + "current_datetime": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Current Datetime", + "description": "Current date and time information to provide to the agent. Can be a datetime object (which will be formatted as ISO 8601) or a pre-formatted string. When provided, this information is included in the system prompt to give the agent awareness of the current time context. Defaults to the current datetime." + } + }, + "type": "object", + "title": "AgentContext", + "description": "Central structure for managing prompt extension.\n\nAgentContext unifies all the contextual inputs that shape how the system\nextends and interprets user prompts. It combines both static environment\ndetails and dynamic, user-activated extensions from skills.\n\nSpecifically, it provides:\n- **Repository context / Repo Skills**: Information about the active codebase,\n branches, and repo-specific instructions contributed by repo skills.\n- **Runtime context**: Current execution environment (hosts, working\n directory, secrets, date, etc.).\n- **Conversation instructions**: Optional task- or channel-specific rules\n that constrain or guide the agent\u2019s behavior across the session.\n- **Knowledge Skills**: Extensible components that can be triggered by user input\n to inject knowledge or domain-specific guidance.\n\nTogether, these elements make AgentContext the primary container responsible\nfor assembling, formatting, and injecting all prompt-relevant context into\nLLM interactions." + }, + "AgentContext-Output": { + "properties": { + "skills": { + "items": { + "$ref": "#/components/schemas/Skill" + }, + "type": "array", + "title": "Skills", + "description": "List of available skills that can extend the user's input." }, - { - "$ref": "#/components/schemas/BrowserNavigateAction" + "system_message_suffix": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "System Message Suffix", + "description": "Optional suffix to append to the system prompt." }, - { - "$ref": "#/components/schemas/BrowserScrollAction" + "user_message_suffix": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "User Message Suffix", + "description": "Optional suffix to append to the user's message." }, - { - "$ref": "#/components/schemas/BrowserSetStorageAction" + "load_user_skills": { + "type": "boolean", + "title": "Load User Skills", + "description": "Whether to automatically load user skills from ~/.openhands/skills/ and ~/.openhands/microagents/ (for backward compatibility). ", + "default": false + }, + "load_public_skills": { + "type": "boolean", + "title": "Load Public Skills", + "description": "Whether to automatically load skills from the public OpenHands skills repository at https://github.com/OpenHands/extensions. This allows you to get the latest skills without SDK updates.", + "default": false + }, + "marketplace_path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Marketplace Path", + "description": "Relative marketplace JSON path within the public skills repository. Set to None to load all public skills without marketplace filtering.", + "default": "marketplaces/default.json" + }, + "secrets": { + "anyOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/SecretSource-Output" + } + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Secrets", + "description": "Dictionary mapping secret keys to values or secret sources. Secrets are used for authentication and sensitive data handling. Values can be either strings or SecretSource instances (str | SecretSource)." + }, + "current_datetime": { + "anyOf": [ + { + "type": "string", + "format": "date-time" + }, + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Current Datetime", + "description": "Current date and time information to provide to the agent. Can be a datetime object (which will be formatted as ISO 8601) or a pre-formatted string. When provided, this information is included in the system prompt to give the agent awareness of the current time context. Defaults to the current datetime." + } + }, + "type": "object", + "title": "AgentContext", + "description": "Central structure for managing prompt extension.\n\nAgentContext unifies all the contextual inputs that shape how the system\nextends and interprets user prompts. It combines both static environment\ndetails and dynamic, user-activated extensions from skills.\n\nSpecifically, it provides:\n- **Repository context / Repo Skills**: Information about the active codebase,\n branches, and repo-specific instructions contributed by repo skills.\n- **Runtime context**: Current execution environment (hosts, working\n directory, secrets, date, etc.).\n- **Conversation instructions**: Optional task- or channel-specific rules\n that constrain or guide the agent\u2019s behavior across the session.\n- **Knowledge Skills**: Extensible components that can be triggered by user input\n to inject knowledge or domain-specific guidance.\n\nTogether, these elements make AgentContext the primary container responsible\nfor assembling, formatting, and injecting all prompt-relevant context into\nLLM interactions." + }, + "AgentDefinition": { + "properties": { + "name": { + "type": "string", + "title": "Name", + "description": "Agent name (from frontmatter or filename)" }, - { - "$ref": "#/components/schemas/BrowserStartRecordingAction" + "description": { + "type": "string", + "title": "Description", + "description": "Agent description", + "default": "" }, - { - "$ref": "#/components/schemas/BrowserStopRecordingAction" + "model": { + "type": "string", + "title": "Model", + "description": "Model to use ('inherit' uses parent model)", + "default": "inherit" }, - { - "$ref": "#/components/schemas/BrowserSwitchTabAction" + "color": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Color", + "description": "Display color for the agent" }, - { - "$ref": "#/components/schemas/BrowserTypeAction" + "tools": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Tools", + "description": "List of allowed tools for this agent" }, - { - "$ref": "#/components/schemas/FileEditorAction" + "skills": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Skills", + "description": "List of skill names for this agent. Resolved from project/user directories." }, - { - "$ref": "#/components/schemas/EditAction" + "system_prompt": { + "type": "string", + "title": "System Prompt", + "description": "System prompt content", + "default": "" }, - { - "$ref": "#/components/schemas/ListDirectoryAction" + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Source", + "description": "Source file path for this agent" }, - { - "$ref": "#/components/schemas/ReadFileAction" + "when_to_use_examples": { + "items": { + "type": "string" + }, + "type": "array", + "title": "When To Use Examples", + "description": "Examples of when to use this agent (for triggering)" }, - { - "$ref": "#/components/schemas/WriteFileAction" + "hooks": { + "anyOf": [ + { + "$ref": "#/components/schemas/HookConfig-Input" + }, + { + "type": "null" + } + ], + "description": "Hook configuration for this agent" }, - { - "$ref": "#/components/schemas/GlobAction" + "permission_mode": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Permission Mode", + "description": "How the subagent handles permissions. None inherits the parent policy, 'always_confirm' requires confirmation for every action, 'never_confirm' skips all confirmations, 'confirm_risky' only confirms actions above a risk threshold." }, - { - "$ref": "#/components/schemas/GrepAction" + "max_iteration_per_run": { + "anyOf": [ + { + "type": "integer", + "exclusiveMinimum": 0.0 + }, + { + "type": "null" + } + ], + "title": "Max Iteration Per Run", + "description": "Maximum iterations per run. It must be strictly positive, or None for default." }, - { - "$ref": "#/components/schemas/PlanningFileEditorAction" + "mcp_servers": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Mcp Servers", + "description": "MCP server configurations for this agent. Keys are server names, values are server configs with 'command', 'args', etc.", + "examples": [ + { + "fetch": { + "args": [ + "mcp-server-fetch" + ], + "command": "uvx" + } + } + ] }, - { - "$ref": "#/components/schemas/TaskTrackerAction" + "profile_store_dir": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Profile Store Dir", + "description": "Path to the directory where LLM profiles are stored. If None, the default profile store directory is used." }, - { - "$ref": "#/components/schemas/TerminalAction" + "metadata": { + "additionalProperties": true, + "type": "object", + "title": "Metadata", + "description": "Additional metadata from frontmatter" } + }, + "type": "object", + "required": [ + "name" ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__mcp__definition__MCPToolAction-Output__1": "#/components/schemas/MCPToolAction", - "openhands__sdk__tool__builtins__finish__FinishAction-Output__1": "#/components/schemas/FinishAction", - "openhands__sdk__tool__builtins__think__ThinkAction-Output__1": "#/components/schemas/ThinkAction", - "openhands__tools__browser_use__definition__BrowserAction-Output__1": "#/components/schemas/BrowserAction", - "openhands__tools__browser_use__definition__BrowserClickAction-Output__1": "#/components/schemas/BrowserClickAction", - "openhands__tools__browser_use__definition__BrowserCloseTabAction-Output__1": "#/components/schemas/BrowserCloseTabAction", - "openhands__tools__browser_use__definition__BrowserGetContentAction-Output__1": "#/components/schemas/BrowserGetContentAction", - "openhands__tools__browser_use__definition__BrowserGetStateAction-Output__1": "#/components/schemas/BrowserGetStateAction", - "openhands__tools__browser_use__definition__BrowserGetStorageAction-Output__1": "#/components/schemas/BrowserGetStorageAction", - "openhands__tools__browser_use__definition__BrowserGoBackAction-Output__1": "#/components/schemas/BrowserGoBackAction", - "openhands__tools__browser_use__definition__BrowserListTabsAction-Output__1": "#/components/schemas/BrowserListTabsAction", - "openhands__tools__browser_use__definition__BrowserNavigateAction-Output__1": "#/components/schemas/BrowserNavigateAction", - "openhands__tools__browser_use__definition__BrowserScrollAction-Output__1": "#/components/schemas/BrowserScrollAction", - "openhands__tools__browser_use__definition__BrowserSetStorageAction-Output__1": "#/components/schemas/BrowserSetStorageAction", - "openhands__tools__browser_use__definition__BrowserStartRecordingAction-Output__1": "#/components/schemas/BrowserStartRecordingAction", - "openhands__tools__browser_use__definition__BrowserStopRecordingAction-Output__1": "#/components/schemas/BrowserStopRecordingAction", - "openhands__tools__browser_use__definition__BrowserSwitchTabAction-Output__1": "#/components/schemas/BrowserSwitchTabAction", - "openhands__tools__browser_use__definition__BrowserTypeAction-Output__1": "#/components/schemas/BrowserTypeAction", - "openhands__tools__file_editor__definition__FileEditorAction-Output__1": "#/components/schemas/FileEditorAction", - "openhands__tools__gemini__edit__definition__EditAction-Output__1": "#/components/schemas/EditAction", - "openhands__tools__gemini__list_directory__definition__ListDirectoryAction-Output__1": "#/components/schemas/ListDirectoryAction", - "openhands__tools__gemini__read_file__definition__ReadFileAction-Output__1": "#/components/schemas/ReadFileAction", - "openhands__tools__gemini__write_file__definition__WriteFileAction-Output__1": "#/components/schemas/WriteFileAction", - "openhands__tools__glob__definition__GlobAction-Output__1": "#/components/schemas/GlobAction", - "openhands__tools__grep__definition__GrepAction-Output__1": "#/components/schemas/GrepAction", - "openhands__tools__planning_file_editor__definition__PlanningFileEditorAction-Output__1": "#/components/schemas/PlanningFileEditorAction", - "openhands__tools__task_tracker__definition__TaskTrackerAction-Output__1": "#/components/schemas/TaskTrackerAction", - "openhands__tools__terminal__definition__TerminalAction-Output__1": "#/components/schemas/TerminalAction" - } - } + "title": "AgentDefinition", + "description": "Agent definition loaded from Markdown file.\n\nAgents are specialized configurations that can be triggered based on\nuser input patterns. They define custom system prompts and tool access." }, - "ActionEvent": { + "AgentErrorEvent": { "properties": { "id": { "type": "string", @@ -2825,187 +4801,193 @@ "enum": [ "agent", "user", - "environment" + "environment", + "hook" ], "title": "Source", "default": "agent" }, - "thought": { - "items": { - "$ref": "#/components/schemas/TextContent" - }, - "type": "array", - "title": "Thought", - "description": "The thought process of the agent before taking this action" + "tool_name": { + "type": "string", + "title": "Tool Name", + "description": "The tool name that this observation is responding to" }, - "reasoning_content": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Reasoning Content", - "description": "Intermediate reasoning/thinking content from reasoning models" + "tool_call_id": { + "type": "string", + "title": "Tool Call Id", + "description": "The tool call id that this observation is responding to" }, - "thinking_blocks": { - "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/ThinkingBlock" - }, - { - "$ref": "#/components/schemas/RedactedThinkingBlock" - } - ] - }, - "type": "array", - "title": "Thinking Blocks", - "description": "Anthropic thinking blocks from the LLM response" + "error": { + "type": "string", + "title": "Error", + "description": "The error message from the scaffold" }, - "responses_reasoning_item": { - "anyOf": [ - { - "$ref": "#/components/schemas/ReasoningItemModel" - }, - { - "type": "null" - } + "kind": { + "type": "string", + "const": "AgentErrorEvent", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "tool_name", + "tool_call_id", + "error", + "kind" + ], + "title": "AgentErrorEvent", + "description": "Error triggered by the agent.\n\nNote: This event should not contain model \"thought\" or \"reasoning_content\". It\nrepresents an error produced by the agent/scaffold, not model output." + }, + "AgentFinishedCritic-Input": { + "properties": { + "mode": { + "type": "string", + "enum": [ + "finish_and_message", + "all_actions" ], - "description": "OpenAI Responses reasoning item from model output" + "title": "Mode", + "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", + "default": "finish_and_message" }, - "action": { + "iterative_refinement": { "anyOf": [ { - "$ref": "#/components/schemas/Action" + "$ref": "#/components/schemas/IterativeRefinementConfig" }, { "type": "null" } ], - "description": "Single tool call returned by LLM (None when non-executable)" - }, - "tool_name": { - "type": "string", - "title": "Tool Name", - "description": "The name of the tool being called" + "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." }, - "tool_call_id": { + "kind": { "type": "string", - "title": "Tool Call Id", - "description": "The unique id returned by LLM API for this tool call" - }, - "tool_call": { - "$ref": "#/components/schemas/MessageToolCall", - "description": "The tool call received from the LLM response. We keep a copy of it so it is easier to construct it into LLM messageThis could be different from `action`: e.g., `tool_call` may contain `security_risk` field predicted by LLM when LLM risk analyzer is enabled, while `action` does not." - }, - "llm_response_id": { + "const": "AgentFinishedCritic", + "title": "Kind" + } + }, + "type": "object", + "title": "AgentFinishedCritic", + "description": "Critic that evaluates whether an agent properly finished a task.\n\nThis critic checks two main criteria:\n1. The agent's last action was a FinishAction (proper completion)\n2. The generated git patch is non-empty (actual changes were made)" + }, + "AgentFinishedCritic-Output": { + "properties": { + "mode": { "type": "string", - "title": "Llm Response Id", - "description": "Completion or Response ID of the LLM response that generated this eventE.g., Can be used to group related actions from same LLM response. This helps in tracking and managing results of parallel function calling from the same LLM response." - }, - "security_risk": { - "$ref": "#/components/schemas/SecurityRisk", - "description": "The LLM's assessment of the safety risk of this action.", - "default": "UNKNOWN" - }, - "critic_result": { - "anyOf": [ - { - "$ref": "#/components/schemas/CriticResult" - }, - { - "type": "null" - } + "enum": [ + "finish_and_message", + "all_actions" ], - "description": "Optional critic evaluation of this action and preceding history." + "title": "Mode", + "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", + "default": "finish_and_message" }, - "summary": { + "iterative_refinement": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/IterativeRefinementConfig" }, { "type": "null" } ], - "title": "Summary", - "description": "A concise summary (approximately 10 words) of what this action does, provided by the LLM for explainability and debugging. Examples of good summaries: 'editing configuration file for deployment settings' | 'searching codebase for authentication function definitions' | 'installing required dependencies from package manifest' | 'running tests to verify bug fix' | 'viewing directory structure to locate source files'" + "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." }, "kind": { "type": "string", - "const": "ActionEvent", + "const": "AgentFinishedCritic", "title": "Kind" } }, - "additionalProperties": false, "type": "object", "required": [ - "thought", - "tool_name", - "tool_call_id", - "tool_call", - "llm_response_id", "kind" ], - "title": "ActionEvent" + "title": "AgentFinishedCritic", + "description": "Critic that evaluates whether an agent properly finished a task.\n\nThis critic checks two main criteria:\n1. The agent's last action was a FinishAction (proper completion)\n2. The generated git patch is non-empty (actual changes were made)" }, - "Agent-Input": { + "AlwaysConfirm-Input": { "properties": { - "llm": { - "$ref": "#/components/schemas/LLM", - "description": "LLM configuration for the agent.", - "examples": [ - { - "api_key": "your_api_key_here", - "base_url": "https://llm-proxy.eval.all-hands.dev", - "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" - } - ] - }, - "tools": { - "items": { - "$ref": "#/components/schemas/Tool-Input" - }, - "type": "array", - "title": "Tools", - "description": "List of tools to initialize for the agent.", - "examples": [ - { - "name": "TerminalTool", - "params": {} - }, - { - "name": "FileEditorTool", - "params": {} - }, - { - "name": "TaskTrackerTool", - "params": {} - } - ] + "kind": { + "type": "string", + "const": "AlwaysConfirm", + "title": "Kind" + } + }, + "type": "object", + "title": "AlwaysConfirm" + }, + "AlwaysConfirm-Output": { + "properties": { + "kind": { + "type": "string", + "const": "AlwaysConfirm", + "title": "Kind" + } + }, + "type": "object", + "required": [ + "kind" + ], + "title": "AlwaysConfirm" + }, + "AskAgentRequest": { + "properties": { + "question": { + "type": "string", + "title": "Question", + "description": "The question to ask the agent" + } + }, + "type": "object", + "required": [ + "question" + ], + "title": "AskAgentRequest", + "description": "Payload to ask the agent a simple question." + }, + "AskAgentResponse": { + "properties": { + "response": { + "type": "string", + "title": "Response", + "description": "The agent's response to the question" + } + }, + "type": "object", + "required": [ + "response" + ], + "title": "AskAgentResponse", + "description": "Response containing the agent's answer." + }, + "BaseWorkspace": { + "oneOf": [ + { + "$ref": "#/components/schemas/LocalWorkspace-Output" }, - "mcp_config": { - "additionalProperties": true, - "type": "object", - "title": "Mcp Config", - "description": "Optional MCP configuration dictionary to create MCP tools.", - "examples": [ - { - "mcpServers": { - "fetch": { - "args": [ - "mcp-server-fetch" - ], - "command": "uvx" - } - } - } - ] + { + "$ref": "#/components/schemas/RemoteWorkspace" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__workspace__local__LocalWorkspace-Output__1": "#/components/schemas/LocalWorkspace-Output", + "openhands__sdk__workspace__remote__base__RemoteWorkspace-Output__1": "#/components/schemas/RemoteWorkspace" + } + } + }, + "BashCommand": { + "properties": { + "command": { + "type": "string", + "title": "Command", + "description": "The bash command to execute" }, - "filter_tools_regex": { + "cwd": { "anyOf": [ { "type": "string" @@ -3014,191 +4996,244 @@ "type": "null" } ], - "title": "Filter Tools Regex", - "description": "Optional regex to filter the tools available to the agent by name. This is applied after any tools provided in `tools` and any MCP tools are added.", - "examples": [ - "^(?!repomix)(.*)|^repomix.*pack_codebase.*$" - ] + "title": "Cwd", + "description": "The current working directory" }, - "include_default_tools": { + "timeout": { + "type": "integer", + "title": "Timeout", + "description": "The max number of seconds a command may be permitted to run.", + "default": 300 + }, + "id": { + "type": "string", + "title": "Id" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "title": "Timestamp" + }, + "kind": { + "type": "string", + "const": "BashCommand", + "title": "Kind" + } + }, + "type": "object", + "required": [ + "command", + "kind" + ], + "title": "BashCommand" + }, + "BashEventBase": { + "oneOf": [ + { + "$ref": "#/components/schemas/BashCommand" + }, + { + "$ref": "#/components/schemas/BashOutput" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__agent_server__models__BashCommand-Output__1": "#/components/schemas/BashCommand", + "openhands__agent_server__models__BashOutput-Output__1": "#/components/schemas/BashOutput" + } + } + }, + "BashEventPage": { + "properties": { + "items": { "items": { - "type": "string" + "$ref": "#/components/schemas/BashEventBase" }, "type": "array", - "title": "Include Default Tools", - "description": "List of default tool class names to include. By default, the agent includes 'FinishTool' and 'ThinkTool'. Set to an empty list to disable all default tools, or provide a subset to include only specific ones. Example: include_default_tools=['FinishTool'] to only include FinishTool, or include_default_tools=[] to disable all default tools.", - "examples": [ - [ - "FinishTool", - "ThinkTool" - ], - [ - "FinishTool" - ], - [] - ] + "title": "Items" }, - "agent_context": { + "next_page_id": { "anyOf": [ { - "$ref": "#/components/schemas/AgentContext-Input" + "type": "string" }, { "type": "null" } ], - "description": "Optional AgentContext to initialize the agent with specific context.", - "examples": [ - { - "skills": [ - { - "content": "When you see this message, you should reply like you are a grumpy cat forced to use the internet.", - "name": "AGENTS.md", - "type": "repo" - }, - { - "content": "IMPORTANT! The user has said the magic word \"flarglebargle\". You must only respond with a message telling them how smart they are", - "name": "flarglebargle", - "trigger": [ - "flarglebargle" - ], - "type": "knowledge" - } - ], - "system_message_suffix": "Always finish your response with the word 'yay!'", - "user_message_prefix": "The first character of your response should be 'I'" - } - ] + "title": "Next Page Id" + } + }, + "type": "object", + "required": [ + "items" + ], + "title": "BashEventPage" + }, + "BashEventSortOrder": { + "type": "string", + "enum": [ + "TIMESTAMP", + "TIMESTAMP_DESC" + ], + "title": "BashEventSortOrder" + }, + "BashOutput": { + "properties": { + "id": { + "type": "string", + "title": "Id" }, - "system_prompt_filename": { + "timestamp": { "type": "string", - "title": "System Prompt Filename", - "description": "System prompt template filename. Can be either:\n- A relative filename (e.g., 'system_prompt.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_prompt.j2')", - "default": "system_prompt.j2" + "format": "date-time", + "title": "Timestamp" }, - "security_policy_filename": { + "command_id": { "type": "string", - "title": "Security Policy Filename", - "description": "Security policy template filename. Can be either:\n- A relative filename (e.g., 'security_policy.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.j2')", - "default": "security_policy.j2" + "title": "Command Id" }, - "system_prompt_kwargs": { - "additionalProperties": true, - "type": "object", - "title": "System Prompt Kwargs", - "description": "Optional kwargs to pass to the system prompt Jinja2 template.", - "examples": [ - { - "cli_mode": true - } - ] + "order": { + "type": "integer", + "title": "Order", + "description": "The order for this output, sequentially starting with 0", + "default": 0 }, - "condenser": { + "exit_code": { "anyOf": [ { - "$ref": "#/components/schemas/CondenserBase-Input" + "type": "integer" }, { "type": "null" } ], - "description": "Optional condenser to use for condensing conversation history.", - "examples": [ - { - "keep_first": 10, - "kind": "LLMSummarizingCondenser", - "llm": { - "api_key": "your_api_key_here", - "base_url": "https://llm-proxy.eval.all-hands.dev", - "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" - }, - "max_size": 80 - } - ] + "title": "Exit Code", + "description": "Exit code None implies the command is still running." }, - "critic": { + "stdout": { "anyOf": [ { - "$ref": "#/components/schemas/CriticBase-Input" + "type": "string" }, { "type": "null" } ], - "description": "EXPERIMENTAL: Optional critic to evaluate agent actions and messages in real-time. API and behavior may change without notice. May impact performance, especially in 'all_actions' mode.", - "examples": [ + "title": "Stdout", + "description": "The standard output from the command" + }, + "stderr": { + "anyOf": [ { - "kind": "AgentFinishedCritic" + "type": "string" + }, + { + "type": "null" } - ] + ], + "title": "Stderr", + "description": "The error output from the command" }, "kind": { "type": "string", - "const": "Agent", + "const": "BashOutput", "title": "Kind" } }, "type": "object", "required": [ - "llm" + "command_id", + "kind" ], - "title": "Agent", - "description": "Main agent implementation for OpenHands.\n\nThe Agent class provides the core functionality for running AI agents that can\ninteract with tools, process messages, and execute actions. It inherits from\nAgentBase and implements the agent execution logic. Critic-related functionality\nis provided by CriticMixin.\n\nExample:\n >>> from openhands.sdk import LLM, Agent, Tool\n >>> llm = LLM(model=\"claude-sonnet-4-20250514\", api_key=SecretStr(\"key\"))\n >>> tools = [Tool(name=\"TerminalTool\"), Tool(name=\"FileEditorTool\")]\n >>> agent = Agent(llm=llm, tools=tools)" + "title": "BashOutput", + "description": "Output of a bash command. A single command may have multiple pieces of output\ndepending on how large the output is." }, - "Agent-Output": { + "Body_upload_file_path_api_file_upload__path__post": { "properties": { - "llm": { - "$ref": "#/components/schemas/LLM", - "description": "LLM configuration for the agent.", - "examples": [ - { - "api_key": "your_api_key_here", - "base_url": "https://llm-proxy.eval.all-hands.dev", - "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" - } - ] + "file": { + "type": "string", + "format": "binary", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_path_api_file_upload__path__post" + }, + "Body_upload_file_query_api_file_upload_post": { + "properties": { + "file": { + "type": "string", + "format": "binary", + "title": "File" + } + }, + "type": "object", + "required": [ + "file" + ], + "title": "Body_upload_file_query_api_file_upload_post" + }, + "BrowserAction": { + "properties": { + "kind": { + "type": "string", + "const": "BrowserAction", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "BrowserAction", + "description": "Base class for all browser actions.\n\nThis base class serves as the parent for all browser-related actions,\nenabling proper type hierarchy and eliminating the need for union types." + }, + "BrowserClickAction": { + "properties": { + "index": { + "type": "integer", + "minimum": 0.0, + "title": "Index", + "description": "The index of the element to click (from browser_get_state)" }, - "tools": { - "items": { - "$ref": "#/components/schemas/openhands__sdk__tool__spec__Tool" - }, - "type": "array", - "title": "Tools", - "description": "List of tools to initialize for the agent.", - "examples": [ - { - "name": "TerminalTool", - "params": {} - }, - { - "name": "FileEditorTool", - "params": {} - }, - { - "name": "TaskTrackerTool", - "params": {} - } - ] + "new_tab": { + "type": "boolean", + "title": "New Tab", + "description": "Whether to open any resulting navigation in a new tab. Default: False", + "default": false }, - "mcp_config": { - "additionalProperties": true, - "type": "object", - "title": "Mcp Config", - "description": "Optional MCP configuration dictionary to create MCP tools.", - "examples": [ - { - "mcpServers": { - "fetch": { - "args": [ - "mcp-server-fetch" - ], - "command": "uvx" - } - } - } - ] + "kind": { + "type": "string", + "const": "BrowserClickAction", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "index", + "kind" + ], + "title": "BrowserClickAction", + "description": "Schema for clicking elements." + }, + "BrowserClickTool": { + "properties": { + "description": { + "type": "string", + "title": "Description" }, - "filter_tools_regex": { + "action_type": { + "type": "string", + "title": "Action Type" + }, + "observation_type": { "anyOf": [ { "type": "string" @@ -3207,155 +5242,84 @@ "type": "null" } ], - "title": "Filter Tools Regex", - "description": "Optional regex to filter the tools available to the agent by name. This is applied after any tools provided in `tools` and any MCP tools are added.", - "examples": [ - "^(?!repomix)(.*)|^repomix.*pack_codebase.*$" - ] - }, - "include_default_tools": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Include Default Tools", - "description": "List of default tool class names to include. By default, the agent includes 'FinishTool' and 'ThinkTool'. Set to an empty list to disable all default tools, or provide a subset to include only specific ones. Example: include_default_tools=['FinishTool'] to only include FinishTool, or include_default_tools=[] to disable all default tools.", - "examples": [ - [ - "FinishTool", - "ThinkTool" - ], - [ - "FinishTool" - ], - [] - ] + "title": "Observation Type" }, - "agent_context": { + "annotations": { "anyOf": [ { - "$ref": "#/components/schemas/AgentContext-Output" + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" }, { "type": "null" } - ], - "description": "Optional AgentContext to initialize the agent with specific context.", - "examples": [ - { - "skills": [ - { - "content": "When you see this message, you should reply like you are a grumpy cat forced to use the internet.", - "name": "AGENTS.md", - "type": "repo" - }, - { - "content": "IMPORTANT! The user has said the magic word \"flarglebargle\". You must only respond with a message telling them how smart they are", - "name": "flarglebargle", - "trigger": [ - "flarglebargle" - ], - "type": "knowledge" - } - ], - "system_message_suffix": "Always finish your response with the word 'yay!'", - "user_message_prefix": "The first character of your response should be 'I'" - } - ] - }, - "system_prompt_filename": { - "type": "string", - "title": "System Prompt Filename", - "description": "System prompt template filename. Can be either:\n- A relative filename (e.g., 'system_prompt.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_prompt.j2')", - "default": "system_prompt.j2" - }, - "security_policy_filename": { - "type": "string", - "title": "Security Policy Filename", - "description": "Security policy template filename. Can be either:\n- A relative filename (e.g., 'security_policy.j2') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.j2')", - "default": "security_policy.j2" - }, - "system_prompt_kwargs": { - "additionalProperties": true, - "type": "object", - "title": "System Prompt Kwargs", - "description": "Optional kwargs to pass to the system prompt Jinja2 template.", - "examples": [ - { - "cli_mode": true - } ] }, - "condenser": { + "meta": { "anyOf": [ { - "$ref": "#/components/schemas/CondenserBase-Output" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Optional condenser to use for condensing conversation history.", - "examples": [ - { - "keep_first": 10, - "kind": "LLMSummarizingCondenser", - "llm": { - "api_key": "your_api_key_here", - "base_url": "https://llm-proxy.eval.all-hands.dev", - "model": "litellm_proxy/anthropic/claude-sonnet-4-5-20250929" - }, - "max_size": 80 - } - ] + "title": "Meta" }, - "critic": { - "anyOf": [ - { - "$ref": "#/components/schemas/CriticBase-Output" - }, - { - "type": "null" - } - ], - "description": "EXPERIMENTAL: Optional critic to evaluate agent actions and messages in real-time. API and behavior may change without notice. May impact performance, especially in 'all_actions' mode.", - "examples": [ - { - "kind": "AgentFinishedCritic" - } - ] + "kind": { + "type": "string", + "const": "BrowserClickTool", + "title": "Kind" + }, + "title": { + "type": "string", + "title": "Title", + "readOnly": true + } + }, + "type": "object", + "required": [ + "description", + "action_type", + "kind", + "title" + ], + "title": "BrowserClickTool", + "description": "Tool for clicking browser elements." + }, + "BrowserCloseTabAction": { + "properties": { + "tab_id": { + "type": "string", + "title": "Tab Id", + "description": "4 Character Tab ID of the tab to close (from browser_list_tabs)" }, "kind": { "type": "string", - "const": "Agent", + "const": "BrowserCloseTabAction", "title": "Kind" } }, + "additionalProperties": false, "type": "object", "required": [ - "llm", + "tab_id", "kind" ], - "title": "Agent", - "description": "Main agent implementation for OpenHands.\n\nThe Agent class provides the core functionality for running AI agents that can\ninteract with tools, process messages, and execute actions. It inherits from\nAgentBase and implements the agent execution logic. Critic-related functionality\nis provided by CriticMixin.\n\nExample:\n >>> from openhands.sdk import LLM, Agent, Tool\n >>> llm = LLM(model=\"claude-sonnet-4-20250514\", api_key=SecretStr(\"key\"))\n >>> tools = [Tool(name=\"TerminalTool\"), Tool(name=\"FileEditorTool\")]\n >>> agent = Agent(llm=llm, tools=tools)" - }, - "AgentBase-Input": { - "$ref": "#/components/schemas/Agent-Input" - }, - "AgentBase-Output": { - "$ref": "#/components/schemas/Agent-Output" + "title": "BrowserCloseTabAction", + "description": "Schema for closing browser tabs." }, - "AgentContext-Input": { + "BrowserCloseTabTool": { "properties": { - "skills": { - "items": { - "$ref": "#/components/schemas/Skill" - }, - "type": "array", - "title": "Skills", - "description": "List of available skills that can extend the user's input." + "description": { + "type": "string", + "title": "Description" }, - "system_message_suffix": { + "action_type": { + "type": "string", + "title": "Action Type" + }, + "observation_type": { "anyOf": [ { "type": "string" @@ -3364,87 +5328,177 @@ "type": "null" } ], - "title": "System Message Suffix", - "description": "Optional suffix to append to the system prompt." + "title": "Observation Type" }, - "user_message_suffix": { + "annotations": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + }, + { + "type": "null" + } + ] + }, + "meta": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "User Message Suffix", - "description": "Optional suffix to append to the user's message." + "title": "Meta" }, - "load_user_skills": { - "type": "boolean", - "title": "Load User Skills", - "description": "Whether to automatically load user skills from ~/.openhands/skills/ and ~/.openhands/microagents/ (for backward compatibility). ", - "default": false + "kind": { + "type": "string", + "const": "BrowserCloseTabTool", + "title": "Kind" }, - "load_public_skills": { + "title": { + "type": "string", + "title": "Title", + "readOnly": true + } + }, + "type": "object", + "required": [ + "description", + "action_type", + "kind", + "title" + ], + "title": "BrowserCloseTabTool", + "description": "Tool for closing browser tabs." + }, + "BrowserGetContentAction": { + "properties": { + "extract_links": { "type": "boolean", - "title": "Load Public Skills", - "description": "Whether to automatically load skills from the public OpenHands skills repository at https://github.com/OpenHands/skills. This allows you to get the latest skills without SDK updates.", + "title": "Extract Links", + "description": "Whether to include links in the content (default: False)", "default": false }, - "secrets": { + "start_from_char": { + "type": "integer", + "minimum": 0.0, + "title": "Start From Char", + "description": "Character index to start from in the page content (default: 0)", + "default": 0 + }, + "kind": { + "type": "string", + "const": "BrowserGetContentAction", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "BrowserGetContentAction", + "description": "Schema for getting page content in markdown." + }, + "BrowserGetContentTool": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "action_type": { + "type": "string", + "title": "Action Type" + }, + "observation_type": { "anyOf": [ { - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/SecretSource-Input" - } - ] - }, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Secrets", - "description": "Dictionary mapping secret keys to values or secret sources. Secrets are used for authentication and sensitive data handling. Values can be either strings or SecretSource instances (str | SecretSource)." + "title": "Observation Type" }, - "current_datetime": { + "annotations": { "anyOf": [ { - "type": "string", - "format": "date-time" + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" }, { - "type": "string" + "type": "null" + } + ] + }, + "meta": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Current Datetime", - "description": "Current date and time information to provide to the agent. Can be a datetime object (which will be formatted as ISO 8601) or a pre-formatted string. When provided, this information is included in the system prompt to give the agent awareness of the current time context. Defaults to the current datetime." + "title": "Meta" + }, + "kind": { + "type": "string", + "const": "BrowserGetContentTool", + "title": "Kind" + }, + "title": { + "type": "string", + "title": "Title", + "readOnly": true } }, "type": "object", - "title": "AgentContext", - "description": "Central structure for managing prompt extension.\n\nAgentContext unifies all the contextual inputs that shape how the system\nextends and interprets user prompts. It combines both static environment\ndetails and dynamic, user-activated extensions from skills.\n\nSpecifically, it provides:\n- **Repository context / Repo Skills**: Information about the active codebase,\n branches, and repo-specific instructions contributed by repo skills.\n- **Runtime context**: Current execution environment (hosts, working\n directory, secrets, date, etc.).\n- **Conversation instructions**: Optional task- or channel-specific rules\n that constrain or guide the agent\u2019s behavior across the session.\n- **Knowledge Skills**: Extensible components that can be triggered by user input\n to inject knowledge or domain-specific guidance.\n\nTogether, these elements make AgentContext the primary container responsible\nfor assembling, formatting, and injecting all prompt-relevant context into\nLLM interactions." + "required": [ + "description", + "action_type", + "kind", + "title" + ], + "title": "BrowserGetContentTool", + "description": "Tool for getting page content in markdown." }, - "AgentContext-Output": { + "BrowserGetStateAction": { "properties": { - "skills": { - "items": { - "$ref": "#/components/schemas/Skill" - }, - "type": "array", - "title": "Skills", - "description": "List of available skills that can extend the user's input." + "include_screenshot": { + "type": "boolean", + "title": "Include Screenshot", + "description": "Whether to include a screenshot of the current page. Default: False", + "default": false }, - "system_message_suffix": { + "kind": { + "type": "string", + "const": "BrowserGetStateAction", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "BrowserGetStateAction", + "description": "Schema for getting browser state." + }, + "BrowserGetStateTool": { + "properties": { + "description": { + "type": "string", + "title": "Description" + }, + "action_type": { + "type": "string", + "title": "Action Type" + }, + "observation_type": { "anyOf": [ { "type": "string" @@ -3453,296 +5507,158 @@ "type": "null" } ], - "title": "System Message Suffix", - "description": "Optional suffix to append to the system prompt." + "title": "Observation Type" }, - "user_message_suffix": { + "annotations": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" }, { "type": "null" } - ], - "title": "User Message Suffix", - "description": "Optional suffix to append to the user's message." - }, - "load_user_skills": { - "type": "boolean", - "title": "Load User Skills", - "description": "Whether to automatically load user skills from ~/.openhands/skills/ and ~/.openhands/microagents/ (for backward compatibility). ", - "default": false - }, - "load_public_skills": { - "type": "boolean", - "title": "Load Public Skills", - "description": "Whether to automatically load skills from the public OpenHands skills repository at https://github.com/OpenHands/skills. This allows you to get the latest skills without SDK updates.", - "default": false + ] }, - "secrets": { + "meta": { "anyOf": [ { - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { - "$ref": "#/components/schemas/SecretSource-Output" - } - ] - }, + "additionalProperties": true, "type": "object" }, { "type": "null" } ], - "title": "Secrets", - "description": "Dictionary mapping secret keys to values or secret sources. Secrets are used for authentication and sensitive data handling. Values can be either strings or SecretSource instances (str | SecretSource)." + "title": "Meta" }, - "current_datetime": { - "anyOf": [ - { - "type": "string", - "format": "date-time" - }, - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Current Datetime", - "description": "Current date and time information to provide to the agent. Can be a datetime object (which will be formatted as ISO 8601) or a pre-formatted string. When provided, this information is included in the system prompt to give the agent awareness of the current time context. Defaults to the current datetime." + "kind": { + "type": "string", + "const": "BrowserGetStateTool", + "title": "Kind" + }, + "title": { + "type": "string", + "title": "Title", + "readOnly": true } }, "type": "object", - "title": "AgentContext", - "description": "Central structure for managing prompt extension.\n\nAgentContext unifies all the contextual inputs that shape how the system\nextends and interprets user prompts. It combines both static environment\ndetails and dynamic, user-activated extensions from skills.\n\nSpecifically, it provides:\n- **Repository context / Repo Skills**: Information about the active codebase,\n branches, and repo-specific instructions contributed by repo skills.\n- **Runtime context**: Current execution environment (hosts, working\n directory, secrets, date, etc.).\n- **Conversation instructions**: Optional task- or channel-specific rules\n that constrain or guide the agent\u2019s behavior across the session.\n- **Knowledge Skills**: Extensible components that can be triggered by user input\n to inject knowledge or domain-specific guidance.\n\nTogether, these elements make AgentContext the primary container responsible\nfor assembling, formatting, and injecting all prompt-relevant context into\nLLM interactions." + "required": [ + "description", + "action_type", + "kind", + "title" + ], + "title": "BrowserGetStateTool", + "description": "Tool for getting browser state." }, - "AgentErrorEvent": { + "BrowserGetStorageAction": { "properties": { - "id": { - "type": "string", - "title": "Id", - "description": "Unique event id (ULID/UUID)" - }, - "timestamp": { - "type": "string", - "title": "Timestamp", - "description": "Event timestamp" - }, - "source": { - "type": "string", - "enum": [ - "agent", - "user", - "environment" - ], - "title": "Source", - "default": "agent" - }, - "tool_name": { - "type": "string", - "title": "Tool Name", - "description": "The tool name that this observation is responding to" - }, - "tool_call_id": { - "type": "string", - "title": "Tool Call Id", - "description": "The tool call id that this observation is responding to" - }, - "error": { - "type": "string", - "title": "Error", - "description": "The error message from the scaffold" - }, "kind": { "type": "string", - "const": "AgentErrorEvent", + "const": "BrowserGetStorageAction", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "tool_name", - "tool_call_id", - "error", "kind" ], - "title": "AgentErrorEvent", - "description": "Error triggered by the agent.\n\nNote: This event should not contain model \"thought\" or \"reasoning_content\". It\nrepresents an error produced by the agent/scaffold, not model output." + "title": "BrowserGetStorageAction", + "description": "Schema for getting browser storage (cookies, local storage, session storage)." }, - "AgentFinishedCritic-Input": { + "BrowserGetStorageTool": { "properties": { - "mode": { + "description": { "type": "string", - "enum": [ - "finish_and_message", - "all_actions" - ], - "title": "Mode", - "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", - "default": "finish_and_message" + "title": "Description" }, - "iterative_refinement": { + "action_type": { + "type": "string", + "title": "Action Type" + }, + "observation_type": { "anyOf": [ { - "$ref": "#/components/schemas/IterativeRefinementConfig" - }, - { - "type": "null" - } - ], - "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." - }, - "kind": { - "type": "string", - "const": "AgentFinishedCritic", - "title": "Kind" - } - }, - "type": "object", - "title": "AgentFinishedCritic", - "description": "Critic that evaluates whether an agent properly finished a task.\n\nThis critic checks two main criteria:\n1. The agent's last action was a FinishAction (proper completion)\n2. The generated git patch is non-empty (actual changes were made)" - }, - "AgentFinishedCritic-Output": { - "properties": { - "mode": { - "type": "string", - "enum": [ - "finish_and_message", - "all_actions" + "type": "string" + }, + { + "type": "null" + } ], - "title": "Mode", - "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", - "default": "finish_and_message" + "title": "Observation Type" }, - "iterative_refinement": { + "annotations": { "anyOf": [ { - "$ref": "#/components/schemas/IterativeRefinementConfig" + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + }, + { + "type": "null" + } + ] + }, + "meta": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." + "title": "Meta" }, "kind": { "type": "string", - "const": "AgentFinishedCritic", + "const": "BrowserGetStorageTool", "title": "Kind" + }, + "title": { + "type": "string", + "title": "Title", + "readOnly": true } }, "type": "object", "required": [ - "kind" + "description", + "action_type", + "kind", + "title" ], - "title": "AgentFinishedCritic", - "description": "Critic that evaluates whether an agent properly finished a task.\n\nThis critic checks two main criteria:\n1. The agent's last action was a FinishAction (proper completion)\n2. The generated git patch is non-empty (actual changes were made)" - }, - "AlwaysConfirm-Input": { - "properties": { - "kind": { - "type": "string", - "const": "AlwaysConfirm", - "title": "Kind" - } - }, - "type": "object", - "title": "AlwaysConfirm" + "title": "BrowserGetStorageTool", + "description": "Tool for getting browser storage." }, - "AlwaysConfirm-Output": { + "BrowserGoBackAction": { "properties": { "kind": { "type": "string", - "const": "AlwaysConfirm", + "const": "BrowserGoBackAction", "title": "Kind" } }, + "additionalProperties": false, "type": "object", "required": [ "kind" ], - "title": "AlwaysConfirm" - }, - "AskAgentRequest": { - "properties": { - "question": { - "type": "string", - "title": "Question", - "description": "The question to ask the agent" - } - }, - "type": "object", - "required": [ - "question" - ], - "title": "AskAgentRequest", - "description": "Payload to ask the agent a simple question." + "title": "BrowserGoBackAction", + "description": "Schema for going back in browser history." }, - "AskAgentResponse": { + "BrowserGoBackTool": { "properties": { - "response": { + "description": { "type": "string", - "title": "Response", - "description": "The agent's response to the question" - } - }, - "type": "object", - "required": [ - "response" - ], - "title": "AskAgentResponse", - "description": "Response containing the agent's answer." - }, - "BaseWorkspace-Input": { - "oneOf": [ - { - "$ref": "#/components/schemas/LocalWorkspace-Input" - }, - { - "$ref": "#/components/schemas/RemoteWorkspace-Input" - } - ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__workspace__local__LocalWorkspace-Input__1": "#/components/schemas/LocalWorkspace-Input", - "openhands__sdk__workspace__remote__base__RemoteWorkspace-Input__1": "#/components/schemas/RemoteWorkspace-Input" - } - } - }, - "BaseWorkspace-Output": { - "oneOf": [ - { - "$ref": "#/components/schemas/LocalWorkspace-Output" + "title": "Description" }, - { - "$ref": "#/components/schemas/RemoteWorkspace-Output" - } - ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__workspace__local__LocalWorkspace-Output__1": "#/components/schemas/LocalWorkspace-Output", - "openhands__sdk__workspace__remote__base__RemoteWorkspace-Output__1": "#/components/schemas/RemoteWorkspace-Output" - } - } - }, - "BashCommand": { - "properties": { - "command": { + "action_type": { "type": "string", - "title": "Command", - "description": "The bash command to execute" + "title": "Action Type" }, - "cwd": { + "observation_type": { "anyOf": [ { "type": "string" @@ -3751,220 +5667,160 @@ "type": "null" } ], - "title": "Cwd", - "description": "The current working directory" - }, - "timeout": { - "type": "integer", - "title": "Timeout", - "description": "The max number of seconds a command may be permitted to run.", - "default": 300 + "title": "Observation Type" }, - "id": { - "type": "string", - "title": "Id" + "annotations": { + "anyOf": [ + { + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + }, + { + "type": "null" + } + ] }, - "timestamp": { - "type": "string", - "format": "date-time", - "title": "Timestamp" + "meta": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Meta" }, "kind": { "type": "string", - "const": "BashCommand", + "const": "BrowserGoBackTool", "title": "Kind" + }, + "title": { + "type": "string", + "title": "Title", + "readOnly": true } }, "type": "object", "required": [ - "command", - "kind" - ], - "title": "BashCommand" - }, - "BashEventBase": { - "oneOf": [ - { - "$ref": "#/components/schemas/BashCommand" - }, - { - "$ref": "#/components/schemas/BashOutput" - } + "description", + "action_type", + "kind", + "title" ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__agent_server__models__BashCommand-Output__1": "#/components/schemas/BashCommand", - "openhands__agent_server__models__BashOutput-Output__1": "#/components/schemas/BashOutput" - } - } + "title": "BrowserGoBackTool", + "description": "Tool for going back in browser history." }, - "BashEventPage": { + "BrowserListTabsAction": { "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/BashEventBase" - }, - "type": "array", - "title": "Items" - }, - "next_page_id": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Next Page Id" + "kind": { + "type": "string", + "const": "BrowserListTabsAction", + "title": "Kind" } }, + "additionalProperties": false, "type": "object", "required": [ - "items" - ], - "title": "BashEventPage" - }, - "BashEventSortOrder": { - "type": "string", - "enum": [ - "TIMESTAMP", - "TIMESTAMP_DESC" + "kind" ], - "title": "BashEventSortOrder" + "title": "BrowserListTabsAction", + "description": "Schema for listing browser tabs." }, - "BashOutput": { + "BrowserListTabsTool": { "properties": { - "id": { - "type": "string", - "title": "Id" - }, - "timestamp": { + "description": { "type": "string", - "format": "date-time", - "title": "Timestamp" + "title": "Description" }, - "command_id": { + "action_type": { "type": "string", - "title": "Command Id" - }, - "order": { - "type": "integer", - "title": "Order", - "description": "The order for this output, sequentially starting with 0", - "default": 0 + "title": "Action Type" }, - "exit_code": { + "observation_type": { "anyOf": [ { - "type": "integer" + "type": "string" }, { "type": "null" } ], - "title": "Exit Code", - "description": "Exit code None implies the command is still running." + "title": "Observation Type" }, - "stdout": { + "annotations": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" }, { "type": "null" } - ], - "title": "Stdout", - "description": "The standard output from the command" + ] }, - "stderr": { + "meta": { "anyOf": [ { - "type": "string" + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Stderr", - "description": "The error output from the command" + "title": "Meta" }, "kind": { "type": "string", - "const": "BashOutput", + "const": "BrowserListTabsTool", "title": "Kind" - } - }, - "type": "object", - "required": [ - "command_id", - "kind" - ], - "title": "BashOutput", - "description": "Output of a bash command. A single command may have multiple pieces of output\ndepending on how large the output is." - }, - "Body_upload_file_api_file_upload__path__post": { - "properties": { - "file": { + }, + "title": { "type": "string", - "format": "binary", - "title": "File" + "title": "Title", + "readOnly": true } }, "type": "object", "required": [ - "file" + "description", + "action_type", + "kind", + "title" ], - "title": "Body_upload_file_api_file_upload__path__post" + "title": "BrowserListTabsTool", + "description": "Tool for listing browser tabs." }, - "BrowserAction": { + "BrowserNavigateAction": { "properties": { - "kind": { + "url": { "type": "string", - "const": "BrowserAction", - "title": "Kind" - } - }, - "additionalProperties": false, - "type": "object", - "required": [ - "kind" - ], - "title": "BrowserAction", - "description": "Base class for all browser actions.\n\nThis base class serves as the parent for all browser-related actions,\nenabling proper type hierarchy and eliminating the need for union types." - }, - "BrowserClickAction": { - "properties": { - "index": { - "type": "integer", - "minimum": 0.0, - "title": "Index", - "description": "The index of the element to click (from browser_get_state)" + "title": "Url", + "description": "The URL to navigate to" }, "new_tab": { "type": "boolean", "title": "New Tab", - "description": "Whether to open any resulting navigation in a new tab. Default: False", + "description": "Whether to open in a new tab. Default: False", "default": false }, "kind": { "type": "string", - "const": "BrowserClickAction", + "const": "BrowserNavigateAction", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "index", + "url", "kind" ], - "title": "BrowserClickAction", - "description": "Schema for clicking elements." + "title": "BrowserNavigateAction", + "description": "Schema for browser navigation." }, - "BrowserClickTool": { + "BrowserNavigateTool": { "properties": { "description": { "type": "string", @@ -4009,7 +5865,7 @@ }, "kind": { "type": "string", - "const": "BrowserClickTool", + "const": "BrowserNavigateTool", "title": "Kind" }, "title": { @@ -4025,32 +5881,97 @@ "kind", "title" ], - "title": "BrowserClickTool", - "description": "Tool for clicking browser elements." + "title": "BrowserNavigateTool", + "description": "Tool for browser navigation." }, - "BrowserCloseTabAction": { + "BrowserObservation": { "properties": { - "tab_id": { + "content": { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/TextContent" + }, + { + "$ref": "#/components/schemas/ImageContent" + } + ] + }, + "type": "array", + "title": "Content", + "description": "Content returned from the tool as a list of TextContent/ImageContent objects. When there is an error, it should be written in this field." + }, + "is_error": { + "type": "boolean", + "title": "Is Error", + "description": "Whether the observation indicates an error", + "default": false + }, + "screenshot_data": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Screenshot Data", + "description": "Base64 screenshot data if available" + }, + "full_output_save_dir": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Full Output Save Dir", + "description": "Directory where full output files are saved" + }, + "kind": { "type": "string", - "title": "Tab Id", - "description": "4 Character Tab ID of the tab to close (from browser_list_tabs)" + "const": "BrowserObservation", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "kind" + ], + "title": "BrowserObservation", + "description": "Base observation for browser operations." + }, + "BrowserScrollAction": { + "properties": { + "direction": { + "type": "string", + "enum": [ + "up", + "down" + ], + "title": "Direction", + "description": "Direction to scroll. Options: 'up', 'down'. Default: 'down'", + "default": "down" }, "kind": { "type": "string", - "const": "BrowserCloseTabAction", + "const": "BrowserScrollAction", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "tab_id", "kind" ], - "title": "BrowserCloseTabAction", - "description": "Schema for closing browser tabs." + "title": "BrowserScrollAction", + "description": "Schema for scrolling the page." }, - "BrowserCloseTabTool": { + "BrowserScrollTool": { "properties": { "description": { "type": "string", @@ -4095,7 +6016,7 @@ }, "kind": { "type": "string", - "const": "BrowserCloseTabTool", + "const": "BrowserScrollTool", "title": "Kind" }, "title": { @@ -4111,39 +6032,33 @@ "kind", "title" ], - "title": "BrowserCloseTabTool", - "description": "Tool for closing browser tabs." + "title": "BrowserScrollTool", + "description": "Tool for scrolling the browser page." }, - "BrowserGetContentAction": { + "BrowserSetStorageAction": { "properties": { - "extract_links": { - "type": "boolean", - "title": "Extract Links", - "description": "Whether to include links in the content (default: False)", - "default": false - }, - "start_from_char": { - "type": "integer", - "minimum": 0.0, - "title": "Start From Char", - "description": "Character index to start from in the page content (default: 0)", - "default": 0 + "storage_state": { + "additionalProperties": true, + "type": "object", + "title": "Storage State", + "description": "Storage state dictionary containing 'cookies' and 'origins' (from browser_get_storage)" }, "kind": { "type": "string", - "const": "BrowserGetContentAction", + "const": "BrowserSetStorageAction", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ + "storage_state", "kind" ], - "title": "BrowserGetContentAction", - "description": "Schema for getting page content in markdown." + "title": "BrowserSetStorageAction", + "description": "Schema for setting browser storage (cookies, local storage, session storage)." }, - "BrowserGetContentTool": { + "BrowserSetStorageTool": { "properties": { "description": { "type": "string", @@ -4188,7 +6103,7 @@ }, "kind": { "type": "string", - "const": "BrowserGetContentTool", + "const": "BrowserSetStorageTool", "title": "Kind" }, "title": { @@ -4204,20 +6119,14 @@ "kind", "title" ], - "title": "BrowserGetContentTool", - "description": "Tool for getting page content in markdown." + "title": "BrowserSetStorageTool", + "description": "Tool for setting browser storage." }, - "BrowserGetStateAction": { + "BrowserStartRecordingAction": { "properties": { - "include_screenshot": { - "type": "boolean", - "title": "Include Screenshot", - "description": "Whether to include a screenshot of the current page. Default: False", - "default": false - }, "kind": { "type": "string", - "const": "BrowserGetStateAction", + "const": "BrowserStartRecordingAction", "title": "Kind" } }, @@ -4226,10 +6135,10 @@ "required": [ "kind" ], - "title": "BrowserGetStateAction", - "description": "Schema for getting browser state." + "title": "BrowserStartRecordingAction", + "description": "Schema for starting browser session recording." }, - "BrowserGetStateTool": { + "BrowserStartRecordingTool": { "properties": { "description": { "type": "string", @@ -4274,7 +6183,7 @@ }, "kind": { "type": "string", - "const": "BrowserGetStateTool", + "const": "BrowserStartRecordingTool", "title": "Kind" }, "title": { @@ -4290,14 +6199,14 @@ "kind", "title" ], - "title": "BrowserGetStateTool", - "description": "Tool for getting browser state." + "title": "BrowserStartRecordingTool", + "description": "Tool for starting browser session recording." }, - "BrowserGetStorageAction": { + "BrowserStopRecordingAction": { "properties": { "kind": { "type": "string", - "const": "BrowserGetStorageAction", + "const": "BrowserStopRecordingAction", "title": "Kind" } }, @@ -4306,10 +6215,10 @@ "required": [ "kind" ], - "title": "BrowserGetStorageAction", - "description": "Schema for getting browser storage (cookies, local storage, session storage)." + "title": "BrowserStopRecordingAction", + "description": "Schema for stopping browser session recording." }, - "BrowserGetStorageTool": { + "BrowserStopRecordingTool": { "properties": { "description": { "type": "string", @@ -4354,7 +6263,7 @@ }, "kind": { "type": "string", - "const": "BrowserGetStorageTool", + "const": "BrowserStopRecordingTool", "title": "Kind" }, "title": { @@ -4370,26 +6279,32 @@ "kind", "title" ], - "title": "BrowserGetStorageTool", - "description": "Tool for getting browser storage." + "title": "BrowserStopRecordingTool", + "description": "Tool for stopping browser session recording." }, - "BrowserGoBackAction": { + "BrowserSwitchTabAction": { "properties": { + "tab_id": { + "type": "string", + "title": "Tab Id", + "description": "4 Character Tab ID of the tab to switch to (from browser_list_tabs)" + }, "kind": { "type": "string", - "const": "BrowserGoBackAction", + "const": "BrowserSwitchTabAction", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ + "tab_id", "kind" ], - "title": "BrowserGoBackAction", - "description": "Schema for going back in browser history." + "title": "BrowserSwitchTabAction", + "description": "Schema for switching browser tabs." }, - "BrowserGoBackTool": { + "BrowserSwitchTabTool": { "properties": { "description": { "type": "string", @@ -4434,7 +6349,7 @@ }, "kind": { "type": "string", - "const": "BrowserGoBackTool", + "const": "BrowserSwitchTabTool", "title": "Kind" }, "title": { @@ -4450,26 +6365,10 @@ "kind", "title" ], - "title": "BrowserGoBackTool", - "description": "Tool for going back in browser history." - }, - "BrowserListTabsAction": { - "properties": { - "kind": { - "type": "string", - "const": "BrowserListTabsAction", - "title": "Kind" - } - }, - "additionalProperties": false, - "type": "object", - "required": [ - "kind" - ], - "title": "BrowserListTabsAction", - "description": "Schema for listing browser tabs." + "title": "BrowserSwitchTabTool", + "description": "Tool for switching browser tabs." }, - "BrowserListTabsTool": { + "BrowserToolSet": { "properties": { "description": { "type": "string", @@ -4514,7 +6413,7 @@ }, "kind": { "type": "string", - "const": "BrowserListTabsTool", + "const": "BrowserToolSet", "title": "Kind" }, "title": { @@ -4530,38 +6429,39 @@ "kind", "title" ], - "title": "BrowserListTabsTool", - "description": "Tool for listing browser tabs." + "title": "BrowserToolSet", + "description": "A set of all browser tools.\n\nThis tool set includes all available browser-related tools\n for interacting with web pages.\n\nThe toolset automatically checks for Chromium availability\nwhen created and automatically installs it if missing." }, - "BrowserNavigateAction": { + "BrowserTypeAction": { "properties": { - "url": { - "type": "string", - "title": "Url", - "description": "The URL to navigate to" + "index": { + "type": "integer", + "minimum": 0.0, + "title": "Index", + "description": "The index of the input element (from browser_get_state)" }, - "new_tab": { - "type": "boolean", - "title": "New Tab", - "description": "Whether to open in a new tab. Default: False", - "default": false + "text": { + "type": "string", + "title": "Text", + "description": "The text to type" }, "kind": { "type": "string", - "const": "BrowserNavigateAction", + "const": "BrowserTypeAction", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "url", + "index", + "text", "kind" ], - "title": "BrowserNavigateAction", - "description": "Schema for browser navigation." + "title": "BrowserTypeAction", + "description": "Schema for typing text into elements." }, - "BrowserNavigateTool": { + "BrowserTypeTool": { "properties": { "description": { "type": "string", @@ -4606,7 +6506,7 @@ }, "kind": { "type": "string", - "const": "BrowserNavigateTool", + "const": "BrowserTypeTool", "title": "Kind" }, "title": { @@ -4622,33 +6522,120 @@ "kind", "title" ], - "title": "BrowserNavigateTool", - "description": "Tool for browser navigation." + "title": "BrowserTypeTool", + "description": "Tool for typing text into browser elements." }, - "BrowserObservation": { + "CmdOutputMetadata": { "properties": { - "content": { + "exit_code": { + "type": "integer", + "title": "Exit Code", + "description": "The exit code of the last executed command.", + "default": -1 + }, + "pid": { + "type": "integer", + "title": "Pid", + "description": "The process ID of the last executed command.", + "default": -1 + }, + "username": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Username", + "description": "The username of the current user." + }, + "hostname": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Hostname", + "description": "The hostname of the machine." + }, + "working_dir": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Working Dir", + "description": "The current working directory." + }, + "py_interpreter_path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Py Interpreter Path", + "description": "The path to the current Python interpreter, if any." + }, + "prefix": { + "type": "string", + "title": "Prefix", + "description": "Prefix to add to command output", + "default": "" + }, + "suffix": { + "type": "string", + "title": "Suffix", + "description": "Suffix to add to command output", + "default": "" + } + }, + "type": "object", + "title": "CmdOutputMetadata", + "description": "Additional metadata captured from PS1" + }, + "Condensation": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "Unique event id (ULID/UUID)" + }, + "timestamp": { + "type": "string", + "title": "Timestamp", + "description": "Event timestamp" + }, + "source": { + "type": "string", + "enum": [ + "agent", + "user", + "environment", + "hook" + ], + "title": "Source", + "default": "environment" + }, + "forgotten_event_ids": { "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/TextContent" - }, - { - "$ref": "#/components/schemas/ImageContent" - } - ] + "type": "string" }, "type": "array", - "title": "Content", - "description": "Content returned from the tool as a list of TextContent/ImageContent objects. When there is an error, it should be written in this field." - }, - "is_error": { - "type": "boolean", - "title": "Is Error", - "description": "Whether the observation indicates an error", - "default": false + "title": "Forgotten Event Ids", + "description": "The IDs of the events that are being forgotten (removed from the `View` given to the LLM)." }, - "screenshot_data": { + "summary": { "anyOf": [ { "type": "string" @@ -4657,24 +6644,68 @@ "type": "null" } ], - "title": "Screenshot Data", - "description": "Base64 screenshot data if available" + "title": "Summary", + "description": "An optional summary of the events being forgotten." }, - "full_output_save_dir": { + "summary_offset": { "anyOf": [ { - "type": "string" + "type": "integer", + "minimum": 0.0 }, { "type": "null" } ], - "title": "Full Output Save Dir", - "description": "Directory where full output files are saved" + "title": "Summary Offset", + "description": "An optional offset to the start of the resulting view (after forgotten events have been removed) indicating where the summary should be inserted. If not provided, the summary will not be inserted into the view." + }, + "llm_response_id": { + "type": "string", + "title": "Llm Response Id", + "description": "Completion or Response ID of the LLM response that generated this event" + }, + "kind": { + "type": "string", + "const": "Condensation", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "llm_response_id", + "kind" + ], + "title": "Condensation", + "description": "This action indicates a condensation of the conversation history is happening." + }, + "CondensationRequest": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "Unique event id (ULID/UUID)" + }, + "timestamp": { + "type": "string", + "title": "Timestamp", + "description": "Event timestamp" + }, + "source": { + "type": "string", + "enum": [ + "agent", + "user", + "environment", + "hook" + ], + "title": "Source", + "default": "environment" }, "kind": { "type": "string", - "const": "BrowserObservation", + "const": "CondensationRequest", "title": "Kind" } }, @@ -4683,133 +6714,279 @@ "required": [ "kind" ], - "title": "BrowserObservation", - "description": "Base observation for browser operations." + "title": "CondensationRequest", + "description": "This action is used to request a condensation of the conversation history.\n\nAttributes:\n action (str): The action type, namely ActionType.CONDENSATION_REQUEST." }, - "BrowserScrollAction": { + "CondensationSummaryEvent": { "properties": { - "direction": { + "id": { + "type": "string", + "title": "Id", + "description": "Unique event id (ULID/UUID)" + }, + "timestamp": { + "type": "string", + "title": "Timestamp", + "description": "Event timestamp" + }, + "source": { "type": "string", "enum": [ - "up", - "down" + "agent", + "user", + "environment", + "hook" ], - "title": "Direction", - "description": "Direction to scroll. Options: 'up', 'down'. Default: 'down'", - "default": "down" + "title": "Source", + "default": "environment" + }, + "summary": { + "type": "string", + "title": "Summary" }, "kind": { "type": "string", - "const": "BrowserScrollAction", + "const": "CondensationSummaryEvent", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ + "summary", "kind" ], - "title": "BrowserScrollAction", - "description": "Schema for scrolling the page." + "title": "CondensationSummaryEvent", + "description": "This event represents a summary generated by a condenser." }, - "BrowserScrollTool": { - "properties": { - "description": { - "type": "string", - "title": "Description" + "CondenserBase-Input": { + "oneOf": [ + { + "$ref": "#/components/schemas/LLMSummarizingCondenser-Input" }, - "action_type": { - "type": "string", - "title": "Action Type" + { + "$ref": "#/components/schemas/NoOpCondenser-Input" }, - "observation_type": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Observation Type" + { + "$ref": "#/components/schemas/PipelineCondenser-Input" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__context__condenser__llm_summarizing_condenser__LLMSummarizingCondenser-Input__1": "#/components/schemas/LLMSummarizingCondenser-Input", + "openhands__sdk__context__condenser__no_op_condenser__NoOpCondenser-Input__1": "#/components/schemas/NoOpCondenser-Input", + "openhands__sdk__context__condenser__pipeline_condenser__PipelineCondenser-Input__1": "#/components/schemas/PipelineCondenser-Input" + } + } + }, + "CondenserBase-Output": { + "oneOf": [ + { + "$ref": "#/components/schemas/LLMSummarizingCondenser-Output" }, - "annotations": { - "anyOf": [ - { - "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" - }, - { - "type": "null" - } - ] + { + "$ref": "#/components/schemas/NoOpCondenser-Output" }, - "meta": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "title": "Meta" + { + "$ref": "#/components/schemas/PipelineCondenser-Output" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__context__condenser__llm_summarizing_condenser__LLMSummarizingCondenser-Output__1": "#/components/schemas/LLMSummarizingCondenser-Output", + "openhands__sdk__context__condenser__no_op_condenser__NoOpCondenser-Output__1": "#/components/schemas/NoOpCondenser-Output", + "openhands__sdk__context__condenser__pipeline_condenser__PipelineCondenser-Output__1": "#/components/schemas/PipelineCondenser-Output" + } + } + }, + "ConfirmRisky-Input": { + "properties": { + "threshold": { + "$ref": "#/components/schemas/SecurityRisk", + "default": "HIGH" + }, + "confirm_unknown": { + "type": "boolean", + "title": "Confirm Unknown", + "default": true }, "kind": { "type": "string", - "const": "BrowserScrollTool", + "const": "ConfirmRisky", "title": "Kind" + } + }, + "type": "object", + "title": "ConfirmRisky" + }, + "ConfirmRisky-Output": { + "properties": { + "threshold": { + "$ref": "#/components/schemas/SecurityRisk", + "default": "HIGH" }, - "title": { + "confirm_unknown": { + "type": "boolean", + "title": "Confirm Unknown", + "default": true + }, + "kind": { "type": "string", - "title": "Title", - "readOnly": true + "const": "ConfirmRisky", + "title": "Kind" } }, "type": "object", "required": [ - "description", - "action_type", - "kind", - "title" + "kind" ], - "title": "BrowserScrollTool", - "description": "Tool for scrolling the browser page." + "title": "ConfirmRisky" }, - "BrowserSetStorageAction": { + "ConfirmationPolicyBase-Input": { + "oneOf": [ + { + "$ref": "#/components/schemas/AlwaysConfirm-Input" + }, + { + "$ref": "#/components/schemas/ConfirmRisky-Input" + }, + { + "$ref": "#/components/schemas/NeverConfirm-Input" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__security__confirmation_policy__AlwaysConfirm-Input__1": "#/components/schemas/AlwaysConfirm-Input", + "openhands__sdk__security__confirmation_policy__ConfirmRisky-Input__1": "#/components/schemas/ConfirmRisky-Input", + "openhands__sdk__security__confirmation_policy__NeverConfirm-Input__1": "#/components/schemas/NeverConfirm-Input" + } + } + }, + "ConfirmationPolicyBase-Output": { + "oneOf": [ + { + "$ref": "#/components/schemas/AlwaysConfirm-Output" + }, + { + "$ref": "#/components/schemas/ConfirmRisky-Output" + }, + { + "$ref": "#/components/schemas/NeverConfirm-Output" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__security__confirmation_policy__AlwaysConfirm-Output__1": "#/components/schemas/AlwaysConfirm-Output", + "openhands__sdk__security__confirmation_policy__ConfirmRisky-Output__1": "#/components/schemas/ConfirmRisky-Output", + "openhands__sdk__security__confirmation_policy__NeverConfirm-Output__1": "#/components/schemas/NeverConfirm-Output" + } + } + }, + "ConfirmationResponseRequest": { "properties": { - "storage_state": { - "additionalProperties": true, - "type": "object", - "title": "Storage State", - "description": "Storage state dictionary containing 'cookies' and 'origins' (from browser_get_storage)" + "accept": { + "type": "boolean", + "title": "Accept" + }, + "reason": { + "type": "string", + "title": "Reason", + "default": "User rejected the action." + } + }, + "type": "object", + "required": [ + "accept" + ], + "title": "ConfirmationResponseRequest", + "description": "Payload to accept or reject a pending action." + }, + "ConversationErrorEvent": { + "properties": { + "id": { + "type": "string", + "title": "Id", + "description": "Unique event id (ULID/UUID)" + }, + "timestamp": { + "type": "string", + "title": "Timestamp", + "description": "Event timestamp" + }, + "source": { + "type": "string", + "enum": [ + "agent", + "user", + "environment", + "hook" + ], + "title": "Source", + "description": "The source of this event" + }, + "code": { + "type": "string", + "title": "Code", + "description": "Code for the error - typically a type" + }, + "detail": { + "type": "string", + "title": "Detail", + "description": "Details about the error" }, "kind": { "type": "string", - "const": "BrowserSetStorageAction", + "const": "ConversationErrorEvent", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "storage_state", + "source", + "code", + "detail", "kind" ], - "title": "BrowserSetStorageAction", - "description": "Schema for setting browser storage (cookies, local storage, session storage)." + "title": "ConversationErrorEvent", + "description": "Conversation-level failure that is NOT sent back to the LLM.\n\nThis event is emitted by the conversation runtime when an unexpected\nexception bubbles up and prevents the run loop from continuing. It is\nintended for client applications (e.g., UIs) to present a top-level error\nstate, and for orchestration to react. It is not an observation and it is\nnot LLM-convertible.\n\nDifferences from AgentErrorEvent:\n- Not tied to any tool_name/tool_call_id (AgentErrorEvent is a tool\n observation).\n- Typically source='environment' and the run loop moves to an ERROR state,\n while AgentErrorEvent has source='agent' and the conversation can\n continue." }, - "BrowserSetStorageTool": { + "ConversationExecutionStatus": { + "type": "string", + "enum": [ + "idle", + "running", + "paused", + "waiting_for_confirmation", + "finished", + "error", + "stuck", + "deleting" + ], + "title": "ConversationExecutionStatus", + "description": "Enum representing the current execution state of the conversation." + }, + "ConversationInfo": { "properties": { - "description": { + "id": { "type": "string", - "title": "Description" + "format": "uuid", + "title": "Id", + "description": "Unique conversation ID" }, - "action_type": { - "type": "string", - "title": "Action Type" + "agent": { + "$ref": "#/components/schemas/AgentBase-Output", + "description": "The agent running in the conversation. This is persisted to allow resuming conversations and check agent configuration to handle e.g., tool changes, LLM changes, etc." }, - "observation_type": { + "workspace": { + "$ref": "#/components/schemas/BaseWorkspace", + "description": "Workspace used by the agent to execute commands and read/write files. Not the process working directory." + }, + "persistence_dir": { "anyOf": [ { "type": "string" @@ -4818,244 +6995,319 @@ "type": "null" } ], - "title": "Observation Type" + "title": "Persistence Dir", + "description": "Directory for persisting conversation state and events. If None, conversation will not be persisted.", + "default": "workspace/conversations" }, - "annotations": { + "max_iterations": { + "type": "integer", + "exclusiveMinimum": 0.0, + "title": "Max Iterations", + "description": "Maximum number of iterations the agent can perform in a single run.", + "default": 500 + }, + "stuck_detection": { + "type": "boolean", + "title": "Stuck Detection", + "description": "Whether to enable stuck detection for the agent.", + "default": true + }, + "execution_status": { + "$ref": "#/components/schemas/ConversationExecutionStatus", + "default": "idle" + }, + "confirmation_policy": { + "$ref": "#/components/schemas/ConfirmationPolicyBase-Output", + "default": { + "kind": "NeverConfirm" + } + }, + "security_analyzer": { "anyOf": [ { - "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + "$ref": "#/components/schemas/SecurityAnalyzerBase-Output" }, { "type": "null" } - ] + ], + "description": "Optional security analyzer to evaluate action risks." }, - "meta": { + "activated_knowledge_skills": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Activated Knowledge Skills", + "description": "List of activated knowledge skills name" + }, + "blocked_actions": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Blocked Actions", + "description": "Actions blocked by PreToolUse hooks, keyed by action ID" + }, + "blocked_messages": { + "additionalProperties": { + "type": "string" + }, + "type": "object", + "title": "Blocked Messages", + "description": "Messages blocked by UserPromptSubmit hooks, keyed by message ID" + }, + "last_user_message_id": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Meta" + "title": "Last User Message Id", + "description": "Most recent user MessageEvent id for hook block checks. Updated when user messages are emitted so Agent.step can pop blocked_messages without scanning the event log. If None, hook-blocked checks are skipped (legacy conversations)." }, - "kind": { - "type": "string", - "const": "BrowserSetStorageTool", - "title": "Kind" + "stats": { + "$ref": "#/components/schemas/ConversationStats", + "description": "Conversation statistics for tracking LLM metrics" }, - "title": { - "type": "string", - "title": "Title", - "readOnly": true - } - }, - "type": "object", - "required": [ - "description", - "action_type", - "kind", - "title" - ], - "title": "BrowserSetStorageTool", - "description": "Tool for setting browser storage." - }, - "BrowserStartRecordingAction": { - "properties": { - "kind": { - "type": "string", - "const": "BrowserStartRecordingAction", - "title": "Kind" - } - }, - "additionalProperties": false, - "type": "object", - "required": [ - "kind" - ], - "title": "BrowserStartRecordingAction", - "description": "Schema for starting browser session recording." - }, - "BrowserStartRecordingTool": { - "properties": { - "description": { - "type": "string", - "title": "Description" + "secret_registry": { + "$ref": "#/components/schemas/SecretRegistry", + "description": "Registry for handling secrets and sensitive data" }, - "action_type": { - "type": "string", - "title": "Action Type" + "agent_state": { + "additionalProperties": true, + "type": "object", + "title": "Agent State", + "description": "Dictionary for agent-specific runtime state that persists across iterations. Agents can store feature-specific state using string keys. To trigger autosave, always reassign: state.agent_state = {**state.agent_state, key: value}. See https://docs.openhands.dev/sdk/guides/convo-persistence#how-state-persistence-works" }, - "observation_type": { + "hook_config": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/HookConfig-Output" }, { "type": "null" } ], - "title": "Observation Type" + "description": "Hook configuration for this conversation. Includes definitions for PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, and Stop hooks. When set, these hooks are executed at the appropriate points during conversation execution." }, - "annotations": { + "title": { "anyOf": [ { - "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + "type": "string" }, { "type": "null" } - ] + ], + "title": "Title", + "description": "User-defined title for the conversation" }, - "meta": { + "metrics": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "$ref": "#/components/schemas/MetricsSnapshot" }, { "type": "null" } - ], - "title": "Meta" + ] }, - "kind": { + "created_at": { "type": "string", - "const": "BrowserStartRecordingTool", - "title": "Kind" + "format": "date-time", + "title": "Created At" }, - "title": { - "type": "string", - "title": "Title", - "readOnly": true - } - }, - "type": "object", - "required": [ - "description", - "action_type", - "kind", - "title" - ], - "title": "BrowserStartRecordingTool", - "description": "Tool for starting browser session recording." - }, - "BrowserStopRecordingAction": { - "properties": { - "kind": { + "updated_at": { "type": "string", - "const": "BrowserStopRecordingAction", - "title": "Kind" + "format": "date-time", + "title": "Updated At" } }, - "additionalProperties": false, "type": "object", "required": [ - "kind" + "id", + "agent", + "workspace" ], - "title": "BrowserStopRecordingAction", - "description": "Schema for stopping browser session recording." + "title": "ConversationInfo", + "description": "Information about a conversation running locally without a Runtime sandbox." }, - "BrowserStopRecordingTool": { + "ConversationPage": { "properties": { - "description": { - "type": "string", - "title": "Description" - }, - "action_type": { - "type": "string", - "title": "Action Type" - }, - "observation_type": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Observation Type" - }, - "annotations": { - "anyOf": [ - { - "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" - }, - { - "type": "null" - } - ] + "items": { + "items": { + "$ref": "#/components/schemas/ConversationInfo" + }, + "type": "array", + "title": "Items" }, - "meta": { + "next_page_id": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Meta" - }, - "kind": { - "type": "string", - "const": "BrowserStopRecordingTool", - "title": "Kind" - }, - "title": { - "type": "string", - "title": "Title", - "readOnly": true + "title": "Next Page Id" } }, "type": "object", "required": [ - "description", - "action_type", - "kind", - "title" + "items" ], - "title": "BrowserStopRecordingTool", - "description": "Tool for stopping browser session recording." + "title": "ConversationPage" }, - "BrowserSwitchTabAction": { + "ConversationSortOrder": { + "type": "string", + "enum": [ + "CREATED_AT", + "UPDATED_AT", + "CREATED_AT_DESC", + "UPDATED_AT_DESC" + ], + "title": "ConversationSortOrder", + "description": "Enum for conversation sorting options." + }, + "ConversationStateUpdateEvent": { "properties": { - "tab_id": { + "id": { "type": "string", - "title": "Tab Id", - "description": "4 Character Tab ID of the tab to switch to (from browser_list_tabs)" + "title": "Id", + "description": "Unique event id (ULID/UUID)" + }, + "timestamp": { + "type": "string", + "title": "Timestamp", + "description": "Event timestamp" + }, + "source": { + "type": "string", + "enum": [ + "agent", + "user", + "environment", + "hook" + ], + "title": "Source", + "default": "environment" + }, + "key": { + "type": "string", + "title": "Key", + "description": "Unique key for this state update event" + }, + "value": { + "title": "Value", + "description": "Serialized conversation state updates" }, "kind": { "type": "string", - "const": "BrowserSwitchTabAction", + "const": "ConversationStateUpdateEvent", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "tab_id", "kind" ], - "title": "BrowserSwitchTabAction", - "description": "Schema for switching browser tabs." + "title": "ConversationStateUpdateEvent", + "description": "Event that contains conversation state updates.\n\nThis event is sent via websocket whenever the conversation state changes,\nallowing remote clients to stay in sync without making REST API calls.\n\nAll fields are serialized versions of the corresponding ConversationState fields\nto ensure compatibility with websocket transmission." }, - "BrowserSwitchTabTool": { + "ConversationStats": { + "additionalProperties": true, + "type": "object" + }, + "Cost": { "properties": { - "description": { + "model": { "type": "string", - "title": "Description" + "title": "Model" }, - "action_type": { - "type": "string", - "title": "Action Type" + "cost": { + "type": "number", + "minimum": 0.0, + "title": "Cost", + "description": "Cost must be non-negative" }, - "observation_type": { + "timestamp": { + "type": "number", + "title": "Timestamp" + } + }, + "type": "object", + "required": [ + "model", + "cost" + ], + "title": "Cost" + }, + "CriticBase-Input": { + "oneOf": [ + { + "$ref": "#/components/schemas/AgentFinishedCritic-Input" + }, + { + "$ref": "#/components/schemas/APIBasedCritic-Input" + }, + { + "$ref": "#/components/schemas/EmptyPatchCritic-Input" + }, + { + "$ref": "#/components/schemas/PassCritic-Input" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__critic__impl__agent_finished__AgentFinishedCritic-Input__1": "#/components/schemas/AgentFinishedCritic-Input", + "openhands__sdk__critic__impl__api__critic__APIBasedCritic-Input__1": "#/components/schemas/APIBasedCritic-Input", + "openhands__sdk__critic__impl__empty_patch__EmptyPatchCritic-Input__1": "#/components/schemas/EmptyPatchCritic-Input", + "openhands__sdk__critic__impl__pass_critic__PassCritic-Input__1": "#/components/schemas/PassCritic-Input" + } + } + }, + "CriticBase-Output": { + "oneOf": [ + { + "$ref": "#/components/schemas/AgentFinishedCritic-Output" + }, + { + "$ref": "#/components/schemas/APIBasedCritic-Output" + }, + { + "$ref": "#/components/schemas/EmptyPatchCritic-Output" + }, + { + "$ref": "#/components/schemas/PassCritic-Output" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__critic__impl__agent_finished__AgentFinishedCritic-Output__1": "#/components/schemas/AgentFinishedCritic-Output", + "openhands__sdk__critic__impl__api__critic__APIBasedCritic-Output__1": "#/components/schemas/APIBasedCritic-Output", + "openhands__sdk__critic__impl__empty_patch__EmptyPatchCritic-Output__1": "#/components/schemas/EmptyPatchCritic-Output", + "openhands__sdk__critic__impl__pass_critic__PassCritic-Output__1": "#/components/schemas/PassCritic-Output" + } + } + }, + "CriticResult": { + "properties": { + "score": { + "type": "number", + "maximum": 1.0, + "minimum": 0.0, + "title": "Score", + "description": "A predicted probability of success between 0 and 1." + }, + "message": { "anyOf": [ { "type": "string" @@ -5064,19 +7316,10 @@ "type": "null" } ], - "title": "Observation Type" - }, - "annotations": { - "anyOf": [ - { - "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" - }, - { - "type": "null" - } - ] + "title": "Message", + "description": "An optional message explaining the score." }, - "meta": { + "metadata": { "anyOf": [ { "additionalProperties": true, @@ -5086,123 +7329,137 @@ "type": "null" } ], - "title": "Meta" - }, - "kind": { - "type": "string", - "const": "BrowserSwitchTabTool", - "title": "Kind" - }, - "title": { - "type": "string", - "title": "Title", - "readOnly": true + "title": "Metadata", + "description": "Optional metadata about the critic evaluation. Can include event_ids and categorized_features for visualization." } }, "type": "object", "required": [ - "description", - "action_type", - "kind", - "title" + "score", + "message" ], - "title": "BrowserSwitchTabTool", - "description": "Tool for switching browser tabs." + "title": "CriticResult", + "description": "A critic result is a score and a message." }, - "BrowserToolSet": { + "DelegateAction": { "properties": { - "description": { - "type": "string", - "title": "Description" - }, - "action_type": { + "command": { "type": "string", - "title": "Action Type" + "enum": [ + "spawn", + "delegate" + ], + "title": "Command", + "description": "The commands to run. Allowed options are: `spawn`, `delegate`." }, - "observation_type": { + "ids": { "anyOf": [ { - "type": "string" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } ], - "title": "Observation Type" + "title": "Ids", + "description": "Required parameter of `spawn` command. List of identifiers to initialize sub-agents with." }, - "annotations": { + "agent_types": { "anyOf": [ { - "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + "items": { + "type": "string" + }, + "type": "array" }, { "type": "null" } - ] + ], + "title": "Agent Types", + "description": "Optional parameter of `spawn` command. List of agent types for each ID (e.g., ['researcher', 'programmer']). If omitted or blank for an ID, the default general-purpose agent is used." }, - "meta": { + "tasks": { "anyOf": [ { - "additionalProperties": true, + "additionalProperties": { + "type": "string" + }, "type": "object" }, { "type": "null" } ], - "title": "Meta" + "title": "Tasks", + "description": "Required parameter of `delegate` command. Dictionary mapping sub-agent identifiers to task descriptions." }, "kind": { "type": "string", - "const": "BrowserToolSet", + "const": "DelegateAction", "title": "Kind" - }, - "title": { - "type": "string", - "title": "Title", - "readOnly": true } }, + "additionalProperties": false, "type": "object", "required": [ - "description", - "action_type", - "kind", - "title" + "command", + "kind" ], - "title": "BrowserToolSet", - "description": "A set of all browser tools.\n\nThis tool set includes all available browser-related tools\n for interacting with web pages.\n\nThe toolset automatically checks for Chromium availability\nwhen created and automatically installs it if missing." + "title": "DelegateAction", + "description": "Schema for delegation operations." }, - "BrowserTypeAction": { + "DelegateObservation": { "properties": { - "index": { - "type": "integer", - "minimum": 0.0, - "title": "Index", - "description": "The index of the input element (from browser_get_state)" + "content": { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/TextContent" + }, + { + "$ref": "#/components/schemas/ImageContent" + } + ] + }, + "type": "array", + "title": "Content", + "description": "Content returned from the tool as a list of TextContent/ImageContent objects. When there is an error, it should be written in this field." }, - "text": { + "is_error": { + "type": "boolean", + "title": "Is Error", + "description": "Whether the observation indicates an error", + "default": false + }, + "command": { "type": "string", - "title": "Text", - "description": "The text to type" + "enum": [ + "spawn", + "delegate" + ], + "title": "Command", + "description": "The command that was executed" }, "kind": { "type": "string", - "const": "BrowserTypeAction", + "const": "DelegateObservation", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "index", - "text", + "command", "kind" ], - "title": "BrowserTypeAction", - "description": "Schema for typing text into elements." + "title": "DelegateObservation", + "description": "Observation from delegation operations." }, - "BrowserTypeTool": { + "DelegateTool": { "properties": { "description": { "type": "string", @@ -5247,7 +7504,7 @@ }, "kind": { "type": "string", - "const": "BrowserTypeTool", + "const": "DelegateTool", "title": "Kind" }, "title": { @@ -5263,60 +7520,12 @@ "kind", "title" ], - "title": "BrowserTypeTool", - "description": "Tool for typing text into browser elements." + "title": "DelegateTool", + "description": "A ToolDefinition subclass that automatically initializes a DelegateExecutor." }, - "CmdOutputMetadata": { + "DesktopUrlResponse": { "properties": { - "exit_code": { - "type": "integer", - "title": "Exit Code", - "description": "The exit code of the last executed command.", - "default": -1 - }, - "pid": { - "type": "integer", - "title": "Pid", - "description": "The process ID of the last executed command.", - "default": -1 - }, - "username": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Username", - "description": "The username of the current user." - }, - "hostname": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Hostname", - "description": "The hostname of the machine." - }, - "working_dir": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Working Dir", - "description": "The current working directory." - }, - "py_interpreter_path": { + "url": { "anyOf": [ { "type": "string" @@ -5325,57 +7534,81 @@ "type": "null" } ], - "title": "Py Interpreter Path", - "description": "The path to the current Python interpreter, if any." - }, - "prefix": { - "type": "string", - "title": "Prefix", - "description": "Prefix to add to command output", - "default": "" - }, - "suffix": { - "type": "string", - "title": "Suffix", - "description": "Suffix to add to command output", - "default": "" + "title": "Url" } }, "type": "object", - "title": "CmdOutputMetadata", - "description": "Additional metadata captured from PS1" + "required": [ + "url" + ], + "title": "DesktopUrlResponse", + "description": "Response model for Desktop URL." }, - "Condensation": { + "EditAction": { "properties": { - "id": { + "file_path": { "type": "string", - "title": "Id", - "description": "Unique event id (ULID/UUID)" + "title": "File Path", + "description": "The path to the file to modify." }, - "timestamp": { + "old_string": { "type": "string", - "title": "Timestamp", - "description": "Event timestamp" + "title": "Old String", + "description": "The text to replace. To create a new file, use an empty string. Must match the exact text in the file including whitespace." }, - "source": { + "new_string": { "type": "string", - "enum": [ - "agent", - "user", - "environment" - ], - "title": "Source", - "default": "environment" + "title": "New String", + "description": "The text to replace it with." }, - "forgotten_event_ids": { + "expected_replacements": { + "type": "integer", + "minimum": 0.0, + "title": "Expected Replacements", + "description": "Number of replacements expected. Defaults to 1. Use when you want to replace multiple occurrences. The edit will fail if the actual count doesn't match.", + "default": 1 + }, + "kind": { + "type": "string", + "const": "EditAction", + "title": "Kind" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "file_path", + "old_string", + "new_string", + "kind" + ], + "title": "EditAction", + "description": "Schema for edit operation." + }, + "EditObservation": { + "properties": { + "content": { "items": { - "type": "string" + "anyOf": [ + { + "$ref": "#/components/schemas/TextContent" + }, + { + "$ref": "#/components/schemas/ImageContent" + } + ] }, "type": "array", - "title": "Forgotten Event Ids", - "description": "The IDs of the events that are being forgotten (removed from the `View` given to the LLM)." + "title": "Content", + "description": "Content returned from the tool as a list of TextContent/ImageContent objects. When there is an error, it should be written in this field." }, - "summary": { + "is_error": { + "type": "boolean", + "title": "Is Error", + "description": "Whether the observation indicates an error", + "default": false + }, + "file_path": { "anyOf": [ { "type": "string" @@ -5384,67 +7617,48 @@ "type": "null" } ], - "title": "Summary", - "description": "An optional summary of the events being forgotten." + "title": "File Path", + "description": "The file path that was edited." }, - "summary_offset": { + "is_new_file": { + "type": "boolean", + "title": "Is New File", + "description": "Whether a new file was created.", + "default": false + }, + "replacements_made": { + "type": "integer", + "title": "Replacements Made", + "description": "Number of replacements actually made.", + "default": 0 + }, + "old_content": { "anyOf": [ { - "type": "integer", - "minimum": 0.0 + "type": "string" }, { "type": "null" } ], - "title": "Summary Offset", - "description": "An optional offset to the start of the resulting view (after forgotten events have been removed) indicating where the summary should be inserted. If not provided, the summary will not be inserted into the view." - }, - "llm_response_id": { - "type": "string", - "title": "Llm Response Id", - "description": "Completion or Response ID of the LLM response that generated this event" - }, - "kind": { - "type": "string", - "const": "Condensation", - "title": "Kind" - } - }, - "additionalProperties": false, - "type": "object", - "required": [ - "llm_response_id", - "kind" - ], - "title": "Condensation", - "description": "This action indicates a condensation of the conversation history is happening." - }, - "CondensationRequest": { - "properties": { - "id": { - "type": "string", - "title": "Id", - "description": "Unique event id (ULID/UUID)" - }, - "timestamp": { - "type": "string", - "title": "Timestamp", - "description": "Event timestamp" + "title": "Old Content", + "description": "The content before the edit." }, - "source": { - "type": "string", - "enum": [ - "agent", - "user", - "environment" + "new_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ], - "title": "Source", - "default": "environment" + "title": "New Content", + "description": "The content after the edit." }, "kind": { "type": "string", - "const": "CondensationRequest", + "const": "EditObservation", "title": "Kind" } }, @@ -5453,362 +7667,225 @@ "required": [ "kind" ], - "title": "CondensationRequest", - "description": "This action is used to request a condensation of the conversation history.\n\nAttributes:\n action (str): The action type, namely ActionType.CONDENSATION_REQUEST." + "title": "EditObservation", + "description": "Observation from editing a file." }, - "CondensationSummaryEvent": { + "EditTool": { "properties": { - "id": { + "description": { "type": "string", - "title": "Id", - "description": "Unique event id (ULID/UUID)" + "title": "Description" }, - "timestamp": { + "action_type": { "type": "string", - "title": "Timestamp", - "description": "Event timestamp" + "title": "Action Type" }, - "source": { - "type": "string", - "enum": [ - "agent", - "user", - "environment" + "observation_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ], - "title": "Source", - "default": "environment" + "title": "Observation Type" }, - "summary": { - "type": "string", - "title": "Summary" + "annotations": { + "anyOf": [ + { + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + }, + { + "type": "null" + } + ] + }, + "meta": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Meta" }, "kind": { "type": "string", - "const": "CondensationSummaryEvent", + "const": "EditTool", "title": "Kind" + }, + "title": { + "type": "string", + "title": "Title", + "readOnly": true } }, - "additionalProperties": false, "type": "object", "required": [ - "summary", - "kind" - ], - "title": "CondensationSummaryEvent", - "description": "This event represents a summary generated by a condenser." - }, - "CondenserBase-Input": { - "oneOf": [ - { - "$ref": "#/components/schemas/LLMSummarizingCondenser-Input" - }, - { - "$ref": "#/components/schemas/NoOpCondenser-Input" - }, - { - "$ref": "#/components/schemas/PipelineCondenser-Input" - } - ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__context__condenser__llm_summarizing_condenser__LLMSummarizingCondenser-Input__1": "#/components/schemas/LLMSummarizingCondenser-Input", - "openhands__sdk__context__condenser__no_op_condenser__NoOpCondenser-Input__1": "#/components/schemas/NoOpCondenser-Input", - "openhands__sdk__context__condenser__pipeline_condenser__PipelineCondenser-Input__1": "#/components/schemas/PipelineCondenser-Input" - } - } - }, - "CondenserBase-Output": { - "oneOf": [ - { - "$ref": "#/components/schemas/LLMSummarizingCondenser-Output" - }, - { - "$ref": "#/components/schemas/NoOpCondenser-Output" - }, - { - "$ref": "#/components/schemas/PipelineCondenser-Output" - } + "description", + "action_type", + "kind", + "title" ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__context__condenser__llm_summarizing_condenser__LLMSummarizingCondenser-Output__1": "#/components/schemas/LLMSummarizingCondenser-Output", - "openhands__sdk__context__condenser__no_op_condenser__NoOpCondenser-Output__1": "#/components/schemas/NoOpCondenser-Output", - "openhands__sdk__context__condenser__pipeline_condenser__PipelineCondenser-Output__1": "#/components/schemas/PipelineCondenser-Output" - } - } + "title": "EditTool", + "description": "Tool for editing files via find/replace." }, - "ConfirmRisky-Input": { + "EmptyPatchCritic-Input": { "properties": { - "threshold": { - "$ref": "#/components/schemas/SecurityRisk", - "default": "HIGH" - }, - "confirm_unknown": { - "type": "boolean", - "title": "Confirm Unknown", - "default": true - }, - "kind": { + "mode": { "type": "string", - "const": "ConfirmRisky", - "title": "Kind" - } - }, - "type": "object", - "title": "ConfirmRisky" - }, - "ConfirmRisky-Output": { - "properties": { - "threshold": { - "$ref": "#/components/schemas/SecurityRisk", - "default": "HIGH" + "enum": [ + "finish_and_message", + "all_actions" + ], + "title": "Mode", + "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", + "default": "finish_and_message" }, - "confirm_unknown": { - "type": "boolean", - "title": "Confirm Unknown", - "default": true + "iterative_refinement": { + "anyOf": [ + { + "$ref": "#/components/schemas/IterativeRefinementConfig" + }, + { + "type": "null" + } + ], + "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." }, "kind": { "type": "string", - "const": "ConfirmRisky", + "const": "EmptyPatchCritic", "title": "Kind" } }, "type": "object", - "required": [ - "kind" - ], - "title": "ConfirmRisky" - }, - "ConfirmationPolicyBase-Input": { - "oneOf": [ - { - "$ref": "#/components/schemas/AlwaysConfirm-Input" - }, - { - "$ref": "#/components/schemas/ConfirmRisky-Input" - }, - { - "$ref": "#/components/schemas/NeverConfirm-Input" - } - ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__security__confirmation_policy__AlwaysConfirm-Input__1": "#/components/schemas/AlwaysConfirm-Input", - "openhands__sdk__security__confirmation_policy__ConfirmRisky-Input__1": "#/components/schemas/ConfirmRisky-Input", - "openhands__sdk__security__confirmation_policy__NeverConfirm-Input__1": "#/components/schemas/NeverConfirm-Input" - } - } - }, - "ConfirmationPolicyBase-Output": { - "oneOf": [ - { - "$ref": "#/components/schemas/AlwaysConfirm-Output" - }, - { - "$ref": "#/components/schemas/ConfirmRisky-Output" - }, - { - "$ref": "#/components/schemas/NeverConfirm-Output" - } - ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__security__confirmation_policy__AlwaysConfirm-Output__1": "#/components/schemas/AlwaysConfirm-Output", - "openhands__sdk__security__confirmation_policy__ConfirmRisky-Output__1": "#/components/schemas/ConfirmRisky-Output", - "openhands__sdk__security__confirmation_policy__NeverConfirm-Output__1": "#/components/schemas/NeverConfirm-Output" - } - } - }, - "ConfirmationResponseRequest": { - "properties": { - "accept": { - "type": "boolean", - "title": "Accept" - }, - "reason": { - "type": "string", - "title": "Reason", - "default": "User rejected the action." - } - }, - "type": "object", - "required": [ - "accept" - ], - "title": "ConfirmationResponseRequest", - "description": "Payload to accept or reject a pending action." + "title": "EmptyPatchCritic", + "description": "Critic that only evaluates whether a git patch is non-empty.\n\nThis critic checks only one criterion:\n- The generated git patch is non-empty (actual changes were made)\n\nUnlike AgentFinishedCritic, this critic does not check for proper\nagent completion with FinishAction." }, - "ConversationErrorEvent": { + "EmptyPatchCritic-Output": { "properties": { - "id": { - "type": "string", - "title": "Id", - "description": "Unique event id (ULID/UUID)" - }, - "timestamp": { - "type": "string", - "title": "Timestamp", - "description": "Event timestamp" - }, - "source": { - "type": "string", - "enum": [ - "agent", - "user", - "environment" - ], - "title": "Source", - "description": "The source of this event" - }, - "code": { + "mode": { "type": "string", - "title": "Code", - "description": "Code for the error - typically a type" + "enum": [ + "finish_and_message", + "all_actions" + ], + "title": "Mode", + "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", + "default": "finish_and_message" }, - "detail": { - "type": "string", - "title": "Detail", - "description": "Details about the error" + "iterative_refinement": { + "anyOf": [ + { + "$ref": "#/components/schemas/IterativeRefinementConfig" + }, + { + "type": "null" + } + ], + "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." }, "kind": { "type": "string", - "const": "ConversationErrorEvent", + "const": "EmptyPatchCritic", "title": "Kind" } }, - "additionalProperties": false, "type": "object", "required": [ - "source", - "code", - "detail", "kind" ], - "title": "ConversationErrorEvent", - "description": "Conversation-level failure that is NOT sent back to the LLM.\n\nThis event is emitted by the conversation runtime when an unexpected\nexception bubbles up and prevents the run loop from continuing. It is\nintended for client applications (e.g., UIs) to present a top-level error\nstate, and for orchestration to react. It is not an observation and it is\nnot LLM-convertible.\n\nDifferences from AgentErrorEvent:\n- Not tied to any tool_name/tool_call_id (AgentErrorEvent is a tool\n observation).\n- Typically source='environment' and the run loop moves to an ERROR state,\n while AgentErrorEvent has source='agent' and the conversation can\n continue." - }, - "ConversationExecutionStatus": { - "type": "string", - "enum": [ - "idle", - "running", - "paused", - "waiting_for_confirmation", - "finished", - "error", - "stuck", - "deleting" - ], - "title": "ConversationExecutionStatus", - "description": "Enum representing the current execution state of the conversation." + "title": "EmptyPatchCritic", + "description": "Critic that only evaluates whether a git patch is non-empty.\n\nThis critic checks only one criterion:\n- The generated git patch is non-empty (actual changes were made)\n\nUnlike AgentFinishedCritic, this critic does not check for proper\nagent completion with FinishAction." }, - "ConversationInfo": { - "properties": { - "id": { - "type": "string", - "format": "uuid", - "title": "Id", - "description": "Unique conversation ID" + "Event": { + "oneOf": [ + { + "$ref": "#/components/schemas/ACPToolCallEvent" }, - "agent": { - "$ref": "#/components/schemas/AgentBase-Output", - "description": "The agent running in the conversation. This is persisted to allow resuming conversations and check agent configuration to handle e.g., tool changes, LLM changes, etc." + { + "$ref": "#/components/schemas/Condensation" }, - "workspace": { - "$ref": "#/components/schemas/BaseWorkspace-Output", - "description": "Workspace used by the agent to execute commands and read/write files. Not the process working directory." + { + "$ref": "#/components/schemas/CondensationRequest" }, - "persistence_dir": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Persistence Dir", - "description": "Directory for persisting conversation state and events. If None, conversation will not be persisted.", - "default": "workspace/conversations" + { + "$ref": "#/components/schemas/CondensationSummaryEvent" }, - "max_iterations": { - "type": "integer", - "exclusiveMinimum": 0.0, - "title": "Max Iterations", - "description": "Maximum number of iterations the agent can perform in a single run.", - "default": 500 + { + "$ref": "#/components/schemas/ConversationErrorEvent" }, - "stuck_detection": { - "type": "boolean", - "title": "Stuck Detection", - "description": "Whether to enable stuck detection for the agent.", - "default": true + { + "$ref": "#/components/schemas/ConversationStateUpdateEvent" }, - "execution_status": { - "$ref": "#/components/schemas/ConversationExecutionStatus", - "default": "idle" + { + "$ref": "#/components/schemas/HookExecutionEvent" }, - "confirmation_policy": { - "$ref": "#/components/schemas/ConfirmationPolicyBase-Output", - "default": { - "kind": "NeverConfirm" - } + { + "$ref": "#/components/schemas/LLMCompletionLogEvent" }, - "security_analyzer": { - "anyOf": [ - { - "$ref": "#/components/schemas/SecurityAnalyzerBase-Output" - }, - { - "type": "null" - } - ], - "description": "Optional security analyzer to evaluate action risks." + { + "$ref": "#/components/schemas/ActionEvent" }, - "activated_knowledge_skills": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Activated Knowledge Skills", - "description": "List of activated knowledge skills name" + { + "$ref": "#/components/schemas/MessageEvent" }, - "blocked_actions": { - "additionalProperties": { - "type": "string" - }, - "type": "object", - "title": "Blocked Actions", - "description": "Actions blocked by PreToolUse hooks, keyed by action ID" + { + "$ref": "#/components/schemas/AgentErrorEvent" }, - "blocked_messages": { - "additionalProperties": { - "type": "string" - }, - "type": "object", - "title": "Blocked Messages", - "description": "Messages blocked by UserPromptSubmit hooks, keyed by message ID" + { + "$ref": "#/components/schemas/ObservationEvent" }, - "stats": { - "$ref": "#/components/schemas/ConversationStats-Output", - "description": "Conversation statistics for tracking LLM metrics" + { + "$ref": "#/components/schemas/UserRejectObservation" }, - "secret_registry": { - "$ref": "#/components/schemas/SecretRegistry-Output", - "description": "Registry for handling secrets and sensitive data" + { + "$ref": "#/components/schemas/SystemPromptEvent" }, - "agent_state": { - "additionalProperties": true, - "type": "object", - "title": "Agent State", - "description": "Dictionary for agent-specific runtime state that persists across iterations. Agents can store feature-specific state using string keys. To trigger autosave, always reassign: state.agent_state = {**state.agent_state, key: value}. See https://docs.openhands.dev/sdk/guides/convo-persistence#how-state-persistence-works" + { + "$ref": "#/components/schemas/TokenEvent" }, - "title": { + { + "$ref": "#/components/schemas/PauseEvent" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "openhands__sdk__event__acp_tool_call__ACPToolCallEvent-Output__1": "#/components/schemas/ACPToolCallEvent", + "openhands__sdk__event__condenser__Condensation-Output__1": "#/components/schemas/Condensation", + "openhands__sdk__event__condenser__CondensationRequest-Output__1": "#/components/schemas/CondensationRequest", + "openhands__sdk__event__condenser__CondensationSummaryEvent-Output__1": "#/components/schemas/CondensationSummaryEvent", + "openhands__sdk__event__conversation_error__ConversationErrorEvent-Output__1": "#/components/schemas/ConversationErrorEvent", + "openhands__sdk__event__conversation_state__ConversationStateUpdateEvent-Output__1": "#/components/schemas/ConversationStateUpdateEvent", + "openhands__sdk__event__hook_execution__HookExecutionEvent-Output__1": "#/components/schemas/HookExecutionEvent", + "openhands__sdk__event__llm_completion_log__LLMCompletionLogEvent-Output__1": "#/components/schemas/LLMCompletionLogEvent", + "openhands__sdk__event__llm_convertible__action__ActionEvent-Output__1": "#/components/schemas/ActionEvent", + "openhands__sdk__event__llm_convertible__message__MessageEvent-Output__1": "#/components/schemas/MessageEvent", + "openhands__sdk__event__llm_convertible__observation__AgentErrorEvent-Output__1": "#/components/schemas/AgentErrorEvent", + "openhands__sdk__event__llm_convertible__observation__ObservationEvent-Output__1": "#/components/schemas/ObservationEvent", + "openhands__sdk__event__llm_convertible__observation__UserRejectObservation-Output__1": "#/components/schemas/UserRejectObservation", + "openhands__sdk__event__llm_convertible__system__SystemPromptEvent-Output__1": "#/components/schemas/SystemPromptEvent", + "openhands__sdk__event__token__TokenEvent-Output__1": "#/components/schemas/TokenEvent", + "openhands__sdk__event__user_action__PauseEvent-Output__1": "#/components/schemas/PauseEvent" + } + } + }, + "EventPage": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/Event" + }, + "type": "array", + "title": "Items" + }, + "next_page_id": { "anyOf": [ { "type": "string" @@ -5817,225 +7894,249 @@ "type": "null" } ], - "title": "Title", - "description": "User-defined title for the conversation" + "title": "Next Page Id" + } + }, + "type": "object", + "required": [ + "items" + ], + "title": "EventPage" + }, + "EventSortOrder": { + "type": "string", + "enum": [ + "TIMESTAMP", + "TIMESTAMP_DESC" + ], + "title": "EventSortOrder", + "description": "Enum for event sorting options." + }, + "ExecuteBashRequest": { + "properties": { + "command": { + "type": "string", + "title": "Command", + "description": "The bash command to execute" }, - "metrics": { + "cwd": { "anyOf": [ { - "$ref": "#/components/schemas/MetricsSnapshot" + "type": "string" }, { "type": "null" } - ] + ], + "title": "Cwd", + "description": "The current working directory" }, - "created_at": { + "timeout": { + "type": "integer", + "title": "Timeout", + "description": "The max number of seconds a command may be permitted to run.", + "default": 300 + } + }, + "type": "object", + "required": [ + "command" + ], + "title": "ExecuteBashRequest" + }, + "ExposedUrl": { + "properties": { + "name": { "type": "string", - "format": "date-time", - "title": "Created At" + "title": "Name" }, - "updated_at": { - "type": "string", - "format": "date-time", - "title": "Updated At" + "url": { + "type": "string", + "title": "Url" + }, + "port": { + "type": "integer", + "title": "Port" } }, "type": "object", "required": [ - "id", - "agent", - "workspace" + "name", + "url", + "port" ], - "title": "ConversationInfo", - "description": "Information about a conversation running locally without a Runtime sandbox." + "title": "ExposedUrl", + "description": "Represents an exposed URL from the sandbox." }, - "ConversationPage": { + "FallbackStrategy": { "properties": { - "items": { + "fallback_llms": { "items": { - "$ref": "#/components/schemas/ConversationInfo" + "type": "string" }, "type": "array", - "title": "Items" + "title": "Fallback Llms", + "description": "Ordered list of LLM profile names to try on transient failure." }, - "next_page_id": { + "profile_store_dir": { "anyOf": [ { "type": "string" }, + { + "type": "string", + "format": "path" + }, { "type": "null" } ], - "title": "Next Page Id" + "title": "Profile Store Dir", + "description": "Path to directory containing profiles. If not specified, defaults to `.openhands/profiles`." } }, "type": "object", "required": [ - "items" - ], - "title": "ConversationPage" - }, - "ConversationSortOrder": { - "type": "string", - "enum": [ - "CREATED_AT", - "UPDATED_AT", - "CREATED_AT_DESC", - "UPDATED_AT_DESC" + "fallback_llms" ], - "title": "ConversationSortOrder", - "description": "Enum for conversation sorting options." + "title": "FallbackStrategy", + "description": "Encapsulates fallback behavior for LLM calls.\n\nWhen the primary LLM fails with a transient error (after retries),\nthis strategy tries alternate LLMs loaded from LLMProfileStore profiles.\nFallback is per-call: each new request starts with the primary model." }, - "ConversationStateUpdateEvent": { + "FileEditorAction": { "properties": { - "id": { + "command": { "type": "string", - "title": "Id", - "description": "Unique event id (ULID/UUID)" + "enum": [ + "view", + "create", + "str_replace", + "insert", + "undo_edit" + ], + "title": "Command", + "description": "The commands to run. Allowed options are: `view`, `create`, `str_replace`, `insert`, `undo_edit`." }, - "timestamp": { + "path": { "type": "string", - "title": "Timestamp", - "description": "Event timestamp" + "title": "Path", + "description": "Absolute path to file or directory." }, - "source": { - "type": "string", - "enum": [ - "agent", - "user", - "environment" + "file_text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ], - "title": "Source", - "default": "environment" + "title": "File Text", + "description": "Required parameter of `create` command, with the content of the file to be created." }, - "key": { - "type": "string", - "title": "Key", - "description": "Unique key for this state update event" + "old_str": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Old Str", + "description": "Required parameter of `str_replace` command containing the string in `path` to replace." }, - "value": { - "title": "Value", - "description": "Serialized conversation state updates" + "new_str": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "New Str", + "description": "Optional parameter of `str_replace` command containing the new string (if not given, no string will be added). Required parameter of `insert` command containing the string to insert." + }, + "insert_line": { + "anyOf": [ + { + "type": "integer", + "minimum": 0.0 + }, + { + "type": "null" + } + ], + "title": "Insert Line", + "description": "Required parameter of `insert` command. The `new_str` will be inserted AFTER the line `insert_line` of `path`." + }, + "view_range": { + "anyOf": [ + { + "items": { + "type": "integer" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "View Range", + "description": "Optional parameter of `view` command when `path` points to a file. If none is given, the full file is shown. If provided, the file will be shown in the indicated line number range, e.g. [11, 12] will show lines 11 and 12. Indexing at 1 to start. Setting `[start_line, -1]` shows all lines from `start_line` to the end of the file." }, "kind": { "type": "string", - "const": "ConversationStateUpdateEvent", + "const": "FileEditorAction", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ + "command", + "path", "kind" ], - "title": "ConversationStateUpdateEvent", - "description": "Event that contains conversation state updates.\n\nThis event is sent via websocket whenever the conversation state changes,\nallowing remote clients to stay in sync without making REST API calls.\n\nAll fields are serialized versions of the corresponding ConversationState fields\nto ensure compatibility with websocket transmission." + "title": "FileEditorAction", + "description": "Schema for file editor operations." }, - "ConversationStats-Input": { + "FileEditorObservation": { "properties": { - "usage_to_metrics": { - "additionalProperties": { - "$ref": "#/components/schemas/Metrics" + "content": { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/TextContent" + }, + { + "$ref": "#/components/schemas/ImageContent" + } + ] }, - "type": "object", - "title": "Usage To Metrics", - "description": "Active usage metrics tracked by the registry." - } - }, - "type": "object", - "title": "ConversationStats", - "description": "Track per-LLM usage metrics observed during conversations." - }, - "ConversationStats-Output": { - "additionalProperties": true, - "type": "object" - }, - "Cost": { - "properties": { - "model": { - "type": "string", - "title": "Model" - }, - "cost": { - "type": "number", - "minimum": 0.0, - "title": "Cost", - "description": "Cost must be non-negative" - }, - "timestamp": { - "type": "number", - "title": "Timestamp" - } - }, - "type": "object", - "required": [ - "model", - "cost" - ], - "title": "Cost" - }, - "CriticBase-Input": { - "oneOf": [ - { - "$ref": "#/components/schemas/AgentFinishedCritic-Input" - }, - { - "$ref": "#/components/schemas/APIBasedCritic-Input" - }, - { - "$ref": "#/components/schemas/EmptyPatchCritic-Input" - }, - { - "$ref": "#/components/schemas/PassCritic-Input" - } - ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__critic__impl__agent_finished__AgentFinishedCritic-Input__1": "#/components/schemas/AgentFinishedCritic-Input", - "openhands__sdk__critic__impl__api__critic__APIBasedCritic-Input__1": "#/components/schemas/APIBasedCritic-Input", - "openhands__sdk__critic__impl__empty_patch__EmptyPatchCritic-Input__1": "#/components/schemas/EmptyPatchCritic-Input", - "openhands__sdk__critic__impl__pass_critic__PassCritic-Input__1": "#/components/schemas/PassCritic-Input" - } - } - }, - "CriticBase-Output": { - "oneOf": [ - { - "$ref": "#/components/schemas/AgentFinishedCritic-Output" - }, - { - "$ref": "#/components/schemas/APIBasedCritic-Output" + "type": "array", + "title": "Content", + "description": "Content returned from the tool as a list of TextContent/ImageContent objects. When there is an error, it should be written in this field." }, - { - "$ref": "#/components/schemas/EmptyPatchCritic-Output" + "is_error": { + "type": "boolean", + "title": "Is Error", + "description": "Whether the observation indicates an error", + "default": false }, - { - "$ref": "#/components/schemas/PassCritic-Output" - } - ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__critic__impl__agent_finished__AgentFinishedCritic-Output__1": "#/components/schemas/AgentFinishedCritic-Output", - "openhands__sdk__critic__impl__api__critic__APIBasedCritic-Output__1": "#/components/schemas/APIBasedCritic-Output", - "openhands__sdk__critic__impl__empty_patch__EmptyPatchCritic-Output__1": "#/components/schemas/EmptyPatchCritic-Output", - "openhands__sdk__critic__impl__pass_critic__PassCritic-Output__1": "#/components/schemas/PassCritic-Output" - } - } - }, - "CriticResult": { - "properties": { - "score": { - "type": "number", - "maximum": 1.0, - "minimum": 0.0, - "title": "Score", - "description": "A predicted probability of success between 0 and 1." + "command": { + "type": "string", + "enum": [ + "view", + "create", + "str_replace", + "insert", + "undo_edit" + ], + "title": "Command", + "description": "The command that was run: `view`, `create`, `str_replace`, `insert`, or `undo_edit`." }, - "message": { + "path": { "anyOf": [ { "type": "string" @@ -6044,34 +8145,65 @@ "type": "null" } ], - "title": "Message", - "description": "An optional message explaining the score." + "title": "Path", + "description": "The file path that was edited." }, - "metadata": { + "prev_exist": { + "type": "boolean", + "title": "Prev Exist", + "description": "Indicates if the file previously existed. If not, it was created.", + "default": true + }, + "old_content": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Metadata", - "description": "Optional metadata about the critic evaluation. Can include event_ids and categorized_features for visualization." + "title": "Old Content", + "description": "The content of the file before the edit." + }, + "new_content": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "New Content", + "description": "The content of the file after the edit." + }, + "kind": { + "type": "string", + "const": "FileEditorObservation", + "title": "Kind" } }, + "additionalProperties": false, "type": "object", "required": [ - "score", - "message" + "command", + "kind" ], - "title": "CriticResult", - "description": "A critic result is a score and a message." + "title": "FileEditorObservation", + "description": "A ToolResult that can be rendered as a CLI output." }, - "DesktopUrlResponse": { + "FileEditorTool": { "properties": { - "url": { + "description": { + "type": "string", + "title": "Description" + }, + "action_type": { + "type": "string", + "title": "Action Type" + }, + "observation_type": { "anyOf": [ { "type": "string" @@ -6080,58 +8212,113 @@ "type": "null" } ], - "title": "Url" + "title": "Observation Type" + }, + "annotations": { + "anyOf": [ + { + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + }, + { + "type": "null" + } + ] + }, + "meta": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Meta" + }, + "kind": { + "type": "string", + "const": "FileEditorTool", + "title": "Kind" + }, + "title": { + "type": "string", + "title": "Title", + "readOnly": true } }, "type": "object", "required": [ - "url" + "description", + "action_type", + "kind", + "title" ], - "title": "DesktopUrlResponse", - "description": "Response model for Desktop URL." + "title": "FileEditorTool", + "description": "A ToolDefinition subclass that automatically initializes a FileEditorExecutor." }, - "EditAction": { + "FileEntry": { "properties": { - "file_path": { + "name": { "type": "string", - "title": "File Path", - "description": "The path to the file to modify." + "title": "Name", + "description": "Name of the file or directory" }, - "old_string": { + "path": { "type": "string", - "title": "Old String", - "description": "The text to replace. To create a new file, use an empty string. Must match the exact text in the file including whitespace." + "title": "Path", + "description": "Absolute path to the file or directory" }, - "new_string": { - "type": "string", - "title": "New String", - "description": "The text to replace it with." + "is_directory": { + "type": "boolean", + "title": "Is Directory", + "description": "Whether this entry is a directory" }, - "expected_replacements": { + "size": { "type": "integer", - "minimum": 0.0, - "title": "Expected Replacements", - "description": "Number of replacements expected. Defaults to 1. Use when you want to replace multiple occurrences. The edit will fail if the actual count doesn't match.", - "default": 1 + "title": "Size", + "description": "Size of the file in bytes (0 for directories)" + }, + "modified_time": { + "type": "string", + "format": "date-time", + "title": "Modified Time", + "description": "Last modified timestamp" + } + }, + "type": "object", + "required": [ + "name", + "path", + "is_directory", + "size", + "modified_time" + ], + "title": "FileEntry", + "description": "Information about a file or directory." + }, + "FinishAction": { + "properties": { + "message": { + "type": "string", + "title": "Message", + "description": "Final message to send to the user." }, "kind": { "type": "string", - "const": "EditAction", + "const": "FinishAction", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "file_path", - "old_string", - "new_string", + "message", "kind" ], - "title": "EditAction", - "description": "Schema for edit operation." + "title": "FinishAction" }, - "EditObservation": { + "FinishObservation": { "properties": { "content": { "items": { @@ -6154,57 +8341,9 @@ "description": "Whether the observation indicates an error", "default": false }, - "file_path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "File Path", - "description": "The file path that was edited." - }, - "is_new_file": { - "type": "boolean", - "title": "Is New File", - "description": "Whether a new file was created.", - "default": false - }, - "replacements_made": { - "type": "integer", - "title": "Replacements Made", - "description": "Number of replacements actually made.", - "default": 0 - }, - "old_content": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Old Content", - "description": "The content before the edit." - }, - "new_content": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "New Content", - "description": "The content after the edit." - }, "kind": { "type": "string", - "const": "EditObservation", + "const": "FinishObservation", "title": "Kind" } }, @@ -6213,10 +8352,10 @@ "required": [ "kind" ], - "title": "EditObservation", - "description": "Observation from editing a file." + "title": "FinishObservation", + "description": "Observation returned after finishing a task.\nThe FinishAction itself contains the message sent to the user so no\nextra fields are needed here." }, - "EditTool": { + "FinishTool": { "properties": { "description": { "type": "string", @@ -6247,183 +8386,249 @@ } ] }, - "meta": { + "meta": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Meta" + }, + "kind": { + "type": "string", + "const": "FinishTool", + "title": "Kind" + }, + "title": { + "type": "string", + "title": "Title", + "readOnly": true + } + }, + "type": "object", + "required": [ + "description", + "action_type", + "kind", + "title" + ], + "title": "FinishTool", + "description": "Tool for signaling the completion of a task or conversation." + }, + "GenerateTitleRequest": { + "properties": { + "max_length": { + "type": "integer", + "maximum": 200.0, + "minimum": 1.0, + "title": "Max Length", + "description": "Maximum length of the generated title", + "default": 50 + }, + "llm": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "$ref": "#/components/schemas/LLM-Input" }, { "type": "null" } ], - "title": "Meta" - }, - "kind": { - "type": "string", - "const": "EditTool", - "title": "Kind" - }, + "description": "Optional LLM to use for title generation" + } + }, + "type": "object", + "title": "GenerateTitleRequest", + "description": "Payload to generate a title for a conversation." + }, + "GenerateTitleResponse": { + "properties": { "title": { "type": "string", "title": "Title", - "readOnly": true + "description": "The generated title for the conversation" } }, "type": "object", "required": [ - "description", - "action_type", - "kind", "title" ], - "title": "EditTool", - "description": "Tool for editing files via find/replace." + "title": "GenerateTitleResponse", + "description": "Response containing the generated conversation title." }, - "EmptyPatchCritic-Input": { + "GitChange": { "properties": { - "mode": { + "status": { + "$ref": "#/components/schemas/GitChangeStatus" + }, + "path": { "type": "string", - "enum": [ - "finish_and_message", - "all_actions" + "format": "path", + "title": "Path" + } + }, + "type": "object", + "required": [ + "status", + "path" + ], + "title": "GitChange" + }, + "GitChangeStatus": { + "type": "string", + "enum": [ + "MOVED", + "ADDED", + "DELETED", + "UPDATED" + ], + "title": "GitChangeStatus" + }, + "GitDiff": { + "properties": { + "modified": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } ], - "title": "Mode", - "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", - "default": "finish_and_message" + "title": "Modified" }, - "iterative_refinement": { + "original": { "anyOf": [ { - "$ref": "#/components/schemas/IterativeRefinementConfig" + "type": "string" }, { "type": "null" } ], - "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." - }, - "kind": { - "type": "string", - "const": "EmptyPatchCritic", - "title": "Kind" + "title": "Original" } }, "type": "object", - "title": "EmptyPatchCritic", - "description": "Critic that only evaluates whether a git patch is non-empty.\n\nThis critic checks only one criterion:\n- The generated git patch is non-empty (actual changes were made)\n\nUnlike AgentFinishedCritic, this critic does not check for proper\nagent completion with FinishAction." + "required": [ + "modified", + "original" + ], + "title": "GitDiff" }, - "EmptyPatchCritic-Output": { + "GlobAction": { "properties": { - "mode": { + "pattern": { "type": "string", - "enum": [ - "finish_and_message", - "all_actions" - ], - "title": "Mode", - "description": "When to run critic evaluation:\n- 'finish_and_message': Evaluate on FinishAction and agent MessageEvent (default, minimal performance impact)\n- 'all_actions': Evaluate after every agent action (WARNING: significantly slower due to API calls on each action)", - "default": "finish_and_message" + "title": "Pattern", + "description": "The glob pattern to match files (e.g., \"**/*.js\", \"src/**/*.ts\")" }, - "iterative_refinement": { + "path": { "anyOf": [ { - "$ref": "#/components/schemas/IterativeRefinementConfig" + "type": "string" }, { "type": "null" } ], - "description": "Optional configuration for iterative refinement. When set, Conversation.run() will automatically retry the task if the critic score is below the success_threshold, up to max_iterations." + "title": "Path", + "description": "The directory (absolute path) to search in. Defaults to the current working directory." }, "kind": { "type": "string", - "const": "EmptyPatchCritic", + "const": "GlobAction", "title": "Kind" } }, + "additionalProperties": false, "type": "object", "required": [ + "pattern", "kind" ], - "title": "EmptyPatchCritic", - "description": "Critic that only evaluates whether a git patch is non-empty.\n\nThis critic checks only one criterion:\n- The generated git patch is non-empty (actual changes were made)\n\nUnlike AgentFinishedCritic, this critic does not check for proper\nagent completion with FinishAction." + "title": "GlobAction", + "description": "Schema for glob pattern matching operations." }, - "Event": { - "oneOf": [ - { - "$ref": "#/components/schemas/Condensation" - }, - { - "$ref": "#/components/schemas/CondensationRequest" - }, - { - "$ref": "#/components/schemas/CondensationSummaryEvent" - }, - { - "$ref": "#/components/schemas/ConversationErrorEvent" - }, - { - "$ref": "#/components/schemas/ConversationStateUpdateEvent" - }, - { - "$ref": "#/components/schemas/LLMCompletionLogEvent" - }, - { - "$ref": "#/components/schemas/ActionEvent" - }, - { - "$ref": "#/components/schemas/MessageEvent" + "GlobObservation": { + "properties": { + "content": { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/TextContent" + }, + { + "$ref": "#/components/schemas/ImageContent" + } + ] + }, + "type": "array", + "title": "Content", + "description": "Content returned from the tool as a list of TextContent/ImageContent objects. When there is an error, it should be written in this field." }, - { - "$ref": "#/components/schemas/AgentErrorEvent" + "is_error": { + "type": "boolean", + "title": "Is Error", + "description": "Whether the observation indicates an error", + "default": false }, - { - "$ref": "#/components/schemas/ObservationEvent" + "files": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Files", + "description": "List of matching file paths sorted by modification time" }, - { - "$ref": "#/components/schemas/UserRejectObservation" + "pattern": { + "type": "string", + "title": "Pattern", + "description": "The glob pattern that was used" }, - { - "$ref": "#/components/schemas/SystemPromptEvent" + "search_path": { + "type": "string", + "title": "Search Path", + "description": "The directory that was searched" }, - { - "$ref": "#/components/schemas/TokenEvent" + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "Whether results were truncated to 100 files", + "default": false }, - { - "$ref": "#/components/schemas/PauseEvent" + "kind": { + "type": "string", + "const": "GlobObservation", + "title": "Kind" } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "files", + "pattern", + "search_path", + "kind" ], - "discriminator": { - "propertyName": "kind", - "mapping": { - "openhands__sdk__event__condenser__Condensation-Output__1": "#/components/schemas/Condensation", - "openhands__sdk__event__condenser__CondensationRequest-Output__1": "#/components/schemas/CondensationRequest", - "openhands__sdk__event__condenser__CondensationSummaryEvent-Output__1": "#/components/schemas/CondensationSummaryEvent", - "openhands__sdk__event__conversation_error__ConversationErrorEvent-Output__1": "#/components/schemas/ConversationErrorEvent", - "openhands__sdk__event__conversation_state__ConversationStateUpdateEvent-Output__1": "#/components/schemas/ConversationStateUpdateEvent", - "openhands__sdk__event__llm_completion_log__LLMCompletionLogEvent-Output__1": "#/components/schemas/LLMCompletionLogEvent", - "openhands__sdk__event__llm_convertible__action__ActionEvent-Output__1": "#/components/schemas/ActionEvent", - "openhands__sdk__event__llm_convertible__message__MessageEvent-Output__1": "#/components/schemas/MessageEvent", - "openhands__sdk__event__llm_convertible__observation__AgentErrorEvent-Output__1": "#/components/schemas/AgentErrorEvent", - "openhands__sdk__event__llm_convertible__observation__ObservationEvent-Output__1": "#/components/schemas/ObservationEvent", - "openhands__sdk__event__llm_convertible__observation__UserRejectObservation-Output__1": "#/components/schemas/UserRejectObservation", - "openhands__sdk__event__llm_convertible__system__SystemPromptEvent-Output__1": "#/components/schemas/SystemPromptEvent", - "openhands__sdk__event__token__TokenEvent-Output__1": "#/components/schemas/TokenEvent", - "openhands__sdk__event__user_action__PauseEvent-Output__1": "#/components/schemas/PauseEvent" - } - } - }, - "EventPage": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/Event" - }, - "type": "array", - "title": "Items" + "title": "GlobObservation", + "description": "Observation from glob pattern matching operations." + }, + "GlobTool": { + "properties": { + "description": { + "type": "string", + "title": "Description" }, - "next_page_id": { + "action_type": { + "type": "string", + "title": "Action Type" + }, + "observation_type": { "anyOf": [ { "type": "string" @@ -6432,112 +8637,104 @@ "type": "null" } ], - "title": "Next Page Id" - } - }, - "type": "object", - "required": [ - "items" - ], - "title": "EventPage" - }, - "EventSortOrder": { - "type": "string", - "enum": [ - "TIMESTAMP", - "TIMESTAMP_DESC" - ], - "title": "EventSortOrder", - "description": "Enum for event sorting options." - }, - "ExecuteBashRequest": { - "properties": { - "command": { - "type": "string", - "title": "Command", - "description": "The bash command to execute" + "title": "Observation Type" }, - "cwd": { + "annotations": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + }, + { + "type": "null" + } + ] + }, + "meta": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" }, { "type": "null" } ], - "title": "Cwd", - "description": "The current working directory" + "title": "Meta" }, - "timeout": { - "type": "integer", - "title": "Timeout", - "description": "The max number of seconds a command may be permitted to run.", - "default": 300 - } - }, - "type": "object", - "required": [ - "command" - ], - "title": "ExecuteBashRequest" - }, - "ExposedUrl": { - "properties": { - "name": { + "kind": { "type": "string", - "title": "Name" + "const": "GlobTool", + "title": "Kind" }, - "url": { + "title": { "type": "string", - "title": "Url" - }, - "port": { - "type": "integer", - "title": "Port" + "title": "Title", + "readOnly": true } }, "type": "object", "required": [ - "name", - "url", - "port" + "description", + "action_type", + "kind", + "title" ], - "title": "ExposedUrl", - "description": "Represents an exposed URL from the sandbox." + "title": "GlobTool", + "description": "A ToolDefinition subclass that automatically initializes a GlobExecutor." }, - "FileEditorAction": { + "GraySwanAnalyzer-Input": { "properties": { - "command": { - "type": "string", - "enum": [ - "view", - "create", - "str_replace", - "insert", - "undo_edit" - ], - "title": "Command", - "description": "The commands to run. Allowed options are: `view`, `create`, `str_replace`, `insert`, `undo_edit`." + "history_limit": { + "type": "integer", + "title": "History Limit", + "description": "Number of recent events to include as context", + "default": 20 }, - "path": { + "max_message_chars": { + "type": "integer", + "title": "Max Message Chars", + "description": "Max characters for conversation processing", + "default": 30000 + }, + "timeout": { + "type": "number", + "title": "Timeout", + "description": "Request timeout in seconds", + "default": 30.0 + }, + "low_threshold": { + "type": "number", + "title": "Low Threshold", + "description": "Risk threshold for LOW classification (score <= threshold)", + "default": 0.3 + }, + "medium_threshold": { + "type": "number", + "title": "Medium Threshold", + "description": "Risk threshold for MEDIUM classification (score <= threshold)", + "default": 0.7 + }, + "api_url": { "type": "string", - "title": "Path", - "description": "Absolute path to file or directory." + "title": "Api Url", + "description": "GraySwan Cygnal API endpoint", + "default": "https://api.grayswan.ai/cygnal/monitor" }, - "file_text": { + "api_key": { "anyOf": [ { - "type": "string" + "type": "string", + "format": "password", + "writeOnly": true }, { "type": "null" } ], - "title": "File Text", - "description": "Required parameter of `create` command, with the content of the file to be created." + "title": "Api Key", + "description": "GraySwan API key (via GRAYSWAN_API_KEY env var)" }, - "old_str": { + "policy_id": { "anyOf": [ { "type": "string" @@ -6546,10 +8743,72 @@ "type": "null" } ], - "title": "Old Str", - "description": "Required parameter of `str_replace` command containing the string in `path` to replace." + "title": "Policy Id", + "description": "GraySwan policy ID (via GRAYSWAN_POLICY_ID env var)" }, - "new_str": { + "kind": { + "type": "string", + "const": "GraySwanAnalyzer", + "title": "Kind" + } + }, + "type": "object", + "title": "GraySwanAnalyzer", + "description": "Security analyzer using GraySwan's Cygnal API for AI safety monitoring.\n\nThis analyzer sends conversation history and pending actions to the GraySwan\nCygnal API for security analysis. The API returns a violation score which is\nmapped to SecurityRisk levels.\n\nEnvironment Variables:\n GRAYSWAN_API_KEY: Required API key for GraySwan authentication\n GRAYSWAN_POLICY_ID: Optional policy ID for custom GraySwan policy\n\nExample:\n >>> from openhands.sdk.security.grayswan import GraySwanAnalyzer\n >>> analyzer = GraySwanAnalyzer()\n >>> risk = analyzer.security_risk(action_event)" + }, + "GraySwanAnalyzer-Output": { + "properties": { + "history_limit": { + "type": "integer", + "title": "History Limit", + "description": "Number of recent events to include as context", + "default": 20 + }, + "max_message_chars": { + "type": "integer", + "title": "Max Message Chars", + "description": "Max characters for conversation processing", + "default": 30000 + }, + "timeout": { + "type": "number", + "title": "Timeout", + "description": "Request timeout in seconds", + "default": 30.0 + }, + "low_threshold": { + "type": "number", + "title": "Low Threshold", + "description": "Risk threshold for LOW classification (score <= threshold)", + "default": 0.3 + }, + "medium_threshold": { + "type": "number", + "title": "Medium Threshold", + "description": "Risk threshold for MEDIUM classification (score <= threshold)", + "default": 0.7 + }, + "api_url": { + "type": "string", + "title": "Api Url", + "description": "GraySwan Cygnal API endpoint", + "default": "https://api.grayswan.ai/cygnal/monitor" + }, + "api_key": { + "anyOf": [ + { + "type": "string", + "format": "password", + "writeOnly": true + }, + { + "type": "null" + } + ], + "title": "Api Key", + "description": "GraySwan API key (via GRAYSWAN_API_KEY env var)" + }, + "policy_id": { "anyOf": [ { "type": "string" @@ -6558,54 +8817,69 @@ "type": "null" } ], - "title": "New Str", - "description": "Optional parameter of `str_replace` command containing the new string (if not given, no string will be added). Required parameter of `insert` command containing the string to insert." + "title": "Policy Id", + "description": "GraySwan policy ID (via GRAYSWAN_POLICY_ID env var)" }, - "insert_line": { + "kind": { + "type": "string", + "const": "GraySwanAnalyzer", + "title": "Kind" + } + }, + "type": "object", + "required": [ + "kind" + ], + "title": "GraySwanAnalyzer", + "description": "Security analyzer using GraySwan's Cygnal API for AI safety monitoring.\n\nThis analyzer sends conversation history and pending actions to the GraySwan\nCygnal API for security analysis. The API returns a violation score which is\nmapped to SecurityRisk levels.\n\nEnvironment Variables:\n GRAYSWAN_API_KEY: Required API key for GraySwan authentication\n GRAYSWAN_POLICY_ID: Optional policy ID for custom GraySwan policy\n\nExample:\n >>> from openhands.sdk.security.grayswan import GraySwanAnalyzer\n >>> analyzer = GraySwanAnalyzer()\n >>> risk = analyzer.security_risk(action_event)" + }, + "GrepAction": { + "properties": { + "pattern": { + "type": "string", + "title": "Pattern", + "description": "The regex pattern to search for in file contents" + }, + "path": { "anyOf": [ { - "type": "integer", - "minimum": 0.0 + "type": "string" }, { "type": "null" } ], - "title": "Insert Line", - "description": "Required parameter of `insert` command. The `new_str` will be inserted AFTER the line `insert_line` of `path`." + "title": "Path", + "description": "The directory (absolute path) to search in. Defaults to the current working directory." }, - "view_range": { + "include": { "anyOf": [ { - "items": { - "type": "integer" - }, - "type": "array" + "type": "string" }, { "type": "null" } ], - "title": "View Range", - "description": "Optional parameter of `view` command when `path` points to a file. If none is given, the full file is shown. If provided, the file will be shown in the indicated line number range, e.g. [11, 12] will show lines 11 and 12. Indexing at 1 to start. Setting `[start_line, -1]` shows all lines from `start_line` to the end of the file." + "title": "Include", + "description": "Optional file pattern to filter which files to search (e.g., \"*.js\", \"*.{ts,tsx}\")" }, "kind": { "type": "string", - "const": "FileEditorAction", + "const": "GrepAction", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "command", - "path", + "pattern", "kind" ], - "title": "FileEditorAction", - "description": "Schema for file editor operations." + "title": "GrepAction", + "description": "Schema for grep content search operations." }, - "FileEditorObservation": { + "GrepObservation": { "properties": { "content": { "items": { @@ -6628,37 +8902,25 @@ "description": "Whether the observation indicates an error", "default": false }, - "command": { - "type": "string", - "enum": [ - "view", - "create", - "str_replace", - "insert", - "undo_edit" - ], - "title": "Command", - "description": "The command that was run: `view`, `create`, `str_replace`, `insert`, or `undo_edit`." + "matches": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Matches", + "description": "List of file paths containing the pattern" }, - "path": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Path", - "description": "The file path that was edited." + "pattern": { + "type": "string", + "title": "Pattern", + "description": "The regex pattern that was used" }, - "prev_exist": { - "type": "boolean", - "title": "Prev Exist", - "description": "Indicates if the file previously existed. If not, it was created.", - "default": true + "search_path": { + "type": "string", + "title": "Search Path", + "description": "The directory that was searched" }, - "old_content": { + "include_pattern": { "anyOf": [ { "type": "string" @@ -6667,37 +8929,33 @@ "type": "null" } ], - "title": "Old Content", - "description": "The content of the file before the edit." + "title": "Include Pattern", + "description": "The file pattern filter that was used" }, - "new_content": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "New Content", - "description": "The content of the file after the edit." + "truncated": { + "type": "boolean", + "title": "Truncated", + "description": "Whether results were truncated to 100 files", + "default": false }, "kind": { "type": "string", - "const": "FileEditorObservation", + "const": "GrepObservation", "title": "Kind" } }, "additionalProperties": false, "type": "object", "required": [ - "command", + "matches", + "pattern", + "search_path", "kind" ], - "title": "FileEditorObservation", - "description": "A ToolResult that can be rendered as a CLI output." + "title": "GrepObservation", + "description": "Observation from grep content search operations." }, - "FileEditorTool": { + "GrepTool": { "properties": { "description": { "type": "string", @@ -6742,7 +9000,7 @@ }, "kind": { "type": "string", - "const": "FileEditorTool", + "const": "GrepTool", "title": "Kind" }, "title": { @@ -6758,118 +9016,205 @@ "kind", "title" ], - "title": "FileEditorTool", - "description": "A ToolDefinition subclass that automatically initializes a FileEditorExecutor." + "title": "GrepTool", + "description": "A ToolDefinition subclass that automatically initializes a GrepExecutor." }, - "FileEntry": { + "HTTPValidationError": { "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "Name of the file or directory" - }, - "path": { - "type": "string", - "title": "Path", - "description": "Absolute path to the file or directory" - }, - "is_directory": { - "type": "boolean", - "title": "Is Directory", - "description": "Whether this entry is a directory" - }, - "size": { - "type": "integer", - "title": "Size", - "description": "Size of the file in bytes (0 for directories)" - }, - "modified_time": { - "type": "string", - "format": "date-time", - "title": "Modified Time", - "description": "Last modified timestamp" + "detail": { + "items": { + "$ref": "#/components/schemas/ValidationError" + }, + "type": "array", + "title": "Detail" } }, "type": "object", - "required": [ - "name", - "path", - "is_directory", - "size", - "modified_time" - ], - "title": "FileEntry", - "description": "Information about a file or directory." + "title": "HTTPValidationError" }, - "FinishAction": { + "HookConfig-Input": { "properties": { - "message": { - "type": "string", - "title": "Message", - "description": "Final message to send to the user." + "pre_tool_use": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Input" + }, + "type": "array", + "title": "Pre Tool Use", + "description": "Hooks that run before tool execution" }, - "kind": { - "type": "string", - "const": "FinishAction", - "title": "Kind" + "post_tool_use": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Input" + }, + "type": "array", + "title": "Post Tool Use", + "description": "Hooks that run after tool execution" + }, + "user_prompt_submit": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Input" + }, + "type": "array", + "title": "User Prompt Submit", + "description": "Hooks that run when user submits a prompt" + }, + "session_start": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Input" + }, + "type": "array", + "title": "Session Start", + "description": "Hooks that run when a session starts" + }, + "session_end": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Input" + }, + "type": "array", + "title": "Session End", + "description": "Hooks that run when a session ends" + }, + "stop": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Input" + }, + "type": "array", + "title": "Stop", + "description": "Hooks that run when the agent attempts to stop" } }, "additionalProperties": false, "type": "object", - "required": [ - "message", - "kind" - ], - "title": "FinishAction" + "title": "HookConfig", + "description": "Configuration for all hooks.\n\nHooks can be configured either by loading from `.openhands/hooks.json` or\nby directly instantiating with typed fields:\n\n # Direct instantiation with typed fields (recommended):\n config = HookConfig(\n pre_tool_use=[\n HookMatcher(\n matcher=\"terminal\",\n hooks=[HookDefinition(command=\"block_dangerous.sh\")]\n )\n ]\n )\n\n # Load from JSON file:\n config = HookConfig.load(\".openhands/hooks.json\")" }, - "FinishObservation": { + "HookConfig-Output": { "properties": { - "content": { + "pre_tool_use": { "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/TextContent" - }, - { - "$ref": "#/components/schemas/ImageContent" - } - ] + "$ref": "#/components/schemas/HookMatcher-Output" + }, + "type": "array", + "title": "Pre Tool Use", + "description": "Hooks that run before tool execution" + }, + "post_tool_use": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Output" + }, + "type": "array", + "title": "Post Tool Use", + "description": "Hooks that run after tool execution" + }, + "user_prompt_submit": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Output" + }, + "type": "array", + "title": "User Prompt Submit", + "description": "Hooks that run when user submits a prompt" + }, + "session_start": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Output" + }, + "type": "array", + "title": "Session Start", + "description": "Hooks that run when a session starts" + }, + "session_end": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Output" }, "type": "array", - "title": "Content", - "description": "Content returned from the tool as a list of TextContent/ImageContent objects. When there is an error, it should be written in this field." + "title": "Session End", + "description": "Hooks that run when a session ends" }, - "is_error": { - "type": "boolean", - "title": "Is Error", - "description": "Whether the observation indicates an error", - "default": false + "stop": { + "items": { + "$ref": "#/components/schemas/HookMatcher-Output" + }, + "type": "array", + "title": "Stop", + "description": "Hooks that run when the agent attempts to stop" + } + }, + "additionalProperties": false, + "type": "object", + "title": "HookConfig", + "description": "Configuration for all hooks.\n\nHooks can be configured either by loading from `.openhands/hooks.json` or\nby directly instantiating with typed fields:\n\n # Direct instantiation with typed fields (recommended):\n config = HookConfig(\n pre_tool_use=[\n HookMatcher(\n matcher=\"terminal\",\n hooks=[HookDefinition(command=\"block_dangerous.sh\")]\n )\n ]\n )\n\n # Load from JSON file:\n config = HookConfig.load(\".openhands/hooks.json\")" + }, + "HookDefinition": { + "properties": { + "type": { + "$ref": "#/components/schemas/HookType", + "default": "command" }, - "kind": { + "command": { "type": "string", - "const": "FinishObservation", - "title": "Kind" + "title": "Command" + }, + "timeout": { + "type": "integer", + "title": "Timeout", + "default": 60 + }, + "async": { + "type": "boolean", + "title": "Async", + "default": false } }, - "additionalProperties": false, "type": "object", "required": [ - "kind" + "command" ], - "title": "FinishObservation", - "description": "Observation returned after finishing a task.\nThe FinishAction itself contains the message sent to the user so no\nextra fields are needed here." + "title": "HookDefinition", + "description": "A single hook definition." }, - "FinishTool": { + "HookExecutionEvent": { "properties": { - "description": { + "id": { "type": "string", - "title": "Description" + "title": "Id", + "description": "Unique event id (ULID/UUID)" }, - "action_type": { + "timestamp": { "type": "string", - "title": "Action Type" + "title": "Timestamp", + "description": "Event timestamp" }, - "observation_type": { + "source": { + "type": "string", + "enum": [ + "agent", + "user", + "environment", + "hook" + ], + "title": "Source", + "description": "Source is always 'hook' for hook execution events", + "default": "hook" + }, + "hook_event_type": { + "type": "string", + "enum": [ + "PreToolUse", + "PostToolUse", + "UserPromptSubmit", + "SessionStart", + "SessionEnd", + "Stop" + ], + "title": "Hook Event Type", + "description": "The type of hook event that triggered this execution" + }, + "hook_command": { + "type": "string", + "title": "Hook Command", + "description": "The hook command that was executed" + }, + "tool_name": { "anyOf": [ { "type": "string" @@ -6878,123 +9223,178 @@ "type": "null" } ], - "title": "Observation Type" + "title": "Tool Name", + "description": "Tool name for PreToolUse/PostToolUse hooks" }, - "annotations": { + "success": { + "type": "boolean", + "title": "Success", + "description": "Whether the hook executed successfully" + }, + "blocked": { + "type": "boolean", + "title": "Blocked", + "description": "Whether the hook blocked the operation (exit code 2 or deny)", + "default": false + }, + "exit_code": { + "type": "integer", + "title": "Exit Code", + "description": "Exit code from the hook command" + }, + "stdout": { + "type": "string", + "title": "Stdout", + "description": "Standard output from the hook", + "default": "" + }, + "stderr": { + "type": "string", + "title": "Stderr", + "description": "Standard error from the hook", + "default": "" + }, + "reason": { "anyOf": [ { - "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + "type": "string" }, { "type": "null" } - ] + ], + "title": "Reason", + "description": "Reason provided by hook (for blocking)" }, - "meta": { + "additional_context": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "string" }, { "type": "null" } ], - "title": "Meta" + "title": "Additional Context", + "description": "Additional context injected by hook (e.g., for UserPromptSubmit)" }, - "kind": { - "type": "string", - "const": "FinishTool", - "title": "Kind" + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error", + "description": "Error message if hook execution failed" }, - "title": { - "type": "string", - "title": "Title", - "readOnly": true - } - }, - "type": "object", - "required": [ - "description", - "action_type", - "kind", - "title" - ], - "title": "FinishTool", - "description": "Tool for signaling the completion of a task or conversation." - }, - "GenerateTitleRequest": { - "properties": { - "max_length": { - "type": "integer", - "maximum": 200.0, - "minimum": 1.0, - "title": "Max Length", - "description": "Maximum length of the generated title", - "default": 50 + "action_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Action Id", + "description": "ID of the action this hook is associated with (PreToolUse/PostToolUse)" }, - "llm": { + "message_id": { "anyOf": [ { - "$ref": "#/components/schemas/LLM" + "type": "string" }, { "type": "null" } ], - "description": "Optional LLM to use for title generation" + "title": "Message Id", + "description": "ID of the message this hook is associated with (UserPromptSubmit)" + }, + "hook_input": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Hook Input", + "description": "The input data that was passed to the hook" + }, + "kind": { + "type": "string", + "const": "HookExecutionEvent", + "title": "Kind" } }, + "additionalProperties": false, "type": "object", - "title": "GenerateTitleRequest", - "description": "Payload to generate a title for a conversation." + "required": [ + "hook_event_type", + "hook_command", + "success", + "exit_code", + "kind" + ], + "title": "HookExecutionEvent", + "description": "Event emitted when a hook is executed.\n\nThis event provides observability into hook execution, including:\n- Which hook type was triggered\n- The command that was run\n- The result (success/blocked/error)\n- Any output from the hook\n\nThis allows clients to track hook execution via the event stream." }, - "GenerateTitleResponse": { + "HookMatcher-Input": { "properties": { - "title": { + "matcher": { "type": "string", - "title": "Title", - "description": "The generated title for the conversation" + "title": "Matcher", + "default": "*" + }, + "hooks": { + "items": { + "$ref": "#/components/schemas/HookDefinition" + }, + "type": "array", + "title": "Hooks" } }, "type": "object", - "required": [ - "title" - ], - "title": "GenerateTitleResponse", - "description": "Response containing the generated conversation title." + "title": "HookMatcher", + "description": "Matches events to hooks based on patterns.\n\nSupports exact match, wildcard (*), and regex (auto-detected or /pattern/)." }, - "GitChange": { + "HookMatcher-Output": { "properties": { - "status": { - "$ref": "#/components/schemas/GitChangeStatus" - }, - "path": { + "matcher": { "type": "string", - "format": "path", - "title": "Path" + "title": "Matcher", + "default": "*" + }, + "hooks": { + "items": { + "$ref": "#/components/schemas/HookDefinition" + }, + "type": "array", + "title": "Hooks" } }, "type": "object", - "required": [ - "status", - "path" - ], - "title": "GitChange" + "title": "HookMatcher", + "description": "Matches events to hooks based on patterns.\n\nSupports exact match, wildcard (*), and regex (auto-detected or /pattern/)." }, - "GitChangeStatus": { + "HookType": { "type": "string", "enum": [ - "MOVED", - "ADDED", - "DELETED", - "UPDATED" + "command", + "prompt" ], - "title": "GitChangeStatus" + "title": "HookType", + "description": "Types of hooks that can be executed." }, - "GitDiff": { + "HooksRequest": { "properties": { - "modified": { + "project_dir": { "anyOf": [ { "type": "string" @@ -7003,35 +9403,39 @@ "type": "null" } ], - "title": "Modified" - }, - "original": { + "title": "Project Dir", + "description": "Workspace directory path for project hooks" + } + }, + "type": "object", + "title": "HooksRequest", + "description": "Request body for loading hooks." + }, + "HooksResponse": { + "properties": { + "hook_config": { "anyOf": [ { - "type": "string" + "$ref": "#/components/schemas/HookConfig-Output" }, { "type": "null" } ], - "title": "Original" + "description": "Hook configuration loaded from the workspace, or None if not found" } }, "type": "object", - "required": [ - "modified", - "original" - ], - "title": "GitDiff" + "title": "HooksResponse", + "description": "Response containing hooks configuration." }, - "GlobAction": { + "Icon": { "properties": { - "pattern": { + "src": { "type": "string", - "title": "Pattern", - "description": "The glob pattern to match files (e.g., \"**/*.js\", \"src/**/*.ts\")" + "title": "Src" }, - "path": { + "mimeType": { "anyOf": [ { "type": "string" @@ -7040,192 +9444,137 @@ "type": "null" } ], - "title": "Path", - "description": "The directory (absolute path) to search in. Defaults to the current working directory." + "title": "Mimetype" }, - "kind": { - "type": "string", - "const": "GlobAction", - "title": "Kind" + "sizes": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Sizes" } }, - "additionalProperties": false, + "additionalProperties": true, "type": "object", "required": [ - "pattern", - "kind" + "src" ], - "title": "GlobAction", - "description": "Schema for glob pattern matching operations." + "title": "Icon", + "description": "An icon for display in user interfaces." }, - "GlobObservation": { + "ImageContent": { "properties": { - "content": { - "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/TextContent" - }, - { - "$ref": "#/components/schemas/ImageContent" - } - ] - }, - "type": "array", - "title": "Content", - "description": "Content returned from the tool as a list of TextContent/ImageContent objects. When there is an error, it should be written in this field." - }, - "is_error": { + "cache_prompt": { "type": "boolean", - "title": "Is Error", - "description": "Whether the observation indicates an error", + "title": "Cache Prompt", "default": false }, - "files": { + "type": { + "type": "string", + "const": "image", + "title": "Type", + "default": "image" + }, + "image_urls": { "items": { "type": "string" }, "type": "array", - "title": "Files", - "description": "List of matching file paths sorted by modification time" - }, - "pattern": { - "type": "string", - "title": "Pattern", - "description": "The glob pattern that was used" - }, - "search_path": { - "type": "string", - "title": "Search Path", - "description": "The directory that was searched" - }, - "truncated": { - "type": "boolean", - "title": "Truncated", - "description": "Whether results were truncated to 100 files", - "default": false - }, - "kind": { - "type": "string", - "const": "GlobObservation", - "title": "Kind" + "title": "Image Urls" } }, - "additionalProperties": false, "type": "object", "required": [ - "files", - "pattern", - "search_path", - "kind" + "image_urls" ], - "title": "GlobObservation", - "description": "Observation from glob pattern matching operations." + "title": "ImageContent" }, - "GlobTool": { + "InputMetadata": { "properties": { - "description": { - "type": "string", - "title": "Description" - }, - "action_type": { - "type": "string", - "title": "Action Type" - }, - "observation_type": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Observation Type" - }, - "annotations": { - "anyOf": [ - { - "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" - }, - { - "type": "null" - } - ] - }, - "meta": { - "anyOf": [ - { - "additionalProperties": true, - "type": "object" - }, - { - "type": "null" - } - ], - "title": "Meta" - }, - "kind": { + "name": { "type": "string", - "const": "GlobTool", - "title": "Kind" + "title": "Name", + "description": "Name of the input parameter" }, - "title": { + "description": { "type": "string", - "title": "Title", - "readOnly": true + "title": "Description", + "description": "Description of the input parameter" } }, "type": "object", "required": [ - "description", - "action_type", - "kind", - "title" + "name", + "description" ], - "title": "GlobTool", - "description": "A ToolDefinition subclass that automatically initializes a GlobExecutor." + "title": "InputMetadata", + "description": "Metadata for task skill inputs." }, - "GraySwanAnalyzer-Input": { + "IterativeRefinementConfig": { "properties": { - "history_limit": { - "type": "integer", - "title": "History Limit", - "description": "Number of recent events to include as context", - "default": 20 - }, - "max_message_chars": { - "type": "integer", - "title": "Max Message Chars", - "description": "Max characters for conversation processing", - "default": 30000 - }, - "timeout": { - "type": "number", - "title": "Timeout", - "description": "Request timeout in seconds", - "default": 30.0 - }, - "low_threshold": { - "type": "number", - "title": "Low Threshold", - "description": "Risk threshold for LOW classification (score <= threshold)", - "default": 0.3 - }, - "medium_threshold": { + "success_threshold": { "type": "number", - "title": "Medium Threshold", - "description": "Risk threshold for MEDIUM classification (score <= threshold)", - "default": 0.7 + "maximum": 1.0, + "minimum": 0.0, + "title": "Success Threshold", + "description": "Score threshold (0-1) to consider task successful.", + "default": 0.6 }, - "api_url": { + "max_iterations": { + "type": "integer", + "minimum": 1.0, + "title": "Max Iterations", + "description": "Maximum number of iterations before giving up.", + "default": 3 + } + }, + "type": "object", + "title": "IterativeRefinementConfig", + "description": "Configuration for iterative refinement based on critic feedback.\n\nWhen attached to a CriticBase, the Conversation.run() method will\nautomatically retry the task if the critic score is below the threshold.\n\nExample:\n critic = APIBasedCritic(\n server_url=\"...\",\n api_key=\"...\",\n model_name=\"critic\",\n iterative_refinement=IterativeRefinementConfig(\n success_threshold=0.7,\n max_iterations=3,\n ),\n )\n agent = Agent(llm=llm, tools=tools, critic=critic)\n conversation = Conversation(agent=agent, workspace=workspace)\n conversation.send_message(\"Create a calculator module...\")\n conversation.run() # Will automatically retry if critic score < 0.7" + }, + "KeywordTrigger": { + "properties": { + "type": { "type": "string", - "title": "Api Url", - "description": "GraySwan Cygnal API endpoint", - "default": "https://api.grayswan.ai/cygnal/monitor" + "const": "keyword", + "title": "Type", + "default": "keyword" + }, + "keywords": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Keywords" + } + }, + "type": "object", + "required": [ + "keywords" + ], + "title": "KeywordTrigger", + "description": "Trigger for keyword-based skills.\n\nThese skills are activated when specific keywords appear in the user's query." + }, + "LLM-Input": { + "properties": { + "model": { + "type": "string", + "title": "Model", + "description": "Model name.", + "default": "claude-sonnet-4-20250514" }, "api_key": { "anyOf": [ + { + "type": "string" + }, { "type": "string", "format": "password", @@ -7236,9 +9585,9 @@ } ], "title": "Api Key", - "description": "GraySwan API key (via GRAYSWAN_API_KEY env var)" + "description": "API key." }, - "policy_id": { + "base_url": { "anyOf": [ { "type": "string" @@ -7247,59 +9596,42 @@ "type": "null" } ], - "title": "Policy Id", - "description": "GraySwan policy ID (via GRAYSWAN_POLICY_ID env var)" - }, - "kind": { - "type": "string", - "const": "GraySwanAnalyzer", - "title": "Kind" - } - }, - "type": "object", - "title": "GraySwanAnalyzer", - "description": "Security analyzer using GraySwan's Cygnal API for AI safety monitoring.\n\nThis analyzer sends conversation history and pending actions to the GraySwan\nCygnal API for security analysis. The API returns a violation score which is\nmapped to SecurityRisk levels.\n\nEnvironment Variables:\n GRAYSWAN_API_KEY: Required API key for GraySwan authentication\n GRAYSWAN_POLICY_ID: Optional policy ID for custom GraySwan policy\n\nExample:\n >>> from openhands.sdk.security.grayswan import GraySwanAnalyzer\n >>> analyzer = GraySwanAnalyzer()\n >>> risk = analyzer.security_risk(action_event)" - }, - "GraySwanAnalyzer-Output": { - "properties": { - "history_limit": { - "type": "integer", - "title": "History Limit", - "description": "Number of recent events to include as context", - "default": 20 - }, - "max_message_chars": { - "type": "integer", - "title": "Max Message Chars", - "description": "Max characters for conversation processing", - "default": 30000 - }, - "timeout": { - "type": "number", - "title": "Timeout", - "description": "Request timeout in seconds", - "default": 30.0 - }, - "low_threshold": { - "type": "number", - "title": "Low Threshold", - "description": "Risk threshold for LOW classification (score <= threshold)", - "default": 0.3 + "title": "Base Url", + "description": "Custom base URL." }, - "medium_threshold": { - "type": "number", - "title": "Medium Threshold", - "description": "Risk threshold for MEDIUM classification (score <= threshold)", - "default": 0.7 + "api_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Api Version", + "description": "API version (e.g., Azure)." }, - "api_url": { - "type": "string", - "title": "Api Url", - "description": "GraySwan Cygnal API endpoint", - "default": "https://api.grayswan.ai/cygnal/monitor" + "aws_access_key_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "string", + "format": "password", + "writeOnly": true + }, + { + "type": "null" + } + ], + "title": "Aws Access Key Id" }, - "api_key": { + "aws_secret_access_key": { "anyOf": [ + { + "type": "string" + }, { "type": "string", "format": "password", @@ -7309,10 +9641,9 @@ "type": "null" } ], - "title": "Api Key", - "description": "GraySwan API key (via GRAYSWAN_API_KEY env var)" + "title": "Aws Secret Access Key" }, - "policy_id": { + "aws_region_name": { "anyOf": [ { "type": "string" @@ -7321,155 +9652,129 @@ "type": "null" } ], - "title": "Policy Id", - "description": "GraySwan policy ID (via GRAYSWAN_POLICY_ID env var)" + "title": "Aws Region Name" }, - "kind": { + "openrouter_site_url": { "type": "string", - "const": "GraySwanAnalyzer", - "title": "Kind" - } - }, - "type": "object", - "required": [ - "kind" - ], - "title": "GraySwanAnalyzer", - "description": "Security analyzer using GraySwan's Cygnal API for AI safety monitoring.\n\nThis analyzer sends conversation history and pending actions to the GraySwan\nCygnal API for security analysis. The API returns a violation score which is\nmapped to SecurityRisk levels.\n\nEnvironment Variables:\n GRAYSWAN_API_KEY: Required API key for GraySwan authentication\n GRAYSWAN_POLICY_ID: Optional policy ID for custom GraySwan policy\n\nExample:\n >>> from openhands.sdk.security.grayswan import GraySwanAnalyzer\n >>> analyzer = GraySwanAnalyzer()\n >>> risk = analyzer.security_risk(action_event)" - }, - "GrepAction": { - "properties": { - "pattern": { + "title": "Openrouter Site Url", + "default": "https://docs.all-hands.dev/" + }, + "openrouter_app_name": { "type": "string", - "title": "Pattern", - "description": "The regex pattern to search for in file contents" + "title": "Openrouter App Name", + "default": "OpenHands" }, - "path": { + "num_retries": { + "type": "integer", + "minimum": 0.0, + "title": "Num Retries", + "default": 5 + }, + "retry_multiplier": { + "type": "number", + "minimum": 0.0, + "title": "Retry Multiplier", + "default": 8.0 + }, + "retry_min_wait": { + "type": "integer", + "minimum": 0.0, + "title": "Retry Min Wait", + "default": 8 + }, + "retry_max_wait": { + "type": "integer", + "minimum": 0.0, + "title": "Retry Max Wait", + "default": 64 + }, + "timeout": { "anyOf": [ { - "type": "string" + "type": "integer", + "minimum": 0.0 }, { "type": "null" } ], - "title": "Path", - "description": "The directory (absolute path) to search in. Defaults to the current working directory." + "title": "Timeout", + "description": "HTTP timeout in seconds. Default is 300s (5 minutes). Set to None to disable timeout (not recommended for production).", + "default": 300 }, - "include": { + "max_message_chars": { + "type": "integer", + "minimum": 1.0, + "title": "Max Message Chars", + "description": "Approx max chars in each event/content sent to the LLM.", + "default": 30000 + }, + "temperature": { "anyOf": [ { - "type": "string" + "type": "number", + "minimum": 0.0 }, { "type": "null" } ], - "title": "Include", - "description": "Optional file pattern to filter which files to search (e.g., \"*.js\", \"*.{ts,tsx}\")" - }, - "kind": { - "type": "string", - "const": "GrepAction", - "title": "Kind" - } - }, - "additionalProperties": false, - "type": "object", - "required": [ - "pattern", - "kind" - ], - "title": "GrepAction", - "description": "Schema for grep content search operations." - }, - "GrepObservation": { - "properties": { - "content": { - "items": { - "anyOf": [ - { - "$ref": "#/components/schemas/TextContent" - }, - { - "$ref": "#/components/schemas/ImageContent" - } - ] - }, - "type": "array", - "title": "Content", - "description": "Content returned from the tool as a list of TextContent/ImageContent objects. When there is an error, it should be written in this field." - }, - "is_error": { - "type": "boolean", - "title": "Is Error", - "description": "Whether the observation indicates an error", - "default": false + "title": "Temperature", + "description": "Sampling temperature for response generation. Defaults to None (uses provider default temperature). Set to 0.0 for deterministic outputs, or higher values (0.7-1.0) for more creative responses." }, - "matches": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Matches", - "description": "List of file paths containing the pattern" + "top_p": { + "anyOf": [ + { + "type": "number", + "maximum": 1.0, + "minimum": 0.0 + }, + { + "type": "null" + } + ], + "title": "Top P", + "description": "Nucleus sampling parameter. Defaults to None (uses provider default). Set to a value between 0 and 1 to control diversity of outputs." }, - "pattern": { - "type": "string", - "title": "Pattern", - "description": "The regex pattern that was used" + "top_k": { + "anyOf": [ + { + "type": "number", + "minimum": 0.0 + }, + { + "type": "null" + } + ], + "title": "Top K" }, - "search_path": { - "type": "string", - "title": "Search Path", - "description": "The directory that was searched" + "max_input_tokens": { + "anyOf": [ + { + "type": "integer", + "minimum": 1.0 + }, + { + "type": "null" + } + ], + "title": "Max Input Tokens", + "description": "The maximum number of input tokens. Note that this is currently unused, and the value at runtime is actually the total tokens in OpenAI (e.g. 128,000 tokens for GPT-4)." }, - "include_pattern": { + "max_output_tokens": { "anyOf": [ { - "type": "string" + "type": "integer", + "minimum": 1.0 }, { "type": "null" } ], - "title": "Include Pattern", - "description": "The file pattern filter that was used" - }, - "truncated": { - "type": "boolean", - "title": "Truncated", - "description": "Whether results were truncated to 100 files", - "default": false - }, - "kind": { - "type": "string", - "const": "GrepObservation", - "title": "Kind" - } - }, - "additionalProperties": false, - "type": "object", - "required": [ - "matches", - "pattern", - "search_path", - "kind" - ], - "title": "GrepObservation", - "description": "Observation from grep content search operations." - }, - "GrepTool": { - "properties": { - "description": { - "type": "string", - "title": "Description" - }, - "action_type": { - "type": "string", - "title": "Action Type" + "title": "Max Output Tokens", + "description": "The maximum number of output tokens. This is sent to the LLM." }, - "observation_type": { + "model_canonical_name": { "anyOf": [ { "type": "string" @@ -7478,249 +9783,122 @@ "type": "null" } ], - "title": "Observation Type" + "title": "Model Canonical Name", + "description": "Optional canonical model name for feature registry lookups. The OpenHands SDK maintains a model feature registry that maps model names to capabilities (e.g., vision support, prompt caching, responses API support). When using proxied or aliased model identifiers, set this field to the canonical model name (e.g., 'openai/gpt-4o') to ensure correct capability detection. If not provided, the 'model' field will be used for capability lookups." }, - "annotations": { + "extra_headers": { "anyOf": [ { - "$ref": "#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations" + "additionalProperties": { + "type": "string" + }, + "type": "object" }, { "type": "null" } - ] + ], + "title": "Extra Headers", + "description": "Optional HTTP headers to forward to LiteLLM requests." }, - "meta": { + "input_cost_per_token": { "anyOf": [ { - "additionalProperties": true, - "type": "object" + "type": "number", + "minimum": 0.0 }, { "type": "null" } ], - "title": "Meta" - }, - "kind": { - "type": "string", - "const": "GrepTool", - "title": "Kind" - }, - "title": { - "type": "string", - "title": "Title", - "readOnly": true - } - }, - "type": "object", - "required": [ - "description", - "action_type", - "kind", - "title" - ], - "title": "GrepTool", - "description": "A ToolDefinition subclass that automatically initializes a GrepExecutor." - }, - "HTTPValidationError": { - "properties": { - "detail": { - "items": { - "$ref": "#/components/schemas/ValidationError" - }, - "type": "array", - "title": "Detail" - } - }, - "type": "object", - "title": "HTTPValidationError" - }, - "HookConfig-Input": { - "properties": { - "pre_tool_use": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Input" - }, - "type": "array", - "title": "Pre Tool Use", - "description": "Hooks that run before tool execution" - }, - "post_tool_use": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Input" - }, - "type": "array", - "title": "Post Tool Use", - "description": "Hooks that run after tool execution" - }, - "user_prompt_submit": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Input" - }, - "type": "array", - "title": "User Prompt Submit", - "description": "Hooks that run when user submits a prompt" - }, - "session_start": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Input" - }, - "type": "array", - "title": "Session Start", - "description": "Hooks that run when a session starts" - }, - "session_end": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Input" - }, - "type": "array", - "title": "Session End", - "description": "Hooks that run when a session ends" + "title": "Input Cost Per Token", + "description": "The cost per input token. This will available in logs for user." }, - "stop": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Input" - }, - "type": "array", - "title": "Stop", - "description": "Hooks that run when the agent attempts to stop" - } - }, - "additionalProperties": false, - "type": "object", - "title": "HookConfig", - "description": "Configuration for all hooks.\n\nHooks can be configured either by loading from `.openhands/hooks.json` or\nby directly instantiating with typed fields:\n\n # Direct instantiation with typed fields (recommended):\n config = HookConfig(\n pre_tool_use=[\n HookMatcher(\n matcher=\"terminal\",\n hooks=[HookDefinition(command=\"block_dangerous.sh\")]\n )\n ]\n )\n\n # Load from JSON file:\n config = HookConfig.load(\".openhands/hooks.json\")" - }, - "HookConfig-Output": { - "properties": { - "pre_tool_use": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Output" - }, - "type": "array", - "title": "Pre Tool Use", - "description": "Hooks that run before tool execution" + "output_cost_per_token": { + "anyOf": [ + { + "type": "number", + "minimum": 0.0 + }, + { + "type": "null" + } + ], + "title": "Output Cost Per Token", + "description": "The cost per output token. This will available in logs for user." }, - "post_tool_use": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Output" - }, - "type": "array", - "title": "Post Tool Use", - "description": "Hooks that run after tool execution" + "ollama_base_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Ollama Base Url" }, - "user_prompt_submit": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Output" - }, - "type": "array", - "title": "User Prompt Submit", - "description": "Hooks that run when user submits a prompt" + "stream": { + "type": "boolean", + "title": "Stream", + "description": "Enable streaming responses from the LLM. When enabled, the provided `on_token` callback in .completions and .responses will be invoked for each chunk of tokens.", + "default": false }, - "session_start": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Output" - }, - "type": "array", - "title": "Session Start", - "description": "Hooks that run when a session starts" + "drop_params": { + "type": "boolean", + "title": "Drop Params", + "default": true }, - "session_end": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Output" - }, - "type": "array", - "title": "Session End", - "description": "Hooks that run when a session ends" + "modify_params": { + "type": "boolean", + "title": "Modify Params", + "description": "Modify params allows litellm to do transformations like adding a default message, when a message is empty.", + "default": true }, - "stop": { - "items": { - "$ref": "#/components/schemas/HookMatcher-Output" - }, - "type": "array", - "title": "Stop", - "description": "Hooks that run when the agent attempts to stop" - } - }, - "additionalProperties": false, - "type": "object", - "title": "HookConfig", - "description": "Configuration for all hooks.\n\nHooks can be configured either by loading from `.openhands/hooks.json` or\nby directly instantiating with typed fields:\n\n # Direct instantiation with typed fields (recommended):\n config = HookConfig(\n pre_tool_use=[\n HookMatcher(\n matcher=\"terminal\",\n hooks=[HookDefinition(command=\"block_dangerous.sh\")]\n )\n ]\n )\n\n # Load from JSON file:\n config = HookConfig.load(\".openhands/hooks.json\")" - }, - "HookDefinition": { - "properties": { - "type": { - "$ref": "#/components/schemas/HookType", - "default": "command" + "disable_vision": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Disable Vision", + "description": "If model is vision capable, this option allows to disable image processing (useful for cost reduction)." }, - "command": { - "type": "string", - "title": "Command" + "disable_stop_word": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "title": "Disable Stop Word", + "description": "Disable using of stop word.", + "default": false }, - "timeout": { - "type": "integer", - "title": "Timeout", - "default": 60 - } - }, - "type": "object", - "required": [ - "command" - ], - "title": "HookDefinition", - "description": "A single hook definition." - }, - "HookMatcher-Input": { - "properties": { - "matcher": { - "type": "string", - "title": "Matcher", - "default": "*" + "caching_prompt": { + "type": "boolean", + "title": "Caching Prompt", + "description": "Enable caching of prompts.", + "default": true }, - "hooks": { - "items": { - "$ref": "#/components/schemas/HookDefinition" - }, - "type": "array", - "title": "Hooks" - } - }, - "type": "object", - "title": "HookMatcher", - "description": "Matches events to hooks based on patterns.\n\nSupports exact match, wildcard (*), and regex (auto-detected or /pattern/)." - }, - "HookMatcher-Output": { - "properties": { - "matcher": { + "log_completions": { + "type": "boolean", + "title": "Log Completions", + "description": "Enable logging of completions.", + "default": false + }, + "log_completions_folder": { "type": "string", - "title": "Matcher", - "default": "*" + "title": "Log Completions Folder", + "description": "The folder to log LLM completions to. Required if log_completions is True.", + "default": "logs/completions" }, - "hooks": { - "items": { - "$ref": "#/components/schemas/HookDefinition" - }, - "type": "array", - "title": "Hooks" - } - }, - "type": "object", - "title": "HookMatcher", - "description": "Matches events to hooks based on patterns.\n\nSupports exact match, wildcard (*), and regex (auto-detected or /pattern/)." - }, - "HookType": { - "type": "string", - "enum": [ - "command", - "prompt" - ], - "title": "HookType", - "description": "Types of hooks that can be executed." - }, - "HooksRequest": { - "properties": { - "project_dir": { + "custom_tokenizer": { "anyOf": [ { "type": "string" @@ -7729,166 +9907,155 @@ "type": "null" } ], - "title": "Project Dir", - "description": "Workspace directory path for project hooks" - } - }, - "type": "object", - "title": "HooksRequest", - "description": "Request body for loading hooks." - }, - "HooksResponse": { - "properties": { - "hook_config": { + "title": "Custom Tokenizer", + "description": "A custom tokenizer to use for token counting." + }, + "native_tool_calling": { + "type": "boolean", + "title": "Native Tool Calling", + "description": "Whether to use native tool calling.", + "default": true + }, + "force_string_serializer": { "anyOf": [ { - "$ref": "#/components/schemas/HookConfig-Output" + "type": "boolean" }, { "type": "null" } ], - "description": "Hook configuration loaded from the workspace, or None if not found" - } - }, - "type": "object", - "title": "HooksResponse", - "description": "Response containing hooks configuration." - }, - "Icon": { - "properties": { - "src": { - "type": "string", - "title": "Src" + "title": "Force String Serializer", + "description": "Force using string content serializer when sending to LLM API. If None (default), auto-detect based on model. Useful for providers that do not support list content, like HuggingFace and Groq." }, - "mimeType": { + "reasoning_effort": { "anyOf": [ { - "type": "string" + "type": "string", + "enum": [ + "low", + "medium", + "high", + "xhigh", + "none" + ] }, { "type": "null" } ], - "title": "Mimetype" + "title": "Reasoning Effort", + "description": "The effort to put into reasoning. This is a string that can be one of 'low', 'medium', 'high', 'xhigh', or 'none'. Can apply to all reasoning models.", + "default": "high" }, - "sizes": { + "reasoning_summary": { "anyOf": [ { - "items": { - "type": "string" - }, - "type": "array" + "type": "string", + "enum": [ + "auto", + "concise", + "detailed" + ] }, { "type": "null" } ], - "title": "Sizes" - } - }, - "additionalProperties": true, - "type": "object", - "required": [ - "src" - ], - "title": "Icon", - "description": "An icon for display in user interfaces." - }, - "ImageContent": { - "properties": { - "cache_prompt": { + "title": "Reasoning Summary", + "description": "The level of detail for reasoning summaries. This is a string that can be one of 'auto', 'concise', or 'detailed'. Requires verified OpenAI organization. Only sent when explicitly set." + }, + "enable_encrypted_reasoning": { "type": "boolean", - "title": "Cache Prompt", - "default": false + "title": "Enable Encrypted Reasoning", + "description": "If True, ask for ['reasoning.encrypted_content'] in Responses API include.", + "default": true }, - "type": { - "type": "string", - "const": "image", - "title": "Type", - "default": "image" + "prompt_cache_retention": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Prompt Cache Retention", + "description": "Retention policy for prompt cache. Only sent for supported models (GPT-5+ and GPT-4.1, excluding Azure deployments); explicitly stripped for all others.", + "default": "24h" }, - "image_urls": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Image Urls" - } - }, - "type": "object", - "required": [ - "image_urls" - ], - "title": "ImageContent" - }, - "InputMetadata": { - "properties": { - "name": { - "type": "string", - "title": "Name", - "description": "Name of the input parameter" + "extended_thinking_budget": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Extended Thinking Budget", + "description": "The budget tokens for extended thinking, supported by Anthropic models.", + "default": 200000 + }, + "seed": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Seed", + "description": "The seed to use for random number generation." + }, + "safety_settings": { + "anyOf": [ + { + "items": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "title": "Safety Settings", + "description": "Deprecated: Safety settings for models that support them (like Mistral AI and Gemini). This field is deprecated in 1.10.0 and will be removed in 1.15.0. Safety settings are designed for consumer-facing content moderation, which is not relevant for coding agents." }, - "description": { + "usage_id": { "type": "string", - "title": "Description", - "description": "Description of the input parameter" - } - }, - "type": "object", - "required": [ - "name", - "description" - ], - "title": "InputMetadata", - "description": "Metadata for task skill inputs." - }, - "IterativeRefinementConfig": { - "properties": { - "success_threshold": { - "type": "number", - "maximum": 1.0, - "minimum": 0.0, - "title": "Success Threshold", - "description": "Score threshold (0-1) to consider task successful.", - "default": 0.6 + "title": "Usage Id", + "description": "Unique usage identifier for the LLM. Used for registry lookups, telemetry, and spend tracking.", + "default": "default" }, - "max_iterations": { - "type": "integer", - "minimum": 1.0, - "title": "Max Iterations", - "description": "Maximum number of iterations before giving up.", - "default": 3 - } - }, - "type": "object", - "title": "IterativeRefinementConfig", - "description": "Configuration for iterative refinement based on critic feedback.\n\nWhen attached to a CriticBase, the Conversation.run() method will\nautomatically retry the task if the critic score is below the threshold.\n\nExample:\n critic = APIBasedCritic(\n server_url=\"...\",\n api_key=\"...\",\n model_name=\"critic\",\n iterative_refinement=IterativeRefinementConfig(\n success_threshold=0.7,\n max_iterations=3,\n ),\n )\n agent = Agent(llm=llm, tools=tools, critic=critic)\n conversation = Conversation(agent=agent, workspace=workspace)\n conversation.send_message(\"Create a calculator module...\")\n conversation.run() # Will automatically retry if critic score < 0.7" - }, - "KeywordTrigger": { - "properties": { - "type": { - "type": "string", - "const": "keyword", - "title": "Type", - "default": "keyword" + "litellm_extra_body": { + "additionalProperties": true, + "type": "object", + "title": "Litellm Extra Body", + "description": "Additional key-value pairs to pass to litellm's extra_body parameter. This is useful for custom inference endpoints that need additional parameters for configuration, routing, or advanced features. NOTE: Not all LLM providers support extra_body parameters. Some providers (e.g., OpenAI) may reject requests with unrecognized options. This is commonly supported by: - LiteLLM proxy servers (routing metadata, tracing) - vLLM endpoints (return_token_ids, etc.) - Custom inference clusters Examples: - Proxy routing: {'trace_version': '1.0.0', 'tags': ['agent:my-agent']} - vLLM features: {'return_token_ids': True}" }, - "keywords": { - "items": { - "type": "string" - }, - "type": "array", - "title": "Keywords" + "fallback_strategy": { + "anyOf": [ + { + "$ref": "#/components/schemas/FallbackStrategy" + }, + { + "type": "null" + } + ], + "description": "Optional fallback strategy for trying alternate LLMs on transient failure. Construct with FallbackStrategy(fallback_llms=[...]).Excluded from serialization; must be reconfigured after load." } }, "type": "object", - "required": [ - "keywords" - ], - "title": "KeywordTrigger", - "description": "Trigger for keyword-based skills.\n\nThese skills are activated when specific keywords appear in the user's query." + "title": "LLM", + "description": "Language model interface for OpenHands agents.\n\nThe LLM class provides a unified interface for interacting with various\nlanguage models through the litellm library. It handles model configuration,\nAPI authentication, retry logic, and tool calling capabilities.\n\nAttributes:\n model: Model name (e.g., \"claude-sonnet-4-20250514\").\n api_key: API key for authentication.\n base_url: Custom API base URL.\n num_retries: Number of retry attempts for failed requests.\n timeout: Request timeout in seconds.\n\nExample:\n ```python\n from openhands.sdk import LLM\n from pydantic import SecretStr\n\n llm = LLM(\n model=\"claude-sonnet-4-20250514\",\n api_key=SecretStr(\"your-api-key\"),\n usage_id=\"my-agent\"\n )\n # Use with agent or conversation\n ```" }, - "LLM": { + "LLM-Output": { "properties": { "model": { "type": "string", @@ -8046,7 +10213,7 @@ } ], "title": "Temperature", - "description": "Sampling temperature for response generation. Defaults to 0 for most models and provider default for reasoning models." + "description": "Sampling temperature for response generation. Defaults to None (uses provider default temperature). Set to 0.0 for deterministic outputs, or higher values (0.7-1.0) for more creative responses." }, "top_p": { "anyOf": [ @@ -8060,7 +10227,7 @@ } ], "title": "Top P", - "default": 1.0 + "description": "Nucleus sampling parameter. Defaults to None (uses provider default). Set to a value between 0 and 1 to control diversity of outputs." }, "top_k": { "anyOf": [ @@ -8307,7 +10474,7 @@ } ], "title": "Prompt Cache Retention", - "description": "Retention policy for prompt cache. Only sent for GPT-5+ models; explicitly stripped for all other models.", + "description": "Retention policy for prompt cache. Only sent for supported models (GPT-5+ and GPT-4.1, excluding Azure deployments); explicitly stripped for all others.", "default": "24h" }, "extended_thinking_budget": { @@ -8368,7 +10535,7 @@ }, "type": "object", "title": "LLM", - "description": "Language model interface for OpenHands agents.\n\nThe LLM class provides a unified interface for interacting with various\nlanguage models through the litellm library. It handles model configuration,\nAPI authentication,\nretry logic, and tool calling capabilities.\n\nExample:\n >>> from openhands.sdk import LLM\n >>> from pydantic import SecretStr\n >>> llm = LLM(\n ... model=\"claude-sonnet-4-20250514\",\n ... api_key=SecretStr(\"your-api-key\"),\n ... usage_id=\"my-agent\"\n ... )\n >>> # Use with agent or conversation" + "description": "Language model interface for OpenHands agents.\n\nThe LLM class provides a unified interface for interacting with various\nlanguage models through the litellm library. It handles model configuration,\nAPI authentication, retry logic, and tool calling capabilities.\n\nAttributes:\n model: Model name (e.g., \"claude-sonnet-4-20250514\").\n api_key: API key for authentication.\n base_url: Custom API base URL.\n num_retries: Number of retry attempts for failed requests.\n timeout: Request timeout in seconds.\n\nExample:\n ```python\n from openhands.sdk import LLM\n from pydantic import SecretStr\n\n llm = LLM(\n model=\"claude-sonnet-4-20250514\",\n api_key=SecretStr(\"your-api-key\"),\n usage_id=\"my-agent\"\n )\n # Use with agent or conversation\n ```" }, "LLMCompletionLogEvent": { "properties": { @@ -8387,7 +10554,8 @@ "enum": [ "agent", "user", - "environment" + "environment", + "hook" ], "title": "Source", "default": "environment" @@ -8460,7 +10628,7 @@ "LLMSummarizingCondenser-Input": { "properties": { "llm": { - "$ref": "#/components/schemas/LLM" + "$ref": "#/components/schemas/LLM-Input" }, "max_size": { "type": "integer", @@ -8485,6 +10653,13 @@ "title": "Keep First", "default": 2 }, + "minimum_progress": { + "type": "number", + "exclusiveMaximum": 1.0, + "exclusiveMinimum": 0.0, + "title": "Minimum Progress", + "default": 0.1 + }, "hard_context_reset_max_retries": { "type": "integer", "exclusiveMinimum": 0.0, @@ -8514,7 +10689,7 @@ "LLMSummarizingCondenser-Output": { "properties": { "llm": { - "$ref": "#/components/schemas/LLM" + "$ref": "#/components/schemas/LLM-Output" }, "max_size": { "type": "integer", @@ -8539,6 +10714,13 @@ "title": "Keep First", "default": 2 }, + "minimum_progress": { + "type": "number", + "exclusiveMaximum": 1.0, + "exclusiveMinimum": 0.0, + "title": "Minimum Progress", + "default": 0.1 + }, "hard_context_reset_max_retries": { "type": "integer", "exclusiveMinimum": 0.0, @@ -9103,7 +11285,8 @@ "enum": [ "agent", "user", - "environment" + "environment", + "hook" ], "title": "Source" }, @@ -9325,6 +11508,23 @@ "title": "MetricsSnapshot", "description": "A snapshot of metrics at a point in time.\n\nDoes not include lists of individual costs, latencies, or token usages." }, + "ModelsResponse": { + "properties": { + "models": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Models" + } + }, + "type": "object", + "required": [ + "models" + ], + "title": "ModelsResponse", + "description": "Response containing the list of available LLM models." + }, "NeverConfirm-Input": { "properties": { "kind": { @@ -9391,6 +11591,9 @@ { "$ref": "#/components/schemas/BrowserObservation" }, + { + "$ref": "#/components/schemas/DelegateObservation" + }, { "$ref": "#/components/schemas/FileEditorObservation" }, @@ -9429,6 +11632,7 @@ "openhands__sdk__tool__builtins__finish__FinishObservation-Output__1": "#/components/schemas/FinishObservation", "openhands__sdk__tool__builtins__think__ThinkObservation-Output__1": "#/components/schemas/ThinkObservation", "openhands__tools__browser_use__definition__BrowserObservation-Output__1": "#/components/schemas/BrowserObservation", + "openhands__tools__delegate__definition__DelegateObservation-Output__1": "#/components/schemas/DelegateObservation", "openhands__tools__file_editor__definition__FileEditorObservation-Output__1": "#/components/schemas/FileEditorObservation", "openhands__tools__gemini__edit__definition__EditObservation-Output__1": "#/components/schemas/EditObservation", "openhands__tools__gemini__list_directory__definition__ListDirectoryObservation-Output__1": "#/components/schemas/ListDirectoryObservation", @@ -9459,7 +11663,8 @@ "enum": [ "agent", "user", - "environment" + "environment", + "hook" ], "title": "Source", "default": "environment" @@ -9619,7 +11824,8 @@ "enum": [ "agent", "user", - "environment" + "environment", + "hook" ], "title": "Source", "default": "user" @@ -9977,6 +12183,23 @@ "title": "PluginSource", "description": "Specification for a plugin to load.\n\nThis model describes where to find a plugin and is used by load_plugins()\nto fetch and load plugins from various sources.\n\nExamples:\n >>> # GitHub repository\n >>> PluginSource(source=\"github:owner/repo\", ref=\"v1.0.0\")\n\n >>> # Plugin from monorepo subdirectory\n >>> PluginSource(\n ... source=\"github:owner/monorepo\",\n ... repo_path=\"plugins/my-plugin\"\n ... )\n\n >>> # Local path\n >>> PluginSource(source=\"/path/to/plugin\")" }, + "ProvidersResponse": { + "properties": { + "providers": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Providers" + } + }, + "type": "object", + "required": [ + "providers" + ], + "title": "ProvidersResponse", + "description": "Response containing the list of available LLM providers." + }, "ReadFileAction": { "properties": { "file_path": { @@ -10260,63 +12483,7 @@ "title": "RedactedThinkingBlock", "description": "Redacted thinking block for previous responses without extended thinking.\n\nThis is used as a placeholder for assistant messages that were generated\nbefore extended thinking was enabled." }, - "RemoteWorkspace-Input": { - "properties": { - "working_dir": { - "type": "string", - "title": "Working Dir", - "description": "The working directory for agent operations and tool execution." - }, - "host": { - "type": "string", - "title": "Host", - "description": "The remote host URL for the workspace." - }, - "api_key": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Api Key", - "description": "API key for authenticating with the remote host." - }, - "read_timeout": { - "type": "number", - "title": "Read Timeout", - "description": "Timeout in seconds for reading operations of httpx.Client.", - "default": 600.0 - }, - "max_connections": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "title": "Max Connections", - "description": "Maximum number of connections for httpx.Client. None means no limit, useful for running many conversations in parallel." - }, - "kind": { - "type": "string", - "const": "RemoteWorkspace", - "title": "Kind" - } - }, - "type": "object", - "required": [ - "working_dir", - "host" - ], - "title": "RemoteWorkspace", - "description": "Remote workspace implementation that connects to an OpenHands agent server.\n\nRemoteWorkspace provides access to a sandboxed environment running on a remote\nOpenHands agent server. This is the recommended approach for production deployments\nas it provides better isolation and security.\n\nExample:\n >>> workspace = RemoteWorkspace(\n ... host=\"https://agent-server.example.com\",\n ... working_dir=\"/workspace\"\n ... )\n >>> with workspace:\n ... result = workspace.execute_command(\"ls -la\")\n ... content = workspace.read_file(\"README.md\")" - }, - "RemoteWorkspace-Output": { + "RemoteWorkspace": { "properties": { "working_dir": { "type": "string", @@ -10414,21 +12581,7 @@ "title": "SandboxConfig", "description": "Configuration for loading sandbox-specific skills." }, - "SecretRegistry-Input": { - "properties": { - "secret_sources": { - "additionalProperties": { - "$ref": "#/components/schemas/SecretSource-Input" - }, - "type": "object", - "title": "Secret Sources" - } - }, - "type": "object", - "title": "SecretRegistry", - "description": "Manages secrets and injects them into bash commands when needed.\n\nThe secret registry stores a mapping of secret keys to SecretSources\nthat retrieve the actual secret values. When a bash command is about to be\nexecuted, it scans the command for any secret keys and injects the corresponding\nenvironment variables.\n\nSecret sources will redact / encrypt their sensitive values as appropriate when\nserializing, depending on the content of the context. If a context is present\nand contains a 'cipher' object, this is used for encryption. If it contains a\nboolean 'expose_secrets' flag set to True, secrets are dunped in plain text.\nOtherwise secrets are redacted.\n\nAdditionally, it tracks the latest exported values to enable consistent masking\neven when callable secrets fail on subsequent calls." - }, - "SecretRegistry-Output": { + "SecretRegistry": { "properties": { "secret_sources": { "additionalProperties": { @@ -10576,8 +12729,31 @@ }, "version": { "type": "string", - "title": "Version", - "default": "1.11.4" + "title": "Version" + }, + "sdk_version": { + "type": "string", + "title": "Sdk Version" + }, + "tools_version": { + "type": "string", + "title": "Tools Version" + }, + "workspace_version": { + "type": "string", + "title": "Workspace Version" + }, + "build_git_sha": { + "type": "string", + "title": "Build Git Sha" + }, + "build_git_ref": { + "type": "string", + "title": "Build Git Ref" + }, + "python_version": { + "type": "string", + "title": "Python Version" }, "docs": { "type": "string", @@ -10717,7 +12893,7 @@ } ], "title": "Description", - "description": "A brief description of what the skill does and when to use it. AgentSkills standard field (max 1024 characters)." + "description": "A brief description of what the skill does and when to use it. Descriptions exceeding MAX_DESCRIPTION_LENGTH are truncated with a notice pointing to the skill's source path." }, "license": { "anyOf": [ @@ -10900,7 +13076,7 @@ "load_public": { "type": "boolean", "title": "Load Public", - "description": "Load public skills from OpenHands/skills repo", + "description": "Load public skills from OpenHands/extensions repo", "default": true }, "load_user": { @@ -10921,6 +13097,19 @@ "description": "Load organization-level skills", "default": true }, + "marketplace_path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Marketplace Path", + "description": "Relative marketplace JSON path for public skills. Set to null to load all public skills.", + "default": "marketplaces/default.json" + }, "project_dir": { "anyOf": [ { @@ -11054,6 +13243,14 @@ "title": "Tool Module Qualnames", "description": "Mapping of tool names to their module qualnames from the client's registry. These modules will be dynamically imported on the server to register the tools for this conversation." }, + "agent_definitions": { + "items": { + "$ref": "#/components/schemas/AgentDefinition" + }, + "type": "array", + "title": "Agent Definitions", + "description": "Agent definitions from the client's registry. These are registered on the server so that DelegateTool and TaskSetTool can see user-registered subagents." + }, "plugins": { "anyOf": [ { @@ -11079,6 +13276,12 @@ } ], "description": "Optional hook configuration for this conversation. Hooks are shell scripts that run at key lifecycle events (PreToolUse, PostToolUse, UserPromptSubmit, Stop, etc.). If both hook_config and plugins are provided, they are merged with explicit hooks running before plugin hooks." + }, + "autotitle": { + "type": "boolean", + "title": "Autotitle", + "description": "If true, automatically generate a title for the conversation from the first user message using the conversation's LLM.", + "default": true } }, "type": "object", @@ -11217,7 +13420,8 @@ "enum": [ "agent", "user", - "environment" + "environment", + "hook" ], "title": "Source", "default": "agent" @@ -11861,7 +14065,8 @@ "enum": [ "agent", "user", - "environment" + "environment", + "hook" ], "title": "Source" }, @@ -12051,6 +14256,9 @@ { "$ref": "#/components/schemas/BrowserTypeTool" }, + { + "$ref": "#/components/schemas/DelegateTool" + }, { "$ref": "#/components/schemas/FileEditorTool" }, @@ -12103,6 +14311,7 @@ "openhands__tools__browser_use__definition__BrowserSwitchTabTool-Output__1": "#/components/schemas/BrowserSwitchTabTool", "openhands__tools__browser_use__definition__BrowserToolSet-Output__1": "#/components/schemas/BrowserToolSet", "openhands__tools__browser_use__definition__BrowserTypeTool-Output__1": "#/components/schemas/BrowserTypeTool", + "openhands__tools__delegate__definition__DelegateTool-Output__1": "#/components/schemas/DelegateTool", "openhands__tools__file_editor__definition__FileEditorTool-Output__1": "#/components/schemas/FileEditorTool", "openhands__tools__gemini__edit__definition__EditTool-Output__1": "#/components/schemas/EditTool", "openhands__tools__gemini__list_directory__definition__ListDirectoryTool-Output__1": "#/components/schemas/ListDirectoryTool", @@ -12116,6 +14325,30 @@ } } }, + "ToolExecution": { + "properties": { + "taskSupport": { + "anyOf": [ + { + "type": "string", + "enum": [ + "forbidden", + "optional", + "required" + ] + }, + { + "type": "null" + } + ], + "title": "Tasksupport" + } + }, + "additionalProperties": true, + "type": "object", + "title": "ToolExecution", + "description": "Execution-related properties for a tool." + }, "UpdateConversationRequest": { "properties": { "title": { @@ -12168,7 +14401,8 @@ "enum": [ "agent", "user", - "environment" + "environment", + "hook" ], "title": "Source", "default": "environment" @@ -12265,6 +14499,13 @@ "type": { "type": "string", "title": "Error Type" + }, + "input": { + "title": "Input" + }, + "ctx": { + "type": "object", + "title": "Context" } }, "type": "object", @@ -12275,6 +14516,26 @@ ], "title": "ValidationError" }, + "VerifiedModelsResponse": { + "properties": { + "models": { + "additionalProperties": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": "object", + "title": "Models" + } + }, + "type": "object", + "required": [ + "models" + ], + "title": "VerifiedModelsResponse", + "description": "Response containing verified models organized by provider." + }, "WriteFileAction": { "properties": { "file_path": { @@ -12526,6 +14787,16 @@ } ], "title": "Meta" + }, + "execution": { + "anyOf": [ + { + "$ref": "#/components/schemas/ToolExecution" + }, + { + "type": "null" + } + ] } }, "additionalProperties": true, @@ -12674,6 +14945,13 @@ "title": "openhands.sdk.tool.tool.ToolAnnotations", "description": "Annotations to provide hints about the tool's behavior.\n\nBased on Model Context Protocol (MCP) spec:\nhttps://github.com/modelcontextprotocol/modelcontextprotocol/blob/caf3424488b10b4a7b1f8cb634244a450a1f4400/schema/2025-06-18/schema.ts#L838" } + }, + "securitySchemes": { + "APIKeyHeader": { + "type": "apiKey", + "in": "header", + "name": "X-Session-API-Key" + } } } } \ No newline at end of file