2026-02-01 23:38:43 -08:00
{
"$schema" : "http://json-schema.org/draft-07/schema#" ,
"definitions" : {
"AbsolutePathBuf" : {
"description" : "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute." ,
"type" : "string"
} ,
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
"ApprovalsReviewer" : {
"description" : "Configures who approval requests are routed to for review. Examples include sandbox escapes, blocked network access, MCP approval prompts, and ARC escalations. Defaults to `user`. `guardian_subagent` uses a carefully prompted subagent to gather relevant context and apply a risk-based decision framework before approving or denying the request." ,
"enum" : [
"user" ,
"guardian_subagent"
] ,
"type" : "string"
} ,
2026-02-01 23:38:43 -08:00
"AppsListParams" : {
2026-02-08 15:24:56 -08:00
"description" : "EXPERIMENTAL - list available apps/connectors." ,
2026-02-01 23:38:43 -08:00
"properties" : {
"cursor" : {
"description" : "Opaque pagination cursor returned by a previous call." ,
"type" : [
"string" ,
"null"
]
} ,
2026-02-08 15:24:56 -08:00
"forceRefetch" : {
"description" : "When true, bypass app caches and fetch the latest data from sources." ,
"type" : "boolean"
} ,
2026-02-01 23:38:43 -08:00
"limit" : {
"description" : "Optional page size; defaults to a reasonable server-side value." ,
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
2026-02-09 23:10:26 -08:00
} ,
"threadId" : {
"description" : "Optional thread id used to evaluate app feature gating from that thread's config." ,
"type" : [
"string" ,
"null"
]
2026-02-01 23:38:43 -08:00
}
} ,
"type" : "object"
} ,
"AskForApproval" : {
2026-02-19 11:41:49 -08:00
"oneOf" : [
{
"enum" : [
"untrusted" ,
"on-failure" ,
"on-request" ,
"never"
] ,
"type" : "string"
} ,
{
"additionalProperties" : false ,
"properties" : {
2026-03-12 16:38:04 -07:00
"granular" : {
2026-02-19 11:41:49 -08:00
"properties" : {
"mcp_elicitations" : {
"type" : "boolean"
} ,
2026-03-09 18:16:54 -07:00
"request_permissions" : {
2026-03-09 21:56:23 -07:00
"default" : false ,
2026-03-09 18:16:54 -07:00
"type" : "boolean"
} ,
2026-02-19 11:41:49 -08:00
"rules" : {
"type" : "boolean"
} ,
"sandbox_approval" : {
"type" : "boolean"
2026-03-10 16:58:23 -07:00
} ,
"skill_approval" : {
"default" : false ,
"type" : "boolean"
2026-02-19 11:41:49 -08:00
}
} ,
"required" : [
"mcp_elicitations" ,
"rules" ,
"sandbox_approval"
] ,
"type" : "object"
}
} ,
"required" : [
2026-03-12 16:38:04 -07:00
"granular"
2026-02-19 11:41:49 -08:00
] ,
2026-03-12 16:38:04 -07:00
"title" : "GranularAskForApproval" ,
2026-02-19 11:41:49 -08:00
"type" : "object"
}
]
2026-02-01 23:38:43 -08:00
} ,
"ByteRange" : {
"properties" : {
"end" : {
"format" : "uint" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"start" : {
"format" : "uint" ,
"minimum" : 0.0 ,
"type" : "integer"
}
} ,
"required" : [
"end" ,
"start"
] ,
"type" : "object"
} ,
"CancelLoginAccountParams" : {
"properties" : {
"loginId" : {
"type" : "string"
}
} ,
"required" : [
"loginId"
] ,
"type" : "object"
} ,
"ClientInfo" : {
"properties" : {
"name" : {
"type" : "string"
} ,
"title" : {
"type" : [
"string" ,
"null"
]
} ,
"version" : {
"type" : "string"
}
} ,
"required" : [
"name" ,
"version"
] ,
"type" : "object"
} ,
"CollaborationMode" : {
"description" : "Collaboration mode for a Codex session." ,
"properties" : {
"mode" : {
"$ref" : "#/definitions/ModeKind"
} ,
"settings" : {
"$ref" : "#/definitions/Settings"
}
} ,
"required" : [
"mode" ,
"settings"
] ,
"type" : "object"
} ,
"CommandExecParams" : {
2026-03-06 17:30:17 -08:00
"description" : "Run a standalone command (argv vector) in the server sandbox without creating a thread or turn.\n\nThe final `command/exec` response is deferred until the process exits and is sent only after all `command/exec/outputDelta` notifications for that connection have been emitted." ,
2026-02-01 23:38:43 -08:00
"properties" : {
"command" : {
2026-03-06 17:30:17 -08:00
"description" : "Command argv vector. Empty arrays are rejected." ,
2026-02-01 23:38:43 -08:00
"items" : {
"type" : "string"
} ,
"type" : "array"
} ,
"cwd" : {
2026-03-06 17:30:17 -08:00
"description" : "Optional working directory. Defaults to the server cwd." ,
"type" : [
"string" ,
"null"
]
} ,
"disableOutputCap" : {
"description" : "Disable stdout/stderr capture truncation for this request.\n\nCannot be combined with `outputBytesCap`." ,
"type" : "boolean"
} ,
"disableTimeout" : {
"description" : "Disable the timeout entirely for this request.\n\nCannot be combined with `timeoutMs`." ,
"type" : "boolean"
} ,
"env" : {
"additionalProperties" : {
"type" : [
"string" ,
"null"
]
} ,
"description" : "Optional environment overrides merged into the server-computed environment.\n\nMatching names override inherited values. Set a key to `null` to unset an inherited variable." ,
"type" : [
"object" ,
"null"
]
} ,
"outputBytesCap" : {
"description" : "Optional per-stream stdout/stderr capture cap in bytes.\n\nWhen omitted, the server default applies. Cannot be combined with `disableOutputCap`." ,
"format" : "uint" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
} ,
"processId" : {
"description" : "Optional client-supplied, connection-scoped process id.\n\nRequired for `tty`, `streamStdin`, `streamStdoutStderr`, and follow-up `command/exec/write`, `command/exec/resize`, and `command/exec/terminate` calls. When omitted, buffered execution gets an internal id that is not exposed to the client." ,
2026-02-01 23:38:43 -08:00
"type" : [
"string" ,
"null"
]
} ,
"sandboxPolicy" : {
"anyOf" : [
{
"$ref" : "#/definitions/SandboxPolicy"
} ,
{
"type" : "null"
}
2026-03-06 17:30:17 -08:00
] ,
"description" : "Optional sandbox policy for this command.\n\nUses the same shape as thread/turn execution sandbox configuration and defaults to the user's configured policy when omitted."
} ,
"size" : {
"anyOf" : [
{
"$ref" : "#/definitions/CommandExecTerminalSize"
} ,
{
"type" : "null"
}
] ,
"description" : "Optional initial PTY size in character cells. Only valid when `tty` is true."
} ,
"streamStdin" : {
"description" : "Allow follow-up `command/exec/write` requests to write stdin bytes.\n\nRequires a client-supplied `processId`." ,
"type" : "boolean"
} ,
"streamStdoutStderr" : {
"description" : "Stream stdout/stderr via `command/exec/outputDelta` notifications.\n\nStreamed bytes are not duplicated into the final response and require a client-supplied `processId`." ,
"type" : "boolean"
2026-02-01 23:38:43 -08:00
} ,
"timeoutMs" : {
2026-03-06 17:30:17 -08:00
"description" : "Optional timeout in milliseconds.\n\nWhen omitted, the server default applies. Cannot be combined with `disableTimeout`." ,
2026-02-01 23:38:43 -08:00
"format" : "int64" ,
"type" : [
"integer" ,
"null"
]
2026-03-06 17:30:17 -08:00
} ,
"tty" : {
"description" : "Enable PTY mode.\n\nThis implies `streamStdin` and `streamStdoutStderr`." ,
"type" : "boolean"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"command"
] ,
"type" : "object"
} ,
2026-03-06 17:30:17 -08:00
"CommandExecResizeParams" : {
"description" : "Resize a running PTY-backed `command/exec` session." ,
"properties" : {
"processId" : {
"description" : "Client-supplied, connection-scoped `processId` from the original `command/exec` request." ,
"type" : "string"
} ,
"size" : {
"allOf" : [
{
"$ref" : "#/definitions/CommandExecTerminalSize"
}
] ,
"description" : "New PTY size in character cells."
}
} ,
"required" : [
"processId" ,
"size"
] ,
"type" : "object"
} ,
"CommandExecTerminalSize" : {
"description" : "PTY size in character cells for `command/exec` PTY sessions." ,
"properties" : {
"cols" : {
"description" : "Terminal width in character cells." ,
"format" : "uint16" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"rows" : {
"description" : "Terminal height in character cells." ,
"format" : "uint16" ,
"minimum" : 0.0 ,
"type" : "integer"
}
} ,
"required" : [
"cols" ,
"rows"
] ,
"type" : "object"
} ,
"CommandExecTerminateParams" : {
"description" : "Terminate a running `command/exec` session." ,
"properties" : {
"processId" : {
"description" : "Client-supplied, connection-scoped `processId` from the original `command/exec` request." ,
"type" : "string"
}
} ,
"required" : [
"processId"
] ,
"type" : "object"
} ,
"CommandExecWriteParams" : {
"description" : "Write stdin bytes to a running `command/exec` session, close stdin, or both." ,
"properties" : {
"closeStdin" : {
"description" : "Close stdin after writing `deltaBase64`, if present." ,
"type" : "boolean"
} ,
"deltaBase64" : {
"description" : "Optional base64-encoded stdin bytes to write." ,
"type" : [
"string" ,
"null"
]
} ,
"processId" : {
"description" : "Client-supplied, connection-scoped `processId` from the original `command/exec` request." ,
"type" : "string"
}
} ,
"required" : [
"processId"
] ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
"ConfigBatchWriteParams" : {
"properties" : {
"edits" : {
"items" : {
"$ref" : "#/definitions/ConfigEdit"
} ,
"type" : "array"
} ,
"expectedVersion" : {
"type" : [
"string" ,
"null"
]
} ,
"filePath" : {
"description" : "Path to the config file to write; defaults to the user's `config.toml` when omitted." ,
"type" : [
"string" ,
"null"
]
2026-03-08 17:38:01 -07:00
} ,
"reloadUserConfig" : {
"description" : "When true, hot-reload the updated user config into all loaded threads after writing." ,
"type" : "boolean"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"edits"
] ,
"type" : "object"
} ,
"ConfigEdit" : {
"properties" : {
"keyPath" : {
"type" : "string"
} ,
"mergeStrategy" : {
"$ref" : "#/definitions/MergeStrategy"
} ,
"value" : true
} ,
"required" : [
"keyPath" ,
"mergeStrategy" ,
"value"
] ,
"type" : "object"
} ,
"ConfigReadParams" : {
"properties" : {
"cwd" : {
"description" : "Optional working directory to resolve project config layers. If specified, return the effective config as seen from that directory (i.e., including any project layers between `cwd` and the project/repo root)." ,
"type" : [
"string" ,
"null"
]
} ,
"includeLayers" : {
"default" : false ,
"type" : "boolean"
}
} ,
"type" : "object"
} ,
"ConfigValueWriteParams" : {
"properties" : {
"expectedVersion" : {
"type" : [
"string" ,
"null"
]
} ,
"filePath" : {
"description" : "Path to the config file to write; defaults to the user's `config.toml` when omitted." ,
"type" : [
"string" ,
"null"
]
} ,
"keyPath" : {
"type" : "string"
} ,
"mergeStrategy" : {
"$ref" : "#/definitions/MergeStrategy"
} ,
"value" : true
} ,
"required" : [
"keyPath" ,
"mergeStrategy" ,
"value"
] ,
"type" : "object"
} ,
"ContentItem" : {
"oneOf" : [
{
"properties" : {
"text" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"input_text"
] ,
"title" : "InputTextContentItemType" ,
"type" : "string"
}
} ,
"required" : [
"text" ,
"type"
] ,
"title" : "InputTextContentItem" ,
"type" : "object"
} ,
{
"properties" : {
"image_url" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"input_image"
] ,
"title" : "InputImageContentItemType" ,
"type" : "string"
}
} ,
"required" : [
"image_url" ,
"type"
] ,
"title" : "InputImageContentItem" ,
"type" : "object"
} ,
{
"properties" : {
"text" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"output_text"
] ,
"title" : "OutputTextContentItemType" ,
"type" : "string"
}
} ,
"required" : [
"text" ,
"type"
] ,
"title" : "OutputTextContentItem" ,
"type" : "object"
}
]
} ,
"DynamicToolSpec" : {
"properties" : {
2026-03-14 01:58:43 -07:00
"deferLoading" : {
"type" : "boolean"
} ,
2026-02-01 23:38:43 -08:00
"description" : {
"type" : "string"
} ,
"inputSchema" : true ,
"name" : {
"type" : "string"
}
} ,
"required" : [
"description" ,
"inputSchema" ,
"name"
] ,
"type" : "object"
} ,
2026-02-05 12:04:01 -08:00
"ExperimentalFeatureListParams" : {
"properties" : {
"cursor" : {
"description" : "Opaque pagination cursor returned by a previous call." ,
"type" : [
"string" ,
"null"
]
} ,
"limit" : {
"description" : "Optional page size; defaults to a reasonable server-side value." ,
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
}
} ,
"type" : "object"
} ,
2026-02-25 02:11:51 -08:00
"ExternalAgentConfigDetectParams" : {
"properties" : {
"cwds" : {
"description" : "Zero or more working directories to include for repo-scoped detection." ,
"items" : {
"type" : "string"
} ,
"type" : [
"array" ,
"null"
]
} ,
"includeHome" : {
"description" : "If true, include detection under the user's home (~/.claude, ~/.codex, etc.)." ,
"type" : "boolean"
}
} ,
"type" : "object"
} ,
"ExternalAgentConfigImportParams" : {
"properties" : {
"migrationItems" : {
"items" : {
"$ref" : "#/definitions/ExternalAgentConfigMigrationItem"
} ,
"type" : "array"
}
} ,
"required" : [
"migrationItems"
] ,
"type" : "object"
} ,
"ExternalAgentConfigMigrationItem" : {
"properties" : {
"cwd" : {
"description" : "Null or empty means home-scoped migration; non-empty means repo-scoped migration." ,
"type" : [
"string" ,
"null"
]
} ,
"description" : {
"type" : "string"
} ,
"itemType" : {
"$ref" : "#/definitions/ExternalAgentConfigMigrationItemType"
}
} ,
"required" : [
"description" ,
"itemType"
] ,
"type" : "object"
} ,
"ExternalAgentConfigMigrationItemType" : {
"enum" : [
"AGENTS_MD" ,
"CONFIG" ,
"SKILLS" ,
"MCP_SERVER_CONFIG"
] ,
"type" : "string"
} ,
2026-02-01 23:38:43 -08:00
"FeedbackUploadParams" : {
"properties" : {
"classification" : {
"type" : "string"
} ,
2026-02-20 14:26:14 -08:00
"extraLogFiles" : {
"items" : {
"type" : "string"
} ,
"type" : [
"array" ,
"null"
]
} ,
2026-02-01 23:38:43 -08:00
"includeLogs" : {
"type" : "boolean"
} ,
"reason" : {
"type" : [
"string" ,
"null"
]
} ,
"threadId" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"classification" ,
"includeLogs"
] ,
"type" : "object"
} ,
app-server: add v2 filesystem APIs (#14245)
Add a protocol-level filesystem surface to the v2 app-server so Codex
clients can read and write files, inspect directories, and subscribe to
path changes without relying on host-specific helpers.
High-level changes:
- define the new v2 fs/readFile, fs/writeFile, fs/createDirectory,
fs/getMetadata, fs/readDirectory, fs/remove, fs/copy RPCs
- implement the app-server handlers, including absolute-path validation,
base64 file payloads, recursive copy/remove semantics
- document the API, regenerate protocol schemas/types, and add
end-to-end tests for filesystem operations, copy edge cases
Testing plan:
- validate protocol serialization and generated schema output for the
new fs request, response, and notification types
- run app-server integration coverage for file and directory CRUD paths,
metadata/readDirectory responses, copy failure modes, and absolute-path
validation
2026-03-13 14:42:20 -07:00
"FsCopyParams" : {
"description" : "Copy a file or directory tree on the host filesystem." ,
"properties" : {
"destinationPath" : {
"allOf" : [
{
"$ref" : "#/definitions/AbsolutePathBuf"
}
] ,
"description" : "Absolute destination path."
} ,
"recursive" : {
"description" : "Required for directory copies; ignored for file copies." ,
"type" : "boolean"
} ,
"sourcePath" : {
"allOf" : [
{
"$ref" : "#/definitions/AbsolutePathBuf"
}
] ,
"description" : "Absolute source path."
}
} ,
"required" : [
"destinationPath" ,
"sourcePath"
] ,
"type" : "object"
} ,
"FsCreateDirectoryParams" : {
"description" : "Create a directory on the host filesystem." ,
"properties" : {
"path" : {
"allOf" : [
{
"$ref" : "#/definitions/AbsolutePathBuf"
}
] ,
"description" : "Absolute directory path to create."
} ,
"recursive" : {
"description" : "Whether parent directories should also be created. Defaults to `true`." ,
"type" : [
"boolean" ,
"null"
]
}
} ,
"required" : [
"path"
] ,
"type" : "object"
} ,
"FsGetMetadataParams" : {
"description" : "Request metadata for an absolute path." ,
"properties" : {
"path" : {
"allOf" : [
{
"$ref" : "#/definitions/AbsolutePathBuf"
}
] ,
"description" : "Absolute path to inspect."
}
} ,
"required" : [
"path"
] ,
"type" : "object"
} ,
"FsReadDirectoryParams" : {
"description" : "List direct child names for a directory." ,
"properties" : {
"path" : {
"allOf" : [
{
"$ref" : "#/definitions/AbsolutePathBuf"
}
] ,
"description" : "Absolute directory path to read."
}
} ,
"required" : [
"path"
] ,
"type" : "object"
} ,
"FsReadFileParams" : {
"description" : "Read a file from the host filesystem." ,
"properties" : {
"path" : {
"allOf" : [
{
"$ref" : "#/definitions/AbsolutePathBuf"
}
] ,
"description" : "Absolute path to read."
}
} ,
"required" : [
"path"
] ,
"type" : "object"
} ,
"FsRemoveParams" : {
"description" : "Remove a file or directory tree from the host filesystem." ,
"properties" : {
"force" : {
"description" : "Whether missing paths should be ignored. Defaults to `true`." ,
"type" : [
"boolean" ,
"null"
]
} ,
"path" : {
"allOf" : [
{
"$ref" : "#/definitions/AbsolutePathBuf"
}
] ,
"description" : "Absolute path to remove."
} ,
"recursive" : {
"description" : "Whether directory removal should recurse. Defaults to `true`." ,
"type" : [
"boolean" ,
"null"
]
}
} ,
"required" : [
"path"
] ,
"type" : "object"
} ,
"FsWriteFileParams" : {
"description" : "Write a file on the host filesystem." ,
"properties" : {
"dataBase64" : {
"description" : "File contents encoded as base64." ,
"type" : "string"
} ,
"path" : {
"allOf" : [
{
"$ref" : "#/definitions/AbsolutePathBuf"
}
] ,
"description" : "Absolute path to write."
}
} ,
"required" : [
"dataBase64" ,
"path"
] ,
"type" : "object"
} ,
feat(app-server, core): allow text + image content items for dynamic tool outputs (#10567)
Took over the work that @aaronl-openai started here:
https://github.com/openai/codex/pull/10397
Now that app-server clients are able to set up custom tools (called
`dynamic_tools` in app-server), we should expose a way for clients to
pass in not just text, but also image outputs. This is something the
Responses API already supports for function call outputs, where you can
pass in either a string or an array of content outputs (text, image,
file):
https://platform.openai.com/docs/api-reference/responses/create#responses_create-input-input_item_list-item-function_tool_call_output-output-array-input_image
So let's just plumb it through in Codex (with the caveat that we only
support text and image for now). This is implemented end-to-end across
app-server v2 protocol types and core tool handling.
## Breaking API change
NOTE: This introduces a breaking change with dynamic tools, but I think
it's ok since this concept was only recently introduced
(https://github.com/openai/codex/pull/9539) and it's better to get the
API contract correct. I don't think there are any real consumers of this
yet (not even the Codex App).
Old shape:
`{ "output": "dynamic-ok", "success": true }`
New shape:
```
{
"contentItems": [
{ "type": "inputText", "text": "dynamic-ok" },
{ "type": "inputImage", "imageUrl": "data:image/png;base64,AAA" }
]
"success": true
}
```
2026-02-04 16:12:47 -08:00
"FunctionCallOutputBody" : {
"anyOf" : [
{
"type" : "string"
} ,
{
"items" : {
"$ref" : "#/definitions/FunctionCallOutputContentItem"
} ,
"type" : "array"
}
]
} ,
2026-02-01 23:38:43 -08:00
"FunctionCallOutputContentItem" : {
"description" : "Responses API compatible content items that can be returned by a tool call. This is a subset of ContentItem with the types we support as function call outputs." ,
"oneOf" : [
{
"properties" : {
"text" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"input_text"
] ,
"title" : "InputTextFunctionCallOutputContentItemType" ,
"type" : "string"
}
} ,
"required" : [
"text" ,
"type"
] ,
"title" : "InputTextFunctionCallOutputContentItem" ,
"type" : "object"
} ,
{
"properties" : {
2026-03-03 15:56:54 -08:00
"detail" : {
"anyOf" : [
{
"$ref" : "#/definitions/ImageDetail"
} ,
{
"type" : "null"
}
]
} ,
2026-02-01 23:38:43 -08:00
"image_url" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"input_image"
] ,
"title" : "InputImageFunctionCallOutputContentItemType" ,
"type" : "string"
}
} ,
"required" : [
"image_url" ,
"type"
] ,
"title" : "InputImageFunctionCallOutputContentItem" ,
"type" : "object"
}
]
} ,
"FuzzyFileSearchParams" : {
"properties" : {
"cancellationToken" : {
"type" : [
"string" ,
"null"
]
} ,
"query" : {
"type" : "string"
} ,
"roots" : {
"items" : {
"type" : "string"
} ,
"type" : "array"
}
} ,
"required" : [
"query" ,
"roots"
] ,
"type" : "object"
} ,
"GetAccountParams" : {
"properties" : {
"refreshToken" : {
"default" : false ,
"description" : "When `true`, requests a proactive token refresh before returning.\n\nIn managed auth mode this triggers the normal refresh-token flow. In external auth mode this flag is ignored. Clients should refresh tokens themselves and call `account/login/start` with `chatgptAuthTokens`." ,
"type" : "boolean"
}
} ,
"type" : "object"
} ,
"GhostCommit" : {
"description" : "Details of a ghost commit created from a repository state." ,
"properties" : {
"id" : {
"type" : "string"
} ,
"parent" : {
"type" : [
"string" ,
"null"
]
} ,
"preexisting_untracked_dirs" : {
"items" : {
"type" : "string"
} ,
"type" : "array"
} ,
"preexisting_untracked_files" : {
"items" : {
"type" : "string"
} ,
"type" : "array"
}
} ,
"required" : [
"id" ,
"preexisting_untracked_dirs" ,
"preexisting_untracked_files"
] ,
"type" : "object"
} ,
2026-03-03 15:56:54 -08:00
"ImageDetail" : {
"enum" : [
"auto" ,
"low" ,
"high" ,
"original"
] ,
"type" : "string"
} ,
2026-02-02 12:06:50 +01:00
"InitializeCapabilities" : {
"description" : "Client-declared capabilities negotiated during initialize." ,
"properties" : {
"experimentalApi" : {
"default" : false ,
"description" : "Opt into receiving experimental API methods and fields." ,
"type" : "boolean"
2026-02-10 18:04:52 +00:00
} ,
"optOutNotificationMethods" : {
2026-03-11 17:45:20 -07:00
"description" : "Exact notification method names that should be suppressed for this connection (for example `thread/started`)." ,
2026-02-10 18:04:52 +00:00
"items" : {
"type" : "string"
} ,
"type" : [
"array" ,
"null"
]
2026-02-02 12:06:50 +01:00
}
} ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
"InitializeParams" : {
"properties" : {
2026-02-02 12:06:50 +01:00
"capabilities" : {
"anyOf" : [
{
"$ref" : "#/definitions/InitializeCapabilities"
} ,
{
"type" : "null"
}
]
} ,
2026-02-01 23:38:43 -08:00
"clientInfo" : {
"$ref" : "#/definitions/ClientInfo"
}
} ,
"required" : [
"clientInfo"
] ,
"type" : "object"
} ,
2026-02-20 21:36:12 -08:00
"ListMcpServerStatusParams" : {
"properties" : {
"cursor" : {
"description" : "Opaque pagination cursor returned by a previous call." ,
"type" : [
"string" ,
"null"
]
} ,
"limit" : {
"description" : "Optional page size; defaults to a server-defined value." ,
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
}
} ,
"type" : "object"
} ,
"LocalShellAction" : {
2026-02-01 23:38:43 -08:00
"oneOf" : [
{
"properties" : {
2026-02-20 21:36:12 -08:00
"command" : {
"items" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"type" : "array"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"env" : {
"additionalProperties" : {
"type" : "string"
2026-02-01 23:38:43 -08:00
} ,
2026-02-20 21:36:12 -08:00
"type" : [
"object" ,
"null"
]
} ,
"timeout_ms" : {
"format" : "uint64" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
2026-02-01 23:38:43 -08:00
} ,
"type" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"exec"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ExecLocalShellActionType" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
2026-02-20 21:36:12 -08:00
} ,
"user" : {
"type" : [
"string" ,
"null"
]
} ,
"working_directory" : {
"type" : [
"string" ,
"null"
]
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
2026-02-20 21:36:12 -08:00
"command" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
2026-02-20 21:36:12 -08:00
"title" : "ExecLocalShellAction" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
}
]
} ,
"LocalShellStatus" : {
"enum" : [
"completed" ,
"in_progress" ,
"incomplete"
] ,
"type" : "string"
} ,
"LoginAccountParams" : {
"oneOf" : [
{
"properties" : {
"apiKey" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"apiKey"
] ,
"title" : "ApiKeyLoginAccountParamsType" ,
"type" : "string"
}
} ,
"required" : [
"apiKey" ,
"type"
] ,
"title" : "ApiKeyLoginAccountParams" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"chatgpt"
] ,
"title" : "ChatgptLoginAccountParamsType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "ChatgptLoginAccountParams" ,
"type" : "object"
} ,
{
"description" : "[UNSTABLE] FOR OPENAI INTERNAL USE ONLY - DO NOT USE. The access token must contain the same scopes that Codex-managed ChatGPT auth tokens have." ,
"properties" : {
"accessToken" : {
2026-02-09 20:48:58 -08:00
"description" : "Access token (JWT) supplied by the client. This token is used for backend API requests and email extraction." ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
2026-02-09 20:48:58 -08:00
"chatgptAccountId" : {
"description" : "Workspace/account identifier supplied by the client." ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
2026-02-09 20:48:58 -08:00
"chatgptPlanType" : {
"description" : "Optional plan type supplied by the client.\n\nWhen `null`, Codex attempts to derive the plan type from access-token claims. If unavailable, the plan defaults to `unknown`." ,
"type" : [
"string" ,
"null"
]
} ,
2026-02-01 23:38:43 -08:00
"type" : {
"enum" : [
"chatgptAuthTokens"
] ,
"title" : "ChatgptAuthTokensLoginAccountParamsType" ,
"type" : "string"
}
} ,
"required" : [
"accessToken" ,
2026-02-09 20:48:58 -08:00
"chatgptAccountId" ,
2026-02-01 23:38:43 -08:00
"type"
] ,
"title" : "ChatgptAuthTokensLoginAccountParams" ,
"type" : "object"
}
]
} ,
"McpServerOauthLoginParams" : {
"properties" : {
"name" : {
"type" : "string"
} ,
"scopes" : {
"items" : {
"type" : "string"
} ,
"type" : [
"array" ,
"null"
]
} ,
"timeoutSecs" : {
"format" : "int64" ,
"type" : [
"integer" ,
"null"
]
}
} ,
"required" : [
"name"
] ,
"type" : "object"
} ,
"MergeStrategy" : {
"enum" : [
"replace" ,
"upsert"
] ,
"type" : "string"
} ,
2026-02-02 18:52:26 -08:00
"MessagePhase" : {
2026-02-06 18:39:52 -08:00
"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"
] ,
"type" : "string"
} ,
{
"description" : "The assistant's terminal answer text for the current turn." ,
"enum" : [
"final_answer"
] ,
"type" : "string"
}
]
2026-02-02 18:52:26 -08:00
} ,
2026-02-01 23:38:43 -08:00
"ModeKind" : {
"description" : "Initial collaboration mode to use when the TUI starts." ,
"enum" : [
"plan" ,
2026-02-03 09:23:53 -08:00
"default"
2026-02-01 23:38:43 -08:00
] ,
"type" : "string"
} ,
"ModelListParams" : {
"properties" : {
"cursor" : {
"description" : "Opaque pagination cursor returned by a previous call." ,
"type" : [
"string" ,
"null"
]
} ,
2026-02-13 16:26:32 -08:00
"includeHidden" : {
"description" : "When true, include models that are hidden from the default picker list." ,
"type" : [
"boolean" ,
"null"
]
} ,
2026-02-01 23:38:43 -08:00
"limit" : {
"description" : "Optional page size; defaults to a reasonable server-side value." ,
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
}
} ,
"type" : "object"
} ,
"NetworkAccess" : {
"enum" : [
"restricted" ,
"enabled"
] ,
"type" : "string"
} ,
"Personality" : {
"enum" : [
2026-02-04 15:40:33 -08:00
"none" ,
2026-02-01 23:38:43 -08:00
"friendly" ,
"pragmatic"
] ,
"type" : "string"
} ,
2026-03-04 19:08:18 -05:00
"PluginInstallParams" : {
"properties" : {
2026-03-16 21:37:27 -07:00
"forceRemoteSync" : {
"description" : "When true, apply the remote plugin change before the local install flow." ,
"type" : "boolean"
} ,
2026-03-05 21:58:50 -05:00
"marketplacePath" : {
"$ref" : "#/definitions/AbsolutePathBuf"
2026-03-04 19:08:18 -05:00
} ,
"pluginName" : {
"type" : "string"
}
} ,
"required" : [
2026-03-05 21:58:50 -05:00
"marketplacePath" ,
2026-03-04 19:08:18 -05:00
"pluginName"
] ,
"type" : "object"
} ,
2026-03-05 21:58:50 -05:00
"PluginListParams" : {
"properties" : {
"cwds" : {
2026-03-06 19:39:35 -05:00
"description" : "Optional working directories used to discover repo marketplaces. When omitted, only home-scoped marketplaces and the official curated marketplace are considered." ,
2026-03-05 21:58:50 -05:00
"items" : {
"$ref" : "#/definitions/AbsolutePathBuf"
} ,
"type" : [
"array" ,
"null"
]
2026-03-10 13:32:59 -07:00
} ,
"forceRemoteSync" : {
"description" : "When true, reconcile the official curated marketplace against the remote plugin state before listing marketplaces." ,
"type" : "boolean"
2026-03-05 21:58:50 -05:00
}
} ,
"type" : "object"
} ,
2026-03-12 16:52:21 -07:00
"PluginReadParams" : {
"properties" : {
"marketplacePath" : {
"$ref" : "#/definitions/AbsolutePathBuf"
} ,
"pluginName" : {
"type" : "string"
}
} ,
"required" : [
"marketplacePath" ,
"pluginName"
] ,
"type" : "object"
} ,
2026-03-09 12:40:25 -07:00
"PluginUninstallParams" : {
"properties" : {
2026-03-16 21:37:27 -07:00
"forceRemoteSync" : {
"description" : "When true, apply the remote plugin change before the local uninstall flow." ,
"type" : "boolean"
} ,
2026-03-09 12:40:25 -07:00
"pluginId" : {
"type" : "string"
}
} ,
"required" : [
"pluginId"
] ,
"type" : "object"
} ,
2026-02-11 18:31:14 -08:00
"ReadOnlyAccess" : {
"oneOf" : [
{
"properties" : {
"includePlatformDefaults" : {
"default" : true ,
"type" : "boolean"
} ,
"readableRoots" : {
"default" : [ ] ,
"items" : {
"$ref" : "#/definitions/AbsolutePathBuf"
} ,
"type" : "array"
} ,
"type" : {
"enum" : [
"restricted"
] ,
"title" : "RestrictedReadOnlyAccessType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "RestrictedReadOnlyAccess" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"fullAccess"
] ,
"title" : "FullAccessReadOnlyAccessType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "FullAccessReadOnlyAccess" ,
"type" : "object"
}
]
} ,
2026-02-01 23:38:43 -08: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"
} ,
"ReasoningItemContent" : {
"oneOf" : [
{
"properties" : {
"text" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"reasoning_text"
] ,
"title" : "ReasoningTextReasoningItemContentType" ,
"type" : "string"
}
} ,
"required" : [
"text" ,
"type"
] ,
"title" : "ReasoningTextReasoningItemContent" ,
"type" : "object"
} ,
{
"properties" : {
"text" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"text"
] ,
"title" : "TextReasoningItemContentType" ,
"type" : "string"
}
} ,
"required" : [
"text" ,
"type"
] ,
"title" : "TextReasoningItemContent" ,
"type" : "object"
}
]
} ,
"ReasoningItemReasoningSummary" : {
"oneOf" : [
{
"properties" : {
"text" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"summary_text"
] ,
"title" : "SummaryTextReasoningItemReasoningSummaryType" ,
"type" : "string"
}
} ,
"required" : [
"text" ,
"type"
] ,
"title" : "SummaryTextReasoningItemReasoningSummary" ,
"type" : "object"
}
]
} ,
"ReasoningSummary" : {
"description" : "A summary of the reasoning performed by the model. This can be useful for debugging and understanding the model's reasoning process. See https://platform.openai.com/docs/guides/reasoning?api-mode=responses#reasoning-summaries" ,
"oneOf" : [
{
"enum" : [
"auto" ,
"concise" ,
"detailed"
] ,
"type" : "string"
} ,
{
"description" : "Option to disable reasoning summaries." ,
"enum" : [
"none"
] ,
"type" : "string"
}
]
} ,
"RequestId" : {
"anyOf" : [
{
"type" : "string"
} ,
{
"format" : "int64" ,
"type" : "integer"
}
]
} ,
"ResponseItem" : {
"oneOf" : [
{
"properties" : {
"content" : {
"items" : {
"$ref" : "#/definitions/ContentItem"
} ,
"type" : "array"
} ,
"end_turn" : {
"type" : [
"boolean" ,
"null"
]
} ,
"id" : {
"type" : [
"string" ,
"null"
] ,
"writeOnly" : true
} ,
2026-02-02 18:52:26 -08:00
"phase" : {
"anyOf" : [
{
"$ref" : "#/definitions/MessagePhase"
} ,
{
"type" : "null"
}
]
} ,
2026-02-01 23:38:43 -08:00
"role" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"message"
] ,
"title" : "MessageResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"content" ,
"role" ,
"type"
] ,
"title" : "MessageResponseItem" ,
"type" : "object"
} ,
{
"properties" : {
"content" : {
"default" : null ,
"items" : {
"$ref" : "#/definitions/ReasoningItemContent"
} ,
"type" : [
"array" ,
"null"
]
} ,
"encrypted_content" : {
"type" : [
"string" ,
"null"
]
} ,
"summary" : {
"items" : {
"$ref" : "#/definitions/ReasoningItemReasoningSummary"
} ,
"type" : "array"
} ,
"type" : {
"enum" : [
"reasoning"
] ,
"title" : "ReasoningResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"summary" ,
"type"
] ,
"title" : "ReasoningResponseItem" ,
"type" : "object"
} ,
{
"properties" : {
"action" : {
"$ref" : "#/definitions/LocalShellAction"
} ,
"call_id" : {
"description" : "Set when using the Responses API." ,
"type" : [
"string" ,
"null"
]
} ,
"id" : {
2026-02-03 11:31:57 +00:00
"description" : "Legacy id field retained for compatibility with older payloads." ,
2026-02-01 23:38:43 -08:00
"type" : [
"string" ,
"null"
] ,
"writeOnly" : true
} ,
"status" : {
"$ref" : "#/definitions/LocalShellStatus"
} ,
"type" : {
"enum" : [
"local_shell_call"
] ,
"title" : "LocalShellCallResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"action" ,
"status" ,
"type"
] ,
"title" : "LocalShellCallResponseItem" ,
"type" : "object"
} ,
{
"properties" : {
"arguments" : {
"type" : "string"
} ,
"call_id" : {
"type" : "string"
} ,
"id" : {
"type" : [
"string" ,
"null"
] ,
"writeOnly" : true
} ,
"name" : {
"type" : "string"
} ,
2026-03-11 17:51:51 -07:00
"namespace" : {
"type" : [
"string" ,
"null"
]
} ,
2026-02-01 23:38:43 -08:00
"type" : {
"enum" : [
"function_call"
] ,
"title" : "FunctionCallResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"arguments" ,
"call_id" ,
"name" ,
"type"
] ,
"title" : "FunctionCallResponseItem" ,
"type" : "object"
} ,
2026-03-11 17:51:51 -07:00
{
"properties" : {
"arguments" : true ,
"call_id" : {
"type" : [
"string" ,
"null"
]
} ,
"execution" : {
"type" : "string"
} ,
"id" : {
"type" : [
"string" ,
"null"
] ,
"writeOnly" : true
} ,
"status" : {
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"tool_search_call"
] ,
"title" : "ToolSearchCallResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"arguments" ,
"execution" ,
"type"
] ,
"title" : "ToolSearchCallResponseItem" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"call_id" : {
"type" : "string"
} ,
"output" : {
2026-03-17 11:19:42 -07:00
"$ref" : "#/definitions/FunctionCallOutputBody"
2026-02-01 23:38:43 -08:00
} ,
"type" : {
"enum" : [
"function_call_output"
] ,
"title" : "FunctionCallOutputResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"call_id" ,
"output" ,
"type"
] ,
"title" : "FunctionCallOutputResponseItem" ,
"type" : "object"
} ,
{
"properties" : {
"call_id" : {
"type" : "string"
} ,
"id" : {
"type" : [
"string" ,
"null"
] ,
"writeOnly" : true
} ,
"input" : {
"type" : "string"
} ,
"name" : {
"type" : "string"
} ,
"status" : {
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"custom_tool_call"
] ,
"title" : "CustomToolCallResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"call_id" ,
"input" ,
"name" ,
"type"
] ,
"title" : "CustomToolCallResponseItem" ,
"type" : "object"
} ,
{
"properties" : {
"call_id" : {
"type" : "string"
} ,
2026-03-18 09:37:13 -07:00
"name" : {
"type" : [
"string" ,
"null"
]
} ,
2026-02-01 23:38:43 -08:00
"output" : {
2026-03-17 11:19:42 -07:00
"$ref" : "#/definitions/FunctionCallOutputBody"
2026-02-01 23:38:43 -08:00
} ,
"type" : {
"enum" : [
"custom_tool_call_output"
] ,
"title" : "CustomToolCallOutputResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"call_id" ,
"output" ,
"type"
] ,
"title" : "CustomToolCallOutputResponseItem" ,
"type" : "object"
} ,
2026-03-11 17:51:51 -07:00
{
"properties" : {
"call_id" : {
"type" : [
"string" ,
"null"
]
} ,
"execution" : {
"type" : "string"
} ,
"status" : {
"type" : "string"
} ,
"tools" : {
"items" : true ,
"type" : "array"
} ,
"type" : {
"enum" : [
"tool_search_output"
] ,
"title" : "ToolSearchOutputResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"execution" ,
"status" ,
"tools" ,
"type"
] ,
"title" : "ToolSearchOutputResponseItem" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"action" : {
"anyOf" : [
{
2026-03-06 17:33:46 -08:00
"$ref" : "#/definitions/ResponsesApiWebSearchAction"
2026-02-01 23:38:43 -08:00
} ,
{
"type" : "null"
}
]
} ,
"id" : {
"type" : [
"string" ,
"null"
] ,
"writeOnly" : true
} ,
"status" : {
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"web_search_call"
] ,
"title" : "WebSearchCallResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "WebSearchCallResponseItem" ,
"type" : "object"
} ,
2026-03-03 23:11:28 -08:00
{
"properties" : {
"id" : {
"type" : "string"
} ,
"result" : {
"type" : "string"
} ,
"revised_prompt" : {
"type" : [
"string" ,
"null"
]
} ,
"status" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"image_generation_call"
] ,
"title" : "ImageGenerationCallResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"id" ,
"result" ,
"status" ,
"type"
] ,
"title" : "ImageGenerationCallResponseItem" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"ghost_commit" : {
"$ref" : "#/definitions/GhostCommit"
} ,
"type" : {
"enum" : [
"ghost_snapshot"
] ,
"title" : "GhostSnapshotResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"ghost_commit" ,
"type"
] ,
"title" : "GhostSnapshotResponseItem" ,
"type" : "object"
} ,
{
"properties" : {
"encrypted_content" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"compaction"
] ,
"title" : "CompactionResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"encrypted_content" ,
"type"
] ,
"title" : "CompactionResponseItem" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"other"
] ,
"title" : "OtherResponseItemType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "OtherResponseItem" ,
"type" : "object"
}
]
} ,
2026-03-06 17:33:46 -08:00
"ResponsesApiWebSearchAction" : {
"oneOf" : [
{
"properties" : {
"queries" : {
"items" : {
"type" : "string"
} ,
"type" : [
"array" ,
"null"
]
} ,
"query" : {
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"search"
] ,
"title" : "SearchResponsesApiWebSearchActionType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "SearchResponsesApiWebSearchAction" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"open_page"
] ,
"title" : "OpenPageResponsesApiWebSearchActionType" ,
"type" : "string"
} ,
"url" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"type"
] ,
"title" : "OpenPageResponsesApiWebSearchAction" ,
"type" : "object"
} ,
{
"properties" : {
"pattern" : {
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"find_in_page"
] ,
"title" : "FindInPageResponsesApiWebSearchActionType" ,
"type" : "string"
} ,
"url" : {
"type" : [
"string" ,
"null"
]
}
} ,
"required" : [
"type"
] ,
"title" : "FindInPageResponsesApiWebSearchAction" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"other"
] ,
"title" : "OtherResponsesApiWebSearchActionType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "OtherResponsesApiWebSearchAction" ,
"type" : "object"
}
]
} ,
2026-02-01 23:38:43 -08:00
"ReviewDelivery" : {
"enum" : [
"inline" ,
"detached"
] ,
"type" : "string"
} ,
"ReviewStartParams" : {
"properties" : {
"delivery" : {
"anyOf" : [
{
"$ref" : "#/definitions/ReviewDelivery"
} ,
{
"type" : "null"
}
] ,
"default" : null ,
"description" : "Where to run the review: inline (default) on the current thread or detached on a new thread (returned in `reviewThreadId`)."
} ,
"target" : {
"$ref" : "#/definitions/ReviewTarget"
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"target" ,
"threadId"
] ,
"type" : "object"
} ,
"ReviewTarget" : {
"oneOf" : [
{
"description" : "Review the working tree: staged, unstaged, and untracked files." ,
"properties" : {
"type" : {
"enum" : [
"uncommittedChanges"
] ,
"title" : "UncommittedChangesReviewTargetType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "UncommittedChangesReviewTarget" ,
"type" : "object"
} ,
{
"description" : "Review changes between the current branch and the given base branch." ,
"properties" : {
"branch" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"baseBranch"
] ,
"title" : "BaseBranchReviewTargetType" ,
"type" : "string"
}
} ,
"required" : [
"branch" ,
"type"
] ,
"title" : "BaseBranchReviewTarget" ,
"type" : "object"
} ,
{
"description" : "Review the changes introduced by a specific commit." ,
"properties" : {
"sha" : {
"type" : "string"
} ,
"title" : {
"description" : "Optional human-readable label (e.g., commit subject) for UIs." ,
"type" : [
"string" ,
"null"
]
} ,
"type" : {
"enum" : [
"commit"
] ,
"title" : "CommitReviewTargetType" ,
"type" : "string"
}
} ,
"required" : [
"sha" ,
"type"
] ,
"title" : "CommitReviewTarget" ,
"type" : "object"
} ,
{
"description" : "Arbitrary instructions, equivalent to the old free-form prompt." ,
"properties" : {
"instructions" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"custom"
] ,
"title" : "CustomReviewTargetType" ,
"type" : "string"
}
} ,
"required" : [
"instructions" ,
"type"
] ,
"title" : "CustomReviewTarget" ,
"type" : "object"
}
]
} ,
"SandboxMode" : {
"enum" : [
"read-only" ,
"workspace-write" ,
"danger-full-access"
] ,
"type" : "string"
} ,
"SandboxPolicy" : {
"oneOf" : [
{
"properties" : {
"type" : {
"enum" : [
"dangerFullAccess"
] ,
"title" : "DangerFullAccessSandboxPolicyType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "DangerFullAccessSandboxPolicy" ,
"type" : "object"
} ,
{
"properties" : {
2026-02-11 18:31:14 -08:00
"access" : {
"allOf" : [
{
"$ref" : "#/definitions/ReadOnlyAccess"
}
] ,
"default" : {
"type" : "fullAccess"
}
} ,
2026-03-03 18:41:57 -08:00
"networkAccess" : {
"default" : false ,
"type" : "boolean"
} ,
2026-02-01 23:38:43 -08:00
"type" : {
"enum" : [
"readOnly"
] ,
"title" : "ReadOnlySandboxPolicyType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "ReadOnlySandboxPolicy" ,
"type" : "object"
} ,
{
"properties" : {
"networkAccess" : {
"allOf" : [
{
"$ref" : "#/definitions/NetworkAccess"
}
] ,
"default" : "restricted"
} ,
"type" : {
"enum" : [
"externalSandbox"
] ,
"title" : "ExternalSandboxSandboxPolicyType" ,
"type" : "string"
}
} ,
"required" : [
"type"
] ,
"title" : "ExternalSandboxSandboxPolicy" ,
"type" : "object"
} ,
{
"properties" : {
"excludeSlashTmp" : {
"default" : false ,
"type" : "boolean"
} ,
"excludeTmpdirEnvVar" : {
"default" : false ,
"type" : "boolean"
} ,
"networkAccess" : {
"default" : false ,
"type" : "boolean"
} ,
2026-02-11 18:31:14 -08:00
"readOnlyAccess" : {
"allOf" : [
{
"$ref" : "#/definitions/ReadOnlyAccess"
}
] ,
"default" : {
"type" : "fullAccess"
}
} ,
2026-02-01 23:38:43 -08:00
"type" : {
"enum" : [
"workspaceWrite"
] ,
"title" : "WorkspaceWriteSandboxPolicyType" ,
"type" : "string"
} ,
"writableRoots" : {
"default" : [ ] ,
"items" : {
"$ref" : "#/definitions/AbsolutePathBuf"
} ,
"type" : "array"
}
} ,
"required" : [
"type"
] ,
"title" : "WorkspaceWriteSandboxPolicy" ,
"type" : "object"
}
]
} ,
2026-03-03 02:35:09 -08:00
"ServiceTier" : {
"enum" : [
2026-03-03 22:46:05 -08:00
"fast" ,
"flex"
2026-03-03 02:35:09 -08:00
] ,
"type" : "string"
} ,
2026-02-01 23:38:43 -08:00
"Settings" : {
"description" : "Settings for a collaboration mode." ,
"properties" : {
"developer_instructions" : {
"type" : [
"string" ,
"null"
]
} ,
"model" : {
"type" : "string"
} ,
"reasoning_effort" : {
"anyOf" : [
{
"$ref" : "#/definitions/ReasoningEffort"
} ,
{
"type" : "null"
}
]
}
} ,
"required" : [
"model"
] ,
"type" : "object"
} ,
"SkillsConfigWriteParams" : {
"properties" : {
"enabled" : {
"type" : "boolean"
} ,
"path" : {
"type" : "string"
}
} ,
"required" : [
"enabled" ,
"path"
] ,
"type" : "object"
} ,
2026-02-09 13:30:38 -08:00
"SkillsListExtraRootsForCwd" : {
"properties" : {
"cwd" : {
"type" : "string"
} ,
"extraUserRoots" : {
"items" : {
"type" : "string"
} ,
"type" : "array"
}
} ,
"required" : [
"cwd" ,
"extraUserRoots"
] ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
"SkillsListParams" : {
"properties" : {
"cwds" : {
"description" : "When empty, defaults to the current session working directory." ,
"items" : {
"type" : "string"
} ,
"type" : "array"
} ,
"forceReload" : {
"description" : "When true, bypass the skills cache and re-scan skills from disk." ,
"type" : "boolean"
2026-02-09 13:30:38 -08:00
} ,
"perCwdExtraUserRoots" : {
"default" : null ,
"description" : "Optional per-cwd extra roots to scan as user-scoped skills." ,
"items" : {
"$ref" : "#/definitions/SkillsListExtraRootsForCwd"
} ,
"type" : [
"array" ,
"null"
]
2026-02-01 23:38:43 -08:00
}
} ,
"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"
} ,
"ThreadArchiveParams" : {
"properties" : {
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
2026-02-03 18:15:55 -08:00
"ThreadCompactStartParams" : {
"properties" : {
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
"ThreadForkParams" : {
"description" : "There are two ways to fork a thread: 1. By thread_id: load the thread from disk by thread_id and fork it into a new thread. 2. By path: load the thread from disk by path and fork it into a new thread.\n\nIf using path, the thread_id param will be ignored.\n\nPrefer using thread_id whenever possible." ,
"properties" : {
"approvalPolicy" : {
"anyOf" : [
{
"$ref" : "#/definitions/AskForApproval"
} ,
{
"type" : "null"
}
]
} ,
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
"approvalsReviewer" : {
"anyOf" : [
{
"$ref" : "#/definitions/ApprovalsReviewer"
} ,
{
"type" : "null"
}
] ,
"description" : "Override where approval requests are routed for review on this thread and subsequent turns."
} ,
2026-02-01 23:38:43 -08:00
"baseInstructions" : {
"type" : [
"string" ,
"null"
]
} ,
"config" : {
"additionalProperties" : true ,
"type" : [
"object" ,
"null"
]
} ,
"cwd" : {
"type" : [
"string" ,
"null"
]
} ,
"developerInstructions" : {
"type" : [
"string" ,
"null"
]
} ,
2026-03-10 16:34:27 -07:00
"ephemeral" : {
"type" : "boolean"
} ,
2026-02-01 23:38:43 -08:00
"model" : {
"description" : "Configuration overrides for the forked thread, if any." ,
"type" : [
"string" ,
"null"
]
} ,
"modelProvider" : {
"type" : [
"string" ,
"null"
]
} ,
"sandbox" : {
"anyOf" : [
{
"$ref" : "#/definitions/SandboxMode"
} ,
{
"type" : "null"
}
]
} ,
2026-03-03 02:35:09 -08:00
"serviceTier" : {
"anyOf" : [
{
"anyOf" : [
{
"$ref" : "#/definitions/ServiceTier"
} ,
{
"type" : "null"
}
]
} ,
{
"type" : "null"
}
]
} ,
2026-02-01 23:38:43 -08:00
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
"ThreadListParams" : {
"properties" : {
"archived" : {
"description" : "Optional archived filter; when set to true, only archived threads are returned. If false or null, only non-archived threads are returned." ,
"type" : [
"boolean" ,
"null"
]
} ,
"cursor" : {
"description" : "Opaque pagination cursor returned by a previous call." ,
"type" : [
"string" ,
"null"
]
} ,
2026-02-12 21:05:04 -05:00
"cwd" : {
"description" : "Optional cwd filter; when set, only threads whose session cwd exactly matches this path are returned." ,
"type" : [
"string" ,
"null"
]
} ,
2026-02-01 23:38:43 -08:00
"limit" : {
"description" : "Optional page size; defaults to a reasonable server-side value." ,
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
} ,
"modelProviders" : {
"description" : "Optional provider filter; when set, only sessions recorded under these providers are returned. When present but empty, includes all providers." ,
"items" : {
"type" : "string"
} ,
"type" : [
"array" ,
"null"
]
} ,
2026-02-25 09:59:41 +00:00
"searchTerm" : {
"description" : "Optional substring filter for the extracted thread title." ,
"type" : [
"string" ,
"null"
]
} ,
2026-02-01 23:38:43 -08:00
"sortKey" : {
"anyOf" : [
{
"$ref" : "#/definitions/ThreadSortKey"
} ,
{
"type" : "null"
}
] ,
"description" : "Optional sort key; defaults to created_at."
} ,
"sourceKinds" : {
"description" : "Optional source filter; when set, only sessions from these source kinds are returned. When omitted or empty, defaults to interactive sources." ,
"items" : {
"$ref" : "#/definitions/ThreadSourceKind"
} ,
"type" : [
"array" ,
"null"
]
}
} ,
"type" : "object"
} ,
"ThreadLoadedListParams" : {
"properties" : {
"cursor" : {
"description" : "Opaque pagination cursor returned by a previous call." ,
"type" : [
"string" ,
"null"
]
} ,
"limit" : {
"description" : "Optional page size; defaults to no limit." ,
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : [
"integer" ,
"null"
]
}
} ,
"type" : "object"
} ,
2026-03-03 15:56:11 -08:00
"ThreadMetadataGitInfoUpdateParams" : {
"properties" : {
"branch" : {
"description" : "Omit to leave the stored branch unchanged, set to `null` to clear it, or provide a non-empty string to replace it." ,
"type" : [
"string" ,
"null"
]
} ,
"originUrl" : {
"description" : "Omit to leave the stored origin URL unchanged, set to `null` to clear it, or provide a non-empty string to replace it." ,
"type" : [
"string" ,
"null"
]
} ,
"sha" : {
"description" : "Omit to leave the stored commit unchanged, set to `null` to clear it, or provide a non-empty string to replace it." ,
"type" : [
"string" ,
"null"
]
}
} ,
"type" : "object"
} ,
"ThreadMetadataUpdateParams" : {
"properties" : {
"gitInfo" : {
"anyOf" : [
{
"$ref" : "#/definitions/ThreadMetadataGitInfoUpdateParams"
} ,
{
"type" : "null"
}
] ,
"description" : "Patch the stored Git metadata for this thread. Omit a field to leave it unchanged, set it to `null` to clear it, or provide a string to replace the stored value."
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
"ThreadReadParams" : {
"properties" : {
"includeTurns" : {
"default" : false ,
"description" : "When true, include turns and their items from rollout history." ,
"type" : "boolean"
} ,
"threadId" : {
"type" : "string"
}
} ,
"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"
} ,
2026-02-01 23:38:43 -08:00
"ThreadResumeParams" : {
"description" : "There are three ways to resume a thread: 1. By thread_id: load the thread from disk by thread_id and resume it. 2. By history: instantiate the thread from memory and resume it. 3. By path: load the thread from disk by path and resume it.\n\nThe precedence is: history > path > thread_id. If using history or path, the thread_id param will be ignored.\n\nPrefer using thread_id whenever possible." ,
"properties" : {
"approvalPolicy" : {
"anyOf" : [
{
"$ref" : "#/definitions/AskForApproval"
} ,
{
"type" : "null"
}
]
} ,
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
"approvalsReviewer" : {
"anyOf" : [
{
"$ref" : "#/definitions/ApprovalsReviewer"
} ,
{
"type" : "null"
}
] ,
"description" : "Override where approval requests are routed for review on this thread and subsequent turns."
} ,
2026-02-01 23:38:43 -08:00
"baseInstructions" : {
"type" : [
"string" ,
"null"
]
} ,
"config" : {
"additionalProperties" : true ,
"type" : [
"object" ,
"null"
]
} ,
"cwd" : {
"type" : [
"string" ,
"null"
]
} ,
"developerInstructions" : {
"type" : [
"string" ,
"null"
]
} ,
"model" : {
"description" : "Configuration overrides for the resumed thread, if any." ,
"type" : [
"string" ,
"null"
]
} ,
"modelProvider" : {
"type" : [
"string" ,
"null"
]
} ,
"personality" : {
"anyOf" : [
{
"$ref" : "#/definitions/Personality"
} ,
{
"type" : "null"
}
]
} ,
"sandbox" : {
"anyOf" : [
{
"$ref" : "#/definitions/SandboxMode"
} ,
{
"type" : "null"
}
]
} ,
2026-03-03 02:35:09 -08:00
"serviceTier" : {
"anyOf" : [
{
"anyOf" : [
{
"$ref" : "#/definitions/ServiceTier"
} ,
{
"type" : "null"
}
]
} ,
{
"type" : "null"
}
]
} ,
2026-02-01 23:38:43 -08:00
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
"ThreadRollbackParams" : {
"properties" : {
"numTurns" : {
"description" : "The number of turns to drop from the end of the thread. Must be >= 1.\n\nThis only modifies the thread's history and does not revert local file changes that have been made by the agent. Clients are responsible for reverting these changes." ,
"format" : "uint32" ,
"minimum" : 0.0 ,
"type" : "integer"
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"numTurns" ,
"threadId"
] ,
"type" : "object"
} ,
"ThreadSetNameParams" : {
"properties" : {
"name" : {
"type" : "string"
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"name" ,
"threadId"
] ,
"type" : "object"
} ,
2026-03-18 23:42:40 -06:00
"ThreadShellCommandParams" : {
"properties" : {
"command" : {
"description" : "Shell command string evaluated by the thread's configured shell. Unlike `command/exec`, this intentionally preserves shell syntax such as pipes, redirects, and quoting. This runs unsandboxed with full access rather than inheriting the thread sandbox policy." ,
"type" : "string"
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"command" ,
"threadId"
] ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
"ThreadSortKey" : {
"enum" : [
"created_at" ,
"updated_at"
] ,
"type" : "string"
} ,
"ThreadSourceKind" : {
"enum" : [
"cli" ,
"vscode" ,
"exec" ,
"appServer" ,
"subAgent" ,
"subAgentReview" ,
"subAgentCompact" ,
"subAgentThreadSpawn" ,
"subAgentOther" ,
"unknown"
] ,
"type" : "string"
} ,
"ThreadStartParams" : {
"properties" : {
"approvalPolicy" : {
"anyOf" : [
{
"$ref" : "#/definitions/AskForApproval"
} ,
{
"type" : "null"
}
]
} ,
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
"approvalsReviewer" : {
"anyOf" : [
{
"$ref" : "#/definitions/ApprovalsReviewer"
} ,
{
"type" : "null"
}
] ,
"description" : "Override where approval requests are routed for review on this thread and subsequent turns."
} ,
2026-02-01 23:38:43 -08:00
"baseInstructions" : {
"type" : [
"string" ,
"null"
]
} ,
"config" : {
"additionalProperties" : true ,
"type" : [
"object" ,
"null"
]
} ,
"cwd" : {
"type" : [
"string" ,
"null"
]
} ,
"developerInstructions" : {
"type" : [
"string" ,
"null"
]
} ,
"ephemeral" : {
"type" : [
"boolean" ,
"null"
]
} ,
"model" : {
"type" : [
"string" ,
"null"
]
} ,
"modelProvider" : {
"type" : [
"string" ,
"null"
]
} ,
"personality" : {
"anyOf" : [
{
"$ref" : "#/definitions/Personality"
} ,
{
"type" : "null"
}
]
} ,
"sandbox" : {
"anyOf" : [
{
"$ref" : "#/definitions/SandboxMode"
} ,
{
"type" : "null"
}
]
2026-02-25 09:51:42 +00:00
} ,
"serviceName" : {
"type" : [
"string" ,
"null"
]
2026-03-03 02:35:09 -08:00
} ,
"serviceTier" : {
"anyOf" : [
{
"anyOf" : [
{
"$ref" : "#/definitions/ServiceTier"
} ,
{
"type" : "null"
}
]
} ,
{
"type" : "null"
}
]
2026-02-01 23:38:43 -08:00
}
} ,
"type" : "object"
} ,
"ThreadUnarchiveParams" : {
"properties" : {
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
2026-02-25 13:14:30 -08:00
"ThreadUnsubscribeParams" : {
"properties" : {
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"threadId"
] ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
"TurnInterruptParams" : {
"properties" : {
"threadId" : {
"type" : "string"
} ,
"turnId" : {
"type" : "string"
}
} ,
"required" : [
"threadId" ,
"turnId"
] ,
"type" : "object"
} ,
"TurnStartParams" : {
"properties" : {
"approvalPolicy" : {
"anyOf" : [
{
"$ref" : "#/definitions/AskForApproval"
} ,
{
"type" : "null"
}
] ,
"description" : "Override the approval policy for this turn and subsequent turns."
} ,
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
"approvalsReviewer" : {
"anyOf" : [
{
"$ref" : "#/definitions/ApprovalsReviewer"
} ,
{
"type" : "null"
}
] ,
"description" : "Override where approval requests are routed for review on this turn and subsequent turns."
} ,
2026-02-01 23:38:43 -08:00
"cwd" : {
"description" : "Override the working directory for this turn and subsequent turns." ,
"type" : [
"string" ,
"null"
]
} ,
"effort" : {
"anyOf" : [
{
"$ref" : "#/definitions/ReasoningEffort"
} ,
{
"type" : "null"
}
] ,
"description" : "Override the reasoning effort for this turn and subsequent turns."
} ,
"input" : {
"items" : {
"$ref" : "#/definitions/UserInput"
} ,
"type" : "array"
} ,
"model" : {
"description" : "Override the model for this turn and subsequent turns." ,
"type" : [
"string" ,
"null"
]
} ,
"outputSchema" : {
"description" : "Optional JSON Schema used to constrain the final assistant message for this turn."
} ,
"personality" : {
"anyOf" : [
{
"$ref" : "#/definitions/Personality"
} ,
{
"type" : "null"
}
] ,
"description" : "Override the personality for this turn and subsequent turns."
} ,
"sandboxPolicy" : {
"anyOf" : [
{
"$ref" : "#/definitions/SandboxPolicy"
} ,
{
"type" : "null"
}
] ,
"description" : "Override the sandbox policy for this turn and subsequent turns."
} ,
2026-03-03 02:35:09 -08:00
"serviceTier" : {
"anyOf" : [
{
"anyOf" : [
{
"$ref" : "#/definitions/ServiceTier"
} ,
{
"type" : "null"
}
]
} ,
{
"type" : "null"
}
] ,
"description" : "Override the service tier for this turn and subsequent turns."
} ,
2026-02-01 23:38:43 -08:00
"summary" : {
"anyOf" : [
{
"$ref" : "#/definitions/ReasoningSummary"
} ,
{
"type" : "null"
}
] ,
"description" : "Override the reasoning summary for this turn and subsequent turns."
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"input" ,
"threadId"
] ,
"type" : "object"
} ,
2026-02-05 16:35:04 -08:00
"TurnSteerParams" : {
"properties" : {
"expectedTurnId" : {
"description" : "Required active turn id precondition. The request fails when it does not match the currently active turn." ,
"type" : "string"
} ,
"input" : {
"items" : {
"$ref" : "#/definitions/UserInput"
} ,
"type" : "array"
} ,
"threadId" : {
"type" : "string"
}
} ,
"required" : [
"expectedTurnId" ,
"input" ,
"threadId"
] ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
"UserInput" : {
"oneOf" : [
{
"properties" : {
"text" : {
"type" : "string"
} ,
"text_elements" : {
"default" : [ ] ,
"description" : "UI-defined spans within `text` used to render or persist special elements." ,
"items" : {
"$ref" : "#/definitions/TextElement"
} ,
"type" : "array"
} ,
"type" : {
"enum" : [
"text"
] ,
"title" : "TextUserInputType" ,
"type" : "string"
}
} ,
"required" : [
"text" ,
"type"
] ,
"title" : "TextUserInput" ,
"type" : "object"
} ,
{
"properties" : {
"type" : {
"enum" : [
"image"
] ,
"title" : "ImageUserInputType" ,
"type" : "string"
} ,
"url" : {
"type" : "string"
}
} ,
"required" : [
"type" ,
"url"
] ,
"title" : "ImageUserInput" ,
"type" : "object"
} ,
{
"properties" : {
"path" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"localImage"
] ,
"title" : "LocalImageUserInputType" ,
"type" : "string"
}
} ,
"required" : [
"path" ,
"type"
] ,
"title" : "LocalImageUserInput" ,
"type" : "object"
} ,
{
"properties" : {
"name" : {
"type" : "string"
} ,
"path" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"skill"
] ,
"title" : "SkillUserInputType" ,
"type" : "string"
}
} ,
"required" : [
"name" ,
"path" ,
"type"
] ,
"title" : "SkillUserInput" ,
"type" : "object"
} ,
{
"properties" : {
"name" : {
"type" : "string"
} ,
"path" : {
"type" : "string"
} ,
"type" : {
"enum" : [
"mention"
] ,
"title" : "MentionUserInputType" ,
"type" : "string"
}
} ,
"required" : [
"name" ,
"path" ,
"type"
] ,
"title" : "MentionUserInput" ,
"type" : "object"
}
]
} ,
2026-02-18 13:03:16 -08:00
"WindowsSandboxSetupMode" : {
"enum" : [
"elevated" ,
"unelevated"
] ,
"type" : "string"
} ,
"WindowsSandboxSetupStartParams" : {
"properties" : {
2026-03-04 10:54:30 -08:00
"cwd" : {
2026-03-06 22:47:08 -08:00
"anyOf" : [
{
"$ref" : "#/definitions/AbsolutePathBuf"
} ,
{
"type" : "null"
}
2026-03-04 10:54:30 -08:00
]
} ,
2026-02-18 13:03:16 -08:00
"mode" : {
"$ref" : "#/definitions/WindowsSandboxSetupMode"
}
} ,
"required" : [
"mode"
] ,
"type" : "object"
2026-02-01 23:38:43 -08:00
}
} ,
"description" : "Request from the client to the server." ,
"oneOf" : [
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"initialize"
2026-02-05 12:04:01 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "InitializeRequestMethod" ,
2026-02-05 12:04:01 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/InitializeParams"
2026-02-05 12:04:01 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "InitializeRequest" ,
2026-02-05 12:04:01 -08:00
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
2026-02-20 21:36:12 -08:00
"description" : "NEW APIs" ,
2026-02-01 23:38:43 -08:00
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/start"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/startRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadStartParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/startRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/resume"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/resumeRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadResumeParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"method" ,
"params"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/resumeRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/fork"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/forkRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadForkParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/forkRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
2026-02-18 13:03:16 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/archive"
2026-02-18 13:03:16 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/archiveRequestMethod" ,
2026-02-18 13:03:16 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadArchiveParams"
2026-02-18 13:03:16 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/archiveRequest" ,
2026-02-18 13:03:16 -08:00
"type" : "object"
} ,
2026-02-25 13:14:30 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"thread/unsubscribe"
] ,
"title" : "Thread/unsubscribeRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadUnsubscribeParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Thread/unsubscribeRequest" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/name/set"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/name/setRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadSetNameParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/name/setRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
2026-03-03 15:56:11 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"thread/metadata/update"
] ,
"title" : "Thread/metadata/updateRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadMetadataUpdateParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Thread/metadata/updateRequest" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/unarchive"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/unarchiveRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadUnarchiveParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/unarchiveRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/compact/start"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/compact/startRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadCompactStartParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"method" ,
"params"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/compact/startRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
2026-03-18 23:42:40 -06:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"thread/shellCommand"
] ,
"title" : "Thread/shellCommandRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ThreadShellCommandParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Thread/shellCommandRequest" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/rollback"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/rollbackRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadRollbackParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"method" ,
"params"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/rollbackRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/list"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/listRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadListParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/listRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/loaded/list"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/loaded/listRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadLoadedListParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/loaded/listRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"thread/read"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/readRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ThreadReadParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Thread/readRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"skills/list"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Skills/listRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/SkillsListParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Skills/listRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
2026-03-05 21:58:50 -05:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"plugin/list"
] ,
"title" : "Plugin/listRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/PluginListParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Plugin/listRequest" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
2026-03-12 16:52:21 -07:00
} ,
"method" : {
"enum" : [
"plugin/read"
] ,
"title" : "Plugin/readRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/PluginReadParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Plugin/readRequest" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"app/list"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "App/listRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/AppsListParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "App/listRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
app-server: add v2 filesystem APIs (#14245)
Add a protocol-level filesystem surface to the v2 app-server so Codex
clients can read and write files, inspect directories, and subscribe to
path changes without relying on host-specific helpers.
High-level changes:
- define the new v2 fs/readFile, fs/writeFile, fs/createDirectory,
fs/getMetadata, fs/readDirectory, fs/remove, fs/copy RPCs
- implement the app-server handlers, including absolute-path validation,
base64 file payloads, recursive copy/remove semantics
- document the API, regenerate protocol schemas/types, and add
end-to-end tests for filesystem operations, copy edge cases
Testing plan:
- validate protocol serialization and generated schema output for the
new fs request, response, and notification types
- run app-server integration coverage for file and directory CRUD paths,
metadata/readDirectory responses, copy failure modes, and absolute-path
validation
2026-03-13 14:42:20 -07:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"fs/readFile"
] ,
"title" : "Fs/readFileRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FsReadFileParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Fs/readFileRequest" ,
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"fs/writeFile"
] ,
"title" : "Fs/writeFileRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FsWriteFileParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Fs/writeFileRequest" ,
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"fs/createDirectory"
] ,
"title" : "Fs/createDirectoryRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FsCreateDirectoryParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Fs/createDirectoryRequest" ,
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"fs/getMetadata"
] ,
"title" : "Fs/getMetadataRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FsGetMetadataParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Fs/getMetadataRequest" ,
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"fs/readDirectory"
] ,
"title" : "Fs/readDirectoryRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FsReadDirectoryParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Fs/readDirectoryRequest" ,
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"fs/remove"
] ,
"title" : "Fs/removeRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FsRemoveParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Fs/removeRequest" ,
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"fs/copy"
] ,
"title" : "Fs/copyRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/FsCopyParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Fs/copyRequest" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"skills/config/write"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Skills/config/writeRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/SkillsConfigWriteParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Skills/config/writeRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
2026-03-04 19:08:18 -05:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"plugin/install"
] ,
"title" : "Plugin/installRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/PluginInstallParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Plugin/installRequest" ,
"type" : "object"
} ,
2026-03-09 12:40:25 -07:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"plugin/uninstall"
] ,
"title" : "Plugin/uninstallRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/PluginUninstallParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Plugin/uninstallRequest" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"turn/start"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Turn/startRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/TurnStartParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Turn/startRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"turn/steer"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Turn/steerRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/TurnSteerParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Turn/steerRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"turn/interrupt"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Turn/interruptRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/TurnInterruptParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Turn/interruptRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"review/start"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Review/startRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ReviewStartParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Review/startRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"model/list"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Model/listRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ModelListParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Model/listRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"experimentalFeature/list"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ExperimentalFeature/listRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ExperimentalFeatureListParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "ExperimentalFeature/listRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"mcpServer/oauth/login"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "McpServer/oauth/loginRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/McpServerOauthLoginParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "McpServer/oauth/loginRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"config/mcpServer/reload"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Config/mcpServer/reloadRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"type" : "null"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"method"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Config/mcpServer/reloadRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"mcpServerStatus/list"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "McpServerStatus/listRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ListMcpServerStatusParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "McpServerStatus/listRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"windowsSandbox/setupStart"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "WindowsSandbox/setupStartRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/WindowsSandboxSetupStartParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "WindowsSandbox/setupStartRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"account/login/start"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/login/startRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/LoginAccountParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/login/startRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"account/login/cancel"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/login/cancelRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/CancelLoginAccountParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/login/cancelRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"account/logout"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/logoutRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
"type" : "null"
}
} ,
"required" : [
"id" ,
"method"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/logoutRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"account/rateLimits/read"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/rateLimits/readRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"type" : "null"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"method"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/rateLimits/readRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"feedback/upload"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Feedback/uploadRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/FeedbackUploadParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"method" ,
"params"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Feedback/uploadRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
2026-03-06 17:30:17 -08:00
"description" : "Execute a standalone command (argv vector) under the server's sandbox." ,
2026-02-01 23:38:43 -08:00
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"command/exec"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Command/execRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/CommandExecParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Command/execRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
2026-03-06 17:30:17 -08:00
{
"description" : "Write stdin bytes to a running `command/exec` session or close stdin." ,
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"command/exec/write"
] ,
"title" : "Command/exec/writeRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/CommandExecWriteParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Command/exec/writeRequest" ,
"type" : "object"
} ,
{
"description" : "Terminate a running `command/exec` session by client-supplied `processId`." ,
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"command/exec/terminate"
] ,
"title" : "Command/exec/terminateRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/CommandExecTerminateParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Command/exec/terminateRequest" ,
"type" : "object"
} ,
{
"description" : "Resize a running PTY-backed `command/exec` session by client-supplied `processId`." ,
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"command/exec/resize"
] ,
"title" : "Command/exec/resizeRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/CommandExecResizeParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "Command/exec/resizeRequest" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"config/read"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Config/readRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ConfigReadParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"method" ,
"params"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Config/readRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
2026-02-25 02:11:51 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"externalAgentConfig/detect"
] ,
"title" : "ExternalAgentConfig/detectRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ExternalAgentConfigDetectParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "ExternalAgentConfig/detectRequest" ,
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
"externalAgentConfig/import"
] ,
"title" : "ExternalAgentConfig/importRequestMethod" ,
"type" : "string"
} ,
"params" : {
"$ref" : "#/definitions/ExternalAgentConfigImportParams"
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
"title" : "ExternalAgentConfig/importRequest" ,
"type" : "object"
} ,
2026-02-01 23:38:43 -08:00
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"config/value/write"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Config/value/writeRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ConfigValueWriteParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Config/value/writeRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"config/batchWrite"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Config/batchWriteRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/ConfigBatchWriteParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
2026-02-20 21:36:12 -08:00
"method" ,
"params"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Config/batchWriteRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"configRequirements/read"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "ConfigRequirements/readRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
"type" : "null"
}
} ,
"required" : [
"id" ,
"method"
] ,
2026-02-20 21:36:12 -08:00
"title" : "ConfigRequirements/readRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"account/read"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/readRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/GetAccountParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "Account/readRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
} ,
{
"properties" : {
"id" : {
"$ref" : "#/definitions/RequestId"
} ,
"method" : {
"enum" : [
2026-02-20 21:36:12 -08:00
"fuzzyFileSearch"
2026-02-01 23:38:43 -08:00
] ,
2026-02-20 21:36:12 -08:00
"title" : "FuzzyFileSearchRequestMethod" ,
2026-02-01 23:38:43 -08:00
"type" : "string"
} ,
"params" : {
2026-02-20 21:36:12 -08:00
"$ref" : "#/definitions/FuzzyFileSearchParams"
2026-02-01 23:38:43 -08:00
}
} ,
"required" : [
"id" ,
"method" ,
"params"
] ,
2026-02-20 21:36:12 -08:00
"title" : "FuzzyFileSearchRequest" ,
2026-02-01 23:38:43 -08:00
"type" : "object"
}
] ,
"title" : "ClientRequest"
app-server: include experimental skill metadata in exec approval requests (#13929)
## Summary
This change surfaces skill metadata on command approval requests so
app-server clients can tell when an approval came from a skill script
and identify the originating `SKILL.md`.
- add `skill_metadata` to exec approval events in the shared protocol
- thread skill metadata through core shell escalation and delegated
approval handling for skill-triggered approvals
- expose the field in app-server v2 as experimental `skillMetadata`
- regenerate the JSON/TypeScript schemas and cover the new field in
protocol, transport, core, and TUI tests
## Why
Skill-triggered approvals already carry skill context inside core, but
app-server clients could not see which skill caused the prompt. Sending
the skill metadata with the approval request makes it possible for
clients to present better approval UX and connect the prompt back to the
relevant skill definition.
## example event in app-server-v2
verified that we see this event when experimental api is on:
```
< {
< "id": 11,
< "method": "item/commandExecution/requestApproval",
< "params": {
< "additionalPermissions": {
< "fileSystem": null,
< "macos": {
< "accessibility": false,
< "automations": {
< "bundle_ids": [
< "com.apple.Notes"
< ]
< },
< "calendar": false,
< "preferences": "read_only"
< },
< "network": null
< },
< "approvalId": "25d600ee-5a3c-4746-8d17-e2e61fb4c563",
< "availableDecisions": [
< "accept",
< "acceptForSession",
< "cancel"
< ],
< "command": "/Applications/ChatGPT.app/Contents/Resources/CodexAppServer_CodexAppServerBundledSkills.bundle/Contents/Resources/skills/apple-notes/scripts/notes_info",
< "commandActions": [
< {
< "command": "/Applications/ChatGPT.app/Contents/Resources/CodexAppServer_CodexAppServerBundledSkills.bundle/Contents/Resources/skills/apple-notes/scripts/notes_info",
< "type": "unknown"
< }
< ],
< "cwd": "/Applications/ChatGPT.app/Contents/Resources/CodexAppServer_CodexAppServerBundledSkills.bundle/Contents/Resources/skills/apple-notes",
< "itemId": "call_jZp3xFpNg4D8iKAD49cvEvZy",
< "skillMetadata": {
< "pathToSkillsMd": "/Applications/ChatGPT.app/Contents/Resources/CodexAppServer_CodexAppServerBundledSkills.bundle/Contents/Resources/skills/apple-notes/SKILL.md"
< },
< "threadId": "019ccc10-b7d3-7ff2-84fe-3a75e7681e69",
< "turnId": "019ccc10-b848-76f1-81b3-4a1fa225493f"
< }
< }`
```
& verified that this is the event when experimental api is off:
```
< {
< "id": 13,
< "method": "item/commandExecution/requestApproval",
< "params": {
< "approvalId": "5fbbf776-261b-4cf8-899b-c125b547f2c0",
< "availableDecisions": [
< "accept",
< "acceptForSession",
< "cancel"
< ],
< "command": "/Applications/ChatGPT.app/Contents/Resources/CodexAppServer_CodexAppServerBundledSkills.bundle/Contents/Resources/skills/apple-notes/scripts/notes_info",
< "commandActions": [
< {
< "command": "/Applications/ChatGPT.app/Contents/Resources/CodexAppServer_CodexAppServerBundledSkills.bundle/Contents/Resources/skills/apple-notes/scripts/notes_info",
< "type": "unknown"
< }
< ],
< "cwd": "/Users/celia/code/codex/codex-rs",
< "itemId": "call_OV2DHzTgYcbYtWaTTBWlocOt",
< "threadId": "019ccc16-2a2b-7be1-8500-e00d45b892d4",
< "turnId": "019ccc16-2a8e-7961-98ec-649600e7d06a"
< }
< }
```
2026-03-08 18:07:46 -07:00
}