{"openapi":"3.1.0","info":{"title":"OpenHands Agent Server","description":"OpenHands Agent Server - REST/WebSocket interface for OpenHands AI Agent","version":"1.54.0"},"paths":{"/alive":{"get":{"tags":["Server Details"],"summary":"Alive","description":"Basic liveness check - returns OK if the server process is running.","operationId":"alive_alive_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatus"}}}}}}},"/health":{"get":{"tags":["Server Details"],"summary":"Health","description":"Basic health check - returns OK if the server process is running.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatus"}}}}}}},"/ready":{"get":{"tags":["Server Details"],"summary":"Ready","description":"Readiness check - returns OK only if the server has completed initialization.\n\nThis endpoint should be used by Kubernetes readiness probes to determine\nwhen the pod is ready to receive traffic. Returns 503 during initialization.","operationId":"ready_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"string"},"type":"object","title":"Response Ready Ready Get"}}}}}}},"/server_info":{"get":{"tags":["Server Details"],"summary":"Get Server Info","operationId":"get_server_info_server_info_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerInfo"}}}}}}},"/api/init":{"get":{"tags":["Init"],"summary":"Get Init Status","description":"Report the current init state.\n\nAuthentication is intentionally not required on this endpoint so a warm\npool controller can poll it without holding the init key. The payload\ncontains no sensitive data.","operationId":"get_init_status_api_init_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitStatus"}}}}}},"post":{"tags":["Init"],"summary":"Initialize Server","description":"Initialize a dormant server with runtime configuration.\n\nReturns 400 if the server has already been initialized (state != dormant).\nReturns 500 if initialization fails; in that case the state rolls back to\n``dormant`` so the orchestrator can retry.","operationId":"initialize_server_api_init_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/models":{"get":{"tags":["OpenAI Compatibility"],"summary":"Get Openai Models","operationId":"get_openai_models_v1_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIModelListResponse"}}}}},"security":[{"APIKeyHeader":[]},{"HTTPBearer":[]}]}},"/v1/chat/completions":{"post":{"tags":["OpenAI Compatibility"],"summary":"Create Chat Completion","operationId":"create_chat_completion_v1_chat_completions_post","security":[{"APIKeyHeader":[]},{"HTTPBearer":[]}],"parameters":[{"name":"X-OpenHands-ServerConversation-ID","in":"header","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"X-Openhands-Serverconversation-Id"}},{"name":"X-OpenHands-Observability-Span-Name","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Span-Name"}},{"name":"X-OpenHands-Observability-Tags","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Tags"}},{"name":"X-OpenHands-Observability-Metadata","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Metadata"}},{"name":"X-OpenHands-Observability-Parent-Span-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Parent-Span-Context"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIChatCompletionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletion"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/responses":{"post":{"tags":["OpenAI Compatibility"],"summary":"Create Response","operationId":"create_response_v1_responses_post","security":[{"APIKeyHeader":[]},{"HTTPBearer":[]}],"parameters":[{"name":"X-OpenHands-Observability-Span-Name","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Span-Name"}},{"name":"X-OpenHands-Observability-Tags","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Tags"}},{"name":"X-OpenHands-Observability-Metadata","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Metadata"}},{"name":"X-OpenHands-Observability-Parent-Span-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Parent-Span-Context"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIResponseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenAIResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/workspace":{"get":{"tags":["Workspace"],"summary":"Serve Workspace Root","description":"Serve ``index.html`` from the conversation's workspace root.","operationId":"serve_workspace_root_api_conversations__conversation_id__workspace_get","security":[{"APIKeyHeader":[]},{"APIKeyCookie":[]}],"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":{}}}},"404":{"description":"File or conversation not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/workspace/{file_path}":{"get":{"tags":["Workspace"],"summary":"Serve Workspace File","description":"Serve a file (or directory ``index.html``) from the workspace.","operationId":"serve_workspace_file_api_conversations__conversation_id__workspace__file_path__get","security":[{"APIKeyHeader":[]},{"APIKeyCookie":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}},{"name":"file_path","in":"path","required":true,"schema":{"type":"string","title":"File Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"File or conversation not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/file/home":{"get":{"tags":["Files"],"summary":"Get Home Directory","description":"Return the agent-server user's home directory and dynamic sidebar lists.\n\n``favorites`` is the set of top-level directories actually present in the\nuser's home (so it reflects the real environment instead of a hardcoded\nlist of names that may not exist). Hidden directories are included only\nwhen ``include_hidden`` is True. ``locations`` is the set of filesystem\nroots — '/' on POSIX or available drive letters on Windows.","operationId":"get_home_directory_api_file_home_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"include_hidden","in":"query","required":false,"schema":{"type":"boolean","description":"Include hidden top-level directories in `favorites`","default":false,"title":"Include Hidden"},"description":"Include hidden top-level directories in `favorites`"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HomeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/file/search_subdirs":{"get":{"tags":["Files"],"summary":"Search Subdirs","description":"Search / List immediate subdirectories of `path`.\n\nUsed by the GUI's workspace picker. Symlinks and files are skipped. Hidden\nentries (names starting with '.') are skipped unless ``include_hidden`` is\nTrue. Returns absolute paths so the GUI can use a result directly as\n``workspace.working_dir``.\n\nResults are sorted case-insensitively by name and paginated. ``page_id`` is\nthe ``next_page_id`` returned by the previous page (the lowercase name of\nthe first item to include on the next page).","operationId":"search_subdirs_api_file_search_subdirs_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Absolute directory path to list subdirectories of","title":"Path"},"description":"Absolute directory path to list subdirectories of"},{"name":"page_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional next_page_id from the previously returned page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"exclusiveMinimum":0,"title":"The max number of results in the page","default":100}},{"name":"include_hidden","in":"query","required":false,"schema":{"type":"boolean","title":"Include hidden subdirectories (names starting with '.')","default":false}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubdirectoryPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/bash/bash_events/search":{"get":{"tags":["Bash"],"summary":"Search Bash Events","description":"Search / List bash event events","operationId":"search_bash_events_api_conversations__runtime_conversation_id__bash_bash_events_search_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"kind__eq","in":"query","required":false,"schema":{"anyOf":[{"enum":["BashCommand","BashOutput"],"type":"string"},{"type":"null"}],"title":"Kind  Eq"}},{"name":"command_id__eq","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Command Id  Eq"}},{"name":"timestamp__gte","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Timestamp  Gte"}},{"name":"timestamp__lt","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Timestamp  Lt"}},{"name":"order__gt","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Filter to events with order greater than this value","description":"Only returns BashOutput events with order > this value. Useful for polling to fetch only new events since the last poll."},"description":"Only returns BashOutput events with order > this value. Useful for polling to fetch only new events since the last poll."},{"name":"sort_order","in":"query","required":false,"schema":{"$ref":"#/components/schemas/BashEventSortOrder","default":"TIMESTAMP"}},{"name":"page_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional next_page_id from the previously returned page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"exclusiveMinimum":0,"title":"The max number of results in the page","default":100}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BashEventPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/bash/bash_events/{event_id}":{"get":{"tags":["Bash"],"summary":"Get Bash Event","description":"Get a bash event event given an id","operationId":"get_bash_event_api_conversations__runtime_conversation_id__bash_bash_events__event_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","title":"Event Id"}},{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BashEventBase"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/bash/bash_events/":{"get":{"tags":["Bash"],"summary":"Batch Get Bash Events","description":"Get a batch of bash event events given their ids, returning null for any\nmissing item.","operationId":"batch_get_bash_events_api_conversations__runtime_conversation_id__bash_bash_events__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Event Ids"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/BashEventBase"},{"type":"null"}]},"title":"Response Batch Get Bash Events Api Conversations  Runtime Conversation Id  Bash Bash Events  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/bash/start_bash_command":{"post":{"tags":["Bash"],"summary":"Start Bash Command","description":"Execute a bash command in the background","operationId":"start_bash_command_api_conversations__runtime_conversation_id__bash_start_bash_command_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteBashRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BashCommand"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/bash/execute_bash_command":{"post":{"tags":["Bash"],"summary":"Execute Bash Command","description":"Execute a bash command and wait for a result","operationId":"execute_bash_command_api_conversations__runtime_conversation_id__bash_execute_bash_command_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteBashRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BashOutput"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/bash/bash_events":{"delete":{"tags":["Bash"],"summary":"Clear All Bash Events","description":"Clear all bash events from storage","operationId":"clear_all_bash_events_api_conversations__runtime_conversation_id__bash_bash_events_delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"integer"},"title":"Response Clear All Bash Events Api Conversations  Runtime Conversation Id  Bash Bash Events Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/bash/bash_commands/{command_id}/stop":{"post":{"tags":["Bash"],"summary":"Stop Bash Command","description":"Stop a running bash command by id without touching the others.\n\nIdempotent: stopping an already-finished command succeeds, while an\nunknown command id reports not-found so the caller can treat it as\nan already-cancelled stop.","operationId":"stop_bash_command_api_conversations__runtime_conversation_id__bash_bash_commands__command_id__stop_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"command_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Command Id"}},{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/file/upload":{"post":{"tags":["Files"],"summary":"Upload File Query","description":"Upload a file to the workspace using query parameter (preferred method).","operationId":"upload_file_query_api_conversations__runtime_conversation_id__file_upload_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","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_conversations__runtime_conversation_id__file_upload_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/file/download":{"get":{"tags":["Files"],"summary":"Download File Query","description":"Download a file from the workspace using query parameter (preferred method).","operationId":"download_file_query_api_conversations__runtime_conversation_id__file_download_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Absolute file path","title":"Path"},"description":"Absolute file path"}],"responses":{"200":{"description":"Successful Response","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/file/create_directory":{"post":{"tags":["Files"],"summary":"Create Directory","description":"Create a directory in the workspace, including any missing parents.\n\nIdempotent: an existing directory succeeds and its contents are left\nuntouched. Creating over an existing file, or under a path whose parent is\na file, is a client error (400) rather than a server fault.","operationId":"create_directory_api_conversations__runtime_conversation_id__file_create_directory_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Absolute directory path to create","title":"Path"},"description":"Absolute directory path to create"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/file/download-trajectory/{conversation_id}":{"get":{"tags":["Files"],"summary":"Download Trajectory","description":"Download a zip archive of a conversation trajectory.","operationId":"download_trajectory_api_conversations__runtime_conversation_id__file_download_trajectory__conversation_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}},{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/file/archive":{"get":{"tags":["Files"],"summary":"Archive Directory","description":"Archive a workspace directory for persistence before runtime deletion.\n\nProduces a downloadable archive of ``path``. Symlinks are never followed\nout of the requested directory, so the archive cannot include files from\noutside it. The temporary archive is created outside ``path`` and removed\nafter the response is sent.","operationId":"archive_directory_api_conversations__runtime_conversation_id__file_archive_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Absolute path of the directory to archive","title":"Path"},"description":"Absolute path of the directory to archive"},{"name":"format","in":"query","required":false,"schema":{"enum":["git-delta","tar.gz"],"type":"string","description":"Archive format: 'git-delta' for a git patch of the working-tree changes against a base ref (requires a git repository); 'tar.gz' for a full gzip tarball of the entire directory (works on non-git directories too).","default":"git-delta","title":"Format"},"description":"Archive format: 'git-delta' for a git patch of the working-tree changes against a base ref (requires a git repository); 'tar.gz' for a full gzip tarball of the entire directory (works on non-git directories too)."},{"name":"base_ref","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only for format='git-delta': base ref to diff against. Defaults to the auto-detected comparison ref (origin branch, merge-base, or the empty tree for a fresh repo). Ignored for format='tar.gz'.","title":"Base Ref"},"description":"Only for format='git-delta': base ref to diff against. Defaults to the auto-detected comparison ref (origin branch, merge-base, or the empty tree for a fresh repo). Ignored for format='tar.gz'."},{"name":"use_default_excludes","in":"query","required":false,"schema":{"type":"boolean","description":"Whether to apply the built-in default exclude patterns (node_modules/, .venv/, caches, build outputs, etc.). Defaults to true for compact archives; set false to allow a full workspace capture, including fat directories.","default":true,"title":"Use Default Excludes"},"description":"Whether to apply the built-in default exclude patterns (node_modules/, .venv/, caches, build outputs, etc.). Defaults to true for compact archives; set false to allow a full workspace capture, including fat directories."},{"name":"exclude","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Additional glob patterns to exclude (repeatable, e.g. ?exclude=foo&exclude=*.bin). Combined with the built-in default excludes when use_default_excludes=true; used by itself when use_default_excludes=false.","title":"Exclude"},"description":"Additional glob patterns to exclude (repeatable, e.g. ?exclude=foo&exclude=*.bin). Combined with the built-in default excludes when use_default_excludes=true; used by itself when use_default_excludes=false."}],"responses":{"200":{"description":"Successful Response","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/git/changes":{"get":{"tags":["Git"],"summary":"Git Changes Query","description":"Get git changes using query parameter (preferred method).","operationId":"git_changes_query_api_conversations__runtime_conversation_id__git_changes_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"The git repository path","title":"Path"},"description":"The git repository path"},{"name":"ref","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional git ref to diff against (e.g. 'HEAD' for git status-style changes, or a commit hash). When omitted, the upstream/default branch is auto-detected.","title":"Ref"},"description":"Optional git ref to diff against (e.g. 'HEAD' for git status-style changes, or a commit hash). When omitted, the upstream/default branch is auto-detected."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GitChange"},"title":"Response Git Changes Query Api Conversations  Runtime Conversation Id  Git Changes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/git/diff":{"get":{"tags":["Git"],"summary":"Git Diff Query","description":"Get git diff using query parameter (preferred method).","operationId":"git_diff_query_api_conversations__runtime_conversation_id__git_diff_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"The file path to get diff for","title":"Path"},"description":"The file path to get diff for"},{"name":"ref","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional git ref to diff against (e.g. 'HEAD' for git status-style changes, or a commit hash). When omitted, the upstream/default branch is auto-detected.","title":"Ref"},"description":"Optional git ref to diff against (e.g. 'HEAD' for git status-style changes, or a commit hash). When omitted, the upstream/default branch is auto-detected."},{"name":"commit","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[0-9a-fA-F]{4,64}$"},{"type":"null"}],"description":"Optional commit SHA. When set, the diff is the change that commit introduced (vs its first parent), read entirely from git objects so deleted files still render. Mutually exclusive with 'ref'.","title":"Commit"},"description":"Optional commit SHA. When set, the diff is the change that commit introduced (vs its first parent), read entirely from git objects so deleted files still render. Mutually exclusive with 'ref'."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitDiff"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/git/commits":{"get":{"tags":["Git"],"summary":"Git Commits Query","description":"List the repository's most recent commits, newest first.","operationId":"git_commits_query_api_conversations__runtime_conversation_id__git_commits_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"The git repository path","title":"Path"},"description":"The git repository path"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Maximum commits to return","default":50,"title":"Limit"},"description":"Maximum commits to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitCommitsPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/git/commits/{sha}/changes":{"get":{"tags":["Git"],"summary":"Git Commit Changes Query","description":"Get the files changed by a single commit (vs its first parent).","operationId":"git_commit_changes_query_api_conversations__runtime_conversation_id__git_commits__sha__changes_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"sha","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9a-fA-F]{4,64}$","description":"Commit SHA","title":"Sha"},"description":"Commit SHA"},{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"The git repository path","title":"Path"},"description":"The git repository path"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GitChange"},"title":"Response Git Commit Changes Query Api Conversations  Runtime Conversation Id  Git Commits  Sha  Changes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/vscode/url":{"get":{"summary":"Get Runtime Vscode Url","operationId":"get_runtime_vscode_url_api_conversations__runtime_conversation_id__vscode_url_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}},{"name":"base_url","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url"}},{"name":"workspace_dir","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"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"}}}}}}},"<redacted:session-cookie>/{runtime_conversation_id}/vscode/status":{"get":{"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_conversations__runtime_conversation_id__vscode_status_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"runtime_conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Runtime Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"anyOf":[{"type":"boolean"},{"type":"string"}]},"title":"Response Get Vscode Status Api Conversations  Runtime Conversation Id  Vscode Status Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/events/search":{"get":{"tags":["Events"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}},{"name":"page_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional next_page_id from the previously returned page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"exclusiveMinimum":0,"title":"The max number of results in the page","default":100}},{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional filter by event kind/type (e.g., ActionEvent, MessageEvent)"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional filter by event source (e.g., agent, user, environment)"}},{"name":"body","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional filter by message content (case-insensitive)"}},{"name":"sort_order","in":"query","required":false,"schema":{"$ref":"#/components/schemas/EventSortOrder","title":"Sort order for events","default":"TIMESTAMP"}},{"name":"timestamp__gte","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Filter: event timestamp >= this datetime"}},{"name":"timestamp__lt","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Filter: event timestamp < this datetime"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Conversation not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/events/count":{"get":{"tags":["Events"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}},{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional filter by event kind/type (e.g., ActionEvent, MessageEvent)"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional filter by event source (e.g., agent, user, environment)"}},{"name":"body","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional filter by message content (case-insensitive)"}},{"name":"timestamp__gte","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Filter: event timestamp >= this datetime"}},{"name":"timestamp__lt","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Filter: event timestamp < this datetime"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"integer","title":"Response Count Conversation Events Api Conversations  Conversation Id  Events Count Get"}}}},"404":{"description":"Conversation not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/events/{event_id}":{"get":{"tags":["Events"],"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","in":"path","required":true,"schema":{"type":"string","title":"Event Id"}},{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/events":{"get":{"tags":["Events"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Event Ids"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/Event"},{"type":"null"}]},"title":"Response Batch Get Conversation Events Api Conversations  Conversation Id  Events Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Events"],"summary":"Send Message","description":"Send a message to a conversation.\n\nIf starting the run returns 429, the message is already saved. Retry the\nconversation's /run endpoint instead of resending the message.","operationId":"send_message_api_conversations__conversation_id__events_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"429":{"description":"Message saved but server run capacity is full"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/events/respond_to_confirmation":{"post":{"tags":["Events"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmationResponseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"429":{"description":"Server conversation run capacity is full"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/search":{"get":{"tags":["Conversations"],"summary":"Search Conversations","description":"Search / List conversations","operationId":"search_conversations_api_conversations_search_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional next_page_id from the previously returned page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"exclusiveMinimum":0,"title":"The max number of results in the page","default":100}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ConversationExecutionStatus"},{"type":"null"}],"title":"Optional filter by conversation execution status"}},{"name":"sort_order","in":"query","required":false,"schema":{"$ref":"#/components/schemas/ConversationSortOrder","title":"Sort order for conversations","default":"CREATED_AT_DESC"}},{"name":"include_skills","in":"query","required":false,"schema":{"type":"boolean","title":"Whether to include ``agent.agent_context.skills`` in the response. Default ``false`` (breaking change as of this release): skills are trimmed to ``[]`` on the wire because no known consumer reads them from HTTP responses, and a stock agent inlines ~260 KB of skill content per fetch. Pass ``true`` to opt back into the legacy full-payload shape — useful only for callers that still rely on ``RemoteConversation.agent.agent_context.skills`` round-tripping over the wire. The persisted conversation state on disk and the in-memory runtime copy are untouched either way.","default":false}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/count":{"get":{"tags":["Conversations"],"summary":"Count Conversations","description":"Count conversations matching the given filters","operationId":"count_conversations_api_conversations_count_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/ConversationExecutionStatus"},{"type":"null"}],"title":"Optional filter by conversation execution status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"integer","title":"Response Count Conversations Api Conversations Count Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}":{"get":{"tags":["Conversations"],"summary":"Get Conversation","description":"Given an id, get a conversation","operationId":"get_conversation_api_conversations__conversation_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}},{"name":"include_skills","in":"query","required":false,"schema":{"type":"boolean","title":"Whether to include ``agent.agent_context.skills`` in the response. Default ``false`` (breaking change as of this release): skills are trimmed to ``[]`` on the wire because no known consumer reads them from HTTP responses, and a stock agent inlines ~260 KB of skill content per fetch. Pass ``true`` to opt back into the legacy full-payload shape — useful only for callers that still rely on ``RemoteConversation.agent.agent_context.skills`` round-tripping over the wire. The persisted conversation state on disk and the in-memory runtime copy are untouched either way.","default":false}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationInfo"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Conversations"],"summary":"Delete Conversation","description":"Permanently delete a conversation.","operationId":"delete_conversation_api_conversations__conversation_id__delete","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":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Conversations"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConversationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/runtime":{"get":{"tags":["Conversations"],"summary":"Get Local Conversation Runtime","description":"Inspect the always-available in-process runtime.","operationId":"get_local_conversation_runtime_api_conversations__conversation_id__runtime_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":{"$ref":"#/components/schemas/ConversationRuntimeInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/runtime/reprovision":{"post":{"tags":["Conversations"],"summary":"Reprovision Local Conversation Runtime","description":"Return local runtime state; local mode has no infrastructure to provision.","operationId":"reprovision_local_conversation_runtime_api_conversations__conversation_id__runtime_reprovision_post","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":{"$ref":"#/components/schemas/ConversationRuntimeInfo"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/agent_final_response":{"get":{"tags":["Conversations"],"summary":"Get Conversation Agent Final Response","description":"Get the agent's final response for a conversation.\n\nReturns the text of the last agent finish message (FinishAction) or\nthe last agent text response (MessageEvent). Returns an empty string\nif the agent has not produced a final response yet.","operationId":"get_conversation_agent_final_response_api_conversations__conversation_id__agent_final_response_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":{"$ref":"#/components/schemas/AgentResponseResult"}}}},"404":{"description":"Conversation not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>":{"get":{"tags":["Conversations"],"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","in":"query","required":true,"schema":{"type":"array","items":{"type":"string","format":"uuid"},"title":"Ids"}},{"name":"include_skills","in":"query","required":false,"schema":{"type":"boolean","title":"Whether to include ``agent.agent_context.skills`` in the response. Default ``false`` (breaking change as of this release): skills are trimmed to ``[]`` on the wire because no known consumer reads them from HTTP responses, and a stock agent inlines ~260 KB of skill content per fetch. Pass ``true`` to opt back into the legacy full-payload shape — useful only for callers that still rely on ``RemoteConversation.agent.agent_context.skills`` round-tripping over the wire. The persisted conversation state on disk and the in-memory runtime copy are untouched either way.","default":false}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/ConversationInfo"},{"type":"null"}]},"title":"Response Batch Get Conversations Api Conversations Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Conversations"],"summary":"Start Conversation","description":"Start a conversation in the local environment.","operationId":"start_conversation_api_conversations_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"include_skills","in":"query","required":false,"schema":{"type":"boolean","title":"Whether to include ``agent.agent_context.skills`` in the response. Default ``false`` (breaking change as of this release): skills are trimmed to ``[]`` on the wire because no known consumer reads them from HTTP responses, and a stock agent inlines ~260 KB of skill content per fetch. Pass ``true`` to opt back into the legacy full-payload shape — useful only for callers that still rely on ``RemoteConversation.agent.agent_context.skills`` round-tripping over the wire. The persisted conversation state on disk and the in-memory runtime copy are untouched either way.","default":false}},{"name":"X-OpenHands-Observability-Span-Name","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Span-Name"}},{"name":"X-OpenHands-Observability-Tags","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Tags"}},{"name":"X-OpenHands-Observability-Metadata","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Metadata"}},{"name":"X-OpenHands-Observability-Parent-Span-Context","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Openhands-Observability-Parent-Span-Context"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartConversationRequest","examples":[{"agent_settings":{"llm":{"usage_id":"your-llm-service","model":"your-model-provider/your-model-name","api_key":"<redacted:api_key>"}},"workspace":{"working_dir":"workspace/project"},"initial_message":{"role":"user","content":[{"type":"text","text":"Flip a coin!"}]}}]}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationInfo"}}}},"429":{"description":"Server conversation run capacity is full"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/pause":{"post":{"tags":["Conversations"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/interrupt":{"post":{"tags":["Conversations"],"summary":"Interrupt Conversation","description":"Immediately interrupt a running conversation.\n\nUnlike ``/pause``, which waits for the current LLM call to finish,\n``/interrupt`` cancels the in-flight request so the effect is instant.\nThe conversation transitions to *paused* and can be resumed later.","operationId":"interrupt_conversation_api_conversations__conversation_id__interrupt_post","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":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/run":{"post":{"tags":["Conversations"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"409":{"description":"Conversation is already running"},"429":{"description":"Server conversation run capacity is full"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/goal":{"post":{"tags":["Conversations"],"summary":"Start Goal In Conversation","description":"Start a ``/goal`` loop inside an existing conversation.\n\nThe loop appends messages and starts agent runs in the same conversation\nhistory and event stream as the main chat. It does not create a separate\nconversation for the goal or fork the existing one.","operationId":"start_goal_in_conversation_api_conversations__conversation_id__goal_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartGoalRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"409":{"description":"Conversation run or goal loop is already running"},"429":{"description":"Server conversation run capacity is full"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/goal/stop":{"post":{"tags":["Conversations"],"summary":"Stop Goal In Conversation","description":"Stop the active ``/goal`` loop inside this conversation.\n\nThis cancels only the background goal loop, not the conversation itself, and\nrecords an ``interrupted`` goal status so ``/goal/resume`` can continue it.","operationId":"stop_goal_in_conversation_api_conversations__conversation_id__goal_stop_post","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":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/goal/resume":{"post":{"tags":["Conversations"],"summary":"Resume Goal In Conversation","description":"Resume the last interrupted ``/goal`` loop inside this conversation.","operationId":"resume_goal_in_conversation_api_conversations__conversation_id__goal_resume_post","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":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"409":{"description":"Conversation run or goal loop is already running"},"429":{"description":"Server conversation run capacity is full"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/secrets":{"post":{"tags":["Conversations"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSecretsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/confirmation_policy":{"post":{"tags":["Conversations"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetConfirmationPolicyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/security_analyzer":{"post":{"tags":["Conversations"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetSecurityAnalyzerRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/switch_profile":{"post":{"tags":["Conversations"],"summary":"Switch Conversation Profile","description":"Switch the conversation's LLM profile to a named profile.","operationId":"switch_conversation_profile_api_conversations__conversation_id__switch_profile_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_switch_conversation_profile_api_conversations__conversation_id__switch_profile_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"description":"Invalid or corrupted profile"},"404":{"description":"Conversation or profile not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/switch_llm":{"post":{"tags":["Conversations"],"summary":"Switch Conversation Llm","description":"Swap the conversation's LLM to a caller-supplied object.\n\nUsed by app-servers that own the LLM directly and don't push profiles\nto the agent-server's filesystem (see #3017), and by the frontend's\nper-conversation model switch, which forwards a profile config that may\nreference a saved provider connection by id instead of carrying an inline\nAPI key.","operationId":"switch_conversation_llm_api_conversations__conversation_id__switch_llm_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_switch_conversation_llm_api_conversations__conversation_id__switch_llm_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Conversation not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/load_plugin":{"post":{"tags":["Conversations"],"summary":"Load Conversation Plugin","description":"Load a plugin from the conversation's registered marketplaces.","operationId":"load_conversation_plugin_api_conversations__conversation_id__load_plugin_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_load_conversation_plugin_api_conversations__conversation_id__load_plugin_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"description":"Invalid plugin reference or inactive conversation"},"404":{"description":"Conversation or plugin not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/switch_acp_model":{"post":{"tags":["Conversations"],"summary":"Switch Conversation Acp Model","description":"Switch the model of an ACP conversation.\n\nFor a conversation that has already started, issues a protocol-level\n``session/set_model`` call to the ACP subprocess so the new model applies to\nsubsequent turns without losing context. For one created but not yet run,\nthe value is persisted and applied when the first session starts (returns\n``200`` either way). Only valid for ACP conversations whose provider\nsupports model switching.","operationId":"switch_conversation_acp_model_api_conversations__conversation_id__switch_acp_model_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_switch_conversation_acp_model_api_conversations__conversation_id__switch_acp_model_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"description":"Agent is not ACP, or provider can't switch models"},"404":{"description":"Conversation not found"},"504":{"description":"ACP server did not answer the model switch in time"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/ask_agent":{"post":{"tags":["Conversations"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskAgentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AskAgentResponse"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/condense":{"post":{"tags":["Conversations"],"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","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/fork":{"post":{"tags":["Conversations"],"summary":"Fork Conversation","description":"Fork a conversation, deep-copying its event history.\n\nThe fork starts in ``idle`` status with a fresh event loop.\nCalling ``run`` on the fork resumes from the copied state, meaning\nthe agent has full event memory of the source conversation.","operationId":"fork_conversation_api_conversations__conversation_id__fork_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}},{"name":"include_skills","in":"query","required":false,"schema":{"type":"boolean","title":"Whether to include ``agent.agent_context.skills`` in the response. Default ``false`` (breaking change as of this release): skills are trimmed to ``[]`` on the wire because no known consumer reads them from HTTP responses, and a stock agent inlines ~260 KB of skill content per fetch. Pass ``true`` to opt back into the legacy full-payload shape — useful only for callers that still rely on ``RemoteConversation.agent.agent_context.skills`` round-tripping over the wire. The persisted conversation state on disk and the in-memory runtime copy are untouched either way.","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForkConversationRequest","default":{"reset_metrics":true}}}}},"responses":{"201":{"description":"Forked conversation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationInfo"}}}},"404":{"description":"Source conversation not found"},"409":{"description":"Fork ID already in use"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"<redacted:session-cookie>/{conversation_id}/navigate":{"post":{"tags":["Conversations"],"summary":"Navigate Conversation","description":"Move a conversation's HEAD to an existing event, re-rooting the branch.\n\nAll branches stay on disk; only the active branch the agent runs on next\nchanges. Unlike ``fork``, no new conversation is created. Returns the\nupdated conversation info (carrying the new ``leaf_event_id``).","operationId":"navigate_conversation_api_conversations__conversation_id__navigate_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Conversation Id"}},{"name":"include_skills","in":"query","required":false,"schema":{"type":"boolean","title":"Whether to include ``agent.agent_context.skills`` in the response. Default ``false`` (breaking change as of this release): skills are trimmed to ``[]`` on the wire because no known consumer reads them from HTTP responses, and a stock agent inlines ~260 KB of skill content per fetch. Pass ``true`` to opt back into the legacy full-payload shape — useful only for callers that still rely on ``RemoteConversation.agent.agent_context.skills`` round-tripping over the wire. The persisted conversation state on disk and the in-memory runtime copy are untouched either way.","default":false}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NavigateConversationRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationInfo"}}}},"404":{"description":"Conversation or event not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/":{"get":{"tags":["Tools"],"summary":"List Available Tools","description":"List all available tools.","operationId":"list_available_tools_api_tools__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Response List Available Tools Api Tools  Get"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/tools/catalog":{"get":{"tags":["Tools"],"summary":"Get Tool Catalog","description":"List the tools this server offers for configuring an agent.\n\nClients offer the ``user_selectable`` entries; ``usable`` says whether the\nruntime conversations run in can run the tool.","operationId":"get_tool_catalog_api_tools_catalog_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToolCatalogResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/bash/bash_events/search":{"get":{"tags":["Bash"],"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","in":"query","required":false,"schema":{"anyOf":[{"enum":["BashCommand","BashOutput"],"type":"string"},{"type":"null"}],"title":"Kind  Eq"}},{"name":"command_id__eq","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Command Id  Eq"}},{"name":"timestamp__gte","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Timestamp  Gte"}},{"name":"timestamp__lt","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Timestamp  Lt"}},{"name":"order__gt","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Filter to events with order greater than this value","description":"Only returns BashOutput events with order > this value. Useful for polling to fetch only new events since the last poll."},"description":"Only returns BashOutput events with order > this value. Useful for polling to fetch only new events since the last poll."},{"name":"sort_order","in":"query","required":false,"schema":{"$ref":"#/components/schemas/BashEventSortOrder","default":"TIMESTAMP"}},{"name":"page_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Optional next_page_id from the previously returned page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"exclusiveMinimum":0,"title":"The max number of results in the page","default":100}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BashEventPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bash/bash_events/{event_id}":{"get":{"tags":["Bash"],"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","in":"path","required":true,"schema":{"type":"string","title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BashEventBase"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bash/bash_events/":{"get":{"tags":["Bash"],"summary":"Batch Get Bash Events","description":"Get a batch of bash event events given their ids, returning null for any\nmissing item.","operationId":"batch_get_bash_events_api_bash_bash_events__get","requestBody":{"content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Event Ids"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"anyOf":[{"$ref":"#/components/schemas/BashEventBase"},{"type":"null"}]},"type":"array","title":"Response Batch Get Bash Events Api Bash Bash Events  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/bash/start_bash_command":{"post":{"tags":["Bash"],"summary":"Start Bash Command","description":"Execute a bash command in the background","operationId":"start_bash_command_api_bash_start_bash_command_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteBashRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BashCommand"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/bash/execute_bash_command":{"post":{"tags":["Bash"],"summary":"Execute Bash Command","description":"Execute a bash command and wait for a result","operationId":"execute_bash_command_api_bash_execute_bash_command_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteBashRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BashOutput"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/bash/bash_events":{"delete":{"tags":["Bash"],"summary":"Clear All Bash Events","description":"Clear all bash events from storage","operationId":"clear_all_bash_events_api_bash_bash_events_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"type":"integer"},"type":"object","title":"Response Clear All Bash Events Api Bash Bash Events Delete"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/bash/bash_commands/{command_id}/stop":{"post":{"tags":["Bash"],"summary":"Stop Bash Command","description":"Stop a running bash command by id without touching the others.\n\nIdempotent: stopping an already-finished command succeeds, while an\nunknown command id reports not-found so the caller can treat it as\nan already-cancelled stop.","operationId":"stop_bash_command_api_bash_bash_commands__command_id__stop_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"command_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Command Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Item not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/git/repositories/search":{"get":{"tags":["Git"],"summary":"Git Repositories Search","description":"List repositories accessible to a configured git provider token.","operationId":"git_repositories_search_api_git_repositories_search_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"provider","in":"query","required":true,"schema":{"$ref":"#/components/schemas/GitProvider","description":"Git provider to search"},"description":"Git provider to search"},{"name":"query","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional repository name filter","title":"Query"},"description":"Optional repository name filter"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Maximum repositories to return","default":100,"title":"Limit"},"description":"Maximum repositories to return"},{"name":"page_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Provider-specific page cursor","title":"Page Id"},"description":"Provider-specific page cursor"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitProviderRepositoryPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/git/changes":{"get":{"tags":["Git"],"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":"query","required":true,"schema":{"type":"string","description":"The git repository path","title":"Path"},"description":"The git repository path"},{"name":"ref","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional git ref to diff against (e.g. 'HEAD' for git status-style changes, or a commit hash). When omitted, the upstream/default branch is auto-detected.","title":"Ref"},"description":"Optional git ref to diff against (e.g. 'HEAD' for git status-style changes, or a commit hash). When omitted, the upstream/default branch is auto-detected."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GitChange"},"title":"Response Git Changes Query Api Git Changes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/git/diff":{"get":{"tags":["Git"],"summary":"Git Diff Query","description":"Get git diff using query parameter (preferred method).","operationId":"git_diff_query_api_git_diff_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"The file path to get diff for","title":"Path"},"description":"The file path to get diff for"},{"name":"ref","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional git ref to diff against (e.g. 'HEAD' for git status-style changes, or a commit hash). When omitted, the upstream/default branch is auto-detected.","title":"Ref"},"description":"Optional git ref to diff against (e.g. 'HEAD' for git status-style changes, or a commit hash). When omitted, the upstream/default branch is auto-detected."},{"name":"commit","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[0-9a-fA-F]{4,64}$"},{"type":"null"}],"description":"Optional commit SHA. When set, the diff is the change that commit introduced (vs its first parent), read entirely from git objects so deleted files still render. Mutually exclusive with 'ref'.","title":"Commit"},"description":"Optional commit SHA. When set, the diff is the change that commit introduced (vs its first parent), read entirely from git objects so deleted files still render. Mutually exclusive with 'ref'."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitDiff"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/git/commits":{"get":{"tags":["Git"],"summary":"Git Commits Query","description":"List the repository's most recent commits, newest first.","operationId":"git_commits_query_api_git_commits_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"The git repository path","title":"Path"},"description":"The git repository path"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Maximum commits to return","default":50,"title":"Limit"},"description":"Maximum commits to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitCommitsPage"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/git/commits/{sha}/changes":{"get":{"tags":["Git"],"summary":"Git Commit Changes Query","description":"Get the files changed by a single commit (vs its first parent).","operationId":"git_commit_changes_query_api_git_commits__sha__changes_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"sha","in":"path","required":true,"schema":{"type":"string","pattern":"^[0-9a-fA-F]{4,64}$","description":"Commit SHA","title":"Sha"},"description":"Commit SHA"},{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"The git repository path","title":"Path"},"description":"The git repository path"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GitChange"},"title":"Response Git Commit Changes Query Api Git Commits  Sha  Changes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/file/upload":{"post":{"tags":["Files"],"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":"path","in":"query","required":true,"schema":{"type":"string","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":{"$ref":"#/components/schemas/Success"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/file/download":{"get":{"tags":["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"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/file/create_directory":{"post":{"tags":["Files"],"summary":"Create Directory","description":"Create a directory in the workspace, including any missing parents.\n\nIdempotent: an existing directory succeeds and its contents are left\nuntouched. Creating over an existing file, or under a path whose parent is\na file, is a client error (400) rather than a server fault.","operationId":"create_directory_api_file_create_directory_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Absolute directory path to create","title":"Path"},"description":"Absolute directory path to create"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"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 zip archive of a conversation trajectory.","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":{}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/file/archive":{"get":{"tags":["Files"],"summary":"Archive Directory","description":"Archive a workspace directory for persistence before runtime deletion.\n\nProduces a downloadable archive of ``path``. Symlinks are never followed\nout of the requested directory, so the archive cannot include files from\noutside it. The temporary archive is created outside ``path`` and removed\nafter the response is sent.","operationId":"archive_directory_api_file_archive_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Absolute path of the directory to archive","title":"Path"},"description":"Absolute path of the directory to archive"},{"name":"format","in":"query","required":false,"schema":{"enum":["git-delta","tar.gz"],"type":"string","description":"Archive format: 'git-delta' for a git patch of the working-tree changes against a base ref (requires a git repository); 'tar.gz' for a full gzip tarball of the entire directory (works on non-git directories too).","default":"git-delta","title":"Format"},"description":"Archive format: 'git-delta' for a git patch of the working-tree changes against a base ref (requires a git repository); 'tar.gz' for a full gzip tarball of the entire directory (works on non-git directories too)."},{"name":"base_ref","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Only for format='git-delta': base ref to diff against. Defaults to the auto-detected comparison ref (origin branch, merge-base, or the empty tree for a fresh repo). Ignored for format='tar.gz'.","title":"Base Ref"},"description":"Only for format='git-delta': base ref to diff against. Defaults to the auto-detected comparison ref (origin branch, merge-base, or the empty tree for a fresh repo). Ignored for format='tar.gz'."},{"name":"use_default_excludes","in":"query","required":false,"schema":{"type":"boolean","description":"Whether to apply the built-in default exclude patterns (node_modules/, .venv/, caches, build outputs, etc.). Defaults to true for compact archives; set false to allow a full workspace capture, including fat directories.","default":true,"title":"Use Default Excludes"},"description":"Whether to apply the built-in default exclude patterns (node_modules/, .venv/, caches, build outputs, etc.). Defaults to true for compact archives; set false to allow a full workspace capture, including fat directories."},{"name":"exclude","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Additional glob patterns to exclude (repeatable, e.g. ?exclude=foo&exclude=*.bin). Combined with the built-in default excludes when use_default_excludes=true; used by itself when use_default_excludes=false.","title":"Exclude"},"description":"Additional glob patterns to exclude (repeatable, e.g. ?exclude=foo&exclude=*.bin). Combined with the built-in default excludes when use_default_excludes=true; used by itself when use_default_excludes=false."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"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. When omitted, the URL is\n        built from the actually configured VSCode port\n        (``http://localhost:{vscode_port}``), so callers that don't know\n        the deployment topology get a URL that matches where the server\n        really binds instead of a hardcoded ``: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":{"anyOf":[{"type":"string"},{"type":"null"}],"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"}]},"type":"object","title":"Response Get Vscode Status Api Vscode Status Get"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/skills":{"post":{"tags":["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 <redacted:unrelated-repository> 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":{"application/json":{"schema":{"$ref":"#/components/schemas/SkillsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SkillsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/skills/sync":{"post":{"tags":["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 <redacted:unrelated-repository> repository.\n\nReturns:\n    SyncResponse indicating success or failure.","operationId":"sync_skills_api_skills_sync_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/skills/install":{"post":{"tags":["Skills"],"summary":"Install Skill Endpoint","description":"Install a skill from a source.\n\nInstalls a skill from a git URL, GitHub shorthand, or local path into\nthe user's installed skills directory (~/.openhands/skills/installed/).\n\nArgs:\n    request: InstallSkillRequest containing source and options.\n\nReturns:\n    InstalledSkillResponse with details about the installation.\n\nRaises:\n    HTTPException 409: If skill is already installed and force=False.\n    HTTPException 400: If fetching the skill source fails.\n    HTTPException 422: If the skill is invalid.","operationId":"install_skill_endpoint_api_skills_install_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallSkillRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledSkillResponse"}}}},"400":{"description":"Failed to fetch skill source"},"409":{"description":"Skill already installed (use force=true)"},"422":{"description":"Invalid skill (missing SKILL.md, etc.)"}},"security":[{"APIKeyHeader":[]}]}},"/api/skills/installed":{"get":{"tags":["Skills"],"summary":"List Installed Skills Endpoint","description":"List all installed skills.\n\nReturns a list of all skills installed in the user's installed skills\ndirectory (~/.openhands/skills/installed/).\n\nReturns:\n    InstalledSkillsListResponse containing list of installed skills.","operationId":"list_installed_skills_endpoint_api_skills_installed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledSkillsListResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/skills/installed/{skill_name}":{"get":{"tags":["Skills"],"summary":"Get Installed Skill Endpoint","description":"Get information about a specific installed skill.\n\nArgs:\n    skill_name: Name of the skill to get.\n\nReturns:\n    InstalledSkillResponse with skill details.\n\nRaises:\n    HTTPException 404: If the skill is not installed.","operationId":"get_installed_skill_endpoint_api_skills_installed__skill_name__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"skill_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","description":"Skill name (lowercase alphanumeric, hyphens)","title":"Skill Name"},"description":"Skill name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledSkillResponse"}}}},"404":{"description":"Skill not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Skills"],"summary":"Set Skill Enabled Endpoint","description":"Enable or disable an installed skill.\n\nArgs:\n    skill_name: Name of the skill to update.\n    request: UpdateSkillStateRequest with enabled state.\n\nReturns:\n    UpdateSkillStateResponse indicating new state.\n\nRaises:\n    HTTPException 404: If the skill is not installed.","operationId":"set_skill_enabled_endpoint_api_skills_installed__skill_name__patch","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"skill_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","description":"Skill name (lowercase alphanumeric, hyphens)","title":"Skill Name"},"description":"Skill name (lowercase alphanumeric, hyphens)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSkillStateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSkillStateResponse"}}}},"404":{"description":"Skill not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Skills"],"summary":"Uninstall Skill Endpoint","description":"Uninstall a skill by name.\n\nRemoves a skill from the user's installed skills directory.\n\nArgs:\n    skill_name: Name of the skill to uninstall.\n\nReturns:\n    UninstallSkillResponse with uninstall message.\n\nRaises:\n    HTTPException 404: If the skill is not installed.","operationId":"uninstall_skill_endpoint_api_skills_installed__skill_name__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"skill_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","description":"Skill name (lowercase alphanumeric, hyphens)","title":"Skill Name"},"description":"Skill name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UninstallSkillResponse"}}}},"404":{"description":"Skill not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/skills/installed/{skill_name}/refresh":{"post":{"tags":["Skills"],"summary":"Refresh Skill Endpoint","description":"Refresh an installed skill to the latest version.\n\nRe-fetches the skill from its original source and updates the installation.\n\nArgs:\n    skill_name: Name of the skill to refresh.\n\nReturns:\n    UpdateSkillResponse with updated skill information.\n\nRaises:\n    HTTPException 404: If the skill is not installed.","operationId":"refresh_skill_endpoint_api_skills_installed__skill_name__refresh_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"skill_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","description":"Skill name (lowercase alphanumeric, hyphens)","title":"Skill Name"},"description":"Skill name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSkillResponse"}}}},"404":{"description":"Skill not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/skills/marketplace":{"get":{"tags":["Skills"],"summary":"Get Marketplace Catalog","description":"Get the marketplace catalog with installation status.\n\nReturns a list of available skills from the OpenHands extensions\nrepository marketplace, along with their installation status.\n\nThis enables frontend applications to display a \"Marketplace\" tab\nwith installable skills.\n\nReturns:\n    MarketplaceCatalogResponse containing list of available skills.","operationId":"get_marketplace_catalog_api_skills_marketplace_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/openhands__agent_server__skills_router__MarketplaceCatalogResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/sub-agents":{"post":{"tags":["Sub Agents"],"summary":"Get Sub Agents","description":"List file-based and built-in sub-agents for the workspace.\n\nMerged first-wins by name with precedence project > user > builtin. Read-only:\nit registers nothing into the conversation registry.","operationId":"get_sub_agents_api_sub_agents_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubAgentsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubAgentsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/plugins":{"post":{"tags":["Plugins"],"summary":"Get Plugins","description":"List locally-available plugins (enabled installed + user/project dirs).\n\nArgs:\n    request: Which local sources to load.\n\nReturns:\n    PluginsResponse with available plugin summaries.","operationId":"get_plugins_api_plugins_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PluginsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PluginsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/plugins/install":{"post":{"tags":["Plugins"],"summary":"Install Plugin Endpoint","description":"Install a plugin from a git URL, GitHub shorthand, or local path.","operationId":"install_plugin_endpoint_api_plugins_install_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallPluginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledPluginResponse"}}}},"400":{"description":"Failed to fetch plugin source"},"409":{"description":"Plugin already installed (use force=true)"},"422":{"description":"Invalid plugin (bad name, etc.)"}},"security":[{"APIKeyHeader":[]}]}},"/api/plugins/installed":{"get":{"tags":["Plugins"],"summary":"List Installed Plugins Endpoint","description":"List all installed plugins (enabled and disabled).","operationId":"list_installed_plugins_endpoint_api_plugins_installed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledPluginsListResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/plugins/installed/{plugin_name}":{"get":{"tags":["Plugins"],"summary":"Get Installed Plugin Endpoint","description":"Get information about a specific installed plugin.","operationId":"get_installed_plugin_endpoint_api_plugins_installed__plugin_name__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"plugin_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Plugin name (lowercase alphanumeric, hyphens)","title":"Plugin Name"},"description":"Plugin name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledPluginResponse"}}}},"404":{"description":"Plugin not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Plugins"],"summary":"Set Plugin Enabled Endpoint","description":"Enable or disable an installed plugin.","operationId":"set_plugin_enabled_endpoint_api_plugins_installed__plugin_name__patch","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"plugin_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Plugin name (lowercase alphanumeric, hyphens)","title":"Plugin Name"},"description":"Plugin name (lowercase alphanumeric, hyphens)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePluginStateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePluginStateResponse"}}}},"404":{"description":"Plugin not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Plugins"],"summary":"Uninstall Plugin Endpoint","description":"Uninstall a plugin by name.","operationId":"uninstall_plugin_endpoint_api_plugins_installed__plugin_name__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"plugin_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Plugin name (lowercase alphanumeric, hyphens)","title":"Plugin Name"},"description":"Plugin name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UninstallPluginResponse"}}}},"404":{"description":"Plugin not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/plugins/installed/{plugin_name}/refresh":{"post":{"tags":["Plugins"],"summary":"Refresh Plugin Endpoint","description":"Refresh an installed plugin to the latest version from its source.","operationId":"refresh_plugin_endpoint_api_plugins_installed__plugin_name__refresh_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"plugin_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Plugin name (lowercase alphanumeric, hyphens)","title":"Plugin Name"},"description":"Plugin name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePluginResponse"}}}},"404":{"description":"Plugin not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/plugins/marketplace":{"get":{"tags":["Plugins"],"summary":"Get Marketplace Catalog","description":"Get the plugins marketplace catalog with installation status.\n\nReturns the true plugins (entries whose source lives under ``./plugins/``)\nfrom the OpenHands extensions repository marketplace, each with attachable\n``PluginSource`` coordinates (``source`` / ``ref`` / ``repo_path``) and an\n``installed`` flag. This enables the front-end to render a plugins\nmarketplace with install/installed state and to attach plugins to\nconversations.\n\nReturns:\n    MarketplaceCatalogResponse containing the list of available plugins.","operationId":"get_marketplace_catalog_api_plugins_marketplace_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/openhands__agent_server__plugins_router__MarketplaceCatalogResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/canvas-extensions/install":{"post":{"tags":["Canvas Extensions"],"summary":"Install Canvas Extension Endpoint","description":"Install a canvas extension from a git URL, GitHub shorthand, or local\npath.\n\nA fresh install always lands disabled, regardless of the request body --\nthere is no ``enabled`` field to smuggle a different state through.","operationId":"install_canvas_extension_endpoint_api_canvas_extensions_install_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallCanvasExtensionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledCanvasExtensionResponse"}}}},"400":{"description":"Could not read canvas extension source"},"409":{"description":"Canvas extension already installed (use force=true)"},"422":{"description":"Invalid canvas extension (bad manifest, etc.)"}},"security":[{"APIKeyHeader":[]}]}},"/api/canvas-extensions/installed":{"get":{"tags":["Canvas Extensions"],"summary":"List Installed Canvas Extensions Endpoint","description":"List all installed canvas extensions (enabled and disabled).","operationId":"list_installed_canvas_extensions_endpoint_api_canvas_extensions_installed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledCanvasExtensionsListResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/canvas-extensions/installed/{extension_name}":{"get":{"tags":["Canvas Extensions"],"summary":"Get Installed Canvas Extension Endpoint","description":"Get information about a specific installed canvas extension.","operationId":"get_installed_canvas_extension_endpoint_api_canvas_extensions_installed__extension_name__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstalledCanvasExtensionResponse"}}}},"404":{"description":"Canvas extension not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Canvas Extensions"],"summary":"Set Canvas Extension Enabled Endpoint","description":"Enable or disable an installed canvas extension.","operationId":"set_canvas_extension_enabled_endpoint_api_canvas_extensions_installed__extension_name__patch","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCanvasExtensionStateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCanvasExtensionStateResponse"}}}},"404":{"description":"Canvas extension not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Canvas Extensions"],"summary":"Uninstall Canvas Extension Endpoint","description":"Uninstall a canvas extension by name while retaining backend data.","operationId":"uninstall_canvas_extension_endpoint_api_canvas_extensions_installed__extension_name__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UninstallCanvasExtensionResponse"}}}},"404":{"description":"Canvas extension not installed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/canvas-extensions/installed/{extension_name}/backend":{"get":{"tags":["Canvas Extensions"],"summary":"Get Canvas Extension Backend Status Endpoint","description":"Probe the optional backend lifecycle state.","operationId":"get_canvas_extension_backend_status_endpoint_api_canvas_extensions_installed__extension_name__backend_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/canvas-extensions/installed/{extension_name}/backend/prepare":{"post":{"tags":["Canvas Extensions"],"summary":"Prepare Canvas Extension Backend Endpoint","description":"Verify and prepare the immutable artifact for an exact revision.","operationId":"prepare_canvas_extension_backend_endpoint_api_canvas_extensions_installed__extension_name__backend_prepare_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendRevisionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendStatus"}}}},"409":{"description":"Revision or checksum approval conflict"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/canvas-extensions/installed/{extension_name}/backend/start":{"post":{"tags":["Canvas Extensions"],"summary":"Start Canvas Extension Backend Endpoint","description":"Start only a previously prepared exact backend revision.","operationId":"start_canvas_extension_backend_endpoint_api_canvas_extensions_installed__extension_name__backend_start_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendRevisionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendStatus"}}}},"409":{"description":"Revision is not prepared or cannot start"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/canvas-extensions/installed/{extension_name}/backend/stop":{"post":{"tags":["Canvas Extensions"],"summary":"Stop Canvas Extension Backend Endpoint","description":"Stop the backend's owned process group idempotently.","operationId":"stop_canvas_extension_backend_endpoint_api_canvas_extensions_installed__extension_name__backend_stop_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/canvas-extensions/installed/{extension_name}/backend/logs":{"get":{"tags":["Canvas Extensions"],"summary":"Get Canvas Extension Backend Logs Endpoint","description":"Return bounded combined stdout and stderr from the owned process.","operationId":"get_canvas_extension_backend_logs_endpoint_api_canvas_extensions_installed__extension_name__backend_logs_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"},{"name":"limit_bytes","in":"query","required":false,"schema":{"type":"integer","maximum":262144,"minimum":1,"default":65536,"title":"Limit Bytes"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendLogs"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/canvas-extensions/installed/{extension_name}/backend/data":{"delete":{"tags":["Canvas Extensions"],"summary":"Delete Canvas Extension Backend Data Endpoint","description":"Delete mutable backend data separately from app uninstall.","operationId":"delete_canvas_extension_backend_data_endpoint_api_canvas_extensions_installed__extension_name__backend_data_delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackendStatus"}}}},"409":{"description":"Backend must be stopped first"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/canvas-extensions/installed/{extension_name}/bundle":{"get":{"tags":["Canvas Extensions"],"summary":"Get Canvas Extension Bundle Endpoint","description":"Serve an installed canvas extension's entrypoint bundle file.\n\nEntrypoint containment is re-validated against the live install path on\nevery request, not just at install time -- see\n``get_canvas_extension_bundle_path``. ``Cache-Control: no-cache`` forces\nrevalidation on each request, so a client never keeps serving a bundle\nfrom before the extension's last refresh: the actual bytes are re-read\nfrom disk, and Starlette's file-stat-based ``ETag``/``Last-Modified``\nchange the moment the on-disk revision does.","operationId":"get_canvas_extension_bundle_endpoint_api_canvas_extensions_installed__extension_name__bundle_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Canvas extension or bundle not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/canvas-extensions/installed/{extension_name}/icon":{"get":{"tags":["Canvas Extensions"],"summary":"Get Canvas Extension Icon Endpoint","description":"Serve the SVG icon declared by an installed canvas extension's manifest.\n\nThe path comes from the manifest, never the request. The CSP sandbox keeps\na directly opened SVG from running scripts on the agent-server origin.","operationId":"get_canvas_extension_icon_endpoint_api_canvas_extensions_installed__extension_name__icon_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Canvas extension name (lowercase alphanumeric, hyphens)","title":"Extension Name"},"description":"Canvas extension name (lowercase alphanumeric, hyphens)"}],"responses":{"200":{"description":"Successful Response","content":{"image/svg+xml":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"Canvas extension or icon not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/hooks":{"post":{"tags":["Hooks"],"summary":"Get Hooks","description":"Load hooks from the workspace .openhands/hooks.json file.\n\nThis endpoint reads the hooks configuration from the project's\n.openhands/hooks.json file if it exists.\n\nArgs:\n    request: HooksRequest containing the project directory path.\n\nReturns:\n    HooksResponse containing the hook configuration or None.","operationId":"get_hooks_api_hooks_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HooksRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HooksResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/llm/providers":{"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/ProvidersResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/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"}}}},"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":[]}]}},"/api/llm/subscription/openai/models":{"get":{"tags":["LLM"],"summary":"List Openai Subscription Models","description":"List models available through ChatGPT subscription authentication.","operationId":"list_openai_subscription_models_api_llm_subscription_openai_models_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionModelsResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/llm/subscription/openai/status":{"get":{"tags":["LLM"],"summary":"Get Openai Subscription Status","description":"Return safe ChatGPT subscription connection state without tokens.","operationId":"get_openai_subscription_status_api_llm_subscription_openai_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionStatusResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/llm/subscription/openai/device/start":{"post":{"tags":["LLM"],"summary":"Start Openai Subscription Device Login","description":"Start ChatGPT device-code sign-in without returning tokens.","operationId":"start_openai_subscription_device_login_api_llm_subscription_openai_device_start_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionDeviceStartResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/llm/subscription/openai/device/poll":{"post":{"tags":["LLM"],"summary":"Poll Openai Subscription Device Login","description":"Poll a ChatGPT device-code sign-in without returning tokens.","operationId":"poll_openai_subscription_device_login_api_llm_subscription_openai_device_poll_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionDevicePollRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/llm/subscription/openai/logout":{"post":{"tags":["LLM"],"summary":"Logout Openai Subscription","description":"Remove stored ChatGPT subscription credentials.","operationId":"logout_openai_subscription_api_llm_subscription_openai_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionStatusResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/acp/models":{"post":{"tags":["ACP"],"summary":"Discover Models","description":"Start the ACP server in a throwaway session and report its models.\n\nThe server answers with its default model and the models it offers for the\ngiven credentials; a launch or authentication failure comes back in\n``error`` rather than as an HTTP error.","operationId":"discover_models_api_acp_models_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ACPModelDiscoveryRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ACPModelDiscovery"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/llm/provider-connections":{"get":{"tags":["LLM Provider Connections"],"summary":"List Provider Connections","operationId":"list_provider_connections_api_llm_provider_connections_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ProviderConnectionResponse"},"type":"array","title":"Response List Provider Connections Api Llm Provider Connections Get"}}}}},"security":[{"APIKeyHeader":[]}]},"post":{"tags":["LLM Provider Connections"],"summary":"Create Provider Connection","operationId":"create_provider_connection_api_llm_provider_connections_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderConnectionCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderConnectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/llm/provider-connections/{connection_id}":{"patch":{"tags":["LLM Provider Connections"],"summary":"Update Provider Connection","operationId":"update_provider_connection_api_llm_provider_connections__connection_id__patch","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"connection_id","in":"path","required":true,"schema":{"type":"string","title":"Connection Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderConnectionUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderConnectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["LLM Provider Connections"],"summary":"Delete Provider Connection","operationId":"delete_provider_connection_api_llm_provider_connections__connection_id__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"connection_id","in":"path","required":true,"schema":{"type":"string","title":"Connection Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderConnectionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mcp/test":{"post":{"tags":["MCP"],"summary":"Test an MCP server configuration","description":"Attempt to connect to a candidate MCP server and list its tools, without persisting any settings. Useful for validating user input in 'add MCP server' flows before storing the config. For OAuth servers, any acquired state is returned as `oauth_state` so clients can persist it under the MCP server object's `auth.state`. Optionally invokes one caller-chosen (read-only) tool via `tool_call` and reports its outcome in `tool_result`, so callers can verify credentials that are only exercised on tool invocation. Encrypted `env`/`headers` values round-tripped from settings are decrypted before the connection is attempted. Returns 200 with `ok=false` for connection / timeout failures (those are expected during validation, not server errors).","operationId":"test_mcp_server_api_mcp_test_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MCPTestRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/MCPTestSuccess"},{"$ref":"#/components/schemas/MCPTestFailure"}],"title":"Response Test Mcp Server Api Mcp Test Post","discriminator":{"propertyName":"ok","mapping":{"True":"#/components/schemas/MCPTestSuccess","False":"#/components/schemas/MCPTestFailure"}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/mcp/oauth/start":{"post":{"tags":["MCP"],"summary":"Start an MCP OAuth install probe","description":"Start OAuth for a candidate MCP server and return the authorization URL.","operationId":"start_mcp_oauth_api_mcp_oauth_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MCPTestRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MCPOAuthStartResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/mcp/oauth/status/{job_id}":{"get":{"tags":["MCP"],"summary":"Get an MCP OAuth install probe status","operationId":"get_mcp_oauth_status_api_mcp_oauth_status__job_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MCPOAuthStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mcp/oauth/callback/{job_id}":{"post":{"tags":["MCP"],"summary":"Submit an MCP OAuth callback URL","operationId":"submit_mcp_oauth_callback_api_mcp_oauth_callback__job_id__post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MCPOAuthCallbackRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MCPOAuthStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/settings/agent-schema":{"get":{"tags":["Settings"],"summary":"Get Agent Settings Schema","description":"Return the schema used to render AgentSettings-based settings forms.","operationId":"get_agent_settings_schema_api_settings_agent_schema_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsSchema"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/settings/conversation-schema":{"get":{"tags":["Settings"],"summary":"Get Conversation Settings Schema","description":"Return the schema used to render ConversationSettings-based forms.","operationId":"get_conversation_settings_schema_api_settings_conversation_schema_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsSchema"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/settings":{"get":{"tags":["Settings"],"summary":"Get Settings","description":"Get current settings.\n\nReturns the persisted settings including agent configuration,\nconversation settings, and whether an LLM API key is configured.\n\nUse the ``X-Expose-Secrets`` header to control secret exposure:\n- ``encrypted``: Returns cipher-encrypted values (safe for frontend clients)\n- ``plaintext``: Returns raw secret values (backend clients only!)\n- (absent): Returns redacted values (\"<redacted:api_key>\")\n\nSecurity:\n    When the server is configured with ``session_api_keys``, all endpoints\n    under ``/api`` (including this one) require the ``X-Session-API-Key``\n    header. When no session API keys are configured, endpoints are open.\n\n    **Trust model:** All authenticated clients are treated as equally\n    trusted. There is no role-based authorization for ``X-Expose-Secrets``\n    modes—any authenticated client can request ``plaintext`` or\n    ``encrypted`` exposure. This design assumes:\n\n    - All clients sharing session API keys operate in the same trust domain\n    - Network-level controls (firewalls, VPCs) restrict access to trusted\n      clients only\n    - Production deployments use session API keys to prevent anonymous access\n\n    The ``plaintext`` mode exists for backend-to-backend communication\n    (e.g., RemoteWorkspace). Frontend clients should prefer ``encrypted``\n    mode for round-tripping secrets, or omit the header to receive redacted\n    values.","operationId":"get_settings_api_settings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsResponse"}}}}},"security":[{"APIKeyHeader":[]}]},"patch":{"tags":["Settings"],"summary":"Update Settings","description":"Update settings with partial changes.\n\nAccepts ``agent_settings_diff``, ``conversation_settings_diff``,\n``misc_settings_diff``, and/or ``active_profile`` for incremental updates.\nSetting ``active_profile`` loads and applies that profile's LLM, same as\n``POST /api/profiles/{name}/activate``, unless ``agent_settings_diff.llm``\nis also given.\n\nThe three ``*_settings_diff`` fields are deep-merged; nested objects merge\nrecursively, and a ``null`` value **inside a nested map deletes that entry**\n— the \"unset\" primitive that lets a client remove a single map key without\nround-tripping the whole map. To remove one MCP server's header::\n\n    PATCH /api/settings\n    {\"agent_settings_diff\":\n        {\"mcp_config\": {\"svc\": {\"headers\": {\"X-Old\": null}}}}}\n\nA ``null`` on a top-level *field* (e.g. ``{\"confirmation_mode\": null}``)\nis **not** an unset — it flows to model validation as before, so it still\nfails loudly rather than silently resetting the field to its default.\n\n``misc_settings_diff`` is deep-merged into the persisted ``misc_settings``\nblock. The agent-server treats ``misc_settings`` as opaque frontend-owned\ndata: nested dicts are merged recursively, lists are replaced wholesale,\nand the contents are never read or validated server-side.\n\nUses file locking to prevent concurrent updates from overwriting each other.\n\nRaises:\n    HTTPException: 400 if the update payload contains invalid values.","operationId":"update_settings_api_settings_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/settings/mcp/{settings_key}":{"post":{"tags":["Settings"],"summary":"Create Mcp Server","description":"Create one named MCP server without replacing an existing map entry.","operationId":"create_mcp_server_api_settings_mcp__settings_key__post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"settings_key","in":"path","required":true,"schema":{"type":"string","title":"Settings Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MCPServer-Input"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Settings"],"summary":"Patch Mcp Server","description":"Sparsely update one existing named MCP server.","operationId":"patch_mcp_server_api_settings_mcp__settings_key__patch","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"settings_key","in":"path","required":true,"schema":{"type":"string","title":"Settings Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MCPServerPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Settings"],"summary":"Delete Mcp Server","description":"Delete one existing named MCP server without altering sibling entries.","operationId":"delete_mcp_server_api_settings_mcp__settings_key__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"settings_key","in":"path","required":true,"schema":{"type":"string","title":"Settings Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/settings/secrets":{"get":{"tags":["Settings"],"summary":"List Secrets","description":"List available secret names, optionally scoped by an agent profile.","operationId":"list_secrets_api_settings_secrets_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"agent_profile_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Profile Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretsListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Settings"],"summary":"Create Secret","description":"Create or update a custom secret (upsert).\n\nRaises:\n    HTTPException: 422 if the name or value is invalid, 500 if file is corrupted.","operationId":"create_secret_api_settings_secrets_put","security":[{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretCreateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecretItemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/settings/secrets/{name}":{"get":{"tags":["Settings"],"summary":"Get Secret Value","description":"Get a single secret value by name.\n\nReturns the raw secret value as plain text. This endpoint is designed\nto be used with LookupSecret for lazy secret resolution.\n\nRaises:\n    HTTPException: 400 if name format is invalid, 404 if secret not found.","operationId":"get_secret_value_api_settings_secrets__name__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Settings"],"summary":"Delete Secret","description":"Delete a custom secret by name.\n\nRaises:\n    HTTPException: 400 if name format is invalid, 404 if secret not found,\n    500 if file is corrupted.","operationId":"delete_secret_api_settings_secrets__name__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"boolean"},"title":"Response Delete Secret Api Settings Secrets  Name  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces":{"get":{"tags":["Workspaces"],"summary":"List Workspaces","description":"Return the saved workspaces and workspace parents.","operationId":"list_workspaces_api_workspaces_get","security":[{"APIKeyHeader":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspacesListResponse"}}}}}},"post":{"tags":["Workspaces"],"summary":"Add Workspaces","description":"Append workspaces to the saved list. Idempotent — dedupes by ``path``.","operationId":"add_workspaces_api_workspaces_post","security":[{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWorkspacesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspacesListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Workspaces"],"summary":"Delete Workspace","description":"Remove a workspace by its absolute path.","operationId":"delete_workspace_api_workspaces_delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Absolute workspace path to remove","title":"Path"},"description":"Absolute workspace path to remove"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/workspaces/parents":{"post":{"tags":["Workspaces"],"summary":"Add Workspace Parents","description":"Append workspace parents. Idempotent — dedupes by ``path``.","operationId":"add_workspace_parents_api_workspaces_parents_post","security":[{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddWorkspaceParentsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspacesListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Workspaces"],"summary":"Delete Workspace Parent","description":"Remove a workspace parent by its absolute path.","operationId":"delete_workspace_parent_api_workspaces_parents_delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"path","in":"query","required":true,"schema":{"type":"string","description":"Absolute workspace parent path to remove","title":"Path"},"description":"Absolute workspace parent path to remove"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/profiles":{"get":{"tags":["Profiles"],"summary":"List Profiles","description":"List all saved LLM profiles.\n\nReturns the list of profiles along with the currently active profile name,\nif one has been activated. The active_profile tracks which LLM profile\nconfiguration is currently in use.","operationId":"list_profiles_api_profiles_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileListResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/profiles/{name}":{"get":{"tags":["Profiles"],"summary":"Get Profile","description":"Get a profile's configuration.\n\nUse the ``X-Expose-Secrets`` header to control secret exposure:\n- ``encrypted``: Returns cipher-encrypted values (safe for frontend clients)\n- ``plaintext``: Resolves linked providers and returns raw secret values\n  for backend clients constructing a runnable LLM configuration\n- (absent): Returns nulled ``api_key`` with ``api_key_set`` indicator","operationId":"get_profile_api_profiles__name__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Profiles"],"summary":"Save Profile","description":"Save an LLM configuration as a named profile.\n\nOverwrites an existing profile of the same name. Returns 409 if creating\na new profile would exceed ``MAX_PROFILES``.\n\nWhen ``OH_SECRET_KEY`` is configured, secrets are encrypted at rest.\nClients can submit cipher-encrypted secrets which will be decrypted\nserver-side before re-encrypting with the storage cipher.","operationId":"save_profile_api_profiles__name__post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveProfileRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileMutationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Profiles"],"summary":"Delete Profile","description":"Delete a saved profile (idempotent).\n\nGuarded by the agent-profile FK: returns 409 naming the referrers if any\n``AgentProfile`` still cites this LLM profile via ``llm_profile_ref``.","operationId":"delete_profile_api_profiles__name__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileMutationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/profiles/{name}/validate":{"post":{"tags":["Profiles"],"summary":"Validate Profile","description":"Pre-flight check: fire a minimal LLM completion to catch misconfigurations.\n\nInstantiates the submitted LLM config and sends a 1-token completion to\nsurface errors like invalid model names, missing provider prefixes, bad\nbase URLs, and invalid API keys — *before* the profile is saved.\n\nTransient errors (rate limits, timeouts) are treated as non-blocking: the\nresponse is ``valid=True`` with no error, since those don't indicate a\nmisconfigured profile.","operationId":"validate_profile_api_profiles__name__validate_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateProfileRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/profiles/{name}/rename":{"post":{"tags":["Profiles"],"summary":"Rename Profile","description":"Rename a saved profile atomically.\n\nReturns 404 if the source does not exist, or 409 if ``new_name`` already\nexists. A same-name rename is a verified no-op (still 404s if missing).\n\nIf the renamed profile is the currently active profile, the active_profile\nsetting is updated to the new name. Any ``AgentProfile.llm_profile_ref``\nciting the old name is cascaded to the new name in lock-step.","operationId":"rename_profile_api_profiles__name__rename_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenameProfileRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileMutationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/profiles/{name}/activate":{"post":{"tags":["Profiles"],"summary":"Activate Profile","description":"Activate a saved LLM profile.\n\nThis endpoint:\n1. Loads the named profile's LLM configuration\n2. Applies it to the current OpenHands agent settings (updates\n   ``agent_settings.llm``); ACP settings have no LLM to update\n3. Records the profile name as the active profile for frontend tracking\n\nReturns 404 if the profile does not exist.\n\nUse ``GET /api/profiles`` to see which profile is currently active via\nthe ``active_profile`` field.","operationId":"activate_profile_api_profiles__name__activate_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent-profiles":{"get":{"tags":["Agent Profiles"],"summary":"List Agent Profiles","description":"List all stored agent profiles and the active pointer.\n\nOn the first call against an empty store with no active pointer, lazily\nseeds one default profile from the current ``agent_settings`` and activates\nit (the one-time migration that replaces a dedicated seed step).","operationId":"list_agent_profiles_api_agent_profiles_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentProfileListResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/agent-profiles/{name}":{"get":{"tags":["Agent Profiles"],"summary":"Get Agent Profile","description":"Get a stored profile.\n\nA profile is secret-free at rest (#4017), so there is nothing to mask or\nexpose — unlike the LLM ``/api/profiles`` router, this endpoint has no\n``X-Expose-Secrets`` behavior.","operationId":"get_agent_profile_api_agent_profiles__name__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentProfileDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Agent Profiles"],"summary":"Save Agent Profile","description":"Save an ``AgentProfile`` under ``name`` (overwriting a namesake).\n\nThe path ``name`` is authoritative — it overrides any ``name`` in the body.\nThe profile is secret-free at rest (#4017), so no cipher/encryption is\ninvolved. Returns 409 if creating a new profile would exceed\n``MAX_AGENT_PROFILES``.","operationId":"save_agent_profile_api_agent_profiles__name__post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Body"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentProfileMutationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Agent Profiles"],"summary":"Delete Agent Profile","description":"Delete a stored profile (idempotent).\n\nIf the deleted profile was the active one, ``active_agent_profile_id`` is\ncleared. If ``agent_settings`` is itself left on a non-OpenHands variant,\nit is reset to default OpenHands agent settings so stale ACP configuration\ndoes not outlive the profile it came from; the server-wide ``mcp_config``\nis carried over.","operationId":"delete_agent_profile_api_agent_profiles__name__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentProfileMutationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent-profiles/{name}/rename":{"post":{"tags":["Agent Profiles"],"summary":"Rename Agent Profile","description":"Rename a stored profile atomically.\n\nThe stable ``id`` is preserved, so an active pointer (keyed on ``id``)\nsurvives the rename untouched. Returns 404 if the source is missing, 409 if\n``new_name`` is taken.","operationId":"rename_agent_profile_api_agent_profiles__name__rename_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenameAgentProfileRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentProfileMutationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent-profiles/{profile_id}/activate":{"post":{"tags":["Agent Profiles"],"summary":"Activate Agent Profile","description":"Activate a profile by its stable ``id`` — pointer only.\n\nSets ``active_agent_profile_id`` and nothing else: unlike the LLM\n``/activate``, this does **not** write ``agent_settings`` (the\ncreation-time-only contract). Returns 404 if no stored profile has that id.","operationId":"activate_agent_profile_api_agent_profiles__profile_id__activate_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"profile_id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":128,"title":"Profile Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateAgentProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/agent-profiles/{name}/materialize":{"post":{"tags":["Agent Profiles"],"summary":"Materialize Agent Profile","description":"Preview the launch of a profile; return a diagnostics report.\n\nPreviews the stored profile ``name``, or ``body.profile`` when given (so an\neditor can preview before saving), with the same resolve and finalize as a\nlaunch, against the runtime this server launches into. Dangling references\nare reported in the body (valid=False) rather than raising — the only error\nstatuses are 404 (unknown stored profile) and 422 (invalid draft).\nresolved_settings is redacted (no raw secrets).","operationId":"materialize_agent_profile_api_agent_profiles__name__materialize_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/MaterializeAgentProfileRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentProfileDiagnostics"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/meta-profiles":{"get":{"tags":["Meta-profiles"],"summary":"List Meta Profiles","description":"List all saved meta-profiles and the currently active one.","operationId":"list_meta_profiles_api_meta_profiles_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetaProfileListResponse"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/meta-profiles/{name}":{"get":{"tags":["Meta-profiles"],"summary":"Get Meta Profile","description":"Get a meta-profile's full configuration.","operationId":"get_meta_profile_api_meta_profiles__name__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetaProfileDetailResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Meta-profiles"],"summary":"Save Meta Profile","description":"Save (create or overwrite) a meta-profile.\n\nReturns 409 if creating a new meta-profile would exceed\n``MAX_META_PROFILES``.","operationId":"save_meta_profile_api_meta_profiles__name__post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetaProfile"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetaProfileMutationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Meta-profiles"],"summary":"Delete Meta Profile","description":"Delete a meta-profile (idempotent).\n\nIf the deleted meta-profile is the active one, ``active_meta_profile`` is\ncleared.","operationId":"delete_meta_profile_api_meta_profiles__name__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetaProfileMutationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/meta-profiles/{name}/activate":{"post":{"tags":["Meta-profiles"],"summary":"Activate Meta Profile","description":"Activate a meta-profile by recording it as ``active_meta_profile``.\n\nUnlike LLM profiles, activating a meta-profile does not mutate the agent's\nLLM config — it only records which meta-profile the\n``route_task_to_model`` tool should route with. Returns 404 if the\nmeta-profile does not exist.","operationId":"activate_meta_profile_api_meta_profiles__name__activate_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateMetaProfileResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/workspace-session":{"post":{"tags":["Auth"],"summary":"Create Workspace Session","description":"Mint a workspace-scoped session cookie.\n\nCaller must already be authenticated by the ``X-Session-API-Key``\nheader (enforced by the parent router's dependency). The cookie value\nis the validated session API key itself; it is HttpOnly so JS in\nworkspace HTML cannot read it back.","operationId":"create_workspace_session_api_auth_workspace_session_post","responses":{"204":{"description":"Cookie set"},"401":{"description":"Missing or invalid X-Session-API-Key header"}},"security":[{"APIKeyHeader":[]}]},"delete":{"tags":["Auth"],"summary":"Delete Workspace Session","description":"Clear the workspace session cookie.\n\nBrowsers identify cookies by ``(name, domain, path)``; the deletion\ncookie must therefore share the original cookie's attributes. We\noverwrite with an empty value and ``max_age=0`` so the browser drops\nit immediately.","operationId":"delete_workspace_session_api_auth_workspace_session_delete","responses":{"204":{"description":"Cookie cleared"}},"security":[{"APIKeyHeader":[]}]}},"/app-backends/{extension_name}/session":{"post":{"tags":["Canvas App Backends"],"summary":"Create App Backend Session Endpoint","description":"Issue a short-lived HttpOnly session for one ready app backend.\n\nCall this endpoint on the configured app ingress origin, using the normal\n``X-Session-API-Key`` control header and the Canvas page's ``Origin``. The\nreturned ingress URL contains no credential. The caller must retain cookies\n(``credentials: include``); third-party iframe deployments require HTTPS and\nbrowser support for partitioned cookies.","operationId":"create_app_backend_session_endpoint_app_backends__extension_name__session_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Installed Canvas App name","title":"Extension Name"},"description":"Installed Canvas App name"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppBackendSessionResponse"}}}},"401":{"description":"Missing or invalid X-Session-API-Key header"},"403":{"description":"Origin is not allowed"},"409":{"description":"Ingress does not use a separate browser origin"},"503":{"description":"Backend is unavailable or ingress is not configured"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Canvas App Backends"],"summary":"Delete App Backend Session Endpoint","description":"Revoke the current app-scoped browser session.","operationId":"delete_app_backend_session_endpoint_app_backends__extension_name__session_delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"extension_name","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Installed Canvas App name","title":"Extension Name"},"description":"Installed Canvas App name"}],"responses":{"204":{"description":"Browser session revoked and cookie cleared"},"401":{"description":"Missing or invalid X-Session-API-Key header"},"403":{"description":"Origin is not allowed"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"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"},"tools":{"items":{"$ref":"#/components/schemas/Tool-Input"},"type":"array","title":"Tools"},"mcp_config":{"additionalProperties":{"$ref":"#/components/schemas/MCPServer-Input"},"type":"object","title":"Mcp Config","description":"Optional MCP servers to expose as tools.","examples":[{"fetch":{"args":["--with","mcp==1.29.0","mcp-server-fetch==2026.7.10"],"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-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":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt","description":"Inline system prompt string.  When provided, the agent uses this text verbatim as the system message instead of rendering from `system_prompt_filename`.  Mutually exclusive with a non-default `system_prompt_filename`.\n\n**Warning**: This is not recommended unless you know what you are doing (e.g. customising agent behaviour for a completely different task).  Setting this will override OpenHands' built-in system instructions that govern default agent behaviour."},"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 filename. The default 'security_policy.j2' is a back-compat sentinel (the file was removed) that selects the built-in default policy from the prompt registry -- it is not loaded from disk. Any other value names a custom policy file whose contents are inserted verbatim (NOT rendered as a Jinja template). Can be either:\n- A relative filename (e.g., 'custom_security_policy.md') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.md')\n- Empty string to disable security policy","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":"<redacted:api_key>","base_url":"https://llm-proxy.eval.all-hands.dev","model":"litellm_proxy/openai/gpt-5.5"},"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"}]},"tool_concurrency_limit":{"type":"integer","minimum":1.0,"title":"Tool Concurrency Limit","description":"Maximum number of tool calls to execute concurrently within a single agent step. Default is 1 (sequential). Values > 1 enable parallel execution; concurrent tools share the conversation object, filesystem, and working directory, so mutations to shared state may race.","default":1},"acp_command":{"items":{"type":"string"},"type":"array","title":"Acp Command","description":"Command to start the ACP server, e.g. ['npx', '-y', '@agentclientprotocol/claude-agent-acp']"},"acp_server":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Server","description":"Provider registry key identifying which ACP CLI this agent runs (any ACP_PROVIDERS key, or 'custom'); None when the agent is built directly rather than via ACPAgentSettings. Set by ACPAgentSettings.create_agent() from ACPAgentSettings.acp_server so the authoritative key survives onto the agent — and thus onto ConversationInfo.agent — because the launch command in acp_command does not reliably reverse-map to a provider. Informational only: consumers use it to resolve a provider brand label / model list; the subprocess is still launched from acp_command."},"acp_args":{"items":{"type":"string"},"type":"array","title":"Acp Args","description":"Additional arguments for the ACP server command"},"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, 'agent-full-access' for codex-acp; a provider with no such mode (pi-acp) skips the call."},"acp_prompt_timeout":{"type":"number","title":"Acp Prompt Timeout","description":"Inactivity timeout in seconds for a single ACP prompt() call. The deadline resets on every update from the ACP server (token, thought, tool-call progress, usage), so a steadily-progressing agent runs as long as it keeps making progress; the prompt is only aborted after this many seconds with no activity at all. Prevents indefinite hangs when the ACP server stops responding without killing legitimately long-running work.","default":1800.0},"acp_startup_timeout":{"type":"number","title":"Acp Startup Timeout","description":"Timeout in seconds for ACP server startup: spawning the subprocess, the initialize/authenticate handshake, and new_session()/load_session(). Unlike acp_prompt_timeout, this is a hard deadline rather than an idle deadline, since startup has no intermediate progress signal to reset it against. Prevents an indefinite hang when the ACP server blocks on authentication (e.g. an expired token) without ever raising.","default":90.0},"acp_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Model","description":"Model for the ACP server to use (e.g. 'sonnet' or 'gpt-5.5'). Applied via the protocol — set_config_option(model) for configOptions-based servers (codex, claude), else set_session_model. If None, the server picks its default."},"acp_resume_session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Resume Session Id","description":"Optional explicit ACP session id to resume. When set, takes precedence over the id persisted in ``state.agent_state`` and is used to call ``session/load`` on the ACP server. Designed for environments where the per-conversation filesystem (and therefore ``base_state.json``) does not survive across restarts (e.g. cloud sandbox recycles), but the id has been mirrored into durable storage elsewhere. Falls back to a fresh session if the server cannot load the id. Treated as a secret on the wire — possession of the id is enough to resume the underlying ACP session, so default serialization redacts it; pass ``expose_secrets='plaintext'`` (trusted backend) or ``expose_secrets='encrypted'`` plus a cipher (frontend round-trip) when the value must cross a serialization boundary."},"acp_file_secrets":{"items":{"$ref":"#/components/schemas/ACPFileSecretSpec"},"type":"array","title":"Acp File Secrets","description":"Reserved 'file-content' credential secrets to materialise to disk before launching the subprocess (e.g. Codex auth.json, Gemini Vertex SA JSON). The SDK owns the mechanism (write the file in the runtime pod, set the env var, seed-if-absent); these specs are the policy. Defaults to the built-in supported providers; a downstream application may override or extend this to support other ACP servers with different file-auth schemes."},"acp_isolate_data_dir":{"type":"boolean","title":"Acp Isolate Data Dir","description":"Give the ACP subprocess a per-conversation CLI data/config root instead of the shared user ``HOME``. When True and the provider is recognised, point its data-dir env var (``CODEX_HOME`` / ``CLAUDE_CONFIG_DIR`` / ``HOME``; see ``ACPProviderInfo.data_dir_env_var``) at ``<persistence_dir>/acp/<provider>`` — the same per-conversation tree materialised file-secrets use. Required for correctness when several of a user's conversations share one sandbox (``SandboxGroupingStrategy != NO_GROUPING``), where they would otherwise race on one set of CLI auth/config/cache/lock files (see #1019). Off by default: with one sandbox per conversation the shared HOME is already private, and relocating it would hide a pre-existing interactive login. Downstream policy decides when to enable it; the SDK owns where the root lives.","default":false},"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":{"$ref":"#/components/schemas/MCPServer-Output"},"type":"object","title":"Mcp Config","description":"Optional MCP servers to expose as tools.","examples":[{"fetch":{"args":["--with","mcp==1.29.0","mcp-server-fetch==2026.7.10"],"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":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt","description":"Inline system prompt string.  When provided, the agent uses this text verbatim as the system message instead of rendering from `system_prompt_filename`.  Mutually exclusive with a non-default `system_prompt_filename`.\n\n**Warning**: This is not recommended unless you know what you are doing (e.g. customising agent behaviour for a completely different task).  Setting this will override OpenHands' built-in system instructions that govern default agent behaviour."},"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 filename. The default 'security_policy.j2' is a back-compat sentinel (the file was removed) that selects the built-in default policy from the prompt registry -- it is not loaded from disk. Any other value names a custom policy file whose contents are inserted verbatim (NOT rendered as a Jinja template). Can be either:\n- A relative filename (e.g., 'custom_security_policy.md') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.md')\n- Empty string to disable security policy","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":"<redacted:api_key>","base_url":"https://llm-proxy.eval.all-hands.dev","model":"litellm_proxy/openai/gpt-5.5"},"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"}]},"tool_concurrency_limit":{"type":"integer","minimum":1.0,"title":"Tool Concurrency Limit","description":"Maximum number of tool calls to execute concurrently within a single agent step. Default is 1 (sequential). Values > 1 enable parallel execution; concurrent tools share the conversation object, filesystem, and working directory, so mutations to shared state may race.","default":1},"acp_command":{"items":{"type":"string"},"type":"array","title":"Acp Command","description":"Command to start the ACP server, e.g. ['npx', '-y', '@agentclientprotocol/claude-agent-acp']"},"acp_server":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Server","description":"Provider registry key identifying which ACP CLI this agent runs (any ACP_PROVIDERS key, or 'custom'); None when the agent is built directly rather than via ACPAgentSettings. Set by ACPAgentSettings.create_agent() from ACPAgentSettings.acp_server so the authoritative key survives onto the agent — and thus onto ConversationInfo.agent — because the launch command in acp_command does not reliably reverse-map to a provider. Informational only: consumers use it to resolve a provider brand label / model list; the subprocess is still launched from acp_command."},"acp_args":{"items":{"type":"string"},"type":"array","title":"Acp Args","description":"Additional arguments for the ACP server command"},"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, 'agent-full-access' for codex-acp; a provider with no such mode (pi-acp) skips the call."},"acp_prompt_timeout":{"type":"number","title":"Acp Prompt Timeout","description":"Inactivity timeout in seconds for a single ACP prompt() call. The deadline resets on every update from the ACP server (token, thought, tool-call progress, usage), so a steadily-progressing agent runs as long as it keeps making progress; the prompt is only aborted after this many seconds with no activity at all. Prevents indefinite hangs when the ACP server stops responding without killing legitimately long-running work.","default":1800.0},"acp_startup_timeout":{"type":"number","title":"Acp Startup Timeout","description":"Timeout in seconds for ACP server startup: spawning the subprocess, the initialize/authenticate handshake, and new_session()/load_session(). Unlike acp_prompt_timeout, this is a hard deadline rather than an idle deadline, since startup has no intermediate progress signal to reset it against. Prevents an indefinite hang when the ACP server blocks on authentication (e.g. an expired token) without ever raising.","default":90.0},"acp_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Model","description":"Model for the ACP server to use (e.g. 'sonnet' or 'gpt-5.5'). Applied via the protocol — set_config_option(model) for configOptions-based servers (codex, claude), else set_session_model. If None, the server picks its default."},"acp_resume_session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Resume Session Id","description":"Optional explicit ACP session id to resume. When set, takes precedence over the id persisted in ``state.agent_state`` and is used to call ``session/load`` on the ACP server. Designed for environments where the per-conversation filesystem (and therefore ``base_state.json``) does not survive across restarts (e.g. cloud sandbox recycles), but the id has been mirrored into durable storage elsewhere. Falls back to a fresh session if the server cannot load the id. Treated as a secret on the wire — possession of the id is enough to resume the underlying ACP session, so default serialization redacts it; pass ``expose_secrets='plaintext'`` (trusted backend) or ``expose_secrets='encrypted'`` plus a cipher (frontend round-trip) when the value must cross a serialization boundary."},"acp_file_secrets":{"items":{"$ref":"#/components/schemas/ACPFileSecretSpec"},"type":"array","title":"Acp File Secrets","description":"Reserved 'file-content' credential secrets to materialise to disk before launching the subprocess (e.g. Codex auth.json, Gemini Vertex SA JSON). The SDK owns the mechanism (write the file in the runtime pod, set the env var, seed-if-absent); these specs are the policy. Defaults to the built-in supported providers; a downstream application may override or extend this to support other ACP servers with different file-auth schemes."},"acp_isolate_data_dir":{"type":"boolean","title":"Acp Isolate Data Dir","description":"Give the ACP subprocess a per-conversation CLI data/config root instead of the shared user ``HOME``. When True and the provider is recognised, point its data-dir env var (``CODEX_HOME`` / ``CLAUDE_CONFIG_DIR`` / ``HOME``; see ``ACPProviderInfo.data_dir_env_var``) at ``<persistence_dir>/acp/<provider>`` — the same per-conversation tree materialised file-secrets use. Required for correctness when several of a user's conversations share one sandbox (``SandboxGroupingStrategy != NO_GROUPING``), where they would otherwise race on one set of CLI auth/config/cache/lock files (see #1019). Off by default: with one sandbox per conversation the shared HOME is already private, and relocating it would hide a pre-existing interactive login. Downstream policy decides when to enable it; the SDK owns where the root lives.","default":false},"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."},"ACPAgentProfile":{"properties":{"schema_version":{"type":"integer","minimum":1.0,"title":"Schema Version","default":3},"agent_kind":{"type":"string","const":"acp","title":"Agent Kind","description":"Discriminator for the ``AgentProfile`` union. ``'acp'`` selects an ACP-delegating agent.","default":"acp"},"id":{"type":"string","format":"uuid","title":"Id","description":"Stable provenance handle for this profile. Conversations record this UUID; it never changes, even when the profile is renamed."},"name":{"type":"string","minLength":1,"title":"Name","description":"Human-facing, renameable key shown in the profile picker."},"revision":{"type":"integer","minimum":0.0,"title":"Revision","description":"Monotonic revision counter, bumped on each saved edit.","default":0},"mcp_server_refs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Mcp Server Refs","description":"Which of the user's globally configured MCP servers to expose. null = all; [] = none; a non-null list = filter to the named keys."},"secret_refs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Secret Refs","description":"Which of the user's saved secrets to expose to this agent. null = all; [] = none; a non-null list = filter to the named keys. Strict: nothing is added back. An ACP profile must list its own provider credential to receive it."},"acp_server":{"type":"string","enum":["claude-code","codex","gemini-cli","kimi-code","pi","opencode","custom"],"title":"Acp Server","description":"Which ACP-compatible backend to launch. The provider's credential env-var name is derived from this via the ACP_PROVIDERS registry.","default":"claude-code"},"acp_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Model","description":"Model identifier for the ACP server (e.g. 'claude-opus-4-8'). Leave blank to let the server pick its default."},"acp_session_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Session Mode","description":"Session mode ID (e.g. 'bypassPermissions'). Leave blank to auto-detect from the ACP server type."},"acp_prompt_timeout":{"type":"number","exclusiveMinimum":0.0,"title":"Acp Prompt Timeout","description":"Inactivity timeout (seconds) for a single ACP prompt() round-trip; resets on every update from the server.","default":1800.0},"acp_startup_timeout":{"type":"number","exclusiveMinimum":0.0,"title":"Acp Startup Timeout","description":"Timeout (seconds) for ACP server startup: spawn, initialize/authenticate, and new_session()/load_session().","default":90.0},"acp_command":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Command","description":"Optional explicit command to launch the ACP subprocess. Leave blank to use the default for ``acp_server``."},"acp_args":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Acp Args","description":"Additional arguments appended to the ACP server command."}},"additionalProperties":false,"type":"object","required":["name"],"title":"ACPAgentProfile","description":"``agent_kind=\"acp\"`` profile — names an ACP backend, stores no credential.\n\nThere is no ``llm_profile_ref`` and no embedded credential: the ACP\nsubprocess makes its own model calls, and the provider's credential\n(env-var name) is derived from :attr:`acp_server` via the\n:data:`~openhands.sdk.settings.acp_providers.ACP_PROVIDERS` registry. The\nvalue rides the conversation secrets channel, never the profile."},"ACPAgentSettings":{"properties":{"schema_version":{"type":"integer","minimum":1.0,"title":"Schema Version","default":8},"agent_kind":{"type":"string","const":"acp","title":"Agent Kind","description":"Discriminator for the ``AgentSettings`` union. ``'acp'`` selects an ACP-delegating agent.","default":"acp"},"acp_server":{"type":"string","enum":["claude-code","codex","gemini-cli","kimi-code","pi","opencode","custom"],"title":"Acp Server","description":"Which ACP-compatible backend to launch. Each choice maps to a default subprocess command (see ``acp_command`` to override).","default":"claude-code","openhands_settings":{"depends_on":[],"label":"ACP server","prominence":"critical"},"openhands_settings_section":{"key":"acp","label":"ACP (Agent Client Protocol)","variant":"acp"}},"acp_command":{"items":{"type":"string"},"type":"array","title":"Acp Command","description":"Optional explicit command to launch the ACP subprocess. Leave empty to use the default for :attr:`acp_server` (e.g. ``npx -y @agentclientprotocol/claude-agent-acp`` for ``claude-code``). Must be set when :attr:`acp_server` is ``'custom'``.","openhands_settings":{"depends_on":[],"label":"ACP command (custom override)","prominence":"minor"},"openhands_settings_section":{"key":"acp","label":"ACP (Agent Client Protocol)","variant":"acp"}},"acp_args":{"items":{"type":"string"},"type":"array","title":"Acp Args","description":"Additional arguments appended to the ACP server command.","openhands_settings":{"depends_on":[],"label":"ACP extra args","prominence":"minor"},"openhands_settings_section":{"key":"acp","label":"ACP (Agent Client Protocol)","variant":"acp"}},"acp_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Model","description":"Model identifier for the ACP server to use (e.g. ``'sonnet'`` or ``'gpt-5.5'``). Applied via the protocol — set_config_option(model) for configOptions-based servers (codex, claude), else set_session_model. Leave blank to let the server pick its default.","openhands_settings":{"depends_on":[],"label":"ACP model","prominence":"critical"},"openhands_settings_section":{"key":"acp","label":"ACP (Agent Client Protocol)","variant":"acp"}},"acp_session_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Session Mode","description":"Session mode ID (e.g. ``bypassPermissions``). Leave blank to auto-detect from the ACP server type.","openhands_settings":{"depends_on":[],"label":"ACP session mode","prominence":"minor"},"openhands_settings_section":{"key":"acp","label":"ACP (Agent Client Protocol)","variant":"acp"}},"acp_prompt_timeout":{"type":"number","exclusiveMinimum":0.0,"title":"Acp Prompt Timeout","description":"Inactivity timeout (seconds) for a single ACP prompt() round-trip. The deadline resets on every update from the ACP server, so a steadily-progressing agent keeps running; the prompt is only aborted after this many seconds with no activity at all.","default":1800.0,"openhands_settings":{"depends_on":[],"label":"ACP prompt inactivity timeout (seconds)","prominence":"minor"},"openhands_settings_section":{"key":"acp","label":"ACP (Agent Client Protocol)","variant":"acp"}},"acp_startup_timeout":{"type":"number","exclusiveMinimum":0.0,"title":"Acp Startup Timeout","description":"Timeout (seconds) for ACP server startup: spawning the subprocess, the initialize/authenticate handshake, and new_session()/load_session(). A hard deadline, unlike acp_prompt_timeout, since startup has no intermediate progress signal to reset it against.","default":90.0,"openhands_settings":{"depends_on":[],"label":"ACP startup timeout (seconds)","prominence":"minor"},"openhands_settings_section":{"key":"acp","label":"ACP (Agent Client Protocol)","variant":"acp"}},"mcp_config":{"additionalProperties":{"$ref":"#/components/schemas/MCPServer-Input"},"type":"object","title":"Mcp Config","description":"MCP servers to make available to the ACP subprocess. Unlike the OpenHands agent — where these become in-process MCP tools — the servers are forwarded to the ACP server at session creation and it owns the connection. Remote (http/sse) servers are only forwarded when the ACP server advertises support for that transport; stdio servers (which run inside the runtime) are always forwarded.","openhands_settings":{"depends_on":[],"label":"MCP servers","prominence":"minor","variant":"acp"}},"acp_isolate_data_dir":{"type":"boolean","title":"Acp Isolate Data Dir","description":"Give the ACP subprocess a per-conversation CLI data/config root instead of the shared user HOME. Forwarded to :attr:`~openhands.sdk.agent.ACPAgent.acp_isolate_data_dir`; off by default. Enable from the deploying application when several conversations share one sandbox (see #1019).","default":false},"acp_file_secrets":{"items":{"$ref":"#/components/schemas/ACPFileSecretSpec"},"type":"array","title":"Acp File Secrets","description":"Reserved 'file-content' credential secrets the SDK materialises to disk before launching the ACP subprocess (e.g. Codex auth.json, Gemini Vertex SA JSON). Defaults to the built-in supported providers; override to support other ACP servers with different file-auth schemes."},"llm":{"$ref":"#/components/schemas/LLM-Input","description":"Deprecated since v1.51.0 and scheduled for removal in v1.56.0. Ignored and not serialized: the ACP subprocess makes its own model calls and ``acp_model`` is the model identity. Route provider credentials through the conversation secrets channel, keyed by the provider's env var name.","deprecated":true},"agent_context":{"anyOf":[{"$ref":"#/components/schemas/AgentContext-Input"},{"type":"null"}],"description":"Prompt-only context for the ACP server. ``secrets`` here are advertised to the agent (names/descriptions) and reach the subprocess env through ``state.secret_registry``: ``LocalConversation`` seeds ``agent_context.secrets`` into the registry at conversation init (below ``request.secrets``), so callers that build the request outside Python (e.g. canvas-local) are covered too, not just the ``create_request`` path. Provider credentials belong here (or in ``request.secrets``) keyed by the provider's env var name."}},"type":"object","title":"ACPAgentSettings","description":"Settings for an ACP (Agent Client Protocol) agent.\n\n``create_agent()`` returns an :class:`ACPAgent` that delegates to a\nsubprocess ACP server.  The ACP server manages its own system prompt,\ntools, MCP, and (primary) LLM calls; those fields from\n:class:`OpenHandsAgentSettings` do not apply here.\n\n:attr:`acp_model` is the model identity. The created ``ACPAgent`` keeps its\nown metrics LLM, so title generation can tell it is never callable.\nProvider credentials ride the conversation secrets channel\n(``request.secrets`` / ``agent_context.secrets`` → ``state.secret_registry``)\nkeyed by the provider's env var name (:attr:`api_key_env_var`)."},"ACPFileSecretSpec":{"properties":{"secret_name":{"type":"string","minLength":1,"title":"Secret Name"},"filename":{"type":"string","minLength":1,"title":"Filename"},"env_var":{"type":"string","minLength":1,"title":"Env Var"},"subdir":{"type":"string","minLength":1,"title":"Subdir"},"env_points_to":{"type":"string","enum":["dir","file"],"title":"Env Points To","default":"file"},"warn_if_unset":{"items":{"type":"string"},"type":"array","title":"Warn If Unset","default":[]}},"type":"object","required":["secret_name","filename","env_var","subdir"],"title":"ACPFileSecretSpec","description":"Declarative mapping from a reserved \"file-content\" secret to a credential\nfile the ACP subprocess authenticates from.\n\nSome providers read their credential from a *file on disk* rather than an\nenv var: Codex reads ``$CODEX_HOME/auth.json``; Gemini (Vertex AI) reads a\nservice-account JSON pointed at by ``GOOGLE_APPLICATION_CREDENTIALS``. The\nuser supplies that credential as a pasted blob — a reserved secret named\n:attr:`secret_name` — and :class:`~openhands.sdk.agent.ACPAgent` materialises\nit to :attr:`filename` under the conversation's durable per-conversation root\n(seed-if-absent), then sets :attr:`env_var` so the CLI can find it.\n\nMaterialisation is keyed off :attr:`secret_name` (not the launch command),\nso a custom or aliased ``acp_command`` still works as long as the reserved\nsecret is supplied.\n\nThe SDK owns the *mechanism* (writing the file in the runtime pod, setting\nthe env var, seed-if-absent, permissions); the *policy* — which secrets map\nto which files for which CLIs — lives in these specs. Built-in defaults\ncover the supported providers, but downstream applications can override\n:attr:`~openhands.sdk.agent.ACPAgent.acp_file_secrets` to support other ACP\nservers with different file-auth schemes without an SDK change."},"ACPModelDiscovery":{"properties":{"agent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Name","description":"Server name from ``initialize``."},"agent_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Version","description":"Server version from ``initialize``."},"current_model_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Model Id","description":"Model the server picks when none is requested — its own default for the given credentials. May be an opaque alias such as ``\"default\"``; match it against ``available_models`` for a label."},"available_models":{"items":{"$ref":"#/components/schemas/ACPModelInfo"},"type":"array","title":"Available Models","description":"Models the server offers for the given credentials. Empty when the server does not report any."},"supports_runtime_model_switch":{"type":"boolean","title":"Supports Runtime Model Switch","description":"Whether a conversation can switch among these models live.","default":false},"error":{"anyOf":[{"$ref":"#/components/schemas/ACPModelDiscoveryError"},{"type":"null"}],"description":"Set when the server could not start a session."}},"type":"object","title":"ACPModelDiscovery","description":"What an ACP server reports for a fresh session, before any conversation."},"ACPModelDiscoveryError":{"properties":{"code":{"type":"string","title":"Code","description":"Same codes as a conversation's cold-start ``ConversationErrorEvent``: ``ACPAuthRequired``, ``ACPStartupTimeout``, ``ACPSpawnError`` or ``ACPInitError``."},"detail":{"type":"string","title":"Detail","description":"Human-readable, secret-free cause."}},"type":"object","required":["code","detail"],"title":"ACPModelDiscoveryError","description":"Why an ACP server could not report its models."},"ACPModelDiscoveryRequest":{"properties":{"agent_settings":{"$ref":"#/components/schemas/ACPAgentSettings","description":"The ACP agent to ask. Only the launch fields are used; ``acp_model``, MCP servers and agent context are ignored."},"secrets":{"additionalProperties":{"$ref":"#/components/schemas/SecretSource-Input"},"type":"object","title":"Secrets","description":"Credentials for the server, in the same shape as a conversation start request's ``secrets`` (typically ``LookupSecret`` references to this server's stored secrets)."},"refresh":{"type":"boolean","title":"Refresh","description":"Ask the server again instead of reusing a result.","default":false}},"type":"object","required":["agent_settings"],"title":"ACPModelDiscoveryRequest"},"ACPModelInfo":{"properties":{"model_id":{"type":"string","title":"Model Id","description":"Server-assigned model identifier. May be concrete (e.g. ``\"gpt-5.6\"``) or an opaque alias (e.g. ``\"default\"``, ``\"auto\"``). This is the value to pass back to the server to switch to this model."},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Human-readable label, e.g. ``\"GPT-5.5\"``."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional longer description supplied by the server."}},"type":"object","required":["model_id"],"title":"ACPModelInfo","description":"One model an ACP server offers for a session.\n\nA normalized, stable mirror of the ACP protocol's ``ModelInfo``. The\nprotocol ``models`` capability is flagged **UNSTABLE**, so we re-map it\ninto our own type at the SDK boundary rather than re-serializing the\nvendored ``acp.schema`` type onto the agent-server's public API — clients\nget a stable shape regardless of upstream protocol churn.\n\nCarries everything a client needs to render a picker and resolve a\n``current_model_id`` to a display label *itself*; the SDK deliberately\ndoes no name curation."},"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":["agent","user","environment","hook"],"title":"Source","default":"agent"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"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"},"content":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Content"},"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`` — 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://llm-proxy.app.all-hands.dev/vllm"},"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"},"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."},"issue_threshold":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Issue Threshold","description":"APIBasedCritic-specific probability threshold for agent issue labels that should trigger iterative refinement.","default":0.75},"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://llm-proxy.app.all-hands.dev/vllm"},"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"},"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."},"issue_threshold":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Issue Threshold","description":"APIBasedCritic-specific probability threshold for agent issue labels that should trigger iterative refinement.","default":0.75},"kind":{"type":"string","const":"APIBasedCritic","title":"Kind"}},"type":"object","required":["api_key","kind"],"title":"APIBasedCritic"},"Action":{"oneOf":[{"$ref":"#/components/schemas/MCPToolAction"},{"$ref":"#/components/schemas/ClassifyAndSwitchLLMAction"},{"$ref":"#/components/schemas/FinishAction"},{"$ref":"#/components/schemas/InvokeSkillAction"},{"$ref":"#/components/schemas/SwitchLLMAction"},{"$ref":"#/components/schemas/ThinkAction"},{"$ref":"#/components/schemas/VisionInspectAction"},{"$ref":"#/components/schemas/AskOracleAction"},{"$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/TaskAction"},{"$ref":"#/components/schemas/TaskTrackerAction"},{"$ref":"#/components/schemas/TerminalAction"},{"$ref":"#/components/schemas/WorkflowAction"}],"discriminator":{"propertyName":"kind","mapping":{"openhands__sdk__mcp__definition__MCPToolAction-Output__1":"#/components/schemas/MCPToolAction","openhands__sdk__tool__builtins__classify_and_switch_llm__ClassifyAndSwitchLLMAction-Output__1":"#/components/schemas/ClassifyAndSwitchLLMAction","openhands__sdk__tool__builtins__finish__FinishAction-Output__1":"#/components/schemas/FinishAction","openhands__sdk__tool__builtins__invoke_skill__InvokeSkillAction-Output__1":"#/components/schemas/InvokeSkillAction","openhands__sdk__tool__builtins__switch_llm__SwitchLLMAction-Output__1":"#/components/schemas/SwitchLLMAction","openhands__sdk__tool__builtins__think__ThinkAction-Output__1":"#/components/schemas/ThinkAction","openhands__sdk__tool__builtins__vision_inspect__VisionInspectAction-Output__1":"#/components/schemas/VisionInspectAction","openhands__tools__ask_oracle__definition__AskOracleAction-Output__1":"#/components/schemas/AskOracleAction","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__definition__TaskAction-Output__1":"#/components/schemas/TaskAction","openhands__tools__task_tracker__definition__TaskTrackerAction-Output__1":"#/components/schemas/TaskTrackerAction","openhands__tools__terminal__definition__TerminalAction-Output__1":"#/components/schemas/TerminalAction","openhands__tools__workflow__definition__WorkflowAction-Output__1":"#/components/schemas/WorkflowAction"}}},"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"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"},"ActivateAgentProfileResponse":{"properties":{"id":{"type":"string","title":"Id"},"message":{"type":"string","title":"Message"},"agent_settings_applied":{"type":"boolean","title":"Agent Settings Applied","default":false}},"type":"object","required":["id","message"],"title":"ActivateAgentProfileResponse"},"ActivateMetaProfileResponse":{"properties":{"name":{"type":"string","title":"Name"},"message":{"type":"string","title":"Message"}},"type":"object","required":["name","message"],"title":"ActivateMetaProfileResponse"},"ActivateProfileResponse":{"properties":{"name":{"type":"string","title":"Name"},"message":{"type":"string","title":"Message"},"llm_applied":{"type":"boolean","title":"Llm Applied","default":true}},"type":"object","required":["name","message"],"title":"ActivateProfileResponse","description":"Response model for profile activation."},"AddWorkspaceParentsRequest":{"properties":{"parents":{"items":{"$ref":"#/components/schemas/WorkspaceParentItem"},"type":"array","title":"Parents"}},"type":"object","required":["parents"],"title":"AddWorkspaceParentsRequest"},"AddWorkspacesRequest":{"properties":{"workspaces":{"items":{"$ref":"#/components/schemas/WorkspaceItem"},"type":"array","title":"Workspaces"}},"type":"object","required":["workspaces"],"title":"AddWorkspacesRequest"},"Agent-Input":{"properties":{"llm":{"$ref":"#/components/schemas/LLM-Input","description":"LLM configuration for the agent.","examples":[{"api_key":"<redacted:api_key>","base_url":"https://llm-proxy.eval.all-hands.dev","model":"litellm_proxy/openai/gpt-5.5"}]},"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":{"$ref":"#/components/schemas/MCPServer-Input"},"type":"object","title":"Mcp Config","description":"Optional MCP servers to expose as tools.","examples":[{"fetch":{"args":["--with","mcp==1.29.0","mcp-server-fetch==2026.7.10"],"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":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt","description":"Inline system prompt string.  When provided, the agent uses this text verbatim as the system message instead of rendering from `system_prompt_filename`.  Mutually exclusive with a non-default `system_prompt_filename`.\n\n**Warning**: This is not recommended unless you know what you are doing (e.g. customising agent behaviour for a completely different task).  Setting this will override OpenHands' built-in system instructions that govern default agent behaviour."},"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 filename. The default 'security_policy.j2' is a back-compat sentinel (the file was removed) that selects the built-in default policy from the prompt registry -- it is not loaded from disk. Any other value names a custom policy file whose contents are inserted verbatim (NOT rendered as a Jinja template). Can be either:\n- A relative filename (e.g., 'custom_security_policy.md') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.md')\n- Empty string to disable security policy","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":"<redacted:api_key>","base_url":"https://llm-proxy.eval.all-hands.dev","model":"litellm_proxy/openai/gpt-5.5"},"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"}]},"tool_concurrency_limit":{"type":"integer","minimum":1.0,"title":"Tool Concurrency Limit","description":"Maximum number of tool calls to execute concurrently within a single agent step. Default is 1 (sequential). Values > 1 enable parallel execution; concurrent tools share the conversation object, filesystem, and working directory, so mutations to shared state may race.","default":1},"persona":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persona","description":"Persona text that replaces OpenHands' built-in persona and coding-workflow sections of the system prompt. Capability and policy sections (memory, security policy, risk assessment, browser, external services, process management, model-specific guidance) and the dynamic context still apply. Ignored when `system_prompt` is set; a custom template receives it as the `persona` kwarg."},"kind":{"type":"string","const":"Agent","title":"Kind"}},"type":"object","required":["llm"],"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    system_prompt: Inline system prompt string. When provided the agent\n        uses this text verbatim instead of rendering from a template.\n        Mutually exclusive with a non-default ``system_prompt_filename``.\n        **Not recommended** unless you know what you are doing (e.g.\n        customising agent behaviour for a completely different task) —\n        this will override OpenHands' built-in system instructions.\n    system_prompt_filename: Jinja2 template filename resolved relative to\n        the agent's prompts directory, or an absolute path. Defaults to\n        ``\"system_prompt.j2\"``.\n    system_prompt_kwargs: Extra kwargs forwarded to the Jinja2 template.\n\nExample:\n    ```python\n    from openhands.sdk import LLM, Agent, Tool\n    from pydantic import SecretStr\n\n    llm = LLM(model=\"gpt-5.6\", api_key=SecretStr(\"key\"))\n    tools = [Tool(name=\"TerminalTool\"), Tool(name=\"FileEditorTool\")]\n    agent = Agent(llm=llm, tools=tools)\n    ```\n\n    To override the system prompt entirely::\n\n        agent = Agent(\n            llm=llm,\n            tools=tools,\n            system_prompt=\"You are a helpful coding assistant.\",\n        )"},"Agent-Output":{"properties":{"llm":{"$ref":"#/components/schemas/LLM-Output","description":"LLM configuration for the agent.","examples":[{"api_key":"<redacted:api_key>","base_url":"https://llm-proxy.eval.all-hands.dev","model":"litellm_proxy/openai/gpt-5.5"}]},"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":{"$ref":"#/components/schemas/MCPServer-Output"},"type":"object","title":"Mcp Config","description":"Optional MCP servers to expose as tools.","examples":[{"fetch":{"args":["--with","mcp==1.29.0","mcp-server-fetch==2026.7.10"],"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-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":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt","description":"Inline system prompt string.  When provided, the agent uses this text verbatim as the system message instead of rendering from `system_prompt_filename`.  Mutually exclusive with a non-default `system_prompt_filename`.\n\n**Warning**: This is not recommended unless you know what you are doing (e.g. customising agent behaviour for a completely different task).  Setting this will override OpenHands' built-in system instructions that govern default agent behaviour."},"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 filename. The default 'security_policy.j2' is a back-compat sentinel (the file was removed) that selects the built-in default policy from the prompt registry -- it is not loaded from disk. Any other value names a custom policy file whose contents are inserted verbatim (NOT rendered as a Jinja template). Can be either:\n- A relative filename (e.g., 'custom_security_policy.md') loaded from the agent's prompts directory\n- An absolute path (e.g., '/path/to/custom_security_policy.md')\n- Empty string to disable security policy","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":"<redacted:api_key>","base_url":"https://llm-proxy.eval.all-hands.dev","model":"litellm_proxy/openai/gpt-5.5"},"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"}]},"tool_concurrency_limit":{"type":"integer","minimum":1.0,"title":"Tool Concurrency Limit","description":"Maximum number of tool calls to execute concurrently within a single agent step. Default is 1 (sequential). Values > 1 enable parallel execution; concurrent tools share the conversation object, filesystem, and working directory, so mutations to shared state may race.","default":1},"persona":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Persona","description":"Persona text that replaces OpenHands' built-in persona and coding-workflow sections of the system prompt. Capability and policy sections (memory, security policy, risk assessment, browser, external services, process management, model-specific guidance) and the dynamic context still apply. Ignored when `system_prompt` is set; a custom template receives it as the `persona` kwarg."},"kind":{"type":"string","const":"Agent","title":"Kind"}},"type":"object","required":["llm","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\nAttributes:\n    llm: The language model instance used for reasoning.\n    tools: List of tools available to the agent.\n    system_prompt: Inline system prompt string. When provided the agent\n        uses this text verbatim instead of rendering from a template.\n        Mutually exclusive with a non-default ``system_prompt_filename``.\n        **Not recommended** unless you know what you are doing (e.g.\n        customising agent behaviour for a completely different task) —\n        this will override OpenHands' built-in system instructions.\n    system_prompt_filename: Jinja2 template filename resolved relative to\n        the agent's prompts directory, or an absolute path. Defaults to\n        ``\"system_prompt.j2\"``.\n    system_prompt_kwargs: Extra kwargs forwarded to the Jinja2 template.\n\nExample:\n    ```python\n    from openhands.sdk import LLM, Agent, Tool\n    from pydantic import SecretStr\n\n    llm = LLM(model=\"gpt-5.6\", api_key=SecretStr(\"key\"))\n    tools = [Tool(name=\"TerminalTool\"), Tool(name=\"FileEditorTool\")]\n    agent = Agent(llm=llm, tools=tools)\n    ```\n\n    To override the system prompt entirely::\n\n        agent = Agent(\n            llm=llm,\n            tools=tools,\n            system_prompt=\"You are a helpful coding assistant.\",\n        )"},"AgentBase-Input":{"oneOf":[{"$ref":"#/components/schemas/ACPAgent-Input"},{"$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/ACPAgent-Output"},{"$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-Input"},"type":"array","title":"Skills","description":"List of available skills that can extend the user's input.","acp_compatible":true},"system_message_suffix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Message Suffix","description":"Optional suffix to append to the system prompt.","acp_compatible":true},"user_message_suffix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Message Suffix","description":"Optional suffix to append to the user's message.","acp_compatible":true},"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,"acp_compatible":true},"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/<redacted:unrelated-repository>. This allows you to get the latest skills without SDK updates.","default":false,"acp_compatible":true},"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","acp_compatible":true},"registered_marketplaces":{"items":{"$ref":"#/components/schemas/MarketplaceRegistration"},"type":"array","title":"Registered Marketplaces","description":"Marketplace registrations for plugin resolution. Registrations with auto_load=True or a list of plugin names are resolved by LocalConversation at startup.","acp_compatible":true},"load_project_skills":{"type":"boolean","title":"Load Project Skills","description":"Whether to automatically load project skills from the conversation workspace (e.g. .openhands/skills/, AGENTS.md). Unlike load_user_skills / load_public_skills, this flag is not resolved by AgentContext itself (the workspace path is unknown at validation time); LocalConversation resolves it lazily on the first send_message() / run(), when the workspace is known. Also unlike load_user_skills / load_public_skills (which yield to explicit skills on a name conflict), resolved project skills are authoritative: a project skill overrides a same-named skill already present in `skills`.","default":false,"acp_compatible":true},"load_memory":{"type":"boolean","title":"Load Memory","description":"Whether to load persistent agent memory (MEMORY.md indexes under ~/.openhands/memory/ and <workspace>/.openhands/memory/) into the system prompt. Like load_project_skills, this flag is not resolved by AgentContext itself (the workspace path is unknown at validation time); LocalConversation resolves it lazily on the first send_message() / run() and stores the result in memory_context.","default":false,"acp_compatible":true,"openhands_settings":{"depends_on":[],"label":"Persistent memory","prominence":"major"}},"memory_context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Memory Context","description":"Resolved memory-index text rendered into the <MEMORY_CONTEXT> prompt block. Populated via model_copy by LocalConversation when load_memory is set; excluded from serialization because it is re-resolved from disk each session and must not bloat persisted conversation state.","acp_compatible":true},"disabled_skills":{"items":{"type":"string"},"type":"array","title":"Disabled Skills","description":"Names of skills to EXCLUDE from this context — a deny-list applied after every skill source is loaded (auto-loaded user/public, explicit, and lazily-loaded project skills). A listed name absent from the loaded set is a harmless no-op. [] (the default) keeps every skill. This is the single, drift-tolerant skill-selection mechanism (agent profiles set it from their own deny-list; #4017).","acp_compatible":true},"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).","acp_compatible":true},"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 (timezone-aware) datetime.","acp_compatible":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’s 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-Output"},"type":"array","title":"Skills","description":"List of available skills that can extend the user's input.","acp_compatible":true},"system_message_suffix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Message Suffix","description":"Optional suffix to append to the system prompt.","acp_compatible":true},"user_message_suffix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Message Suffix","description":"Optional suffix to append to the user's message.","acp_compatible":true},"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,"acp_compatible":true},"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/<redacted:unrelated-repository>. This allows you to get the latest skills without SDK updates.","default":false,"acp_compatible":true},"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","acp_compatible":true},"registered_marketplaces":{"items":{"$ref":"#/components/schemas/MarketplaceRegistration"},"type":"array","title":"Registered Marketplaces","description":"Marketplace registrations for plugin resolution. Registrations with auto_load=True or a list of plugin names are resolved by LocalConversation at startup.","acp_compatible":true},"load_project_skills":{"type":"boolean","title":"Load Project Skills","description":"Whether to automatically load project skills from the conversation workspace (e.g. .openhands/skills/, AGENTS.md). Unlike load_user_skills / load_public_skills, this flag is not resolved by AgentContext itself (the workspace path is unknown at validation time); LocalConversation resolves it lazily on the first send_message() / run(), when the workspace is known. Also unlike load_user_skills / load_public_skills (which yield to explicit skills on a name conflict), resolved project skills are authoritative: a project skill overrides a same-named skill already present in `skills`.","default":false,"acp_compatible":true},"load_memory":{"type":"boolean","title":"Load Memory","description":"Whether to load persistent agent memory (MEMORY.md indexes under ~/.openhands/memory/ and <workspace>/.openhands/memory/) into the system prompt. Like load_project_skills, this flag is not resolved by AgentContext itself (the workspace path is unknown at validation time); LocalConversation resolves it lazily on the first send_message() / run() and stores the result in memory_context.","default":false,"acp_compatible":true,"openhands_settings":{"depends_on":[],"label":"Persistent memory","prominence":"major"}},"disabled_skills":{"items":{"type":"string"},"type":"array","title":"Disabled Skills","description":"Names of skills to EXCLUDE from this context — a deny-list applied after every skill source is loaded (auto-loaded user/public, explicit, and lazily-loaded project skills). A listed name absent from the loaded set is a harmless no-op. [] (the default) keeps every skill. This is the single, drift-tolerant skill-selection mechanism (agent profiles set it from their own deny-list; #4017).","acp_compatible":true},"secrets":{"anyOf":[{"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).","acp_compatible":true},"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 (timezone-aware) datetime.","acp_compatible":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’s 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)"},"description":{"type":"string","title":"Description","description":"Agent description","default":""},"model":{"type":"string","title":"Model","description":"Model to use ('inherit' uses parent model)","default":"inherit"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color","description":"Display color for the agent"},"tools":{"items":{"type":"string"},"type":"array","title":"Tools","description":"List of allowed tools for this agent"},"skills":{"items":{"type":"string"},"type":"array","title":"Skills","description":"List of skill names for this agent. Resolved from project/user directories."},"system_prompt":{"type":"string","title":"System Prompt","description":"System prompt content","default":""},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"Source file path for this agent"},"level":{"anyOf":[{"type":"string","enum":["project","user","builtin","plugin","programmatic"]},{"type":"null"}],"title":"Level","description":"Scope where the agent was discovered. Set during discovery; None when loaded directly from a file."},"when_to_use_examples":{"items":{"type":"string"},"type":"array","title":"When To Use Examples","description":"Examples of when to use this agent (for triggering)"},"hooks":{"anyOf":[{"$ref":"#/components/schemas/HookConfig"},{"type":"null"}],"description":"Hook configuration for this agent"},"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."},"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."},"max_budget_per_run":{"anyOf":[{"type":"number","exclusiveMinimum":0.0},{"type":"null"}],"title":"Max Budget Per Run","description":"Maximum accumulated cost (USD) per run for this sub-agent. Must be strictly positive, or None for no budget."},"mcp_config":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/MCPServer-Input"},"type":"object"},{"type":"null"}],"title":"Mcp Config","description":"MCP servers for this agent.","examples":[{"fetch":{"args":["--with","mcp==1.29.0","mcp-server-fetch==2026.7.10"],"command":"uvx"}}]},"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."},"condenser":{"anyOf":[{"$ref":"#/components/schemas/CondenserBase-Input"},{"type":"null"}],"description":"Context condenser for the sub-agent. None applies a default summarizing condenser; set a NoOpCondenser to disable condensation."},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","description":"Additional metadata from frontmatter"}},"type":"object","required":["name"],"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."},"AgentErrorEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"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"},"classification":{"anyOf":[{"$ref":"#/components/schemas/ErrorClassification"},{"type":"null"}],"description":"Safe structured error semantics for API consumers."},"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"],"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":"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"],"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":"AgentFinishedCritic","title":"Kind"}},"type":"object","required":["kind"],"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)"},"AgentLaunchAdditions":{"properties":{"system_message_suffix_append":{"anyOf":[{"type":"string","maxLength":32768},{"type":"null"}],"title":"System Message Suffix Append","description":"Deployment-controlled text appended to the resolved agent's system-message suffix."}},"additionalProperties":false,"type":"object","title":"AgentLaunchAdditions","description":"Add deployment context after agent resolution."},"AgentProfileDetailResponse":{"properties":{"name":{"type":"string","title":"Name"},"profile":{"additionalProperties":true,"type":"object","title":"Profile"}},"type":"object","required":["name","profile"],"title":"AgentProfileDetailResponse"},"AgentProfileDiagnostics":{"properties":{"agent_kind":{"type":"string","title":"Agent Kind"},"valid":{"type":"boolean","title":"Valid","default":false},"errors":{"items":{"type":"string"},"type":"array","title":"Errors"},"unusable_tools":{"items":{"type":"string"},"type":"array","title":"Unusable Tools","description":"Selected tools the runtime cannot run. An unavailable browser is left out of the launch; any other such tool fails the launch or fails when the agent uses it."},"llm_profile_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Profile Ref"},"llm_profile_resolved":{"type":"boolean","title":"Llm Profile Resolved","default":false},"llm_api_key_set":{"type":"boolean","title":"Llm Api Key Set","default":false},"mcp_server_refs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Mcp Server Refs"},"resolved_mcp_config_keys":{"items":{"type":"string"},"type":"array","title":"Resolved Mcp Config Keys"},"dangling_mcp_server_refs":{"items":{"type":"string"},"type":"array","title":"Dangling Mcp Server Refs"},"disabled_skills":{"items":{"type":"string"},"type":"array","title":"Disabled Skills"},"resolved_skills":{"items":{"type":"string"},"type":"array","title":"Resolved Skills"},"secret_refs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Secret Refs"},"acp_api_key_secret_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Api Key Secret Name"},"acp_base_url_secret_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acp Base Url Secret Name"},"acp_file_secret_names":{"items":{"type":"string"},"type":"array","title":"Acp File Secret Names"},"meta_profile_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Meta Profile Ref"},"dangling_meta_profile_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dangling Meta Profile Ref"},"dangling_meta_profile_llm_refs":{"items":{"type":"string"},"type":"array","title":"Dangling Meta Profile Llm Refs"},"resolved_settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Resolved Settings"}},"type":"object","required":["agent_kind"],"title":"AgentProfileDiagnostics","description":"Side-effect-free report of what :func:`resolve_agent_profile` would do.\n\nConsumed by ``POST /{id}/materialize`` (#3719) and the canvas editor. The\nverdict (:attr:`valid`) and the dangling-ref lists match exactly what a real\nresolve produces; :attr:`resolved_settings` is the redacted settings dump\n(present only when :attr:`valid`)."},"AgentProfileInfo":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name"},"agent_kind":{"type":"string","title":"Agent Kind","default":"openhands"},"revision":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Revision"},"llm_profile_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Profile Ref"},"mcp_server_refs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Mcp Server Refs"}},"type":"object","required":["name"],"title":"AgentProfileInfo","description":"Summary projection of a stored profile (no secret instantiation)."},"AgentProfileListResponse":{"properties":{"profiles":{"items":{"$ref":"#/components/schemas/AgentProfileInfo"},"type":"array","title":"Profiles"},"active_agent_profile_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Agent Profile Id"}},"type":"object","required":["profiles"],"title":"AgentProfileListResponse"},"AgentProfileMutationResponse":{"properties":{"name":{"type":"string","title":"Name"},"message":{"type":"string","title":"Message"}},"type":"object","required":["name","message"],"title":"AgentProfileMutationResponse"},"AgentResponseResult":{"properties":{"response":{"type":"string","title":"Response","description":"The agent's final response text. Extracted from either a FinishAction message or the last agent MessageEvent. Empty string if no final response is available."}},"type":"object","required":["response"],"title":"AgentResponseResult","description":"The agent's final response for a conversation.\n\nContains the text of the last agent finish message or text response.\nEmpty string if the agent has not produced a final response yet."},"AlwaysConfirm-Input":{"properties":{"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"},"Annotation":{"properties":{"type":{"type":"string","const":"url_citation","title":"Type"},"url_citation":{"$ref":"#/components/schemas/AnnotationURLCitation"}},"additionalProperties":true,"type":"object","required":["type","url_citation"],"title":"Annotation","description":"A URL citation when using web search."},"AnnotationURLCitation":{"properties":{"end_index":{"type":"integer","title":"End Index"},"start_index":{"type":"integer","title":"Start Index"},"title":{"type":"string","title":"Title"},"url":{"type":"string","title":"Url"}},"additionalProperties":true,"type":"object","required":["end_index","start_index","title","url"],"title":"AnnotationURLCitation","description":"A URL citation when using web search."},"AppBackendSessionResponse":{"properties":{"ingress_url":{"type":"string","title":"Ingress Url"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"iframe_sandbox":{"type":"string","title":"Iframe Sandbox","default":"allow-forms allow-modals allow-popups allow-same-origin allow-scripts"}},"type":"object","required":["ingress_url","expires_at"],"title":"AppBackendSessionResponse","description":"Browser bootstrap result for one running Canvas App backend.\n\nThe session credential is delivered only as an HttpOnly cookie. ``ingress_url``\ncontains no credential and must be loaded from a separate browser origin. That\norigin is the isolation boundary, so frames retain their origin for cookies,\nworkers, WebSockets, and Origin-based request validation."},"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."},"AskOracleAction":{"properties":{"question":{"type":"string","title":"Question","description":"The specific question or dilemma to ask the Oracle about. Use this when you are stuck, uncertain, or need a second opinion."},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context","description":"Optional extra context, such as approaches already tried, constraints, or the recommendation you are considering."},"kind":{"type":"string","const":"AskOracleAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["question","kind"],"title":"AskOracleAction","description":"Action for asking the Oracle for advice."},"AskOracleObservation":{"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},"kind":{"type":"string","const":"AskOracleObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"AskOracleObservation","description":"Observation returned by the Oracle consultation."},"AskOracleTool":{"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":{"type":"string","const":"AskOracleTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"AskOracleTool","description":"Tool for consulting the Oracle (a saved LLM profile named \"oracle\")."},"BackendLogs":{"properties":{"name":{"type":"string","title":"Name"},"logs":{"type":"string","title":"Logs"},"truncated":{"type":"boolean","title":"Truncated"}},"type":"object","required":["name","logs","truncated"],"title":"BackendLogs","description":"Bounded combined stdout and stderr output."},"BackendRevisionRequest":{"properties":{"revision":{"type":"string","minLength":1,"title":"Revision"}},"type":"object","required":["revision"],"title":"BackendRevisionRequest","description":"Explicit approval for one exact installed revision."},"BackendStatus":{"properties":{"name":{"type":"string","title":"Name"},"state":{"type":"string","enum":["missing","stopped","starting","ready","unhealthy","unsupported"],"title":"State"},"revision":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revision"},"prepared_revision":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prepared Revision"},"pid":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Pid"},"port":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Port"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["name","state"],"title":"BackendStatus","description":"Current state of an installed Canvas App backend."},"BaseWorkspace":{"oneOf":[{"$ref":"#/components/schemas/LocalWorkspace-Output"},{"$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"},"cwd":{"anyOf":[{"type":"string"},{"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},"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"},"BashError":{"properties":{"id":{"type":"string","title":"Id"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"code":{"type":"string","title":"Code","description":"Code for the error - typically an error type"},"detail":{"type":"string","title":"Detail","description":"Details about the error"},"kind":{"type":"string","const":"BashError","title":"Kind"}},"type":"object","required":["code","detail","kind"],"title":"BashError"},"BashEventBase":{"oneOf":[{"$ref":"#/components/schemas/BashCommand"},{"$ref":"#/components/schemas/BashError"},{"$ref":"#/components/schemas/BashOutput"}],"discriminator":{"propertyName":"kind","mapping":{"openhands__agent_server__models__BashCommand-Output__1":"#/components/schemas/BashCommand","openhands__agent_server__models__BashError-Output__1":"#/components/schemas/BashError","openhands__agent_server__models__BashOutput-Output__1":"#/components/schemas/BashOutput"}}},"BashEventPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/BashEventBase"},"type":"array","title":"Items"},"next_page_id":{"anyOf":[{"type":"string"},{"type":"null"}],"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"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"command_id":{"type":"string","title":"Command Id"},"order":{"type":"integer","title":"Order","description":"The order for this output, sequentially starting with 0","default":0},"exit_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Exit Code","description":"Exit code None implies the command is still running."},"stdout":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stdout","description":"The standard output from the command"},"stderr":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stderr","description":"The error output from the command"},"kind":{"type":"string","const":"BashOutput","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_load_conversation_plugin_api_conversations__conversation_id__load_plugin_post":{"properties":{"plugin_ref":{"type":"string","title":"Plugin Ref"}},"type":"object","required":["plugin_ref"],"title":"Body_load_conversation_plugin_api_conversations__conversation_id__load_plugin_post"},"Body_switch_conversation_acp_model_api_conversations__conversation_id__switch_acp_model_post":{"properties":{"model":{"type":"string","title":"Model"}},"type":"object","required":["model"],"title":"Body_switch_conversation_acp_model_api_conversations__conversation_id__switch_acp_model_post"},"Body_switch_conversation_llm_api_conversations__conversation_id__switch_llm_post":{"properties":{"llm":{"$ref":"#/components/schemas/LLM-Input"}},"type":"object","required":["llm"],"title":"Body_switch_conversation_llm_api_conversations__conversation_id__switch_llm_post"},"Body_switch_conversation_profile_api_conversations__conversation_id__switch_profile_post":{"properties":{"profile_name":{"type":"string","title":"Profile Name"}},"type":"object","required":["profile_name"],"title":"Body_switch_conversation_profile_api_conversations__conversation_id__switch_profile_post"},"Body_upload_file_query_api_conversations__runtime_conversation_id__file_upload_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_file_query_api_conversations__runtime_conversation_id__file_upload_post"},"Body_upload_file_query_api_file_upload_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","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)"},"new_tab":{"type":"boolean","title":"New Tab","description":"Whether to open any resulting navigation in a new tab. Default: False","default":false},"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"},"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":{"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":"BrowserCloseTabAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["tab_id","kind"],"title":"BrowserCloseTabAction","description":"Schema for closing browser tabs."},"BrowserCloseTabTool":{"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":{"type":"string","const":"BrowserCloseTabTool","title":"Kind"},"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":"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},"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":[{"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":{"type":"string","const":"BrowserGetContentTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"BrowserGetContentTool","description":"Tool for getting page content in markdown."},"BrowserGetStateAction":{"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","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"},{"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":{"type":"string","const":"BrowserGetStateTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"BrowserGetStateTool","description":"Tool for getting browser state."},"BrowserGetStorageAction":{"properties":{"kind":{"type":"string","const":"BrowserGetStorageAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"BrowserGetStorageAction","description":"Schema for getting browser storage (cookies, local storage, session storage)."},"BrowserGetStorageTool":{"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":{"type":"string","const":"BrowserGetStorageTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"BrowserGetStorageTool","description":"Tool for getting browser storage."},"BrowserGoBackAction":{"properties":{"kind":{"type":"string","const":"BrowserGoBackAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"BrowserGoBackAction","description":"Schema for going back in browser history."},"BrowserGoBackTool":{"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":{"type":"string","const":"BrowserGoBackTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","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."},"BrowserListTabsTool":{"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":{"type":"string","const":"BrowserListTabsTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"BrowserListTabsTool","description":"Tool for listing browser tabs."},"BrowserNavigateAction":{"properties":{"url":{"type":"string","title":"Url","description":"The URL to navigate to"},"new_tab":{"type":"boolean","title":"New Tab","description":"Whether to open in a new tab. Default: False","default":false},"kind":{"type":"string","const":"BrowserNavigateAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["url","kind"],"title":"BrowserNavigateAction","description":"Schema for browser navigation."},"BrowserNavigateTool":{"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":{"type":"string","const":"BrowserNavigateTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"BrowserNavigateTool","description":"Tool for browser navigation."},"BrowserObservation":{"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},"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","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":"BrowserScrollAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"BrowserScrollAction","description":"Schema for scrolling the page."},"BrowserScrollTool":{"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":{"type":"string","const":"BrowserScrollTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"BrowserScrollTool","description":"Tool for scrolling the browser page."},"BrowserSetStorageAction":{"properties":{"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":"BrowserSetStorageAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["storage_state","kind"],"title":"BrowserSetStorageAction","description":"Schema for setting browser storage (cookies, local storage, session storage)."},"BrowserSetStorageTool":{"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":{"type":"string","const":"BrowserSetStorageTool","title":"Kind"},"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"},"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":{"type":"string","const":"BrowserStartRecordingTool","title":"Kind"},"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":{"type":"string","const":"BrowserStopRecordingAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"BrowserStopRecordingAction","description":"Schema for stopping browser session recording."},"BrowserStopRecordingTool":{"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":{"type":"string","const":"BrowserStopRecordingTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"BrowserStopRecordingTool","description":"Tool for stopping browser session recording."},"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":"BrowserSwitchTabAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["tab_id","kind"],"title":"BrowserSwitchTabAction","description":"Schema for switching browser tabs."},"BrowserSwitchTabTool":{"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":{"type":"string","const":"BrowserSwitchTabTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"BrowserSwitchTabTool","description":"Tool for switching browser tabs."},"BrowserToolSet":{"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":{"type":"string","const":"BrowserToolSet","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"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."},"BrowserTypeAction":{"properties":{"index":{"type":"integer","minimum":0.0,"title":"Index","description":"The index of the input element (from browser_get_state)"},"text":{"type":"string","title":"Text","description":"The text to type"},"kind":{"type":"string","const":"BrowserTypeAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["index","text","kind"],"title":"BrowserTypeAction","description":"Schema for typing text into elements."},"BrowserTypeTool":{"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":{"type":"string","const":"BrowserTypeTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"BrowserTypeTool","description":"Tool for typing text into browser elements."},"CanvasExtensionBackend":{"properties":{"schema_version":{"type":"integer","const":1,"title":"Schema Version"},"artifacts":{"additionalProperties":{"$ref":"#/components/schemas/CanvasExtensionBackendArtifact"},"propertyNames":{"enum":["linux-amd64","linux-arm64"]},"type":"object","minProperties":1,"title":"Artifacts"},"argv":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Argv"},"health":{"$ref":"#/components/schemas/CanvasExtensionBackendHealth"},"inherit_environment":{"items":{"type":"string"},"type":"array","title":"Inherit Environment"}},"type":"object","required":["schema_version","artifacts","argv"],"title":"CanvasExtensionBackend","description":"Optional trusted backend declaration for schema-1 Canvas Apps."},"CanvasExtensionBackendArtifact":{"properties":{"path":{"type":"string","title":"Path","description":"Package-relative .tar.gz artifact path"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","description":"Public HTTPS .tar.gz artifact URL"},"sha256":{"type":"string","pattern":"^[0-9a-f]{64}$","title":"Sha256","description":"Lowercase SHA-256 checksum"},"strip_components":{"type":"integer","maximum":16.0,"minimum":0.0,"title":"Strip Components","description":"Leading archive path components to remove","default":0}},"type":"object","required":["path","sha256"],"title":"CanvasExtensionBackendArtifact","description":"Immutable local or HTTPS backend artifact for one platform."},"CanvasExtensionBackendHealth":{"properties":{"path":{"type":"string","pattern":"^/[A-Za-z0-9._~!$&'()*+,;=:@%/-]*$","title":"Path","default":"/health"},"timeout_seconds":{"type":"number","maximum":300.0,"exclusiveMinimum":0.0,"title":"Timeout Seconds","default":30},"interval_seconds":{"type":"number","maximum":10.0,"exclusiveMinimum":0.0,"title":"Interval Seconds","default":0.1}},"type":"object","title":"CanvasExtensionBackendHealth","description":"Loopback HTTP readiness probe for a backend process."},"CanvasExtensionContributes":{"properties":{"pages":{"items":{"$ref":"#/components/schemas/CanvasExtensionPage"},"type":"array","title":"Pages","description":"Pages contributed to Canvas navigation"}},"type":"object","title":"CanvasExtensionContributes","description":"Contributions an extension makes to the Canvas UI."},"CanvasExtensionManifest":{"properties":{"schema_version":{"type":"integer","title":"Schema Version","description":"Manifest schema version"},"name":{"type":"string","title":"Name","description":"Extension name (kebab-case)"},"display_name":{"type":"string","title":"Display Name","description":"Human-readable extension name"},"version":{"type":"string","title":"Version","description":"Extension version"},"description":{"type":"string","title":"Description","description":"Extension description","default":""},"entrypoint":{"type":"string","title":"Entrypoint","description":"Path, relative to the extension package root, to the bundle entry file"},"contributes":{"$ref":"#/components/schemas/CanvasExtensionContributes","description":"Contributions this extension makes to the Canvas UI"},"backend":{"anyOf":[{"$ref":"#/components/schemas/CanvasExtensionBackend"},{"type":"null"}],"description":"Optional explicitly prepared and started backend service"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon","description":"Path, relative to the extension package root, to an SVG icon"}},"type":"object","required":["schema_version","name","display_name","version","entrypoint"],"title":"CanvasExtensionManifest","description":"Canvas extension manifest (``canvas-extension.json``)."},"CanvasExtensionPage":{"properties":{"id":{"type":"string","title":"Id","description":"Unique contribution id within the extension"},"title":{"type":"string","title":"Title","description":"Page title shown in Canvas navigation"},"path":{"type":"string","title":"Path","description":"Route the page is mounted at, e.g. '/dashboard'"}},"type":"object","required":["id","title","path"],"title":"CanvasExtensionPage","description":"A single page contributed to the Canvas UI by an extension."},"ChatCompletion":{"properties":{"id":{"type":"string","title":"Id"},"choices":{"items":{"$ref":"#/components/schemas/Choice"},"type":"array","title":"Choices"},"created":{"type":"integer","title":"Created"},"model":{"type":"string","title":"Model"},"object":{"type":"string","const":"chat.completion","title":"Object"},"service_tier":{"anyOf":[{"type":"string","enum":["auto","default","flex","scale","priority"]},{"type":"null"}],"title":"Service Tier"},"system_fingerprint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Fingerprint"},"usage":{"anyOf":[{"$ref":"#/components/schemas/CompletionUsage"},{"type":"null"}]}},"additionalProperties":true,"type":"object","required":["id","choices","created","model","object"],"title":"ChatCompletion","description":"Represents a chat completion response returned by model, based on the provided input."},"ChatCompletionAudio":{"properties":{"id":{"type":"string","title":"Id"},"data":{"type":"string","title":"Data"},"expires_at":{"type":"integer","title":"Expires At"},"transcript":{"type":"string","title":"Transcript"}},"additionalProperties":true,"type":"object","required":["id","data","expires_at","transcript"],"title":"ChatCompletionAudio","description":"If the audio output modality is requested, this object contains data\nabout the audio response from the model. [Learn more](https://platform.openai.com/docs/guides/audio)."},"ChatCompletionMessage":{"properties":{"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"refusal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refusal"},"role":{"type":"string","const":"assistant","title":"Role"},"annotations":{"anyOf":[{"items":{"$ref":"#/components/schemas/Annotation"},"type":"array"},{"type":"null"}],"title":"Annotations"},"audio":{"anyOf":[{"$ref":"#/components/schemas/ChatCompletionAudio"},{"type":"null"}]},"function_call":{"anyOf":[{"$ref":"#/components/schemas/FunctionCall"},{"type":"null"}]},"tool_calls":{"anyOf":[{"items":{"anyOf":[{"$ref":"#/components/schemas/ChatCompletionMessageFunctionToolCall"},{"$ref":"#/components/schemas/ChatCompletionMessageCustomToolCall"}]},"type":"array"},{"type":"null"}],"title":"Tool Calls"}},"additionalProperties":true,"type":"object","required":["role"],"title":"ChatCompletionMessage","description":"A chat completion message generated by the model."},"ChatCompletionMessageCustomToolCall":{"properties":{"id":{"type":"string","title":"Id"},"custom":{"$ref":"#/components/schemas/Custom"},"type":{"type":"string","const":"custom","title":"Type"}},"additionalProperties":true,"type":"object","required":["id","custom","type"],"title":"ChatCompletionMessageCustomToolCall","description":"A call to a custom tool created by the model."},"ChatCompletionMessageFunctionToolCall":{"properties":{"id":{"type":"string","title":"Id"},"function":{"$ref":"#/components/schemas/Function"},"type":{"type":"string","const":"function","title":"Type"}},"additionalProperties":true,"type":"object","required":["id","function","type"],"title":"ChatCompletionMessageFunctionToolCall","description":"A call to a function tool created by the model."},"ChatCompletionTokenLogprob":{"properties":{"token":{"type":"string","title":"Token"},"bytes":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Bytes"},"logprob":{"type":"number","title":"Logprob"},"top_logprobs":{"items":{"$ref":"#/components/schemas/TopLogprob"},"type":"array","title":"Top Logprobs"}},"additionalProperties":true,"type":"object","required":["token","logprob","top_logprobs"],"title":"ChatCompletionTokenLogprob"},"Choice":{"properties":{"finish_reason":{"type":"string","enum":["stop","length","tool_calls","content_filter","function_call"],"title":"Finish Reason"},"index":{"type":"integer","title":"Index"},"logprobs":{"anyOf":[{"$ref":"#/components/schemas/ChoiceLogprobs"},{"type":"null"}]},"message":{"$ref":"#/components/schemas/ChatCompletionMessage"}},"additionalProperties":true,"type":"object","required":["finish_reason","index","message"],"title":"Choice"},"ChoiceLogprobs":{"properties":{"content":{"anyOf":[{"items":{"$ref":"#/components/schemas/ChatCompletionTokenLogprob"},"type":"array"},{"type":"null"}],"title":"Content"},"refusal":{"anyOf":[{"items":{"$ref":"#/components/schemas/ChatCompletionTokenLogprob"},"type":"array"},{"type":"null"}],"title":"Refusal"}},"additionalProperties":true,"type":"object","title":"ChoiceLogprobs","description":"Log probability information for the choice."},"ClassifyAndSwitchLLMAction":{"properties":{"kind":{"type":"string","const":"ClassifyAndSwitchLLMAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"ClassifyAndSwitchLLMAction","description":"Trigger classification of the current task and switch the LLM profile."},"ClassifyAndSwitchLLMObservation":{"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},"chosen_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Chosen Class","description":"Description of the matched class, or None when no class matched and the tool returned an error."},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"Name of the LLM profile that was activated."},"active_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Model","description":"Model configured by the activated profile, when available."},"kind":{"type":"string","const":"ClassifyAndSwitchLLMObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"ClassifyAndSwitchLLMObservation","description":"Result of classifying the task and switching the LLM profile."},"ClassifyAndSwitchLLMTool":{"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":{"type":"string","const":"ClassifyAndSwitchLLMTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"ClassifyAndSwitchLLMTool","description":"Tool that classifies the task and switches to a meta-profile's LLM."},"ClientTool":{"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"},"client_tool_name":{"type":"string","title":"Client Tool Name","description":"Per-instance tool name from the ClientToolSpec."},"input_schema":{"additionalProperties":true,"type":"object","title":"Input Schema","description":"The original JSON Schema for the tool's parameters, as provided by the client. Used verbatim when exporting the tool to the LLM so client-defined constraints (enum, nested objects, bounds, additionalProperties, ...) are preserved."},"kind":{"type":"string","const":"ClientTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","client_tool_name","input_schema","kind","title"],"title":"ClientTool","description":"A tool whose execution is deferred to the external client.\n\nCreated from a :class:`ClientToolSpec` at conversation start. The agent\nsees it as a normal tool and can call it; the ActionEvent is emitted\nover WebSocket for the client to handle."},"ClientToolObservation":{"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},"kind":{"type":"string","const":"ClientToolObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"ClientToolObservation","description":"Observation returned when a client tool is called.\n\nThe actual execution happens on the client side; the SDK returns\nthis acknowledgment so the agent loop can continue."},"ClientToolSpec-Input":{"properties":{"name":{"type":"string","title":"Name","description":"Unique tool name the agent will use to call this tool."},"description":{"type":"string","title":"Description","description":"Description shown to the LLM explaining when and how to use this tool."},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters","description":"JSON Schema describing the tool's input parameters. Must be an object schema."},"annotations":{"anyOf":[{"$ref":"#/components/schemas/ToolAnnotations-Input"},{"type":"null"}],"description":"Optional MCP-style annotations for the tool. When omitted, the tool is treated conservatively (not read-only), so the agent is asked to predict a security risk before calling it."}},"type":"object","required":["name","description"],"title":"ClientToolSpec","description":"A tool defined by the client, executed externally (not by the SDK).\n\nClients pass these specs in ``POST /conversations`` to register tools\nwhose execution is handled outside the SDK (e.g., by a frontend\nlistening for ActionEvents over WebSocket)."},"ClientToolSpec-Output":{"properties":{"name":{"type":"string","title":"Name","description":"Unique tool name the agent will use to call this tool."},"description":{"type":"string","title":"Description","description":"Description shown to the LLM explaining when and how to use this tool."},"parameters":{"additionalProperties":true,"type":"object","title":"Parameters","description":"JSON Schema describing the tool's input parameters. Must be an object schema."},"annotations":{"anyOf":[{"$ref":"#/components/schemas/openhands__sdk__tool__tool__ToolAnnotations"},{"type":"null"}],"description":"Optional MCP-style annotations for the tool. When omitted, the tool is treated conservatively (not read-only), so the agent is asked to predict a security risk before calling it."}},"type":"object","required":["name","description"],"title":"ClientToolSpec","description":"A tool defined by the client, executed externally (not by the SDK).\n\nClients pass these specs in ``POST /conversations`` to register tools\nwhose execution is handled outside the SDK (e.g., by a frontend\nlistening for ActionEvents over WebSocket)."},"CmdOutputMetadata":{"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":{"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"},"CompletionTokensDetails":{"properties":{"accepted_prediction_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Accepted Prediction Tokens"},"audio_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Audio Tokens"},"reasoning_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reasoning Tokens"},"rejected_prediction_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rejected Prediction Tokens"}},"additionalProperties":true,"type":"object","title":"CompletionTokensDetails","description":"Breakdown of tokens used in a completion."},"CompletionUsage":{"properties":{"completion_tokens":{"type":"integer","title":"Completion Tokens"},"prompt_tokens":{"type":"integer","title":"Prompt Tokens"},"total_tokens":{"type":"integer","title":"Total Tokens"},"completion_tokens_details":{"anyOf":[{"$ref":"#/components/schemas/CompletionTokensDetails"},{"type":"null"}]},"prompt_tokens_details":{"anyOf":[{"$ref":"#/components/schemas/PromptTokensDetails"},{"type":"null"}]}},"additionalProperties":true,"type":"object","required":["completion_tokens","prompt_tokens","total_tokens"],"title":"CompletionUsage","description":"Usage statistics for the completion request."},"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"forgotten_event_ids":{"items":{"type":"string"},"type":"array","uniqueItems":true,"title":"Forgotten Event Ids","description":"The IDs of the events that are being forgotten (removed from the `View` given to the LLM)."},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary","description":"An optional summary of the events being forgotten."},"summary_offset":{"anyOf":[{"type":"integer","minimum":0.0},{"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"},"source":{"type":"string","enum":["agent","user","environment","hook"],"title":"Source","default":"environment"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"kind":{"type":"string","const":"CondensationRequest","title":"Kind"}},"additionalProperties":false,"type":"object","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."},"CondensationSummaryEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"summary":{"type":"string","title":"Summary"},"kind":{"type":"string","const":"CondensationSummaryEvent","title":"Kind"}},"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"}],"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":"ConfirmRisky","title":"Kind"}},"type":"object","title":"ConfirmRisky"},"ConfirmRisky-Output":{"properties":{"threshold":{"$ref":"#/components/schemas/SecurityRisk","default":"HIGH"},"confirm_unknown":{"type":"boolean","title":"Confirm Unknown","default":true},"kind":{"type":"string","const":"ConfirmRisky","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."},"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"code":{"type":"string","title":"Code","description":"Code for the error - typically a type"},"detail":{"type":"string","title":"Detail","description":"Details about the error"},"classification":{"anyOf":[{"$ref":"#/components/schemas/ErrorClassification"},{"type":"null"}],"description":"Safe structured error semantics for API consumers."},"kind":{"type":"string","const":"ConversationErrorEvent","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."},"ConversationInfo":{"properties":{"id":{"type":"string","format":"uuid","title":"Id","description":"Unique conversation ID"},"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"},{"type":"null"}],"title":"Persistence Dir","description":"Directory for persisting conversation state and events. If None, conversation will not be persisted.","default":"workspace/conversations"},"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/SecurityAnalyzerBase-Output"},{"type":"null"}],"description":"Optional security analyzer to evaluate action risks."},"activated_knowledge_skills":{"items":{"type":"string"},"type":"array","title":"Activated Knowledge Skills","description":"List of activated knowledge skills name"},"invoked_skills":{"items":{"type":"string"},"type":"array","title":"Invoked Skills","description":"Names of progressive-disclosure skills explicitly invoked via the `invoke_skill` tool."},"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":[{"type":"string"},{"type":"null"}],"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)."},"leaf_event_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Leaf Event Id","description":"HEAD of the conversation tree: the parent of the next appended event. ``None`` means an empty tree (or, for pre-feature conversations, the linear tail). Moving it via ``navigate`` re-roots the active branch the agent runs on."},"stats":{"$ref":"#/components/schemas/ConversationStats","description":"Conversation statistics for tracking LLM metrics"},"secret_registry":{"$ref":"#/components/schemas/SecretRegistry","description":"Registry for handling secrets and sensitive data"},"agent_state":{"additionalProperties":true,"type":"object","title":"Agent State","description":"Dictionary for agent-specific runtime state that persists across iterations."},"hook_config":{"anyOf":[{"$ref":"#/components/schemas/HookConfig"},{"type":"null"}],"description":"Hook configuration for this conversation. Includes definitions for PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, SessionEnd, and Stop hooks."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"User-defined title for the conversation"},"metrics":{"anyOf":[{"$ref":"#/components/schemas/MetricsSnapshot"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"forked_from_conversation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Forked From Conversation Id","description":"ID of the conversation this one was forked from. ``None`` for conversations created directly (not via fork)."},"forked_from_event_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Forked From Event Id","description":"Event ID this conversation was forked at. ``None`` for non-forked conversations or whole-conversation forks."},"parent_conversation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Conversation Id","description":"ID of the conversation that owns this one. ``None`` for top-level conversations."},"sub_conversation_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Sub Conversation Ids","description":"IDs of conversations naming this one as their parent. Derived from the server catalog; empty on webhook payloads. Name mirrors the Cloud API field."},"tags":{"additionalProperties":{"type":"string"},"type":"object","title":"Tags","description":"Key-value tags for the conversation. Keys must be lowercase alphanumeric. Values are arbitrary strings up to 256 characters."},"current_model_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Model Id","description":"Model the agent is actually using for this session. For ACP agents, this is lifted off ``ACPAgent.current_model_id`` (populated from the ``models.currentModelId`` field on the ACP session response, or from ``acp_model`` when the caller forced an override). May be an opaque alias (e.g. claude-agent-acp's ``\"default\"``); match it against ``available_models`` to get a display label. ``None`` for older ACP servers that don't surface the field, or while the agent is still initializing. Native OpenHands agents leave this ``None`` — consumers should read ``agent.llm.model`` for those."},"available_models":{"items":{"$ref":"#/components/schemas/ACPModelInfo"},"type":"array","title":"Available Models","description":"Models the ACP server offers for this session, lifted off ``ACPAgent.available_models`` (the ``models.availableModels`` field on the ACP session response). Each entry carries a ``model_id`` plus an optional ``name``/``description``. Surfaced verbatim so clients can render a model picker and resolve ``current_model_id`` to a display label themselves — the server does no name curation. Empty for ACP servers that don't surface the (UNSTABLE) capability and for native OpenHands agents. Client contract: ``current_model_id`` is NOT guaranteed to be a member — a forced ``acp_model`` override may name a model absent from the list — so treat a miss as 'show the raw id'. Some entries are opaque aliases whose human identity lives in ``description`` (e.g. claude-agent-acp's ``\"default\"`` -> ``\"Opus 4.7 with 1M context · ...\"``)."},"supports_runtime_model_switch":{"type":"boolean","title":"Supports Runtime Model Switch","description":"Whether a live, mid-conversation model switch will be attempted for this conversation — tells the inline picker whether to offer a live-switch control. Mirrors the SDK's switch gate: ``True`` for known switch-capable providers; ``False`` for unknown/custom ACP servers because their generic config writes are not guaranteed live-switch primitives. ``False`` for native OpenHands agents, for a known provider that declares no support, and before the conversation has started a session.","default":false},"launched_agent_profile":{"anyOf":[{"$ref":"#/components/schemas/LaunchedAgentProfile"},{"type":"null"}],"description":"Provenance snapshot of the agent profile that launched this conversation. Set at creation when the conversation was started via ``agent_profile_id``; ``None`` for conversations started directly with ``agent`` or ``agent_settings``. Clients use this to identify which agent profile is current without fragile settings-comparison."},"agent":{"$ref":"#/components/schemas/AgentBase-Output","description":"The agent running in the conversation."},"client_tools":{"items":{"$ref":"#/components/schemas/ClientToolSpec-Output"},"type":"array","title":"Client Tools","description":"Client-defined tool specs registered for this conversation. Surfaced so that a client re-attaching by conversation id can register the dynamic ClientAction_* action types before syncing persisted events, avoiding 'Unknown kind' deserialization errors."},"tool_module_qualnames":{"additionalProperties":{"type":"string"},"type":"object","title":"Tool Module Qualnames","description":"Tool names mapped to importable module qualnames. SDK clients use this metadata to restore the registrations needed to deserialize the conversation's tool events when attaching."},"runtime_info":{"anyOf":[{"$ref":"#/components/schemas/ConversationRuntimeInfo"},{"type":"null"}],"description":"Availability of the execution runtime. Catalog responses populate this when the hosting server manages runtime lifecycle."}},"type":"object","required":["id","workspace","agent"],"title":"ConversationInfo","description":"Information about a conversation running locally without a Runtime sandbox."},"ConversationPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ConversationInfo"},"type":"array","title":"Items"},"next_page_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Page Id"}},"type":"object","required":["items"],"title":"ConversationPage"},"ConversationRuntimeError":{"properties":{"code":{"type":"string","title":"Code"},"message":{"type":"string","title":"Message"}},"type":"object","required":["code","message"],"title":"ConversationRuntimeError","description":"Structured details for the latest runtime lifecycle failure."},"ConversationRuntimeInfo":{"properties":{"runtime_status":{"$ref":"#/components/schemas/ConversationRuntimeStatus"},"can_resume":{"type":"boolean","title":"Can Resume"},"runtime_error":{"anyOf":[{"$ref":"#/components/schemas/ConversationRuntimeError"},{"type":"null"}]}},"type":"object","required":["runtime_status","can_resume"],"title":"ConversationRuntimeInfo","description":"Runtime availability and recovery information for a conversation."},"ConversationRuntimeStatus":{"type":"string","enum":["available","starting","missing","ownership_lost","error"],"title":"ConversationRuntimeStatus","description":"Availability of the runtime that executes a conversation."},"ConversationSortOrder":{"type":"string","enum":["CREATED_AT","UPDATED_AT","CREATED_AT_DESC","UPDATED_AT_DESC"],"title":"ConversationSortOrder","description":"Enum for conversation sorting options."},"ConversationStateUpdateEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"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":"ConversationStateUpdateEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["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."},"ConversationStats":{"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"},{"$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"},{"type":"null"}],"title":"Message","description":"An optional message explaining the score."},"metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Metadata","description":"Optional metadata about the critic evaluation. Can include event_ids and categorized_features for visualization."}},"type":"object","required":["score","message"],"title":"CriticResult","description":"A critic result is a score and a message."},"Custom":{"properties":{"input":{"type":"string","title":"Input"},"name":{"type":"string","title":"Name"}},"additionalProperties":true,"type":"object","required":["input","name"],"title":"Custom","description":"The custom tool that the model called."},"DelegateAction":{"properties":{"command":{"type":"string","enum":["spawn","delegate"],"title":"Command","description":"The commands to run. Allowed options are: `spawn`, `delegate`."},"ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Ids","description":"Required parameter of `spawn` command. List of identifiers to initialize sub-agents with."},"agent_types":{"anyOf":[{"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."},"tasks":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Tasks","description":"Required parameter of `delegate` command. Dictionary mapping sub-agent identifiers to task descriptions."},"kind":{"type":"string","const":"DelegateAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["command","kind"],"title":"DelegateAction","description":"Schema for delegation operations."},"DelegateObservation":{"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},"command":{"type":"string","enum":["spawn","delegate"],"title":"Command","description":"The command that was executed"},"kind":{"type":"string","const":"DelegateObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["command","kind"],"title":"DelegateObservation","description":"Observation from delegation operations."},"DeleteResponse":{"properties":{"deleted":{"type":"boolean","title":"Deleted","default":true}},"type":"object","title":"DeleteResponse"},"EditAction":{"properties":{"file_path":{"type":"string","title":"File Path","description":"The path to the file to modify."},"old_string":{"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."},"new_string":{"type":"string","title":"New String","description":"The text to replace it with."},"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":{"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},"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","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"EditObservation","description":"Observation from editing a file."},"EditTool":{"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":{"type":"string","const":"EditTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"EditTool","description":"Tool for editing files via find/replace."},"EmptyPatchCritic-Input":{"properties":{"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":"EmptyPatchCritic","title":"Kind"}},"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."},"EmptyPatchCritic-Output":{"properties":{"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":"EmptyPatchCritic","title":"Kind"}},"type":"object","required":["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."},"EnsembleSecurityAnalyzer-Input":{"properties":{"analyzers":{"items":{"$ref":"#/components/schemas/SecurityAnalyzerBase-Input"},"type":"array","minItems":1,"title":"Analyzers","description":"Analyzers whose assessments are combined via max-severity"},"propagate_unknown":{"type":"boolean","title":"Propagate Unknown","description":"When True, any child returning UNKNOWN causes the ensemble to return UNKNOWN. When False (default), UNKNOWN is filtered out if any child returns a concrete level.","default":false},"kind":{"type":"string","const":"EnsembleSecurityAnalyzer","title":"Kind"}},"type":"object","required":["analyzers"],"title":"EnsembleSecurityAnalyzer","description":"Wire multiple analyzers together and take the worst-case risk.\n\nUse this as the top-level analyzer you set on a conversation. It\ncalls each child analyzer, collects their risk assessments, and\nreturns the highest concrete risk. It does not perform any detection,\nextraction, or normalization of its own.\n\nHow UNKNOWN works (default, ``propagate_unknown=False``): if *all*\nchildren return UNKNOWN, the ensemble returns UNKNOWN (which\n``ConfirmRisky`` confirms by default). If any child returns a\nconcrete level, UNKNOWN results are filtered out and the highest\nconcrete level wins.\n\nWith ``propagate_unknown=True``: if *any* child returns UNKNOWN, the\nensemble returns UNKNOWN regardless of other results. Use this in\nstricter environments where incomplete assessment should trigger\nconfirmation.\n\nIf a child analyzer raises an exception, it contributes HIGH\n(fail-closed, logged). This prevents a broken analyzer from silently\ndegrading safety.\n\nExample::\n\n    from openhands.sdk.security import (\n        EnsembleSecurityAnalyzer,\n        PatternSecurityAnalyzer,\n        PolicyRailSecurityAnalyzer,\n        ConfirmRisky,\n        SecurityRisk,\n    )\n\n    analyzer = EnsembleSecurityAnalyzer(\n        analyzers=[\n            PolicyRailSecurityAnalyzer(),\n            PatternSecurityAnalyzer(),\n        ]\n    )\n    policy = ConfirmRisky(threshold=SecurityRisk.MEDIUM)"},"EnsembleSecurityAnalyzer-Output":{"properties":{"analyzers":{"items":{"$ref":"#/components/schemas/SecurityAnalyzerBase-Output"},"type":"array","minItems":1,"title":"Analyzers","description":"Analyzers whose assessments are combined via max-severity"},"propagate_unknown":{"type":"boolean","title":"Propagate Unknown","description":"When True, any child returning UNKNOWN causes the ensemble to return UNKNOWN. When False (default), UNKNOWN is filtered out if any child returns a concrete level.","default":false},"kind":{"type":"string","const":"EnsembleSecurityAnalyzer","title":"Kind"}},"type":"object","required":["analyzers","kind"],"title":"EnsembleSecurityAnalyzer","description":"Wire multiple analyzers together and take the worst-case risk.\n\nUse this as the top-level analyzer you set on a conversation. It\ncalls each child analyzer, collects their risk assessments, and\nreturns the highest concrete risk. It does not perform any detection,\nextraction, or normalization of its own.\n\nHow UNKNOWN works (default, ``propagate_unknown=False``): if *all*\nchildren return UNKNOWN, the ensemble returns UNKNOWN (which\n``ConfirmRisky`` confirms by default). If any child returns a\nconcrete level, UNKNOWN results are filtered out and the highest\nconcrete level wins.\n\nWith ``propagate_unknown=True``: if *any* child returns UNKNOWN, the\nensemble returns UNKNOWN regardless of other results. Use this in\nstricter environments where incomplete assessment should trigger\nconfirmation.\n\nIf a child analyzer raises an exception, it contributes HIGH\n(fail-closed, logged). This prevents a broken analyzer from silently\ndegrading safety.\n\nExample::\n\n    from openhands.sdk.security import (\n        EnsembleSecurityAnalyzer,\n        PatternSecurityAnalyzer,\n        PolicyRailSecurityAnalyzer,\n        ConfirmRisky,\n        SecurityRisk,\n    )\n\n    analyzer = EnsembleSecurityAnalyzer(\n        analyzers=[\n            PolicyRailSecurityAnalyzer(),\n            PatternSecurityAnalyzer(),\n        ]\n    )\n    policy = ConfirmRisky(threshold=SecurityRisk.MEDIUM)"},"ErrorClassification":{"properties":{"kind":{"$ref":"#/components/schemas/FailureKind"},"retryable":{"type":"boolean","title":"Retryable"},"user_action":{"type":"string","enum":["none","retry","settings"],"title":"User Action","default":"none"},"error_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Id"}},"additionalProperties":false,"type":"object","required":["kind","retryable"],"title":"ErrorClassification","description":"The only failure metadata that crosses the event/API boundary.\n\nIt is intentionally small. ``detail`` is inspected locally only to map\nbroad third-party errors to this closed vocabulary; it is never copied\nhere or sent to telemetry."},"Event":{"oneOf":[{"$ref":"#/components/schemas/ServerErrorEvent"},{"$ref":"#/components/schemas/ACPToolCallEvent"},{"$ref":"#/components/schemas/Condensation"},{"$ref":"#/components/schemas/CondensationRequest"},{"$ref":"#/components/schemas/CondensationSummaryEvent"},{"$ref":"#/components/schemas/ConversationErrorEvent"},{"$ref":"#/components/schemas/ConversationStateUpdateEvent"},{"$ref":"#/components/schemas/HookExecutionEvent"},{"$ref":"#/components/schemas/LLMCompletionLogEvent"},{"$ref":"#/components/schemas/ActionEvent"},{"$ref":"#/components/schemas/MessageEvent"},{"$ref":"#/components/schemas/AgentErrorEvent"},{"$ref":"#/components/schemas/ObservationEvent"},{"$ref":"#/components/schemas/UserRejectObservation"},{"$ref":"#/components/schemas/SystemPromptEvent"},{"$ref":"#/components/schemas/SecurityAnalysisEvent"},{"$ref":"#/components/schemas/StreamingDeltaEvent"},{"$ref":"#/components/schemas/TokenEvent"},{"$ref":"#/components/schemas/InterruptEvent"},{"$ref":"#/components/schemas/PauseEvent"}],"discriminator":{"propertyName":"kind","mapping":{"openhands__agent_server__models__ServerErrorEvent-Output__1":"#/components/schemas/ServerErrorEvent","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__security__SecurityAnalysisEvent-Output__1":"#/components/schemas/SecurityAnalysisEvent","openhands__sdk__event__streaming_delta__StreamingDeltaEvent-Output__1":"#/components/schemas/StreamingDeltaEvent","openhands__sdk__event__token__TokenEvent-Output__1":"#/components/schemas/TokenEvent","openhands__sdk__event__user_action__InterruptEvent-Output__1":"#/components/schemas/InterruptEvent","openhands__sdk__event__user_action__PauseEvent-Output__1":"#/components/schemas/PauseEvent"}}},"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"},"cwd":{"anyOf":[{"type":"string"},{"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}},"type":"object","required":["command"],"title":"ExecuteBashRequest"},"ExposedUrl":{"properties":{"name":{"type":"string","title":"Name"},"url":{"type":"string","title":"Url"},"port":{"type":"integer","title":"Port"}},"type":"object","required":["name","url","port"],"title":"ExposedUrl","description":"Represents an exposed URL from the sandbox."},"FailureKind":{"type":"string","enum":["auth","quota","rate_limit","config","transient","agent_action","internal","unknown"],"title":"FailureKind"},"FallbackStrategy":{"properties":{"fallback_llms":{"items":{"type":"string"},"type":"array","title":"Fallback Llms","description":"Ordered list of LLM profile names to try on transient failure."},"profile_store_dir":{"anyOf":[{"type":"string"},{"type":"string","format":"path"},{"type":"null"}],"title":"Profile Store Dir","description":"Path to directory containing profiles. If not specified, defaults to `.openhands/profiles`."}},"type":"object","required":["fallback_llms"],"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."},"FileBrowserEntry":{"properties":{"label":{"type":"string","title":"Label"},"path":{"type":"string","title":"Path"}},"type":"object","required":["label","path"],"title":"FileBrowserEntry"},"FileEditorAction":{"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`."},"path":{"type":"string","title":"Path","description":"Absolute path to file or directory."},"file_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Text","description":"Required parameter of `create` command, with the content of the file to be created."},"old_str":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Str","description":"Required parameter of `str_replace` command containing the string in `path` to replace."},"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":"FileEditorAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["command","path","kind"],"title":"FileEditorAction","description":"Schema for file editor operations."},"FileEditorObservation":{"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},"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`."},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path","description":"The file path that was edited."},"prev_exist":{"type":"boolean","title":"Prev Exist","description":"Indicates if the file previously existed. If not, it was created.","default":true},"old_content":{"anyOf":[{"type":"string"},{"type":"null"}],"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":["command","kind"],"title":"FileEditorObservation","description":"A ToolResult that can be rendered as a CLI output."},"FileEditorTool":{"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":{"type":"string","const":"FileEditorTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"FileEditorTool","description":"A ToolDefinition subclass that automatically initializes a FileEditorExecutor."},"FileEntry":{"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"}},"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":"FinishAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["message","kind"],"title":"FinishAction"},"FinishObservation":{"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},"kind":{"type":"string","const":"FinishObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"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."},"FinishTool":{"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":{"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."},"ForkConversationRequest":{"properties":{"id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Id","description":"ID for the forked conversation (auto-generated if null)"},"title":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Title","description":"Optional title for the forked conversation"},"tags":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Tags","description":"Optional tags for the forked conversation. Keys must be lowercase alphanumeric."},"reset_metrics":{"type":"boolean","title":"Reset Metrics","description":"If true, cost/token stats start fresh on the fork. If false, metrics are copied from the source.","default":true},"from_event_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Event Id","description":"If set, fork only the branch up to and including this event and set the fork's HEAD there. If null (default), copy the whole conversation."}},"type":"object","title":"ForkConversationRequest","description":"Payload to fork a conversation."},"Function":{"properties":{"arguments":{"type":"string","title":"Arguments"},"name":{"type":"string","title":"Name"}},"additionalProperties":true,"type":"object","required":["arguments","name"],"title":"Function","description":"The function that the model called."},"FunctionCall":{"properties":{"arguments":{"type":"string","title":"Arguments"},"name":{"type":"string","title":"Name"}},"additionalProperties":true,"type":"object","required":["arguments","name"],"title":"FunctionCall","description":"Deprecated and replaced by `tool_calls`.\n\nThe name and arguments of a function that should be called, as generated by the model."},"GitChange":{"properties":{"status":{"$ref":"#/components/schemas/GitChangeStatus"},"path":{"type":"string","format":"path","title":"Path"}},"type":"object","required":["status","path"],"title":"GitChange"},"GitChangeStatus":{"type":"string","enum":["MOVED","ADDED","DELETED","UPDATED"],"title":"GitChangeStatus"},"GitCommit":{"properties":{"sha":{"type":"string","title":"Sha"},"short_sha":{"type":"string","title":"Short Sha"},"subject":{"type":"string","title":"Subject"},"author":{"type":"string","title":"Author"},"timestamp":{"type":"string","title":"Timestamp"}},"type":"object","required":["sha","short_sha","subject","author","timestamp"],"title":"GitCommit"},"GitCommitsPage":{"properties":{"commits":{"items":{"$ref":"#/components/schemas/GitCommit"},"type":"array","title":"Commits"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["commits","has_more"],"title":"GitCommitsPage"},"GitDiff":{"properties":{"modified":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Modified"},"original":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Original"}},"type":"object","required":["modified","original"],"title":"GitDiff"},"GitProvider":{"type":"string","enum":["github","gitlab","bitbucket"],"title":"GitProvider","description":"Supported git hosting providers."},"GitProviderRepository":{"properties":{"id":{"type":"string","title":"Id"},"full_name":{"type":"string","title":"Full Name"},"git_provider":{"type":"string","title":"Git Provider"},"is_public":{"type":"boolean","title":"Is Public"},"stargazers_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Stargazers Count"},"pushed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pushed At"},"main_branch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Main Branch"}},"type":"object","required":["id","full_name","git_provider","is_public"],"title":"GitProviderRepository"},"GitProviderRepositoryPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/GitProviderRepository"},"type":"array","title":"Items"},"next_page_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Page Id"},"missing_token":{"type":"boolean","title":"Missing Token","default":false}},"type":"object","required":["items"],"title":"GitProviderRepositoryPage"},"GlobAction":{"properties":{"pattern":{"type":"string","title":"Pattern","description":"The glob pattern to match files (e.g., \"**/*.js\", \"src/**/*.ts\")"},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path","description":"The directory (absolute path) to search in. Defaults to the current working directory."},"kind":{"type":"string","const":"GlobAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["pattern","kind"],"title":"GlobAction","description":"Schema for glob pattern matching operations."},"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."},"is_error":{"type":"boolean","title":"Is Error","description":"Whether the observation indicates an error","default":false},"files":{"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"}},"additionalProperties":false,"type":"object","required":["files","pattern","search_path","kind"],"title":"GlobObservation","description":"Observation from glob pattern matching operations."},"GlobTool":{"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":{"type":"string","const":"GlobTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"GlobTool","description":"A ToolDefinition subclass that automatically initializes a GlobExecutor."},"GraySwanAnalyzer-Input":{"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"},{"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},"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"},{"type":"null"}],"title":"Policy Id","description":"GraySwan policy ID (via GRAYSWAN_POLICY_ID env var)"},"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":"string"},{"type":"null"}],"title":"Path","description":"The directory (absolute path) to search in. Defaults to the current working directory."},"include":{"anyOf":[{"type":"string"},{"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},"matches":{"items":{"type":"string"},"type":"array","title":"Matches","description":"List of file paths containing the pattern"},"pattern":{"type":"string","title":"Pattern","description":"The regex pattern that was used"},"search_path":{"type":"string","title":"Search Path","description":"The directory that was searched"},"include_pattern":{"anyOf":[{"type":"string"},{"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"},"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":{"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"},"HealthStatus":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"HealthStatus"},"HomeResponse":{"properties":{"home":{"type":"string","title":"Home"},"favorites":{"items":{"$ref":"#/components/schemas/FileBrowserEntry"},"type":"array","title":"Favorites","default":[]},"locations":{"items":{"$ref":"#/components/schemas/FileBrowserEntry"},"type":"array","title":"Locations","default":[]}},"type":"object","required":["home"],"title":"HomeResponse"},"HookConfig":{"properties":{"pre_tool_use":{"items":{"$ref":"#/components/schemas/HookMatcher"},"type":"array","title":"Pre Tool Use","description":"Hooks that run before tool execution"},"post_tool_use":{"items":{"$ref":"#/components/schemas/HookMatcher"},"type":"array","title":"Post Tool Use","description":"Hooks that run after tool execution"},"user_prompt_submit":{"items":{"$ref":"#/components/schemas/HookMatcher"},"type":"array","title":"User Prompt Submit","description":"Hooks that run when user submits a prompt"},"session_start":{"items":{"$ref":"#/components/schemas/HookMatcher"},"type":"array","title":"Session Start","description":"Hooks that run when a session starts"},"session_end":{"items":{"$ref":"#/components/schemas/HookMatcher"},"type":"array","title":"Session End","description":"Hooks that run when a session ends"},"stop":{"items":{"$ref":"#/components/schemas/HookMatcher"},"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"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"command":{"type":"string","title":"Command"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt"},"system_prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Prompt"},"tools":{"items":{"type":"string"},"type":"array","title":"Tools"},"timeout":{"type":"integer","title":"Timeout","default":60},"max_iterations":{"type":"integer","title":"Max Iterations","default":3},"async":{"type":"boolean","title":"Async","default":false}},"type":"object","required":["command"],"title":"HookDefinition","description":"A single hook definition."},"HookExecutionEvent":{"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":"Source is always 'hook' for hook execution events","default":"hook"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"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"},{"type":"null"}],"title":"Tool Name","description":"Tool name for PreToolUse/PostToolUse hooks"},"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":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Reason provided by hook (for blocking)"},"additional_context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Additional Context","description":"Additional context injected by hook (e.g., for UserPromptSubmit)"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Error message if hook execution failed"},"action_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action Id","description":"ID of the action this hook is associated with (PreToolUse/PostToolUse)"},"message_id":{"anyOf":[{"type":"string"},{"type":"null"}],"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","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."},"HookMatcher":{"properties":{"matcher":{"type":"string","title":"Matcher","default":"*"},"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","agent"],"title":"HookType","description":"Types of hooks that can be executed."},"HooksRequest":{"properties":{"project_dir":{"anyOf":[{"type":"string"},{"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":{"anyOf":[{"$ref":"#/components/schemas/HookConfig"},{"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"},"mimeType":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mimetype"},"sizes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Sizes"}},"additionalProperties":true,"type":"object","required":["src"],"title":"Icon","description":"An icon for display in user interfaces."},"ImageContent":{"properties":{"cache_prompt":{"type":"boolean","title":"Cache Prompt","default":false},"type":{"type":"string","const":"image","title":"Type","default":"image"},"image_urls":{"items":{"type":"string"},"type":"array","title":"Image Urls"}},"type":"object","required":["image_urls"],"title":"ImageContent"},"InitRequest":{"properties":{"session_api_keys":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Session Api Keys","description":"Per-user session API keys. If provided, all subsequent /api/* requests must authenticate with one of these keys via the X-Session-API-Key header."},"secret_key":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Secret Key","description":"Symmetric secret used to encrypt persisted secrets. If not provided, falls back to the first session_api_key (matching the default Config behavior)."},"conversations_path":{"anyOf":[{"type":"string","format":"path"},{"type":"null"}],"title":"Conversations Path","description":"Directory where conversations are persisted. Override this to point at the mounted user workspace."},"bash_events_dir":{"anyOf":[{"type":"string","format":"path"},{"type":"null"}],"title":"Bash Events Dir","description":"Directory where bash events are persisted. Typically located inside the mounted user workspace."},"conversation_worktree_root":{"anyOf":[{"type":"string","format":"path"},{"type":"null"}],"title":"Conversation Worktree Root","description":"Root directory for conversation git worktrees. Override this to point at the mounted user workspace."},"webhooks":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookSpec"},"type":"array"},{"type":"null"}],"title":"Webhooks","description":"Per-user webhooks (e.g. for streaming events back)."},"web_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Web Url","description":"External URL where this server is reachable, used for root-path calculation. Only honored when not already set in dormant config."},"allow_cors_origins":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allow Cors Origins","description":"CORS origins to add to the existing localhost allowlist."},"max_concurrent_runs":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Concurrent Runs","description":"Override the conversation-step concurrency limit."},"env":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Env","description":"Process environment variables to set before conversation services start. Useful for credentials consumed by tools (e.g. GITHUB_TOKEN). These are applied with ``os.environ.update``; existing values are overwritten."},"telemetry":{"anyOf":[{"$ref":"#/components/schemas/TelemetrySpec"},{"type":"null"}],"description":"Product-analytics policy for this pod. Without this, a warm-pool pod keeps whatever mode it booted with (normally 'disabled'), so a deployment that expects telemetry must supply it here."}},"additionalProperties":false,"type":"object","title":"InitRequest","description":"Runtime configuration delivered at /api/init time.\n\nEach field is optional and overrides the equivalent field on the dormant\n``Config``. Fields not provided keep the value the server was constructed\nwith (typically from env vars at pod startup). The set of overridable\nfields is intentionally narrow — it covers the values that today are\n\"env-var shaped\" and must change per-user, not image-build-time\nconfiguration (Python deps, plugin set, etc.) which stays bound to the\nwarm-pool flavor."},"InitStatus":{"properties":{"state":{"type":"string","enum":["dormant","initializing","ready"],"title":"State","description":"``dormant`` — server is up but waiting for /api/init. ``initializing`` — /api/init has been received and services are starting. ``ready`` — initialization complete; all /api/* routes are live."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"If a previous /api/init attempt failed, the error message. The state rolls back to ``dormant`` so /api/init can be retried."}},"type":"object","required":["state"],"title":"InitStatus"},"InputMetadata":{"properties":{"name":{"type":"string","title":"Name","description":"Name of the input parameter"},"description":{"type":"string","title":"Description","description":"Description of the input parameter"}},"type":"object","required":["name","description"],"title":"InputMetadata","description":"Metadata for task skill inputs."},"InstallCanvasExtensionRequest":{"properties":{"source":{"type":"string","minLength":1,"title":"Source","description":"Canvas extension source - git URL, GitHub shorthand, or local path. Examples: 'github:owner/repo', '/path/to/extension'"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref","description":"Optional branch, tag, or commit to install"},"repo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Path","description":"Subdirectory path within the repository (for monorepos)"},"force":{"type":"boolean","title":"Force","description":"If true, overwrite existing installation","default":false}},"type":"object","required":["source"],"title":"InstallCanvasExtensionRequest","description":"Request body for installing a canvas extension."},"InstallPluginRequest":{"properties":{"source":{"type":"string","minLength":1,"title":"Source","description":"Plugin source - git URL, GitHub shorthand, or local path. Examples: 'github:<redacted:unrelated-repository>/plugins/city-weather', '/path/to/plugin'"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref","description":"Optional branch, tag, or commit to install"},"repo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Path","description":"Subdirectory path within the repository (for monorepos)"},"force":{"type":"boolean","title":"Force","description":"If true, overwrite existing installation","default":false}},"type":"object","required":["source"],"title":"InstallPluginRequest","description":"Request body for installing a plugin."},"InstallSkillRequest":{"properties":{"source":{"type":"string","minLength":1,"title":"Source","description":"Skill source - git URL, GitHub shorthand, or local path. Examples: 'https://github.com/<redacted:unrelated-repository>/tree/main/skills/github', 'github:<redacted:unrelated-repository>/skills/github', '/path/to/skill'"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref","description":"Optional branch, tag, or commit to install"},"repo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Path","description":"Subdirectory path within the repository (for monorepos)"},"force":{"type":"boolean","title":"Force","description":"If true, overwrite existing installation","default":false}},"type":"object","required":["source"],"title":"InstallSkillRequest","description":"Request body for installing a skill."},"InstalledCanvasExtensionResponse":{"properties":{"name":{"type":"string","title":"Name","description":"Canvas extension name"},"version":{"type":"string","title":"Version","description":"Canvas extension version","default":""},"description":{"type":"string","title":"Description","description":"Canvas extension description","default":""},"enabled":{"type":"boolean","title":"Enabled","description":"Whether the canvas extension is enabled","default":false},"source":{"type":"string","title":"Source","description":"Original source (e.g., 'github:owner/repo')"},"requested_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Requested Ref","description":"Branch, tag, or commit requested at install time. None means no ref was requested (tracking the source's default branch)."},"resolved_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolved Ref","description":"Resolved git commit SHA"},"repo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Path","description":"Subdirectory path within the repository"},"installed_at":{"type":"string","title":"Installed At","description":"ISO 8601 timestamp of installation"},"install_path":{"type":"string","title":"Install Path","description":"Path where the extension is installed"},"manifest":{"anyOf":[{"$ref":"#/components/schemas/CanvasExtensionManifest"},{"type":"null"}],"description":"The extension's validated manifest (display_name, contributes.pages, ...). None if the installed manifest can no longer be read."}},"type":"object","required":["name","source","installed_at","install_path"],"title":"InstalledCanvasExtensionResponse","description":"Response containing installed canvas extension information."},"InstalledCanvasExtensionsListResponse":{"properties":{"canvas_extensions":{"items":{"$ref":"#/components/schemas/InstalledCanvasExtensionResponse"},"type":"array","title":"Canvas Extensions"}},"type":"object","required":["canvas_extensions"],"title":"InstalledCanvasExtensionsListResponse","description":"Response containing the list of installed canvas extensions."},"InstalledPluginResponse":{"properties":{"name":{"type":"string","title":"Name","description":"Plugin name"},"version":{"type":"string","title":"Version","description":"Plugin version","default":""},"description":{"type":"string","title":"Description","description":"Plugin description","default":""},"enabled":{"type":"boolean","title":"Enabled","description":"Whether the plugin is enabled","default":true},"source":{"type":"string","title":"Source","description":"Original source (e.g., 'github:owner/repo')"},"resolved_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolved Ref","description":"Resolved git commit SHA"},"repo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Path","description":"Subdirectory path within the repository"},"installed_at":{"type":"string","title":"Installed At","description":"ISO 8601 timestamp of installation"},"install_path":{"type":"string","title":"Install Path","description":"Path where the plugin is installed"},"skills":{"anyOf":[{"items":{"$ref":"#/components/schemas/PluginSkillSummary"},"type":"array"},{"type":"null"}],"title":"Skills","description":"Skills bundled in the plugin (None if it failed to load)"},"files":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Files","description":"Plugin files, relative to install_path (None if load failed)"}},"type":"object","required":["name","source","installed_at","install_path"],"title":"InstalledPluginResponse","description":"Response containing installed plugin information."},"InstalledPluginsListResponse":{"properties":{"plugins":{"items":{"$ref":"#/components/schemas/InstalledPluginResponse"},"type":"array","title":"Plugins"}},"type":"object","required":["plugins"],"title":"InstalledPluginsListResponse","description":"Response containing the list of installed plugins."},"InstalledSkillResponse":{"properties":{"name":{"type":"string","title":"Name","description":"Skill name"},"version":{"type":"string","title":"Version","description":"Skill version","default":""},"description":{"type":"string","title":"Description","description":"Skill description","default":""},"enabled":{"type":"boolean","title":"Enabled","description":"Whether the skill is enabled","default":true},"source":{"type":"string","title":"Source","description":"Original source (e.g., 'github:owner/repo')"},"resolved_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resolved Ref","description":"Resolved git commit SHA"},"repo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Path","description":"Subdirectory path within the repository"},"installed_at":{"type":"string","title":"Installed At","description":"ISO 8601 timestamp of installation"},"install_path":{"type":"string","title":"Install Path","description":"Path where the skill is installed"}},"type":"object","required":["name","source","installed_at","install_path"],"title":"InstalledSkillResponse","description":"Response containing installed skill information."},"InstalledSkillsListResponse":{"properties":{"skills":{"items":{"$ref":"#/components/schemas/InstalledSkillResponse"},"type":"array","title":"Skills"}},"type":"object","required":["skills"],"title":"InstalledSkillsListResponse","description":"Response containing list of installed skills."},"InterruptEvent":{"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":"user"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"kind":{"type":"string","const":"InterruptEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"InterruptEvent","description":"Event indicating the agent was interrupted mid-operation.\n\nUnlike :class:`PauseEvent` which takes effect between agent steps,\nan interrupt cancels the in-flight LLM call immediately.  The\nconversation state is set to PAUSED so it can be resumed later."},"InvokeSkillAction":{"properties":{"name":{"type":"string","title":"Name","description":"Name of the loaded skill to invoke."},"kind":{"type":"string","const":"InvokeSkillAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["name","kind"],"title":"InvokeSkillAction"},"InvokeSkillObservation":{"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},"skill_name":{"type":"string","title":"Skill Name","description":"Name of the skill this observation corresponds to."},"kind":{"type":"string","const":"InvokeSkillObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["skill_name","kind"],"title":"InvokeSkillObservation"},"InvokeSkillTool":{"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":{"type":"string","const":"InvokeSkillTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"InvokeSkillTool","description":"Built-in tool for explicit invocation of progressive-disclosure skills."},"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},"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"},"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":"gpt-5.6","openhands_settings":{"depends_on":[],"prominence":"critical"}},"api_key":{"anyOf":[{"type":"string"},{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Api Key","description":"API key.","openhands_settings":{"depends_on":[],"label":"API Key","prominence":"critical"}},"provider_connection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Connection Id","description":"Optional provider connection whose shared API key and base URL are resolved and applied each time this LLM profile is loaded (read-at-use). When set, the profile stores no inline api_key or base_url of its own.","openhands_settings":{"depends_on":[],"prominence":"major"}},"auth_type":{"type":"string","enum":["api_key","subscription"],"title":"Auth Type","description":"Authentication mode for the LLM.","default":"api_key","openhands_settings":{"depends_on":[],"label":"Authentication","prominence":"critical"}},"subscription_vendor":{"anyOf":[{"type":"string","const":"openai"},{"type":"null"}],"title":"Subscription Vendor","description":"Subscription provider for subscription-backed LLM access.","openhands_settings":{"depends_on":["auth_type"],"label":"Subscription provider","prominence":"critical"}},"base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url","description":"Custom base URL.","openhands_settings":{"depends_on":[],"prominence":"major"}},"api_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Version","description":"API version (e.g., Azure).","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_access_key_id":{"anyOf":[{"type":"string"},{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Aws Access Key Id","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_secret_access_key":{"anyOf":[{"type":"string"},{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Aws Secret Access Key","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_session_token":{"anyOf":[{"type":"string"},{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Aws Session Token","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_region_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Region Name","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_profile_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Profile Name","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_role_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Role Name","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_session_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Session Name","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_bedrock_runtime_endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Bedrock Runtime Endpoint","openhands_settings":{"depends_on":[],"prominence":"minor"}},"openrouter_site_url":{"type":"string","title":"Openrouter Site Url","default":"https://docs.all-hands.dev/","openhands_settings":{"depends_on":[],"prominence":"minor"}},"openrouter_app_name":{"type":"string","title":"Openrouter App Name","default":"OpenHands","openhands_settings":{"depends_on":[],"prominence":"minor"}},"num_retries":{"type":"integer","minimum":0.0,"title":"Num Retries","default":5,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"retry_multiplier":{"type":"number","minimum":0.0,"title":"Retry Multiplier","default":8.0,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"retry_min_wait":{"type":"integer","minimum":0.0,"title":"Retry Min Wait","default":8,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"retry_max_wait":{"type":"integer","minimum":0.0,"title":"Retry Max Wait","default":64,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"timeout":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Timeout","description":"HTTP and hard per-attempt timeout in seconds. Default is 300s (5 minutes). Set to None to disable the hard timeout.","default":300,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"stream_idle_timeout":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Stream Idle Timeout","description":"Maximum seconds between chunks in an asynchronous streaming response. Default is 300s (5 minutes); set to None to disable.","default":300,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"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,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"temperature":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"top_k":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Top K","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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).","openhands_settings":{"depends_on":[],"prominence":"minor"}},"max_output_tokens":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Output Tokens","description":"The maximum number of output tokens. This is sent to the LLM.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"model_canonical_name":{"anyOf":[{"type":"string"},{"type":"null"}],"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"api_mode":{"type":"string","enum":["auto","chat","responses"],"title":"Api Mode","description":"LLM API endpoint mode. 'auto' resolves from model metadata and SDK fallbacks; use 'chat' or 'responses' to override endpoint selection for proxy aliases and newly released models.","default":"auto","openhands_settings":{"depends_on":[],"prominence":"minor"}},"capability_overrides":{"additionalProperties":{"anyOf":[{"type":"boolean"},{"type":"string"}]},"type":"object","title":"Capability Overrides","description":"Explicit model capability overrides. Supported keys include supports_reasoning_effort, thinking_mode (adaptive, manual, none, or unknown), supports_sampling_params, supports_prompt_cache, supports_stop_words, supports_responses_api, supports_vision, and supports_prompt_cache_retention. Overrides take precedence over LiteLLM metadata and SDK fallbacks.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"extra_headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Extra Headers","description":"Optional HTTP headers to forward to LiteLLM requests.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"input_cost_per_token":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Input Cost Per Token","description":"The cost per input token. This will available in logs for user.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"ollama_base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ollama Base Url","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"drop_params":{"type":"boolean","title":"Drop Params","default":true,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"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).","openhands_settings":{"depends_on":[],"prominence":"minor"}},"disable_stop_word":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Disable Stop Word","description":"Disable using of stop word.","default":false,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"caching_prompt":{"type":"boolean","title":"Caching Prompt","description":"Enable caching of prompts.","default":true,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"log_completions":{"type":"boolean","title":"Log Completions","description":"Enable logging of completions.","default":false,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"log_completions_folder":{"type":"string","title":"Log Completions Folder","description":"The folder to log LLM completions to. Required if log_completions is True.","default":"logs/completions","openhands_settings":{"depends_on":[],"prominence":"minor"}},"custom_tokenizer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Tokenizer","description":"A custom tokenizer to use for token counting.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"native_tool_calling":{"type":"boolean","title":"Native Tool Calling","description":"Whether to use native tool calling.","default":true,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"force_string_serializer":{"anyOf":[{"type":"boolean"},{"type":"null"}],"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"inline_image_urls":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Inline Image Urls","description":"If True, fetch any http(s) image URL in outgoing messages and inline it as a base64 ``data:`` URL before sending. If None (default), auto-detect based on model (some APIs such as Moonshot's public Kimi endpoint reject URL-formatted images and require base64). Set this explicitly when the model is reached through a proxy alias that hides the underlying provider (e.g. ``litellm_proxy/<custom-alias>``). Note: inlining only runs when ``vision_is_active()`` is True, so the alias must still be recognised as vision-capable by the SDK feature registry or proxy model metadata.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"reasoning_effort":{"anyOf":[{"type":"string","enum":["low","medium","high","xhigh","none"]},{"type":"null"}],"title":"Reasoning Effort","description":"Provider-neutral reasoning effort. Common values include 'none', 'minimal', 'low', 'medium', 'high', 'xhigh', and 'max'. The SDK accepts future provider values and lets LiteLLM translate them.","default":"high","openhands_settings":{"depends_on":[],"prominence":"minor"}},"reasoning_summary":{"anyOf":[{"type":"string","enum":["auto","concise","detailed"]},{"type":"null"}],"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"enable_encrypted_reasoning":{"type":"boolean","title":"Enable Encrypted Reasoning","description":"If True, ask for ['reasoning.encrypted_content'] in Responses API include.","default":true,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"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","openhands_settings":{"depends_on":[],"prominence":"minor"}},"extended_thinking_budget":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Extended Thinking Budget","description":"Legacy token budget for models confirmed to use manual Anthropic extended thinking. Ignored for adaptive-thinking models. Prefer reasoning_effort for new integrations.","default":200000,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"The seed to use for random number generation.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"usage_id":{"type":"string","title":"Usage Id","description":"Unique usage identifier for the LLM. Used for registry lookups, telemetry, and spend tracking.","default":"default","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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}","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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","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., \"gpt-5.6\").\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=\"gpt-5.6\",\n        api_key=SecretStr(\"your-api-key\"),\n        usage_id=\"my-agent\"\n    )\n    # Use with agent or conversation\n    ```"},"LLM-Output":{"properties":{"model":{"type":"string","title":"Model","description":"Model name.","default":"gpt-5.6","openhands_settings":{"depends_on":[],"prominence":"critical"}},"api_key":{"anyOf":[{"type":"string"},{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Api Key","description":"API key.","openhands_settings":{"depends_on":[],"label":"API Key","prominence":"critical"}},"provider_connection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Connection Id","description":"Optional provider connection whose shared API key and base URL are resolved and applied each time this LLM profile is loaded (read-at-use). When set, the profile stores no inline api_key or base_url of its own.","openhands_settings":{"depends_on":[],"prominence":"major"}},"auth_type":{"type":"string","enum":["api_key","subscription"],"title":"Auth Type","description":"Authentication mode for the LLM.","default":"api_key","openhands_settings":{"depends_on":[],"label":"Authentication","prominence":"critical"}},"subscription_vendor":{"anyOf":[{"type":"string","const":"openai"},{"type":"null"}],"title":"Subscription Vendor","description":"Subscription provider for subscription-backed LLM access.","openhands_settings":{"depends_on":["auth_type"],"label":"Subscription provider","prominence":"critical"}},"base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url","description":"Custom base URL.","openhands_settings":{"depends_on":[],"prominence":"major"}},"api_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Api Version","description":"API version (e.g., Azure).","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_access_key_id":{"anyOf":[{"type":"string"},{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Aws Access Key Id","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_secret_access_key":{"anyOf":[{"type":"string"},{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Aws Secret Access Key","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_session_token":{"anyOf":[{"type":"string"},{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Aws Session Token","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_region_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Region Name","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_profile_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Profile Name","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_role_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Role Name","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_session_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Session Name","openhands_settings":{"depends_on":[],"prominence":"minor"}},"aws_bedrock_runtime_endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aws Bedrock Runtime Endpoint","openhands_settings":{"depends_on":[],"prominence":"minor"}},"openrouter_site_url":{"type":"string","title":"Openrouter Site Url","default":"https://docs.all-hands.dev/","openhands_settings":{"depends_on":[],"prominence":"minor"}},"openrouter_app_name":{"type":"string","title":"Openrouter App Name","default":"OpenHands","openhands_settings":{"depends_on":[],"prominence":"minor"}},"num_retries":{"type":"integer","minimum":0.0,"title":"Num Retries","default":5,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"retry_multiplier":{"type":"number","minimum":0.0,"title":"Retry Multiplier","default":8.0,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"retry_min_wait":{"type":"integer","minimum":0.0,"title":"Retry Min Wait","default":8,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"retry_max_wait":{"type":"integer","minimum":0.0,"title":"Retry Max Wait","default":64,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"timeout":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Timeout","description":"HTTP and hard per-attempt timeout in seconds. Default is 300s (5 minutes). Set to None to disable the hard timeout.","default":300,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"stream_idle_timeout":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Stream Idle Timeout","description":"Maximum seconds between chunks in an asynchronous streaming response. Default is 300s (5 minutes); set to None to disable.","default":300,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"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,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"temperature":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"top_k":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Top K","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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).","openhands_settings":{"depends_on":[],"prominence":"minor"}},"max_output_tokens":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Output Tokens","description":"The maximum number of output tokens. This is sent to the LLM.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"model_canonical_name":{"anyOf":[{"type":"string"},{"type":"null"}],"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"api_mode":{"type":"string","enum":["auto","chat","responses"],"title":"Api Mode","description":"LLM API endpoint mode. 'auto' resolves from model metadata and SDK fallbacks; use 'chat' or 'responses' to override endpoint selection for proxy aliases and newly released models.","default":"auto","openhands_settings":{"depends_on":[],"prominence":"minor"}},"capability_overrides":{"additionalProperties":{"anyOf":[{"type":"boolean"},{"type":"string"}]},"type":"object","title":"Capability Overrides","description":"Explicit model capability overrides. Supported keys include supports_reasoning_effort, thinking_mode (adaptive, manual, none, or unknown), supports_sampling_params, supports_prompt_cache, supports_stop_words, supports_responses_api, supports_vision, and supports_prompt_cache_retention. Overrides take precedence over LiteLLM metadata and SDK fallbacks.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"extra_headers":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Extra Headers","description":"Optional HTTP headers to forward to LiteLLM requests.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"input_cost_per_token":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Input Cost Per Token","description":"The cost per input token. This will available in logs for user.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"ollama_base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ollama Base Url","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"drop_params":{"type":"boolean","title":"Drop Params","default":true,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"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).","openhands_settings":{"depends_on":[],"prominence":"minor"}},"disable_stop_word":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Disable Stop Word","description":"Disable using of stop word.","default":false,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"caching_prompt":{"type":"boolean","title":"Caching Prompt","description":"Enable caching of prompts.","default":true,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"log_completions":{"type":"boolean","title":"Log Completions","description":"Enable logging of completions.","default":false,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"log_completions_folder":{"type":"string","title":"Log Completions Folder","description":"The folder to log LLM completions to. Required if log_completions is True.","default":"logs/completions","openhands_settings":{"depends_on":[],"prominence":"minor"}},"custom_tokenizer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Tokenizer","description":"A custom tokenizer to use for token counting.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"native_tool_calling":{"type":"boolean","title":"Native Tool Calling","description":"Whether to use native tool calling.","default":true,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"force_string_serializer":{"anyOf":[{"type":"boolean"},{"type":"null"}],"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"inline_image_urls":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Inline Image Urls","description":"If True, fetch any http(s) image URL in outgoing messages and inline it as a base64 ``data:`` URL before sending. If None (default), auto-detect based on model (some APIs such as Moonshot's public Kimi endpoint reject URL-formatted images and require base64). Set this explicitly when the model is reached through a proxy alias that hides the underlying provider (e.g. ``litellm_proxy/<custom-alias>``). Note: inlining only runs when ``vision_is_active()`` is True, so the alias must still be recognised as vision-capable by the SDK feature registry or proxy model metadata.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"reasoning_effort":{"anyOf":[{"type":"string","enum":["low","medium","high","xhigh","none"]},{"type":"null"}],"title":"Reasoning Effort","description":"Provider-neutral reasoning effort. Common values include 'none', 'minimal', 'low', 'medium', 'high', 'xhigh', and 'max'. The SDK accepts future provider values and lets LiteLLM translate them.","default":"high","openhands_settings":{"depends_on":[],"prominence":"minor"}},"reasoning_summary":{"anyOf":[{"type":"string","enum":["auto","concise","detailed"]},{"type":"null"}],"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.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"enable_encrypted_reasoning":{"type":"boolean","title":"Enable Encrypted Reasoning","description":"If True, ask for ['reasoning.encrypted_content'] in Responses API include.","default":true,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"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","openhands_settings":{"depends_on":[],"prominence":"minor"}},"extended_thinking_budget":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Extended Thinking Budget","description":"Legacy token budget for models confirmed to use manual Anthropic extended thinking. Ignored for adaptive-thinking models. Prefer reasoning_effort for new integrations.","default":200000,"openhands_settings":{"depends_on":[],"prominence":"minor"}},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"The seed to use for random number generation.","openhands_settings":{"depends_on":[],"prominence":"minor"}},"usage_id":{"type":"string","title":"Usage Id","description":"Unique usage identifier for the LLM. Used for registry lookups, telemetry, and spend tracking.","default":"default","openhands_settings":{"depends_on":[],"prominence":"minor"}},"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}","openhands_settings":{"depends_on":[],"prominence":"minor"}},"is_subscription":{"type":"boolean","title":"Is Subscription","description":"Whether this LLM uses subscription-based authentication. Serialized so that subscription-specific request handling survives transport to a remote agent-server.","readOnly":true}},"type":"object","required":["is_subscription"],"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., \"gpt-5.6\").\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=\"gpt-5.6\",\n        api_key=SecretStr(\"your-api-key\"),\n        usage_id=\"my-agent\"\n    )\n    # Use with agent or conversation\n    ```"},"LLMCompletionLogEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"filename":{"type":"string","title":"Filename","description":"The intended filename for this log (relative to log directory)"},"log_data":{"type":"string","title":"Log Data","description":"The JSON-encoded log data to be written to the file"},"model_name":{"type":"string","title":"Model Name","description":"The model name for context","default":"unknown"},"usage_id":{"type":"string","title":"Usage Id","description":"The LLM usage_id that produced this log","default":"default"},"kind":{"type":"string","const":"LLMCompletionLogEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["filename","log_data","kind"],"title":"LLMCompletionLogEvent","description":"Event containing LLM completion log data.\n\nWhen an LLM is configured with log_completions=True in a remote conversation,\nthis event streams the completion log data back to the client through WebSocket\ninstead of writing it to a file inside the Docker container."},"LLMSecurityAnalyzer-Input":{"properties":{"kind":{"type":"string","const":"LLMSecurityAnalyzer","title":"Kind"}},"type":"object","title":"LLMSecurityAnalyzer","description":"LLM-based security analyzer.\n\nThis analyzer respects the security_risk attribute that can be set by the LLM\nwhen generating actions, similar to OpenHands' LLMRiskAnalyzer.\n\nIt provides a lightweight security analysis approach that leverages the LLM's\nunderstanding of action context and potential risks."},"LLMSecurityAnalyzer-Output":{"properties":{"kind":{"type":"string","const":"LLMSecurityAnalyzer","title":"Kind"}},"type":"object","required":["kind"],"title":"LLMSecurityAnalyzer","description":"LLM-based security analyzer.\n\nThis analyzer respects the security_risk attribute that can be set by the LLM\nwhen generating actions, similar to OpenHands' LLMRiskAnalyzer.\n\nIt provides a lightweight security analysis approach that leverages the LLM's\nunderstanding of action context and potential risks."},"LLMSummarizingCondenser-Input":{"properties":{"llm":{"$ref":"#/components/schemas/LLM-Input"},"max_size":{"type":"integer","exclusiveMinimum":0.0,"title":"Max Size","default":240},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens"},"keep_first":{"type":"integer","minimum":0.0,"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,"title":"Hard Context Reset Max Retries","default":5},"hard_context_reset_context_scaling":{"type":"number","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"title":"Hard Context Reset Context Scaling","default":0.8},"kind":{"type":"string","const":"LLMSummarizingCondenser","title":"Kind"}},"type":"object","required":["llm"],"title":"LLMSummarizingCondenser","description":"LLM-based condenser that summarizes forgotten events.\n\nUses an independent LLM (stored in the `llm` attribute) for generating summaries\nof forgotten events. The optional `agent_llm` parameter passed to condense() is\nthe LLM used by the agent for token counting purposes, and you should not assume\nit is the same as the one defined in this condenser."},"LLMSummarizingCondenser-Output":{"properties":{"llm":{"$ref":"#/components/schemas/LLM-Output"},"max_size":{"type":"integer","exclusiveMinimum":0.0,"title":"Max Size","default":240},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens"},"keep_first":{"type":"integer","minimum":0.0,"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,"title":"Hard Context Reset Max Retries","default":5},"hard_context_reset_context_scaling":{"type":"number","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"title":"Hard Context Reset Context Scaling","default":0.8},"kind":{"type":"string","const":"LLMSummarizingCondenser","title":"Kind"}},"type":"object","required":["llm","kind"],"title":"LLMSummarizingCondenser","description":"LLM-based condenser that summarizes forgotten events.\n\nUses an independent LLM (stored in the `llm` attribute) for generating summaries\nof forgotten events. The optional `agent_llm` parameter passed to condense() is\nthe LLM used by the agent for token counting purposes, and you should not assume\nit is the same as the one defined in this condenser."},"LLMSummarizingCondenserSettings":{"properties":{"condenser_kind":{"type":"string","const":"llm_summarizing","title":"Condenser Kind","description":"Discriminator for the condenser settings union. ``'llm_summarizing'`` selects the default LLM summarizing condenser.","default":"llm_summarizing","openhands_settings":{"depends_on":[],"prominence":"minor"}},"enabled":{"type":"boolean","title":"Enabled","description":"Enable conversation memory condensation.","default":true,"openhands_settings":{"depends_on":[],"label":"Enable memory condensation","prominence":"critical"}},"max_size":{"type":"integer","minimum":20.0,"title":"Max Size","description":"Maximum number of events kept before the condenser runs. Kept on the base settings class for compatibility; concrete condenser-settings variants may opt out when this does not apply.","default":240,"openhands_settings":{"depends_on":["enabled"],"label":"Max size","prominence":"minor"}},"max_tokens":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Max Tokens","description":"Maximum number of tokens allowed before the condenser runs. When unset, condensation is only based on event count.","openhands_settings":{"depends_on":["enabled"],"label":"Max tokens","prominence":"minor"}},"keep_first":{"type":"integer","minimum":0.0,"title":"Keep First","description":"Minimum number of initial events to preserve before condensation.","default":2,"openhands_settings":{"depends_on":["enabled"],"label":"Keep first","prominence":"minor"}},"minimum_progress":{"type":"number","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"title":"Minimum Progress","description":"Minimum fraction of events that must be condensed for condensation to be considered successful.","default":0.1,"openhands_settings":{"depends_on":["enabled"],"label":"Minimum progress","prominence":"minor"}},"hard_context_reset_max_retries":{"type":"integer","exclusiveMinimum":0.0,"title":"Hard Context Reset Max Retries","description":"Number of hard context reset attempts before raising an error.","default":5,"openhands_settings":{"depends_on":["enabled"],"label":"Hard reset retries","prominence":"minor"}},"hard_context_reset_context_scaling":{"type":"number","exclusiveMaximum":1.0,"exclusiveMinimum":0.0,"title":"Hard Context Reset Context Scaling","description":"Factor used to reduce event string size after a hard context reset summarization failure.","default":0.8,"openhands_settings":{"depends_on":["enabled"],"label":"Hard reset scaling","prominence":"minor"}}},"type":"object","title":"LLMSummarizingCondenserSettings","description":"Settings for the default LLM summarizing condenser."},"LaunchedAgentProfile":{"properties":{"agent_profile_id":{"type":"string","format":"uuid","title":"Agent Profile Id","description":"Stable id of the agent profile that launched the conversation."},"revision":{"type":"integer","minimum":0.0,"title":"Revision","description":"Revision of the agent profile at launch time."},"secret_refs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Secret Refs","description":"Secret allow-list captured at launch, also enforced on resume. null preserves unrestricted behavior for older conversations."}},"type":"object","required":["agent_profile_id","revision"],"title":"LaunchedAgentProfile","description":"Provenance snapshot recorded when an agent profile launches a conversation.\n\nStored on ``StoredConversation`` and projected onto ``ConversationInfo`` so\nts-client ``deriveSwitchPlan`` can identify which agent profile is current\nwithout fragile settings-comparison. See #3720."},"ListDirectoryAction":{"properties":{"dir_path":{"type":"string","title":"Dir Path","description":"The path to the directory to list. Defaults to current directory.","default":"."},"recursive":{"type":"boolean","title":"Recursive","description":"Whether to list subdirectories recursively (up to 2 levels).","default":false},"kind":{"type":"string","const":"ListDirectoryAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"ListDirectoryAction","description":"Schema for list directory operation."},"ListDirectoryObservation":{"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},"dir_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dir Path","description":"The directory path that was listed."},"entries":{"items":{"$ref":"#/components/schemas/FileEntry"},"type":"array","title":"Entries","description":"List of files and directories found."},"total_count":{"type":"integer","title":"Total Count","description":"Total number of entries found.","default":0},"is_truncated":{"type":"boolean","title":"Is Truncated","description":"Whether the listing was truncated due to too many entries.","default":false},"kind":{"type":"string","const":"ListDirectoryObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"ListDirectoryObservation","description":"Observation from listing a directory."},"ListDirectoryTool":{"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":{"type":"string","const":"ListDirectoryTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"ListDirectoryTool","description":"Tool for listing directory contents with metadata."},"LocalWorkspace-Input":{"properties":{"working_dir":{"type":"string","title":"Working Dir","description":"The working directory for agent operations and tool execution. Accepts both string paths and Path objects. Path objects are automatically converted to strings."},"kind":{"type":"string","const":"LocalWorkspace","title":"Kind"}},"type":"object","required":["working_dir"],"title":"LocalWorkspace","description":"Local workspace implementation that operates on the host filesystem.\n\nLocalWorkspace provides direct access to the local filesystem and command execution\nenvironment. It's suitable for development and testing scenarios where the agent\nshould operate directly on the host system.\n\nExample:\n    >>> workspace = LocalWorkspace(working_dir=\"/path/to/project\")\n    >>> with workspace:\n    ...     result = workspace.execute_command(\"ls -la\")\n    ...     content = workspace.read_file(\"README.md\")"},"LocalWorkspace-Output":{"properties":{"working_dir":{"type":"string","title":"Working Dir","description":"The working directory for agent operations and tool execution. Accepts both string paths and Path objects. Path objects are automatically converted to strings."},"kind":{"type":"string","const":"LocalWorkspace","title":"Kind"}},"type":"object","required":["working_dir","kind"],"title":"LocalWorkspace","description":"Local workspace implementation that operates on the host filesystem.\n\nLocalWorkspace provides direct access to the local filesystem and command execution\nenvironment. It's suitable for development and testing scenarios where the agent\nshould operate directly on the host system.\n\nExample:\n    >>> workspace = LocalWorkspace(working_dir=\"/path/to/project\")\n    >>> with workspace:\n    ...     result = workspace.execute_command(\"ls -la\")\n    ...     content = workspace.read_file(\"README.md\")"},"LookupSecret-Input":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description for this secret"},"url":{"type":"string","title":"Url"},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers"},"kind":{"type":"string","const":"LookupSecret","title":"Kind"}},"type":"object","required":["url"],"title":"LookupSecret","description":"A secret looked up from some external url"},"LookupSecret-Output":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description for this secret"},"url":{"type":"string","title":"Url"},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers"},"kind":{"type":"string","const":"LookupSecret","title":"Kind"}},"type":"object","required":["url","kind"],"title":"LookupSecret","description":"A secret looked up from some external url"},"MCPApiKeyAuthCredential-Input":{"properties":{"strategy":{"type":"string","const":"api_key","title":"Strategy"},"value":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Value"},"header_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Header Name"}},"type":"object","required":["strategy"],"title":"MCPApiKeyAuthCredential"},"MCPApiKeyAuthCredential-Output":{"properties":{"strategy":{"type":"string","const":"api_key","title":"Strategy"},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value"},"header_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Header Name"}},"type":"object","required":["strategy"],"title":"MCPApiKeyAuthCredential"},"MCPBasicAuthCredential-Input":{"properties":{"strategy":{"type":"string","const":"basic","title":"Strategy"},"username":{"type":"string","title":"Username"},"password":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Password"}},"type":"object","required":["strategy","username"],"title":"MCPBasicAuthCredential"},"MCPBasicAuthCredential-Output":{"properties":{"strategy":{"type":"string","const":"basic","title":"Strategy"},"username":{"type":"string","title":"Username"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Password"}},"type":"object","required":["strategy","username"],"title":"MCPBasicAuthCredential"},"MCPBearerAuthCredential-Input":{"properties":{"strategy":{"type":"string","const":"bearer","title":"Strategy"},"value":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Value"}},"type":"object","required":["strategy"],"title":"MCPBearerAuthCredential"},"MCPBearerAuthCredential-Output":{"properties":{"strategy":{"type":"string","const":"bearer","title":"Strategy"},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value"}},"type":"object","required":["strategy"],"title":"MCPBearerAuthCredential"},"MCPConfig":{"additionalProperties":{"$ref":"#/components/schemas/MCPServer-Output"},"type":"object","title":"MCPConfig","description":"Canonical persisted MCP server map keyed by stable server name."},"MCPConfigPatch":{"additionalProperties":{"anyOf":[{"$ref":"#/components/schemas/MCPServerPatch"},{"type":"null"}]},"type":"object","title":"MCPConfigPatch","description":"Sparse MCP map patch; a null map value deletes that named server."},"MCPHeaderAuthCredential-Input":{"properties":{"strategy":{"type":"string","const":"header","title":"Strategy"},"headers":{"additionalProperties":{"type":"string","format":"password","writeOnly":true},"type":"object","title":"Headers"}},"type":"object","required":["strategy"],"title":"MCPHeaderAuthCredential"},"MCPHeaderAuthCredential-Output":{"properties":{"strategy":{"type":"string","const":"header","title":"Strategy"},"headers":{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object","title":"Headers"}},"type":"object","required":["strategy"],"title":"MCPHeaderAuthCredential"},"MCPNoneAuthCredential":{"properties":{"strategy":{"type":"string","const":"none","title":"Strategy"}},"type":"object","required":["strategy"],"title":"MCPNoneAuthCredential"},"MCPOAuthAuthCredential-Input":{"properties":{"strategy":{"type":"string","const":"oauth2","title":"Strategy"},"authentication":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthAuthentication-Input"},{"type":"null"}]},"state":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthState-Input"},{"type":"null"}]}},"type":"object","required":["strategy"],"title":"MCPOAuthAuthCredential"},"MCPOAuthAuthCredential-Output":{"properties":{"strategy":{"type":"string","const":"oauth2","title":"Strategy"},"authentication":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthAuthentication-Output"},{"type":"null"}]},"state":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthState-Output"},{"type":"null"}]}},"type":"object","required":["strategy"],"title":"MCPOAuthAuthCredential"},"MCPOAuthAuthentication-Input":{"properties":{"type":{"type":"string","const":"oauth","title":"Type"},"client_auth_method":{"anyOf":[{"type":"string","enum":["none","client_secret_post","client_secret_basic","private_key_jwt"]},{"type":"null"}],"title":"Client Auth Method"},"scopes":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Scopes"},"client_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Name"},"client_metadata_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Metadata Url"},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"client_secret":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Client Secret"},"additional_client_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Additional Client Metadata"}},"additionalProperties":false,"type":"object","required":["type"],"title":"MCPOAuthAuthentication"},"MCPOAuthAuthentication-Output":{"properties":{"type":{"type":"string","const":"oauth","title":"Type"},"client_auth_method":{"anyOf":[{"type":"string","enum":["none","client_secret_post","client_secret_basic","private_key_jwt"]},{"type":"null"}],"title":"Client Auth Method"},"scopes":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Scopes"},"client_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Name"},"client_metadata_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Metadata Url"},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret"},"additional_client_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Additional Client Metadata"}},"additionalProperties":false,"type":"object","required":["type"],"title":"MCPOAuthAuthentication"},"MCPOAuthCallbackRequest":{"properties":{"callback_url":{"type":"string","minLength":1,"title":"Callback Url"}},"type":"object","required":["callback_url"],"title":"MCPOAuthCallbackRequest","description":"Callback URL copied from a browser OAuth redirect."},"MCPOAuthClientInfoState-Input":{"properties":{"client_secret":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Client Secret"}},"additionalProperties":true,"type":"object","title":"MCPOAuthClientInfoState"},"MCPOAuthClientInfoState-Output":{"properties":{"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret"}},"additionalProperties":true,"type":"object","title":"MCPOAuthClientInfoState"},"MCPOAuthStartResponse":{"properties":{"ok":{"type":"boolean","title":"Ok"},"job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Id"},"authorization_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization Url"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"error_kind":{"anyOf":[{"type":"string","enum":["timeout","connection","unknown"]},{"type":"null"}],"title":"Error Kind"}},"type":"object","required":["ok"],"title":"MCPOAuthStartResponse","description":"Response for starting an install-time OAuth MCP probe."},"MCPOAuthState-Input":{"properties":{"tokens":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthTokenState-Input"},{"type":"null"}]},"client_info":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthClientInfoState-Input"},{"type":"null"}]},"token_expires_at":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Token Expires At"}},"type":"object","title":"MCPOAuthState"},"MCPOAuthState-Output":{"properties":{"tokens":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthTokenState-Output"},{"type":"null"}]},"client_info":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthClientInfoState-Output"},{"type":"null"}]},"token_expires_at":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Token Expires At"}},"type":"object","title":"MCPOAuthState"},"MCPOAuthStateResponse":{"properties":{"tokens":{"anyOf":[{"properties":{"access_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Token"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"}},"additionalProperties":true,"type":"object","title":"MCPOAuthTokenState"},{"type":"null"}],"title":"Tokens"},"client_info":{"anyOf":[{"properties":{"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret"}},"additionalProperties":true,"type":"object","title":"MCPOAuthClientInfoState"},{"type":"null"}],"title":"Client Info"},"token_expires_at":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Token Expires At"}},"type":"object","title":"MCPOAuthStateResponse"},"MCPOAuthStatusResponse":{"properties":{"ok":{"type":"boolean","title":"Ok"},"status":{"type":"string","enum":["pending","authorizing","succeeded","failed"],"title":"Status"},"job_id":{"type":"string","title":"Job Id"},"authorization_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization Url"},"callback_ready":{"type":"boolean","title":"Callback Ready","default":false},"tools":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tools"},"tool_result":{"anyOf":[{"$ref":"#/components/schemas/MCPToolCallResult"},{"type":"null"}]},"oauth_state":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthStateResponse"},{"type":"null"}]},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"error_kind":{"anyOf":[{"type":"string","enum":["timeout","connection","unknown"]},{"type":"null"}],"title":"Error Kind"}},"type":"object","required":["ok","status","job_id"],"title":"MCPOAuthStatusResponse","description":"Current state of an install-time OAuth MCP probe."},"MCPOAuthTokenState-Input":{"properties":{"access_token":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Access Token"},"refresh_token":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Refresh Token"}},"additionalProperties":true,"type":"object","title":"MCPOAuthTokenState"},"MCPOAuthTokenState-Output":{"properties":{"access_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Token"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"}},"additionalProperties":true,"type":"object","title":"MCPOAuthTokenState"},"MCPServer-Input":{"properties":{"url":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Url"},"transport":{"anyOf":[{"type":"string","enum":["stdio","http","sse","streamable-http"]},{"type":"null"}],"title":"Transport"},"command":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Command"},"args":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Args"},"env":{"anyOf":[{"additionalProperties":{"type":"string","format":"password","writeOnly":true},"type":"object"},{"type":"null"}],"title":"Env"},"cwd":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cwd"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"timeout":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Timeout"},"sse_read_timeout":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sse Read Timeout"},"keep_alive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Keep Alive"},"headers":{"anyOf":[{"additionalProperties":{"type":"string","format":"password","writeOnly":true},"type":"object"},{"type":"null"}],"title":"Headers"},"auth":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/MCPNoneAuthCredential"},{"$ref":"<redacted:api_key>"},{"$ref":"#/components/schemas/MCPBearerAuthCredential-Input"},{"$ref":"#/components/schemas/MCPBasicAuthCredential-Input"},{"$ref":"#/components/schemas/MCPHeaderAuthCredential-Input"},{"$ref":"#/components/schemas/MCPOAuthAuthCredential-Input"}],"discriminator":{"propertyName":"strategy","mapping":{"api_key":"<redacted:api_key>","basic":"#/components/schemas/MCPBasicAuthCredential-Input","bearer":"#/components/schemas/MCPBearerAuthCredential-Input","header":"#/components/schemas/MCPHeaderAuthCredential-Input","none":"#/components/schemas/MCPNoneAuthCredential","oauth2":"#/components/schemas/MCPOAuthAuthCredential-Input"}}},{"type":"null"}],"title":"Auth"},"enabled":{"type":"boolean","title":"Enabled","description":"Whether this server is exposed to the agent. A disabled server stays fully configured -- including its secrets -- but is skipped when MCP tools are created and when servers are forwarded to an ACP subprocess.","default":true}},"additionalProperties":false,"type":"object","title":"MCPServer","description":"One MCP server in the settings DataModel."},"MCPServer-Output":{"properties":{"url":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Url"},"transport":{"anyOf":[{"type":"string","enum":["stdio","http","sse","streamable-http"]},{"type":"null"}],"title":"Transport"},"command":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Command"},"args":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Args"},"env":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Env"},"cwd":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cwd"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"timeout":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Timeout"},"sse_read_timeout":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sse Read Timeout"},"keep_alive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Keep Alive"},"headers":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Headers"},"auth":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/MCPNoneAuthCredential"},{"$ref":"<redacted:api_key>"},{"$ref":"#/components/schemas/MCPBearerAuthCredential-Output"},{"$ref":"#/components/schemas/MCPBasicAuthCredential-Output"},{"$ref":"#/components/schemas/MCPHeaderAuthCredential-Output"},{"$ref":"#/components/schemas/MCPOAuthAuthCredential-Output"}],"discriminator":{"propertyName":"strategy","mapping":{"api_key":"<redacted:api_key>","basic":"#/components/schemas/MCPBasicAuthCredential-Output","bearer":"#/components/schemas/MCPBearerAuthCredential-Output","header":"#/components/schemas/MCPHeaderAuthCredential-Output","none":"#/components/schemas/MCPNoneAuthCredential","oauth2":"#/components/schemas/MCPOAuthAuthCredential-Output"}}},{"type":"null"}],"title":"Auth"},"enabled":{"type":"boolean","title":"Enabled","description":"Whether this server is exposed to the agent. A disabled server stays fully configured -- including its secrets -- but is skipped when MCP tools are created and when servers are forwarded to an ACP subprocess.","default":true}},"additionalProperties":false,"type":"object","title":"MCPServer","description":"One MCP server in the settings DataModel."},"MCPServerPatch":{"properties":{"url":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Url"},"transport":{"anyOf":[{"type":"string","enum":["stdio","http","sse","streamable-http"]},{"type":"null"}],"title":"Transport"},"command":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Command"},"args":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Args"},"env":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Env"},"cwd":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cwd"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"icon":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon"},"timeout":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Timeout"},"sse_read_timeout":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sse Read Timeout"},"keep_alive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Keep Alive"},"headers":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}]},"type":"object"},{"type":"null"}],"title":"Headers"},"auth":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/MCPNoneAuthCredential"},{"$ref":"<redacted:api_key>"},{"$ref":"#/components/schemas/MCPBearerAuthCredential-Input"},{"$ref":"#/components/schemas/MCPBasicAuthCredential-Input"},{"$ref":"#/components/schemas/MCPHeaderAuthCredential-Input"},{"$ref":"#/components/schemas/MCPOAuthAuthCredential-Input"}],"discriminator":{"propertyName":"strategy","mapping":{"api_key":"<redacted:api_key>","basic":"#/components/schemas/MCPBasicAuthCredential-Input","bearer":"#/components/schemas/MCPBearerAuthCredential-Input","header":"#/components/schemas/MCPHeaderAuthCredential-Input","none":"#/components/schemas/MCPNoneAuthCredential","oauth2":"#/components/schemas/MCPOAuthAuthCredential-Input"}}},{"type":"null"}],"title":"Auth"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled","description":"Switch the server off (false) or back on (true) without touching the rest of its configuration. A null clears the override, which restores the canonical default (enabled)."}},"additionalProperties":false,"type":"object","title":"MCPServerPatch","description":"Sparse RFC 7386 merge patch for one persisted MCP server."},"MCPTestFailure":{"properties":{"ok":{"type":"boolean","const":false,"title":"Ok","default":false},"error":{"type":"string","title":"Error","description":"Human-readable error message."},"error_kind":{"type":"string","enum":["timeout","connection","unknown"],"title":"Error Kind","description":"Coarse error classification, useful for branching UI."}},"type":"object","required":["error","error_kind"],"title":"MCPTestFailure","description":"Response when the candidate server fails to connect or list tools.\n\nThe endpoint returns HTTP 200 in both success and failure cases: a\nfailure here is the *expected* outcome of validating a user-supplied\nconfig, not a server-side error. The structured shape makes it easy\nfor the UI to render an actionable message."},"MCPTestRequest":{"properties":{"name":{"type":"string","maxLength":128,"minLength":1,"title":"Name","description":"Name to use for the server inside the temporary MCP server map. Only affects error messages -- does not need to match any persisted setting.","default":"test-server"},"server":{"oneOf":[{"$ref":"#/components/schemas/_StdioMCPServerSpec"},{"$ref":"#/components/schemas/_RemoteMCPServerSpec"}],"title":"Server","discriminator":{"propertyName":"type","mapping":{"http":"#/components/schemas/_RemoteMCPServerSpec","shttp":"#/components/schemas/_RemoteMCPServerSpec","sse":"#/components/schemas/_RemoteMCPServerSpec","stdio":"#/components/schemas/_StdioMCPServerSpec","streamable-http":"#/components/schemas/_RemoteMCPServerSpec"}}},"timeout":{"type":"number","maximum":120.0,"exclusiveMinimum":0.0,"title":"Timeout","description":"Seconds to wait for connection + tools/list to complete.","default":15.0},"tool_call":{"anyOf":[{"$ref":"#/components/schemas/MCPToolCallSpec"},{"type":"null"}],"description":"Optional read-only tool to invoke after listing succeeds, so callers can verify credentials the server only exercises on tool invocation. Its outcome is reported verbatim in `tool_result` without affecting `ok`."}},"type":"object","required":["server"],"title":"MCPTestRequest","description":"Body for ``POST /api/mcp/test``."},"MCPTestSuccess":{"properties":{"ok":{"type":"boolean","const":true,"title":"Ok","default":true},"tools":{"items":{"type":"string"},"type":"array","title":"Tools","description":"Names of tools advertised by the MCP server."},"tool_result":{"anyOf":[{"$ref":"#/components/schemas/MCPToolCallResult"},{"type":"null"}],"description":"Outcome of the requested `tool_call`, when one was supplied."},"resolved_mcp_servers":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Resolved Mcp Servers","description":"Deprecated compatibility field for older clients that expected resolved MCP server metadata in test responses.","deprecated":true},"oauth_state":{"anyOf":[{"$ref":"#/components/schemas/MCPOAuthStateResponse"},{"type":"null"}],"description":"Serialized OAuth state acquired or refreshed by the probe. Clients should persist this under the tested server's auth.state."}},"type":"object","title":"MCPTestSuccess","description":"Response when the candidate server connects and lists its tools."},"MCPToolAction":{"properties":{"data":{"additionalProperties":true,"type":"object","title":"Data","description":"Dynamic data fields from the tool call"},"kind":{"type":"string","const":"MCPToolAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"MCPToolAction","description":"Schema for MCP input action.\n\nIt is just a thin wrapper around raw JSON and does\nnot do any validation.\n\nValidation will be performed by MCPTool.__call__\nby constructing dynamically created Pydantic model\nfrom the MCP tool input schema."},"MCPToolCallResult":{"properties":{"is_error":{"type":"boolean","title":"Is Error","description":"The MCP-level isError flag of the result."},"text":{"type":"string","title":"Text","description":"Concatenated text content of the result."}},"type":"object","required":["is_error","text"],"title":"MCPToolCallResult","description":"Verbatim outcome of the requested ``tool_call``.\n\nThe endpoint stays provider-neutral: many servers report upstream\nfailures (e.g. Slack's ``{\"ok\": false, \"error\": \"invalid_auth\"}``)\nas ordinary text content with ``isError`` unset, so interpreting the\npayload is the caller's job."},"MCPToolCallSpec":{"properties":{"name":{"type":"string","minLength":1,"title":"Name","description":"Name of the tool to invoke"},"arguments":{"additionalProperties":true,"type":"object","title":"Arguments","description":"Arguments passed to the tool unchanged."}},"type":"object","required":["name"],"title":"MCPToolCallSpec","description":"A single tool invocation to run as part of the connection test.\n\nListing tools does not exercise the credentials many servers only use\ninside tool handlers, so callers can name one tool to invoke after the\nlisting succeeds. Callers are responsible for choosing a read-only tool;\nthe endpoint executes it verbatim."},"MCPToolDefinition":{"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"},"mcp_tool":{"$ref":"#/components/schemas/mcp__types__Tool","description":"The MCP tool definition."},"kind":{"type":"string","const":"MCPToolDefinition","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","mcp_tool","kind","title"],"title":"MCPToolDefinition","description":"MCP Tool that wraps an MCP client and provides tool functionality."},"MCPToolObservation":{"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},"tool_name":{"type":"string","title":"Tool Name","description":"Name of the tool that was called"},"kind":{"type":"string","const":"MCPToolObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["tool_name","kind"],"title":"MCPToolObservation","description":"Observation from MCP tool execution."},"MarketplacePluginInfo":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"source":{"type":"string","title":"Source"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref"},"repo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Path"},"installed":{"type":"boolean","title":"Installed"},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path"},"skills":{"anyOf":[{"items":{"$ref":"#/components/schemas/PluginSkillSummary"},"type":"array"},{"type":"null"}],"title":"Skills"},"files":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Files"}},"type":"object","required":["name","description","source","installed"],"title":"MarketplacePluginInfo","description":"A true plugin in the marketplace catalog, with attach coordinates."},"MarketplaceRegistration":{"properties":{"name":{"type":"string","title":"Name","description":"Identifier for this marketplace registration"},"source":{"type":"string","title":"Source","description":"Marketplace source: 'github:owner/repo', git URL, or local path"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref","description":"Optional branch, tag, or commit for git sources"},"repo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Path","description":"Subdirectory path within the git repository containing the marketplace. Only relevant for git sources."},"auto_load":{"anyOf":[{"type":"boolean"},{"items":{"type":"string"},"type":"array"}],"title":"Auto Load","description":"Whether to load marketplace plugins and standalone skills at conversation start. Use True for all, False or [] for none, or a list of plugin/skill names for selective loading.","default":false}},"type":"object","required":["name","source"],"title":"MarketplaceRegistration","description":"Registration for a marketplace source used for plugin resolution."},"MarketplaceSkillInfo":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"source":{"type":"string","title":"Source"},"installed":{"type":"boolean","title":"Installed"}},"type":"object","required":["name","description","source","installed"],"title":"MarketplaceSkillInfo","description":"Information about a skill in the marketplace catalog."},"MaterializeAgentProfileRequest":{"properties":{"profile":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/OpenHandsAgentProfile"},{"$ref":"#/components/schemas/ACPAgentProfile"}]},{"type":"null"}],"title":"Profile","description":"Draft profile to evaluate instead of the stored one. The path name overrides the draft's name."}},"additionalProperties":false,"type":"object","title":"MaterializeAgentProfileRequest"},"Message":{"properties":{"role":{"type":"string","enum":["user","system","assistant","tool"],"title":"Role"},"content":{"items":{"anyOf":[{"$ref":"#/components/schemas/TextContent"},{"$ref":"#/components/schemas/ImageContent"}]},"type":"array","title":"Content"},"tool_calls":{"anyOf":[{"items":{"$ref":"#/components/schemas/MessageToolCall"},"type":"array"},{"type":"null"}],"title":"Tool Calls"},"tool_call_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tool Call Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"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":"Raw Anthropic thinking blocks for extended thinking feature"},"responses_reasoning_item":{"anyOf":[{"$ref":"#/components/schemas/ReasoningItemModel"},{"type":"null"}],"description":"OpenAI Responses reasoning item from model output"}},"type":"object","required":["role"],"title":"Message"},"MessageEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"llm_message":{"$ref":"#/components/schemas/Message","description":"The exact LLM message for this message event"},"llm_response_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Llm Response Id","description":"Completion or Response ID of the LLM response that generated this eventIf the source != 'agent', this field is None"},"activated_skills":{"items":{"type":"string"},"type":"array","title":"Activated Skills","description":"List of activated skill name"},"extended_content":{"items":{"$ref":"#/components/schemas/TextContent"},"type":"array","title":"Extended Content","description":"List of content added by agent context"},"sender":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sender","description":"Optional identifier of the sender. Can be used to track message origin in multi-agent scenarios."},"critic_result":{"anyOf":[{"$ref":"#/components/schemas/CriticResult"},{"type":"null"}],"description":"Optional critic evaluation of this message and preceding history."},"kind":{"type":"string","const":"MessageEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["source","llm_message","kind"],"title":"MessageEvent","description":"Message from either agent or user.\n\nThis is originally the \"MessageAction\", but it suppose not to be tool call."},"MessageToolCall":{"properties":{"id":{"type":"string","title":"Id","description":"Canonical tool call id"},"responses_item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Responses Item Id","description":"Original Responses function_call.id, echoed verbatim on replay"},"name":{"type":"string","title":"Name","description":"Tool/function name"},"arguments":{"type":"string","title":"Arguments","description":"JSON string of arguments"},"origin":{"type":"string","enum":["completion","responses"],"title":"Origin","description":"Originating API family"}},"type":"object","required":["id","name","arguments","origin"],"title":"MessageToolCall","description":"Transport-agnostic tool call representation.\n\nOne canonical id is used for linking across actions/observations and\nfor Responses function_call_output call_id."},"MetaProfile":{"properties":{"classifier_model":{"type":"string","title":"Classifier Model","description":"Name of the saved LLM profile used to classify the task."},"classes":{"items":{"$ref":"#/components/schemas/MetaProfileClass"},"type":"array","title":"Classes","description":"Ordered list of task classes and their target profiles."},"prompt_template":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt Template","description":"Optional direct-routing prompt template. When set, the classifier receives this rendered prompt and should return JSON with a `model` field instead of a class number."},"model_table":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Table","description":"Optional text inserted into `{{ model_table }}` for direct-routing prompts."}},"type":"object","required":["classifier_model"],"title":"MetaProfile","description":"A declarative model-routing configuration."},"MetaProfileClass":{"properties":{"description":{"type":"string","title":"Description","description":"Natural-language description of the kind of task this class covers (e.g. 'task is UI oriented or requires looking at images')."},"model":{"type":"string","title":"Model","description":"Name of the saved LLM profile to switch to for tasks matching this class."}},"type":"object","required":["description","model"],"title":"MetaProfileClass","description":"A single task category and the LLM profile that should handle it."},"MetaProfileDetailResponse":{"properties":{"name":{"type":"string","title":"Name"},"config":{"$ref":"#/components/schemas/MetaProfile"}},"type":"object","required":["name","config"],"title":"MetaProfileDetailResponse"},"MetaProfileInfo":{"properties":{"name":{"type":"string","title":"Name"},"classifier_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Classifier Model"},"num_classes":{"type":"integer","title":"Num Classes","default":0}},"type":"object","required":["name"],"title":"MetaProfileInfo"},"MetaProfileListResponse":{"properties":{"meta_profiles":{"items":{"$ref":"#/components/schemas/MetaProfileInfo"},"type":"array","title":"Meta Profiles"},"active_meta_profile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Meta Profile"}},"type":"object","required":["meta_profiles"],"title":"MetaProfileListResponse"},"MetaProfileMutationResponse":{"properties":{"name":{"type":"string","title":"Name"},"message":{"type":"string","title":"Message"}},"type":"object","required":["name","message"],"title":"MetaProfileMutationResponse"},"Metrics":{"properties":{"model_name":{"type":"string","title":"Model Name","description":"Name of the model","default":"default"},"accumulated_cost":{"type":"number","minimum":0.0,"title":"Accumulated Cost","description":"Total accumulated cost, must be non-negative","default":0.0},"max_budget_per_task":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Budget Per Task","description":"Maximum budget per task"},"accumulated_token_usage":{"anyOf":[{"$ref":"#/components/schemas/TokenUsage"},{"type":"null"}],"description":"Accumulated token usage across all calls"},"costs":{"items":{"$ref":"#/components/schemas/Cost"},"type":"array","title":"Costs","description":"List of individual costs"},"response_latencies":{"items":{"$ref":"#/components/schemas/ResponseLatency"},"type":"array","title":"Response Latencies","description":"List of response latencies"},"token_usages":{"items":{"$ref":"#/components/schemas/TokenUsage"},"type":"array","title":"Token Usages","description":"List of token usage records"}},"type":"object","title":"Metrics","description":"Metrics class can record various metrics during running and evaluation.\nWe track:\n  - accumulated_cost and costs\n  - max_budget_per_task (budget limit)\n  - A list of ResponseLatency\n  - A list of TokenUsage (one per call)."},"MetricsSnapshot":{"properties":{"model_name":{"type":"string","title":"Model Name","description":"Name of the model","default":"default"},"accumulated_cost":{"type":"number","minimum":0.0,"title":"Accumulated Cost","description":"Total accumulated cost, must be non-negative","default":0.0},"max_budget_per_task":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Budget Per Task","description":"Maximum budget per task"},"accumulated_token_usage":{"anyOf":[{"$ref":"#/components/schemas/TokenUsage"},{"type":"null"}],"description":"Accumulated token usage across all calls"}},"type":"object","title":"MetricsSnapshot","description":"A snapshot of metrics at a point in time.\n\nDoes not include lists of individual costs, latencies, or token usages."},"Model":{"properties":{"id":{"type":"string","title":"Id"},"created":{"type":"integer","title":"Created"},"object":{"type":"string","const":"model","title":"Object"},"owned_by":{"type":"string","title":"Owned By"}},"additionalProperties":true,"type":"object","required":["id","created","object","owned_by"],"title":"Model","description":"Describes an OpenAI model offering that can be used with the API."},"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."},"NavigateConversationRequest":{"properties":{"event_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Id","description":"Event to make the new HEAD, re-rooting the active branch the agent runs on. All branches stay on disk; this creates no new conversation. ``None`` selects the empty tree."}},"type":"object","title":"NavigateConversationRequest","description":"Payload to move a conversation's HEAD to an existing event."},"NeverConfirm-Input":{"properties":{"kind":{"type":"string","const":"NeverConfirm","title":"Kind"}},"type":"object","title":"NeverConfirm"},"NeverConfirm-Output":{"properties":{"kind":{"type":"string","const":"NeverConfirm","title":"Kind"}},"type":"object","required":["kind"],"title":"NeverConfirm"},"NoOpCondenser-Input":{"properties":{"kind":{"type":"string","const":"NoOpCondenser","title":"Kind"}},"type":"object","title":"NoOpCondenser","description":"Simple condenser that returns a view un-manipulated.\n\nPrimarily intended for testing purposes."},"NoOpCondenser-Output":{"properties":{"kind":{"type":"string","const":"NoOpCondenser","title":"Kind"}},"type":"object","required":["kind"],"title":"NoOpCondenser","description":"Simple condenser that returns a view un-manipulated.\n\nPrimarily intended for testing purposes."},"NoOpCondenserSettings":{"properties":{"condenser_kind":{"type":"string","const":"no_op","title":"Condenser Kind","description":"Discriminator for the condenser settings union. ``'no_op'`` selects a condenser that leaves conversation views unchanged.","default":"no_op","openhands_settings":{"depends_on":[],"prominence":"minor"}},"enabled":{"type":"boolean","title":"Enabled","description":"Enable conversation memory condensation.","default":true,"openhands_settings":{"depends_on":[],"label":"Enable memory condensation","prominence":"critical"}}},"type":"object","title":"NoOpCondenserSettings","description":"Settings for a condenser that leaves conversation views unchanged."},"Observation":{"oneOf":[{"$ref":"#/components/schemas/MCPToolObservation"},{"$ref":"#/components/schemas/ClassifyAndSwitchLLMObservation"},{"$ref":"#/components/schemas/FinishObservation"},{"$ref":"#/components/schemas/InvokeSkillObservation"},{"$ref":"#/components/schemas/SwitchLLMObservation"},{"$ref":"#/components/schemas/ThinkObservation"},{"$ref":"#/components/schemas/VisionInspectObservation"},{"$ref":"#/components/schemas/ClientToolObservation"},{"$ref":"#/components/schemas/AskOracleObservation"},{"$ref":"#/components/schemas/BrowserObservation"},{"$ref":"#/components/schemas/DelegateObservation"},{"$ref":"#/components/schemas/FileEditorObservation"},{"$ref":"#/components/schemas/EditObservation"},{"$ref":"#/components/schemas/ListDirectoryObservation"},{"$ref":"#/components/schemas/ReadFileObservation"},{"$ref":"#/components/schemas/WriteFileObservation"},{"$ref":"#/components/schemas/GlobObservation"},{"$ref":"#/components/schemas/GrepObservation"},{"$ref":"#/components/schemas/PlanningFileEditorObservation"},{"$ref":"#/components/schemas/TaskObservation"},{"$ref":"#/components/schemas/TaskTrackerObservation"},{"$ref":"#/components/schemas/TerminalObservation"},{"$ref":"#/components/schemas/WorkflowObservation"}],"discriminator":{"propertyName":"kind","mapping":{"openhands__sdk__mcp__definition__MCPToolObservation-Output__1":"#/components/schemas/MCPToolObservation","openhands__sdk__tool__builtins__classify_and_switch_llm__ClassifyAndSwitchLLMObservation-Output__1":"#/components/schemas/ClassifyAndSwitchLLMObservation","openhands__sdk__tool__builtins__finish__FinishObservation-Output__1":"#/components/schemas/FinishObservation","openhands__sdk__tool__builtins__invoke_skill__InvokeSkillObservation-Output__1":"#/components/schemas/InvokeSkillObservation","openhands__sdk__tool__builtins__switch_llm__SwitchLLMObservation-Output__1":"#/components/schemas/SwitchLLMObservation","openhands__sdk__tool__builtins__think__ThinkObservation-Output__1":"#/components/schemas/ThinkObservation","openhands__sdk__tool__builtins__vision_inspect__VisionInspectObservation-Output__1":"#/components/schemas/VisionInspectObservation","openhands__sdk__tool__client_tool__ClientToolObservation-Output__1":"#/components/schemas/ClientToolObservation","openhands__tools__ask_oracle__definition__AskOracleObservation-Output__1":"#/components/schemas/AskOracleObservation","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","openhands__tools__gemini__read_file__definition__ReadFileObservation-Output__1":"#/components/schemas/ReadFileObservation","openhands__tools__gemini__write_file__definition__WriteFileObservation-Output__1":"#/components/schemas/WriteFileObservation","openhands__tools__glob__definition__GlobObservation-Output__1":"#/components/schemas/GlobObservation","openhands__tools__grep__definition__GrepObservation-Output__1":"#/components/schemas/GrepObservation","openhands__tools__planning_file_editor__definition__PlanningFileEditorObservation-Output__1":"#/components/schemas/PlanningFileEditorObservation","openhands__tools__task__definition__TaskObservation-Output__1":"#/components/schemas/TaskObservation","openhands__tools__task_tracker__definition__TaskTrackerObservation-Output__1":"#/components/schemas/TaskTrackerObservation","openhands__tools__terminal__definition__TerminalObservation-Output__1":"#/components/schemas/TerminalObservation","openhands__tools__workflow__definition__WorkflowObservation-Output__1":"#/components/schemas/WorkflowObservation"}}},"ObservationEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"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"},"observation":{"$ref":"#/components/schemas/Observation","description":"The observation (tool call) sent to LLM"},"action_id":{"type":"string","title":"Action Id","description":"The action id that this observation is responding to"},"extended_content":{"items":{"$ref":"#/components/schemas/TextContent"},"type":"array","title":"Extended Content","description":"Content added by agent context (e.g. path-scoped rules triggered by the touched file), appended after the tool result in to_llm_message."},"kind":{"type":"string","const":"ObservationEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["tool_name","tool_call_id","observation","action_id","kind"],"title":"ObservationEvent"},"OpenAIChatCompletionRequest":{"properties":{"model":{"type":"string","title":"Model"},"messages":{"items":{"$ref":"#/components/schemas/OpenAIChatMessage"},"type":"array","title":"Messages"},"stream":{"type":"boolean","title":"Stream","default":false},"stream_options":{"anyOf":[{"$ref":"#/components/schemas/OpenAIStreamOptions"},{"type":"null"}]}},"type":"object","required":["model","messages"],"title":"OpenAIChatCompletionRequest"},"OpenAIChatMessage":{"properties":{"role":{"type":"string","enum":["system","developer","user","assistant","tool"],"title":"Role"},"content":{"anyOf":[{"type":"string"},{"items":{"$ref":"#/components/schemas/OpenAIContentPart"},"type":"array"},{"type":"null"}],"title":"Content"}},"type":"object","required":["role"],"title":"OpenAIChatMessage"},"OpenAIContentPart":{"properties":{"type":{"type":"string","title":"Type"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"image_url":{"anyOf":[{"$ref":"#/components/schemas/OpenAIImageURL"},{"type":"string"},{"type":"null"}],"title":"Image Url"}},"type":"object","required":["type"],"title":"OpenAIContentPart"},"OpenAIImageURL":{"properties":{"url":{"type":"string","title":"Url"}},"type":"object","required":["url"],"title":"OpenAIImageURL"},"OpenAIModelListResponse":{"properties":{"object":{"type":"string","const":"list","title":"Object","default":"list"},"data":{"items":{"$ref":"#/components/schemas/Model"},"type":"array","title":"Data"}},"type":"object","required":["data"],"title":"OpenAIModelListResponse"},"OpenAIResponse":{"properties":{"id":{"type":"string","title":"Id"},"created_at":{"type":"number","title":"Created At"},"completed_at":{"type":"number","title":"Completed At"},"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instructions"},"metadata":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Metadata"},"model":{"type":"string","title":"Model"},"object":{"type":"string","const":"response","title":"Object","default":"response"},"output":{"items":{"$ref":"#/components/schemas/OpenAIResponseOutputMessage"},"type":"array","title":"Output"},"parallel_tool_calls":{"type":"boolean","title":"Parallel Tool Calls","default":false},"previous_response_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Response Id"},"status":{"type":"string","const":"completed","title":"Status","default":"completed"},"tool_choice":{"type":"string","const":"none","title":"Tool Choice","default":"none"},"tools":{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array","title":"Tools"},"usage":{"$ref":"#/components/schemas/OpenAIResponseUsage"}},"type":"object","required":["id","created_at","completed_at","model","output","tools","usage"],"title":"OpenAIResponse"},"OpenAIResponseInputContentPart":{"properties":{"type":{"type":"string","title":"Type"},"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"}},"type":"object","required":["type"],"title":"OpenAIResponseInputContentPart"},"OpenAIResponseInputMessage":{"properties":{"role":{"type":"string","enum":["system","developer","user","assistant"],"title":"Role"},"content":{"anyOf":[{"type":"string"},{"items":{"$ref":"#/components/schemas/OpenAIResponseInputContentPart"},"type":"array"}],"title":"Content"}},"type":"object","required":["role","content"],"title":"OpenAIResponseInputMessage"},"OpenAIResponseInputTokensDetails":{"properties":{"cached_tokens":{"type":"integer","title":"Cached Tokens"}},"type":"object","required":["cached_tokens"],"title":"OpenAIResponseInputTokensDetails"},"OpenAIResponseOutputMessage":{"properties":{"id":{"type":"string","title":"Id"},"content":{"items":{"$ref":"#/components/schemas/OpenAIResponseOutputText"},"type":"array","title":"Content"},"role":{"type":"string","const":"assistant","title":"Role","default":"assistant"},"status":{"type":"string","const":"completed","title":"Status","default":"completed"},"type":{"type":"string","const":"message","title":"Type","default":"message"}},"type":"object","required":["id","content"],"title":"OpenAIResponseOutputMessage"},"OpenAIResponseOutputText":{"properties":{"annotations":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Annotations"},"text":{"type":"string","title":"Text"},"type":{"type":"string","const":"output_text","title":"Type","default":"output_text"}},"type":"object","required":["annotations","text"],"title":"OpenAIResponseOutputText"},"OpenAIResponseOutputTokensDetails":{"properties":{"reasoning_tokens":{"type":"integer","title":"Reasoning Tokens"}},"type":"object","required":["reasoning_tokens"],"title":"OpenAIResponseOutputTokensDetails"},"OpenAIResponseRequest":{"properties":{"model":{"type":"string","title":"Model"},"input":{"anyOf":[{"type":"string"},{"items":{"$ref":"#/components/schemas/OpenAIResponseInputMessage"},"type":"array"}],"title":"Input"},"instructions":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instructions"},"previous_response_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Response Id"},"store":{"type":"boolean","title":"Store","default":false},"stream":{"type":"boolean","title":"Stream","default":false},"metadata":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Metadata"}},"type":"object","required":["model","input"],"title":"OpenAIResponseRequest"},"OpenAIResponseUsage":{"properties":{"input_tokens":{"type":"integer","title":"Input Tokens"},"input_tokens_details":{"$ref":"#/components/schemas/OpenAIResponseInputTokensDetails"},"output_tokens":{"type":"integer","title":"Output Tokens"},"output_tokens_details":{"$ref":"#/components/schemas/OpenAIResponseOutputTokensDetails"},"total_tokens":{"type":"integer","title":"Total Tokens"}},"type":"object","required":["input_tokens","input_tokens_details","output_tokens","output_tokens_details","total_tokens"],"title":"OpenAIResponseUsage"},"OpenAIStreamOptions":{"properties":{"include_usage":{"type":"boolean","title":"Include Usage","default":false}},"type":"object","title":"OpenAIStreamOptions"},"OpenHandsAgentProfile":{"properties":{"schema_version":{"type":"integer","minimum":1.0,"title":"Schema Version","default":3},"agent_kind":{"type":"string","const":"openhands","title":"Agent Kind","description":"Discriminator for the ``AgentProfile`` union. ``'openhands'`` selects the standard built-in OpenHands agent.","default":"openhands"},"id":{"type":"string","format":"uuid","title":"Id","description":"Stable provenance handle for this profile. Conversations record this UUID; it never changes, even when the profile is renamed."},"name":{"type":"string","minLength":1,"title":"Name","description":"Human-facing, renameable key shown in the profile picker."},"revision":{"type":"integer","minimum":0.0,"title":"Revision","description":"Monotonic revision counter, bumped on each saved edit.","default":0},"mcp_server_refs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Mcp Server Refs","description":"Which of the user's globally configured MCP servers to expose. null = all; [] = none; a non-null list = filter to the named keys."},"secret_refs":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Secret Refs","description":"Which of the user's saved secrets to expose to this agent. null = all; [] = none; a non-null list = filter to the named keys. Strict: nothing is added back. An ACP profile must list its own provider credential to receive it."},"llm_profile_ref":{"type":"string","minLength":1,"title":"Llm Profile Ref","description":"Name of the saved LLM profile to resolve for this agent. The profile itself stores no LLM credential — it lives on the referenced LLM profile."},"agent":{"type":"string","title":"Agent","description":"Agent class to build.","default":"CodeActAgent"},"tools":{"anyOf":[{"items":{"$ref":"#/components/schemas/Tool-Input"},"type":"array"},{"type":"null"}],"title":"Tools","description":"Tool selection for the resolved agent. None (the default) = the server's standard tool set; [] = an explicitly bare agent; a non-empty list is used exactly as given."},"persona":{"anyOf":[{"type":"string","maxLength":65536,"minLength":1},{"type":"null"}],"title":"Persona","description":"Persona text that replaces OpenHands' built-in persona and coding-workflow guidance. Capability and policy guidance (memory, security policy, risk assessment, browser, external services, process management, model-specific notes) and the dynamic context are still included. None keeps the built-in persona."},"system_message_suffix":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"System Message Suffix","description":"Optional suffix appended to the system prompt."},"disabled_skills":{"items":{"type":"string"},"type":"array","title":"Disabled Skills","description":"Names of server-discovered skills to EXCLUDE from this agent's prompt — a deny-list over the discovered catalog. [] (the default) = all discovered skills; a listed name that is absent from the catalog is simply a no-op, so the field never fails a launch when the catalog drifts. Replaces the former allow-list ``skill_refs`` (#4017): skills are discovered from many incomplete sources, so exclusion is the only selection model that can't dangle."},"condenser":{"oneOf":[{"$ref":"#/components/schemas/LLMSummarizingCondenserSettings"},{"$ref":"#/components/schemas/NoOpCondenserSettings"}],"title":"Condenser","description":"Condenser settings for the agent."},"verification":{"$ref":"#/components/schemas/ProfileVerificationSettings","description":"Critic/verification policy (secret-free; no critic_api_key)."},"enable_classify_and_switch_llm_tool":{"type":"boolean","title":"Enable Classify And Switch Llm Tool","description":"Enable the built-in route_task_to_model tool, which routes the task to an LLM profile using the meta-profile named by `meta_profile_ref`.","default":false},"meta_profile_ref":{"anyOf":[{"type":"string","minLength":1},{"type":"null"}],"title":"Meta Profile Ref","description":"Name of the saved meta-profile the routing tool uses. The launch copies it and the LLM profiles it routes to into the agent, so a runtime without the stores can still route. null lets the tool fall back to the first meta-profile in the runtime's store."},"tool_concurrency_limit":{"type":"integer","minimum":1.0,"title":"Tool Concurrency Limit","description":"Maximum number of tool calls to execute concurrently per agent step. 1 = sequential (default).","default":1}},"additionalProperties":false,"type":"object","required":["name","llm_profile_ref"],"title":"OpenHandsAgentProfile","description":"``agent_kind=\"openhands\"`` profile — references an LLM profile by name.\n\nMirrors the configurable surface of\n:class:`~openhands.sdk.settings.model.OpenHandsAgentSettings`, except the\nconcrete ``llm`` is replaced by :attr:`llm_profile_ref` (resolved against\nthe LLM profile store) and ``mcp_config`` by the inherited\n:attr:`~AgentProfileBase.mcp_server_refs`."},"OrgConfig":{"properties":{"repository":{"type":"string","title":"Repository","description":"Selected repository (e.g., 'owner/repo')"},"provider":{"type":"string","title":"Provider","description":"Git provider type: github, gitlab, azure, bitbucket"},"org_repo_url":{"type":"string","title":"Org Repo Url","description":"Pre-authenticated Git URL for the organization repository. Contains sensitive credentials - handle with care and avoid logging."},"org_name":{"type":"string","title":"Org Name","description":"Organization name"}},"type":"object","required":["repository","provider","org_repo_url","org_name"],"title":"OrgConfig","description":"Configuration for loading organization-level skills."},"PassCritic-Input":{"properties":{"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":"PassCritic","title":"Kind"}},"type":"object","title":"PassCritic","description":"Critic that always returns success.\n\nThis critic can be used when no evaluation is needed or when\nall instances should be considered successful regardless of their output."},"PassCritic-Output":{"properties":{"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":"PassCritic","title":"Kind"}},"type":"object","required":["kind"],"title":"PassCritic","description":"Critic that always returns success.\n\nThis critic can be used when no evaluation is needed or when\nall instances should be considered successful regardless of their output."},"PathTrigger":{"properties":{"type":{"type":"string","const":"path","title":"Type","default":"path"},"paths":{"items":{"type":"string"},"type":"array","title":"Paths"}},"type":"object","required":["paths"],"title":"PathTrigger","description":"Trigger for path-scoped skills (\"rules\").\n\nThese skills are activated when the agent touches a file whose path matches\none of the ``paths`` glob patterns (gitignore-style ``**`` semantics)."},"PatternSecurityAnalyzer-Input":{"properties":{"high_patterns":{"items":{"prefixItems":[{"type":"string"},{"type":"string"},{"type":"string"}],"type":"array","maxItems":3,"minItems":3},"type":"array","title":"High Patterns","description":"HIGH patterns scanned against executable fields only"},"medium_patterns":{"items":{"prefixItems":[{"type":"string"},{"type":"string"},{"type":"string"}],"type":"array","maxItems":3,"minItems":3},"type":"array","title":"Medium Patterns","description":"MEDIUM patterns scanned against executable fields only"},"injection_high_patterns":{"items":{"prefixItems":[{"type":"string"},{"type":"string"},{"type":"string"}],"type":"array","maxItems":3,"minItems":3},"type":"array","title":"Injection High Patterns","description":"HIGH patterns scanned against all fields"},"injection_medium_patterns":{"items":{"prefixItems":[{"type":"string"},{"type":"string"},{"type":"string"}],"type":"array","maxItems":3,"minItems":3},"type":"array","title":"Injection Medium Patterns","description":"MEDIUM patterns scanned against all fields"},"kind":{"type":"string","const":"PatternSecurityAnalyzer","title":"Kind"}},"type":"object","title":"PatternSecurityAnalyzer","description":"Catch dangerous agent actions through deterministic signature scanning.\n\nUse this when you want fast, local, no-network threat detection at the\naction boundary. It returns ``SecurityRisk.HIGH``, ``MEDIUM``, or ``LOW``\n-- pair it with ``ConfirmRisky`` to decide what gets confirmed.\n\nThe key design choice: shell-destructive patterns only scan what the\nagent will *execute* (tool arguments), never what it *thought about*\n(reasoning text). Injection patterns scan everything, because\n\"ignore all previous instructions\" is dangerous wherever it appears.\n\nNormalization is always on -- invisible characters and fullwidth\nsubstitutions are collapsed before matching.\n\nExample::\n\n    from openhands.sdk.security import PatternSecurityAnalyzer, ConfirmRisky\n\n    analyzer = PatternSecurityAnalyzer()\n    policy = ConfirmRisky(threshold=SecurityRisk.MEDIUM)"},"PatternSecurityAnalyzer-Output":{"properties":{"high_patterns":{"items":{"prefixItems":[{"type":"string"},{"type":"string"},{"type":"string"}],"type":"array","maxItems":3,"minItems":3},"type":"array","title":"High Patterns","description":"HIGH patterns scanned against executable fields only"},"medium_patterns":{"items":{"prefixItems":[{"type":"string"},{"type":"string"},{"type":"string"}],"type":"array","maxItems":3,"minItems":3},"type":"array","title":"Medium Patterns","description":"MEDIUM patterns scanned against executable fields only"},"injection_high_patterns":{"items":{"prefixItems":[{"type":"string"},{"type":"string"},{"type":"string"}],"type":"array","maxItems":3,"minItems":3},"type":"array","title":"Injection High Patterns","description":"HIGH patterns scanned against all fields"},"injection_medium_patterns":{"items":{"prefixItems":[{"type":"string"},{"type":"string"},{"type":"string"}],"type":"array","maxItems":3,"minItems":3},"type":"array","title":"Injection Medium Patterns","description":"MEDIUM patterns scanned against all fields"},"kind":{"type":"string","const":"PatternSecurityAnalyzer","title":"Kind"}},"type":"object","required":["kind"],"title":"PatternSecurityAnalyzer","description":"Catch dangerous agent actions through deterministic signature scanning.\n\nUse this when you want fast, local, no-network threat detection at the\naction boundary. It returns ``SecurityRisk.HIGH``, ``MEDIUM``, or ``LOW``\n-- pair it with ``ConfirmRisky`` to decide what gets confirmed.\n\nThe key design choice: shell-destructive patterns only scan what the\nagent will *execute* (tool arguments), never what it *thought about*\n(reasoning text). Injection patterns scan everything, because\n\"ignore all previous instructions\" is dangerous wherever it appears.\n\nNormalization is always on -- invisible characters and fullwidth\nsubstitutions are collapsed before matching.\n\nExample::\n\n    from openhands.sdk.security import PatternSecurityAnalyzer, ConfirmRisky\n\n    analyzer = PatternSecurityAnalyzer()\n    policy = ConfirmRisky(threshold=SecurityRisk.MEDIUM)"},"PauseEvent":{"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":"user"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"kind":{"type":"string","const":"PauseEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"PauseEvent","description":"Event indicating that the agent execution was paused by user request."},"PipelineCondenser-Input":{"properties":{"condensers":{"items":{"$ref":"#/components/schemas/CondenserBase-Input"},"type":"array","title":"Condensers"},"kind":{"type":"string","const":"PipelineCondenser","title":"Kind"}},"type":"object","required":["condensers"],"title":"PipelineCondenser","description":"A condenser that applies a sequence of condensers in order.\n\nAll condensers are defined primarily by their `condense` method, which takes a\n`View` and an optional `agent_llm` parameter, returning either a new `View` or a\n`Condensation` event. That means we can chain multiple condensers together by\npassing `View`s along and exiting early if any condenser returns a `Condensation`.\n\nFor example:\n\n    # Use the pipeline condenser to chain multiple other condensers together\n    condenser = PipelineCondenser(condensers=[\n        CondenserA(...),\n        CondenserB(...),\n        CondenserC(...),\n    ])\n\n    result = condenser.condense(view, agent_llm=agent_llm)\n\n    # Doing the same thing without the pipeline condenser requires more boilerplate\n    # for the monadic chaining\n    other_result = view\n\n    if isinstance(other_result, View):\n        other_result = CondenserA(...).condense(other_result, agent_llm=agent_llm)\n\n    if isinstance(other_result, View):\n        other_result = CondenserB(...).condense(other_result, agent_llm=agent_llm)\n\n    if isinstance(other_result, View):\n        other_result = CondenserC(...).condense(other_result, agent_llm=agent_llm)\n\n    assert result == other_result"},"PipelineCondenser-Output":{"properties":{"condensers":{"items":{"$ref":"#/components/schemas/CondenserBase-Output"},"type":"array","title":"Condensers"},"kind":{"type":"string","const":"PipelineCondenser","title":"Kind"}},"type":"object","required":["condensers","kind"],"title":"PipelineCondenser","description":"A condenser that applies a sequence of condensers in order.\n\nAll condensers are defined primarily by their `condense` method, which takes a\n`View` and an optional `agent_llm` parameter, returning either a new `View` or a\n`Condensation` event. That means we can chain multiple condensers together by\npassing `View`s along and exiting early if any condenser returns a `Condensation`.\n\nFor example:\n\n    # Use the pipeline condenser to chain multiple other condensers together\n    condenser = PipelineCondenser(condensers=[\n        CondenserA(...),\n        CondenserB(...),\n        CondenserC(...),\n    ])\n\n    result = condenser.condense(view, agent_llm=agent_llm)\n\n    # Doing the same thing without the pipeline condenser requires more boilerplate\n    # for the monadic chaining\n    other_result = view\n\n    if isinstance(other_result, View):\n        other_result = CondenserA(...).condense(other_result, agent_llm=agent_llm)\n\n    if isinstance(other_result, View):\n        other_result = CondenserB(...).condense(other_result, agent_llm=agent_llm)\n\n    if isinstance(other_result, View):\n        other_result = CondenserC(...).condense(other_result, agent_llm=agent_llm)\n\n    assert result == other_result"},"PlanningFileEditorAction":{"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`."},"path":{"type":"string","title":"Path","description":"Absolute path to file or directory."},"file_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Text","description":"Required parameter of `create` command, with the content of the file to be created."},"old_str":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Str","description":"Required parameter of `str_replace` command containing the string in `path` to replace."},"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":"PlanningFileEditorAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["command","path","kind"],"title":"PlanningFileEditorAction","description":"Schema for planning file editor operations.\n\nInherits from FileEditorAction but restricts editing to PLAN.md only.\nAllows viewing any file but only editing PLAN.md."},"PlanningFileEditorObservation":{"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},"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`."},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path","description":"The file path that was edited."},"prev_exist":{"type":"boolean","title":"Prev Exist","description":"Indicates if the file previously existed. If not, it was created.","default":true},"old_content":{"anyOf":[{"type":"string"},{"type":"null"}],"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":"PlanningFileEditorObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["command","kind"],"title":"PlanningFileEditorObservation","description":"Observation from planning file editor operations.\n\nInherits from FileEditorObservation - same structure, just different type."},"PlanningFileEditorTool":{"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":{"type":"string","const":"PlanningFileEditorTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"PlanningFileEditorTool","description":"A planning file editor tool with read-all, edit-PLAN.md-only access."},"PluginInfo":{"properties":{"name":{"type":"string","title":"Name"},"version":{"type":"string","title":"Version","default":""},"description":{"type":"string","title":"Description","default":""},"path":{"type":"string","title":"Path","description":"Path to the plugin directory","default":""},"skills":{"items":{"$ref":"#/components/schemas/PluginSkillSummary"},"type":"array","title":"Skills","description":"Skills bundled in the plugin"},"files":{"items":{"type":"string"},"type":"array","title":"Files","description":"Plugin files, relative to the plugin directory"}},"type":"object","required":["name"],"title":"PluginInfo","description":"Summary of an available plugin."},"PluginSkillSummary":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["name"],"title":"PluginSkillSummary","description":"Summary of a skill bundled in a plugin."},"PluginSource":{"properties":{"source":{"type":"string","title":"Source","description":"Plugin source: 'github:owner/repo', any git URL, or local path"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref","description":"Optional branch, tag, or commit (only for git sources)"},"repo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Path","description":"Subdirectory path within the git repository (e.g., 'plugins/my-plugin' for monorepos). Only relevant for git sources, not local paths."}},"type":"object","required":["source"],"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\")"},"PluginsRequest":{"properties":{"load_user":{"type":"boolean","title":"Load User","description":"Load user plugins (~/.agents/plugins, etc.)","default":true},"load_project":{"type":"boolean","title":"Load Project","description":"Load project plugins from the workspace","default":true},"project_dir":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Dir","description":"Workspace directory path for project plugins"}},"type":"object","title":"PluginsRequest","description":"Request body for listing locally-available plugins."},"PluginsResponse":{"properties":{"plugins":{"items":{"$ref":"#/components/schemas/PluginInfo"},"type":"array","title":"Plugins"}},"type":"object","required":["plugins"],"title":"PluginsResponse","description":"Response containing the locally-available plugins."},"PolicyRailSecurityAnalyzer-Input":{"properties":{"kind":{"type":"string","const":"PolicyRailSecurityAnalyzer","title":"Kind"}},"type":"object","title":"PolicyRailSecurityAnalyzer","description":"Catch composed threats that plain regex signatures would miss.\n\nUse this when you need to detect threats defined by *combinations*\nof tokens (e.g., ``curl`` piped to ``bash``) rather than individual\nsignatures. While these rails *could* each be expressed as a single\nregex, keeping them as named rules with per-segment evaluation makes\nthe threat model more interpretable, the rules easier to maintain,\nand the audit trail clearer than a flat pattern list.\n\nEvaluates normalized executable segments only -- reasoning text is\nnever scanned.\n\nReturns ``SecurityRisk.HIGH`` when a rail fires, ``LOW`` otherwise.\nPair with ``ConfirmRisky`` and compose via ``EnsembleSecurityAnalyzer``.\n\nv1 rails: fetch-to-exec, raw-disk-op, catastrophic-delete.\n\nExample::\n\n    from openhands.sdk.security import PolicyRailSecurityAnalyzer\n\n    analyzer = PolicyRailSecurityAnalyzer()\n    # risk = analyzer.security_risk(action)"},"PolicyRailSecurityAnalyzer-Output":{"properties":{"kind":{"type":"string","const":"PolicyRailSecurityAnalyzer","title":"Kind"}},"type":"object","required":["kind"],"title":"PolicyRailSecurityAnalyzer","description":"Catch composed threats that plain regex signatures would miss.\n\nUse this when you need to detect threats defined by *combinations*\nof tokens (e.g., ``curl`` piped to ``bash``) rather than individual\nsignatures. While these rails *could* each be expressed as a single\nregex, keeping them as named rules with per-segment evaluation makes\nthe threat model more interpretable, the rules easier to maintain,\nand the audit trail clearer than a flat pattern list.\n\nEvaluates normalized executable segments only -- reasoning text is\nnever scanned.\n\nReturns ``SecurityRisk.HIGH`` when a rail fires, ``LOW`` otherwise.\nPair with ``ConfirmRisky`` and compose via ``EnsembleSecurityAnalyzer``.\n\nv1 rails: fetch-to-exec, raw-disk-op, catastrophic-delete.\n\nExample::\n\n    from openhands.sdk.security import PolicyRailSecurityAnalyzer\n\n    analyzer = PolicyRailSecurityAnalyzer()\n    # risk = analyzer.security_risk(action)"},"ProfileDetailResponse":{"properties":{"name":{"type":"string","title":"Name"},"config":{"additionalProperties":true,"type":"object","title":"Config"},"api_key_set":{"type":"boolean","title":"Api Key Set","default":false}},"type":"object","required":["name","config"],"title":"ProfileDetailResponse","description":"Secrets are nulled unless explicitly requested via X-Expose-Secrets."},"ProfileInfo":{"properties":{"name":{"type":"string","title":"Name"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url"},"provider_connection_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Connection Id"},"provider_connection_broken":{"type":"boolean","title":"Provider Connection Broken","default":false},"api_key_set":{"type":"boolean","title":"Api Key Set","default":false}},"type":"object","required":["name"],"title":"ProfileInfo"},"ProfileListResponse":{"properties":{"profiles":{"items":{"$ref":"#/components/schemas/ProfileInfo"},"type":"array","title":"Profiles"},"active_profile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Profile"}},"type":"object","required":["profiles"],"title":"ProfileListResponse"},"ProfileMutationResponse":{"properties":{"name":{"type":"string","title":"Name"},"message":{"type":"string","title":"Message"}},"type":"object","required":["name","message"],"title":"ProfileMutationResponse"},"ProfileVerificationSettings":{"properties":{"critic_enabled":{"type":"boolean","title":"Critic Enabled","default":false},"critic_mode":{"type":"string","enum":["finish_and_message","all_actions"],"title":"Critic Mode","default":"finish_and_message"},"enable_iterative_refinement":{"type":"boolean","title":"Enable Iterative Refinement","default":false},"critic_threshold":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Critic Threshold","default":0.6},"max_refinement_iterations":{"type":"integer","minimum":1.0,"title":"Max Refinement Iterations","default":3},"critic_server_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Critic Server Url"},"critic_model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Critic Model Name"}},"type":"object","title":"ProfileVerificationSettings","description":"Secret-free critic/refinement policy for a profile.\n\nThe non-credential subset of\n:class:`~openhands.sdk.settings.model.VerificationSettings`: ``critic_api_key``\nis omitted so the profile holds no secret. The critic reuses the resolved\nLLM profile's key (the existing ``critic_api_key=None`` behavior)."},"PromptTokensDetails":{"properties":{"audio_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Audio Tokens"},"cached_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cached Tokens"}},"additionalProperties":true,"type":"object","title":"PromptTokensDetails","description":"Breakdown of tokens used in the prompt."},"ProviderConnectionCreateRequest":{"properties":{"display_name":{"type":"string","maxLength":128,"minLength":1,"title":"Display Name"},"provider":{"type":"string","maxLength":128,"minLength":1,"title":"Provider","default":"custom"},"api_key":{"type":"string","minLength":1,"format":"password","title":"Api Key","writeOnly":true},"base_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Base Url"}},"additionalProperties":false,"type":"object","required":["display_name","api_key"],"title":"ProviderConnectionCreateRequest"},"ProviderConnectionResponse":{"properties":{"id":{"type":"string","title":"Id"},"display_name":{"type":"string","title":"Display Name"},"provider":{"type":"string","title":"Provider"},"base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url"},"created_at":{"type":"integer","title":"Created At"},"updated_at":{"type":"integer","title":"Updated At"},"api_key_set":{"type":"boolean","title":"Api Key Set","default":false}},"type":"object","required":["id","display_name","provider","created_at","updated_at"],"title":"ProviderConnectionResponse"},"ProviderConnectionUpdateRequest":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":128,"minLength":1},{"type":"null"}],"title":"Display Name"},"provider":{"anyOf":[{"type":"string","maxLength":128,"minLength":1},{"type":"null"}],"title":"Provider"},"api_key":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Api Key"},"base_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Base Url"}},"additionalProperties":false,"type":"object","title":"ProviderConnectionUpdateRequest"},"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":{"type":"string","title":"File Path","description":"The path to the file to read."},"offset":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Offset","description":"Optional: The 0-based line number to start reading from. Use for paginating through large files."},"limit":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Limit","description":"Optional: Maximum number of lines to read. Use with 'offset' to paginate through large files."},"kind":{"type":"string","const":"ReadFileAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["file_path","kind"],"title":"ReadFileAction","description":"Schema for read file operation."},"ReadFileObservation":{"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},"file_path":{"type":"string","title":"File Path","description":"The file path that was read."},"file_content":{"type":"string","title":"File Content","description":"The content read from the file.","default":""},"is_truncated":{"type":"boolean","title":"Is Truncated","description":"Whether the content was truncated due to size limits.","default":false},"lines_shown":{"anyOf":[{"prefixItems":[{"type":"integer"},{"type":"integer"}],"type":"array","maxItems":2,"minItems":2},{"type":"null"}],"title":"Lines Shown","description":"If truncated, the range of lines shown (start, end) - 1-indexed."},"total_lines":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Lines","description":"Total number of lines in the file."},"kind":{"type":"string","const":"ReadFileObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["file_path","kind"],"title":"ReadFileObservation","description":"Observation from reading a file."},"ReadFileTool":{"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":{"type":"string","const":"ReadFileTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"ReadFileTool","description":"Tool for reading file contents with pagination support."},"ReasoningItemModel":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"summary":{"items":{"type":"string"},"type":"array","title":"Summary"},"content":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Content"},"encrypted_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Encrypted Content"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"ReasoningItemModel","description":"OpenAI Responses reasoning item (non-stream, subset we consume).\n\nDo not log or render encrypted_content."},"RedactedThinkingBlock":{"properties":{"type":{"type":"string","const":"redacted_thinking","title":"Type","default":"redacted_thinking"},"data":{"type":"string","title":"Data","description":"The redacted thinking content"}},"type":"object","required":["data"],"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":{"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."},"runtime_conversation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Runtime Conversation Id","description":"Conversation runtime scope; None uses the host workspace."},"kind":{"type":"string","const":"RemoteWorkspace","title":"Kind"}},"type":"object","required":["working_dir","host","kind"],"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\nSupports optional completion callbacks on exit via environment variables:\n  - ``AUTOMATION_CALLBACK_URL`` — URL to POST completion status to\n  - ``AUTOMATION_CALLBACK_API_KEY`` — Bearer token for callback auth (optional)\n  - ``AUTOMATION_RUN_ID`` — Run ID to include in callback payload (optional)\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\")"},"RenameAgentProfileRequest":{"properties":{"new_name":{"type":"string","maxLength":64,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"New Name"}},"type":"object","required":["new_name"],"title":"RenameAgentProfileRequest"},"RenameProfileRequest":{"properties":{"new_name":{"type":"string","maxLength":64,"minLength":1,"pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$","title":"New Name"}},"type":"object","required":["new_name"],"title":"RenameProfileRequest"},"ResponseLatency":{"properties":{"model":{"type":"string","title":"Model"},"latency":{"type":"number","minimum":0.0,"title":"Latency","description":"Latency must be non-negative"},"response_id":{"type":"string","title":"Response Id"}},"type":"object","required":["model","latency","response_id"],"title":"ResponseLatency","description":"Metric tracking the round-trip time per completion call."},"SandboxConfig":{"properties":{"exposed_urls":{"items":{"$ref":"#/components/schemas/ExposedUrl"},"type":"array","title":"Exposed Urls","description":"List of exposed URLs from the sandbox"}},"type":"object","title":"SandboxConfig","description":"Configuration for loading sandbox-specific skills."},"SaveProfileRequest":{"properties":{"llm":{"$ref":"#/components/schemas/LLM-Input"},"include_secrets":{"type":"boolean","title":"Include Secrets","description":"Whether to persist the API key with the profile.","default":true}},"type":"object","required":["llm"],"title":"SaveProfileRequest"},"SecretCreateRequest":{"properties":{"name":{"type":"string","title":"Name"},"value":{"type":"string","format":"password","title":"Value","writeOnly":true},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["name","value"],"title":"SecretCreateRequest","description":"Request model for PUT /api/settings/secrets.\n\nCreates or updates a secret with the given name and value."},"SecretItemResponse":{"properties":{"name":{"type":"string","title":"Name"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["name"],"title":"SecretItemResponse","description":"Response model for a secret item (without value).\n\nUsed in list responses and as the response for create/update operations."},"SecretRegistry":{"properties":{"secret_sources":{"additionalProperties":{"$ref":"#/components/schemas/SecretSource-Output"},"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."},"SecretSource-Input":{"oneOf":[{"$ref":"#/components/schemas/LookupSecret-Input"},{"$ref":"#/components/schemas/StaticSecret-Input"}],"discriminator":{"propertyName":"kind","mapping":{"openhands__sdk__secret__secrets__LookupSecret-Input__1":"#/components/schemas/LookupSecret-Input","openhands__sdk__secret__secrets__StaticSecret-Input__1":"#/components/schemas/StaticSecret-Input"}}},"SecretSource-Output":{"oneOf":[{"$ref":"#/components/schemas/LookupSecret-Output"},{"$ref":"#/components/schemas/StaticSecret-Output"}],"discriminator":{"propertyName":"kind","mapping":{"openhands__sdk__secret__secrets__LookupSecret-Output__1":"#/components/schemas/LookupSecret-Output","openhands__sdk__secret__secrets__StaticSecret-Output__1":"#/components/schemas/StaticSecret-Output"}}},"SecretsListResponse":{"properties":{"secrets":{"items":{"$ref":"#/components/schemas/SecretItemResponse"},"type":"array","title":"Secrets"}},"type":"object","required":["secrets"],"title":"SecretsListResponse","description":"Response model for GET /api/settings/secrets.\n\nLists all available secrets with their names and descriptions.\nValues are never included in list responses."},"SecurityAnalysisEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"analyzer":{"type":"string","title":"Analyzer","description":"Kind of the security analyzer that produced these risks."},"policy":{"type":"string","title":"Policy","description":"Kind of the confirmation policy in force when the actions were analyzed."},"risks":{"additionalProperties":{"$ref":"#/components/schemas/SecurityRisk"},"type":"object","title":"Risks","description":"Risk level per analyzed action, keyed by ActionEvent id."},"details":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Details","description":"Optional analyzer-specific detail per action, keyed by ActionEvent id (for example probabilities, confidence, or a rationale)."},"kind":{"type":"string","const":"SecurityAnalysisEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["analyzer","policy","risks","kind"],"title":"SecurityAnalysisEvent","description":"Risk levels the configured security analyzer assigned to pending actions.\n\nEmitted once per batch of actions the agent is about to execute, whenever a\nsecurity analyzer is configured on the conversation, regardless of whether\nthe confirmation policy then asks for confirmation. This makes the\nanalyzer's verdict visible in the event log and UI even when the policy\n(for example ``NeverConfirm``) never consults it.\n\nThis event is not sent to the LLM."},"SecurityAnalyzerBase-Input":{"oneOf":[{"$ref":"#/components/schemas/PatternSecurityAnalyzer-Input"},{"$ref":"#/components/schemas/PolicyRailSecurityAnalyzer-Input"},{"$ref":"#/components/schemas/EnsembleSecurityAnalyzer-Input"},{"$ref":"#/components/schemas/GraySwanAnalyzer-Input"},{"$ref":"#/components/schemas/LLMSecurityAnalyzer-Input"},{"$ref":"#/components/schemas/ToolShieldLLMSecurityAnalyzer-Input"}],"discriminator":{"propertyName":"kind","mapping":{"openhands__sdk__security__defense_in_depth__pattern__PatternSecurityAnalyzer-Input__1":"#/components/schemas/PatternSecurityAnalyzer-Input","openhands__sdk__security__defense_in_depth__policy_rails__PolicyRailSecurityAnalyzer-Input__1":"#/components/schemas/PolicyRailSecurityAnalyzer-Input","openhands__sdk__security__ensemble__EnsembleSecurityAnalyzer-Input__1":"#/components/schemas/EnsembleSecurityAnalyzer-Input","openhands__sdk__security__grayswan__analyzer__GraySwanAnalyzer-Input__1":"#/components/schemas/GraySwanAnalyzer-Input","openhands__sdk__security__llm_analyzer__LLMSecurityAnalyzer-Input__1":"#/components/schemas/LLMSecurityAnalyzer-Input","openhands__sdk__security__toolshield_llm_analyzer__ToolShieldLLMSecurityAnalyzer-Input__1":"#/components/schemas/ToolShieldLLMSecurityAnalyzer-Input"}}},"SecurityAnalyzerBase-Output":{"oneOf":[{"$ref":"#/components/schemas/PatternSecurityAnalyzer-Output"},{"$ref":"#/components/schemas/PolicyRailSecurityAnalyzer-Output"},{"$ref":"#/components/schemas/EnsembleSecurityAnalyzer-Output"},{"$ref":"#/components/schemas/GraySwanAnalyzer-Output"},{"$ref":"#/components/schemas/LLMSecurityAnalyzer-Output"},{"$ref":"#/components/schemas/ToolShieldLLMSecurityAnalyzer-Output"}],"discriminator":{"propertyName":"kind","mapping":{"openhands__sdk__security__defense_in_depth__pattern__PatternSecurityAnalyzer-Output__1":"#/components/schemas/PatternSecurityAnalyzer-Output","openhands__sdk__security__defense_in_depth__policy_rails__PolicyRailSecurityAnalyzer-Output__1":"#/components/schemas/PolicyRailSecurityAnalyzer-Output","openhands__sdk__security__ensemble__EnsembleSecurityAnalyzer-Output__1":"#/components/schemas/EnsembleSecurityAnalyzer-Output","openhands__sdk__security__grayswan__analyzer__GraySwanAnalyzer-Output__1":"#/components/schemas/GraySwanAnalyzer-Output","openhands__sdk__security__llm_analyzer__LLMSecurityAnalyzer-Output__1":"#/components/schemas/LLMSecurityAnalyzer-Output","openhands__sdk__security__toolshield_llm_analyzer__ToolShieldLLMSecurityAnalyzer-Output__1":"#/components/schemas/ToolShieldLLMSecurityAnalyzer-Output"}}},"SecurityRisk":{"type":"string","enum":["UNKNOWN","LOW","MEDIUM","HIGH"],"title":"SecurityRisk","description":"Security risk levels for actions.\n\nBased on OpenHands security risk levels but adapted for agent-sdk.\nInteger values allow for easy comparison and ordering."},"SendMessageRequest":{"properties":{"role":{"type":"string","enum":["user","system","assistant","tool"],"title":"Role","default":"user"},"content":{"items":{"anyOf":[{"$ref":"#/components/schemas/TextContent"},{"$ref":"#/components/schemas/ImageContent"}]},"type":"array","title":"Content"},"run":{"type":"boolean","title":"Run","description":"Whether the agent loop should automatically run if not running","default":false}},"type":"object","title":"SendMessageRequest","description":"Payload to send a message to the agent."},"ServerErrorEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"code":{"type":"string","title":"Code","description":"Code for the error - typically an error type"},"detail":{"type":"string","title":"Detail","description":"Details about the error"},"kind":{"type":"string","const":"ServerErrorEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["source","code","detail","kind"],"title":"ServerErrorEvent","description":"Event emitted by the agent server when a server-level error occurs.\n\nThis event is used for errors that originate from the agent server itself,\nsuch as MCP connection failures, WebSocket errors, or other infrastructure\nissues. Unlike ConversationErrorEvent which is for conversation-level failures,\nthis event indicates a problem with the server environment."},"ServerInfo":{"properties":{"uptime":{"type":"number","title":"Uptime"},"idle_time":{"type":"number","title":"Idle Time"},"title":{"type":"string","title":"Title","default":"OpenHands Agent Server"},"version":{"type":"string","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"},"usable_tools":{"items":{"type":"string"},"type":"array","title":"Usable Tools"},"runtime_idle_timeout_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Runtime Idle Timeout Seconds"},"conversation_runtime":{"type":"string","enum":["local","docker"],"title":"Conversation Runtime","default":"local"},"capabilities":{"items":{"type":"string"},"type":"array","title":"Capabilities"},"app_backend_ingress_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Backend Ingress Url","description":"Separate browser origin for authenticated Canvas App backend sessions"},"max_foreground_terminal_timeout_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Foreground Terminal Timeout Seconds"},"docs":{"type":"string","title":"Docs","default":"/docs"},"redoc":{"type":"string","title":"Redoc","default":"/redoc"}},"type":"object","required":["uptime","idle_time"],"title":"ServerInfo"},"SetConfirmationPolicyRequest":{"properties":{"policy":{"$ref":"#/components/schemas/ConfirmationPolicyBase-Input","description":"The confirmation policy to set"}},"type":"object","required":["policy"],"title":"SetConfirmationPolicyRequest","description":"Payload to set confirmation policy for a conversation."},"SetSecurityAnalyzerRequest":{"properties":{"security_analyzer":{"anyOf":[{"$ref":"#/components/schemas/SecurityAnalyzerBase-Input"},{"type":"null"}],"description":"The security analyzer to set"}},"type":"object","required":["security_analyzer"],"title":"SetSecurityAnalyzerRequest","description":"Payload to set security analyzer for a conversation"},"SettingProminence":{"type":"string","enum":["critical","major","minor"],"title":"SettingProminence"},"SettingsChoice":{"properties":{"value":{"anyOf":[{"type":"boolean"},{"type":"integer"},{"type":"number"},{"type":"string"}],"title":"Value"},"label":{"type":"string","title":"Label"}},"type":"object","required":["value","label"],"title":"SettingsChoice"},"SettingsFieldSchema":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"section":{"type":"string","title":"Section"},"section_label":{"type":"string","title":"Section Label"},"value_type":{"type":"string","enum":["string","integer","number","boolean","array","object"],"title":"Value Type"},"default":{"title":"Default"},"prominence":{"$ref":"#/components/schemas/SettingProminence","default":"minor"},"depends_on":{"items":{"type":"string"},"type":"array","title":"Depends On"},"secret":{"type":"boolean","title":"Secret","default":false},"choices":{"items":{"$ref":"#/components/schemas/SettingsChoice"},"type":"array","title":"Choices"},"variant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant","description":"When set, the field only applies to the named ``AgentSettings`` variant (``'openhands'`` or ``'acp'``). The GUI filters fields by the user's current variant; fields with ``variant=None`` are shown regardless."}},"type":"object","required":["key","label","section","section_label","value_type"],"title":"SettingsFieldSchema"},"SettingsResponse":{"properties":{"agent_settings":{"properties":{"schema_version":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Schema Version"},"agent_kind":{"anyOf":[{"type":"string","enum":["openhands","acp"]},{"type":"null"}],"title":"Agent Kind"},"mcp_config":{"$ref":"#/components/schemas/MCPConfig"}},"additionalProperties":true,"type":"object","required":["mcp_config"],"title":"_AgentSettingsContract"},"conversation_settings":{"additionalProperties":true,"type":"object","title":"Conversation Settings"},"llm_api_key_is_set":{"type":"boolean","title":"Llm Api Key Is Set"},"active_profile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Profile","description":"Name of the currently active LLM profile, if one is selected."},"active_agent_profile_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Agent Profile Id","description":"Stable id of the currently active AgentProfile, if one is set."},"active_meta_profile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Meta Profile","description":"Name of the currently active meta-profile, if one is selected."},"misc_settings":{"additionalProperties":true,"type":"object","title":"Misc Settings"}},"type":"object","required":["agent_settings","conversation_settings","llm_api_key_is_set"],"title":"SettingsResponse","description":"Response model for GET /api/settings.\n\nContains the full settings payload including agent configuration,\nconversation settings, active LLM profile, miscellaneous frontend-owned\nsettings, and a flag indicating whether an LLM API key is set.\n\nThe ``agent_settings`` and ``conversation_settings`` fields are raw dicts\nbecause the server controls secret serialization via context. Use the\ntyped accessor methods for validation:\n\nExample::\n\n    response = SettingsResponse.model_validate(api_response.json())\n    agent = response.get_agent_settings()  # Returns AgentSettingsConfig\n    conv = response.get_conversation_settings()  # Returns ConversationSettings\n\n``misc_settings`` is an opaque container for frontend-owned data that the\nagent-server persists but does not interpret — see the docstring of\n:class:`PersistedSettings.misc_settings`."},"SettingsSchema":{"properties":{"model_name":{"type":"string","title":"Model Name"},"sections":{"items":{"$ref":"#/components/schemas/SettingsSectionSchema"},"type":"array","title":"Sections"}},"type":"object","required":["model_name","sections"],"title":"SettingsSchema"},"SettingsSectionSchema":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"fields":{"items":{"$ref":"#/components/schemas/SettingsFieldSchema"},"type":"array","title":"Fields"},"variant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant","description":"When set, this section only applies to the named ``AgentSettings`` variant (e.g. ``'openhands'`` or ``'acp'``). The GUI filters sections by the current ``agent_kind`` value; sections with ``variant=None`` are always shown."}},"type":"object","required":["key","label","fields"],"title":"SettingsSectionSchema"},"SettingsUpdateRequest":{"properties":{"agent_settings_diff":{"anyOf":[{"properties":{"mcp_config":{"anyOf":[{"$ref":"#/components/schemas/MCPConfigPatch"},{"type":"null"}]}},"additionalProperties":true,"type":"object","title":"_AgentSettingsPatchContract"},{"type":"null"}],"title":"Agent Settings Diff"},"conversation_settings_diff":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Conversation Settings Diff"},"misc_settings_diff":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Misc Settings Diff"},"active_profile":{"anyOf":[{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"},{"type":"null"}],"title":"Active Profile","description":"Name of the active LLM profile to persist; null clears it."},"active_agent_profile_id":{"anyOf":[{"type":"string","pattern":"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"},{"type":"null"}],"title":"Active Agent Profile Id","description":"Stable id of the active AgentProfile to persist; null clears it."},"active_meta_profile":{"anyOf":[{"type":"string","pattern":"^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"},{"type":"null"}],"title":"Active Meta Profile","description":"Name of the active meta-profile to persist; null clears it."}},"type":"object","title":"SettingsUpdateRequest","description":"Request model for PATCH /api/settings.\n\nSupports partial updates via diff objects that are deep-merged with\nexisting settings. ``misc_settings_diff`` is deep-merged into the\npersisted ``misc_settings`` block with the same semantics as\n``agent_settings_diff`` and ``conversation_settings_diff``: nested dicts\nmerge recursively, and lists are replaced wholesale rather than merged.\nBecause ``misc_settings`` is opaque to the agent-server, callers are\nresponsible for the shape of what they store there."},"Skill-Input":{"properties":{"name":{"type":"string","title":"Name"},"content":{"type":"string","title":"Content"},"trigger":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/KeywordTrigger"},{"$ref":"#/components/schemas/TaskTrigger"},{"$ref":"#/components/schemas/PathTrigger"}],"discriminator":{"propertyName":"type","mapping":{"keyword":"#/components/schemas/KeywordTrigger","path":"#/components/schemas/PathTrigger","task":"#/components/schemas/TaskTrigger"}}},{"type":"null"}],"title":"Trigger","description":"Trigger determines when skill content is auto-injected. None = no auto-injection (for AgentSkills: agent reads on demand; for legacy: full content always in system prompt). KeywordTrigger = auto-inject when keywords appear in user messages. TaskTrigger = auto-inject for specific tasks, may require user input."},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"The source path or identifier of the skill. When it is None, it is treated as a programmatically defined skill."},"mcp_tools":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/MCPServer-Input"},"type":"object"},{"type":"null"}],"title":"Mcp Tools","description":"MCP servers for the skill (repo skills only)."},"inputs":{"items":{"$ref":"#/components/schemas/InputMetadata"},"type":"array","title":"Inputs","description":"Input metadata for the skill (task skills only)"},"is_agentskills_format":{"type":"boolean","title":"Is Agentskills Format","description":"Whether this skill was loaded from a SKILL.md file following the AgentSkills standard. AgentSkills-format skills use progressive disclosure: always listed in <available_skills> with name, description, and location. If the skill also has triggers, content is auto-injected when triggered AND agent can read file anytime.","default":false},"version":{"type":"string","title":"Version","description":"Skill version (AgentSkills standard field).","default":"1.0.0"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","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":[{"type":"string"},{"type":"null"}],"title":"License","description":"The license under which the skill is distributed. AgentSkills standard field (e.g., 'Apache-2.0', 'MIT')."},"compatibility":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compatibility","description":"Environment requirements or compatibility notes for the skill. AgentSkills standard field (e.g., 'Requires git and docker')."},"metadata":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Metadata","description":"Arbitrary key-value metadata for the skill. AgentSkills standard field for extensibility."},"allowed_tools":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Tools","description":"List of pre-approved tools for this skill. AgentSkills standard field (parsed from space-delimited string)."},"disable_model_invocation":{"type":"boolean","title":"Disable Model Invocation","description":"Whether this skill can only be activated by trigger matching and should not be advertised to the model for direct invocation.","default":false},"resources":{"anyOf":[{"$ref":"#/components/schemas/SkillResources"},{"type":"null"}],"description":"Resource directories for the skill (scripts/, references/, assets/). AgentSkills standard field. Only populated for SKILL.md directory format."}},"type":"object","required":["name","content"],"title":"Skill","description":"A skill provides specialized knowledge or functionality.\n\nSkill behavior depends on format (is_agentskills_format) and trigger:\n\nAgentSkills format (SKILL.md files):\n- Always listed in <available_skills> with name, description, location\n- Agent reads full content on demand (progressive disclosure)\n- If has triggers: content is ALSO auto-injected when triggered\n\nLegacy OpenHands format:\n- With triggers: Listed in <available_skills>, content injected on trigger\n- Without triggers (None): Full content in <REPO_CONTEXT>, always active\n\nThis model supports both OpenHands-specific fields and AgentSkills standard\nfields (https://agentskills.io/specification) for cross-platform compatibility."},"Skill-Output":{"properties":{"name":{"type":"string","title":"Name"},"content":{"type":"string","title":"Content"},"trigger":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/KeywordTrigger"},{"$ref":"#/components/schemas/TaskTrigger"},{"$ref":"#/components/schemas/PathTrigger"}],"discriminator":{"propertyName":"type","mapping":{"keyword":"#/components/schemas/KeywordTrigger","path":"#/components/schemas/PathTrigger","task":"#/components/schemas/TaskTrigger"}}},{"type":"null"}],"title":"Trigger","description":"Trigger determines when skill content is auto-injected. None = no auto-injection (for AgentSkills: agent reads on demand; for legacy: full content always in system prompt). KeywordTrigger = auto-inject when keywords appear in user messages. TaskTrigger = auto-inject for specific tasks, may require user input."},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"The source path or identifier of the skill. When it is None, it is treated as a programmatically defined skill."},"mcp_tools":{"anyOf":[{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object"},{"type":"null"}],"title":"Mcp Tools","description":"MCP servers for the skill (repo skills only)."},"inputs":{"items":{"$ref":"#/components/schemas/InputMetadata"},"type":"array","title":"Inputs","description":"Input metadata for the skill (task skills only)"},"is_agentskills_format":{"type":"boolean","title":"Is Agentskills Format","description":"Whether this skill was loaded from a SKILL.md file following the AgentSkills standard. AgentSkills-format skills use progressive disclosure: always listed in <available_skills> with name, description, and location. If the skill also has triggers, content is auto-injected when triggered AND agent can read file anytime.","default":false},"version":{"type":"string","title":"Version","description":"Skill version (AgentSkills standard field).","default":"1.0.0"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","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":[{"type":"string"},{"type":"null"}],"title":"License","description":"The license under which the skill is distributed. AgentSkills standard field (e.g., 'Apache-2.0', 'MIT')."},"compatibility":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Compatibility","description":"Environment requirements or compatibility notes for the skill. AgentSkills standard field (e.g., 'Requires git and docker')."},"metadata":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Metadata","description":"Arbitrary key-value metadata for the skill. AgentSkills standard field for extensibility."},"allowed_tools":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Allowed Tools","description":"List of pre-approved tools for this skill. AgentSkills standard field (parsed from space-delimited string)."},"disable_model_invocation":{"type":"boolean","title":"Disable Model Invocation","description":"Whether this skill can only be activated by trigger matching and should not be advertised to the model for direct invocation.","default":false},"resources":{"anyOf":[{"$ref":"#/components/schemas/SkillResources"},{"type":"null"}],"description":"Resource directories for the skill (scripts/, references/, assets/). AgentSkills standard field. Only populated for SKILL.md directory format."}},"type":"object","required":["name","content"],"title":"Skill","description":"A skill provides specialized knowledge or functionality.\n\nSkill behavior depends on format (is_agentskills_format) and trigger:\n\nAgentSkills format (SKILL.md files):\n- Always listed in <available_skills> with name, description, location\n- Agent reads full content on demand (progressive disclosure)\n- If has triggers: content is ALSO auto-injected when triggered\n\nLegacy OpenHands format:\n- With triggers: Listed in <available_skills>, content injected on trigger\n- Without triggers (None): Full content in <REPO_CONTEXT>, always active\n\nThis model supports both OpenHands-specific fields and AgentSkills standard\nfields (https://agentskills.io/specification) for cross-platform compatibility."},"SkillInfo":{"properties":{"name":{"type":"string","title":"Name"},"type":{"type":"string","enum":["repo","knowledge","agentskills"],"title":"Type"},"content":{"type":"string","title":"Content"},"triggers":{"items":{"type":"string"},"type":"array","title":"Triggers"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_agentskills_format":{"type":"boolean","title":"Is Agentskills Format","default":false},"disable_model_invocation":{"type":"boolean","title":"Disable Model Invocation","default":false}},"type":"object","required":["name","type","content"],"title":"SkillInfo","description":"Lightweight representation of a skill's essential information.\n\nThis class provides a standardized, serializable format for skill metadata\nthat can be used across different components of the system."},"SkillResources":{"properties":{"skill_root":{"type":"string","title":"Skill Root","description":"Root directory of the skill (absolute path)"},"scripts":{"items":{"type":"string"},"type":"array","title":"Scripts","description":"List of script files in scripts/ directory (relative paths)"},"references":{"items":{"type":"string"},"type":"array","title":"References","description":"List of reference files in references/ directory (relative paths)"},"assets":{"items":{"type":"string"},"type":"array","title":"Assets","description":"List of asset files in assets/ directory (relative paths)"}},"type":"object","required":["skill_root"],"title":"SkillResources","description":"Resource directories for a skill (AgentSkills standard).\n\nPer the AgentSkills specification, skills can include:\n- scripts/: Executable scripts the agent can run\n- references/: Reference documentation and examples\n- assets/: Static assets (images, data files, etc.)"},"SkillsRequest":{"properties":{"load_public":{"type":"boolean","title":"Load Public","description":"Load public skills from <redacted:unrelated-repository> repo","default":true},"load_user":{"type":"boolean","title":"Load User","description":"Load user skills from ~/.openhands/skills/","default":true},"load_project":{"type":"boolean","title":"Load Project","description":"Load project skills from workspace","default":true},"load_org":{"type":"boolean","title":"Load Org","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"},"registered_marketplaces":{"items":{"$ref":"#/components/schemas/MarketplaceRegistration"},"type":"array","title":"Registered Marketplaces","description":"Marketplace registrations for plugin-based skill loading. Registrations with auto_load=True or a list of plugin names add their skills to the public skills."},"project_dir":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Dir","description":"Workspace directory path for project skills"},"org_configs":{"anyOf":[{"items":{"$ref":"#/components/schemas/OrgConfig"},"type":"array"},{"type":"null"}],"title":"Org Configs","description":"Organization/user skill repositories to load concurrently"},"sandbox_config":{"anyOf":[{"$ref":"#/components/schemas/SandboxConfig"},{"type":"null"}],"description":"Sandbox skills configuration"}},"type":"object","title":"SkillsRequest","description":"Request body for loading skills."},"SkillsResponse":{"properties":{"skills":{"items":{"$ref":"#/components/schemas/SkillInfo"},"type":"array","title":"Skills"},"sources":{"additionalProperties":{"type":"integer"},"type":"object","title":"Sources","description":"Count of skills loaded from each source"}},"type":"object","required":["skills"],"title":"SkillsResponse","description":"Response containing all available skills."},"StartConversationRequest":{"properties":{"workspace":{"$ref":"#/components/schemas/LocalWorkspace-Input","description":"Working directory for agent operations and tool execution."},"worktree":{"type":"boolean","title":"Worktree","description":"If true and the workspace is already inside a git repository, create a dedicated git worktree for this conversation under `/tmp/conversation-worktrees/<conversation_id>/<project_name>`.","default":false},"conversation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Conversation Id","description":"Optional conversation ID. If not provided, a random UUID will be generated."},"parent_conversation_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Parent Conversation Id","description":"Optional ID of an existing conversation that owns this one. The parent must already exist and share this conversation's workspace."},"confirmation_policy":{"$ref":"#/components/schemas/ConfirmationPolicyBase-Input","description":"Controls when the conversation will prompt the user before continuing. Defaults to never.","default":{"kind":"NeverConfirm"}},"security_analyzer":{"anyOf":[{"$ref":"#/components/schemas/SecurityAnalyzerBase-Input"},{"type":"null"}],"description":"Optional security analyzer to evaluate action risks."},"initial_message":{"anyOf":[{"$ref":"#/components/schemas/SendMessageRequest"},{"type":"null"}],"description":"Initial message to pass to the LLM"},"max_iterations":{"type":"integer","minimum":1.0,"title":"Max Iterations","description":"If set, the max number of iterations the agent will run before stopping. This is useful to prevent infinite loops.","default":500},"stuck_detection":{"type":"boolean","title":"Stuck Detection","description":"If true, the conversation will use stuck detection to prevent infinite loops.","default":true},"secrets":{"additionalProperties":{"$ref":"#/components/schemas/SecretSource-Input"},"type":"object","title":"Secrets","description":"Secrets available in the conversation"},"secrets_encrypted":{"type":"boolean","title":"Secrets Encrypted","description":"If true, indicates that secret values in the agent configuration are cipher-encrypted and should be decrypted by the server before use. This enables secure round-tripping of settings through untrusted clients (e.g., frontend) that received encrypted values via the X-Expose-Secrets header. Flow: client calls GET /api/settings with X-Expose-Secrets: encrypted to receive cipher-encrypted secrets, then passes them in the agent config with secrets_encrypted=True so the server can decrypt them.","default":false},"tool_module_qualnames":{"additionalProperties":{"type":"string"},"type":"object","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."},"client_tools":{"items":{"$ref":"#/components/schemas/ClientToolSpec-Input"},"type":"array","title":"Client Tools","description":"Tools defined by the client via JSON spec. These tools have no server-side executor — when the agent calls them, an ActionEvent is emitted over the WebSocket and the client handles execution. The SDK returns an acknowledgment observation immediately."},"agent_launch_additions":{"anyOf":[{"$ref":"#/components/schemas/AgentLaunchAdditions"},{"type":"null"}],"description":"Deployment context applied after agent or Agent Profile resolution. The stored Agent Profile is not modified."},"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 task tools can see user-registered subagents."},"plugins":{"anyOf":[{"items":{"$ref":"#/components/schemas/PluginSource"},"type":"array"},{"type":"null"}],"title":"Plugins","description":"List of plugins to load for this conversation. Plugins are loaded and their skills/MCP config are merged into the agent. Hooks are extracted and stored for runtime execution."},"hook_config":{"anyOf":[{"$ref":"#/components/schemas/HookConfig"},{"type":"null"}],"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."},"tags":{"additionalProperties":{"type":"string"},"type":"object","title":"Tags","description":"Key-value tags for the conversation. Keys must be lowercase alphanumeric. Values are arbitrary strings up to 256 characters."},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id","description":"Optional user ID supplied by the hosting deployment, used to correlate this conversation with the identity that deployment already established. When set it is passed to Laminar.set_trace_user_id() so traces can be queried by user, and — where a host has enabled product analytics — it is reused verbatim as the analytics correlation id so events attach to the existing person rather than creating a duplicate identity. It is never generated by the SDK, and is omitted entirely when unset."},"observability_metadata":{"additionalProperties":{"$ref":"#/components/schemas/TraceMetadataValue"},"type":"object","title":"Observability Metadata","description":"Trace-level metadata to attach to observability backends. Values must be scalars or homogeneous scalar lists supported by OpenTelemetry."},"observability_tags":{"items":{"type":"string"},"type":"array","title":"Observability Tags","description":"Tags to attach to the conversation root observability span."},"observability_span_name":{"type":"string","title":"Observability Span Name","description":"Optional named child span to emit under the conversation root. Use stable, low-cardinality names because observability backends may use span names for grouping or signal routing.","default":"conversation"},"observability_parent_span_context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Observability Parent Span Context","description":"Serialized parent span context used to attach this conversation to an upstream automation or integration trace."},"autotitle":{"type":"boolean","title":"Autotitle","description":"If true, automatically generate a title for the conversation from the first user message. Precedence: title_llm_profile (if set and loads) → agent.llm → message truncation.","default":true},"title_llm_profile":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title Llm Profile","description":"Optional LLM profile name for title generation. If set, the LLM is loaded from LLMProfileStore (~/.openhands/profiles/) and used for LLM-based title generation. This enables using a fast/cheap model for titles regardless of the agent's main model. If not set (or profile loading fails), title generation falls back to the agent's LLM."},"agent_settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Agent Settings","description":"Reference-free agent settings, validated with the AgentSettingsBase `agent_kind` discriminator. The server builds the agent from them at launch. Ignored when `agent` is set."},"agent_profile_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Agent Profile Id","description":"Stored Agent Profile to launch. The server resolves it with its own stores. Mutually exclusive with `agent` and `agent_settings`."},"agent":{"$ref":"#/components/schemas/AgentBase-Input"}},"type":"object","required":["workspace"],"title":"StartConversationRequest","description":"Payload to create a new conversation.\n\nExtends :class:`ConversationConfig` with the agent source: a stored Agent\nProfile (``agent_profile_id``), resolved agent settings (``agent_settings``),\nor an ``agent`` built in code. The server builds the conversation's agent\nfrom that source at launch; this model only validates it.\n\nNote: the agent lives here on the *request*, deliberately not on\n``ConversationConfig``. The persisted record (``StoredConversation``) does\nnot carry the agent — its single source of truth is ``ConversationState`` /\n``base_state.json``."},"StartGoalRequest":{"properties":{"objective":{"type":"string","title":"Objective","description":"The goal objective to pursue and audit."},"max_iterations":{"type":"integer","minimum":1.0,"title":"Max Iterations","description":"Maximum audit rounds before giving up.","default":10}},"type":"object","required":["objective"],"title":"StartGoalRequest","description":"Payload to start a ``/goal`` loop inside a conversation."},"StaticSecret-Input":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description for this secret"},"value":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Value"},"kind":{"type":"string","const":"StaticSecret","title":"Kind"}},"type":"object","title":"StaticSecret","description":"A secret stored locally"},"StaticSecret-Output":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Optional description for this secret"},"value":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Value"},"kind":{"type":"string","const":"StaticSecret","title":"Kind"}},"type":"object","required":["kind"],"title":"StaticSecret","description":"A secret stored locally"},"StreamingDeltaEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"reasoning_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reasoning Content"},"kind":{"type":"string","const":"StreamingDeltaEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"StreamingDeltaEvent","description":"Transient LLM token delta for real-time WebSocket delivery.\n\nNot persisted to the conversation event log: these events are published\ndirectly to PubSub, bypassing the callback chain that writes to\nConversationState.events. Clients reconnecting mid-stream will receive\nthe final MessageEvent from history but none of the deltas that produced\nit — deltas are a UX affordance, not part of the durable conversation\nrecord."},"SubAgentInfo":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description","default":""},"model":{"type":"string","title":"Model","default":"inherit"},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color"},"tools":{"items":{"type":"string"},"type":"array","title":"Tools"},"skills":{"items":{"type":"string"},"type":"array","title":"Skills"},"system_prompt":{"type":"string","title":"System Prompt","default":""},"when_to_use_examples":{"items":{"type":"string"},"type":"array","title":"When To Use Examples"},"permission_mode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Permission Mode"},"max_iteration_per_run":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Iteration Per Run"},"max_budget_per_run":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Budget Per Run"},"mcp_config":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/MCPServer-Output"},"type":"object"},{"type":"null"}],"title":"Mcp Config"},"mcp_servers":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/MCPServer-Output"},"type":"object"},{"type":"null"}],"title":"Mcp Servers","description":"Deprecated compatibility alias for mcp_config. Use mcp_config for new clients.","deprecated":true},"profile_store_dir":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Store Dir"},"hooks":{"anyOf":[{"$ref":"#/components/schemas/HookConfig"},{"type":"null"}]},"condenser":{"anyOf":[{"$ref":"#/components/schemas/CondenserBase-Output"},{"type":"null"}]},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"level":{"anyOf":[{"type":"string","enum":["project","user","builtin","plugin","programmatic"]},{"type":"null"}],"title":"Level"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"is_builtin":{"type":"boolean","title":"Is Builtin","default":false}},"type":"object","required":["name"],"title":"SubAgentInfo","description":"Lossless view of an ``AgentDefinition`` returned by the API.\n\nEvery frontmatter field plus the discovered ``level``/``source``, an\n``is_builtin`` flag, and the inline ``system_prompt`` (Markdown body) so a\ndetail view needs no extra fetch."},"SubAgentsRequest":{"properties":{"load_user":{"type":"boolean","title":"Load User","description":"Load user agents from ~/.agents/agents and ~/.openhands/agents","default":true},"load_project":{"type":"boolean","title":"Load Project","description":"Load project agents from the workspace","default":true},"load_builtin":{"type":"boolean","title":"Load Builtin","description":"Load SDK built-in agents (general-purpose, code-explorer, ...)","default":true},"project_dir":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Project Dir","description":"Workspace directory path for project agents"}},"type":"object","title":"SubAgentsRequest","description":"Request body for listing sub-agents."},"SubAgentsResponse":{"properties":{"agents":{"items":{"$ref":"#/components/schemas/SubAgentInfo"},"type":"array","title":"Agents"}},"type":"object","required":["agents"],"title":"SubAgentsResponse","description":"Response containing all available sub-agents."},"SubdirectoryEntry":{"properties":{"name":{"type":"string","title":"Name"},"path":{"type":"string","title":"Path"}},"type":"object","required":["name","path"],"title":"SubdirectoryEntry"},"SubdirectoryPage":{"properties":{"items":{"items":{"$ref":"#/components/schemas/SubdirectoryEntry"},"type":"array","title":"Items"},"next_page_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Page Id"}},"type":"object","required":["items"],"title":"SubdirectoryPage"},"SubscriptionDevicePollRequest":{"properties":{"device_code":{"type":"string","title":"Device Code"}},"type":"object","required":["device_code"],"title":"SubscriptionDevicePollRequest","description":"Poll request for a previously-started subscription device login."},"SubscriptionDeviceStartResponse":{"properties":{"device_code":{"type":"string","title":"Device Code","description":"Opaque server-side polling token."},"user_code":{"type":"string","title":"User Code"},"verification_uri":{"type":"string","title":"Verification Uri"},"verification_uri_complete":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification Uri Complete"},"expires_at":{"type":"integer","title":"Expires At"},"interval_seconds":{"type":"integer","title":"Interval Seconds"}},"type":"object","required":["device_code","user_code","verification_uri","expires_at","interval_seconds"],"title":"SubscriptionDeviceStartResponse","description":"Device-code challenge details for browser sign-in."},"SubscriptionModelsResponse":{"properties":{"vendor":{"type":"string","title":"Vendor","default":"openai"},"models":{"items":{"type":"string"},"type":"array","title":"Models"}},"type":"object","required":["models"],"title":"SubscriptionModelsResponse","description":"Models available through a subscription provider."},"SubscriptionStatusResponse":{"properties":{"vendor":{"type":"string","title":"Vendor","default":"openai"},"connected":{"type":"boolean","title":"Connected"},"account_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Email"},"expires_at":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires At"}},"type":"object","required":["connected"],"title":"SubscriptionStatusResponse","description":"Safe subscription authentication status."},"Success":{"properties":{"success":{"type":"boolean","title":"Success","default":true}},"type":"object","title":"Success"},"SwitchLLMAction":{"properties":{"profile_name":{"type":"string","title":"Profile Name","description":"Name of the saved LLM profile to use for future agent steps."},"reason":{"type":"string","title":"Reason","description":"Brief reason why this profile is a better fit for the next step."},"kind":{"type":"string","const":"SwitchLLMAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["profile_name","reason","kind"],"title":"SwitchLLMAction","description":"Action for switching this conversation to a saved LLM profile."},"SwitchLLMObservation":{"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},"profile_name":{"type":"string","title":"Profile Name","description":"Name of the profile that the tool attempted to activate."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Reason the agent gave for attempting this LLM profile switch."},"active_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Active Model","description":"Model configured by the activated profile, when available."},"kind":{"type":"string","const":"SwitchLLMObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["profile_name","kind"],"title":"SwitchLLMObservation","description":"Observation returned after switching this conversation's LLM profile."},"SwitchLLMTool":{"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":{"type":"string","const":"SwitchLLMTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"SwitchLLMTool","description":"Tool for switching a conversation to a saved LLM profile."},"SyncResponse":{"properties":{"status":{"type":"string","enum":["success","error"],"title":"Status"},"message":{"type":"string","title":"Message"}},"type":"object","required":["status","message"],"title":"SyncResponse","description":"Response from skill sync operation."},"SystemPromptEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"system_prompt":{"$ref":"#/components/schemas/TextContent","description":"The system prompt text"},"tools":{"items":{"$ref":"#/components/schemas/ToolDefinition"},"type":"array","title":"Tools","description":"List of tools as ToolDefinition objects"},"dynamic_context":{"anyOf":[{"$ref":"#/components/schemas/TextContent"},{"type":"null"}],"description":"Optional dynamic per-conversation context (runtime info, repo context, secrets). When provided, this is included as a second content block in the system message (not cached)."},"kind":{"type":"string","const":"SystemPromptEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["system_prompt","tools","kind"],"title":"SystemPromptEvent","description":"System prompt added by the agent.\n\nThe system prompt can optionally include dynamic context that varies between\nconversations. When ``dynamic_context`` is provided, it is included as a\nsecond content block in the same system message. Cache markers are NOT\napplied here - they are applied by ``LLM._apply_prompt_caching()`` when\ncaching is enabled, ensuring provider-specific cache control is only added\nwhen appropriate.\n\nAttributes:\n    system_prompt: The static system prompt text (cacheable across conversations)\n    tools: List of available tools\n    dynamic_context: Optional per-conversation context (hosts, repo info, etc.)\n        Sent as a second TextContent block inside the system message."},"TaskAction":{"properties":{"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"A short (3-5 word) description of the task."},"prompt":{"type":"string","title":"Prompt","description":"The task for the agent to perform."},"subagent_type":{"type":"string","title":"Subagent Type","description":"The type of specialized agent to use for this task.","default":"general-purpose"},"resume":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resume","description":"Task ID of the task to resume from."},"kind":{"type":"string","const":"TaskAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["prompt","kind"],"title":"TaskAction","description":"Schema for launching a sub-agent task."},"TaskItem":{"properties":{"title":{"type":"string","title":"Title","description":"A brief title for the task."},"notes":{"type":"string","title":"Notes","description":"Additional details or notes about the task.","default":""},"status":{"type":"string","enum":["todo","in_progress","done"],"title":"Status","description":"The current status of the task. One of 'todo', 'in_progress', or 'done'.","default":"todo"}},"type":"object","required":["title"],"title":"TaskItem"},"TaskObservation":{"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},"task_id":{"type":"string","title":"Task Id","description":"The unique identifier of the task."},"subagent":{"type":"string","title":"Subagent","description":"The subagent of the task."},"status":{"type":"string","title":"Status","description":"The status of the task."},"kind":{"type":"string","const":"TaskObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["task_id","subagent","status","kind"],"title":"TaskObservation","description":"Observation from a task execution."},"TaskTool":{"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":{"type":"string","const":"TaskTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"TaskTool","description":"Tool for launching (blocking) sub-agent tasks."},"TaskToolSet":{"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":{"type":"string","const":"TaskToolSet","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"TaskToolSet","description":"Task tool set.\n\nCreates the Task tool backed by a shared TaskManager.\n\nUsage:\n    from openhands.tools.task import TaskToolSet\n\n    agent = Agent(\n        llm=llm,\n        tools=[\n            Tool(name=TerminalTool.name),\n            Tool(name=FileEditorTool.name),\n            Tool(name=TaskToolSet.name),\n        ],\n    )"},"TaskTrackerAction":{"properties":{"command":{"type":"string","enum":["view","plan"],"title":"Command","description":"The command to execute. `view` shows the current task list. `plan` creates or updates the task list based on provided requirements and progress. Always `view` the current list before making changes.","default":"view"},"task_list":{"items":{"$ref":"#/components/schemas/TaskItem"},"type":"array","title":"Task List","description":"The full task list. Required parameter of `plan` command."},"kind":{"type":"string","const":"TaskTrackerAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"TaskTrackerAction","description":"An action where the agent writes or updates a task list for task management."},"TaskTrackerObservation":{"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},"command":{"type":"string","enum":["view","plan"],"title":"Command","description":"The command that was executed: \"view\" or \"plan\"."},"task_list":{"items":{"$ref":"#/components/schemas/TaskItem"},"type":"array","title":"Task List","description":"The current task list"},"kind":{"type":"string","const":"TaskTrackerObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["command","kind"],"title":"TaskTrackerObservation","description":"This data class represents the result of a task tracking operation."},"TaskTrackerTool":{"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":{"type":"string","const":"TaskTrackerTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"TaskTrackerTool","description":"A ToolDefinition subclass that automatically initializes a TaskTrackerExecutor."},"TaskTrigger":{"properties":{"type":{"type":"string","const":"task","title":"Type","default":"task"},"triggers":{"items":{"type":"string"},"type":"array","title":"Triggers"}},"type":"object","required":["triggers"],"title":"TaskTrigger","description":"Trigger for task-specific skills.\n\nThese skills are activated for specific task types and can modify prompts."},"TelemetrySpec":{"properties":{"deployment_kind":{"type":"string","enum":["local","remote"],"title":"Deployment Kind","description":"Deployment kind attached to diagnostic events. Use 'remote' for hosted OpenHands and 'local' for self-hosted or developer runs.","default":"local"},"exporter":{"type":"string","enum":["none","posthog","http"],"title":"Exporter","description":"Exporter to use. 'none' (the default) never delivers, and is what library and headless consumers get. 'posthog' requires the [posthog] extra. 'http' POSTs sanitized batches to telemetry_http_endpoint.","default":"none"},"posthog_api_key":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Posthog Api Key","description":"PostHog project API key. Required by the 'posthog' exporter; without it telemetry stays inactive."},"posthog_host":{"type":"string","title":"Posthog Host","description":"PostHog ingestion host.","default":"https://us.i.posthog.com"},"http_endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Http Endpoint","description":"Endpoint the 'http' exporter POSTs sanitized event batches to. Intended to front a backend that revalidates auth and consent before forwarding onward."},"http_token":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Http Token","description":"Bearer token sent by the 'http' exporter, if required."},"salt":{"anyOf":[{"type":"string","format":"password","writeOnly":true},{"type":"null"}],"title":"Salt","description":"Key used to pseudonymize conversation identifiers. Falls back to a per-process random salt, which keeps pseudonyms stable within a run but unlinkable across runs."},"max_queue_size":{"type":"integer","minimum":1.0,"title":"Max Queue Size","description":"Upper bound on buffered diagnostic events. The queue is bounded on ingest: past this many events the oldest are dropped, so a failing exporter cannot grow memory without limit.","default":1000},"event_buffer_size":{"type":"integer","minimum":1.0,"title":"Event Buffer Size","description":"Maximum events per delivery batch.","default":20},"flush_delay":{"type":"number","exclusiveMinimum":0.0,"title":"Flush Delay","description":"Seconds to wait before flushing a partial batch.","default":30.0},"num_retries":{"type":"integer","minimum":0.0,"title":"Num Retries","description":"Retries before a batch is dropped.","default":2},"retry_delay":{"type":"number","minimum":0.0,"title":"Retry Delay","description":"Base seconds between delivery retries.","default":5.0}},"type":"object","title":"TelemetrySpec","description":"Deployment-supplied product-analytics transport settings.\n\nThis carries transport plus the non-identifying deployment tag. Whether\ntelemetry may be delivered is resolved from consent\n(``misc_settings.telemetry.consent``, optionally seeded or overridden by\n``OH_TELEMETRY_CONSENT``)."},"TerminalAction":{"properties":{"command":{"type":"string","title":"Command","description":"The shell command to execute. Can be empty string to view additional logs when the previous exit code is `-1`. Can be a special key name when `is_input` is True: `C-c` (Ctrl+C), `C-d` (Ctrl+D/EOF), `C-z` (Ctrl+Z), or any `C-<letter>` for Ctrl sequences; navigation keys `UP`, `DOWN`, `LEFT`, `RIGHT`, `HOME`, `END`, `PGUP`, `PGDN`; and `TAB`, `ESC`, `BS` (Backspace), `ENTER`. You can only execute one command at a time. Use the platform-appropriate shell syntax described in the tool description when chaining commands."},"is_input":{"type":"boolean","title":"Is Input","description":"If True, the command is an input to the running process. If False, the command is executed in the terminal session. Default is False.","default":false},"timeout":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Timeout","description":"Optional. Sets a maximum time limit (in seconds) for running the command. If the command takes longer than this limit, you’ll be asked whether to continue or stop it. If you don’t set a value, the command will instead pause and ask for confirmation when it produces no new output for 30 seconds. Use a higher value if the command is expected to take a long time (like installation or testing), or if it has a known fixed duration (like sleep)."},"reset":{"type":"boolean","title":"Reset","description":"If True, reset the terminal by creating a new session. Use this only when the terminal becomes unresponsive. Note that all previously set environment variables and session state will be lost after reset. Cannot be used with is_input=True.","default":false},"kind":{"type":"string","const":"TerminalAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["command","kind"],"title":"TerminalAction","description":"Schema for terminal command execution."},"TerminalObservation":{"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},"command":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Command","description":"The shell command that was executed. Can be empty string if the observation is from a previous command that hit soft timeout and is not yet finished."},"exit_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Exit Code","description":"The exit code of the command. -1 indicates the process hit the soft timeout and is not yet finished."},"timeout":{"type":"boolean","title":"Timeout","description":"Whether the command execution timed out.","default":false},"metadata":{"$ref":"#/components/schemas/CmdOutputMetadata","description":"Additional metadata captured from PS1 after command execution."},"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","const":"TerminalObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["command","kind"],"title":"TerminalObservation","description":"A ToolResult that can be rendered as a CLI output."},"TerminalTool":{"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":{"type":"string","const":"TerminalTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"TerminalTool","description":"A ToolDefinition subclass that automatically initializes a TerminalExecutor with auto-detection."},"TextContent":{"properties":{"cache_prompt":{"type":"boolean","title":"Cache Prompt","default":false},"type":{"type":"string","const":"text","title":"Type","default":"text"},"text":{"type":"string","title":"Text"}},"additionalProperties":false,"type":"object","required":["text"],"title":"TextContent"},"ThinkAction":{"properties":{"thought":{"type":"string","title":"Thought","description":"The thought to log."},"kind":{"type":"string","const":"ThinkAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["thought","kind"],"title":"ThinkAction","description":"Action for logging a thought without making any changes."},"ThinkObservation":{"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},"kind":{"type":"string","const":"ThinkObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"ThinkObservation","description":"Observation returned after logging a thought.\nThe ThinkAction itself contains the thought logged so no extra\nfields are needed here."},"ThinkTool":{"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":{"type":"string","const":"ThinkTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"ThinkTool","description":"Tool for logging thoughts without making changes."},"ThinkingBlock":{"properties":{"type":{"type":"string","const":"thinking","title":"Type","default":"thinking"},"thinking":{"type":"string","title":"Thinking","description":"The thinking content"},"signature":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signature","description":"Cryptographic signature for the thinking block"}},"type":"object","required":["thinking"],"title":"ThinkingBlock","description":"Anthropic thinking block for extended thinking feature.\n\nThis represents the raw thinking blocks returned by Anthropic models\nwhen extended thinking is enabled. These blocks must be preserved\nand passed back to the API for tool use scenarios."},"TokenEvent":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"prompt_token_ids":{"items":{"type":"integer"},"type":"array","title":"Prompt Token Ids","description":"The exact prompt token IDs for this message event"},"response_token_ids":{"items":{"type":"integer"},"type":"array","title":"Response Token Ids","description":"The exact response token IDs for this message event"},"kind":{"type":"string","const":"TokenEvent","title":"Kind"}},"additionalProperties":false,"type":"object","required":["source","prompt_token_ids","response_token_ids","kind"],"title":"TokenEvent","description":"Event from VLLM representing token IDs used in LLM interaction."},"TokenUsage":{"properties":{"model":{"type":"string","title":"Model","default":""},"prompt_tokens":{"type":"integer","minimum":0.0,"title":"Prompt Tokens","description":"Prompt tokens must be non-negative","default":0},"completion_tokens":{"type":"integer","minimum":0.0,"title":"Completion Tokens","description":"Completion tokens must be non-negative","default":0},"cache_read_tokens":{"type":"integer","minimum":0.0,"title":"Cache Read Tokens","description":"Cache read tokens must be non-negative","default":0},"cache_write_tokens":{"type":"integer","minimum":0.0,"title":"Cache Write Tokens","description":"Cache write tokens must be non-negative","default":0},"reasoning_tokens":{"type":"integer","minimum":0.0,"title":"Reasoning Tokens","description":"Reasoning tokens must be non-negative","default":0},"context_window":{"type":"integer","minimum":0.0,"title":"Context Window","description":"Context window must be non-negative","default":0},"per_turn_token":{"type":"integer","minimum":0.0,"title":"Per Turn Token","description":"Per turn tokens must be non-negative","default":0},"response_id":{"type":"string","title":"Response Id","default":""}},"type":"object","title":"TokenUsage","description":"Metric tracking detailed token usage per completion call."},"Tool-Input":{"properties":{"name":{"type":"string","title":"Name","description":"Name of the tool class, e.g., 'TerminalTool'. Import it from an `openhands.tools.<module>` subpackage.","examples":["TerminalTool","FileEditorTool","TaskTrackerTool"]},"params":{"additionalProperties":true,"type":"object","title":"Params","description":"Parameters for the tool's .create() method, e.g., {'working_dir': '/app'}","examples":[{"working_dir":"/workspace"}]}},"type":"object","required":["name"],"title":"Tool","description":"Defines a tool to be initialized for the agent.\n\nThis is only used in agent-sdk for type schema for server use."},"ToolAnnotations-Input":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"A human-readable title for the tool."},"readOnlyHint":{"type":"boolean","title":"Readonlyhint","description":"If true, the tool does not modify its environment. Default: false","default":false},"destructiveHint":{"type":"boolean","title":"Destructivehint","description":"If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates. (This property is meaningful only when `readOnlyHint == false`) Default: true","default":true},"idempotentHint":{"type":"boolean","title":"Idempotenthint","description":"If true, calling the tool repeatedly with the same arguments will have no additional effect on the its environment. (This property is meaningful only when `readOnlyHint == false`) Default: false","default":false},"openWorldHint":{"type":"boolean","title":"Openworldhint","description":"If true, this tool may interact with an 'open world' of external entities. If false, the tool's domain of interaction is closed. For example, the world of a web search tool is open, whereas that of a memory tool is not. Default: true","default":true}},"type":"object","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"},"ToolCatalogEntry":{"properties":{"name":{"type":"string","title":"Name"},"user_selectable":{"type":"boolean","title":"User Selectable","default":true},"usable":{"type":"boolean","title":"Usable","default":true},"description":{"type":"string","title":"Description","default":""},"in_default_set":{"type":"boolean","title":"In Default Set","default":false}},"type":"object","required":["name"],"title":"ToolCatalogEntry","description":"A registered tool as offered to clients configuring an agent."},"ToolCatalogResponse":{"properties":{"tools":{"items":{"$ref":"#/components/schemas/ToolCatalogEntry"},"type":"array","title":"Tools"}},"type":"object","required":["tools"],"title":"ToolCatalogResponse"},"ToolDefinition":{"oneOf":[{"$ref":"#/components/schemas/MCPToolDefinition"},{"$ref":"#/components/schemas/ClassifyAndSwitchLLMTool"},{"$ref":"#/components/schemas/FinishTool"},{"$ref":"#/components/schemas/InvokeSkillTool"},{"$ref":"#/components/schemas/SwitchLLMTool"},{"$ref":"#/components/schemas/ThinkTool"},{"$ref":"#/components/schemas/VisionInspectTool"},{"$ref":"#/components/schemas/ClientTool"},{"$ref":"#/components/schemas/AskOracleTool"},{"$ref":"#/components/schemas/BrowserClickTool"},{"$ref":"#/components/schemas/BrowserCloseTabTool"},{"$ref":"#/components/schemas/BrowserGetContentTool"},{"$ref":"#/components/schemas/BrowserGetStateTool"},{"$ref":"#/components/schemas/BrowserGetStorageTool"},{"$ref":"#/components/schemas/BrowserGoBackTool"},{"$ref":"#/components/schemas/BrowserListTabsTool"},{"$ref":"#/components/schemas/BrowserNavigateTool"},{"$ref":"#/components/schemas/BrowserScrollTool"},{"$ref":"#/components/schemas/BrowserSetStorageTool"},{"$ref":"#/components/schemas/BrowserStartRecordingTool"},{"$ref":"#/components/schemas/BrowserStopRecordingTool"},{"$ref":"#/components/schemas/BrowserSwitchTabTool"},{"$ref":"#/components/schemas/BrowserToolSet"},{"$ref":"#/components/schemas/BrowserTypeTool"},{"$ref":"#/components/schemas/FileEditorTool"},{"$ref":"#/components/schemas/EditTool"},{"$ref":"#/components/schemas/ListDirectoryTool"},{"$ref":"#/components/schemas/ReadFileTool"},{"$ref":"#/components/schemas/WriteFileTool"},{"$ref":"#/components/schemas/GlobTool"},{"$ref":"#/components/schemas/GrepTool"},{"$ref":"#/components/schemas/PlanningFileEditorTool"},{"$ref":"#/components/schemas/TaskTool"},{"$ref":"#/components/schemas/TaskToolSet"},{"$ref":"#/components/schemas/TaskTrackerTool"},{"$ref":"#/components/schemas/TerminalTool"},{"$ref":"#/components/schemas/WorkflowTool"},{"$ref":"#/components/schemas/WorkflowToolSet"}],"discriminator":{"propertyName":"kind","mapping":{"openhands__sdk__mcp__tool__MCPToolDefinition-Output__1":"#/components/schemas/MCPToolDefinition","openhands__sdk__tool__builtins__classify_and_switch_llm__ClassifyAndSwitchLLMTool-Output__1":"#/components/schemas/ClassifyAndSwitchLLMTool","openhands__sdk__tool__builtins__finish__FinishTool-Output__1":"#/components/schemas/FinishTool","openhands__sdk__tool__builtins__invoke_skill__InvokeSkillTool-Output__1":"#/components/schemas/InvokeSkillTool","openhands__sdk__tool__builtins__switch_llm__SwitchLLMTool-Output__1":"#/components/schemas/SwitchLLMTool","openhands__sdk__tool__builtins__think__ThinkTool-Output__1":"#/components/schemas/ThinkTool","openhands__sdk__tool__builtins__vision_inspect__VisionInspectTool-Output__1":"#/components/schemas/VisionInspectTool","openhands__sdk__tool__client_tool__ClientTool-Output__1":"#/components/schemas/ClientTool","openhands__tools__ask_oracle__definition__AskOracleTool-Output__1":"#/components/schemas/AskOracleTool","openhands__tools__browser_use__definition__BrowserClickTool-Output__1":"#/components/schemas/BrowserClickTool","openhands__tools__browser_use__definition__BrowserCloseTabTool-Output__1":"#/components/schemas/BrowserCloseTabTool","openhands__tools__browser_use__definition__BrowserGetContentTool-Output__1":"#/components/schemas/BrowserGetContentTool","openhands__tools__browser_use__definition__BrowserGetStateTool-Output__1":"#/components/schemas/BrowserGetStateTool","openhands__tools__browser_use__definition__BrowserGetStorageTool-Output__1":"#/components/schemas/BrowserGetStorageTool","openhands__tools__browser_use__definition__BrowserGoBackTool-Output__1":"#/components/schemas/BrowserGoBackTool","openhands__tools__browser_use__definition__BrowserListTabsTool-Output__1":"#/components/schemas/BrowserListTabsTool","openhands__tools__browser_use__definition__BrowserNavigateTool-Output__1":"#/components/schemas/BrowserNavigateTool","openhands__tools__browser_use__definition__BrowserScrollTool-Output__1":"#/components/schemas/BrowserScrollTool","openhands__tools__browser_use__definition__BrowserSetStorageTool-Output__1":"#/components/schemas/BrowserSetStorageTool","openhands__tools__browser_use__definition__BrowserStartRecordingTool-Output__1":"#/components/schemas/BrowserStartRecordingTool","openhands__tools__browser_use__definition__BrowserStopRecordingTool-Output__1":"#/components/schemas/BrowserStopRecordingTool","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__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","openhands__tools__gemini__read_file__definition__ReadFileTool-Output__1":"#/components/schemas/ReadFileTool","openhands__tools__gemini__write_file__definition__WriteFileTool-Output__1":"#/components/schemas/WriteFileTool","openhands__tools__glob__definition__GlobTool-Output__1":"#/components/schemas/GlobTool","openhands__tools__grep__definition__GrepTool-Output__1":"#/components/schemas/GrepTool","openhands__tools__planning_file_editor__definition__PlanningFileEditorTool-Output__1":"#/components/schemas/PlanningFileEditorTool","openhands__tools__task__definition__TaskTool-Output__1":"#/components/schemas/TaskTool","openhands__tools__task__definition__TaskToolSet-Output__1":"#/components/schemas/TaskToolSet","openhands__tools__task_tracker__definition__TaskTrackerTool-Output__1":"#/components/schemas/TaskTrackerTool","openhands__tools__terminal__definition__TerminalTool-Output__1":"#/components/schemas/TerminalTool","openhands__tools__workflow__definition__WorkflowTool-Output__1":"#/components/schemas/WorkflowTool","openhands__tools__workflow__definition__WorkflowToolSet-Output__1":"#/components/schemas/WorkflowToolSet"}}},"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."},"ToolShieldLLMSecurityAnalyzer-Input":{"properties":{"llm":{"$ref":"#/components/schemas/LLM-Input","description":"LLM used as the guardrail. Can be a smaller/cheaper model than the actor LLM; only the model's ability to classify action risk matters."},"history_window":{"type":"integer","title":"History Window","description":"Number of prior actions to include as context.","default":20},"safety_experiences":{"type":"string","title":"Safety Experiences","description":"Pre-generated safety guidelines injected into the guardrail's system prompt.\n- ``\"\"`` (default): bare guardrail -- no experiences. The analyzer still separates actor from judge; it just classifies without distilled tool-specific guidance.\n- Any non-empty string: used as-is. The intended pattern is to call one of the helpers (``default_safety_experiences()``, ``load_safety_experiences(tool_names)``, ``auto_detect_safety_experiences()``) which require the ``[toolshield]`` optional extra (``pip install openhands-sdk[toolshield]``). Callers with their own source of guidelines can pass any custom string.","default":""},"kind":{"type":"string","const":"ToolShieldLLMSecurityAnalyzer","title":"Kind"}},"type":"object","required":["llm"],"title":"ToolShieldLLMSecurityAnalyzer","description":"Evaluate each action via a separate guardrail LLM.\n\nPairs with the existing ``ConfirmRisky`` policy unchanged: this\nanalyzer only *assigns* the risk level; ``ConfirmRisky`` decides\nwhether to pause for user confirmation.\n\nBy default the analyzer runs as a bare guardrail (no distilled\nsafety experiences). To enable the ToolShield seed, install\n``pip install openhands-sdk[toolshield]`` and pass the rendered\nexperiences via the ``safety_experiences`` field -- typically via\none of the helpers (``default_safety_experiences()``,\n``load_safety_experiences(...)``, ``auto_detect_safety_experiences()``).\nTested against ``toolshield>=0.1.3,<0.2``.\n\nNote: ``reasoning_content`` and ``thinking_blocks`` from extended-\nthinking models are deliberately excluded from the guardrail\ncontext. The risk signal lives in the tool call's name and\narguments; including reasoning text would inflate the prompt\nwithout proportional safety gain. Subclasses needing reasoning\nvisibility should override :func:`_format_action_for_guardrail`.\n\nLifecycle: instances maintain a per-conversation deque of recent\nactions (``history_window`` items) for guardrail context. Each\ninstance is intended for SINGLE-CONVERSATION use. Reusing one\nanalyzer instance across multiple conversations will leak action\nhistory between them, which is both a privacy issue (conversation\nA's tool arguments visible in conversation B's guardrail prompt)\nand a correctness issue (the guardrail evaluates conversation B's\nactions against irrelevant history). Construct one analyzer per\nconversation, OR call :meth:`reset_history` at conversation\nboundaries.\n\nThe recent-action-context propagation across analyzers (this one,\n:class:`LLMSecurityAnalyzer`, :class:`GraySwanAnalyzer`) is tracked\nfor convergence in a separate follow-up; until that lands,\nsingle-conversation lifecycle is the contract.\n\nFailure modes are consistent and ensemble-safe -- both an\ninfrastructure error (network, rate limit) and a parse failure\n(the guardrail responded but its output had no parseable\n``RISK:`` label) return ``SecurityRisk.UNKNOWN``. ``ConfirmRisky``\nwith ``confirm_unknown=True`` then pauses for user confirmation,\nmatching the conservative posture without dominating ``max()`` in\nensemble fusion."},"ToolShieldLLMSecurityAnalyzer-Output":{"properties":{"llm":{"$ref":"#/components/schemas/LLM-Output","description":"LLM used as the guardrail. Can be a smaller/cheaper model than the actor LLM; only the model's ability to classify action risk matters."},"history_window":{"type":"integer","title":"History Window","description":"Number of prior actions to include as context.","default":20},"safety_experiences":{"type":"string","title":"Safety Experiences","description":"Pre-generated safety guidelines injected into the guardrail's system prompt.\n- ``\"\"`` (default): bare guardrail -- no experiences. The analyzer still separates actor from judge; it just classifies without distilled tool-specific guidance.\n- Any non-empty string: used as-is. The intended pattern is to call one of the helpers (``default_safety_experiences()``, ``load_safety_experiences(tool_names)``, ``auto_detect_safety_experiences()``) which require the ``[toolshield]`` optional extra (``pip install openhands-sdk[toolshield]``). Callers with their own source of guidelines can pass any custom string.","default":""},"kind":{"type":"string","const":"ToolShieldLLMSecurityAnalyzer","title":"Kind"}},"type":"object","required":["llm","kind"],"title":"ToolShieldLLMSecurityAnalyzer","description":"Evaluate each action via a separate guardrail LLM.\n\nPairs with the existing ``ConfirmRisky`` policy unchanged: this\nanalyzer only *assigns* the risk level; ``ConfirmRisky`` decides\nwhether to pause for user confirmation.\n\nBy default the analyzer runs as a bare guardrail (no distilled\nsafety experiences). To enable the ToolShield seed, install\n``pip install openhands-sdk[toolshield]`` and pass the rendered\nexperiences via the ``safety_experiences`` field -- typically via\none of the helpers (``default_safety_experiences()``,\n``load_safety_experiences(...)``, ``auto_detect_safety_experiences()``).\nTested against ``toolshield>=0.1.3,<0.2``.\n\nNote: ``reasoning_content`` and ``thinking_blocks`` from extended-\nthinking models are deliberately excluded from the guardrail\ncontext. The risk signal lives in the tool call's name and\narguments; including reasoning text would inflate the prompt\nwithout proportional safety gain. Subclasses needing reasoning\nvisibility should override :func:`_format_action_for_guardrail`.\n\nLifecycle: instances maintain a per-conversation deque of recent\nactions (``history_window`` items) for guardrail context. Each\ninstance is intended for SINGLE-CONVERSATION use. Reusing one\nanalyzer instance across multiple conversations will leak action\nhistory between them, which is both a privacy issue (conversation\nA's tool arguments visible in conversation B's guardrail prompt)\nand a correctness issue (the guardrail evaluates conversation B's\nactions against irrelevant history). Construct one analyzer per\nconversation, OR call :meth:`reset_history` at conversation\nboundaries.\n\nThe recent-action-context propagation across analyzers (this one,\n:class:`LLMSecurityAnalyzer`, :class:`GraySwanAnalyzer`) is tracked\nfor convergence in a separate follow-up; until that lands,\nsingle-conversation lifecycle is the contract.\n\nFailure modes are consistent and ensemble-safe -- both an\ninfrastructure error (network, rate limit) and a parse failure\n(the guardrail responded but its output had no parseable\n``RISK:`` label) return ``SecurityRisk.UNKNOWN``. ``ConfirmRisky``\nwith ``confirm_unknown=True`` then pauses for user confirmation,\nmatching the conservative posture without dominating ``max()`` in\nensemble fusion."},"TopLogprob":{"properties":{"token":{"type":"string","title":"Token"},"bytes":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Bytes"},"logprob":{"type":"number","title":"Logprob"}},"additionalProperties":true,"type":"object","required":["token","logprob"],"title":"TopLogprob"},"TraceMetadataValue":{"anyOf":[{"type":"string"},{"type":"boolean"},{"type":"integer"},{"type":"number"},{"items":{"type":"string"},"type":"array"},{"items":{"type":"boolean"},"type":"array"},{"items":{"type":"integer"},"type":"array"},{"items":{"type":"number"},"type":"array"}]},"UninstallCanvasExtensionResponse":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"UninstallCanvasExtensionResponse","description":"Response from a canvas extension uninstall."},"UninstallPluginResponse":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"UninstallPluginResponse","description":"Response from a plugin uninstall."},"UninstallSkillResponse":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"UninstallSkillResponse","description":"Response from skill uninstall operation."},"UpdateCanvasExtensionStateRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["enabled"],"title":"UpdateCanvasExtensionStateRequest","description":"Request body for updating canvas extension state (enable/disable)."},"UpdateCanvasExtensionStateResponse":{"properties":{"name":{"type":"string","title":"Name"},"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["name","enabled"],"title":"UpdateCanvasExtensionStateResponse","description":"Response from a canvas extension state update."},"UpdateConversationRequest":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":200,"minLength":1},{"type":"null"}],"title":"Title","description":"New conversation title"},"tags":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Tags","description":"Key-value tags to set on the conversation. Keys must be lowercase alphanumeric. Values are arbitrary strings up to 256 characters. Replaces all existing tags when provided."}},"type":"object","title":"UpdateConversationRequest","description":"Payload to update conversation metadata."},"UpdatePluginResponse":{"properties":{"message":{"type":"string","title":"Message"},"plugin":{"$ref":"#/components/schemas/InstalledPluginResponse"}},"type":"object","required":["message","plugin"],"title":"UpdatePluginResponse","description":"Response from a plugin refresh/update."},"UpdatePluginStateRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["enabled"],"title":"UpdatePluginStateRequest","description":"Request body for updating plugin state (enable/disable)."},"UpdatePluginStateResponse":{"properties":{"name":{"type":"string","title":"Name"},"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["name","enabled"],"title":"UpdatePluginStateResponse","description":"Response from a plugin state update."},"UpdateSecretsRequest":{"properties":{"secrets":{"additionalProperties":{"$ref":"#/components/schemas/SecretSource-Input"},"type":"object","title":"Secrets","description":"Dictionary mapping secret keys to values"}},"type":"object","required":["secrets"],"title":"UpdateSecretsRequest","description":"Payload to update secrets in a conversation."},"UpdateSkillResponse":{"properties":{"message":{"type":"string","title":"Message"},"skill":{"$ref":"#/components/schemas/InstalledSkillResponse"}},"type":"object","required":["message","skill"],"title":"UpdateSkillResponse","description":"Response from skill update operation."},"UpdateSkillStateRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["enabled"],"title":"UpdateSkillStateRequest","description":"Request body for updating skill state (enable/disable)."},"UpdateSkillStateResponse":{"properties":{"name":{"type":"string","title":"Name"},"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["name","enabled"],"title":"UpdateSkillStateResponse","description":"Response from skill state update operation."},"UserRejectObservation":{"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"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id","description":"Parent event id in the conversation tree. None for the root, or for legacy events predating the tree (see EventLog's effective-parent rule). Events sharing a parent_id are sibling branches."},"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"},"rejection_reason":{"type":"string","title":"Rejection Reason","description":"Reason for rejecting the action","default":"User rejected the action"},"rejection_source":{"type":"string","enum":["user","hook"],"title":"Rejection Source","description":"Source of the rejection: 'user' for confirmation mode rejections, 'hook' for PreToolUse hook blocks","default":"user"},"action_id":{"type":"string","title":"Action Id","description":"The action id that this observation is responding to"},"kind":{"type":"string","const":"UserRejectObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["tool_name","tool_call_id","action_id","kind"],"title":"UserRejectObservation","description":"Observation when an action is rejected by user or hook.\n\nThis event is emitted when:\n- User rejects an action during confirmation mode (rejection_source=\"user\")\n- A PreToolUse hook blocks an action (rejection_source=\"hook\")"},"VSCodeUrlResponse":{"properties":{"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"}},"type":"object","required":["url"],"title":"VSCodeUrlResponse","description":"Response model for VSCode URL."},"ValidateProfileError":{"properties":{"type":{"type":"string","title":"Type"},"message":{"type":"string","title":"Message"}},"type":"object","required":["type","message"],"title":"ValidateProfileError","description":"Structured error returned when validation fails."},"ValidateProfileRequest":{"properties":{"llm":{"$ref":"#/components/schemas/LLM-Input"}},"type":"object","required":["llm"],"title":"ValidateProfileRequest","description":"Request body for LLM pre-flight validation.\n\nAccepts an LLM config (same shape as ``SaveProfileRequest.llm``) so the\nfrontend can validate a draft *before* persisting it."},"ValidateProfileResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"error":{"anyOf":[{"$ref":"#/components/schemas/ValidateProfileError"},{"type":"null"}]}},"type":"object","required":["valid"],"title":"ValidateProfileResponse","description":"Result of an LLM pre-flight check."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"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 LLM models organized by provider."},"VisionInspectAction":{"properties":{"image_index":{"type":"integer","minimum":0.0,"title":"Image Index","description":"Zero-based index of the image to inspect from the latest user message."},"question":{"type":"string","minLength":1,"title":"Question","description":"Question to ask the vision model about the selected image."},"profile_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Name","description":"Optional saved vision-capable LLM profile name. If omitted, the first available vision profile listed in the tool description is used."},"kind":{"type":"string","const":"VisionInspectAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["image_index","question","kind"],"title":"VisionInspectAction","description":"Action for asking a vision model about an attached image."},"VisionInspectObservation":{"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},"image_index":{"type":"integer","title":"Image Index","description":"Image index that was inspected."},"question":{"type":"string","title":"Question","description":"Question asked of the vision model."},"profile_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Name","description":"Vision-capable profile used for inspection."},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"Vision-capable model used for inspection."},"base_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Base Url","description":"Vision-capable LLM endpoint used for inspection."},"answer":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Answer","description":"Text answer returned by the vision model."},"kind":{"type":"string","const":"VisionInspectObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["image_index","question","kind"],"title":"VisionInspectObservation","description":"Observation returned after a vision model inspects an image."},"VisionInspectTool":{"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":{"type":"string","const":"VisionInspectTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"VisionInspectTool","description":"Tool for one-off image inspection through a saved vision profile."},"WebhookSpec":{"properties":{"event_buffer_size":{"type":"integer","minimum":1.0,"title":"Event Buffer Size","description":"The number of events to buffer locally before posting to the webhook","default":5},"base_url":{"type":"string","title":"Base Url","description":"The base URL of the webhook service. Events will be sent to {base_url}/events and conversation info to {base_url}/conversations"},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers"},"flush_delay":{"type":"number","exclusiveMinimum":0.0,"title":"Flush Delay","description":"The delay in seconds after which buffered events will be flushed to the webhook, even if the buffer is not full. Timer is reset on each new event.","default":30.0},"num_retries":{"type":"integer","minimum":0.0,"title":"Num Retries","description":"The number of times to retry if the post operation fails","default":3},"retry_delay":{"type":"integer","minimum":0.0,"title":"Retry Delay","description":"The delay between retries","default":5},"max_queue_size":{"type":"integer","minimum":1.0,"title":"Max Queue Size","description":"Upper bound on the number of events buffered for delivery. The oldest events are dropped past this bound to prevent unbounded memory growth.","default":1000},"max_batch_bytes":{"type":"integer","minimum":1.0,"title":"Max Batch Bytes","description":"Upper bound on the serialized size of each webhook request. A single event larger than this limit is sent by itself.","default":5242880},"max_queue_bytes":{"type":"integer","minimum":1.0,"title":"Max Queue Bytes","description":"Upper bound on the serialized size of events buffered for delivery. The oldest events are dropped when the queue exceeds this bound.","default":52428800}},"type":"object","required":["base_url"],"title":"WebhookSpec","description":"Spec to create a webhook. All webhook requests use POST method."},"WorkflowAction":{"properties":{"name":{"type":"string","title":"Name","description":"A short name for this workflow run."},"script":{"type":"string","title":"Script","description":"Python workflow script to run. It must define `async def main(wf):` and coordinate work only through the provided `wf` object."},"max_concurrency":{"type":"integer","maximum":64.0,"minimum":1.0,"title":"Max Concurrency","description":"Maximum number of sub-agent tasks to run concurrently. Consider 2–4 for LLM-heavy workflows to avoid hitting API rate limits.","default":8},"kind":{"type":"string","const":"WorkflowAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["name","script","kind"],"title":"WorkflowAction","description":"Schema for running a Python dynamic workflow script."},"WorkflowObservation":{"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},"name":{"type":"string","title":"Name","description":"The workflow name that was executed."},"status":{"type":"string","enum":["completed","error"],"title":"Status","description":"The workflow execution status."},"kind":{"type":"string","const":"WorkflowObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["name","status","kind"],"title":"WorkflowObservation","description":"Observation from a dynamic workflow run."},"WorkflowTool":{"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":{"type":"string","const":"WorkflowTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"WorkflowTool","description":"Low-level tool for explicit executor injection.\n\nPrefer ``WorkflowToolSet`` for standard SDK auto-create usage.\nUse ``WorkflowTool`` when you need to inject a custom executor\n(e.g., in tests or extensions)."},"WorkflowToolSet":{"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":{"type":"string","const":"WorkflowToolSet","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"WorkflowToolSet","description":"Tool set that creates the dynamic workflow tool."},"WorkspaceItem":{"properties":{"id":{"type":"string","maxLength":4096,"minLength":1,"title":"Id"},"name":{"type":"string","maxLength":256,"minLength":1,"title":"Name"},"path":{"type":"string","maxLength":4096,"minLength":1,"title":"Path"},"parentPath":{"anyOf":[{"type":"string","maxLength":4096},{"type":"null"}],"title":"Parentpath"}},"type":"object","required":["id","name","path"],"title":"WorkspaceItem"},"WorkspaceParentItem":{"properties":{"id":{"type":"string","maxLength":4096,"minLength":1,"title":"Id"},"name":{"type":"string","maxLength":256,"minLength":1,"title":"Name"},"path":{"type":"string","maxLength":4096,"minLength":1,"title":"Path"}},"type":"object","required":["id","name","path"],"title":"WorkspaceParentItem"},"WorkspacesListResponse":{"properties":{"workspaces":{"items":{"$ref":"#/components/schemas/WorkspaceItem"},"type":"array","title":"Workspaces"},"workspaceParents":{"items":{"$ref":"#/components/schemas/WorkspaceParentItem"},"type":"array","title":"Workspaceparents"}},"type":"object","title":"WorkspacesListResponse"},"WriteFileAction":{"properties":{"file_path":{"type":"string","title":"File Path","description":"The path to the file to write to."},"content":{"type":"string","title":"Content","description":"The content to write to the file."},"kind":{"type":"string","const":"WriteFileAction","title":"Kind"}},"additionalProperties":false,"type":"object","required":["file_path","content","kind"],"title":"WriteFileAction","description":"Schema for write file operation."},"WriteFileObservation":{"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},"file_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Path","description":"The file path that was written."},"is_new_file":{"type":"boolean","title":"Is New File","description":"Whether a new file was created.","default":false},"old_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Old Content","description":"The previous content of the file (if it existed)."},"new_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"New Content","description":"The new content written to the file."},"kind":{"type":"string","const":"WriteFileObservation","title":"Kind"}},"additionalProperties":false,"type":"object","required":["kind"],"title":"WriteFileObservation","description":"Observation from writing a file."},"WriteFileTool":{"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":{"type":"string","const":"WriteFileTool","title":"Kind"},"title":{"type":"string","title":"Title","readOnly":true}},"type":"object","required":["description","action_type","kind","title"],"title":"WriteFileTool","description":"Tool for writing complete file contents."},"_RemoteMCPServerSpec":{"properties":{"type":{"type":"string","enum":["http","shttp","streamable-http","sse"],"title":"Type"},"url":{"type":"string","minLength":1,"title":"Url"},"headers":{"additionalProperties":{"type":"string"},"type":"object","title":"Headers"},"auth":{"anyOf":[{"oneOf":[{"$ref":"#/components/schemas/MCPNoneAuthCredential"},{"$ref":"<redacted:api_key>"},{"$ref":"#/components/schemas/MCPBearerAuthCredential-Input"},{"$ref":"#/components/schemas/MCPBasicAuthCredential-Input"},{"$ref":"#/components/schemas/MCPHeaderAuthCredential-Input"},{"$ref":"#/components/schemas/MCPOAuthAuthCredential-Input"}],"discriminator":{"propertyName":"strategy","mapping":{"api_key":"<redacted:api_key>","basic":"#/components/schemas/MCPBasicAuthCredential-Input","bearer":"#/components/schemas/MCPBearerAuthCredential-Input","header":"#/components/schemas/MCPHeaderAuthCredential-Input","none":"#/components/schemas/MCPNoneAuthCredential","oauth2":"#/components/schemas/MCPOAuthAuthCredential-Input"}}},{"type":"null"}],"title":"Auth"},"timeout":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Timeout"},"sse_read_timeout":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sse Read Timeout"},"keep_alive":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Keep Alive"}},"type":"object","required":["type","url"],"title":"_RemoteMCPServerSpec","description":"Legacy remote MCP server spec accepted by the public REST API."},"_StdioMCPServerSpec":{"properties":{"type":{"type":"string","const":"stdio","title":"Type","default":"stdio"},"command":{"type":"string","minLength":1,"title":"Command","description":"Executable to invoke"},"args":{"items":{"type":"string"},"type":"array","title":"Args"},"env":{"additionalProperties":{"type":"string"},"type":"object","title":"Env"},"cwd":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cwd"}},"type":"object","required":["command"],"title":"_StdioMCPServerSpec","description":"Legacy stdio MCP server spec accepted by the public REST API."},"mcp__types__Tool":{"properties":{"name":{"type":"string","title":"Name"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"inputSchema":{"additionalProperties":true,"type":"object","title":"Inputschema"},"outputSchema":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Outputschema"},"icons":{"anyOf":[{"items":{"$ref":"#/components/schemas/Icon"},"type":"array"},{"type":"null"}],"title":"Icons"},"annotations":{"anyOf":[{"$ref":"#/components/schemas/mcp__types__ToolAnnotations"},{"type":"null"}]},"_meta":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Meta"},"execution":{"anyOf":[{"$ref":"#/components/schemas/ToolExecution"},{"type":"null"}]}},"additionalProperties":true,"type":"object","required":["name","inputSchema"],"title":"Tool","description":"Definition for a tool the client can call."},"mcp__types__ToolAnnotations":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"readOnlyHint":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Readonlyhint"},"destructiveHint":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Destructivehint"},"idempotentHint":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Idempotenthint"},"openWorldHint":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Openworldhint"}},"additionalProperties":true,"type":"object","title":"ToolAnnotations","description":"Additional properties describing a Tool to clients.\n\nNOTE: all properties in ToolAnnotations are **hints**.\nThey are not guaranteed to provide a faithful description of\ntool behavior (including descriptive properties like `title`).\n\nClients should never make tool use decisions based on ToolAnnotations\nreceived from untrusted servers."},"openhands__agent_server__plugins_router__MarketplaceCatalogResponse":{"properties":{"plugins":{"items":{"$ref":"#/components/schemas/MarketplacePluginInfo"},"type":"array","title":"Plugins"}},"type":"object","required":["plugins"],"title":"MarketplaceCatalogResponse","description":"Response containing the plugins marketplace catalog."},"openhands__agent_server__skills_router__MarketplaceCatalogResponse":{"properties":{"skills":{"items":{"$ref":"#/components/schemas/MarketplaceSkillInfo"},"type":"array","title":"Skills"}},"type":"object","required":["skills"],"title":"MarketplaceCatalogResponse","description":"Response containing the marketplace catalog."},"openhands__sdk__tool__spec__Tool":{"properties":{"name":{"type":"string","title":"Name","description":"Name of the tool class, e.g., 'TerminalTool'. Import it from an `openhands.tools.<module>` subpackage.","examples":["TerminalTool","FileEditorTool","TaskTrackerTool"]},"params":{"additionalProperties":true,"type":"object","title":"Params","description":"Parameters for the tool's .create() method, e.g., {'working_dir': '/app'}","examples":[{"working_dir":"/workspace"}]}},"type":"object","required":["name"],"title":"Tool","description":"Defines a tool to be initialized for the agent.\n\nThis is only used in agent-sdk for type schema for server use."},"openhands__sdk__tool__tool__ToolAnnotations":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"A human-readable title for the tool."},"readOnlyHint":{"type":"boolean","title":"Readonlyhint","description":"If true, the tool does not modify its environment. Default: false","default":false},"destructiveHint":{"type":"boolean","title":"Destructivehint","description":"If true, the tool may perform destructive updates to its environment. If false, the tool performs only additive updates. (This property is meaningful only when `readOnlyHint == false`) Default: true","default":true},"idempotentHint":{"type":"boolean","title":"Idempotenthint","description":"If true, calling the tool repeatedly with the same arguments will have no additional effect on the its environment. (This property is meaningful only when `readOnlyHint == false`) Default: false","default":false},"openWorldHint":{"type":"boolean","title":"Openworldhint","description":"If true, this tool may interact with an 'open world' of external entities. If false, the tool's domain of interaction is closed. For example, the world of a web search tool is open, whereas that of a memory tool is not. Default: true","default":true}},"type":"object","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"},"HTTPBearer":{"type":"http","scheme":"bearer"},"APIKeyCookie":{"type":"apiKey","in":"cookie","name":"oh_workspace_session_key"}}}}