2026-02-01 23:38:43 -08:00
{
"$schema" : "http://json-schema.org/draft-07/schema#" ,
"definitions" : {
"AccountLoginCompletedNotification" : {
"properties" : {
"error" : {
"type" : [
"string" ,
"null"
]
} ,
"loginId" : {
"type" : [
"string" ,
"null"
]
} ,
"success" : {
"type" : "boolean"
}
} ,
"required" : [
"success"
] ,
"type" : "object"
} ,
"AccountRateLimitsUpdatedNotification" : {
"properties" : {
"rateLimits" : {
"$ref" : "#/definitions/RateLimitSnapshot"
}
} ,
"required" : [
"rateLimits"
] ,
"type" : "object"
} ,
"AccountUpdatedNotification" : {
"properties" : {
"authMode" : {
"anyOf" : [
{
"$ref" : "#/definitions/AuthMode"
} ,
{
"type" : "null"
}
]
2026-03-01 22:43:37 +01:00
} ,
"planType" : {
"anyOf" : [
{
"$ref" : "#/definitions/PlanType"
} ,
{
"type" : "null"
}
]
2026-02-01 23:38:43 -08:00
}
} ,
"type" : "object"
} ,
"AgentMessageDeltaNotification" : {
"properties" : {
"delta" : {
"type" : "string"
} ,
"itemId" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"delta" ,
"itemId" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
2026-02-17 11:45:04 -08:00
"AppBranding" : {
"description" : "EXPERIMENTAL - app metadata returned by app-list APIs." ,
"properties" : {
"category" : {
"type" : [
"string" ,
"null"
]
} ,
"developer" : {
"type" : [
"string" ,
"null"
]
} ,
"isDiscoverableApp" : {
"type" : "boolean"
} ,
"privacyPolicy" : {
"type" : [
"string" ,
"null"
]
} ,
"termsOfService" : {
"type" : [
"string" ,
"null"
]
} ,
"website" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"isDiscoverableApp"
] ,
"type" : "object"
} ,
2026-02-08 15:24:56 -08:00
"AppInfo" : {
"description" : "EXPERIMENTAL - app metadata returned by app-list APIs." ,
"properties" : {
2026-02-17 11:45:04 -08:00
"appMetadata" : {
"anyOf" : [
{
"$ref" : "#/definitions/AppMetadata"
} ,
{
"type" : "null"
}
]
} ,
"branding" : {
"anyOf" : [
{
"$ref" : "#/definitions/AppBranding"
} ,
{
"type" : "null"
}
]
} ,
2026-02-08 15:24:56 -08:00
"description" : {
"type" : [
"string" ,
"null"
]
} ,
"distributionChannel" : {
"type" : [
"string" ,
"null"
]
} ,
"id" : {
"type" : "string"
} ,
"installUrl" : {
"type" : [
"string" ,
"null"
]
} ,
"isAccessible" : {
"default" : false ,
"type" : "boolean"
} ,
2026-02-12 16:30:52 -08:00
"isEnabled" : {
"default" : true ,
"description" : "Whether this app is enabled in config.toml. Example: ```toml [apps.bad_app] enabled = false ```" ,
"type" : "boolean"
} ,
2026-02-17 11:45:04 -08:00
"labels" : {
"additionalProperties" : {
"type" : "string"
} ,
"type" : [
"object" ,
"null"
]
} ,
2026-02-08 15:24:56 -08:00
"logoUrl" : {
"type" : [
"string" ,
"null"
]
} ,
"logoUrlDark" : {
"type" : [
"string" ,
"null"
]
} ,
"name" : {
"type" : "string"
add @plugin mentions (#13510)
## Note-- added plugin mentions via @, but that conflicts with file
mentions
depends and builds upon #13433.
- introduces explicit `@plugin` mentions. this injects the plugin's mcp
servers, app names, and skill name format into turn context as a dev
message.
- we do not yet have UI for these mentions, so we currently parse raw
text (as opposed to skills and apps which have UI chips, autocomplete,
etc.) this depends on a `plugins/list` app-server endpoint we can feed
the UI with, which is upcoming
- also annotate mcp and app tool descriptions with the plugin(s) they
come from. this gives the model a first class way of understanding what
tools come from which plugins, which will help implicit invocation.
### Tests
Added and updated tests, unit and integration. Also confirmed locally a
raw `@plugin` injects the dev message, and the model knows about its
apps, mcps, and skills.
2026-03-05 16:03:39 -08:00
} ,
"pluginDisplayNames" : {
"default" : [ ] ,
"items" : {
"type" : "string"
} ,
"type" : "array"
2026-02-08 15:24:56 -08:00
}
} ,
"required" : [
"id" ,
"name"
] ,
"type" : "object"
} ,
"AppListUpdatedNotification" : {
"description" : "EXPERIMENTAL - notification emitted when the app list changes." ,
"properties" : {
"data" : {
"items" : {
"$ref" : "#/definitions/AppInfo"
} ,
"type" : "array"
}
} ,
"required" : [
"data"
] ,
"type" : "object"
} ,
2026-02-17 11:45:04 -08:00
"AppMetadata" : {
"properties" : {
"categories" : {
"items" : {
"type" : "string"
} ,
"type" : [
"array" ,
"null"
]
} ,
"developer" : {
"type" : [
"string" ,
"null"
]
} ,
"firstPartyRequiresInstall" : {
"type" : [
"boolean" ,
"null"
]
} ,
"firstPartyType" : {
"type" : [
"string" ,
"null"
]
} ,
"review" : {
"anyOf" : [
{
"$ref" : "#/definitions/AppReview"
} ,
{
"type" : "null"
}
]
} ,
"screenshots" : {
"items" : {
"$ref" : "#/definitions/AppScreenshot"
} ,
"type" : [
"array" ,
"null"
]
} ,
"seoDescription" : {
"type" : [
"string" ,
"null"
]
} ,
"showInComposerWhenUnlinked" : {
"type" : [
"boolean" ,
"null"
]
} ,
"subCategories" : {
"items" : {
"type" : "string"
} ,
"type" : [
"array" ,
"null"
]
} ,
"version" : {
"type" : [
"string" ,
"null"
]
} ,
"versionId" : {
"type" : [
"string" ,
"null"
]
} ,
"versionNotes" : {
"type" : [
"string" ,
"null"
]
}
} ,
"type" : "object"
} ,
"AppReview" : {
"properties" : {
"status" : {
"type" : "string"
}
} ,
"required" : [
"status"
] ,
"type" : "object"
} ,
"AppScreenshot" : {
"properties" : {
"fileId" : {
"type" : [
"string" ,
"null"
]
} ,
"url" : {
"type" : [
"string" ,
"null"
]
} ,
"userPrompt" : {
"type" : "string"
}
} ,
"required" : [
"userPrompt"
] ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
"AuthMode" : {
"description" : "Authentication mode for OpenAI-backed providers." ,
"oneOf" : [
{
"description" : "OpenAI API key provided by the caller and stored by Codex." ,
"enum" : [
"apikey"
] ,
"type" : "string"
} ,
{
"description" : "ChatGPT OAuth managed by Codex (tokens persisted and refreshed by Codex)." ,
"enum" : [
"chatgpt"
] ,
"type" : "string"
} ,
{
"description" : "[UNSTABLE] FOR OPENAI INTERNAL USE ONLY - DO NOT USE.\n\nChatGPT auth tokens are supplied by an external host app and are only stored in memory. Token refresh must be handled by the external host app." ,
"enum" : [
"chatgptAuthTokens"
] ,
"type" : "string"
}
]
} ,
"ByteRange" : {
"properties" : {
"end" : {
"format" : "uint" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"start" : {
"format" : "uint" ,
"minimum" : 0.0 ,
"type" : "integer"
}
} ,
"required" : [
"end" ,
"start"
] ,
"type" : "object"
} ,
"CodexErrorInfo" : {
"description" : "This translation layer make sure that we expose codex error code in camel case.\n\nWhen an upstream HTTP status is available (for example, from the Responses API or a provider), it is forwarded in `httpStatusCode` on the relevant `codexErrorInfo` variant." ,
"oneOf" : [
{
"enum" : [
"contextWindowExceeded" ,
"usageLimitExceeded" ,
2026-02-11 17:16:27 -08:00
"serverOverloaded" ,
2026-02-01 23:38:43 -08:00
"internalServerError" ,
"unauthorized" ,
"badRequest" ,
"threadRollbackFailed" ,
"sandboxError" ,
"other"
] ,
"type" : "string"
} ,
{
"additionalProperties" : false ,
"properties" : {
"httpConnectionFailed" : {
"properties" : {
"httpStatusCode" : {
"format" : "uint16" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
}
} ,
"type" : "object"
}
} ,
"required" : [
"httpConnectionFailed"
] ,
"title" : "HttpConnectionFailedCodexErrorInfo" ,
"type" : "object"
} ,
{
"additionalProperties" : false ,
"description" : "Failed to connect to the response SSE stream." ,
"properties" : {
"responseStreamConnectionFailed" : {
"properties" : {
"httpStatusCode" : {
"format" : "uint16" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
}
} ,
"type" : "object"
}
} ,
"required" : [
"responseStreamConnectionFailed"
] ,
"title" : "ResponseStreamConnectionFailedCodexErrorInfo" ,
"type" : "object"
} ,
{
"additionalProperties" : false ,
"description" : "The response SSE stream disconnected in the middle of a turn before completion." ,
"properties" : {
"responseStreamDisconnected" : {
"properties" : {
"httpStatusCode" : {
"format" : "uint16" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
}
} ,
"type" : "object"
}
} ,
"required" : [
"responseStreamDisconnected"
] ,
"title" : "ResponseStreamDisconnectedCodexErrorInfo" ,
"type" : "object"
} ,
{
"additionalProperties" : false ,
"description" : "Reached the retry limit for responses." ,
"properties" : {
"responseTooManyFailedAttempts" : {
"properties" : {
"httpStatusCode" : {
"format" : "uint16" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
}
} ,
"type" : "object"
}
} ,
"required" : [
"responseTooManyFailedAttempts"
] ,
"title" : "ResponseTooManyFailedAttemptsCodexErrorInfo" ,
"type" : "object"
}
]
} ,
2026-02-20 21:36:12 -08:00
"CollabAgentState" : {
"properties" : {
"message" : {
"type" : [
"string" ,
"null"
]
} ,
"status" : {
"$ref" : "#/definitions/CollabAgentStatus"
}
} ,
"required" : [
"status"
] ,
"type" : "object"
} ,
"CollabAgentStatus" : {
"enum" : [
"pendingInit" ,
"running" ,
2026-03-16 16:39:40 +00:00
"interrupted" ,
2026-02-20 21:36:12 -08:00
"completed" ,
"errored" ,
"shutdown" ,
"notFound"
] ,
"type" : "string"
} ,
"CollabAgentTool" : {
"enum" : [
"spawnAgent" ,
"sendInput" ,
"resumeAgent" ,
"wait" ,
"closeAgent"
] ,
"type" : "string"
} ,
"CollabAgentToolCallStatus" : {
"enum" : [
"inProgress" ,
"completed" ,
"failed"
] ,
"type" : "string"
} ,
"CommandAction" : {
2026-02-01 23:38:43 -08:00
"oneOf" : [
{
2026-02-20 21:36:12 -08:00
"properties" : {
"command" : {
"type" : "string"
} ,
"name" : {
"type" : "string"
} ,
"path" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"read"
] ,
"title" : "ReadCommandActionType" ,
"type" : "string"
}
} ,
"required" : [
"command" ,
"name" ,
"path" ,
"type"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ReadCommandAction" ,
"type" : "object"
2026-02-01 23:38:43 -08:00
} ,
{
"properties" : {
2026-02-20 21:36:12 -08:00
"command" : {
"type" : "string"
} ,
"path" : {
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"listFiles"
] ,
"title" : "ListFilesCommandActionType" ,
"type" : "string"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"command" ,
"type"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ListFilesCommandAction" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"command" : {
"type" : "string"
} ,
"path" : {
"type" : [
"string" ,
"null"
]
} ,
"query" : {
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"search"
] ,
"title" : "SearchCommandActionType" ,
"type" : "string"
}
} ,
"required" : [
"command" ,
"type"
] ,
"title" : "SearchCommandAction" ,
"type" : "object"
} ,
{
"properties" : {
"command" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"unknown"
] ,
"title" : "UnknownCommandActionType" ,
"type" : "string"
}
} ,
"required" : [
"command" ,
"type"
] ,
"title" : "UnknownCommandAction" ,
"type" : "object"
}
]
} ,
2026-03-06 17:30:17 -08:00
"CommandExecOutputDeltaNotification" : {
"description" : "Base64-encoded output chunk emitted for a streaming `command/exec` request.\n\nThese notifications are connection-scoped. If the originating connection closes, the server terminates the process." ,
"properties" : {
"capReached" : {
"description" : "`true` on the final streamed chunk for a stream when `outputBytesCap` truncated later output on that stream." ,
"type" : "boolean"
} ,
"deltaBase64" : {
"description" : "Base64-encoded output bytes." ,
"type" : "string"
} ,
"processId" : {
"description" : "Client-supplied, connection-scoped `processId` from the original `command/exec` request." ,
"type" : "string"
} ,
"stream" : {
"allOf" : [
{
"$ref" : "#/definitions/CommandExecOutputStream"
}
] ,
"description" : "Output stream for this chunk."
}
} ,
"required" : [
"capReached" ,
"deltaBase64" ,
"processId" ,
"stream"
] ,
"type" : "object"
} ,
"CommandExecOutputStream" : {
"description" : "Stream label for `command/exec/outputDelta` notifications." ,
"oneOf" : [
{
"description" : "stdout stream. PTY mode multiplexes terminal output here." ,
"enum" : [
"stdout"
] ,
"type" : "string"
} ,
{
"description" : "stderr stream." ,
"enum" : [
"stderr"
] ,
"type" : "string"
}
]
} ,
2026-02-01 23:38:43 -08:00
"CommandExecutionOutputDeltaNotification" : {
"properties" : {
"delta" : {
"type" : "string"
} ,
"itemId" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"delta" ,
"itemId" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
2026-03-18 23:42:40 -06:00
"CommandExecutionSource" : {
"enum" : [
"agent" ,
"userShell" ,
"unifiedExecStartup" ,
"unifiedExecInteraction"
] ,
"type" : "string"
} ,
2026-02-01 23:38:43 -08:00
"CommandExecutionStatus" : {
"enum" : [
"inProgress" ,
"completed" ,
"failed" ,
"declined"
] ,
"type" : "string"
} ,
"ConfigWarningNotification" : {
"properties" : {
"details" : {
"description" : "Optional extra guidance or error details." ,
"type" : [
"string" ,
"null"
]
} ,
"path" : {
"description" : "Optional path to the config file that triggered the warning." ,
"type" : [
"string" ,
"null"
]
} ,
"range" : {
"anyOf" : [
{
"$ref" : "#/definitions/TextRange"
} ,
{
"type" : "null"
}
] ,
"description" : "Optional range for the error location inside the config file."
} ,
"summary" : {
"description" : "Concise summary of the warning." ,
"type" : "string"
}
} ,
"required" : [
"summary"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"ContextCompactedNotification" : {
"description" : "Deprecated: Use `ContextCompaction` item type instead." ,
"properties" : {
"threadId" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"CreditsSnapshot" : {
"properties" : {
"balance" : {
"type" : [
"string" ,
"null"
]
} ,
"hasCredits" : {
"type" : "boolean"
} ,
"unlimited" : {
"type" : "boolean"
}
} ,
"required" : [
"hasCredits" ,
"unlimited"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"DeprecationNoticeNotification" : {
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"details" : {
"description" : "Optional extra guidance, such as migration steps or rationale." ,
2026-02-01 23:38:43 -08:00
"type" : [
"string" ,
"null"
]
} ,
2026-02-20 21:36:12 -08:00
"summary" : {
"description" : "Concise summary of what is deprecated." ,
"type" : "string"
}
} ,
"required" : [
"summary"
] ,
"type" : "object"
} ,
2026-02-25 12:00:10 -08:00
"DynamicToolCallOutputContentItem" : {
"oneOf" : [
{
"properties" : {
"text" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"inputText"
] ,
"title" : "InputTextDynamicToolCallOutputContentItemType" ,
"type" : "string"
}
} ,
"required" : [
"text" ,
"type"
] ,
"title" : "InputTextDynamicToolCallOutputContentItem" ,
"type" : "object"
} ,
{
"properties" : {
"imageUrl" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"inputImage"
] ,
"title" : "InputImageDynamicToolCallOutputContentItemType" ,
"type" : "string"
}
} ,
"required" : [
"imageUrl" ,
"type"
] ,
"title" : "InputImageDynamicToolCallOutputContentItem" ,
"type" : "object"
}
]
} ,
"DynamicToolCallStatus" : {
"enum" : [
"inProgress" ,
"completed" ,
"failed"
] ,
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"ErrorNotification" : {
"properties" : {
"error" : {
"$ref" : "#/definitions/TurnError"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
} ,
"willRetry" : {
2026-02-01 23:38:43 -08:00
"type" : "boolean"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"error" ,
"threadId" ,
"turnId" ,
"willRetry"
] ,
"type" : "object"
} ,
"FileChangeOutputDeltaNotification" : {
"properties" : {
"delta" : {
"type" : "string"
} ,
"itemId" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"delta" ,
"itemId" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"FileUpdateChange" : {
"properties" : {
"diff" : {
"type" : "string"
} ,
"kind" : {
"$ref" : "#/definitions/PatchChangeKind"
} ,
"path" : {
"type" : "string"
}
} ,
"required" : [
"diff" ,
"kind" ,
"path"
2026-02-01 23:38:43 -08:00
] ,
"type" : "object"
} ,
2026-03-18 22:24:09 -07:00
"FuzzyFileSearchMatchType" : {
"enum" : [
"file" ,
"directory"
] ,
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"FuzzyFileSearchResult" : {
"description" : "Superset of [`codex_file_search::FileMatch`]" ,
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"file_name" : {
"type" : "string"
} ,
"indices" : {
"items" : {
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
2026-02-01 23:38:43 -08:00
"type" : [
2026-02-20 21:36:12 -08:00
"array" ,
2026-02-01 23:38:43 -08:00
"null"
]
} ,
2026-03-18 22:24:09 -07:00
"match_type" : {
"$ref" : "#/definitions/FuzzyFileSearchMatchType"
} ,
2026-02-20 21:36:12 -08:00
"path" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"root" : {
"type" : "string"
} ,
"score" : {
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : "integer"
}
} ,
"required" : [
"file_name" ,
2026-03-18 22:24:09 -07:00
"match_type" ,
2026-02-20 21:36:12 -08:00
"path" ,
"root" ,
"score"
] ,
"type" : "object"
} ,
"FuzzyFileSearchSessionCompletedNotification" : {
"properties" : {
"sessionId" : {
"type" : "string"
}
} ,
"required" : [
"sessionId"
] ,
"type" : "object"
} ,
"FuzzyFileSearchSessionUpdatedNotification" : {
"properties" : {
"files" : {
"items" : {
"$ref" : "#/definitions/FuzzyFileSearchResult"
} ,
"type" : "array"
} ,
"query" : {
"type" : "string"
} ,
"sessionId" : {
"type" : "string"
}
} ,
"required" : [
"files" ,
"query" ,
"sessionId"
] ,
"type" : "object"
} ,
"GitInfo" : {
"properties" : {
"branch" : {
2026-02-01 23:38:43 -08:00
"type" : [
"string" ,
"null"
]
} ,
2026-02-20 21:36:12 -08:00
"originUrl" : {
"type" : [
"string" ,
"null"
]
} ,
"sha" : {
"type" : [
"string" ,
"null"
]
}
} ,
"type" : "object"
} ,
Add Smart Approvals guardian review across core, app-server, and TUI (#13860)
## Summary
- add `approvals_reviewer = "user" | "guardian_subagent"` as the runtime
control for who reviews approval requests
- route Smart Approvals guardian review through core for command
execution, file changes, managed-network approvals, MCP approvals, and
delegated/subagent approval flows
- expose guardian review in app-server with temporary unstable
`item/autoApprovalReview/{started,completed}` notifications carrying
`targetItemId`, `review`, and `action`
- update the TUI so Smart Approvals can be enabled from `/experimental`,
aligned with the matching `/approvals` mode, and surfaced clearly while
reviews are pending or resolved
## Runtime model
This PR does not introduce a new `approval_policy`.
Instead:
- `approval_policy` still controls when approval is needed
- `approvals_reviewer` controls who reviewable approval requests are
routed to:
- `user`
- `guardian_subagent`
`guardian_subagent` is a carefully prompted reviewer subagent that
gathers relevant context and applies a risk-based decision framework
before approving or denying the request.
The `smart_approvals` feature flag is a rollout/UI gate. Core runtime
behavior keys off `approvals_reviewer`.
When Smart Approvals is enabled from the TUI, it also switches the
current `/approvals` settings to the matching Smart Approvals mode so
users immediately see guardian review in the active thread:
- `approval_policy = on-request`
- `approvals_reviewer = guardian_subagent`
- `sandbox_mode = workspace-write`
Users can still change `/approvals` afterward.
Config-load behavior stays intentionally narrow:
- plain `smart_approvals = true` in `config.toml` remains just the
rollout/UI gate and does not auto-set `approvals_reviewer`
- the deprecated `guardian_approval = true` alias migration does
backfill `approvals_reviewer = "guardian_subagent"` in the same scope
when that reviewer is not already configured there, so old configs
preserve their original guardian-enabled behavior
ARC remains a separate safety check. For MCP tool approvals, ARC
escalations now flow into the configured reviewer instead of always
bypassing guardian and forcing manual review.
## Config stability
The runtime reviewer override is stable, but the config-backed
app-server protocol shape is still settling.
- `thread/start`, `thread/resume`, and `turn/start` keep stable
`approvalsReviewer` overrides
- the config-backed `approvals_reviewer` exposure returned via
`config/read` (including profile-level config) is now marked
`[UNSTABLE]` / experimental in the app-server protocol until we are more
confident in that config surface
## App-server surface
This PR intentionally keeps the guardian app-server shape narrow and
temporary.
It adds generic unstable lifecycle notifications:
- `item/autoApprovalReview/started`
- `item/autoApprovalReview/completed`
with payloads of the form:
- `{ threadId, turnId, targetItemId, review, action? }`
`review` is currently:
- `{ status, riskScore?, riskLevel?, rationale? }`
- where `status` is one of `inProgress`, `approved`, `denied`, or
`aborted`
`action` carries the guardian action summary payload from core when
available. This lets clients render temporary standalone pending-review
UI, including parallel reviews, even when the underlying tool item has
not been emitted yet.
These notifications are explicitly documented as `[UNSTABLE]` and
expected to change soon.
This PR does **not** persist guardian review state onto `thread/read`
tool items. The intended follow-up is to attach guardian review state to
the reviewed tool item lifecycle instead, which would improve
consistency with manual approvals and allow thread history / reconnect
flows to replay guardian review state directly.
## TUI behavior
- `/experimental` exposes the rollout gate as `Smart Approvals`
- enabling it in the TUI enables the feature and switches the current
session to the matching Smart Approvals `/approvals` mode
- disabling it in the TUI clears the persisted `approvals_reviewer`
override when appropriate and returns the session to default manual
review when the effective reviewer changes
- `/approvals` still exposes the reviewer choice directly
- the TUI renders:
- pending guardian review state in the live status footer, including
parallel review aggregation
- resolved approval/denial state in history
## Scope notes
This PR includes the supporting core/runtime work needed to make Smart
Approvals usable end-to-end:
- shell / unified-exec / apply_patch / managed-network / MCP guardian
review
- delegated/subagent approval routing into guardian review
- guardian review risk metadata and action summaries for app-server/TUI
- config/profile/TUI handling for `smart_approvals`, `guardian_approval`
alias migration, and `approvals_reviewer`
- a small internal cleanup of delegated approval forwarding to dedupe
fallback paths and simplify guardian-vs-parent approval waiting (no
intended behavior change)
Out of scope for this PR:
- redesigning the existing manual approval protocol shapes
- persisting guardian review state onto app-server `ThreadItem`s
- delegated MCP elicitation auto-review (the current delegated MCP
guardian shim only covers the legacy `RequestUserInput` path)
---------
Co-authored-by: Codex <noreply@openai.com>
2026-03-13 15:27:00 -07:00
"GuardianApprovalReview" : {
"description" : "[UNSTABLE] Temporary guardian approval review payload used by `item/autoApprovalReview/*` notifications. This shape is expected to change soon." ,
"properties" : {
"rationale" : {
"type" : [
"string" ,
"null"
]
} ,
"riskLevel" : {
"anyOf" : [
{
"$ref" : "#/definitions/GuardianRiskLevel"
} ,
{
"type" : "null"
}
]
} ,
"riskScore" : {
"format" : "uint8" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
} ,
"status" : {
"$ref" : "#/definitions/GuardianApprovalReviewStatus"
}
} ,
"required" : [
"status"
] ,
"type" : "object"
} ,
"GuardianApprovalReviewStatus" : {
"description" : "[UNSTABLE] Lifecycle state for a guardian approval review." ,
"enum" : [
"inProgress" ,
"approved" ,
"denied" ,
"aborted"
] ,
"type" : "string"
} ,
"GuardianRiskLevel" : {
"description" : "[UNSTABLE] Risk level assigned by guardian approval review." ,
"enum" : [
"low" ,
"medium" ,
"high"
] ,
"type" : "string"
} ,
2026-03-09 21:11:31 -07:00
"HookCompletedNotification" : {
"properties" : {
"run" : {
"$ref" : "#/definitions/HookRunSummary"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"run" ,
"threadId"
] ,
"type" : "object"
} ,
"HookEventName" : {
"enum" : [
"sessionStart" ,
[hooks] userpromptsubmit - hook before user's prompt is executed (#14626)
- this allows blocking the user's prompts from executing, and also
prevents them from entering history
- handles the edge case where you can both prevent the user's prompt AND
add n amount of additionalContexts
- refactors some old code into common.rs where hooks overlap
functionality
- refactors additionalContext being previously added to user messages,
instead we use developer messages for them
- handles queued messages correctly
Sample hook for testing - if you write "[block-user-submit]" this hook
will stop the thread:
example run
```
› sup
• Running UserPromptSubmit hook: reading the observatory notes
UserPromptSubmit hook (completed)
warning: wizard-tower UserPromptSubmit demo inspected: sup
hook context: Wizard Tower UserPromptSubmit demo fired. For this reply only, include the exact
phrase 'observatory lanterns lit' exactly once near the end.
• Just riding the cosmic wave and ready to help, my friend. What are we building today? observatory
lanterns lit
› and [block-user-submit]
• Running UserPromptSubmit hook: reading the observatory notes
UserPromptSubmit hook (stopped)
warning: wizard-tower UserPromptSubmit demo blocked the prompt on purpose.
stop: Wizard Tower demo block: remove [block-user-submit] to continue.
```
.codex/config.toml
```
[features]
codex_hooks = true
```
.codex/hooks.json
```
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "/usr/bin/python3 .codex/hooks/user_prompt_submit_demo.py",
"timeoutSec": 10,
"statusMessage": "reading the observatory notes"
}
]
}
]
}
}
```
.codex/hooks/user_prompt_submit_demo.py
```
#!/usr/bin/env python3
import json
import sys
from pathlib import Path
def prompt_from_payload(payload: dict) -> str:
prompt = payload.get("prompt")
if isinstance(prompt, str) and prompt.strip():
return prompt.strip()
event = payload.get("event")
if isinstance(event, dict):
user_prompt = event.get("user_prompt")
if isinstance(user_prompt, str):
return user_prompt.strip()
return ""
def main() -> int:
payload = json.load(sys.stdin)
prompt = prompt_from_payload(payload)
cwd = Path(payload.get("cwd", ".")).name or "wizard-tower"
if "[block-user-submit]" in prompt:
print(
json.dumps(
{
"systemMessage": (
f"{cwd} UserPromptSubmit demo blocked the prompt on purpose."
),
"decision": "block",
"reason": (
"Wizard Tower demo block: remove [block-user-submit] to continue."
),
}
)
)
return 0
prompt_preview = prompt or "(empty prompt)"
if len(prompt_preview) > 80:
prompt_preview = f"{prompt_preview[:77]}..."
print(
json.dumps(
{
"systemMessage": (
f"{cwd} UserPromptSubmit demo inspected: {prompt_preview}"
),
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": (
"Wizard Tower UserPromptSubmit demo fired. "
"For this reply only, include the exact phrase "
"'observatory lanterns lit' exactly once near the end."
),
},
}
)
)
return 0
if __name__ == "__main__":
raise SystemExit(main())
```
2026-03-17 22:09:22 -07:00
"userPromptSubmit" ,
2026-03-09 21:11:31 -07:00
"stop"
] ,
"type" : "string"
} ,
"HookExecutionMode" : {
"enum" : [
"sync" ,
"async"
] ,
"type" : "string"
} ,
"HookHandlerType" : {
"enum" : [
"command" ,
"prompt" ,
"agent"
] ,
"type" : "string"
} ,
"HookOutputEntry" : {
"properties" : {
"kind" : {
"$ref" : "#/definitions/HookOutputEntryKind"
} ,
"text" : {
"type" : "string"
}
} ,
"required" : [
"kind" ,
"text"
] ,
"type" : "object"
} ,
"HookOutputEntryKind" : {
"enum" : [
"warning" ,
"stop" ,
"feedback" ,
"context" ,
"error"
] ,
"type" : "string"
} ,
[hooks] use a user message > developer message for prompt continuation (#14867)
## Summary
Persist Stop-hook continuation prompts as `user` messages instead of
hidden `developer` messages + some requested integration tests
This is a followup to @pakrym 's comment in
https://github.com/openai/codex/pull/14532 to make sure stop-block
continuation prompts match training for turn loops
- Stop continuation now writes `<hook_prompt hook_run_id="...">stop
hook's user prompt<hook_prompt>`
- Introduces quick-xml dependency, though we already indirectly depended
on it anyway via syntect
- This PR only has about 500 lines of actual logic changes, the rest is
tests/schema
## Testing
Example run (with a sessionstart hook and 3 stop hooks) - this shows
context added by session start, then two stop hooks sending their own
additional prompts in a new turn. The model responds with a single
message addressing both. Then when that turn ends, the hooks detect that
they just ran using `stop_hook_active` and decide not to infinite loop
test files for this (unzip, move codex -> .codex):
[codex.zip](https://github.com/user-attachments/files/26075806/codex.zip)
```
› cats
• Running SessionStart hook: lighting the observatory
SessionStart hook (completed)
warning: Hi, I'm a session start hook for wizard-tower (startup).
hook context: A wimboltine stonpet is an exotic cuisine from hyperspace
• Cats are tiny zen wizards, my friend: equal parts nap, mystery, and chaos. If you want, we can talk
cat facts, cat breeds, cat names, or build something cat-themed in this repo.
• Running Stop hook: checking the tower wards
• Running Stop hook: sacking the guards
• Running Stop hook: hiring the guards
Stop hook (completed)
warning: Wizard Tower Stop hook reviewed the completed reply (177 chars).
Stop hook (blocked)
warning: Wizard Tower Stop hook continuing conversation
feedback: cook the stonpet
Stop hook (blocked)
warning: Wizard Tower Stop hook continuing conversation
feedback: eat the cooked stonpet
• Stonpet’s cooked, aloha style: flash-seared over a blue quasiflame, glazed with nebula salt, and
rested until the hyperspace juices settle.
Now we eat with gratitude, my friend. One mindful bite in, and the flavor is pure cosmic surf:
smoky, bright, and totally out of this dimension.
• Running Stop hook: checking the tower wards
• Running Stop hook: sacking the guards
• Running Stop hook: hiring the guards
Stop hook (completed)
warning: Wizard Tower Stop hook reviewed the completed reply (285 chars).
Stop hook (completed)
warning: Wizard Tower Stop hook saw a second pass and stayed calm to avoid a loop.
Stop hook (completed)
warning: Wizard Tower Stop hook saw a second pass and stayed calm to avoid a loop.
```
2026-03-19 10:53:08 -07:00
"HookPromptFragment" : {
"properties" : {
"hookRunId" : {
"type" : "string"
} ,
"text" : {
"type" : "string"
}
} ,
"required" : [
"hookRunId" ,
"text"
] ,
"type" : "object"
} ,
2026-03-09 21:11:31 -07:00
"HookRunStatus" : {
"enum" : [
"running" ,
"completed" ,
"failed" ,
"blocked" ,
"stopped"
] ,
"type" : "string"
} ,
"HookRunSummary" : {
"properties" : {
"completedAt" : {
"format" : "int64" ,
"type" : [
"integer" ,
"null"
]
} ,
"displayOrder" : {
"format" : "int64" ,
"type" : "integer"
} ,
"durationMs" : {
"format" : "int64" ,
"type" : [
"integer" ,
"null"
]
} ,
"entries" : {
"items" : {
"$ref" : "#/definitions/HookOutputEntry"
} ,
"type" : "array"
} ,
"eventName" : {
"$ref" : "#/definitions/HookEventName"
} ,
"executionMode" : {
"$ref" : "#/definitions/HookExecutionMode"
} ,
"handlerType" : {
"$ref" : "#/definitions/HookHandlerType"
} ,
"id" : {
"type" : "string"
} ,
"scope" : {
"$ref" : "#/definitions/HookScope"
} ,
"sourcePath" : {
"type" : "string"
} ,
"startedAt" : {
"format" : "int64" ,
"type" : "integer"
} ,
"status" : {
"$ref" : "#/definitions/HookRunStatus"
} ,
"statusMessage" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"displayOrder" ,
"entries" ,
"eventName" ,
"executionMode" ,
"handlerType" ,
"id" ,
"scope" ,
"sourcePath" ,
"startedAt" ,
"status"
] ,
"type" : "object"
} ,
"HookScope" : {
"enum" : [
"thread" ,
"turn"
] ,
"type" : "string"
} ,
"HookStartedNotification" : {
"properties" : {
"run" : {
"$ref" : "#/definitions/HookRunSummary"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"run" ,
"threadId"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"ItemCompletedNotification" : {
"properties" : {
"item" : {
"$ref" : "#/definitions/ThreadItem"
} ,
"threadId" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"turnId" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"item" ,
"threadId" ,
"turnId"
2026-02-01 23:38:43 -08:00
] ,
"type" : "object"
} ,
Add Smart Approvals guardian review across core, app-server, and TUI (#13860)
## Summary
- add `approvals_reviewer = "user" | "guardian_subagent"` as the runtime
control for who reviews approval requests
- route Smart Approvals guardian review through core for command
execution, file changes, managed-network approvals, MCP approvals, and
delegated/subagent approval flows
- expose guardian review in app-server with temporary unstable
`item/autoApprovalReview/{started,completed}` notifications carrying
`targetItemId`, `review`, and `action`
- update the TUI so Smart Approvals can be enabled from `/experimental`,
aligned with the matching `/approvals` mode, and surfaced clearly while
reviews are pending or resolved
## Runtime model
This PR does not introduce a new `approval_policy`.
Instead:
- `approval_policy` still controls when approval is needed
- `approvals_reviewer` controls who reviewable approval requests are
routed to:
- `user`
- `guardian_subagent`
`guardian_subagent` is a carefully prompted reviewer subagent that
gathers relevant context and applies a risk-based decision framework
before approving or denying the request.
The `smart_approvals` feature flag is a rollout/UI gate. Core runtime
behavior keys off `approvals_reviewer`.
When Smart Approvals is enabled from the TUI, it also switches the
current `/approvals` settings to the matching Smart Approvals mode so
users immediately see guardian review in the active thread:
- `approval_policy = on-request`
- `approvals_reviewer = guardian_subagent`
- `sandbox_mode = workspace-write`
Users can still change `/approvals` afterward.
Config-load behavior stays intentionally narrow:
- plain `smart_approvals = true` in `config.toml` remains just the
rollout/UI gate and does not auto-set `approvals_reviewer`
- the deprecated `guardian_approval = true` alias migration does
backfill `approvals_reviewer = "guardian_subagent"` in the same scope
when that reviewer is not already configured there, so old configs
preserve their original guardian-enabled behavior
ARC remains a separate safety check. For MCP tool approvals, ARC
escalations now flow into the configured reviewer instead of always
bypassing guardian and forcing manual review.
## Config stability
The runtime reviewer override is stable, but the config-backed
app-server protocol shape is still settling.
- `thread/start`, `thread/resume`, and `turn/start` keep stable
`approvalsReviewer` overrides
- the config-backed `approvals_reviewer` exposure returned via
`config/read` (including profile-level config) is now marked
`[UNSTABLE]` / experimental in the app-server protocol until we are more
confident in that config surface
## App-server surface
This PR intentionally keeps the guardian app-server shape narrow and
temporary.
It adds generic unstable lifecycle notifications:
- `item/autoApprovalReview/started`
- `item/autoApprovalReview/completed`
with payloads of the form:
- `{ threadId, turnId, targetItemId, review, action? }`
`review` is currently:
- `{ status, riskScore?, riskLevel?, rationale? }`
- where `status` is one of `inProgress`, `approved`, `denied`, or
`aborted`
`action` carries the guardian action summary payload from core when
available. This lets clients render temporary standalone pending-review
UI, including parallel reviews, even when the underlying tool item has
not been emitted yet.
These notifications are explicitly documented as `[UNSTABLE]` and
expected to change soon.
This PR does **not** persist guardian review state onto `thread/read`
tool items. The intended follow-up is to attach guardian review state to
the reviewed tool item lifecycle instead, which would improve
consistency with manual approvals and allow thread history / reconnect
flows to replay guardian review state directly.
## TUI behavior
- `/experimental` exposes the rollout gate as `Smart Approvals`
- enabling it in the TUI enables the feature and switches the current
session to the matching Smart Approvals `/approvals` mode
- disabling it in the TUI clears the persisted `approvals_reviewer`
override when appropriate and returns the session to default manual
review when the effective reviewer changes
- `/approvals` still exposes the reviewer choice directly
- the TUI renders:
- pending guardian review state in the live status footer, including
parallel review aggregation
- resolved approval/denial state in history
## Scope notes
This PR includes the supporting core/runtime work needed to make Smart
Approvals usable end-to-end:
- shell / unified-exec / apply_patch / managed-network / MCP guardian
review
- delegated/subagent approval routing into guardian review
- guardian review risk metadata and action summaries for app-server/TUI
- config/profile/TUI handling for `smart_approvals`, `guardian_approval`
alias migration, and `approvals_reviewer`
- a small internal cleanup of delegated approval forwarding to dedupe
fallback paths and simplify guardian-vs-parent approval waiting (no
intended behavior change)
Out of scope for this PR:
- redesigning the existing manual approval protocol shapes
- persisting guardian review state onto app-server `ThreadItem`s
- delegated MCP elicitation auto-review (the current delegated MCP
guardian shim only covers the legacy `RequestUserInput` path)
---------
Co-authored-by: Codex <noreply@openai.com>
2026-03-13 15:27:00 -07:00
"ItemGuardianApprovalReviewCompletedNotification" : {
"description" : "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`." ,
"properties" : {
"action" : true ,
"review" : {
"$ref" : "#/definitions/GuardianApprovalReview"
} ,
"targetItemId" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"review" ,
"targetItemId" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"ItemGuardianApprovalReviewStartedNotification" : {
"description" : "[UNSTABLE] Temporary notification payload for guardian automatic approval review. This shape is expected to change soon.\n\nTODO(ccunningham): Attach guardian review state to the reviewed tool item's lifecycle instead of sending separate standalone review notifications so the app-server API can persist and replay review state via `thread/read`." ,
"properties" : {
"action" : true ,
"review" : {
"$ref" : "#/definitions/GuardianApprovalReview"
} ,
"targetItemId" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"review" ,
"targetItemId" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"ItemStartedNotification" : {
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"item" : {
"$ref" : "#/definitions/ThreadItem"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"item" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"McpServerOauthLoginCompletedNotification" : {
"properties" : {
"error" : {
2026-02-01 23:38:43 -08:00
"type" : [
"string" ,
"null"
]
} ,
2026-02-20 21:36:12 -08:00
"name" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
2026-02-20 21:36:12 -08:00
} ,
"success" : {
"type" : "boolean"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"name" ,
"success"
2026-02-01 23:38:43 -08:00
] ,
"type" : "object"
} ,
feat(app-server): add mcpServer/startupStatus/updated notification (#15220)
Exposes the legacy `codex/event/mcp_startup_update` event as an API v2
notification.
The legacy event has this shape:
```
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
pub struct McpStartupUpdateEvent {
/// Server name being started.
pub server: String,
/// Current startup status.
pub status: McpStartupStatus,
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
#[serde(rename_all = "snake_case", tag = "state")]
#[ts(rename_all = "snake_case", tag = "state")]
pub enum McpStartupStatus {
Starting,
Ready,
Failed { error: String },
Cancelled,
}
```
2026-03-19 15:09:59 -07:00
"McpServerStartupState" : {
"enum" : [
"starting" ,
"ready" ,
"failed" ,
"cancelled"
] ,
"type" : "string"
} ,
"McpServerStatusUpdatedNotification" : {
"properties" : {
"error" : {
"type" : [
"string" ,
"null"
]
} ,
"name" : {
"type" : "string"
} ,
"status" : {
"$ref" : "#/definitions/McpServerStartupState"
}
} ,
"required" : [
"name" ,
"status"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"McpToolCallError" : {
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"message" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"message"
2026-02-01 23:38:43 -08:00
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"McpToolCallProgressNotification" : {
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"itemId" : {
"type" : "string"
} ,
"message" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"itemId" ,
"message" ,
2026-02-01 23:38:43 -08:00
"threadId" ,
2026-02-20 21:36:12 -08:00
"turnId"
2026-02-01 23:38:43 -08:00
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"McpToolCallResult" : {
"properties" : {
"content" : {
"items" : true ,
"type" : "array"
} ,
"structuredContent" : true
} ,
"required" : [
"content"
] ,
"type" : "object"
} ,
"McpToolCallStatus" : {
"enum" : [
"inProgress" ,
"completed" ,
"failed"
] ,
"type" : "string"
} ,
2026-03-18 10:03:38 +00:00
"MemoryCitation" : {
"properties" : {
"entries" : {
"items" : {
"$ref" : "#/definitions/MemoryCitationEntry"
} ,
"type" : "array"
} ,
"threadIds" : {
"items" : {
"type" : "string"
} ,
"type" : "array"
}
} ,
"required" : [
"entries" ,
"threadIds"
] ,
"type" : "object"
} ,
"MemoryCitationEntry" : {
"properties" : {
"lineEnd" : {
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"lineStart" : {
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"note" : {
"type" : "string"
} ,
"path" : {
"type" : "string"
}
} ,
"required" : [
"lineEnd" ,
"lineStart" ,
"note" ,
"path"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"MessagePhase" : {
"description" : "Classifies an assistant message as interim commentary or final answer text.\n\nProviders do not emit this consistently, so callers must treat `None` as \"phase unknown\" and keep compatibility behavior for legacy models." ,
"oneOf" : [
{
"description" : "Mid-turn assistant text (for example preamble/progress narration).\n\nAdditional tool calls or assistant output may follow before turn completion." ,
"enum" : [
"commentary"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
{
2026-02-20 21:36:12 -08:00
"description" : "The assistant's terminal answer text for the current turn." ,
"enum" : [
"final_answer"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"type" : "string"
}
]
} ,
"ModelRerouteReason" : {
"enum" : [
"highRiskCyberActivity"
] ,
"type" : "string"
} ,
"ModelReroutedNotification" : {
"properties" : {
"fromModel" : {
"type" : "string"
} ,
"reason" : {
"$ref" : "#/definitions/ModelRerouteReason"
} ,
"threadId" : {
"type" : "string"
} ,
"toModel" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"fromModel" ,
"reason" ,
"threadId" ,
"toModel" ,
"turnId"
] ,
"type" : "object"
} ,
"PatchApplyStatus" : {
"enum" : [
"inProgress" ,
"completed" ,
"failed" ,
"declined"
] ,
"type" : "string"
} ,
"PatchChangeKind" : {
"oneOf" : [
2026-02-20 19:06:35 -08:00
{
"properties" : {
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"add"
2026-02-20 19:06:35 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "AddPatchChangeKindType" ,
2026-02-20 19:06:35 -08:00
"type" : "string"
}
} ,
"required" : [
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "AddPatchChangeKind" ,
2026-02-20 19:06:35 -08:00
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"delete"
2026-02-20 19:06:35 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "DeletePatchChangeKindType" ,
2026-02-20 19:06:35 -08:00
"type" : "string"
}
} ,
"required" : [
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "DeletePatchChangeKind" ,
2026-02-20 19:06:35 -08:00
"type" : "object"
} ,
{
"properties" : {
2026-02-20 21:36:12 -08:00
"move_path" : {
2026-02-20 19:06:35 -08:00
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"update"
2026-02-20 19:06:35 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "UpdatePatchChangeKindType" ,
2026-02-20 19:06:35 -08:00
"type" : "string"
}
} ,
"required" : [
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "UpdatePatchChangeKind" ,
2026-02-20 19:06:35 -08:00
"type" : "object"
2026-02-20 21:36:12 -08:00
}
]
} ,
"PlanDeltaNotification" : {
"description" : "EXPERIMENTAL - proposed plan streaming deltas for plan items. Clients should not assume concatenated deltas match the completed plan item content." ,
"properties" : {
"delta" : {
"type" : "string"
2026-02-20 19:06:35 -08:00
} ,
2026-02-20 21:36:12 -08:00
"itemId" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"delta" ,
"itemId" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"PlanType" : {
"enum" : [
"free" ,
"go" ,
"plus" ,
"pro" ,
"team" ,
"business" ,
"enterprise" ,
"edu" ,
"unknown"
] ,
"type" : "string"
} ,
"RateLimitSnapshot" : {
"properties" : {
"credits" : {
"anyOf" : [
{
"$ref" : "#/definitions/CreditsSnapshot"
2026-02-17 11:02:23 -08:00
} ,
2026-02-20 21:36:12 -08:00
{
"type" : "null"
2026-02-17 11:02:23 -08:00
}
2026-02-20 21:36:12 -08:00
]
2026-02-17 11:02:23 -08:00
} ,
2026-02-20 21:36:12 -08:00
"limitId" : {
"type" : [
"string" ,
"null"
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"limitName" : {
"type" : [
"string" ,
"null"
]
} ,
"planType" : {
"anyOf" : [
{
"$ref" : "#/definitions/PlanType"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
{
"type" : "null"
2026-02-01 23:38:43 -08:00
}
2026-02-20 21:36:12 -08:00
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"primary" : {
"anyOf" : [
{
"$ref" : "#/definitions/RateLimitWindow"
chore: persist turn_id in rollout session and make turn_id uuid based (#11246)
Problem:
1. turn id is constructed in-memory;
2. on resuming threads, turn_id might not be unique;
3. client cannot no the boundary of a turn from rollout files easily.
This PR does three things:
1. persist `task_started` and `task_complete` events;
1. persist `turn_id` in rollout turn events;
5. generate turn_id as unique uuids instead of incrementing it in
memory.
This helps us resolve the issue of clients wanting to have unique turn
ids for resuming a thread, and knowing the boundry of each turn in
rollout files.
example debug logs
```
2026-02-11T00:32:10.746876Z DEBUG codex_app_server_protocol::protocol::thread_history: built turn from rollout items turn_index=8 turn=Turn { id: "019c4a07-d809-74c3-bc4b-fd9618487b4b", items: [UserMessage { id: "item-24", content: [Text { text: "hi", text_elements: [] }] }, AgentMessage { id: "item-25", text: "Hi. I’m in the workspace with your current changes loaded and ready. Send the next task and I’ll execute it end-to-end." }], status: Completed, error: None }
2026-02-11T00:32:10.746888Z DEBUG codex_app_server_protocol::protocol::thread_history: built turn from rollout items turn_index=9 turn=Turn { id: "019c4a18-1004-76c0-a0fb-a77610f6a9b8", items: [UserMessage { id: "item-26", content: [Text { text: "hello", text_elements: [] }] }, AgentMessage { id: "item-27", text: "Hello. Ready for the next change in `codex-rs`; I can continue from the current in-progress diff or start a new task." }], status: Completed, error: None }
2026-02-11T00:32:10.746899Z DEBUG codex_app_server_protocol::protocol::thread_history: built turn from rollout items turn_index=10 turn=Turn { id: "019c4a19-41f0-7db0-ad78-74f1503baeb8", items: [UserMessage { id: "item-28", content: [Text { text: "hello", text_elements: [] }] }, AgentMessage { id: "item-29", text: "Hello. Send the specific change you want in `codex-rs`, and I’ll implement it and run the required checks." }], status: Completed, error: None }
```
backward compatibility:
if you try to resume an old session without task_started and
task_complete event populated, the following happens:
- If you resume and do nothing: those reconstructed historical IDs can
differ next time you resume.
- If you resume and send a new turn: the new turn gets a fresh UUID from
live submission flow and is persisted, so that new turn’s ID is stable
on later resumes.
I think this behavior is fine, because we only care about deterministic
turn id once a turn is triggered.
2026-02-10 19:56:01 -08:00
} ,
2026-02-20 21:36:12 -08:00
{
"type" : "null"
2026-02-01 23:38:43 -08:00
}
2026-02-20 21:36:12 -08:00
]
} ,
"secondary" : {
"anyOf" : [
{
"$ref" : "#/definitions/RateLimitWindow"
} ,
{
"type" : "null"
}
]
}
} ,
"type" : "object"
} ,
"RateLimitWindow" : {
"properties" : {
"resetsAt" : {
"format" : "int64" ,
"type" : [
"integer" ,
"null"
]
} ,
"usedPercent" : {
"format" : "int32" ,
"type" : "integer"
} ,
"windowDurationMins" : {
"format" : "int64" ,
"type" : [
"integer" ,
"null"
]
}
} ,
"required" : [
"usedPercent"
] ,
"type" : "object"
} ,
2026-03-17 15:24:37 -07:00
"RealtimeConversationVersion" : {
"enum" : [
"v1" ,
"v2"
] ,
"type" : "string"
} ,
2026-03-11 19:25:21 -07:00
"ReasoningEffort" : {
"description" : "See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#get-started-with-reasoning" ,
"enum" : [
"none" ,
"minimal" ,
"low" ,
"medium" ,
"high" ,
"xhigh"
] ,
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"ReasoningSummaryPartAddedNotification" : {
"properties" : {
"itemId" : {
"type" : "string"
} ,
"summaryIndex" : {
"format" : "int64" ,
"type" : "integer"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"itemId" ,
"summaryIndex" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"ReasoningSummaryTextDeltaNotification" : {
"properties" : {
"delta" : {
"type" : "string"
} ,
"itemId" : {
"type" : "string"
} ,
"summaryIndex" : {
"format" : "int64" ,
"type" : "integer"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"delta" ,
"itemId" ,
"summaryIndex" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"ReasoningTextDeltaNotification" : {
"properties" : {
"contentIndex" : {
"format" : "int64" ,
"type" : "integer"
} ,
"delta" : {
"type" : "string"
} ,
"itemId" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"contentIndex" ,
"delta" ,
"itemId" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
2026-02-27 12:45:59 -08:00
"RequestId" : {
"anyOf" : [
{
"type" : "string"
} ,
{
"format" : "int64" ,
"type" : "integer"
}
]
} ,
"ServerRequestResolvedNotification" : {
"properties" : {
"requestId" : {
"$ref" : "#/definitions/RequestId"
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"requestId" ,
"threadId"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"SessionSource" : {
"oneOf" : [
{
"enum" : [
"cli" ,
"vscode" ,
"exec" ,
"appServer" ,
"unknown"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
2026-03-19 00:46:15 -07:00
{
"additionalProperties" : false ,
"properties" : {
"custom" : {
"type" : "string"
}
} ,
"required" : [
"custom"
] ,
"title" : "CustomSessionSource" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
2026-02-20 21:36:12 -08:00
"additionalProperties" : false ,
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"subAgent" : {
"$ref" : "#/definitions/SubAgentSource"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"subAgent"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "SubAgentSessionSource" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
2026-02-20 21:36:12 -08:00
}
]
} ,
2026-03-03 17:01:00 -08:00
"SkillsChangedNotification" : {
"description" : "Notification emitted when watched local skill files change.\n\nTreat this as an invalidation signal and re-run `skills/list` with the client's current parameters when refreshed skill metadata is needed." ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"SubAgentSource" : {
"oneOf" : [
{
"enum" : [
"review" ,
"compact" ,
"memory_consolidation"
] ,
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
{
2026-02-20 21:36:12 -08:00
"additionalProperties" : false ,
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"thread_spawn" : {
"properties" : {
"agent_nickname" : {
"default" : null ,
"type" : [
"string" ,
"null"
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"agent_role" : {
"default" : null ,
"type" : [
"string" ,
"null"
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"depth" : {
"format" : "int32" ,
"type" : "integer"
} ,
"parent_thread_id" : {
"$ref" : "#/definitions/ThreadId"
2026-02-01 23:38:43 -08:00
}
2026-02-20 21:36:12 -08:00
} ,
"required" : [
"depth" ,
"parent_thread_id"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"type" : "object"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"thread_spawn"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ThreadSpawnSubAgentSource" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
2026-02-20 21:36:12 -08:00
"additionalProperties" : false ,
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"other" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"other"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "OtherSubAgentSource" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
2026-02-20 21:36:12 -08:00
}
]
} ,
"TerminalInteractionNotification" : {
"properties" : {
"itemId" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"processId" : {
"type" : "string"
} ,
"stdin" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"itemId" ,
"processId" ,
"stdin" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"TextElement" : {
"properties" : {
"byteRange" : {
"allOf" : [
{
"$ref" : "#/definitions/ByteRange"
}
] ,
"description" : "Byte range in the parent `text` buffer that this element occupies."
} ,
"placeholder" : {
"description" : "Optional human-readable placeholder for the element, displayed in the UI." ,
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"byteRange"
] ,
"type" : "object"
} ,
"TextPosition" : {
"properties" : {
"column" : {
"description" : "1-based column number (in Unicode scalar values)." ,
"format" : "uint" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"line" : {
"description" : "1-based line number." ,
"format" : "uint" ,
"minimum" : 0.0 ,
"type" : "integer"
}
} ,
"required" : [
"column" ,
"line"
] ,
"type" : "object"
} ,
"TextRange" : {
"properties" : {
"end" : {
"$ref" : "#/definitions/TextPosition"
} ,
"start" : {
"$ref" : "#/definitions/TextPosition"
}
} ,
"required" : [
"end" ,
"start"
] ,
"type" : "object"
} ,
"Thread" : {
"properties" : {
"agentNickname" : {
"description" : "Optional random unique nickname assigned to an AgentControl-spawned sub-agent." ,
"type" : [
"string" ,
"null"
]
} ,
"agentRole" : {
"description" : "Optional role (agent_role) assigned to an AgentControl-spawned sub-agent." ,
"type" : [
"string" ,
"null"
]
} ,
"cliVersion" : {
"description" : "Version of the CLI that created the thread." ,
"type" : "string"
} ,
"createdAt" : {
"description" : "Unix timestamp (in seconds) when the thread was created." ,
"format" : "int64" ,
"type" : "integer"
} ,
"cwd" : {
"description" : "Working directory captured for the thread." ,
"type" : "string"
} ,
2026-02-27 17:42:25 -08:00
"ephemeral" : {
"description" : "Whether the thread is ephemeral and should not be materialized on disk." ,
"type" : "boolean"
} ,
2026-02-20 21:36:12 -08:00
"gitInfo" : {
"anyOf" : [
{
"$ref" : "#/definitions/GitInfo"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
{
"type" : "null"
2026-02-01 23:38:43 -08:00
}
] ,
2026-02-20 21:36:12 -08:00
"description" : "Optional Git metadata captured when the thread was created."
} ,
"id" : {
"type" : "string"
} ,
"modelProvider" : {
"description" : "Model provider used for this thread (for example, 'openai')." ,
"type" : "string"
} ,
"name" : {
"description" : "Optional user-facing thread title." ,
"type" : [
"string" ,
"null"
]
} ,
"path" : {
"description" : "[UNSTABLE] Path to the thread on disk." ,
"type" : [
"string" ,
"null"
]
} ,
"preview" : {
"description" : "Usually the first user message in the thread, if available." ,
"type" : "string"
} ,
"source" : {
"allOf" : [
{
"$ref" : "#/definitions/SessionSource"
}
] ,
"description" : "Origin of the thread (CLI, VSCode, codex exec, codex app-server, etc.)."
} ,
"status" : {
"allOf" : [
{
"$ref" : "#/definitions/ThreadStatus"
}
] ,
"description" : "Current runtime status for the thread."
} ,
"turns" : {
"description" : "Only populated on `thread/resume`, `thread/rollback`, `thread/fork`, and `thread/read` (when `includeTurns` is true) responses. For all other responses and notifications returning a Thread, the turns field will be an empty list." ,
"items" : {
"$ref" : "#/definitions/Turn"
} ,
"type" : "array"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"updatedAt" : {
"description" : "Unix timestamp (in seconds) when the thread was last updated." ,
"format" : "int64" ,
"type" : "integer"
}
} ,
"required" : [
"cliVersion" ,
"createdAt" ,
"cwd" ,
2026-02-27 17:42:25 -08:00
"ephemeral" ,
2026-02-20 21:36:12 -08:00
"id" ,
"modelProvider" ,
"preview" ,
"source" ,
"status" ,
"turns" ,
"updatedAt"
] ,
"type" : "object"
} ,
"ThreadActiveFlag" : {
"enum" : [
"waitingOnApproval" ,
"waitingOnUserInput"
] ,
"type" : "string"
} ,
"ThreadArchivedNotification" : {
"properties" : {
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
2026-02-25 13:14:30 -08:00
"ThreadClosedNotification" : {
"properties" : {
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"ThreadId" : {
"type" : "string"
} ,
"ThreadItem" : {
"oneOf" : [
2026-02-01 23:38:43 -08:00
{
"properties" : {
2026-02-20 21:36:12 -08:00
"content" : {
"items" : {
"$ref" : "#/definitions/UserInput"
} ,
"type" : "array"
} ,
"id" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"userMessage"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "UserMessageThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"content" ,
"id" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "UserMessageThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
[hooks] use a user message > developer message for prompt continuation (#14867)
## Summary
Persist Stop-hook continuation prompts as `user` messages instead of
hidden `developer` messages + some requested integration tests
This is a followup to @pakrym 's comment in
https://github.com/openai/codex/pull/14532 to make sure stop-block
continuation prompts match training for turn loops
- Stop continuation now writes `<hook_prompt hook_run_id="...">stop
hook's user prompt<hook_prompt>`
- Introduces quick-xml dependency, though we already indirectly depended
on it anyway via syntect
- This PR only has about 500 lines of actual logic changes, the rest is
tests/schema
## Testing
Example run (with a sessionstart hook and 3 stop hooks) - this shows
context added by session start, then two stop hooks sending their own
additional prompts in a new turn. The model responds with a single
message addressing both. Then when that turn ends, the hooks detect that
they just ran using `stop_hook_active` and decide not to infinite loop
test files for this (unzip, move codex -> .codex):
[codex.zip](https://github.com/user-attachments/files/26075806/codex.zip)
```
› cats
• Running SessionStart hook: lighting the observatory
SessionStart hook (completed)
warning: Hi, I'm a session start hook for wizard-tower (startup).
hook context: A wimboltine stonpet is an exotic cuisine from hyperspace
• Cats are tiny zen wizards, my friend: equal parts nap, mystery, and chaos. If you want, we can talk
cat facts, cat breeds, cat names, or build something cat-themed in this repo.
• Running Stop hook: checking the tower wards
• Running Stop hook: sacking the guards
• Running Stop hook: hiring the guards
Stop hook (completed)
warning: Wizard Tower Stop hook reviewed the completed reply (177 chars).
Stop hook (blocked)
warning: Wizard Tower Stop hook continuing conversation
feedback: cook the stonpet
Stop hook (blocked)
warning: Wizard Tower Stop hook continuing conversation
feedback: eat the cooked stonpet
• Stonpet’s cooked, aloha style: flash-seared over a blue quasiflame, glazed with nebula salt, and
rested until the hyperspace juices settle.
Now we eat with gratitude, my friend. One mindful bite in, and the flavor is pure cosmic surf:
smoky, bright, and totally out of this dimension.
• Running Stop hook: checking the tower wards
• Running Stop hook: sacking the guards
• Running Stop hook: hiring the guards
Stop hook (completed)
warning: Wizard Tower Stop hook reviewed the completed reply (285 chars).
Stop hook (completed)
warning: Wizard Tower Stop hook saw a second pass and stayed calm to avoid a loop.
Stop hook (completed)
warning: Wizard Tower Stop hook saw a second pass and stayed calm to avoid a loop.
```
2026-03-19 10:53:08 -07:00
{
"properties" : {
"fragments" : {
"items" : {
"$ref" : "#/definitions/HookPromptFragment"
} ,
"type" : "array"
} ,
"id" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"hookPrompt"
] ,
"title" : "HookPromptThreadItemType" ,
"type" : "string"
}
} ,
"required" : [
"fragments" ,
"id" ,
"type"
] ,
"title" : "HookPromptThreadItem" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
2026-02-20 21:36:12 -08:00
"id" : {
"type" : "string"
} ,
2026-03-18 10:03:38 +00:00
"memoryCitation" : {
"anyOf" : [
{
"$ref" : "#/definitions/MemoryCitation"
} ,
{
"type" : "null"
}
] ,
"default" : null
} ,
2026-02-20 21:36:12 -08:00
"phase" : {
"anyOf" : [
{
"$ref" : "#/definitions/MessagePhase"
} ,
{
"type" : "null"
}
] ,
"default" : null
} ,
2026-02-01 23:38:43 -08:00
"text" : {
"type" : "string"
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"agentMessage"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "AgentMessageThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"id" ,
2026-02-01 23:38:43 -08:00
"text" ,
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "AgentMessageThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
2026-02-20 21:36:12 -08:00
"description" : "EXPERIMENTAL - proposed plan item content. The completed plan item is authoritative and may not match the concatenation of `PlanDelta` text." ,
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"id" : {
"type" : "string"
} ,
"text" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"plan"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "PlanThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"id" ,
"text" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "PlanThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
2026-02-20 21:36:12 -08:00
"content" : {
"default" : [ ] ,
"items" : {
"type" : "string"
} ,
"type" : "array"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"id" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"summary" : {
"default" : [ ] ,
"items" : {
"type" : "string"
} ,
"type" : "array"
2026-02-01 23:38:43 -08:00
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"reasoning"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ReasoningThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"id" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "ReasoningThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
2026-02-20 21:36:12 -08:00
"aggregatedOutput" : {
"description" : "The command's output, aggregated from stdout and stderr." ,
2026-02-01 23:38:43 -08:00
"type" : [
2026-02-20 21:36:12 -08:00
"string" ,
2026-02-01 23:38:43 -08:00
"null"
]
} ,
2026-02-20 21:36:12 -08:00
"command" : {
"description" : "The command to be executed." ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"commandActions" : {
"description" : "A best-effort parsing of the command to understand the action(s) it will perform. This returns a list of CommandAction objects because a single shell command may be composed of many commands piped together." ,
"items" : {
"$ref" : "#/definitions/CommandAction"
} ,
"type" : "array"
2026-02-10 02:09:23 -08:00
} ,
2026-02-20 21:36:12 -08:00
"cwd" : {
"description" : "The command's working directory." ,
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"durationMs" : {
"description" : "The duration of the command execution in milliseconds." ,
"format" : "int64" ,
2026-02-01 23:38:43 -08:00
"type" : [
2026-02-20 21:36:12 -08:00
"integer" ,
2026-02-01 23:38:43 -08:00
"null"
]
} ,
2026-02-20 21:36:12 -08:00
"exitCode" : {
"description" : "The command's exit code." ,
"format" : "int32" ,
2026-02-01 23:38:43 -08:00
"type" : [
2026-02-20 21:36:12 -08:00
"integer" ,
2026-02-01 23:38:43 -08:00
"null"
]
} ,
2026-02-20 21:36:12 -08:00
"id" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"processId" : {
"description" : "Identifier for the underlying PTY process (when available)." ,
2026-02-01 23:38:43 -08:00
"type" : [
"string" ,
"null"
]
} ,
2026-03-18 23:42:40 -06:00
"source" : {
"allOf" : [
{
"$ref" : "#/definitions/CommandExecutionSource"
}
] ,
"default" : "agent"
} ,
2026-02-01 23:38:43 -08:00
"status" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/CommandExecutionStatus"
2026-02-01 23:38:43 -08:00
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"commandExecution"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "CommandExecutionThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"command" ,
"commandActions" ,
"cwd" ,
"id" ,
2026-02-01 23:38:43 -08:00
"status" ,
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "CommandExecutionThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
2026-02-20 21:36:12 -08:00
"changes" : {
2026-02-01 23:38:43 -08:00
"items" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/FileUpdateChange"
2026-02-01 23:38:43 -08:00
} ,
"type" : "array"
} ,
2026-02-20 21:36:12 -08:00
"id" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"status" : {
"$ref" : "#/definitions/PatchApplyStatus"
2026-02-01 23:38:43 -08:00
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"fileChange"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "FileChangeThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"changes" ,
"id" ,
"status" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "FileChangeThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
2026-02-20 21:36:12 -08:00
"arguments" : true ,
"durationMs" : {
"description" : "The duration of the MCP tool call in milliseconds." ,
"format" : "int64" ,
"type" : [
"integer" ,
"null"
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"error" : {
"anyOf" : [
{
"$ref" : "#/definitions/McpToolCallError"
} ,
{
"type" : "null"
}
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"id" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
"result" : {
2026-02-20 21:36:12 -08:00
"anyOf" : [
{
"$ref" : "#/definitions/McpToolCallResult"
} ,
2026-02-01 23:38:43 -08:00
{
2026-02-20 21:36:12 -08:00
"type" : "null"
2026-02-01 23:38:43 -08:00
}
2026-02-20 21:36:12 -08:00
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"server" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
2026-02-20 21:36:12 -08:00
} ,
"status" : {
"$ref" : "#/definitions/McpToolCallStatus"
} ,
"tool" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"mcpToolCall"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "McpToolCallThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"arguments" ,
"id" ,
"server" ,
"status" ,
"tool" ,
"type"
] ,
"title" : "McpToolCallThreadItem" ,
"type" : "object"
} ,
2026-02-25 12:00:10 -08:00
{
"properties" : {
"arguments" : true ,
"contentItems" : {
"items" : {
"$ref" : "#/definitions/DynamicToolCallOutputContentItem"
} ,
"type" : [
"array" ,
"null"
]
} ,
"durationMs" : {
"description" : "The duration of the dynamic tool call in milliseconds." ,
"format" : "int64" ,
"type" : [
"integer" ,
"null"
]
} ,
"id" : {
"type" : "string"
} ,
"status" : {
"$ref" : "#/definitions/DynamicToolCallStatus"
} ,
"success" : {
"type" : [
"boolean" ,
"null"
]
} ,
"tool" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"dynamicToolCall"
] ,
"title" : "DynamicToolCallThreadItemType" ,
"type" : "string"
}
} ,
"required" : [
"arguments" ,
"id" ,
"status" ,
"tool" ,
"type"
] ,
"title" : "DynamicToolCallThreadItem" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
2026-02-20 21:36:12 -08:00
"agentsStates" : {
"additionalProperties" : {
"$ref" : "#/definitions/CollabAgentState"
} ,
"description" : "Last known status of the target agents, when available." ,
"type" : "object"
} ,
"id" : {
"description" : "Unique identifier for this collab tool call." ,
"type" : "string"
} ,
2026-03-11 19:25:21 -07:00
"model" : {
"description" : "Model requested for the spawned agent, when applicable." ,
"type" : [
"string" ,
"null"
]
} ,
2026-02-20 21:36:12 -08:00
"prompt" : {
"description" : "Prompt text sent as part of the collab tool call, when available." ,
"type" : [
"string" ,
"null"
]
} ,
2026-03-11 19:25:21 -07:00
"reasoningEffort" : {
"anyOf" : [
{
"$ref" : "#/definitions/ReasoningEffort"
} ,
{
"type" : "null"
}
] ,
"description" : "Reasoning effort requested for the spawned agent, when applicable."
} ,
2026-02-20 21:36:12 -08:00
"receiverThreadIds" : {
"description" : "Thread ID of the receiving agent, when applicable. In case of spawn operation, this corresponds to the newly spawned agent." ,
2026-02-01 23:38:43 -08:00
"items" : {
2026-02-20 21:36:12 -08:00
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
"type" : "array"
} ,
2026-02-20 21:36:12 -08:00
"senderThreadId" : {
"description" : "Thread ID of the agent issuing the collab request." ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"status" : {
"allOf" : [
{
"$ref" : "#/definitions/CollabAgentToolCallStatus"
}
] ,
"description" : "Current status of the collab tool call."
} ,
"tool" : {
"allOf" : [
{
"$ref" : "#/definitions/CollabAgentTool"
}
] ,
"description" : "Name of the collab tool that was invoked."
} ,
2026-02-01 23:38:43 -08:00
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"collabAgentToolCall"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "CollabAgentToolCallThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"agentsStates" ,
2026-02-01 23:38:43 -08:00
"id" ,
2026-02-20 21:36:12 -08:00
"receiverThreadIds" ,
"senderThreadId" ,
"status" ,
"tool" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "CollabAgentToolCallThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
2026-02-20 21:36:12 -08:00
"action" : {
2026-02-06 18:39:52 -08:00
"anyOf" : [
{
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/WebSearchAction"
2026-02-06 18:39:52 -08:00
} ,
{
"type" : "null"
}
2026-02-20 21:36:12 -08:00
]
} ,
"id" : {
"type" : "string"
} ,
"query" : {
"type" : "string"
2026-02-06 18:39:52 -08:00
} ,
2026-02-01 23:38:43 -08:00
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"webSearch"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "WebSearchThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"query" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "WebSearchThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"path" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"imageView"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ImageViewThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"path" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "ImageViewThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"type" : "string"
2026-03-04 16:54:38 -08:00
} ,
"result" : {
"type" : "string"
} ,
"revisedPrompt" : {
"type" : [
"string" ,
"null"
]
} ,
2026-03-19 22:57:16 -07:00
"savedPath" : {
"type" : [
"string" ,
"null"
]
} ,
2026-03-04 16:54:38 -08:00
"status" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"imageGeneration"
] ,
"title" : "ImageGenerationThreadItemType" ,
"type" : "string"
}
} ,
"required" : [
"id" ,
"result" ,
"status" ,
"type"
] ,
"title" : "ImageGenerationThreadItem" ,
"type" : "object"
} ,
{
"properties" : {
"id" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"review" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"enteredReviewMode"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "EnteredReviewModeThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"review" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "EnteredReviewModeThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"type" : "string"
} ,
2026-02-20 21:36:12 -08:00
"review" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"exitedReviewMode"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ExitedReviewModeThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"review" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "ExitedReviewModeThreadItem" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"type" : "string"
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"contextCompaction"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ContextCompactionThreadItemType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
"id" ,
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "ContextCompactionThreadItem" ,
"type" : "object"
}
]
} ,
"ThreadNameUpdatedNotification" : {
"properties" : {
"threadId" : {
"type" : "string"
} ,
"threadName" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
2026-02-25 09:59:10 -08:00
"ThreadRealtimeAudioChunk" : {
"description" : "EXPERIMENTAL - thread realtime audio chunk." ,
"properties" : {
"data" : {
"type" : "string"
} ,
2026-03-16 21:38:07 -07:00
"itemId" : {
"type" : [
"string" ,
"null"
]
} ,
2026-02-25 09:59:10 -08:00
"numChannels" : {
"format" : "uint16" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"sampleRate" : {
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"samplesPerChannel" : {
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
}
} ,
"required" : [
"data" ,
"numChannels" ,
"sampleRate"
] ,
"type" : "object"
} ,
"ThreadRealtimeClosedNotification" : {
"description" : "EXPERIMENTAL - emitted when thread realtime transport closes." ,
"properties" : {
"reason" : {
"type" : [
"string" ,
"null"
]
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
"ThreadRealtimeErrorNotification" : {
"description" : "EXPERIMENTAL - emitted when thread realtime encounters an error." ,
"properties" : {
"message" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"message" ,
"threadId"
] ,
"type" : "object"
} ,
"ThreadRealtimeItemAddedNotification" : {
"description" : "EXPERIMENTAL - raw non-audio thread realtime item emitted by the backend." ,
"properties" : {
"item" : true ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"item" ,
"threadId"
] ,
"type" : "object"
} ,
"ThreadRealtimeOutputAudioDeltaNotification" : {
"description" : "EXPERIMENTAL - streamed output audio emitted by thread realtime." ,
"properties" : {
"audio" : {
"$ref" : "#/definitions/ThreadRealtimeAudioChunk"
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"audio" ,
"threadId"
] ,
"type" : "object"
} ,
"ThreadRealtimeStartedNotification" : {
"description" : "EXPERIMENTAL - emitted when thread realtime startup is accepted." ,
"properties" : {
"sessionId" : {
"type" : [
"string" ,
"null"
]
} ,
"threadId" : {
"type" : "string"
2026-03-17 15:24:37 -07:00
} ,
"version" : {
"$ref" : "#/definitions/RealtimeConversationVersion"
2026-02-25 09:59:10 -08:00
}
} ,
"required" : [
2026-03-17 15:24:37 -07:00
"threadId" ,
"version"
2026-02-25 09:59:10 -08:00
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"ThreadStartedNotification" : {
"properties" : {
"thread" : {
"$ref" : "#/definitions/Thread"
}
} ,
"required" : [
"thread"
] ,
"type" : "object"
} ,
"ThreadStatus" : {
"oneOf" : [
{
"properties" : {
"type" : {
"enum" : [
"notLoaded"
] ,
"title" : "NotLoadedThreadStatusType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "NotLoadedThreadStatus" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"idle"
] ,
"title" : "IdleThreadStatusType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "IdleThreadStatus" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"systemError"
] ,
"title" : "SystemErrorThreadStatusType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "SystemErrorThreadStatus" ,
"type" : "object"
} ,
{
"properties" : {
"activeFlags" : {
"items" : {
"$ref" : "#/definitions/ThreadActiveFlag"
} ,
"type" : "array"
} ,
"type" : {
"enum" : [
"active"
] ,
"title" : "ActiveThreadStatusType" ,
"type" : "string"
}
} ,
"required" : [
"activeFlags" ,
"type"
] ,
"title" : "ActiveThreadStatus" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
}
]
} ,
2026-02-20 21:36:12 -08:00
"ThreadStatusChangedNotification" : {
"properties" : {
"status" : {
"$ref" : "#/definitions/ThreadStatus"
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"status" ,
"threadId"
] ,
"type" : "object"
} ,
"ThreadTokenUsage" : {
"properties" : {
"last" : {
"$ref" : "#/definitions/TokenUsageBreakdown"
} ,
"modelContextWindow" : {
"format" : "int64" ,
"type" : [
"integer" ,
"null"
]
} ,
"total" : {
"$ref" : "#/definitions/TokenUsageBreakdown"
}
} ,
"required" : [
"last" ,
"total"
] ,
"type" : "object"
} ,
"ThreadTokenUsageUpdatedNotification" : {
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"threadId" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"tokenUsage" : {
"$ref" : "#/definitions/ThreadTokenUsage"
} ,
"turnId" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"threadId" ,
"tokenUsage" ,
"turnId"
2026-02-01 23:38:43 -08:00
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"ThreadUnarchivedNotification" : {
"properties" : {
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"type" : "object"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"TokenUsageBreakdown" : {
2026-02-01 23:38:43 -08:00
"properties" : {
2026-02-20 21:36:12 -08:00
"cachedInputTokens" : {
"format" : "int64" ,
"type" : "integer"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"inputTokens" : {
"format" : "int64" ,
"type" : "integer"
} ,
"outputTokens" : {
"format" : "int64" ,
"type" : "integer"
} ,
"reasoningOutputTokens" : {
"format" : "int64" ,
"type" : "integer"
} ,
"totalTokens" : {
"format" : "int64" ,
"type" : "integer"
}
} ,
"required" : [
"cachedInputTokens" ,
"inputTokens" ,
"outputTokens" ,
"reasoningOutputTokens" ,
"totalTokens"
] ,
"type" : "object"
} ,
"Turn" : {
"properties" : {
"error" : {
"anyOf" : [
{
"$ref" : "#/definitions/TurnError"
} ,
{
"type" : "null"
}
] ,
"description" : "Only populated when the Turn's status is failed."
} ,
"id" : {
"type" : "string"
} ,
"items" : {
"description" : "Only populated on a `thread/resume` or `thread/fork` response. For all other responses and notifications returning a Turn, the items field will be an empty list." ,
2026-02-01 23:38:43 -08:00
"items" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadItem"
2026-02-01 23:38:43 -08:00
} ,
"type" : "array"
} ,
2026-02-20 21:36:12 -08:00
"status" : {
"$ref" : "#/definitions/TurnStatus"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"id" ,
"items" ,
"status"
2026-02-01 23:38:43 -08:00
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"TurnCompletedNotification" : {
2026-02-01 23:38:43 -08:00
"properties" : {
"threadId" : {
"type" : "string"
} ,
"turn" : {
"$ref" : "#/definitions/Turn"
}
} ,
"required" : [
"threadId" ,
"turn"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"TurnDiffUpdatedNotification" : {
"description" : "Notification that the turn-level unified diff has changed. Contains the latest aggregated diff across all file changes in the turn." ,
"properties" : {
"diff" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"diff" ,
"threadId" ,
"turnId"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"type" : "object"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"TurnError" : {
"properties" : {
"additionalDetails" : {
"default" : null ,
"type" : [
"string" ,
"null"
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"codexErrorInfo" : {
"anyOf" : [
{
"$ref" : "#/definitions/CodexErrorInfo"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
{
"type" : "null"
2026-02-01 23:38:43 -08:00
}
2026-02-20 21:36:12 -08:00
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"message" : {
"type" : "string"
}
} ,
"required" : [
"message"
] ,
"type" : "object"
} ,
"TurnPlanStep" : {
"properties" : {
"status" : {
"$ref" : "#/definitions/TurnPlanStepStatus"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"step" : {
"type" : "string"
}
} ,
"required" : [
"status" ,
"step"
] ,
"type" : "object"
} ,
"TurnPlanStepStatus" : {
"enum" : [
"pending" ,
"inProgress" ,
"completed"
] ,
"type" : "string"
} ,
"TurnPlanUpdatedNotification" : {
"properties" : {
"explanation" : {
"type" : [
"string" ,
"null"
]
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"plan" : {
"items" : {
"$ref" : "#/definitions/TurnPlanStep"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"type" : "array"
} ,
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
}
2026-02-20 21:36:12 -08:00
} ,
"required" : [
"plan" ,
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"TurnStartedNotification" : {
"properties" : {
"threadId" : {
"type" : "string"
} ,
"turn" : {
"$ref" : "#/definitions/Turn"
}
} ,
"required" : [
"threadId" ,
"turn"
] ,
"type" : "object"
} ,
"TurnStatus" : {
"enum" : [
"completed" ,
"interrupted" ,
"failed" ,
"inProgress"
] ,
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"UserInput" : {
2026-02-01 23:38:43 -08:00
"oneOf" : [
{
"properties" : {
"text" : {
"type" : "string"
} ,
"text_elements" : {
"default" : [ ] ,
2026-02-20 21:36:12 -08:00
"description" : "UI-defined spans within `text` used to render or persist special elements." ,
2026-02-01 23:38:43 -08:00
"items" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/TextElement"
2026-02-01 23:38:43 -08:00
} ,
"type" : "array"
} ,
"type" : {
"enum" : [
"text"
] ,
2026-02-20 21:36:12 -08:00
"title" : "TextUserInputType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
"text" ,
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "TextUserInput" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"image"
] ,
2026-02-20 21:36:12 -08:00
"title" : "ImageUserInputType" ,
"type" : "string"
} ,
"url" : {
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"type" ,
"url"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ImageUserInput" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"path" : {
"type" : "string"
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"localImage"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "LocalImageUserInputType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
"path" ,
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "LocalImageUserInput" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"name" : {
"type" : "string"
} ,
"path" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"skill"
] ,
2026-02-20 21:36:12 -08:00
"title" : "SkillUserInputType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
"name" ,
"path" ,
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "SkillUserInput" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"name" : {
"type" : "string"
} ,
"path" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"mention"
] ,
2026-02-20 21:36:12 -08:00
"title" : "MentionUserInputType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
}
} ,
"required" : [
"name" ,
"path" ,
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "MentionUserInput" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
}
]
} ,
"WebSearchAction" : {
"oneOf" : [
{
"properties" : {
"queries" : {
"items" : {
"type" : "string"
} ,
"type" : [
"array" ,
"null"
]
} ,
"query" : {
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"search"
] ,
"title" : "SearchWebSearchActionType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "SearchWebSearchAction" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"openPage"
] ,
"title" : "OpenPageWebSearchActionType" ,
"type" : "string"
} ,
"url" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"type"
] ,
"title" : "OpenPageWebSearchAction" ,
"type" : "object"
} ,
{
"properties" : {
"pattern" : {
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"findInPage"
] ,
"title" : "FindInPageWebSearchActionType" ,
"type" : "string"
} ,
"url" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"type"
] ,
"title" : "FindInPageWebSearchAction" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"other"
] ,
"title" : "OtherWebSearchActionType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "OtherWebSearchAction" ,
"type" : "object"
}
]
} ,
2026-02-18 13:03:16 -08:00
"WindowsSandboxSetupCompletedNotification" : {
"properties" : {
"error" : {
"type" : [
"string" ,
"null"
]
} ,
"mode" : {
"$ref" : "#/definitions/WindowsSandboxSetupMode"
} ,
"success" : {
"type" : "boolean"
}
} ,
"required" : [
"mode" ,
"success"
] ,
"type" : "object"
} ,
"WindowsSandboxSetupMode" : {
"enum" : [
"elevated" ,
"unelevated"
] ,
"type" : "string"
} ,
2026-02-01 23:38:43 -08:00
"WindowsWorldWritableWarningNotification" : {
"properties" : {
"extraCount" : {
"format" : "uint" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"failedScan" : {
"type" : "boolean"
} ,
"samplePaths" : {
"items" : {
"type" : "string"
} ,
"type" : "array"
}
} ,
"required" : [
"extraCount" ,
"failedScan" ,
"samplePaths"
] ,
"type" : "object"
}
} ,
"description" : "Notification sent from the server to the client." ,
"oneOf" : [
{
"description" : "NEW NOTIFICATIONS" ,
"properties" : {
"method" : {
"enum" : [
"error"
] ,
"title" : "ErrorNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ErrorNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "ErrorNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"thread/started"
] ,
"title" : "Thread/startedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadStartedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/startedNotification" ,
"type" : "object"
} ,
2026-02-18 15:20:03 -08:00
{
"properties" : {
"method" : {
"enum" : [
"thread/status/changed"
] ,
"title" : "Thread/status/changedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadStatusChangedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/status/changedNotification" ,
"type" : "object"
} ,
2026-02-17 14:53:58 -08:00
{
"properties" : {
"method" : {
"enum" : [
"thread/archived"
] ,
"title" : "Thread/archivedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadArchivedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/archivedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"thread/unarchived"
] ,
"title" : "Thread/unarchivedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadUnarchivedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/unarchivedNotification" ,
"type" : "object"
} ,
2026-02-25 13:14:30 -08:00
{
"properties" : {
"method" : {
"enum" : [
"thread/closed"
] ,
"title" : "Thread/closedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadClosedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/closedNotification" ,
2026-03-03 17:01:00 -08:00
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"skills/changed"
] ,
"title" : "Skills/changedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/SkillsChangedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Skills/changedNotification" ,
2026-02-25 13:14:30 -08:00
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"method" : {
"enum" : [
"thread/name/updated"
] ,
"title" : "Thread/name/updatedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadNameUpdatedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/name/updatedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"thread/tokenUsage/updated"
] ,
"title" : "Thread/tokenUsage/updatedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadTokenUsageUpdatedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/tokenUsage/updatedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"turn/started"
] ,
"title" : "Turn/startedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/TurnStartedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Turn/startedNotification" ,
"type" : "object"
} ,
2026-03-09 21:11:31 -07:00
{
"properties" : {
"method" : {
"enum" : [
"hook/started"
] ,
"title" : "Hook/startedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/HookStartedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Hook/startedNotification" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"method" : {
"enum" : [
"turn/completed"
] ,
"title" : "Turn/completedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/TurnCompletedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Turn/completedNotification" ,
"type" : "object"
} ,
2026-03-09 21:11:31 -07:00
{
"properties" : {
"method" : {
"enum" : [
"hook/completed"
] ,
"title" : "Hook/completedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/HookCompletedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Hook/completedNotification" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"method" : {
"enum" : [
"turn/diff/updated"
] ,
"title" : "Turn/diff/updatedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/TurnDiffUpdatedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Turn/diff/updatedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"turn/plan/updated"
] ,
"title" : "Turn/plan/updatedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/TurnPlanUpdatedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Turn/plan/updatedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"item/started"
] ,
"title" : "Item/startedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ItemStartedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/startedNotification" ,
"type" : "object"
} ,
Add Smart Approvals guardian review across core, app-server, and TUI (#13860)
## Summary
- add `approvals_reviewer = "user" | "guardian_subagent"` as the runtime
control for who reviews approval requests
- route Smart Approvals guardian review through core for command
execution, file changes, managed-network approvals, MCP approvals, and
delegated/subagent approval flows
- expose guardian review in app-server with temporary unstable
`item/autoApprovalReview/{started,completed}` notifications carrying
`targetItemId`, `review`, and `action`
- update the TUI so Smart Approvals can be enabled from `/experimental`,
aligned with the matching `/approvals` mode, and surfaced clearly while
reviews are pending or resolved
## Runtime model
This PR does not introduce a new `approval_policy`.
Instead:
- `approval_policy` still controls when approval is needed
- `approvals_reviewer` controls who reviewable approval requests are
routed to:
- `user`
- `guardian_subagent`
`guardian_subagent` is a carefully prompted reviewer subagent that
gathers relevant context and applies a risk-based decision framework
before approving or denying the request.
The `smart_approvals` feature flag is a rollout/UI gate. Core runtime
behavior keys off `approvals_reviewer`.
When Smart Approvals is enabled from the TUI, it also switches the
current `/approvals` settings to the matching Smart Approvals mode so
users immediately see guardian review in the active thread:
- `approval_policy = on-request`
- `approvals_reviewer = guardian_subagent`
- `sandbox_mode = workspace-write`
Users can still change `/approvals` afterward.
Config-load behavior stays intentionally narrow:
- plain `smart_approvals = true` in `config.toml` remains just the
rollout/UI gate and does not auto-set `approvals_reviewer`
- the deprecated `guardian_approval = true` alias migration does
backfill `approvals_reviewer = "guardian_subagent"` in the same scope
when that reviewer is not already configured there, so old configs
preserve their original guardian-enabled behavior
ARC remains a separate safety check. For MCP tool approvals, ARC
escalations now flow into the configured reviewer instead of always
bypassing guardian and forcing manual review.
## Config stability
The runtime reviewer override is stable, but the config-backed
app-server protocol shape is still settling.
- `thread/start`, `thread/resume`, and `turn/start` keep stable
`approvalsReviewer` overrides
- the config-backed `approvals_reviewer` exposure returned via
`config/read` (including profile-level config) is now marked
`[UNSTABLE]` / experimental in the app-server protocol until we are more
confident in that config surface
## App-server surface
This PR intentionally keeps the guardian app-server shape narrow and
temporary.
It adds generic unstable lifecycle notifications:
- `item/autoApprovalReview/started`
- `item/autoApprovalReview/completed`
with payloads of the form:
- `{ threadId, turnId, targetItemId, review, action? }`
`review` is currently:
- `{ status, riskScore?, riskLevel?, rationale? }`
- where `status` is one of `inProgress`, `approved`, `denied`, or
`aborted`
`action` carries the guardian action summary payload from core when
available. This lets clients render temporary standalone pending-review
UI, including parallel reviews, even when the underlying tool item has
not been emitted yet.
These notifications are explicitly documented as `[UNSTABLE]` and
expected to change soon.
This PR does **not** persist guardian review state onto `thread/read`
tool items. The intended follow-up is to attach guardian review state to
the reviewed tool item lifecycle instead, which would improve
consistency with manual approvals and allow thread history / reconnect
flows to replay guardian review state directly.
## TUI behavior
- `/experimental` exposes the rollout gate as `Smart Approvals`
- enabling it in the TUI enables the feature and switches the current
session to the matching Smart Approvals `/approvals` mode
- disabling it in the TUI clears the persisted `approvals_reviewer`
override when appropriate and returns the session to default manual
review when the effective reviewer changes
- `/approvals` still exposes the reviewer choice directly
- the TUI renders:
- pending guardian review state in the live status footer, including
parallel review aggregation
- resolved approval/denial state in history
## Scope notes
This PR includes the supporting core/runtime work needed to make Smart
Approvals usable end-to-end:
- shell / unified-exec / apply_patch / managed-network / MCP guardian
review
- delegated/subagent approval routing into guardian review
- guardian review risk metadata and action summaries for app-server/TUI
- config/profile/TUI handling for `smart_approvals`, `guardian_approval`
alias migration, and `approvals_reviewer`
- a small internal cleanup of delegated approval forwarding to dedupe
fallback paths and simplify guardian-vs-parent approval waiting (no
intended behavior change)
Out of scope for this PR:
- redesigning the existing manual approval protocol shapes
- persisting guardian review state onto app-server `ThreadItem`s
- delegated MCP elicitation auto-review (the current delegated MCP
guardian shim only covers the legacy `RequestUserInput` path)
---------
Co-authored-by: Codex <noreply@openai.com>
2026-03-13 15:27:00 -07:00
{
"properties" : {
"method" : {
"enum" : [
"item/autoApprovalReview/started"
] ,
"title" : "Item/autoApprovalReview/startedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ItemGuardianApprovalReviewStartedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/autoApprovalReview/startedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"item/autoApprovalReview/completed"
] ,
"title" : "Item/autoApprovalReview/completedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ItemGuardianApprovalReviewCompletedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/autoApprovalReview/completedNotification" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"method" : {
"enum" : [
"item/completed"
] ,
"title" : "Item/completedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ItemCompletedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/completedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"item/agentMessage/delta"
] ,
"title" : "Item/agentMessage/deltaNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/AgentMessageDeltaNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/agentMessage/deltaNotification" ,
"type" : "object"
} ,
{
"description" : "EXPERIMENTAL - proposed plan streaming deltas for plan items." ,
"properties" : {
"method" : {
"enum" : [
"item/plan/delta"
] ,
"title" : "Item/plan/deltaNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/PlanDeltaNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/plan/deltaNotification" ,
"type" : "object"
} ,
2026-03-06 17:30:17 -08:00
{
"description" : "Stream base64-encoded stdout/stderr chunks for a running `command/exec` session." ,
"properties" : {
"method" : {
"enum" : [
"command/exec/outputDelta"
] ,
"title" : "Command/exec/outputDeltaNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/CommandExecOutputDeltaNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Command/exec/outputDeltaNotification" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"method" : {
"enum" : [
"item/commandExecution/outputDelta"
] ,
"title" : "Item/commandExecution/outputDeltaNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/CommandExecutionOutputDeltaNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/commandExecution/outputDeltaNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"item/commandExecution/terminalInteraction"
] ,
"title" : "Item/commandExecution/terminalInteractionNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/TerminalInteractionNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/commandExecution/terminalInteractionNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"item/fileChange/outputDelta"
] ,
"title" : "Item/fileChange/outputDeltaNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FileChangeOutputDeltaNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/fileChange/outputDeltaNotification" ,
"type" : "object"
} ,
2026-02-27 12:45:59 -08:00
{
"properties" : {
"method" : {
"enum" : [
"serverRequest/resolved"
] ,
"title" : "ServerRequest/resolvedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ServerRequestResolvedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "ServerRequest/resolvedNotification" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"method" : {
"enum" : [
"item/mcpToolCall/progress"
] ,
"title" : "Item/mcpToolCall/progressNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/McpToolCallProgressNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/mcpToolCall/progressNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"mcpServer/oauthLogin/completed"
] ,
"title" : "McpServer/oauthLogin/completedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/McpServerOauthLoginCompletedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "McpServer/oauthLogin/completedNotification" ,
"type" : "object"
} ,
feat(app-server): add mcpServer/startupStatus/updated notification (#15220)
Exposes the legacy `codex/event/mcp_startup_update` event as an API v2
notification.
The legacy event has this shape:
```
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
pub struct McpStartupUpdateEvent {
/// Server name being started.
pub server: String,
/// Current startup status.
pub status: McpStartupStatus,
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
#[serde(rename_all = "snake_case", tag = "state")]
#[ts(rename_all = "snake_case", tag = "state")]
pub enum McpStartupStatus {
Starting,
Ready,
Failed { error: String },
Cancelled,
}
```
2026-03-19 15:09:59 -07:00
{
"properties" : {
"method" : {
"enum" : [
"mcpServer/startupStatus/updated"
] ,
"title" : "McpServer/startupStatus/updatedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/McpServerStatusUpdatedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "McpServer/startupStatus/updatedNotification" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"method" : {
"enum" : [
"account/updated"
] ,
"title" : "Account/updatedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/AccountUpdatedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Account/updatedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"account/rateLimits/updated"
] ,
"title" : "Account/rateLimits/updatedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/AccountRateLimitsUpdatedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Account/rateLimits/updatedNotification" ,
"type" : "object"
} ,
2026-02-08 15:24:56 -08:00
{
"properties" : {
"method" : {
"enum" : [
"app/list/updated"
] ,
"title" : "App/list/updatedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/AppListUpdatedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "App/list/updatedNotification" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"method" : {
"enum" : [
"item/reasoning/summaryTextDelta"
] ,
"title" : "Item/reasoning/summaryTextDeltaNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ReasoningSummaryTextDeltaNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/reasoning/summaryTextDeltaNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"item/reasoning/summaryPartAdded"
] ,
"title" : "Item/reasoning/summaryPartAddedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ReasoningSummaryPartAddedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/reasoning/summaryPartAddedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"item/reasoning/textDelta"
] ,
"title" : "Item/reasoning/textDeltaNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ReasoningTextDeltaNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Item/reasoning/textDeltaNotification" ,
"type" : "object"
} ,
{
"description" : "Deprecated: Use `ContextCompaction` item type instead." ,
"properties" : {
"method" : {
"enum" : [
"thread/compacted"
] ,
"title" : "Thread/compactedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ContextCompactedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/compactedNotification" ,
"type" : "object"
} ,
2026-02-17 11:02:23 -08:00
{
"properties" : {
"method" : {
"enum" : [
"model/rerouted"
] ,
"title" : "Model/reroutedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ModelReroutedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Model/reroutedNotification" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"method" : {
"enum" : [
"deprecationNotice"
] ,
"title" : "DeprecationNoticeNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/DeprecationNoticeNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "DeprecationNoticeNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"configWarning"
] ,
"title" : "ConfigWarningNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ConfigWarningNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "ConfigWarningNotification" ,
"type" : "object"
} ,
2026-02-12 10:49:44 -08:00
{
"properties" : {
"method" : {
"enum" : [
"fuzzyFileSearch/sessionUpdated"
] ,
"title" : "FuzzyFileSearch/sessionUpdatedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FuzzyFileSearchSessionUpdatedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "FuzzyFileSearch/sessionUpdatedNotification" ,
"type" : "object"
} ,
2026-02-13 15:08:14 -08:00
{
"properties" : {
"method" : {
"enum" : [
"fuzzyFileSearch/sessionCompleted"
] ,
"title" : "FuzzyFileSearch/sessionCompletedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FuzzyFileSearchSessionCompletedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "FuzzyFileSearch/sessionCompletedNotification" ,
"type" : "object"
} ,
2026-02-25 09:59:10 -08:00
{
"properties" : {
"method" : {
"enum" : [
"thread/realtime/started"
] ,
"title" : "Thread/realtime/startedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadRealtimeStartedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/realtime/startedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"thread/realtime/itemAdded"
] ,
"title" : "Thread/realtime/itemAddedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadRealtimeItemAddedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/realtime/itemAddedNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"thread/realtime/outputAudio/delta"
] ,
"title" : "Thread/realtime/outputAudio/deltaNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadRealtimeOutputAudioDeltaNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/realtime/outputAudio/deltaNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"thread/realtime/error"
] ,
"title" : "Thread/realtime/errorNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadRealtimeErrorNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/realtime/errorNotification" ,
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"thread/realtime/closed"
] ,
"title" : "Thread/realtime/closedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadRealtimeClosedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Thread/realtime/closedNotification" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"description" : "Notifies the user of world-writable directories on Windows, which cannot be protected by the sandbox." ,
"properties" : {
"method" : {
"enum" : [
"windows/worldWritableWarning"
] ,
"title" : "Windows/worldWritableWarningNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/WindowsWorldWritableWarningNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Windows/worldWritableWarningNotification" ,
2026-02-18 13:03:16 -08:00
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"windowsSandbox/setupCompleted"
] ,
"title" : "WindowsSandbox/setupCompletedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/WindowsSandboxSetupCompletedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "WindowsSandbox/setupCompletedNotification" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"method" : {
"enum" : [
"account/login/completed"
] ,
"title" : "Account/login/completedNotificationMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/AccountLoginCompletedNotification"
}
} ,
"required" : [
"method" ,
"params"
] ,
"title" : "Account/login/completedNotification" ,
"type" : "object"
}
] ,
"title" : "ServerNotification"
2026-02-10 02:09:23 -08:00
}