From 3afcb5a68ceae23cd28942bd474d9f9634bbc192 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Mon, 27 Apr 2026 22:52:00 -0700 Subject: [PATCH] app-server-protocol: mark permission profiles experimental --- .../schema/json/ClientRequest.json | 55 -------- .../codex_app_server_protocol.schemas.json | 91 ------------- .../codex_app_server_protocol.v2.schemas.json | 91 ------------- .../schema/json/v2/CommandExecParams.json | 11 -- .../schema/json/v2/ThreadForkParams.json | 11 -- .../schema/json/v2/ThreadForkResponse.json | 12 -- .../schema/json/v2/ThreadResumeParams.json | 11 -- .../schema/json/v2/ThreadResumeResponse.json | 12 -- .../schema/json/v2/ThreadStartParams.json | 11 -- .../schema/json/v2/ThreadStartResponse.json | 12 -- .../schema/json/v2/TurnStartParams.json | 11 -- .../schema/typescript/v2/CommandExecParams.ts | 49 ++----- .../CommandExecutionRequestApprovalParams.ts | 36 ++---- .../schema/typescript/v2/ThreadForkParams.ts | 17 +-- .../typescript/v2/ThreadForkResponse.ts | 16 +-- .../typescript/v2/ThreadResumeParams.ts | 23 +--- .../typescript/v2/ThreadResumeResponse.ts | 16 +-- .../schema/typescript/v2/ThreadStartParams.ts | 15 +-- .../typescript/v2/ThreadStartResponse.ts | 16 +-- .../schema/typescript/v2/TurnStartParams.ts | 15 +-- codex-rs/app-server-protocol/src/export.rs | 120 +++++++++++++++++- .../src/protocol/common.rs | 28 ++++ .../app-server-protocol/src/protocol/v2.rs | 10 +- 23 files changed, 193 insertions(+), 496 deletions(-) diff --git a/codex-rs/app-server-protocol/schema/json/ClientRequest.json b/codex-rs/app-server-protocol/schema/json/ClientRequest.json index 079a8a2d76d5..31cfd542b713 100644 --- a/codex-rs/app-server-protocol/schema/json/ClientRequest.json +++ b/codex-rs/app-server-protocol/schema/json/ClientRequest.json @@ -218,17 +218,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Optional full permissions profile for this command.\n\nDefaults to the user's configured permissions when omitted. Cannot be combined with `sandboxPolicy`." - }, "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.", "type": [ @@ -3271,17 +3260,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for the forked thread. Cannot be combined with `sandbox`." - }, "sandbox": { "anyOf": [ { @@ -3687,17 +3665,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for the resumed thread. Cannot be combined with `sandbox`." - }, "personality": { "anyOf": [ { @@ -3881,17 +3848,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for this thread. Cannot be combined with `sandbox`." - }, "personality": { "anyOf": [ { @@ -4103,17 +4059,6 @@ "outputSchema": { "description": "Optional JSON Schema used to constrain the final assistant message for this turn." }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Override the full permissions profile for this turn and subsequent turns. Cannot be combined with `sandboxPolicy`." - }, "personality": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json index 7e34967470ef..1c0ace7fd858 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.schemas.json @@ -6536,17 +6536,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/v2/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Optional full permissions profile for this command.\n\nDefaults to the user's configured permissions when omitted. Cannot be combined with `sandboxPolicy`." - }, "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.", "type": [ @@ -14443,17 +14432,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/v2/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for the forked thread. Cannot be combined with `sandbox`." - }, "sandbox": { "anyOf": [ { @@ -14522,18 +14500,6 @@ "modelProvider": { "type": "string" }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/v2/PermissionProfile" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Canonical active permissions view for this thread." - }, "reasoningEffort": { "anyOf": [ { @@ -15967,17 +15933,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/v2/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for the resumed thread. Cannot be combined with `sandbox`." - }, "personality": { "anyOf": [ { @@ -16056,18 +16011,6 @@ "modelProvider": { "type": "string" }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/v2/PermissionProfile" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Canonical active permissions view for this thread." - }, "reasoningEffort": { "anyOf": [ { @@ -16284,17 +16227,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/v2/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for this thread. Cannot be combined with `sandbox`." - }, "personality": { "anyOf": [ { @@ -16383,18 +16315,6 @@ "modelProvider": { "type": "string" }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/v2/PermissionProfile" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Canonical active permissions view for this thread." - }, "reasoningEffort": { "anyOf": [ { @@ -17100,17 +17020,6 @@ "outputSchema": { "description": "Optional JSON Schema used to constrain the final assistant message for this turn." }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/v2/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Override the full permissions profile for this turn and subsequent turns. Cannot be combined with `sandboxPolicy`." - }, "personality": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json index 406795ff5441..cf721d82afc7 100644 --- a/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json +++ b/codex-rs/app-server-protocol/schema/json/codex_app_server_protocol.v2.schemas.json @@ -3055,17 +3055,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Optional full permissions profile for this command.\n\nDefaults to the user's configured permissions when omitted. Cannot be combined with `sandboxPolicy`." - }, "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.", "type": [ @@ -12329,17 +12318,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for the forked thread. Cannot be combined with `sandbox`." - }, "sandbox": { "anyOf": [ { @@ -12408,18 +12386,6 @@ "modelProvider": { "type": "string" }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Canonical active permissions view for this thread." - }, "reasoningEffort": { "anyOf": [ { @@ -13853,17 +13819,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for the resumed thread. Cannot be combined with `sandbox`." - }, "personality": { "anyOf": [ { @@ -13942,18 +13897,6 @@ "modelProvider": { "type": "string" }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Canonical active permissions view for this thread." - }, "reasoningEffort": { "anyOf": [ { @@ -14170,17 +14113,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for this thread. Cannot be combined with `sandbox`." - }, "personality": { "anyOf": [ { @@ -14269,18 +14201,6 @@ "modelProvider": { "type": "string" }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Canonical active permissions view for this thread." - }, "reasoningEffort": { "anyOf": [ { @@ -14986,17 +14906,6 @@ "outputSchema": { "description": "Optional JSON Schema used to constrain the final assistant message for this turn." }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Override the full permissions profile for this turn and subsequent turns. Cannot be combined with `sandboxPolicy`." - }, "personality": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/v2/CommandExecParams.json b/codex-rs/app-server-protocol/schema/json/v2/CommandExecParams.json index 7db4d635ee87..f29483862cd1 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/CommandExecParams.json +++ b/codex-rs/app-server-protocol/schema/json/v2/CommandExecParams.json @@ -505,17 +505,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Optional full permissions profile for this command.\n\nDefaults to the user's configured permissions when omitted. Cannot be combined with `sandboxPolicy`." - }, "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.", "type": [ diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadForkParams.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadForkParams.json index 504dbdc67eb4..eb8f3bdb4f63 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadForkParams.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadForkParams.json @@ -473,17 +473,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for the forked thread. Cannot be combined with `sandbox`." - }, "sandbox": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadForkResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadForkResponse.json index 3ab0077d0ac3..b5d6b139b2c0 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadForkResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadForkResponse.json @@ -2485,18 +2485,6 @@ "modelProvider": { "type": "string" }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Canonical active permissions view for this thread." - }, "reasoningEffort": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeParams.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeParams.json index 63d0345daec0..425fc52a48a0 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeParams.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeParams.json @@ -1328,17 +1328,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for the resumed thread. Cannot be combined with `sandbox`." - }, "personality": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeResponse.json index 12c38db5dc7a..7135a5317439 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadResumeResponse.json @@ -2485,18 +2485,6 @@ "modelProvider": { "type": "string" }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Canonical active permissions view for this thread." - }, "reasoningEffort": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartParams.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartParams.json index bc8d83d2bc33..d5e76f05e3c9 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartParams.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartParams.json @@ -526,17 +526,6 @@ "null" ] }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Full permissions override for this thread. Cannot be combined with `sandbox`." - }, "personality": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartResponse.json b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartResponse.json index 6e1637ec8054..5deca9f6990a 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/ThreadStartResponse.json +++ b/codex-rs/app-server-protocol/schema/json/v2/ThreadStartResponse.json @@ -2485,18 +2485,6 @@ "modelProvider": { "type": "string" }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Canonical active permissions view for this thread." - }, "reasoningEffort": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/json/v2/TurnStartParams.json b/codex-rs/app-server-protocol/schema/json/v2/TurnStartParams.json index d866c03152d1..719a1bedc8b9 100644 --- a/codex-rs/app-server-protocol/schema/json/v2/TurnStartParams.json +++ b/codex-rs/app-server-protocol/schema/json/v2/TurnStartParams.json @@ -829,17 +829,6 @@ "outputSchema": { "description": "Optional JSON Schema used to constrain the final assistant message for this turn." }, - "permissionProfile": { - "anyOf": [ - { - "$ref": "#/definitions/PermissionProfile" - }, - { - "type": "null" - } - ], - "description": "Override the full permissions profile for this turn and subsequent turns. Cannot be combined with `sandboxPolicy`." - }, "personality": { "anyOf": [ { diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecParams.ts b/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecParams.ts index 659974feafef..221a2399c15f 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecParams.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecParams.ts @@ -2,7 +2,6 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { CommandExecTerminalSize } from "./CommandExecTerminalSize"; -import type { PermissionProfile } from "./PermissionProfile"; import type { SandboxPolicy } from "./SandboxPolicy"; /** @@ -13,12 +12,10 @@ import type { SandboxPolicy } from "./SandboxPolicy"; * sent only after all `command/exec/outputDelta` notifications for that * connection have been emitted. */ -export type CommandExecParams = { -/** +export type CommandExecParams = {/** * Command argv vector. Empty arrays are rejected. */ -command: Array, -/** +command: Array, /** * Optional client-supplied, connection-scoped process id. * * Required for `tty`, `streamStdin`, `streamStdoutStderr`, and follow-up @@ -26,81 +23,63 @@ command: Array, * `command/exec/terminate` calls. When omitted, buffered execution gets an * internal id that is not exposed to the client. */ -processId?: string | null, -/** +processId?: string | null, /** * Enable PTY mode. * * This implies `streamStdin` and `streamStdoutStderr`. */ -tty?: boolean, -/** +tty?: boolean, /** * Allow follow-up `command/exec/write` requests to write stdin bytes. * * Requires a client-supplied `processId`. */ -streamStdin?: boolean, -/** +streamStdin?: boolean, /** * Stream stdout/stderr via `command/exec/outputDelta` notifications. * * Streamed bytes are not duplicated into the final response and require a * client-supplied `processId`. */ -streamStdoutStderr?: boolean, -/** +streamStdoutStderr?: boolean, /** * Optional per-stream stdout/stderr capture cap in bytes. * * When omitted, the server default applies. Cannot be combined with * `disableOutputCap`. */ -outputBytesCap?: number | null, -/** +outputBytesCap?: number | null, /** * Disable stdout/stderr capture truncation for this request. * * Cannot be combined with `outputBytesCap`. */ -disableOutputCap?: boolean, -/** +disableOutputCap?: boolean, /** * Disable the timeout entirely for this request. * * Cannot be combined with `timeoutMs`. */ -disableTimeout?: boolean, -/** +disableTimeout?: boolean, /** * Optional timeout in milliseconds. * * When omitted, the server default applies. Cannot be combined with * `disableTimeout`. */ -timeoutMs?: number | null, -/** +timeoutMs?: number | null, /** * Optional working directory. Defaults to the server cwd. */ -cwd?: string | null, -/** +cwd?: string | null, /** * Optional environment overrides merged into the server-computed * environment. * * Matching names override inherited values. Set a key to `null` to unset * an inherited variable. */ -env?: { [key in string]?: string | null } | null, -/** +env?: { [key in string]?: string | null } | null, /** * Optional initial PTY size in character cells. Only valid when `tty` is * true. */ -size?: CommandExecTerminalSize | null, -/** +size?: CommandExecTerminalSize | null, /** * Optional sandbox policy for this command. * * Uses the same shape as thread/turn execution sandbox configuration and * defaults to the user's configured policy when omitted. Cannot be * combined with `permissionProfile`. */ -sandboxPolicy?: SandboxPolicy | null, -/** - * Optional full permissions profile for this command. - * - * Defaults to the user's configured permissions when omitted. Cannot be - * combined with `sandboxPolicy`. - */ -permissionProfile?: PermissionProfile | null, }; +sandboxPolicy?: SandboxPolicy | null}; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionRequestApprovalParams.ts b/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionRequestApprovalParams.ts index 59da1de94523..ca2d0b0aa0de 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionRequestApprovalParams.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/CommandExecutionRequestApprovalParams.ts @@ -2,15 +2,12 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { AbsolutePathBuf } from "../AbsolutePathBuf"; -import type { AdditionalPermissionProfile } from "./AdditionalPermissionProfile"; import type { CommandAction } from "./CommandAction"; -import type { CommandExecutionApprovalDecision } from "./CommandExecutionApprovalDecision"; import type { ExecPolicyAmendment } from "./ExecPolicyAmendment"; import type { NetworkApprovalContext } from "./NetworkApprovalContext"; import type { NetworkPolicyAmendment } from "./NetworkPolicyAmendment"; -export type CommandExecutionRequestApprovalParams = { threadId: string, turnId: string, itemId: string, -/** +export type CommandExecutionRequestApprovalParams = {threadId: string, turnId: string, itemId: string, /** * Unique identifier for this specific approval callback. * * For regular shell/unified_exec approvals, this is null. @@ -19,40 +16,25 @@ export type CommandExecutionRequestApprovalParams = { threadId: string, turnId: * one parent `itemId`, so `approvalId` is a distinct opaque callback id * (a UUID) used to disambiguate routing. */ -approvalId?: string | null, -/** +approvalId?: string | null, /** * Optional explanatory reason (e.g. request for network access). */ -reason?: string | null, -/** +reason?: string | null, /** * Optional context for a managed-network approval prompt. */ -networkApprovalContext?: NetworkApprovalContext | null, -/** +networkApprovalContext?: NetworkApprovalContext | null, /** * The command to be executed. */ -command?: string | null, -/** +command?: string | null, /** * The command's working directory. */ -cwd?: AbsolutePathBuf | null, -/** +cwd?: AbsolutePathBuf | null, /** * Best-effort parsed command actions for friendly display. */ -commandActions?: Array | null, -/** - * Optional additional permissions requested for this command. - */ -additionalPermissions?: AdditionalPermissionProfile | null, -/** +commandActions?: Array | null, /** * Optional proposed execpolicy amendment to allow similar commands without prompting. */ -proposedExecpolicyAmendment?: ExecPolicyAmendment | null, -/** +proposedExecpolicyAmendment?: ExecPolicyAmendment | null, /** * Optional proposed network policy amendments (allow/deny host) for future requests. */ -proposedNetworkPolicyAmendments?: Array | null, -/** - * Ordered list of decisions the client may present for this prompt. - */ -availableDecisions?: Array | null, }; +proposedNetworkPolicyAmendments?: Array | null}; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadForkParams.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadForkParams.ts index f5f3f1878cc7..a40e406df9ef 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadForkParams.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadForkParams.ts @@ -5,7 +5,6 @@ import type { ServiceTier } from "../ServiceTier"; import type { JsonValue } from "../serde_json/JsonValue"; import type { ApprovalsReviewer } from "./ApprovalsReviewer"; import type { AskForApproval } from "./AskForApproval"; -import type { PermissionProfile } from "./PermissionProfile"; import type { SandboxMode } from "./SandboxMode"; /** @@ -18,27 +17,15 @@ import type { SandboxMode } from "./SandboxMode"; * Prefer using thread_id whenever possible. */ export type ThreadForkParams = {threadId: string, /** - * [UNSTABLE] Specify the rollout path to fork from. - * If specified, the thread_id param will be ignored. - */ -path?: string | null, /** * Configuration overrides for the forked thread, if any. */ model?: string | null, modelProvider?: string | null, serviceTier?: ServiceTier | null | null, cwd?: string | null, approvalPolicy?: AskForApproval | null, /** * Override where approval requests are routed for review on this thread * and subsequent turns. */ -approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, /** - * Full permissions override for the forked thread. Cannot be combined - * with `sandbox`. - */ -permissionProfile?: PermissionProfile | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, ephemeral?: boolean, /** +approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, ephemeral?: boolean, /** * When true, return only thread metadata and live fork state without * populating `thread.turns`. This is useful when the client plans to call * `thread/turns/list` immediately after forking. */ -excludeTurns?: boolean, /** - * If true, persist additional rollout EventMsg variants required to - * reconstruct a richer thread history on subsequent resume/fork/read. - */ -persistExtendedHistory: boolean}; +excludeTurns?: boolean}; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadForkResponse.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadForkResponse.ts index b69f1da01205..1207002514de 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadForkResponse.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadForkResponse.ts @@ -6,26 +6,18 @@ import type { ReasoningEffort } from "../ReasoningEffort"; import type { ServiceTier } from "../ServiceTier"; import type { ApprovalsReviewer } from "./ApprovalsReviewer"; import type { AskForApproval } from "./AskForApproval"; -import type { PermissionProfile } from "./PermissionProfile"; import type { SandboxPolicy } from "./SandboxPolicy"; import type { Thread } from "./Thread"; -export type ThreadForkResponse = { thread: Thread, model: string, modelProvider: string, serviceTier: ServiceTier | null, cwd: AbsolutePathBuf, -/** +export type ThreadForkResponse = {thread: Thread, model: string, modelProvider: string, serviceTier: ServiceTier | null, cwd: AbsolutePathBuf, /** * Instruction source files currently loaded for this thread. */ -instructionSources: Array, approvalPolicy: AskForApproval, -/** +instructionSources: Array, approvalPolicy: AskForApproval, /** * Reviewer currently used for approval requests on this thread. */ -approvalsReviewer: ApprovalsReviewer, -/** +approvalsReviewer: ApprovalsReviewer, /** * Legacy sandbox policy retained for compatibility. New clients should use * `permissionProfile` when present as the canonical active permissions * view. */ -sandbox: SandboxPolicy, -/** - * Canonical active permissions view for this thread. - */ -permissionProfile: PermissionProfile | null, reasoningEffort: ReasoningEffort | null, }; +sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null}; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadResumeParams.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadResumeParams.ts index 452126be46b4..f9821585fb15 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadResumeParams.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadResumeParams.ts @@ -2,12 +2,10 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. import type { Personality } from "../Personality"; -import type { ResponseItem } from "../ResponseItem"; import type { ServiceTier } from "../ServiceTier"; import type { JsonValue } from "../serde_json/JsonValue"; import type { ApprovalsReviewer } from "./ApprovalsReviewer"; import type { AskForApproval } from "./AskForApproval"; -import type { PermissionProfile } from "./PermissionProfile"; import type { SandboxMode } from "./SandboxMode"; /** @@ -22,32 +20,15 @@ import type { SandboxMode } from "./SandboxMode"; * Prefer using thread_id whenever possible. */ export type ThreadResumeParams = {threadId: string, /** - * [UNSTABLE] FOR CODEX CLOUD - DO NOT USE. - * If specified, the thread will be resumed with the provided history - * instead of loaded from disk. - */ -history?: Array | null, /** - * [UNSTABLE] Specify the rollout path to resume from. - * If specified, the thread_id param will be ignored. - */ -path?: string | null, /** * Configuration overrides for the resumed thread, if any. */ model?: string | null, modelProvider?: string | null, serviceTier?: ServiceTier | null | null, cwd?: string | null, approvalPolicy?: AskForApproval | null, /** * Override where approval requests are routed for review on this thread * and subsequent turns. */ -approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, /** - * Full permissions override for the resumed thread. Cannot be combined - * with `sandbox`. - */ -permissionProfile?: PermissionProfile | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, personality?: Personality | null, /** +approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, personality?: Personality | null, /** * When true, return only thread metadata and live-resume state without * populating `thread.turns`. This is useful when the client plans to call * `thread/turns/list` immediately after resuming. */ -excludeTurns?: boolean, /** - * If true, persist additional rollout EventMsg variants required to - * reconstruct a richer thread history on subsequent resume/fork/read. - */ -persistExtendedHistory: boolean}; +excludeTurns?: boolean}; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadResumeResponse.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadResumeResponse.ts index 5ceec7f3fe60..20f91b3e9153 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadResumeResponse.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadResumeResponse.ts @@ -6,26 +6,18 @@ import type { ReasoningEffort } from "../ReasoningEffort"; import type { ServiceTier } from "../ServiceTier"; import type { ApprovalsReviewer } from "./ApprovalsReviewer"; import type { AskForApproval } from "./AskForApproval"; -import type { PermissionProfile } from "./PermissionProfile"; import type { SandboxPolicy } from "./SandboxPolicy"; import type { Thread } from "./Thread"; -export type ThreadResumeResponse = { thread: Thread, model: string, modelProvider: string, serviceTier: ServiceTier | null, cwd: AbsolutePathBuf, -/** +export type ThreadResumeResponse = {thread: Thread, model: string, modelProvider: string, serviceTier: ServiceTier | null, cwd: AbsolutePathBuf, /** * Instruction source files currently loaded for this thread. */ -instructionSources: Array, approvalPolicy: AskForApproval, -/** +instructionSources: Array, approvalPolicy: AskForApproval, /** * Reviewer currently used for approval requests on this thread. */ -approvalsReviewer: ApprovalsReviewer, -/** +approvalsReviewer: ApprovalsReviewer, /** * Legacy sandbox policy retained for compatibility. New clients should use * `permissionProfile` when present as the canonical active permissions * view. */ -sandbox: SandboxPolicy, -/** - * Canonical active permissions view for this thread. - */ -permissionProfile: PermissionProfile | null, reasoningEffort: ReasoningEffort | null, }; +sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null}; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadStartParams.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadStartParams.ts index 8b9dafec9f86..374ac2e681eb 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadStartParams.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadStartParams.ts @@ -6,7 +6,6 @@ import type { ServiceTier } from "../ServiceTier"; import type { JsonValue } from "../serde_json/JsonValue"; import type { ApprovalsReviewer } from "./ApprovalsReviewer"; import type { AskForApproval } from "./AskForApproval"; -import type { PermissionProfile } from "./PermissionProfile"; import type { SandboxMode } from "./SandboxMode"; import type { ThreadStartSource } from "./ThreadStartSource"; @@ -14,16 +13,4 @@ export type ThreadStartParams = {model?: string | null, modelProvider?: string | * Override where approval requests are routed for review on this thread * and subsequent turns. */ -approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, /** - * Full permissions override for this thread. Cannot be combined with - * `sandbox`. - */ -permissionProfile?: PermissionProfile | null, config?: { [key in string]?: JsonValue } | null, serviceName?: string | null, baseInstructions?: string | null, developerInstructions?: string | null, personality?: Personality | null, ephemeral?: boolean | null, sessionStartSource?: ThreadStartSource | null, /** - * If true, opt into emitting raw Responses API items on the event stream. - * This is for internal use only (e.g. Codex Cloud). - */ -experimentalRawEvents: boolean, /** - * If true, persist additional rollout EventMsg variants required to - * reconstruct a richer thread history on resume/fork/read. - */ -persistExtendedHistory: boolean}; +approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, serviceName?: string | null, baseInstructions?: string | null, developerInstructions?: string | null, personality?: Personality | null, ephemeral?: boolean | null, sessionStartSource?: ThreadStartSource | null}; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadStartResponse.ts b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadStartResponse.ts index 61d268afe858..87e15411a28b 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/ThreadStartResponse.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/ThreadStartResponse.ts @@ -6,26 +6,18 @@ import type { ReasoningEffort } from "../ReasoningEffort"; import type { ServiceTier } from "../ServiceTier"; import type { ApprovalsReviewer } from "./ApprovalsReviewer"; import type { AskForApproval } from "./AskForApproval"; -import type { PermissionProfile } from "./PermissionProfile"; import type { SandboxPolicy } from "./SandboxPolicy"; import type { Thread } from "./Thread"; -export type ThreadStartResponse = { thread: Thread, model: string, modelProvider: string, serviceTier: ServiceTier | null, cwd: AbsolutePathBuf, -/** +export type ThreadStartResponse = {thread: Thread, model: string, modelProvider: string, serviceTier: ServiceTier | null, cwd: AbsolutePathBuf, /** * Instruction source files currently loaded for this thread. */ -instructionSources: Array, approvalPolicy: AskForApproval, -/** +instructionSources: Array, approvalPolicy: AskForApproval, /** * Reviewer currently used for approval requests on this thread. */ -approvalsReviewer: ApprovalsReviewer, -/** +approvalsReviewer: ApprovalsReviewer, /** * Legacy sandbox policy retained for compatibility. New clients should use * `permissionProfile` when present as the canonical active permissions * view. */ -sandbox: SandboxPolicy, -/** - * Canonical active permissions view for this thread. - */ -permissionProfile: PermissionProfile | null, reasoningEffort: ReasoningEffort | null, }; +sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null}; diff --git a/codex-rs/app-server-protocol/schema/typescript/v2/TurnStartParams.ts b/codex-rs/app-server-protocol/schema/typescript/v2/TurnStartParams.ts index 3d12e6001cf8..4af17115c8a0 100644 --- a/codex-rs/app-server-protocol/schema/typescript/v2/TurnStartParams.ts +++ b/codex-rs/app-server-protocol/schema/typescript/v2/TurnStartParams.ts @@ -1,7 +1,6 @@ // GENERATED CODE! DO NOT MODIFY BY HAND! // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -import type { CollaborationMode } from "../CollaborationMode"; import type { Personality } from "../Personality"; import type { ReasoningEffort } from "../ReasoningEffort"; import type { ReasoningSummary } from "../ReasoningSummary"; @@ -9,7 +8,6 @@ import type { ServiceTier } from "../ServiceTier"; import type { JsonValue } from "../serde_json/JsonValue"; import type { ApprovalsReviewer } from "./ApprovalsReviewer"; import type { AskForApproval } from "./AskForApproval"; -import type { PermissionProfile } from "./PermissionProfile"; import type { SandboxPolicy } from "./SandboxPolicy"; import type { UserInput } from "./UserInput"; @@ -27,10 +25,6 @@ approvalsReviewer?: ApprovalsReviewer | null, /** * Override the sandbox policy for this turn and subsequent turns. */ sandboxPolicy?: SandboxPolicy | null, /** - * Override the full permissions profile for this turn and subsequent - * turns. Cannot be combined with `sandboxPolicy`. - */ -permissionProfile?: PermissionProfile | null, /** * Override the model for this turn and subsequent turns. */ model?: string | null, /** @@ -49,11 +43,4 @@ personality?: Personality | null, /** * Optional JSON Schema used to constrain the final assistant message for * this turn. */ -outputSchema?: JsonValue | null, /** - * EXPERIMENTAL - Set a pre-set collaboration mode. - * Takes precedence over model, reasoning_effort, and developer instructions if set. - * - * For `collaboration_mode.settings.developer_instructions`, `null` means - * "use the built-in instructions for the selected mode". - */ -collaborationMode?: CollaborationMode | null}; +outputSchema?: JsonValue | null}; diff --git a/codex-rs/app-server-protocol/src/export.rs b/codex-rs/app-server-protocol/src/export.rs index 96bb8d17a973..0f9b33671b28 100644 --- a/codex-rs/app-server-protocol/src/export.rs +++ b/codex-rs/app-server-protocol/src/export.rs @@ -736,11 +736,11 @@ fn find_top_level_brace_span(input: &str) -> Option<(usize, usize)> { let mut state = ScanState::default(); let mut open_index = None; for (index, ch) in input.char_indices() { - if !state.in_string() && ch == '{' && state.depth.is_top_level() { + if !state.in_ignored_syntax() && ch == '{' && state.depth.is_top_level() { open_index = Some(index); } state.observe(ch); - if !state.in_string() + if !state.in_ignored_syntax() && ch == '}' && state.depth.is_top_level() && let Some(open) = open_index @@ -760,7 +760,7 @@ fn split_top_level_multi(input: &str, delimiters: &[char]) -> Vec { let mut start = 0usize; let mut parts = Vec::new(); for (index, ch) in input.char_indices() { - if !state.in_string() && state.depth.is_top_level() && delimiters.contains(&ch) { + if !state.in_ignored_syntax() && state.depth.is_top_level() && delimiters.contains(&ch) { let part = input[start..index].trim(); if !part.is_empty() { parts.push(part.to_string()); @@ -882,22 +882,58 @@ struct ScanState { depth: Depth, string_delim: Option, escape: bool, + block_comment: bool, + line_comment: bool, + previous_char: Option, } impl ScanState { fn observe(&mut self, ch: char) { + if self.line_comment { + if ch == '\n' { + self.line_comment = false; + } + self.previous_char = Some(ch); + return; + } + + if self.block_comment { + if self.previous_char == Some('*') && ch == '/' { + self.block_comment = false; + self.previous_char = None; + } else { + self.previous_char = Some(ch); + } + return; + } + if let Some(delim) = self.string_delim { if self.escape { self.escape = false; + self.previous_char = Some(ch); return; } if ch == '\\' { self.escape = true; + self.previous_char = Some(ch); return; } if ch == delim { self.string_delim = None; } + self.previous_char = Some(ch); + return; + } + + if self.previous_char == Some('/') && ch == '/' { + self.line_comment = true; + self.previous_char = Some(ch); + return; + } + + if self.previous_char == Some('/') && ch == '*' { + self.block_comment = true; + self.previous_char = Some(ch); return; } @@ -919,10 +955,11 @@ impl ScanState { } _ => {} } + self.previous_char = Some(ch); } - fn in_string(&self) -> bool { - self.string_delim.is_some() + fn in_ignored_syntax(&self) -> bool { + self.string_delim.is_some() || self.block_comment || self.line_comment } } @@ -2694,6 +2731,79 @@ export type Config = { stableField: Keep, unstableField: string | null } & ({ [k Ok(()) } + #[test] + fn experimental_type_fields_ts_filter_handles_generated_command_params_shape() -> Result<()> { + let output_dir = std::env::temp_dir().join(format!("codex_ts_filter_{}", Uuid::now_v7())); + fs::create_dir_all(&output_dir)?; + + struct TempDirGuard(PathBuf); + + impl Drop for TempDirGuard { + fn drop(&mut self) { + let _ = fs::remove_dir_all(&self.0); + } + } + + let _guard = TempDirGuard(output_dir.clone()); + let path = output_dir.join("CommandExecParams.ts"); + let content = r#"import type { CommandExecTerminalSize } from "./CommandExecTerminalSize"; +import type { PermissionProfile } from "./PermissionProfile"; +import type { SandboxPolicy } from "./SandboxPolicy"; + +export type CommandExecParams = {/** + * Command argv vector. Empty arrays are rejected. + */ +command: Array, /** + * Optional environment overrides merged into the server-computed + * environment. + */ +env?: { [key in string]?: string | null } | null, /** + * Optional initial PTY size in character cells. Only valid when `tty` is + * true. + */ +size?: CommandExecTerminalSize | null, /** + * Optional sandbox policy for this command. + * + * Uses the same shape as thread/turn execution sandbox configuration and + * defaults to the user's configured policy when omitted. Cannot be + * combined with `permissionProfile`. + */ +sandboxPolicy?: SandboxPolicy | null, +/** + * Optional full permissions profile for this command. + * + * Defaults to the user's configured permissions when omitted. Cannot be + * combined with `sandboxPolicy`. + */ +permissionProfile?: PermissionProfile | null}; +"#; + fs::write(&path, content)?; + + static CUSTOM_FIELD: crate::experimental_api::ExperimentalField = + crate::experimental_api::ExperimentalField { + type_name: "CommandExecParams", + field_name: "permissionProfile", + reason: "command/exec.permissionProfile", + }; + filter_experimental_type_fields_ts(&output_dir, &[&CUSTOM_FIELD])?; + + let filtered = fs::read_to_string(&path)?; + assert_eq!( + filtered.contains("permissionProfile?: PermissionProfile"), + false + ); + assert_eq!( + filtered.contains(r#"import type { PermissionProfile } from "./PermissionProfile";"#), + false + ); + assert_eq!(filtered.contains("sandboxPolicy?: SandboxPolicy"), true); + assert_eq!( + filtered.contains(r#"import type { SandboxPolicy } from "./SandboxPolicy";"#), + true + ); + Ok(()) + } + #[test] fn stable_schema_filter_removes_mock_experimental_method() -> Result<()> { let output_dir = std::env::temp_dir().join(format!("codex_schema_{}", Uuid::now_v7())); diff --git a/codex-rs/app-server-protocol/src/protocol/common.rs b/codex-rs/app-server-protocol/src/protocol/common.rs index 016d6e16b8bc..167435ac8887 100644 --- a/codex-rs/app-server-protocol/src/protocol/common.rs +++ b/codex-rs/app-server-protocol/src/protocol/common.rs @@ -581,6 +581,7 @@ client_request_definitions! { /// Execute a standalone command (argv vector) under the server's sandbox. OneOffCommandExec => "command/exec" { params: v2::CommandExecParams, + inspect_params: true, response: v2::CommandExecResponse, }, /// Write stdin bytes to a running `command/exec` session or close stdin. @@ -2049,6 +2050,33 @@ mod tests { let reason = crate::experimental_api::ExperimentalApi::experimental_reason(&request); assert_eq!(reason, Some("mock/experimentalMethod")); } + + #[test] + fn command_exec_permission_profile_is_marked_experimental() { + let request = ClientRequest::OneOffCommandExec { + request_id: RequestId::Integer(1), + params: v2::CommandExecParams { + command: vec!["pwd".to_string()], + process_id: None, + tty: false, + stream_stdin: false, + stream_stdout_stderr: false, + output_bytes_cap: None, + disable_output_cap: false, + disable_timeout: false, + timeout_ms: None, + cwd: None, + env: None, + size: None, + sandbox_policy: None, + permission_profile: Some(v2::PermissionProfile::Disabled), + }, + }; + + let reason = crate::experimental_api::ExperimentalApi::experimental_reason(&request); + assert_eq!(reason, Some("command/exec.permissionProfile")); + } + #[test] fn thread_realtime_start_is_marked_experimental() { let request = ClientRequest::ThreadRealtimeStart { diff --git a/codex-rs/app-server-protocol/src/protocol/v2.rs b/codex-rs/app-server-protocol/src/protocol/v2.rs index e1c941019d13..bfb1eaac0777 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2.rs @@ -3163,7 +3163,7 @@ pub struct CommandExecTerminalSize { /// The 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. -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS, ExperimentalApi)] #[serde(rename_all = "camelCase")] #[ts(export_to = "v2/")] pub struct CommandExecParams { @@ -3242,6 +3242,7 @@ pub struct CommandExecParams { /// /// Defaults to the user's configured permissions when omitted. Cannot be /// combined with `sandboxPolicy`. + #[experimental("command/exec.permissionProfile")] #[ts(optional = nullable)] pub permission_profile: Option, } @@ -3364,6 +3365,7 @@ pub struct ThreadStartParams { pub sandbox: Option, /// Full permissions override for this thread. Cannot be combined with /// `sandbox`. + #[experimental("thread/start.permissionProfile")] #[ts(optional = nullable)] pub permission_profile: Option, #[ts(optional = nullable)] @@ -3447,6 +3449,7 @@ pub struct ThreadStartResponse { /// view. pub sandbox: SandboxPolicy, /// Canonical active permissions view for this thread. + #[experimental("thread/start.permissionProfile")] #[serde(default)] pub permission_profile: Option, pub reasoning_effort: Option, @@ -3508,6 +3511,7 @@ pub struct ThreadResumeParams { pub sandbox: Option, /// Full permissions override for the resumed thread. Cannot be combined /// with `sandbox`. + #[experimental("thread/resume.permissionProfile")] #[ts(optional = nullable)] pub permission_profile: Option, #[ts(optional = nullable)] @@ -3551,6 +3555,7 @@ pub struct ThreadResumeResponse { /// view. pub sandbox: SandboxPolicy, /// Canonical active permissions view for this thread. + #[experimental("thread/resume.permissionProfile")] #[serde(default)] pub permission_profile: Option, pub reasoning_effort: Option, @@ -3603,6 +3608,7 @@ pub struct ThreadForkParams { pub sandbox: Option, /// Full permissions override for the forked thread. Cannot be combined /// with `sandbox`. + #[experimental("thread/fork.permissionProfile")] #[ts(optional = nullable)] pub permission_profile: Option, #[ts(optional = nullable)] @@ -3646,6 +3652,7 @@ pub struct ThreadForkResponse { /// view. pub sandbox: SandboxPolicy, /// Canonical active permissions view for this thread. + #[experimental("thread/fork.permissionProfile")] #[serde(default)] pub permission_profile: Option, pub reasoning_effort: Option, @@ -5184,6 +5191,7 @@ pub struct TurnStartParams { pub sandbox_policy: Option, /// Override the full permissions profile for this turn and subsequent /// turns. Cannot be combined with `sandboxPolicy`. + #[experimental("turn/start.permissionProfile")] #[ts(optional = nullable)] pub permission_profile: Option, /// Override the model for this turn and subsequent turns.