Compare commits

..

1 Commits

Author SHA1 Message Date
Michael Bolin
93d342a404 Release 0.95.0-alpha.3 2026-02-02 17:43:50 -08:00
415 changed files with 14105 additions and 26787 deletions

View File

@@ -1,47 +0,0 @@
name: 🖥️ Codex App Bug
description: Report an issue with the Codex App
labels:
- app
body:
- type: markdown
attributes:
value: |
Before submitting a new issue, please search for existing issues to see if your issue has already been reported.
If it has, please add a 👍 reaction (no need to leave a comment) to the existing issue instead of creating a new one.
- type: input
id: version
attributes:
label: What version of the Codex App are you using (From “About Codex” dialog)?
validations:
required: true
- type: input
id: plan
attributes:
label: What subscription do you have?
validations:
required: true
- type: textarea
id: actual
attributes:
label: What issue are you seeing?
description: Please include the full error messages and prompts with PII redacted. If possible, please provide text instead of a screenshot.
validations:
required: true
- type: textarea
id: steps
attributes:
label: What steps can reproduce the bug?
description: Explain the bug and provide a code snippet that can reproduce it. Please include session id, token limit usage, context window usage if applicable.
validations:
required: true
- type: textarea
id: expected
attributes:
label: What is the expected behavior?
description: If possible, please provide text instead of a screenshot.
- type: textarea
id: notes
attributes:
label: Additional information
description: Is there anything else you think we should know?

View File

@@ -1,5 +1,5 @@
name: 💻 CLI Bug
description: Report an issue in the Codex CLI
name: 🪲 Bug Report
description: Report an issue that should be fixed
labels:
- bug
- needs triage
@@ -7,16 +7,19 @@ body:
- type: markdown
attributes:
value: |
Before submitting a new issue, please search for existing issues to see if your issue has already been reported.
If it has, please add a 👍 reaction (no need to leave a comment) to the existing issue instead of creating a new one.
Thank you for submitting a bug report! It helps make Codex better for everyone.
If you need help or support using Codex, and are not reporting a bug, please post on [codex/discussions](https://github.com/openai/codex/discussions), where you can ask questions or engage with others on ideas for how to improve codex.
Make sure you are running the [latest](https://npmjs.com/package/@openai/codex) version of Codex CLI. The bug you are experiencing may already have been fixed.
Please try to include as much information as possible.
- type: input
id: version
attributes:
label: What version of Codex CLI is running?
description: use `codex --version`
label: What version of Codex is running?
description: Copy the output of `codex --version`
validations:
required: true
- type: input
@@ -29,13 +32,13 @@ body:
id: model
attributes:
label: Which model were you using?
description: Like `gpt-5.2`, `gpt-5.2-codex`, etc.
description: Like `gpt-4.1`, `o4-mini`, `o3`, etc.
- type: input
id: platform
attributes:
label: What platform is your computer?
description: |
For macOS and Linux: copy the output of `uname -mprs`
For MacOS and Linux: copy the output of `uname -mprs`
For Windows: copy the output of `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` in the PowerShell console
- type: input
id: terminal
@@ -55,7 +58,7 @@ body:
id: steps
attributes:
label: What steps can reproduce the bug?
description: Explain the bug and provide a code snippet that can reproduce it. Please include thread id if applicable.
description: Explain the bug and provide a code snippet that can reproduce it. Please include session id, token limit usage, context window usage if applicable.
validations:
required: true
- type: textarea

View File

@@ -1,37 +0,0 @@
name: 🪲 Other Bug
description: Report an issue in Codex Web, integrations, or other Codex components
labels:
- bug
body:
- type: markdown
attributes:
value: |
Before submitting a new issue, please search for existing issues to see if your issue has already been reported.
If it has, please add a 👍 reaction (no need to leave a comment) to the existing issue instead of creating a new one.
If you need help or support using Codex and are not reporting a bug, please post on [codex/discussions](https://github.com/openai/codex/discussions), where you can ask questions or engage with others on ideas for how to improve codex.
- type: textarea
id: actual
attributes:
label: What issue are you seeing?
description: Please include the full error messages and prompts with PII redacted. If possible, please provide text instead of a screenshot.
validations:
required: true
- type: textarea
id: steps
attributes:
label: What steps can reproduce the bug?
description: Explain the bug and provide a code snippet that can reproduce it.
validations:
required: true
- type: textarea
id: expected
attributes:
label: What is the expected behavior?
description: If possible, please provide text instead of a screenshot.
- type: textarea
id: notes
attributes:
label: Additional information
description: Is there anything else you think we should know?

View File

@@ -12,13 +12,6 @@ body:
1. Search existing issues for similar features. If you find one, 👍 it rather than opening a new one.
2. The Codex team will try to balance the varying needs of the community when prioritizing or rejecting new features. Not all features will be accepted. See [Contributing](https://github.com/openai/codex#contributing) for more details.
- type: input
id: variant
attributes:
label: What variant of Codex are you using?
description: (e.g., App, IDE Extension, CLI, Web)
validations:
required: true
- type: textarea
id: feature
attributes:

View File

@@ -1,7 +1,8 @@
name: 🧑‍💻 IDE Extension Bug
description: Report an issue with the IDE extension
name: 🧑‍💻 VS Code Extension
description: Report an issue with the VS Code extension
labels:
- extension
- needs triage
body:
- type: markdown
attributes:
@@ -12,7 +13,7 @@ body:
- type: input
id: version
attributes:
label: What version of the IDE extension are you using?
label: What version of the VS Code extension are you using?
validations:
required: true
- type: input
@@ -33,20 +34,20 @@ body:
attributes:
label: What platform is your computer?
description: |
For macOS and Linux: copy the output of `uname -mprs`
For MacOS and Linux: copy the output of `uname -mprs`
For Windows: copy the output of `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` in the PowerShell console
- type: textarea
id: actual
attributes:
label: What issue are you seeing?
description: Please include the full error messages and prompts with PII redacted. If possible, please provide text instead of a screenshot.
description: Please include the full error messages and prompts with PII redacted. If possible, please provide text instead of a screenshot.
validations:
required: true
- type: textarea
id: steps
attributes:
label: What steps can reproduce the bug?
description: Explain the bug and provide a code snippet that can reproduce it.
description: Explain the bug and provide a code snippet that can reproduce it. Please include session id, token limit usage, context window usage if applicable.
validations:
required: true
- type: textarea

View File

@@ -100,7 +100,6 @@ jobs:
- name: bazel test //...
env:
BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }}
CODEX_BWRAP_ENABLE_FFI: ${{ contains(matrix.target, 'unknown-linux') && '1' || '0' }}
shell: bash
run: |
bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc test //... \

View File

@@ -64,6 +64,8 @@ jobs:
components: rustfmt
- name: cargo fmt
run: cargo fmt -- --config imports_granularity=Item --check
- name: Verify codegen for mcp-types
run: ./mcp-types/check_lib_rs.py
cargo_shear:
name: cargo shear
@@ -99,9 +101,6 @@ jobs:
USE_SCCACHE: ${{ startsWith(matrix.runner, 'windows') && 'false' || 'true' }}
CARGO_INCREMENTAL: "0"
SCCACHE_CACHE_SIZE: 10G
# Keep cargo-based CI independent of system bwrap build deps.
# The bwrap FFI path is validated in Bazel workflows.
CODEX_BWRAP_ENABLE_FFI: "0"
strategy:
fail-fast: false
@@ -470,9 +469,6 @@ jobs:
USE_SCCACHE: ${{ startsWith(matrix.runner, 'windows') && 'false' || 'true' }}
CARGO_INCREMENTAL: "0"
SCCACHE_CACHE_SIZE: 10G
# Keep cargo-based CI independent of system bwrap build deps.
# The bwrap FFI path is validated in Bazel workflows.
CODEX_BWRAP_ENABLE_FFI: "0"
strategy:
fail-fast: false
@@ -508,6 +504,7 @@ jobs:
steps:
- uses: actions/checkout@v6
# Some integration tests rely on DotSlash being installed.
# See https://github.com/openai/codex/pull/7617.
- name: Install DotSlash

View File

@@ -65,8 +65,6 @@ jobs:
defaults:
run:
working-directory: codex-rs
env:
CODEX_BWRAP_ENABLE_FFI: ${{ contains(matrix.target, 'unknown-linux') && '1' || '0' }}
strategy:
fail-fast: false
@@ -91,13 +89,6 @@ jobs:
steps:
- uses: actions/checkout@v6
- name: Install Linux bwrap build dependencies
if: ${{ runner.os == 'Linux' }}
shell: bash
run: |
set -euo pipefail
sudo apt-get update -y
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
- name: Install UBSan runtime (musl)
if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl' }}
shell: bash

View File

@@ -112,43 +112,3 @@ If you dont have the tool:
let request = mock.single_request();
// assert using request.function_call_output(call_id) or request.json_body() or other helpers.
```
## App-server API Development Best Practices
These guidelines apply to app-server protocol work in `codex-rs`, especially:
- `app-server-protocol/src/protocol/common.rs`
- `app-server-protocol/src/protocol/v2.rs`
- `app-server/README.md`
### Core Rules
- All active API development should happen in app-server v2. Do not add new API surface area to v1.
- Follow payload naming consistently:
`*Params` for request payloads, `*Response` for responses, and `*Notification` for notifications.
- Expose RPC methods as `<resource>/<method>` and keep `<resource>` singular (for example, `thread/read`, `app/list`).
- Always expose fields as camelCase on the wire with `#[serde(rename_all = "camelCase")]` unless a tagged union or explicit compatibility requirement needs a targeted rename.
- Always set `#[ts(export_to = "v2/")]` on v2 request/response/notification types so generated TypeScript lands in the correct namespace.
- Never use `#[serde(skip_serializing_if = "Option::is_none")]` for v2 API payload fields.
Exception: client->server requests that intentionally have no params may use:
`params: #[ts(type = "undefined")] #[serde(skip_serializing_if = "Option::is_none")] Option<()>`.
- For client->server JSON-RPC request payloads (`*Params`) only, every optional field must be annotated with `#[ts(optional = nullable)]`. Do not use `#[ts(optional = nullable)]` outside client->server request payloads (`*Params`).
- For client->server JSON-RPC request payloads only, and you want to express a boolean field where omission means `false`, use `#[serde(default, skip_serializing_if = "std::ops::Not::not")] pub field: bool` over `Option<bool>`.
- For new list methods, implement cursor pagination by default:
request fields `pub cursor: Option<String>` and `pub limit: Option<u32>`,
response fields `pub data: Vec<...>` and `pub next_cursor: Option<String>`.
- Keep Rust and TS wire renames aligned. If a field or variant uses `#[serde(rename = "...")]`, add matching `#[ts(rename = "...")]`.
- For discriminated unions, use explicit tagging in both serializers:
`#[serde(tag = "type", ...)]` and `#[ts(tag = "type", ...)]`.
- Prefer plain `String` IDs at the API boundary (do UUID parsing/conversion internally if needed).
- Timestamps should be integer Unix seconds (`i64`) and named `*_at` (for example, `created_at`, `updated_at`, `resets_at`).
- For experimental API surface area:
use `#[experimental("method/or/field")]`, derive `ExperimentalApi` when field-level gating is needed, and use `inspect_params: true` in `common.rs` when only some fields of a method are experimental.
### Development Workflow
- Update docs/examples when API behavior changes (at minimum `app-server/README.md`).
- Regenerate schema fixtures when API shapes change:
`just write-app-server-schema`
(and `just write-app-server-schema --experimental` when experimental API fixtures are affected).
- Validate with `cargo test -p codex-app-server-protocol`.

685
codex-rs/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -17,7 +17,6 @@ members = [
"cli",
"common",
"core",
"secrets",
"exec",
"exec-server",
"execpolicy",
@@ -28,6 +27,7 @@ members = [
"lmstudio",
"login",
"mcp-server",
"mcp-types",
"network-proxy",
"ollama",
"process-hardening",
@@ -55,7 +55,7 @@ members = [
resolver = "2"
[workspace.package]
version = "0.97.0-alpha.3"
version = "0.95.0-alpha.3"
# Track the edition for all workspace crates in one place. Individual
# crates can still override this value, but keeping it here means new
# crates created with `cargo new -w ...` automatically inherit the 2024
@@ -70,7 +70,6 @@ codex-ansi-escape = { path = "ansi-escape" }
codex-api = { path = "codex-api" }
codex-app-server = { path = "app-server" }
codex-app-server-protocol = { path = "app-server-protocol" }
codex-app-server-test-client = { path = "app-server-test-client" }
codex-apply-patch = { path = "apply-patch" }
codex-arg0 = { path = "arg0" }
codex-async-utils = { path = "async-utils" }
@@ -81,7 +80,6 @@ codex-cli = { path = "cli"}
codex-client = { path = "codex-client" }
codex-common = { path = "common" }
codex-core = { path = "core" }
codex-secrets = { path = "secrets" }
codex-exec = { path = "exec" }
codex-execpolicy = { path = "execpolicy" }
codex-experimental-api-macros = { path = "codex-experimental-api-macros" }
@@ -117,7 +115,6 @@ exec_server_test_support = { path = "exec-server/tests/common" }
mcp_test_support = { path = "mcp-server/tests/common" }
# External
age = "0.11.1"
allocative = "0.3.3"
ansi-to-tui = "7.0.0"
anyhow = "1"
@@ -250,7 +247,6 @@ walkdir = "2.5.0"
webbrowser = "1.0"
which = "8"
wildmatch = "2.6.1"
zip = "2.4.2"
wiremock = "0.6"
zeroize = "1.8.2"
@@ -296,7 +292,7 @@ unwrap_used = "deny"
# cargo-shear cannot see the platform-specific openssl-sys usage, so we
# silence the false positive here instead of deleting a real dependency.
[workspace.metadata.cargo-shear]
ignored = ["icu_provider", "openssl-sys", "codex-utils-readiness", "codex-secrets"]
ignored = ["icu_provider", "openssl-sys", "codex-utils-readiness"]
[profile.release]
lto = "fat"

View File

@@ -480,19 +480,6 @@
},
"type": "object"
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -539,10 +526,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -552,7 +548,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -1042,18 +1038,14 @@
],
"type": "string"
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
"plan",
"default"
"code",
"pair_programming",
"execute",
"custom"
],
"type": "string"
},
@@ -1175,7 +1167,6 @@
},
"Personality": {
"enum": [
"none",
"friendly",
"pragmatic"
],
@@ -1326,16 +1317,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -1412,7 +1393,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"
@@ -2188,24 +2169,6 @@
},
"type": "object"
},
"SkillsRemoteReadParams": {
"type": "object"
},
"SkillsRemoteWriteParams": {
"properties": {
"hazelnutId": {
"type": "string"
},
"isPreload": {
"type": "boolean"
}
},
"required": [
"hazelnutId",
"isPreload"
],
"type": "object"
},
"TextElement": {
"properties": {
"byteRange": {
@@ -2240,17 +2203,6 @@
],
"type": "object"
},
"ThreadCompactStartParams": {
"properties": {
"threadId": {
"type": "string"
}
},
"required": [
"threadId"
],
"type": "object"
},
"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": {
@@ -3226,30 +3178,6 @@
"title": "Thread/unarchiveRequest",
"type": "object"
},
{
"properties": {
"id": {
"$ref": "#/definitions/RequestId"
},
"method": {
"enum": [
"thread/compact/start"
],
"title": "Thread/compact/startRequestMethod",
"type": "string"
},
"params": {
"$ref": "#/definitions/ThreadCompactStartParams"
}
},
"required": [
"id",
"method",
"params"
],
"title": "Thread/compact/startRequest",
"type": "object"
},
{
"properties": {
"id": {
@@ -3370,54 +3298,6 @@
"title": "Skills/listRequest",
"type": "object"
},
{
"properties": {
"id": {
"$ref": "#/definitions/RequestId"
},
"method": {
"enum": [
"skills/remote/read"
],
"title": "Skills/remote/readRequestMethod",
"type": "string"
},
"params": {
"$ref": "#/definitions/SkillsRemoteReadParams"
}
},
"required": [
"id",
"method",
"params"
],
"title": "Skills/remote/readRequest",
"type": "object"
},
{
"properties": {
"id": {
"$ref": "#/definitions/RequestId"
},
"method": {
"enum": [
"skills/remote/write"
],
"title": "Skills/remote/writeRequestMethod",
"type": "string"
},
"params": {
"$ref": "#/definitions/SkillsRemoteWriteParams"
}
},
"required": [
"id",
"method",
"params"
],
"title": "Skills/remote/writeRequest",
"type": "object"
},
{
"properties": {
"id": {

View File

@@ -1,64 +1,15 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"DynamicToolCallOutputContentItem": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"inputText"
],
"title": "InputTextDynamicToolCallOutputContentItemType",
"type": "string"
}
},
"required": [
"text",
"type"
],
"title": "InputTextDynamicToolCallOutputContentItem",
"type": "object"
},
{
"properties": {
"imageUrl": {
"type": "string"
},
"type": {
"enum": [
"inputImage"
],
"title": "InputImageDynamicToolCallOutputContentItemType",
"type": "string"
}
},
"required": [
"imageUrl",
"type"
],
"title": "InputImageDynamicToolCallOutputContentItem",
"type": "object"
}
]
}
},
"properties": {
"contentItems": {
"items": {
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
},
"type": "array"
"output": {
"type": "string"
},
"success": {
"type": "boolean"
}
},
"required": [
"contentItems",
"output",
"success"
],
"title": "DynamicToolCallResponse",

View File

@@ -551,7 +551,7 @@
"$ref": "#/definitions/ModeKind"
}
],
"default": "default"
"default": "code"
},
"model_context_window": {
"format": "int64",
@@ -2012,59 +2012,6 @@
"title": "ListSkillsResponseEventMsg",
"type": "object"
},
{
"description": "List of remote skills available to the agent.",
"properties": {
"skills": {
"items": {
"$ref": "#/definitions/RemoteSkillSummary"
},
"type": "array"
},
"type": {
"enum": [
"list_remote_skills_response"
],
"title": "ListRemoteSkillsResponseEventMsgType",
"type": "string"
}
},
"required": [
"skills",
"type"
],
"title": "ListRemoteSkillsResponseEventMsg",
"type": "object"
},
{
"description": "Remote skill downloaded to local cache.",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"type": {
"enum": [
"remote_skill_downloaded"
],
"title": "RemoteSkillDownloadedEventMsgType",
"type": "string"
}
},
"required": [
"id",
"name",
"path",
"type"
],
"title": "RemoteSkillDownloadedEventMsg",
"type": "object"
},
{
"description": "Notification that skill data may have been updated and clients may want to reload.",
"properties": {
@@ -2864,19 +2811,6 @@
}
]
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -2923,10 +2857,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -2936,7 +2879,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -3168,18 +3111,14 @@
}
]
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
"plan",
"default"
"code",
"pair_programming",
"execute",
"custom"
],
"type": "string"
},
@@ -3486,25 +3425,6 @@
}
]
},
"RemoteSkillSummary": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"description",
"id",
"name"
],
"type": "object"
},
"RequestId": {
"anyOf": [
{
@@ -3676,16 +3596,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -3762,7 +3672,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"
@@ -5151,7 +5061,7 @@
"$ref": "#/definitions/ModeKind"
}
],
"default": "default"
"default": "code"
},
"model_context_window": {
"format": "int64",
@@ -6612,59 +6522,6 @@
"title": "ListSkillsResponseEventMsg",
"type": "object"
},
{
"description": "List of remote skills available to the agent.",
"properties": {
"skills": {
"items": {
"$ref": "#/definitions/RemoteSkillSummary"
},
"type": "array"
},
"type": {
"enum": [
"list_remote_skills_response"
],
"title": "ListRemoteSkillsResponseEventMsgType",
"type": "string"
}
},
"required": [
"skills",
"type"
],
"title": "ListRemoteSkillsResponseEventMsg",
"type": "object"
},
{
"description": "Remote skill downloaded to local cache.",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"type": {
"enum": [
"remote_skill_downloaded"
],
"title": "RemoteSkillDownloadedEventMsgType",
"type": "string"
}
},
"required": [
"id",
"name",
"path",
"type"
],
"title": "RemoteSkillDownloadedEventMsg",
"type": "object"
},
{
"description": "Notification that skill data may have been updated and clients may want to reload.",
"properties": {

View File

@@ -1129,7 +1129,7 @@
"$ref": "#/definitions/ModeKind"
}
],
"default": "default"
"default": "code"
},
"model_context_window": {
"format": "int64",
@@ -2590,59 +2590,6 @@
"title": "ListSkillsResponseEventMsg",
"type": "object"
},
{
"description": "List of remote skills available to the agent.",
"properties": {
"skills": {
"items": {
"$ref": "#/definitions/RemoteSkillSummary"
},
"type": "array"
},
"type": {
"enum": [
"list_remote_skills_response"
],
"title": "ListRemoteSkillsResponseEventMsgType",
"type": "string"
}
},
"required": [
"skills",
"type"
],
"title": "ListRemoteSkillsResponseEventMsg",
"type": "object"
},
{
"description": "Remote skill downloaded to local cache.",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"type": {
"enum": [
"remote_skill_downloaded"
],
"title": "RemoteSkillDownloadedEventMsgType",
"type": "string"
}
},
"required": [
"id",
"name",
"path",
"type"
],
"title": "RemoteSkillDownloadedEventMsg",
"type": "object"
},
{
"description": "Notification that skill data may have been updated and clients may want to reload.",
"properties": {
@@ -3484,19 +3431,6 @@
],
"type": "object"
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -3543,10 +3477,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -3556,7 +3499,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -3947,18 +3890,14 @@
],
"type": "string"
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
"plan",
"default"
"code",
"pair_programming",
"execute",
"custom"
],
"type": "string"
},
@@ -4526,25 +4465,6 @@
],
"type": "object"
},
"RemoteSkillSummary": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"description",
"id",
"name"
],
"type": "object"
},
"RequestId": {
"anyOf": [
{
@@ -4716,16 +4636,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -4802,7 +4712,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"

View File

@@ -598,30 +598,6 @@
"title": "Thread/unarchiveRequest",
"type": "object"
},
{
"properties": {
"id": {
"$ref": "#/definitions/RequestId"
},
"method": {
"enum": [
"thread/compact/start"
],
"title": "Thread/compact/startRequestMethod",
"type": "string"
},
"params": {
"$ref": "#/definitions/v2/ThreadCompactStartParams"
}
},
"required": [
"id",
"method",
"params"
],
"title": "Thread/compact/startRequest",
"type": "object"
},
{
"properties": {
"id": {
@@ -742,54 +718,6 @@
"title": "Skills/listRequest",
"type": "object"
},
{
"properties": {
"id": {
"$ref": "#/definitions/RequestId"
},
"method": {
"enum": [
"skills/remote/read"
],
"title": "Skills/remote/readRequestMethod",
"type": "string"
},
"params": {
"$ref": "#/definitions/v2/SkillsRemoteReadParams"
}
},
"required": [
"id",
"method",
"params"
],
"title": "Skills/remote/readRequest",
"type": "object"
},
{
"properties": {
"id": {
"$ref": "#/definitions/RequestId"
},
"method": {
"enum": [
"skills/remote/write"
],
"title": "Skills/remote/writeRequestMethod",
"type": "string"
},
"params": {
"$ref": "#/definitions/v2/SkillsRemoteWriteParams"
}
},
"required": [
"id",
"method",
"params"
],
"title": "Skills/remote/writeRequest",
"type": "object"
},
{
"properties": {
"id": {
@@ -2312,50 +2240,6 @@
],
"type": "object"
},
"DynamicToolCallOutputContentItem": {
"oneOf": [
{
"properties": {
"text": {
"type": "string"
},
"type": {
"enum": [
"inputText"
],
"title": "InputTextDynamicToolCallOutputContentItemType",
"type": "string"
}
},
"required": [
"text",
"type"
],
"title": "InputTextDynamicToolCallOutputContentItem",
"type": "object"
},
{
"properties": {
"imageUrl": {
"type": "string"
},
"type": {
"enum": [
"inputImage"
],
"title": "InputImageDynamicToolCallOutputContentItemType",
"type": "string"
}
},
"required": [
"imageUrl",
"type"
],
"title": "InputImageDynamicToolCallOutputContentItem",
"type": "object"
}
]
},
"DynamicToolCallParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
@@ -2386,18 +2270,15 @@
"DynamicToolCallResponse": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"contentItems": {
"items": {
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
},
"type": "array"
"output": {
"type": "string"
},
"success": {
"type": "boolean"
}
},
"required": [
"contentItems",
"output",
"success"
],
"title": "DynamicToolCallResponse",
@@ -2510,7 +2391,7 @@
"$ref": "#/definitions/v2/ModeKind"
}
],
"default": "default"
"default": "code"
},
"model_context_window": {
"format": "int64",
@@ -3971,59 +3852,6 @@
"title": "ListSkillsResponseEventMsg",
"type": "object"
},
{
"description": "List of remote skills available to the agent.",
"properties": {
"skills": {
"items": {
"$ref": "#/definitions/v2/RemoteSkillSummary"
},
"type": "array"
},
"type": {
"enum": [
"list_remote_skills_response"
],
"title": "ListRemoteSkillsResponseEventMsgType",
"type": "string"
}
},
"required": [
"skills",
"type"
],
"title": "ListRemoteSkillsResponseEventMsg",
"type": "object"
},
{
"description": "Remote skill downloaded to local cache.",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"type": {
"enum": [
"remote_skill_downloaded"
],
"title": "RemoteSkillDownloadedEventMsgType",
"type": "string"
}
},
"required": [
"id",
"name",
"path",
"type"
],
"title": "RemoteSkillDownloadedEventMsg",
"type": "object"
},
{
"description": "Notification that skill data may have been updated and clients may want to reload.",
"properties": {
@@ -5091,19 +4919,6 @@
"title": "ForkConversationResponse",
"type": "object"
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -5150,10 +4965,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -5163,7 +4987,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -6015,18 +5839,14 @@
}
]
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
"plan",
"default"
"code",
"pair_programming",
"execute",
"custom"
],
"type": "string"
},
@@ -6527,25 +6347,6 @@
}
]
},
"RemoteSkillSummary": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"description",
"id",
"name"
],
"type": "object"
},
"RemoveConversationListenerParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
@@ -6735,16 +6536,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -6821,7 +6612,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"
@@ -11297,19 +11088,6 @@
],
"type": "string"
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/v2/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -11356,10 +11134,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/v2/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/v2/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -11369,7 +11156,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -11476,25 +11263,6 @@
},
"type": "object"
},
"InputModality": {
"description": "Canonical user-input modality tags advertised by a model.",
"oneOf": [
{
"description": "Plain text turns and tool payloads.",
"enum": [
"text"
],
"type": "string"
},
{
"description": "Image attachments included in user turns.",
"enum": [
"image"
],
"type": "string"
}
]
},
"ItemCompletedNotification": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
@@ -11963,18 +11731,14 @@
],
"type": "string"
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
"plan",
"default"
"code",
"pair_programming",
"execute",
"custom"
],
"type": "string"
},
@@ -11992,16 +11756,6 @@
"id": {
"type": "string"
},
"inputModalities": {
"default": [
"text",
"image"
],
"items": {
"$ref": "#/definitions/v2/InputModality"
},
"type": "array"
},
"isDefault": {
"type": "boolean"
},
@@ -12017,12 +11771,6 @@
"supportsPersonality": {
"default": false,
"type": "boolean"
},
"upgrade": {
"type": [
"string",
"null"
]
}
},
"required": [
@@ -12175,7 +11923,6 @@
},
"Personality": {
"enum": [
"none",
"friendly",
"pragmatic"
],
@@ -12588,25 +12335,6 @@
"title": "ReasoningTextDeltaNotification",
"type": "object"
},
"RemoteSkillSummary": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"description",
"id",
"name"
],
"type": "object"
},
"ResidencyRequirement": {
"enum": [
"us"
@@ -12721,16 +12449,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/v2/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -12807,7 +12525,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"
@@ -13642,65 +13360,6 @@
"title": "SkillsListResponse",
"type": "object"
},
"SkillsRemoteReadParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "SkillsRemoteReadParams",
"type": "object"
},
"SkillsRemoteReadResponse": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"data": {
"items": {
"$ref": "#/definitions/v2/RemoteSkillSummary"
},
"type": "array"
}
},
"required": [
"data"
],
"title": "SkillsRemoteReadResponse",
"type": "object"
},
"SkillsRemoteWriteParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"hazelnutId": {
"type": "string"
},
"isPreload": {
"type": "boolean"
}
},
"required": [
"hazelnutId",
"isPreload"
],
"title": "SkillsRemoteWriteParams",
"type": "object"
},
"SkillsRemoteWriteResponse": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"id",
"name",
"path"
],
"title": "SkillsRemoteWriteResponse",
"type": "object"
},
"SubAgentSource": {
"oneOf": [
{
@@ -13935,24 +13594,6 @@
"title": "ThreadArchiveResponse",
"type": "object"
},
"ThreadCompactStartParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"threadId": {
"type": "string"
}
},
"required": [
"threadId"
],
"title": "ThreadCompactStartParams",
"type": "object"
},
"ThreadCompactStartResponse": {
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ThreadCompactStartResponse",
"type": "object"
},
"ThreadForkParams": {
"$schema": "http://json-schema.org/draft-07/schema#",
"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.",

View File

@@ -551,7 +551,7 @@
"$ref": "#/definitions/ModeKind"
}
],
"default": "default"
"default": "code"
},
"model_context_window": {
"format": "int64",
@@ -2012,59 +2012,6 @@
"title": "ListSkillsResponseEventMsg",
"type": "object"
},
{
"description": "List of remote skills available to the agent.",
"properties": {
"skills": {
"items": {
"$ref": "#/definitions/RemoteSkillSummary"
},
"type": "array"
},
"type": {
"enum": [
"list_remote_skills_response"
],
"title": "ListRemoteSkillsResponseEventMsgType",
"type": "string"
}
},
"required": [
"skills",
"type"
],
"title": "ListRemoteSkillsResponseEventMsg",
"type": "object"
},
{
"description": "Remote skill downloaded to local cache.",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"type": {
"enum": [
"remote_skill_downloaded"
],
"title": "RemoteSkillDownloadedEventMsgType",
"type": "string"
}
},
"required": [
"id",
"name",
"path",
"type"
],
"title": "RemoteSkillDownloadedEventMsg",
"type": "object"
},
{
"description": "Notification that skill data may have been updated and clients may want to reload.",
"properties": {
@@ -2864,19 +2811,6 @@
}
]
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -2923,10 +2857,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -2936,7 +2879,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -3168,18 +3111,14 @@
}
]
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
"plan",
"default"
"code",
"pair_programming",
"execute",
"custom"
],
"type": "string"
},
@@ -3486,25 +3425,6 @@
}
]
},
"RemoteSkillSummary": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"description",
"id",
"name"
],
"type": "object"
},
"RequestId": {
"anyOf": [
{
@@ -3676,16 +3596,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -3762,7 +3672,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"

View File

@@ -98,19 +98,6 @@
}
]
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -157,10 +144,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -170,7 +166,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -270,13 +266,6 @@
],
"type": "string"
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"NewConversationParams": {
"properties": {
"approvalPolicy": {
@@ -448,16 +437,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -534,7 +513,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"

View File

@@ -551,7 +551,7 @@
"$ref": "#/definitions/ModeKind"
}
],
"default": "default"
"default": "code"
},
"model_context_window": {
"format": "int64",
@@ -2012,59 +2012,6 @@
"title": "ListSkillsResponseEventMsg",
"type": "object"
},
{
"description": "List of remote skills available to the agent.",
"properties": {
"skills": {
"items": {
"$ref": "#/definitions/RemoteSkillSummary"
},
"type": "array"
},
"type": {
"enum": [
"list_remote_skills_response"
],
"title": "ListRemoteSkillsResponseEventMsgType",
"type": "string"
}
},
"required": [
"skills",
"type"
],
"title": "ListRemoteSkillsResponseEventMsg",
"type": "object"
},
{
"description": "Remote skill downloaded to local cache.",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"type": {
"enum": [
"remote_skill_downloaded"
],
"title": "RemoteSkillDownloadedEventMsgType",
"type": "string"
}
},
"required": [
"id",
"name",
"path",
"type"
],
"title": "RemoteSkillDownloadedEventMsg",
"type": "object"
},
{
"description": "Notification that skill data may have been updated and clients may want to reload.",
"properties": {
@@ -2864,19 +2811,6 @@
}
]
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -2923,10 +2857,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -2936,7 +2879,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -3168,18 +3111,14 @@
}
]
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
"plan",
"default"
"code",
"pair_programming",
"execute",
"custom"
],
"type": "string"
},
@@ -3486,25 +3425,6 @@
}
]
},
"RemoteSkillSummary": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"description",
"id",
"name"
],
"type": "object"
},
"RequestId": {
"anyOf": [
{
@@ -3676,16 +3596,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -3762,7 +3672,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"

View File

@@ -551,7 +551,7 @@
"$ref": "#/definitions/ModeKind"
}
],
"default": "default"
"default": "code"
},
"model_context_window": {
"format": "int64",
@@ -2012,59 +2012,6 @@
"title": "ListSkillsResponseEventMsg",
"type": "object"
},
{
"description": "List of remote skills available to the agent.",
"properties": {
"skills": {
"items": {
"$ref": "#/definitions/RemoteSkillSummary"
},
"type": "array"
},
"type": {
"enum": [
"list_remote_skills_response"
],
"title": "ListRemoteSkillsResponseEventMsgType",
"type": "string"
}
},
"required": [
"skills",
"type"
],
"title": "ListRemoteSkillsResponseEventMsg",
"type": "object"
},
{
"description": "Remote skill downloaded to local cache.",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
},
"type": {
"enum": [
"remote_skill_downloaded"
],
"title": "RemoteSkillDownloadedEventMsgType",
"type": "string"
}
},
"required": [
"id",
"name",
"path",
"type"
],
"title": "RemoteSkillDownloadedEventMsg",
"type": "object"
},
{
"description": "Notification that skill data may have been updated and clients may want to reload.",
"properties": {
@@ -2864,19 +2811,6 @@
}
]
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -2923,10 +2857,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -2936,7 +2879,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -3168,18 +3111,14 @@
}
]
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"ModeKind": {
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
"plan",
"default"
"code",
"pair_programming",
"execute",
"custom"
],
"type": "string"
},
@@ -3486,25 +3425,6 @@
}
]
},
"RemoteSkillSummary": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"description",
"id",
"name"
],
"type": "object"
},
"RequestId": {
"anyOf": [
{
@@ -3676,16 +3596,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -3762,7 +3672,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"

View File

@@ -1,25 +1,6 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"InputModality": {
"description": "Canonical user-input modality tags advertised by a model.",
"oneOf": [
{
"description": "Plain text turns and tool payloads.",
"enum": [
"text"
],
"type": "string"
},
{
"description": "Image attachments included in user turns.",
"enum": [
"image"
],
"type": "string"
}
]
},
"Model": {
"properties": {
"defaultReasoningEffort": {
@@ -34,16 +15,6 @@
"id": {
"type": "string"
},
"inputModalities": {
"default": [
"text",
"image"
],
"items": {
"$ref": "#/definitions/InputModality"
},
"type": "array"
},
"isDefault": {
"type": "boolean"
},
@@ -59,12 +30,6 @@
"supportsPersonality": {
"default": false,
"type": "boolean"
},
"upgrade": {
"type": [
"string",
"null"
]
}
},
"required": [

View File

@@ -65,19 +65,6 @@
}
]
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -124,10 +111,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -137,7 +133,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -237,13 +233,6 @@
],
"type": "string"
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"ReasoningItemContent": {
"oneOf": [
{
@@ -335,16 +324,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -421,7 +400,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"

View File

@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "SkillsRemoteReadParams",
"type": "object"
}

View File

@@ -1,37 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"RemoteSkillSummary": {
"properties": {
"description": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"description",
"id",
"name"
],
"type": "object"
}
},
"properties": {
"data": {
"items": {
"$ref": "#/definitions/RemoteSkillSummary"
},
"type": "array"
}
},
"required": [
"data"
],
"title": "SkillsRemoteReadResponse",
"type": "object"
}

View File

@@ -1,17 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"hazelnutId": {
"type": "string"
},
"isPreload": {
"type": "boolean"
}
},
"required": [
"hazelnutId",
"isPreload"
],
"title": "SkillsRemoteWriteParams",
"type": "object"
}

View File

@@ -1,21 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"id",
"name",
"path"
],
"title": "SkillsRemoteWriteResponse",
"type": "object"
}

View File

@@ -1,13 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"threadId": {
"type": "string"
}
},
"required": [
"threadId"
],
"title": "ThreadCompactStartParams",
"type": "object"
}

View File

@@ -1,5 +0,0 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ThreadCompactStartResponse",
"type": "object"
}

View File

@@ -74,19 +74,6 @@
}
]
},
"FunctionCallOutputBody": {
"anyOf": [
{
"type": "string"
},
{
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": "array"
}
]
},
"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": [
@@ -133,10 +120,19 @@
]
},
"FunctionCallOutputPayload": {
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`body` serializes directly as the wire value for `function_call_output.output`. `success` remains internal metadata for downstream handling.",
"description": "The payload we send back to OpenAI when reporting a tool call result.\n\n`content` preserves the historical plain-string payload so downstream integrations (tests, logging, etc.) can keep treating tool output as `String`. When an MCP server returns richer data we additionally populate `content_items` with the structured form that the Responses/Chat Completions APIs understand.",
"properties": {
"body": {
"$ref": "#/definitions/FunctionCallOutputBody"
"content": {
"type": "string"
},
"content_items": {
"items": {
"$ref": "#/definitions/FunctionCallOutputContentItem"
},
"type": [
"array",
"null"
]
},
"success": {
"type": [
@@ -146,7 +142,7 @@
}
},
"required": [
"body"
"content"
],
"type": "object"
},
@@ -246,16 +242,8 @@
],
"type": "string"
},
"MessagePhase": {
"enum": [
"commentary",
"final_answer"
],
"type": "string"
},
"Personality": {
"enum": [
"none",
"friendly",
"pragmatic"
],
@@ -352,16 +340,6 @@
],
"writeOnly": true
},
"phase": {
"anyOf": [
{
"$ref": "#/definitions/MessagePhase"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
@@ -438,7 +416,7 @@
]
},
"id": {
"description": "Legacy id field retained for compatibility with older payloads.",
"description": "Set when using the chat completions API.",
"type": [
"string",
"null"

View File

@@ -29,7 +29,6 @@
},
"Personality": {
"enum": [
"none",
"friendly",
"pragmatic"
],

View File

@@ -53,7 +53,10 @@
"description": "Initial collaboration mode to use when the TUI starts.",
"enum": [
"plan",
"default"
"code",
"pair_programming",
"execute",
"custom"
],
"type": "string"
},
@@ -66,7 +69,6 @@
},
"Personality": {
"enum": [
"none",
"friendly",
"pragmatic"
],

View File

@@ -36,10 +36,7 @@ import type { ModelListParams } from "./v2/ModelListParams";
import type { ReviewStartParams } from "./v2/ReviewStartParams";
import type { SkillsConfigWriteParams } from "./v2/SkillsConfigWriteParams";
import type { SkillsListParams } from "./v2/SkillsListParams";
import type { SkillsRemoteReadParams } from "./v2/SkillsRemoteReadParams";
import type { SkillsRemoteWriteParams } from "./v2/SkillsRemoteWriteParams";
import type { ThreadArchiveParams } from "./v2/ThreadArchiveParams";
import type { ThreadCompactStartParams } from "./v2/ThreadCompactStartParams";
import type { ThreadForkParams } from "./v2/ThreadForkParams";
import type { ThreadListParams } from "./v2/ThreadListParams";
import type { ThreadLoadedListParams } from "./v2/ThreadLoadedListParams";
@@ -55,4 +52,4 @@ import type { TurnStartParams } from "./v2/TurnStartParams";
/**
* Request from the client to the server.
*/
export type ClientRequest ={ "method": "initialize", id: RequestId, params: InitializeParams, } | { "method": "thread/start", id: RequestId, params: ThreadStartParams, } | { "method": "thread/resume", id: RequestId, params: ThreadResumeParams, } | { "method": "thread/fork", id: RequestId, params: ThreadForkParams, } | { "method": "thread/archive", id: RequestId, params: ThreadArchiveParams, } | { "method": "thread/name/set", id: RequestId, params: ThreadSetNameParams, } | { "method": "thread/unarchive", id: RequestId, params: ThreadUnarchiveParams, } | { "method": "thread/compact/start", id: RequestId, params: ThreadCompactStartParams, } | { "method": "thread/rollback", id: RequestId, params: ThreadRollbackParams, } | { "method": "thread/list", id: RequestId, params: ThreadListParams, } | { "method": "thread/loaded/list", id: RequestId, params: ThreadLoadedListParams, } | { "method": "thread/read", id: RequestId, params: ThreadReadParams, } | { "method": "skills/list", id: RequestId, params: SkillsListParams, } | { "method": "skills/remote/read", id: RequestId, params: SkillsRemoteReadParams, } | { "method": "skills/remote/write", id: RequestId, params: SkillsRemoteWriteParams, } | { "method": "app/list", id: RequestId, params: AppsListParams, } | { "method": "skills/config/write", id: RequestId, params: SkillsConfigWriteParams, } | { "method": "turn/start", id: RequestId, params: TurnStartParams, } | { "method": "turn/interrupt", id: RequestId, params: TurnInterruptParams, } | { "method": "review/start", id: RequestId, params: ReviewStartParams, } | { "method": "model/list", id: RequestId, params: ModelListParams, } | { "method": "mcpServer/oauth/login", id: RequestId, params: McpServerOauthLoginParams, } | { "method": "config/mcpServer/reload", id: RequestId, params: undefined, } | { "method": "mcpServerStatus/list", id: RequestId, params: ListMcpServerStatusParams, } | { "method": "account/login/start", id: RequestId, params: LoginAccountParams, } | { "method": "account/login/cancel", id: RequestId, params: CancelLoginAccountParams, } | { "method": "account/logout", id: RequestId, params: undefined, } | { "method": "account/rateLimits/read", id: RequestId, params: undefined, } | { "method": "feedback/upload", id: RequestId, params: FeedbackUploadParams, } | { "method": "command/exec", id: RequestId, params: CommandExecParams, } | { "method": "config/read", id: RequestId, params: ConfigReadParams, } | { "method": "config/value/write", id: RequestId, params: ConfigValueWriteParams, } | { "method": "config/batchWrite", id: RequestId, params: ConfigBatchWriteParams, } | { "method": "configRequirements/read", id: RequestId, params: undefined, } | { "method": "account/read", id: RequestId, params: GetAccountParams, } | { "method": "newConversation", id: RequestId, params: NewConversationParams, } | { "method": "getConversationSummary", id: RequestId, params: GetConversationSummaryParams, } | { "method": "listConversations", id: RequestId, params: ListConversationsParams, } | { "method": "resumeConversation", id: RequestId, params: ResumeConversationParams, } | { "method": "forkConversation", id: RequestId, params: ForkConversationParams, } | { "method": "archiveConversation", id: RequestId, params: ArchiveConversationParams, } | { "method": "sendUserMessage", id: RequestId, params: SendUserMessageParams, } | { "method": "sendUserTurn", id: RequestId, params: SendUserTurnParams, } | { "method": "interruptConversation", id: RequestId, params: InterruptConversationParams, } | { "method": "addConversationListener", id: RequestId, params: AddConversationListenerParams, } | { "method": "removeConversationListener", id: RequestId, params: RemoveConversationListenerParams, } | { "method": "gitDiffToRemote", id: RequestId, params: GitDiffToRemoteParams, } | { "method": "loginApiKey", id: RequestId, params: LoginApiKeyParams, } | { "method": "loginChatGpt", id: RequestId, params: undefined, } | { "method": "cancelLoginChatGpt", id: RequestId, params: CancelLoginChatGptParams, } | { "method": "logoutChatGpt", id: RequestId, params: undefined, } | { "method": "getAuthStatus", id: RequestId, params: GetAuthStatusParams, } | { "method": "getUserSavedConfig", id: RequestId, params: undefined, } | { "method": "setDefaultModel", id: RequestId, params: SetDefaultModelParams, } | { "method": "getUserAgent", id: RequestId, params: undefined, } | { "method": "userInfo", id: RequestId, params: undefined, } | { "method": "fuzzyFileSearch", id: RequestId, params: FuzzyFileSearchParams, } | { "method": "execOneOffCommand", id: RequestId, params: ExecOneOffCommandParams, };
export type ClientRequest ={ "method": "initialize", id: RequestId, params: InitializeParams, } | { "method": "thread/start", id: RequestId, params: ThreadStartParams, } | { "method": "thread/resume", id: RequestId, params: ThreadResumeParams, } | { "method": "thread/fork", id: RequestId, params: ThreadForkParams, } | { "method": "thread/archive", id: RequestId, params: ThreadArchiveParams, } | { "method": "thread/name/set", id: RequestId, params: ThreadSetNameParams, } | { "method": "thread/unarchive", id: RequestId, params: ThreadUnarchiveParams, } | { "method": "thread/rollback", id: RequestId, params: ThreadRollbackParams, } | { "method": "thread/list", id: RequestId, params: ThreadListParams, } | { "method": "thread/loaded/list", id: RequestId, params: ThreadLoadedListParams, } | { "method": "thread/read", id: RequestId, params: ThreadReadParams, } | { "method": "skills/list", id: RequestId, params: SkillsListParams, } | { "method": "app/list", id: RequestId, params: AppsListParams, } | { "method": "skills/config/write", id: RequestId, params: SkillsConfigWriteParams, } | { "method": "turn/start", id: RequestId, params: TurnStartParams, } | { "method": "turn/interrupt", id: RequestId, params: TurnInterruptParams, } | { "method": "review/start", id: RequestId, params: ReviewStartParams, } | { "method": "model/list", id: RequestId, params: ModelListParams, } | { "method": "mcpServer/oauth/login", id: RequestId, params: McpServerOauthLoginParams, } | { "method": "config/mcpServer/reload", id: RequestId, params: undefined, } | { "method": "mcpServerStatus/list", id: RequestId, params: ListMcpServerStatusParams, } | { "method": "account/login/start", id: RequestId, params: LoginAccountParams, } | { "method": "account/login/cancel", id: RequestId, params: CancelLoginAccountParams, } | { "method": "account/logout", id: RequestId, params: undefined, } | { "method": "account/rateLimits/read", id: RequestId, params: undefined, } | { "method": "feedback/upload", id: RequestId, params: FeedbackUploadParams, } | { "method": "command/exec", id: RequestId, params: CommandExecParams, } | { "method": "config/read", id: RequestId, params: ConfigReadParams, } | { "method": "config/value/write", id: RequestId, params: ConfigValueWriteParams, } | { "method": "config/batchWrite", id: RequestId, params: ConfigBatchWriteParams, } | { "method": "configRequirements/read", id: RequestId, params: undefined, } | { "method": "account/read", id: RequestId, params: GetAccountParams, } | { "method": "newConversation", id: RequestId, params: NewConversationParams, } | { "method": "getConversationSummary", id: RequestId, params: GetConversationSummaryParams, } | { "method": "listConversations", id: RequestId, params: ListConversationsParams, } | { "method": "resumeConversation", id: RequestId, params: ResumeConversationParams, } | { "method": "forkConversation", id: RequestId, params: ForkConversationParams, } | { "method": "archiveConversation", id: RequestId, params: ArchiveConversationParams, } | { "method": "sendUserMessage", id: RequestId, params: SendUserMessageParams, } | { "method": "sendUserTurn", id: RequestId, params: SendUserTurnParams, } | { "method": "interruptConversation", id: RequestId, params: InterruptConversationParams, } | { "method": "addConversationListener", id: RequestId, params: AddConversationListenerParams, } | { "method": "removeConversationListener", id: RequestId, params: RemoveConversationListenerParams, } | { "method": "gitDiffToRemote", id: RequestId, params: GitDiffToRemoteParams, } | { "method": "loginApiKey", id: RequestId, params: LoginApiKeyParams, } | { "method": "loginChatGpt", id: RequestId, params: undefined, } | { "method": "cancelLoginChatGpt", id: RequestId, params: CancelLoginChatGptParams, } | { "method": "logoutChatGpt", id: RequestId, params: undefined, } | { "method": "getAuthStatus", id: RequestId, params: GetAuthStatusParams, } | { "method": "getUserSavedConfig", id: RequestId, params: undefined, } | { "method": "setDefaultModel", id: RequestId, params: SetDefaultModelParams, } | { "method": "getUserAgent", id: RequestId, params: undefined, } | { "method": "userInfo", id: RequestId, params: undefined, } | { "method": "fuzzyFileSearch", id: RequestId, params: FuzzyFileSearchParams, } | { "method": "execOneOffCommand", id: RequestId, params: ExecOneOffCommandParams, };

View File

@@ -33,7 +33,6 @@ import type { GetHistoryEntryResponseEvent } from "./GetHistoryEntryResponseEven
import type { ItemCompletedEvent } from "./ItemCompletedEvent";
import type { ItemStartedEvent } from "./ItemStartedEvent";
import type { ListCustomPromptsResponseEvent } from "./ListCustomPromptsResponseEvent";
import type { ListRemoteSkillsResponseEvent } from "./ListRemoteSkillsResponseEvent";
import type { ListSkillsResponseEvent } from "./ListSkillsResponseEvent";
import type { McpListToolsResponseEvent } from "./McpListToolsResponseEvent";
import type { McpStartupCompleteEvent } from "./McpStartupCompleteEvent";
@@ -46,7 +45,6 @@ import type { PlanDeltaEvent } from "./PlanDeltaEvent";
import type { RawResponseItemEvent } from "./RawResponseItemEvent";
import type { ReasoningContentDeltaEvent } from "./ReasoningContentDeltaEvent";
import type { ReasoningRawContentDeltaEvent } from "./ReasoningRawContentDeltaEvent";
import type { RemoteSkillDownloadedEvent } from "./RemoteSkillDownloadedEvent";
import type { RequestUserInputEvent } from "./RequestUserInputEvent";
import type { ReviewRequest } from "./ReviewRequest";
import type { SessionConfiguredEvent } from "./SessionConfiguredEvent";
@@ -72,4 +70,4 @@ import type { WebSearchEndEvent } from "./WebSearchEndEvent";
* Response event from the agent
* NOTE: Make sure none of these values have optional types, as it will mess up the extension code-gen.
*/
export type EventMsg = { "type": "error" } & ErrorEvent | { "type": "warning" } & WarningEvent | { "type": "context_compacted" } & ContextCompactedEvent | { "type": "thread_rolled_back" } & ThreadRolledBackEvent | { "type": "task_started" } & TurnStartedEvent | { "type": "task_complete" } & TurnCompleteEvent | { "type": "token_count" } & TokenCountEvent | { "type": "agent_message" } & AgentMessageEvent | { "type": "user_message" } & UserMessageEvent | { "type": "agent_message_delta" } & AgentMessageDeltaEvent | { "type": "agent_reasoning" } & AgentReasoningEvent | { "type": "agent_reasoning_delta" } & AgentReasoningDeltaEvent | { "type": "agent_reasoning_raw_content" } & AgentReasoningRawContentEvent | { "type": "agent_reasoning_raw_content_delta" } & AgentReasoningRawContentDeltaEvent | { "type": "agent_reasoning_section_break" } & AgentReasoningSectionBreakEvent | { "type": "session_configured" } & SessionConfiguredEvent | { "type": "thread_name_updated" } & ThreadNameUpdatedEvent | { "type": "mcp_startup_update" } & McpStartupUpdateEvent | { "type": "mcp_startup_complete" } & McpStartupCompleteEvent | { "type": "mcp_tool_call_begin" } & McpToolCallBeginEvent | { "type": "mcp_tool_call_end" } & McpToolCallEndEvent | { "type": "web_search_begin" } & WebSearchBeginEvent | { "type": "web_search_end" } & WebSearchEndEvent | { "type": "exec_command_begin" } & ExecCommandBeginEvent | { "type": "exec_command_output_delta" } & ExecCommandOutputDeltaEvent | { "type": "terminal_interaction" } & TerminalInteractionEvent | { "type": "exec_command_end" } & ExecCommandEndEvent | { "type": "view_image_tool_call" } & ViewImageToolCallEvent | { "type": "exec_approval_request" } & ExecApprovalRequestEvent | { "type": "request_user_input" } & RequestUserInputEvent | { "type": "dynamic_tool_call_request" } & DynamicToolCallRequest | { "type": "elicitation_request" } & ElicitationRequestEvent | { "type": "apply_patch_approval_request" } & ApplyPatchApprovalRequestEvent | { "type": "deprecation_notice" } & DeprecationNoticeEvent | { "type": "background_event" } & BackgroundEventEvent | { "type": "undo_started" } & UndoStartedEvent | { "type": "undo_completed" } & UndoCompletedEvent | { "type": "stream_error" } & StreamErrorEvent | { "type": "patch_apply_begin" } & PatchApplyBeginEvent | { "type": "patch_apply_end" } & PatchApplyEndEvent | { "type": "turn_diff" } & TurnDiffEvent | { "type": "get_history_entry_response" } & GetHistoryEntryResponseEvent | { "type": "mcp_list_tools_response" } & McpListToolsResponseEvent | { "type": "list_custom_prompts_response" } & ListCustomPromptsResponseEvent | { "type": "list_skills_response" } & ListSkillsResponseEvent | { "type": "list_remote_skills_response" } & ListRemoteSkillsResponseEvent | { "type": "remote_skill_downloaded" } & RemoteSkillDownloadedEvent | { "type": "skills_update_available" } | { "type": "plan_update" } & UpdatePlanArgs | { "type": "turn_aborted" } & TurnAbortedEvent | { "type": "shutdown_complete" } | { "type": "entered_review_mode" } & ReviewRequest | { "type": "exited_review_mode" } & ExitedReviewModeEvent | { "type": "raw_response_item" } & RawResponseItemEvent | { "type": "item_started" } & ItemStartedEvent | { "type": "item_completed" } & ItemCompletedEvent | { "type": "agent_message_content_delta" } & AgentMessageContentDeltaEvent | { "type": "plan_delta" } & PlanDeltaEvent | { "type": "reasoning_content_delta" } & ReasoningContentDeltaEvent | { "type": "reasoning_raw_content_delta" } & ReasoningRawContentDeltaEvent | { "type": "collab_agent_spawn_begin" } & CollabAgentSpawnBeginEvent | { "type": "collab_agent_spawn_end" } & CollabAgentSpawnEndEvent | { "type": "collab_agent_interaction_begin" } & CollabAgentInteractionBeginEvent | { "type": "collab_agent_interaction_end" } & CollabAgentInteractionEndEvent | { "type": "collab_waiting_begin" } & CollabWaitingBeginEvent | { "type": "collab_waiting_end" } & CollabWaitingEndEvent | { "type": "collab_close_begin" } & CollabCloseBeginEvent | { "type": "collab_close_end" } & CollabCloseEndEvent;
export type EventMsg = { "type": "error" } & ErrorEvent | { "type": "warning" } & WarningEvent | { "type": "context_compacted" } & ContextCompactedEvent | { "type": "thread_rolled_back" } & ThreadRolledBackEvent | { "type": "task_started" } & TurnStartedEvent | { "type": "task_complete" } & TurnCompleteEvent | { "type": "token_count" } & TokenCountEvent | { "type": "agent_message" } & AgentMessageEvent | { "type": "user_message" } & UserMessageEvent | { "type": "agent_message_delta" } & AgentMessageDeltaEvent | { "type": "agent_reasoning" } & AgentReasoningEvent | { "type": "agent_reasoning_delta" } & AgentReasoningDeltaEvent | { "type": "agent_reasoning_raw_content" } & AgentReasoningRawContentEvent | { "type": "agent_reasoning_raw_content_delta" } & AgentReasoningRawContentDeltaEvent | { "type": "agent_reasoning_section_break" } & AgentReasoningSectionBreakEvent | { "type": "session_configured" } & SessionConfiguredEvent | { "type": "thread_name_updated" } & ThreadNameUpdatedEvent | { "type": "mcp_startup_update" } & McpStartupUpdateEvent | { "type": "mcp_startup_complete" } & McpStartupCompleteEvent | { "type": "mcp_tool_call_begin" } & McpToolCallBeginEvent | { "type": "mcp_tool_call_end" } & McpToolCallEndEvent | { "type": "web_search_begin" } & WebSearchBeginEvent | { "type": "web_search_end" } & WebSearchEndEvent | { "type": "exec_command_begin" } & ExecCommandBeginEvent | { "type": "exec_command_output_delta" } & ExecCommandOutputDeltaEvent | { "type": "terminal_interaction" } & TerminalInteractionEvent | { "type": "exec_command_end" } & ExecCommandEndEvent | { "type": "view_image_tool_call" } & ViewImageToolCallEvent | { "type": "exec_approval_request" } & ExecApprovalRequestEvent | { "type": "request_user_input" } & RequestUserInputEvent | { "type": "dynamic_tool_call_request" } & DynamicToolCallRequest | { "type": "elicitation_request" } & ElicitationRequestEvent | { "type": "apply_patch_approval_request" } & ApplyPatchApprovalRequestEvent | { "type": "deprecation_notice" } & DeprecationNoticeEvent | { "type": "background_event" } & BackgroundEventEvent | { "type": "undo_started" } & UndoStartedEvent | { "type": "undo_completed" } & UndoCompletedEvent | { "type": "stream_error" } & StreamErrorEvent | { "type": "patch_apply_begin" } & PatchApplyBeginEvent | { "type": "patch_apply_end" } & PatchApplyEndEvent | { "type": "turn_diff" } & TurnDiffEvent | { "type": "get_history_entry_response" } & GetHistoryEntryResponseEvent | { "type": "mcp_list_tools_response" } & McpListToolsResponseEvent | { "type": "list_custom_prompts_response" } & ListCustomPromptsResponseEvent | { "type": "list_skills_response" } & ListSkillsResponseEvent | { "type": "skills_update_available" } | { "type": "plan_update" } & UpdatePlanArgs | { "type": "turn_aborted" } & TurnAbortedEvent | { "type": "shutdown_complete" } | { "type": "entered_review_mode" } & ReviewRequest | { "type": "exited_review_mode" } & ExitedReviewModeEvent | { "type": "raw_response_item" } & RawResponseItemEvent | { "type": "item_started" } & ItemStartedEvent | { "type": "item_completed" } & ItemCompletedEvent | { "type": "agent_message_content_delta" } & AgentMessageContentDeltaEvent | { "type": "plan_delta" } & PlanDeltaEvent | { "type": "reasoning_content_delta" } & ReasoningContentDeltaEvent | { "type": "reasoning_raw_content_delta" } & ReasoningRawContentDeltaEvent | { "type": "collab_agent_spawn_begin" } & CollabAgentSpawnBeginEvent | { "type": "collab_agent_spawn_end" } & CollabAgentSpawnEndEvent | { "type": "collab_agent_interaction_begin" } & CollabAgentInteractionBeginEvent | { "type": "collab_agent_interaction_end" } & CollabAgentInteractionEndEvent | { "type": "collab_waiting_begin" } & CollabWaitingBeginEvent | { "type": "collab_waiting_end" } & CollabWaitingEndEvent | { "type": "collab_close_begin" } & CollabCloseBeginEvent | { "type": "collab_close_end" } & CollabCloseEndEvent;

View File

@@ -1,6 +0,0 @@
// 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 { FunctionCallOutputContentItem } from "./FunctionCallOutputContentItem";
export type FunctionCallOutputBody = string | Array<FunctionCallOutputContentItem>;

View File

@@ -1,12 +1,15 @@
// 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 { FunctionCallOutputBody } from "./FunctionCallOutputBody";
import type { FunctionCallOutputContentItem } from "./FunctionCallOutputContentItem";
/**
* The payload we send back to OpenAI when reporting a tool call result.
*
* `body` serializes directly as the wire value for `function_call_output.output`.
* `success` remains internal metadata for downstream handling.
* `content` preserves the historical plain-string payload so downstream
* integrations (tests, logging, etc.) can keep treating tool output as
* `String`. When an MCP server returns richer data we additionally populate
* `content_items` with the structured form that the Responses/Chat
* Completions APIs understand.
*/
export type FunctionCallOutputPayload = { body: FunctionCallOutputBody, success: boolean | null, };
export type FunctionCallOutputPayload = { content: string, content_items: Array<FunctionCallOutputContentItem> | null, success: boolean | null, };

View File

@@ -1,8 +0,0 @@
// 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.
/**
* Canonical user-input modality tags advertised by a model.
*/
export type InputModality = "text" | "image";

View File

@@ -1,9 +0,0 @@
// 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 { RemoteSkillSummary } from "./RemoteSkillSummary";
/**
* Response payload for `Op::ListRemoteSkills`.
*/
export type ListRemoteSkillsResponseEvent = { skills: Array<RemoteSkillSummary>, };

View File

@@ -1,5 +0,0 @@
// 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.
export type MessagePhase = "commentary" | "final_answer";

View File

@@ -5,4 +5,4 @@
/**
* Initial collaboration mode to use when the TUI starts.
*/
export type ModeKind = "plan" | "default";
export type ModeKind = "plan" | "code" | "pair_programming" | "execute" | "custom";

View File

@@ -2,4 +2,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type Personality = "none" | "friendly" | "pragmatic";
export type Personality = "friendly" | "pragmatic";

View File

@@ -1,8 +0,0 @@
// 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.
/**
* Response payload for `Op::DownloadRemoteSkill`.
*/
export type RemoteSkillDownloadedEvent = { id: string, name: string, path: string, };

View File

@@ -1,5 +0,0 @@
// 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.
export type RemoteSkillSummary = { id: string, name: string, description: string, };

View File

@@ -6,12 +6,11 @@ import type { FunctionCallOutputPayload } from "./FunctionCallOutputPayload";
import type { GhostCommit } from "./GhostCommit";
import type { LocalShellAction } from "./LocalShellAction";
import type { LocalShellStatus } from "./LocalShellStatus";
import type { MessagePhase } from "./MessagePhase";
import type { ReasoningItemContent } from "./ReasoningItemContent";
import type { ReasoningItemReasoningSummary } from "./ReasoningItemReasoningSummary";
import type { WebSearchAction } from "./WebSearchAction";
export type ResponseItem = { "type": "message", role: string, content: Array<ContentItem>, end_turn?: boolean, phase?: MessagePhase, } | { "type": "reasoning", summary: Array<ReasoningItemReasoningSummary>, content?: Array<ReasoningItemContent>, encrypted_content: string | null, } | { "type": "local_shell_call",
export type ResponseItem = { "type": "message", role: string, content: Array<ContentItem>, end_turn?: boolean, } | { "type": "reasoning", summary: Array<ReasoningItemReasoningSummary>, content?: Array<ReasoningItemContent>, encrypted_content: string | null, } | { "type": "local_shell_call",
/**
* Set when using the Responses API.
*/

View File

@@ -69,7 +69,6 @@ export type { FileChange } from "./FileChange";
export type { ForcedLoginMethod } from "./ForcedLoginMethod";
export type { ForkConversationParams } from "./ForkConversationParams";
export type { ForkConversationResponse } from "./ForkConversationResponse";
export type { FunctionCallOutputBody } from "./FunctionCallOutputBody";
export type { FunctionCallOutputContentItem } from "./FunctionCallOutputContentItem";
export type { FunctionCallOutputPayload } from "./FunctionCallOutputPayload";
export type { FuzzyFileSearchParams } from "./FuzzyFileSearchParams";
@@ -91,7 +90,6 @@ export type { InitializeCapabilities } from "./InitializeCapabilities";
export type { InitializeParams } from "./InitializeParams";
export type { InitializeResponse } from "./InitializeResponse";
export type { InputItem } from "./InputItem";
export type { InputModality } from "./InputModality";
export type { InterruptConversationParams } from "./InterruptConversationParams";
export type { InterruptConversationResponse } from "./InterruptConversationResponse";
export type { ItemCompletedEvent } from "./ItemCompletedEvent";
@@ -99,7 +97,6 @@ export type { ItemStartedEvent } from "./ItemStartedEvent";
export type { ListConversationsParams } from "./ListConversationsParams";
export type { ListConversationsResponse } from "./ListConversationsResponse";
export type { ListCustomPromptsResponseEvent } from "./ListCustomPromptsResponseEvent";
export type { ListRemoteSkillsResponseEvent } from "./ListRemoteSkillsResponseEvent";
export type { ListSkillsResponseEvent } from "./ListSkillsResponseEvent";
export type { LocalShellAction } from "./LocalShellAction";
export type { LocalShellExecAction } from "./LocalShellExecAction";
@@ -118,7 +115,6 @@ export type { McpStartupStatus } from "./McpStartupStatus";
export type { McpStartupUpdateEvent } from "./McpStartupUpdateEvent";
export type { McpToolCallBeginEvent } from "./McpToolCallBeginEvent";
export type { McpToolCallEndEvent } from "./McpToolCallEndEvent";
export type { MessagePhase } from "./MessagePhase";
export type { ModeKind } from "./ModeKind";
export type { NetworkAccess } from "./NetworkAccess";
export type { NewConversationParams } from "./NewConversationParams";
@@ -142,8 +138,6 @@ export type { ReasoningItemContent } from "./ReasoningItemContent";
export type { ReasoningItemReasoningSummary } from "./ReasoningItemReasoningSummary";
export type { ReasoningRawContentDeltaEvent } from "./ReasoningRawContentDeltaEvent";
export type { ReasoningSummary } from "./ReasoningSummary";
export type { RemoteSkillDownloadedEvent } from "./RemoteSkillDownloadedEvent";
export type { RemoteSkillSummary } from "./RemoteSkillSummary";
export type { RemoveConversationListenerParams } from "./RemoveConversationListenerParams";
export type { RemoveConversationSubscriptionResponse } from "./RemoveConversationSubscriptionResponse";
export type { RequestId } from "./RequestId";

View File

@@ -6,8 +6,8 @@ export type AppsListParams = {
/**
* Opaque pagination cursor returned by a previous call.
*/
cursor?: string | null,
cursor: string | null,
/**
* Optional page size; defaults to a reasonable server-side value.
*/
limit?: number | null, };
limit: number | null, };

View File

@@ -13,4 +13,4 @@ export type ChatgptAuthTokensRefreshParams = { reason: ChatgptAuthTokensRefreshR
* This may be `null` when the prior ID token did not include a workspace
* identifier (`chatgpt_account_id`) or when the token could not be parsed.
*/
previousAccountId?: string | null, };
previousAccountId: string | null, };

View File

@@ -3,4 +3,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { SandboxPolicy } from "./SandboxPolicy";
export type CommandExecParams = { command: Array<string>, timeoutMs?: number | null, cwd?: string | null, sandboxPolicy?: SandboxPolicy | null, };
export type CommandExecParams = { command: Array<string>, timeoutMs: number | null, cwd: string | null, sandboxPolicy: SandboxPolicy | null, };

View File

@@ -8,20 +8,20 @@ export type CommandExecutionRequestApprovalParams = { threadId: string, turnId:
/**
* Optional explanatory reason (e.g. request for network access).
*/
reason?: string | null,
reason: string | null,
/**
* The command to be executed.
*/
command?: string | null,
command?: string,
/**
* The command's working directory.
*/
cwd?: string | null,
cwd?: string,
/**
* Best-effort parsed command actions for friendly display.
*/
commandActions?: Array<CommandAction> | null,
commandActions?: Array<CommandAction>,
/**
* Optional proposed execpolicy amendment to allow similar commands without prompting.
*/
proposedExecpolicyAmendment?: ExecPolicyAmendment | null, };
proposedExecpolicyAmendment: ExecPolicyAmendment | null, };

View File

@@ -7,4 +7,4 @@ export type ConfigBatchWriteParams = { edits: Array<ConfigEdit>,
/**
* Path to the config file to write; defaults to the user's `config.toml` when omitted.
*/
filePath?: string | null, expectedVersion?: string | null, };
filePath: string | null, expectedVersion: string | null, };

View File

@@ -8,4 +8,4 @@ export type ConfigReadParams = { includeLayers: boolean,
* return the effective config as seen from that directory (i.e., including any
* project layers between `cwd` and the project/repo root).
*/
cwd?: string | null, };
cwd: string | null, };

View File

@@ -8,4 +8,4 @@ export type ConfigValueWriteParams = { keyPath: string, value: JsonValue, mergeS
/**
* Path to the config file to write; defaults to the user's `config.toml` when omitted.
*/
filePath?: string | null, expectedVersion?: string | null, };
filePath: string | null, expectedVersion: string | null, };

View File

@@ -1,5 +0,0 @@
// 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.
export type DynamicToolCallOutputContentItem = { "type": "inputText", text: string, } | { "type": "inputImage", imageUrl: string, };

View File

@@ -1,6 +1,5 @@
// 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 { DynamicToolCallOutputContentItem } from "./DynamicToolCallOutputContentItem";
export type DynamicToolCallResponse = { contentItems: Array<DynamicToolCallOutputContentItem>, success: boolean, };
export type DynamicToolCallResponse = { output: string, success: boolean, };

View File

@@ -2,4 +2,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type FeedbackUploadParams = { classification: string, reason?: string | null, threadId?: string | null, includeLogs: boolean, };
export type FeedbackUploadParams = { classification: string, reason: string | null, threadId: string | null, includeLogs: boolean, };

View File

@@ -6,9 +6,9 @@ export type FileChangeRequestApprovalParams = { threadId: string, turnId: string
/**
* Optional explanatory reason (e.g. request for extra write access).
*/
reason?: string | null,
reason: string | null,
/**
* [UNSTABLE] When set, the agent is asking the user to allow writes under this root
* for the remainder of the session (unclear if this is honored today).
*/
grantRoot?: string | null, };
grantRoot: string | null, };

View File

@@ -6,8 +6,8 @@ export type ListMcpServerStatusParams = {
/**
* Opaque pagination cursor returned by a previous call.
*/
cursor?: string | null,
cursor: string | null,
/**
* Optional page size; defaults to a server-defined value.
*/
limit?: number | null, };
limit: number | null, };

View File

@@ -2,4 +2,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type McpServerOauthLoginParams = { name: string, scopes?: Array<string> | null, timeoutSecs?: bigint | null, };
export type McpServerOauthLoginParams = { name: string, scopes?: Array<string>, timeoutSecs?: bigint, };

View File

@@ -1,8 +1,7 @@
// 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 { InputModality } from "../InputModality";
import type { ReasoningEffort } from "../ReasoningEffort";
import type { ReasoningEffortOption } from "./ReasoningEffortOption";
export type Model = { id: string, model: string, upgrade: string | null, displayName: string, description: string, supportedReasoningEfforts: Array<ReasoningEffortOption>, defaultReasoningEffort: ReasoningEffort, inputModalities: Array<InputModality>, supportsPersonality: boolean, isDefault: boolean, };
export type Model = { id: string, model: string, displayName: string, description: string, supportedReasoningEfforts: Array<ReasoningEffortOption>, defaultReasoningEffort: ReasoningEffort, supportsPersonality: boolean, isDefault: boolean, };

View File

@@ -6,8 +6,8 @@ export type ModelListParams = {
/**
* Opaque pagination cursor returned by a previous call.
*/
cursor?: string | null,
cursor: string | null,
/**
* Optional page size; defaults to a reasonable server-side value.
*/
limit?: number | null, };
limit: number | null, };

View File

@@ -1,5 +0,0 @@
// 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.
export type RemoteSkillSummary = { id: string, name: string, description: string, };

View File

@@ -9,4 +9,4 @@ export type ReviewStartParams = { threadId: string, target: ReviewTarget,
* Where to run the review: inline (default) on the current thread or
* detached on a new thread (returned in `reviewThreadId`).
*/
delivery?: ReviewDelivery | null, };
delivery: ReviewDelivery | null, };

View File

@@ -1,5 +0,0 @@
// 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.
export type SkillsRemoteReadParams = Record<string, never>;

View File

@@ -1,6 +0,0 @@
// 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 { RemoteSkillSummary } from "./RemoteSkillSummary";
export type SkillsRemoteReadResponse = { data: Array<RemoteSkillSummary>, };

View File

@@ -1,5 +0,0 @@
// 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.
export type SkillsRemoteWriteParams = { hazelnutId: string, isPreload: boolean, };

View File

@@ -1,5 +0,0 @@
// 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.
export type SkillsRemoteWriteResponse = { id: string, name: string, path: string, };

View File

@@ -1,5 +0,0 @@
// 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.
export type ThreadCompactStartParams = { threadId: string, };

View File

@@ -1,5 +0,0 @@
// 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.
export type ThreadCompactStartResponse = Record<string, never>;

View File

@@ -19,8 +19,8 @@ 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,
path: string | null,
/**
* Configuration overrides for the forked thread, if any.
*/
model?: string | null, modelProvider?: string | null, cwd?: string | null, approvalPolicy?: AskForApproval | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, };
model: string | null, modelProvider: string | null, cwd: string | null, approvalPolicy: AskForApproval | null, sandbox: SandboxMode | null, config: { [key in string]?: JsonValue } | null, baseInstructions: string | null, developerInstructions: string | null, };

View File

@@ -1,6 +1,7 @@
// 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 { WebSearchAction } from "../WebSearchAction";
import type { JsonValue } from "../serde_json/JsonValue";
import type { CollabAgentState } from "./CollabAgentState";
import type { CollabAgentTool } from "./CollabAgentTool";
@@ -13,7 +14,6 @@ import type { McpToolCallResult } from "./McpToolCallResult";
import type { McpToolCallStatus } from "./McpToolCallStatus";
import type { PatchApplyStatus } from "./PatchApplyStatus";
import type { UserInput } from "./UserInput";
import type { WebSearchAction } from "./WebSearchAction";
export type ThreadItem = { "type": "userMessage", id: string, content: Array<UserInput>, } | { "type": "agentMessage", id: string, text: string, } | { "type": "plan", id: string, text: string, } | { "type": "reasoning", id: string, summary: Array<string>, content: Array<string>, } | { "type": "commandExecution", id: string,
/**

View File

@@ -8,27 +8,27 @@ export type ThreadListParams = {
/**
* Opaque pagination cursor returned by a previous call.
*/
cursor?: string | null,
cursor: string | null,
/**
* Optional page size; defaults to a reasonable server-side value.
*/
limit?: number | null,
limit: number | null,
/**
* Optional sort key; defaults to created_at.
*/
sortKey?: ThreadSortKey | null,
sortKey: ThreadSortKey | null,
/**
* Optional provider filter; when set, only sessions recorded under these
* providers are returned. When present but empty, includes all providers.
*/
modelProviders?: Array<string> | null,
modelProviders: Array<string> | null,
/**
* Optional source filter; when set, only sessions from these source kinds
* are returned. When omitted or empty, defaults to interactive sources.
*/
sourceKinds?: Array<ThreadSourceKind> | null,
sourceKinds: Array<ThreadSourceKind> | null,
/**
* Optional archived filter; when set to true, only archived threads are returned.
* If false or null, only non-archived threads are returned.
*/
archived?: boolean | null, };
archived: boolean | null, };

View File

@@ -6,8 +6,8 @@ export type ThreadLoadedListParams = {
/**
* Opaque pagination cursor returned by a previous call.
*/
cursor?: string | null,
cursor: string | null,
/**
* Optional page size; defaults to no limit.
*/
limit?: number | null, };
limit: number | null, };

View File

@@ -24,13 +24,13 @@ export type ThreadResumeParams = { threadId: string,
* If specified, the thread will be resumed with the provided history
* instead of loaded from disk.
*/
history?: Array<ResponseItem> | null,
history: Array<ResponseItem> | null,
/**
* [UNSTABLE] Specify the rollout path to resume from.
* If specified, the thread_id param will be ignored.
*/
path?: string | null,
path: string | null,
/**
* Configuration overrides for the resumed thread, if any.
*/
model?: string | null, modelProvider?: string | null, cwd?: string | null, approvalPolicy?: AskForApproval | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, personality?: Personality | null, };
model: string | null, modelProvider: string | null, cwd: string | null, approvalPolicy: AskForApproval | null, sandbox: SandboxMode | null, config: { [key in string]?: JsonValue } | null, baseInstructions: string | null, developerInstructions: string | null, personality: Personality | null, };

View File

@@ -6,7 +6,7 @@ import type { JsonValue } from "../serde_json/JsonValue";
import type { AskForApproval } from "./AskForApproval";
import type { SandboxMode } from "./SandboxMode";
export type ThreadStartParams = {model?: string | null, modelProvider?: string | null, cwd?: string | null, approvalPolicy?: AskForApproval | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, personality?: Personality | null, ephemeral?: boolean | null, /**
export type ThreadStartParams = {model: string | null, modelProvider: string | null, cwd: string | null, approvalPolicy: AskForApproval | null, sandbox: SandboxMode | null, config: { [key in string]?: JsonValue } | null, baseInstructions: string | null, developerInstructions: string | null, personality: Personality | null, ephemeral: boolean | null, /**
* If true, opt into emitting raw response items on the event stream.
*
* This is for internal use only (e.g. Codex Cloud).

View File

@@ -14,37 +14,37 @@ export type TurnStartParams = { threadId: string, input: Array<UserInput>,
/**
* Override the working directory for this turn and subsequent turns.
*/
cwd?: string | null,
cwd: string | null,
/**
* Override the approval policy for this turn and subsequent turns.
*/
approvalPolicy?: AskForApproval | null,
approvalPolicy: AskForApproval | null,
/**
* Override the sandbox policy for this turn and subsequent turns.
*/
sandboxPolicy?: SandboxPolicy | null,
sandboxPolicy: SandboxPolicy | null,
/**
* Override the model for this turn and subsequent turns.
*/
model?: string | null,
model: string | null,
/**
* Override the reasoning effort for this turn and subsequent turns.
*/
effort?: ReasoningEffort | null,
effort: ReasoningEffort | null,
/**
* Override the reasoning summary for this turn and subsequent turns.
*/
summary?: ReasoningSummary | null,
summary: ReasoningSummary | null,
/**
* Override the personality for this turn and subsequent turns.
*/
personality?: Personality | null,
personality: Personality | null,
/**
* Optional JSON Schema used to constrain the final assistant message for this turn.
*/
outputSchema?: JsonValue | null,
outputSchema: JsonValue | null,
/**
* EXPERIMENTAL - set a pre-set collaboration mode.
* Takes precedence over model, reasoning_effort, and developer instructions if set.
*/
collaborationMode?: CollaborationMode | null, };
collaborationMode: CollaborationMode | null, };

View File

@@ -1,5 +0,0 @@
// 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.
export type WebSearchAction = { "type": "search", query: string | null, queries: Array<string> | null, } | { "type": "openPage", url: string | null, } | { "type": "findInPage", url: string | null, pattern: string | null, } | { "type": "other" };

View File

@@ -46,7 +46,6 @@ export type { ConfigWriteResponse } from "./ConfigWriteResponse";
export type { ContextCompactedNotification } from "./ContextCompactedNotification";
export type { CreditsSnapshot } from "./CreditsSnapshot";
export type { DeprecationNoticeNotification } from "./DeprecationNoticeNotification";
export type { DynamicToolCallOutputContentItem } from "./DynamicToolCallOutputContentItem";
export type { DynamicToolCallParams } from "./DynamicToolCallParams";
export type { DynamicToolCallResponse } from "./DynamicToolCallResponse";
export type { DynamicToolSpec } from "./DynamicToolSpec";
@@ -97,7 +96,6 @@ export type { ReasoningEffortOption } from "./ReasoningEffortOption";
export type { ReasoningSummaryPartAddedNotification } from "./ReasoningSummaryPartAddedNotification";
export type { ReasoningSummaryTextDeltaNotification } from "./ReasoningSummaryTextDeltaNotification";
export type { ReasoningTextDeltaNotification } from "./ReasoningTextDeltaNotification";
export type { RemoteSkillSummary } from "./RemoteSkillSummary";
export type { ResidencyRequirement } from "./ResidencyRequirement";
export type { ReviewDelivery } from "./ReviewDelivery";
export type { ReviewStartParams } from "./ReviewStartParams";
@@ -118,10 +116,6 @@ export type { SkillsConfigWriteResponse } from "./SkillsConfigWriteResponse";
export type { SkillsListEntry } from "./SkillsListEntry";
export type { SkillsListParams } from "./SkillsListParams";
export type { SkillsListResponse } from "./SkillsListResponse";
export type { SkillsRemoteReadParams } from "./SkillsRemoteReadParams";
export type { SkillsRemoteReadResponse } from "./SkillsRemoteReadResponse";
export type { SkillsRemoteWriteParams } from "./SkillsRemoteWriteParams";
export type { SkillsRemoteWriteResponse } from "./SkillsRemoteWriteResponse";
export type { TerminalInteractionNotification } from "./TerminalInteractionNotification";
export type { TextElement } from "./TextElement";
export type { TextPosition } from "./TextPosition";
@@ -129,8 +123,6 @@ export type { TextRange } from "./TextRange";
export type { Thread } from "./Thread";
export type { ThreadArchiveParams } from "./ThreadArchiveParams";
export type { ThreadArchiveResponse } from "./ThreadArchiveResponse";
export type { ThreadCompactStartParams } from "./ThreadCompactStartParams";
export type { ThreadCompactStartResponse } from "./ThreadCompactStartResponse";
export type { ThreadForkParams } from "./ThreadForkParams";
export type { ThreadForkResponse } from "./ThreadForkResponse";
export type { ThreadItem } from "./ThreadItem";
@@ -177,6 +169,5 @@ export type { TurnStartResponse } from "./TurnStartResponse";
export type { TurnStartedNotification } from "./TurnStartedNotification";
export type { TurnStatus } from "./TurnStatus";
export type { UserInput } from "./UserInput";
export type { WebSearchAction } from "./WebSearchAction";
export type { WindowsWorldWritableWarningNotification } from "./WindowsWorldWritableWarningNotification";
export type { WriteStatus } from "./WriteStatus";

View File

@@ -1402,8 +1402,8 @@ mod tests {
use uuid::Uuid;
#[test]
fn generated_ts_optional_nullable_fields_only_in_params() -> Result<()> {
// Assert that "?: T | null" only appears in generated *Params types.
fn generated_ts_has_no_optional_nullable_fields() -> Result<()> {
// Assert that there are no types of the form "?: T | null" in the generated TS files.
let output_dir = std::env::temp_dir().join(format!("codex_ts_types_{}", Uuid::now_v7()));
fs::create_dir(&output_dir)?;
@@ -1463,13 +1463,6 @@ mod tests {
}
if matches!(path.extension().and_then(|ext| ext.to_str()), Some("ts")) {
// Only allow "?: T | null" in objects representing JSON-RPC requests,
// which we assume are called "*Params".
let allow_optional_nullable = path
.file_stem()
.and_then(|stem| stem.to_str())
.is_some_and(|stem| stem.ends_with("Params"));
let contents = fs::read_to_string(&path)?;
if contents.contains("| undefined") {
undefined_offenders.push(path.clone());
@@ -1590,11 +1583,9 @@ mod tests {
}
// If the last non-whitespace before ':' is '?', then this is an
// optional field with a nullable type (i.e., "?: T | null").
// These are only allowed in *Params types.
if field_prefix.chars().rev().find(|c| !c.is_whitespace()) == Some('?')
&& !allow_optional_nullable
{
// optional field with a nullable type (i.e., "?: T | null"),
// which we explicitly disallow.
if field_prefix.chars().rev().find(|c| !c.is_whitespace()) == Some('?') {
let line_number =
contents[..abs_idx].chars().filter(|c| *c == '\n').count() + 1;
let offending_line_end = contents[line_start_idx..]
@@ -1622,12 +1613,12 @@ mod tests {
"Generated TypeScript still includes unions with `undefined` in {undefined_offenders:?}"
);
// If this assertion fails, it means a field was generated as "?: T | null",
// which is both optional (undefined) and nullable (null), for a type not ending
// in "Params" (which represent JSON-RPC requests).
// If this assertion fails, it means a field was generated as
// "?: T | null" — i.e., both optional (undefined) and nullable (null).
// We only want either "?: T" or ": T | null".
assert!(
optional_nullable_offenders.is_empty(),
"Generated TypeScript has optional nullable fields outside *Params types (disallowed '?: T | null'):\n{optional_nullable_offenders:?}"
"Generated TypeScript has optional fields with nullable types (disallowed '?: T | null'), add #[ts(optional)] to fix:\n{optional_nullable_offenders:?}"
);
Ok(())

View File

@@ -208,10 +208,6 @@ client_request_definitions! {
params: v2::ThreadUnarchiveParams,
response: v2::ThreadUnarchiveResponse,
},
ThreadCompactStart => "thread/compact/start" {
params: v2::ThreadCompactStartParams,
response: v2::ThreadCompactStartResponse,
},
ThreadRollback => "thread/rollback" {
params: v2::ThreadRollbackParams,
response: v2::ThreadRollbackResponse,
@@ -232,14 +228,6 @@ client_request_definitions! {
params: v2::SkillsListParams,
response: v2::SkillsListResponse,
},
SkillsRemoteRead => "skills/remote/read" {
params: v2::SkillsRemoteReadParams,
response: v2::SkillsRemoteReadResponse,
},
SkillsRemoteWrite => "skills/remote/write" {
params: v2::SkillsRemoteWriteParams,
response: v2::SkillsRemoteWriteResponse,
},
AppsList => "app/list" {
params: v2::AppsListParams,
response: v2::AppsListResponse,

View File

@@ -19,9 +19,7 @@ use codex_protocol::mcp::Resource as McpResource;
use codex_protocol::mcp::ResourceTemplate as McpResourceTemplate;
use codex_protocol::mcp::Tool as McpTool;
use codex_protocol::models::ResponseItem;
use codex_protocol::openai_models::InputModality;
use codex_protocol::openai_models::ReasoningEffort;
use codex_protocol::openai_models::default_input_modalities;
use codex_protocol::parse_command::ParsedCommand as CoreParsedCommand;
use codex_protocol::plan_tool::PlanItemArg as CorePlanItemArg;
use codex_protocol::plan_tool::StepStatus as CorePlanStepStatus;
@@ -480,7 +478,6 @@ pub struct ConfigReadParams {
/// 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).
#[ts(optional = nullable)]
pub cwd: Option<String>,
}
@@ -526,9 +523,7 @@ pub struct ConfigValueWriteParams {
pub value: JsonValue,
pub merge_strategy: MergeStrategy,
/// Path to the config file to write; defaults to the user's `config.toml` when omitted.
#[ts(optional = nullable)]
pub file_path: Option<String>,
#[ts(optional = nullable)]
pub expected_version: Option<String>,
}
@@ -538,9 +533,7 @@ pub struct ConfigValueWriteParams {
pub struct ConfigBatchWriteParams {
pub edits: Vec<ConfigEdit>,
/// Path to the config file to write; defaults to the user's `config.toml` when omitted.
#[ts(optional = nullable)]
pub file_path: Option<String>,
#[ts(optional = nullable)]
pub expected_version: Option<String>,
}
@@ -940,7 +933,6 @@ pub struct ChatgptAuthTokensRefreshParams {
///
/// This may be `null` when the prior ID token did not include a workspace
/// identifier (`chatgpt_account_id`) or when the token could not be parsed.
#[ts(optional = nullable)]
pub previous_account_id: Option<String>,
}
@@ -985,10 +977,8 @@ pub struct GetAccountResponse {
#[ts(export_to = "v2/")]
pub struct ModelListParams {
/// Opaque pagination cursor returned by a previous call.
#[ts(optional = nullable)]
pub cursor: Option<String>,
/// Optional page size; defaults to a reasonable server-side value.
#[ts(optional = nullable)]
pub limit: Option<u32>,
}
@@ -998,13 +988,10 @@ pub struct ModelListParams {
pub struct Model {
pub id: String,
pub model: String,
pub upgrade: Option<String>,
pub display_name: String,
pub description: String,
pub supported_reasoning_efforts: Vec<ReasoningEffortOption>,
pub default_reasoning_effort: ReasoningEffort,
#[serde(default = "default_input_modalities")]
pub input_modalities: Vec<InputModality>,
#[serde(default)]
pub supports_personality: bool,
// Only one model should be marked as default.
@@ -1048,10 +1035,8 @@ pub struct CollaborationModeListResponse {
#[ts(export_to = "v2/")]
pub struct ListMcpServerStatusParams {
/// Opaque pagination cursor returned by a previous call.
#[ts(optional = nullable)]
pub cursor: Option<String>,
/// Optional page size; defaults to a server-defined value.
#[ts(optional = nullable)]
pub limit: Option<u32>,
}
@@ -1081,10 +1066,8 @@ pub struct ListMcpServerStatusResponse {
#[ts(export_to = "v2/")]
pub struct AppsListParams {
/// Opaque pagination cursor returned by a previous call.
#[ts(optional = nullable)]
pub cursor: Option<String>,
/// Optional page size; defaults to a reasonable server-side value.
#[ts(optional = nullable)]
pub limit: Option<u32>,
}
@@ -1129,10 +1112,10 @@ pub struct McpServerRefreshResponse {}
pub struct McpServerOauthLoginParams {
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional = nullable)]
#[ts(optional)]
pub scopes: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional = nullable)]
#[ts(optional)]
pub timeout_secs: Option<i64>,
}
@@ -1148,9 +1131,7 @@ pub struct McpServerOauthLoginResponse {
#[ts(export_to = "v2/")]
pub struct FeedbackUploadParams {
pub classification: String,
#[ts(optional = nullable)]
pub reason: Option<String>,
#[ts(optional = nullable)]
pub thread_id: Option<String>,
pub include_logs: bool,
}
@@ -1168,11 +1149,8 @@ pub struct FeedbackUploadResponse {
pub struct CommandExecParams {
pub command: Vec<String>,
#[ts(type = "number | null")]
#[ts(optional = nullable)]
pub timeout_ms: Option<i64>,
#[ts(optional = nullable)]
pub cwd: Option<PathBuf>,
#[ts(optional = nullable)]
pub sandbox_policy: Option<SandboxPolicy>,
}
@@ -1193,33 +1171,21 @@ pub struct CommandExecResponse {
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadStartParams {
#[ts(optional = nullable)]
pub model: Option<String>,
#[ts(optional = nullable)]
pub model_provider: Option<String>,
#[ts(optional = nullable)]
pub cwd: Option<String>,
#[ts(optional = nullable)]
pub approval_policy: Option<AskForApproval>,
#[ts(optional = nullable)]
pub sandbox: Option<SandboxMode>,
#[ts(optional = nullable)]
pub config: Option<HashMap<String, JsonValue>>,
#[ts(optional = nullable)]
pub base_instructions: Option<String>,
#[ts(optional = nullable)]
pub developer_instructions: Option<String>,
#[ts(optional = nullable)]
pub personality: Option<Personality>,
#[ts(optional = nullable)]
pub ephemeral: Option<bool>,
#[experimental("thread/start.dynamicTools")]
#[ts(optional = nullable)]
pub dynamic_tools: Option<Vec<DynamicToolSpec>>,
/// Test-only experimental field used to validate experimental gating and
/// schema filtering behavior in a stable way.
#[experimental("thread/start.mockExperimentalField")]
#[ts(optional = nullable)]
pub mock_experimental_field: Option<String>,
/// If true, opt into emitting raw response items on the event stream.
///
@@ -1234,7 +1200,6 @@ pub struct ThreadStartParams {
#[ts(export_to = "v2/")]
pub struct MockExperimentalMethodParams {
/// Test-only payload field.
#[ts(optional = nullable)]
pub value: Option<String>,
}
@@ -1277,32 +1242,21 @@ pub struct ThreadResumeParams {
/// [UNSTABLE] FOR CODEX CLOUD - DO NOT USE.
/// If specified, the thread will be resumed with the provided history
/// instead of loaded from disk.
#[ts(optional = nullable)]
pub history: Option<Vec<ResponseItem>>,
/// [UNSTABLE] Specify the rollout path to resume from.
/// If specified, the thread_id param will be ignored.
#[ts(optional = nullable)]
pub path: Option<PathBuf>,
/// Configuration overrides for the resumed thread, if any.
#[ts(optional = nullable)]
pub model: Option<String>,
#[ts(optional = nullable)]
pub model_provider: Option<String>,
#[ts(optional = nullable)]
pub cwd: Option<String>,
#[ts(optional = nullable)]
pub approval_policy: Option<AskForApproval>,
#[ts(optional = nullable)]
pub sandbox: Option<SandboxMode>,
#[ts(optional = nullable)]
pub config: Option<HashMap<String, serde_json::Value>>,
#[ts(optional = nullable)]
pub base_instructions: Option<String>,
#[ts(optional = nullable)]
pub developer_instructions: Option<String>,
#[ts(optional = nullable)]
pub personality: Option<Personality>,
}
@@ -1334,25 +1288,16 @@ pub struct ThreadForkParams {
/// [UNSTABLE] Specify the rollout path to fork from.
/// If specified, the thread_id param will be ignored.
#[ts(optional = nullable)]
pub path: Option<PathBuf>,
/// Configuration overrides for the forked thread, if any.
#[ts(optional = nullable)]
pub model: Option<String>,
#[ts(optional = nullable)]
pub model_provider: Option<String>,
#[ts(optional = nullable)]
pub cwd: Option<String>,
#[ts(optional = nullable)]
pub approval_policy: Option<AskForApproval>,
#[ts(optional = nullable)]
pub sandbox: Option<SandboxMode>,
#[ts(optional = nullable)]
pub config: Option<HashMap<String, serde_json::Value>>,
#[ts(optional = nullable)]
pub base_instructions: Option<String>,
#[ts(optional = nullable)]
pub developer_instructions: Option<String>,
}
@@ -1408,18 +1353,6 @@ pub struct ThreadUnarchiveResponse {
pub thread: Thread,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadCompactStartParams {
pub thread_id: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct ThreadCompactStartResponse {}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
@@ -1449,25 +1382,19 @@ pub struct ThreadRollbackResponse {
#[ts(export_to = "v2/")]
pub struct ThreadListParams {
/// Opaque pagination cursor returned by a previous call.
#[ts(optional = nullable)]
pub cursor: Option<String>,
/// Optional page size; defaults to a reasonable server-side value.
#[ts(optional = nullable)]
pub limit: Option<u32>,
/// Optional sort key; defaults to created_at.
#[ts(optional = nullable)]
pub sort_key: Option<ThreadSortKey>,
/// Optional provider filter; when set, only sessions recorded under these
/// providers are returned. When present but empty, includes all providers.
#[ts(optional = nullable)]
pub model_providers: Option<Vec<String>>,
/// Optional source filter; when set, only sessions from these source kinds
/// are returned. When omitted or empty, defaults to interactive sources.
#[ts(optional = nullable)]
pub source_kinds: Option<Vec<ThreadSourceKind>>,
/// Optional archived filter; when set to true, only archived threads are returned.
/// If false or null, only non-archived threads are returned.
#[ts(optional = nullable)]
pub archived: Option<bool>,
}
@@ -1512,10 +1439,8 @@ pub struct ThreadListResponse {
#[ts(export_to = "v2/")]
pub struct ThreadLoadedListParams {
/// Opaque pagination cursor returned by a previous call.
#[ts(optional = nullable)]
pub cursor: Option<String>,
/// Optional page size; defaults to no limit.
#[ts(optional = nullable)]
pub limit: Option<u32>,
}
@@ -1567,44 +1492,6 @@ pub struct SkillsListResponse {
pub data: Vec<SkillsListEntry>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct SkillsRemoteReadParams {}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct RemoteSkillSummary {
pub id: String,
pub name: String,
pub description: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct SkillsRemoteReadResponse {
pub data: Vec<RemoteSkillSummary>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct SkillsRemoteWriteParams {
pub hazelnut_id: String,
pub is_preload: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct SkillsRemoteWriteResponse {
pub id: String,
pub name: String,
pub path: PathBuf,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "snake_case")]
#[ts(rename_all = "snake_case")]
@@ -1941,33 +1828,24 @@ pub struct TurnStartParams {
pub thread_id: String,
pub input: Vec<UserInput>,
/// Override the working directory for this turn and subsequent turns.
#[ts(optional = nullable)]
pub cwd: Option<PathBuf>,
/// Override the approval policy for this turn and subsequent turns.
#[ts(optional = nullable)]
pub approval_policy: Option<AskForApproval>,
/// Override the sandbox policy for this turn and subsequent turns.
#[ts(optional = nullable)]
pub sandbox_policy: Option<SandboxPolicy>,
/// Override the model for this turn and subsequent turns.
#[ts(optional = nullable)]
pub model: Option<String>,
/// Override the reasoning effort for this turn and subsequent turns.
#[ts(optional = nullable)]
pub effort: Option<ReasoningEffort>,
/// Override the reasoning summary for this turn and subsequent turns.
#[ts(optional = nullable)]
pub summary: Option<ReasoningSummary>,
/// Override the personality for this turn and subsequent turns.
#[ts(optional = nullable)]
pub personality: Option<Personality>,
/// Optional JSON Schema used to constrain the final assistant message for this turn.
#[ts(optional = nullable)]
pub output_schema: Option<JsonValue>,
/// EXPERIMENTAL - set a pre-set collaboration mode.
/// Takes precedence over model, reasoning_effort, and developer instructions if set.
#[ts(optional = nullable)]
pub collaboration_mode: Option<CollaborationMode>,
}
@@ -1981,7 +1859,6 @@ pub struct ReviewStartParams {
/// Where to run the review: inline (default) on the current thread or
/// detached on a new thread (returned in `reviewThreadId`).
#[serde(default)]
#[ts(optional = nullable)]
pub delivery: Option<ReviewDelivery>,
}
@@ -2289,7 +2166,6 @@ pub enum ThreadItem {
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(tag = "type", rename_all = "camelCase")]
#[ts(tag = "type", rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub enum WebSearchAction {
Search {
query: Option<String>,
@@ -2763,22 +2639,20 @@ pub struct CommandExecutionRequestApprovalParams {
pub turn_id: String,
pub item_id: String,
/// Optional explanatory reason (e.g. request for network access).
#[ts(optional = nullable)]
pub reason: Option<String>,
/// The command to be executed.
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional = nullable)]
#[ts(optional)]
pub command: Option<String>,
/// The command's working directory.
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional = nullable)]
#[ts(optional)]
pub cwd: Option<PathBuf>,
/// Best-effort parsed command actions for friendly display.
#[serde(default, skip_serializing_if = "Option::is_none")]
#[ts(optional = nullable)]
#[ts(optional)]
pub command_actions: Option<Vec<CommandAction>>,
/// Optional proposed execpolicy amendment to allow similar commands without prompting.
#[ts(optional = nullable)]
pub proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
}
@@ -2797,11 +2671,9 @@ pub struct FileChangeRequestApprovalParams {
pub turn_id: String,
pub item_id: String,
/// Optional explanatory reason (e.g. request for extra write access).
#[ts(optional = nullable)]
pub reason: Option<String>,
/// [UNSTABLE] When set, the agent is asking the user to allow writes under this root
/// for the remainder of the session (unclear if this is honored today).
#[ts(optional = nullable)]
pub grant_root: Option<PathBuf>,
}
@@ -2826,34 +2698,10 @@ pub struct DynamicToolCallParams {
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct DynamicToolCallResponse {
pub content_items: Vec<DynamicToolCallOutputContentItem>,
pub output: String,
pub success: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(tag = "type", rename_all = "camelCase")]
#[ts(tag = "type")]
#[ts(export_to = "v2/")]
pub enum DynamicToolCallOutputContentItem {
#[serde(rename_all = "camelCase")]
InputText { text: String },
#[serde(rename_all = "camelCase")]
InputImage { image_url: String },
}
impl From<DynamicToolCallOutputContentItem>
for codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem
{
fn from(item: DynamicToolCallOutputContentItem) -> Self {
match item {
DynamicToolCallOutputContentItem::InputText { text } => Self::InputText { text },
DynamicToolCallOutputContentItem::InputImage { image_url } => {
Self::InputImage { image_url }
}
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
@@ -3213,61 +3061,4 @@ mod tests {
})
);
}
#[test]
fn dynamic_tool_response_serializes_content_items() {
let value = serde_json::to_value(DynamicToolCallResponse {
content_items: vec![DynamicToolCallOutputContentItem::InputText {
text: "dynamic-ok".to_string(),
}],
success: true,
})
.unwrap();
assert_eq!(
value,
json!({
"contentItems": [
{
"type": "inputText",
"text": "dynamic-ok"
}
],
"success": true,
})
);
}
#[test]
fn dynamic_tool_response_serializes_text_and_image_content_items() {
let value = serde_json::to_value(DynamicToolCallResponse {
content_items: vec![
DynamicToolCallOutputContentItem::InputText {
text: "dynamic-ok".to_string(),
},
DynamicToolCallOutputContentItem::InputImage {
image_url: "data:image/png;base64,AAA".to_string(),
},
],
success: true,
})
.unwrap();
assert_eq!(
value,
json!({
"contentItems": [
{
"type": "inputText",
"text": "dynamic-ok"
},
{
"type": "inputImage",
"imageUrl": "data:image/png;base64,AAA"
}
],
"success": true,
})
);
}
}

View File

@@ -1,6 +1,6 @@
load("//:defs.bzl", "codex_rust_crate")
codex_rust_crate(
name = "app-server-test-client",
name = "codex-app-server-test-client",
crate_name = "codex_app_server_test_client",
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@
- [Skills](#skills)
- [Apps](#apps)
- [Auth endpoints](#auth-endpoints)
- [Experimental API Opt-in](#experimental-api-opt-in)
- [Adding an experimental field](#adding-an-experimental-field)
## Protocol
@@ -85,17 +85,14 @@ Example (from OpenAI's official VSCode extension):
- `thread/archive` — move a threads rollout file into the archived directory; returns `{}` on success.
- `thread/name/set` — set or update a threads user-facing name; returns `{}` on success. Thread names are not required to be unique; name lookups resolve to the most recently updated thread.
- `thread/unarchive` — move an archived rollout file back into the sessions directory; returns the restored `thread` on success.
- `thread/compact/start` — trigger conversation history compaction for a thread; returns `{}` immediately while progress streams through standard turn/item notifications.
- `thread/rollback` — drop the last N turns from the agents in-memory context and persist a rollback marker in the rollout so future resumes see the pruned history; returns the updated `thread` (with `turns` populated) on success.
- `turn/start` — add user input to a thread and begin Codex generation; responds with the initial `turn` object and streams `turn/started`, `item/*`, and `turn/completed` notifications.
- `turn/interrupt` — request cancellation of an in-flight turn by `(thread_id, turn_id)`; success is an empty `{}` response and the turn finishes with `status: "interrupted"`.
- `review/start` — kick off Codexs automated reviewer for a thread; responds like `turn/start` and emits `item/started`/`item/completed` notifications with `enteredReviewMode` and `exitedReviewMode` items, plus a final assistant `agentMessage` containing the review.
- `command/exec` — run a single command under the server sandbox without starting a thread/turn (handy for utilities and validation).
- `model/list` — list available models (with reasoning effort options and optional `upgrade` model ids).
- `model/list` — list available models (with reasoning effort options).
- `collaborationMode/list` — list available collaboration mode presets (experimental, no pagination).
- `skills/list` — list skills for one or more `cwd` values (optional `forceReload`).
- `skills/remote/read` — list public remote skills (**under development; do not call from production clients yet**).
- `skills/remote/write` — download a public remote skill by `hazelnutId`; `isPreload=true` writes to `.codex/vendor_imports/skills` under `codex_home` (**under development; do not call from production clients yet**).
- `app/list` — list available apps.
- `skills/config/write` — write user-level skill config by path.
- `mcpServer/oauth/login` — start an OAuth login for a configured MCP server; returns an `authorization_url` and later emits `mcpServer/oauthLogin/completed` once the browser flow finishes.
@@ -122,7 +119,6 @@ Start a fresh thread when you need a new Codex conversation.
"approvalPolicy": "never",
"sandbox": "workspaceWrite",
"personality": "friendly",
// Experimental: requires opt-in
"dynamicTools": [
{
"name": "lookup_ticket",
@@ -148,8 +144,6 @@ Start a fresh thread when you need a new Codex conversation.
{ "method": "thread/started", "params": { "thread": { } } }
```
Valid `personality` values are `"friendly"`, `"pragmatic"`, and `"none"`. When `"none"` is selected, the personality placeholder is replaced with an empty string.
To continue a stored session, call `thread/resume` with the `thread.id` you previously recorded. The response shape matches `thread/start`, and no additional notifications are emitted. You can also pass the same configuration overrides supported by `thread/start`, such as `personality`:
```json
@@ -243,22 +237,6 @@ Use `thread/unarchive` to move an archived rollout back into the sessions direct
{ "id": 24, "result": { "thread": { "id": "thr_b" } } }
```
### Example: Trigger thread compaction
Use `thread/compact/start` to trigger manual history compaction for a thread. The request returns immediately with `{}`.
Progress is emitted as standard `turn/*` and `item/*` notifications on the same `threadId`. Clients should expect a single compaction item:
- `item/started` with `item: { "type": "contextCompaction", ... }`
- `item/completed` with the same `contextCompaction` item id
While compaction is running, the thread is effectively in a turn so clients should surface progress UI based on the notifications.
```json
{ "method": "thread/compact/start", "id": 25, "params": { "threadId": "thr_b" } }
{ "id": 25, "result": {} }
```
### Example: Start a turn (send user input)
Turns attach user input (text or images) to a thread and trigger Codex generation. The `input` field is a list of discriminated unions:
@@ -557,41 +535,6 @@ Order of messages:
UI guidance for IDEs: surface an approval dialog as soon as the request arrives. The turn will proceed after the server receives a response to the approval request. The terminal `item/completed` notification will be sent with the appropriate status.
### Dynamic tool calls (experimental)
`dynamicTools` on `thread/start` and the corresponding `item/tool/call` request/response flow are experimental APIs. To enable them, set `initialize.params.capabilities.experimentalApi = true`.
When a dynamic tool is invoked during a turn, the server sends an `item/tool/call` JSON-RPC request to the client:
```json
{
"method": "item/tool/call",
"id": 60,
"params": {
"threadId": "thr_123",
"turnId": "turn_123",
"callId": "call_123",
"tool": "lookup_ticket",
"arguments": { "id": "ABC-123" }
}
}
```
The client must respond with content items. Use `inputText` for text and `inputImage` for image URLs/data URLs:
```json
{
"id": 60,
"result": {
"contentItems": [
{ "type": "inputText", "text": "Ticket ABC-123 is open." },
{ "type": "inputImage", "imageUrl": "data:image/png;base64,AAA" }
],
"success": true
}
}
```
## Skills
Invoke a skill by including `$<skill-name>` in the text input. Add a `skill` input item (recommended) so the backend injects full skill instructions instead of relying on the model to resolve the name.
@@ -827,67 +770,7 @@ Field notes:
- `windowDurationMins` is the quota window length.
- `resetsAt` is a Unix timestamp (seconds) for the next reset.
## Experimental API Opt-in
Some app-server methods and fields are intentionally gated behind an experimental capability with no backwards-compatible guarantees. This lets clients choose between:
- Stable surface only (default): no opt-in, no experimental methods/fields exposed.
- Experimental surface: opt in during `initialize`.
### Generating stable vs experimental client schemas
`codex app-server` schema generation defaults to the stable API surface (experimental fields and methods filtered out). Pass `--experimental` to include experimental methods/fields in generated TypeScript or JSON schema:
```bash
# Stable-only output (default)
codex app-server generate-ts --out DIR
codex app-server generate-json-schema --out DIR
# Include experimental API surface
codex app-server generate-ts --out DIR --experimental
codex app-server generate-json-schema --out DIR --experimental
```
### How clients opt in at runtime
Set `capabilities.experimentalApi` to `true` in your single `initialize` request:
```json
{
"method": "initialize",
"id": 1,
"params": {
"clientInfo": {
"name": "my_client",
"title": "My Client",
"version": "0.1.0"
},
"capabilities": {
"experimentalApi": true
}
}
}
```
Then send the standard `initialized` notification and proceed normally.
Notes:
- If `capabilities` is omitted, `experimentalApi` is treated as `false`.
- This setting is negotiated once at initialization time for the process lifetime (re-initializing is rejected with `"Already initialized"`).
### What happens without opt-in
If a request uses an experimental method or sets an experimental field without opting in, app-server rejects it with a JSON-RPC error. The message is:
`<descriptor> requires experimentalApi capability`
Examples of descriptor strings:
- `mock/experimentalMethod` (method-level gate)
- `thread/start.mockExperimentalField` (field-level gate)
### For maintainers: Adding experimental fields and methods
## Adding an experimental field
Use this checklist when introducing a field/method that should only be available when the client opts into experimental APIs.
At runtime, clients must send `initialize` with `capabilities.experimentalApi = true` to use experimental methods or fields.

View File

@@ -88,7 +88,6 @@ use codex_core::protocol::TurnDiffEvent;
use codex_core::review_format::format_review_findings_block;
use codex_core::review_prompts;
use codex_protocol::ThreadId;
use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem as CoreDynamicToolCallOutputContentItem;
use codex_protocol::dynamic_tools::DynamicToolResponse as CoreDynamicToolResponse;
use codex_protocol::plan_tool::UpdatePlanArgs;
use codex_protocol::protocol::ReviewOutputEvent;
@@ -352,9 +351,8 @@ pub(crate) async fn apply_bespoke_event_handling(
.submit(Op::DynamicToolResponse {
id: call_id.clone(),
response: CoreDynamicToolResponse {
content_items: vec![CoreDynamicToolCallOutputContentItem::InputText {
text: "dynamic tool calls require api v2".to_string(),
}],
call_id,
output: "dynamic tool calls require api v2".to_string(),
success: false,
},
})

View File

@@ -97,15 +97,9 @@ use codex_app_server_protocol::SkillsConfigWriteParams;
use codex_app_server_protocol::SkillsConfigWriteResponse;
use codex_app_server_protocol::SkillsListParams;
use codex_app_server_protocol::SkillsListResponse;
use codex_app_server_protocol::SkillsRemoteReadParams;
use codex_app_server_protocol::SkillsRemoteReadResponse;
use codex_app_server_protocol::SkillsRemoteWriteParams;
use codex_app_server_protocol::SkillsRemoteWriteResponse;
use codex_app_server_protocol::Thread;
use codex_app_server_protocol::ThreadArchiveParams;
use codex_app_server_protocol::ThreadArchiveResponse;
use codex_app_server_protocol::ThreadCompactStartParams;
use codex_app_server_protocol::ThreadCompactStartResponse;
use codex_app_server_protocol::ThreadForkParams;
use codex_app_server_protocol::ThreadForkResponse;
use codex_app_server_protocol::ThreadItem;
@@ -182,8 +176,6 @@ use codex_core::read_head_for_summary;
use codex_core::read_session_meta_line;
use codex_core::rollout_date_parts;
use codex_core::sandboxing::SandboxPermissions;
use codex_core::skills::remote::download_remote_skill;
use codex_core::skills::remote::list_remote_skills;
use codex_core::state_db::get_state_db;
use codex_core::token_data::parse_id_token;
use codex_core::windows_sandbox::WindowsSandboxLevelExt;
@@ -457,9 +449,6 @@ impl CodexMessageProcessor {
ClientRequest::ThreadUnarchive { request_id, params } => {
self.thread_unarchive(request_id, params).await;
}
ClientRequest::ThreadCompactStart { request_id, params } => {
self.thread_compact_start(request_id, params).await;
}
ClientRequest::ThreadRollback { request_id, params } => {
self.thread_rollback(request_id, params).await;
}
@@ -475,12 +464,6 @@ impl CodexMessageProcessor {
ClientRequest::SkillsList { request_id, params } => {
self.skills_list(request_id, params).await;
}
ClientRequest::SkillsRemoteRead { request_id, params } => {
self.skills_remote_read(request_id, params).await;
}
ClientRequest::SkillsRemoteWrite { request_id, params } => {
self.skills_remote_write(request_id, params).await;
}
ClientRequest::AppsList { request_id, params } => {
self.apps_list(request_id, params).await;
}
@@ -1447,7 +1430,7 @@ impl CodexMessageProcessor {
}
let cwd = params.cwd.unwrap_or_else(|| self.config.cwd.clone());
let env = create_env(&self.config.shell_environment_policy, None);
let env = create_env(&self.config.shell_environment_policy);
let timeout_ms = params
.timeout_ms
.and_then(|timeout_ms| u64::try_from(timeout_ms).ok());
@@ -1484,7 +1467,6 @@ impl CodexMessageProcessor {
let outgoing = self.outgoing.clone();
let req_id = request_id;
let sandbox_cwd = self.config.cwd.clone();
let use_linux_sandbox_bwrap = self.config.features.enabled(Feature::UseLinuxSandboxBwrap);
tokio::spawn(async move {
match codex_core::exec::process_exec_tool_call(
@@ -1492,7 +1474,6 @@ impl CodexMessageProcessor {
&effective_policy,
sandbox_cwd.as_path(),
&codex_linux_sandbox_exe,
use_linux_sandbox_bwrap,
None,
)
.await
@@ -2101,30 +2082,6 @@ impl CodexMessageProcessor {
}
}
async fn thread_compact_start(&self, request_id: RequestId, params: ThreadCompactStartParams) {
let ThreadCompactStartParams { thread_id } = params;
let (_, thread) = match self.load_thread(&thread_id).await {
Ok(v) => v,
Err(error) => {
self.outgoing.send_error(request_id, error).await;
return;
}
};
match thread.submit(Op::Compact).await {
Ok(_) => {
self.outgoing
.send_response(request_id, ThreadCompactStartResponse {})
.await;
}
Err(err) => {
self.send_internal_error(request_id, format!("failed to start compaction: {err}"))
.await;
}
}
}
async fn thread_list(&self, request_id: RequestId, params: ThreadListParams) {
let ThreadListParams {
cursor,
@@ -4096,61 +4053,6 @@ impl CodexMessageProcessor {
.await;
}
async fn skills_remote_read(&self, request_id: RequestId, _params: SkillsRemoteReadParams) {
match list_remote_skills(&self.config).await {
Ok(skills) => {
let data = skills
.into_iter()
.map(|skill| codex_app_server_protocol::RemoteSkillSummary {
id: skill.id,
name: skill.name,
description: skill.description,
})
.collect();
self.outgoing
.send_response(request_id, SkillsRemoteReadResponse { data })
.await;
}
Err(err) => {
self.send_internal_error(
request_id,
format!("failed to read remote skills: {err}"),
)
.await;
}
}
}
async fn skills_remote_write(&self, request_id: RequestId, params: SkillsRemoteWriteParams) {
let SkillsRemoteWriteParams {
hazelnut_id,
is_preload,
} = params;
let response = download_remote_skill(&self.config, hazelnut_id.as_str(), is_preload).await;
match response {
Ok(downloaded) => {
self.outgoing
.send_response(
request_id,
SkillsRemoteWriteResponse {
id: downloaded.id,
name: downloaded.name,
path: downloaded.path,
},
)
.await;
}
Err(err) => {
self.send_internal_error(
request_id,
format!("failed to download remote skill: {err}"),
)
.await;
}
}
}
async fn skills_config_write(&self, request_id: RequestId, params: SkillsConfigWriteParams) {
let SkillsConfigWriteParams { path, enabled } = params;
let edits = vec![ConfigEdit::SetSkillConfig { path, enabled }];

View File

@@ -1,6 +1,5 @@
use codex_app_server_protocol::DynamicToolCallResponse;
use codex_core::CodexThread;
use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem as CoreDynamicToolCallOutputContentItem;
use codex_protocol::dynamic_tools::DynamicToolResponse as CoreDynamicToolResponse;
use codex_protocol::protocol::Op;
use std::sync::Arc;
@@ -18,9 +17,8 @@ pub(crate) async fn on_call_response(
Err(err) => {
error!("request failed: {err:?}");
let fallback = CoreDynamicToolResponse {
content_items: vec![CoreDynamicToolCallOutputContentItem::InputText {
text: "dynamic tool request failed".to_string(),
}],
call_id: call_id.clone(),
output: "dynamic tool request failed".to_string(),
success: false,
};
if let Err(err) = conversation
@@ -39,25 +37,14 @@ pub(crate) async fn on_call_response(
let response = serde_json::from_value::<DynamicToolCallResponse>(value).unwrap_or_else(|err| {
error!("failed to deserialize DynamicToolCallResponse: {err}");
DynamicToolCallResponse {
content_items: vec![
codex_app_server_protocol::DynamicToolCallOutputContentItem::InputText {
text: "dynamic tool response was invalid".to_string(),
},
],
output: "dynamic tool response was invalid".to_string(),
success: false,
}
});
let DynamicToolCallResponse {
content_items,
success,
} = response;
let response = CoreDynamicToolResponse {
content_items: content_items
.into_iter()
.map(CoreDynamicToolCallOutputContentItem::from)
.collect(),
success,
call_id: call_id.clone(),
output: response.output,
success: response.success,
};
if let Err(err) = conversation
.submit(Op::DynamicToolResponse {

View File

@@ -22,14 +22,12 @@ fn model_from_preset(preset: ModelPreset) -> Model {
Model {
id: preset.id.to_string(),
model: preset.model.to_string(),
upgrade: preset.upgrade.map(|upgrade| upgrade.id),
display_name: preset.display_name.to_string(),
description: preset.description.to_string(),
supported_reasoning_efforts: reasoning_efforts_from_preset(
preset.supported_reasoning_efforts,
),
default_reasoning_effort: preset.default_reasoning_effort,
input_modalities: preset.input_modalities,
supports_personality: preset.supports_personality,
is_default: preset.is_default,
}

View File

@@ -50,7 +50,6 @@ use codex_app_server_protocol::SendUserTurnParams;
use codex_app_server_protocol::ServerRequest;
use codex_app_server_protocol::SetDefaultModelParams;
use codex_app_server_protocol::ThreadArchiveParams;
use codex_app_server_protocol::ThreadCompactStartParams;
use codex_app_server_protocol::ThreadForkParams;
use codex_app_server_protocol::ThreadListParams;
use codex_app_server_protocol::ThreadLoadedListParams;
@@ -419,15 +418,6 @@ impl McpProcess {
self.send_request("thread/unarchive", params).await
}
/// Send a `thread/compact/start` JSON-RPC request.
pub async fn send_thread_compact_start_request(
&mut self,
params: ThreadCompactStartParams,
) -> anyhow::Result<i64> {
let params = Some(serde_json::to_value(params)?);
self.send_request("thread/compact/start", params).await
}
/// Send a `thread/rollback` JSON-RPC request.
pub async fn send_thread_rollback_request(
&mut self,

View File

@@ -6,7 +6,6 @@ use codex_protocol::openai_models::ModelInfo;
use codex_protocol::openai_models::ModelPreset;
use codex_protocol::openai_models::ModelVisibility;
use codex_protocol::openai_models::TruncationPolicyConfig;
use codex_protocol::openai_models::default_input_modalities;
use serde_json::json;
use std::path::Path;
@@ -39,7 +38,6 @@ fn preset_to_info(preset: &ModelPreset, priority: i32) -> ModelInfo {
auto_compact_token_limit: None,
effective_context_window_percent: 95,
experimental_supported_tools: Vec::new(),
input_modalities: default_input_modalities(),
}
}
@@ -77,11 +75,9 @@ pub fn write_models_cache_with_models(
let cache_path = codex_home.join("models_cache.json");
// DateTime<Utc> serializes to RFC3339 format by default with serde
let fetched_at: DateTime<Utc> = Utc::now();
let client_version = codex_core::models_manager::client_version_to_whole();
let cache = json!({
"fetched_at": fetched_at,
"etag": null,
"client_version": client_version,
"models": models
});
std::fs::write(cache_path, serde_json::to_string_pretty(&cache)?)

View File

@@ -36,7 +36,7 @@ use std::path::Path;
use tempfile::TempDir;
use tokio::time::timeout;
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(20);
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
async fn test_codex_jsonrpc_conversation_flow() -> Result<()> {
@@ -76,7 +76,6 @@ async fn test_codex_jsonrpc_conversation_flow() -> Result<()> {
let new_conv_id = mcp
.send_new_conversation_request(NewConversationParams {
cwd: Some(working_directory.to_string_lossy().into_owned()),
sandbox: Some(SandboxMode::DangerFullAccess),
..Default::default()
})
.await?;

View File

@@ -147,7 +147,7 @@ fn create_config_toml(codex_home: &Path, server_uri: String) -> std::io::Result<
r#"
model = "mock-model"
approval_policy = "never"
sandbox_mode = "danger-full-access"
sandbox_mode = "read-only"
model_provider = "mock_provider"

View File

@@ -308,7 +308,6 @@ async fn test_list_and_resume_conversations() -> Result<()> {
text: fork_history_text.to_string(),
}],
end_turn: None,
phase: None,
}];
let resume_with_history_req_id = mcp
.send_resume_conversation_request(ResumeConversationParams {

View File

@@ -1,8 +1,8 @@
//! Validates that the collaboration mode list endpoint returns the expected default presets.
//!
//! The test drives the app server through the MCP harness and asserts that the list response
//! includes the plan and default modes with their default model and reasoning effort
//! settings, which keeps the API contract visible in one place.
//! includes the plan, coding, pair programming, and execute modes with their default model and reasoning
//! effort settings, which keeps the API contract visible in one place.
#![allow(clippy::unwrap_used)]
@@ -45,8 +45,23 @@ async fn list_collaboration_modes_returns_presets() -> Result<()> {
let CollaborationModeListResponse { data: items } =
to_response::<CollaborationModeListResponse>(response)?;
let expected = vec![plan_preset(), default_preset()];
assert_eq!(expected, items);
let expected = [
plan_preset(),
code_preset(),
pair_programming_preset(),
execute_preset(),
];
assert_eq!(expected.len(), items.len());
for (expected_mask, actual_mask) in expected.iter().zip(items.iter()) {
assert_eq!(expected_mask.name, actual_mask.name);
assert_eq!(expected_mask.mode, actual_mask.mode);
assert_eq!(expected_mask.model, actual_mask.model);
assert_eq!(expected_mask.reasoning_effort, actual_mask.reasoning_effort);
assert_eq!(
expected_mask.developer_instructions,
actual_mask.developer_instructions
);
}
Ok(())
}
@@ -62,11 +77,35 @@ fn plan_preset() -> CollaborationModeMask {
.unwrap()
}
/// Builds the default preset that the list response is expected to return.
fn default_preset() -> CollaborationModeMask {
/// Builds the pair programming preset that the list response is expected to return.
///
/// The helper keeps the expected model and reasoning defaults co-located with the test
/// so that mismatches point directly at the API contract being exercised.
fn pair_programming_preset() -> CollaborationModeMask {
let presets = test_builtin_collaboration_mode_presets();
presets
.into_iter()
.find(|p| p.mode == Some(ModeKind::Default))
.find(|p| p.mode == Some(ModeKind::PairProgramming))
.unwrap()
}
/// Builds the code preset that the list response is expected to return.
fn code_preset() -> CollaborationModeMask {
let presets = test_builtin_collaboration_mode_presets();
presets
.into_iter()
.find(|p| p.mode == Some(ModeKind::Code))
.unwrap()
}
/// Builds the execute preset that the list response is expected to return.
///
/// The execute preset uses a different reasoning effort to capture the higher-effort
/// execution contract the server currently exposes.
fn execute_preset() -> CollaborationModeMask {
let presets = test_builtin_collaboration_mode_presets();
presets
.into_iter()
.find(|p| p.mode == Some(ModeKind::Execute))
.unwrap()
}

View File

@@ -15,12 +15,9 @@ use app_test_support::write_chatgpt_auth;
use app_test_support::write_mock_responses_config_toml;
use codex_app_server_protocol::ItemCompletedNotification;
use codex_app_server_protocol::ItemStartedNotification;
use codex_app_server_protocol::JSONRPCError;
use codex_app_server_protocol::JSONRPCNotification;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::RequestId;
use codex_app_server_protocol::ThreadCompactStartParams;
use codex_app_server_protocol::ThreadCompactStartResponse;
use codex_app_server_protocol::ThreadItem;
use codex_app_server_protocol::ThreadStartParams;
use codex_app_server_protocol::ThreadStartResponse;
@@ -42,7 +39,6 @@ use tokio::time::timeout;
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
const AUTO_COMPACT_LIMIT: i64 = 1_000;
const COMPACT_PROMPT: &str = "Summarize the conversation.";
const INVALID_REQUEST_ERROR_CODE: i64 = -32600;
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn auto_compaction_local_emits_started_and_completed_items() -> Result<()> {
@@ -130,7 +126,6 @@ async fn auto_compaction_remote_emits_started_and_completed_items() -> Result<()
text: "REMOTE_COMPACT_SUMMARY".to_string(),
}],
end_turn: None,
phase: None,
},
ResponseItem::Compaction {
encrypted_content: "ENCRYPTED_COMPACTION_SUMMARY".to_string(),
@@ -200,134 +195,6 @@ async fn auto_compaction_remote_emits_started_and_completed_items() -> Result<()
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn thread_compact_start_triggers_compaction_and_returns_empty_response() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = responses::start_mock_server().await;
let sse = responses::sse(vec![
responses::ev_assistant_message("m1", "MANUAL_COMPACT_SUMMARY"),
responses::ev_completed_with_tokens("r1", 200),
]);
responses::mount_sse_sequence(&server, vec![sse]).await;
let codex_home = TempDir::new()?;
write_mock_responses_config_toml(
codex_home.path(),
&server.uri(),
&BTreeMap::default(),
AUTO_COMPACT_LIMIT,
None,
"mock_provider",
COMPACT_PROMPT,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_thread(&mut mcp).await?;
let compact_id = mcp
.send_thread_compact_start_request(ThreadCompactStartParams {
thread_id: thread_id.clone(),
})
.await?;
let compact_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(compact_id)),
)
.await??;
let _compact: ThreadCompactStartResponse =
to_response::<ThreadCompactStartResponse>(compact_resp)?;
let started = wait_for_context_compaction_started(&mut mcp).await?;
let completed = wait_for_context_compaction_completed(&mut mcp).await?;
let ThreadItem::ContextCompaction { id: started_id } = started.item else {
unreachable!("started item should be context compaction");
};
let ThreadItem::ContextCompaction { id: completed_id } = completed.item else {
unreachable!("completed item should be context compaction");
};
assert_eq!(started.thread_id, thread_id);
assert_eq!(completed.thread_id, thread_id);
assert_eq!(started_id, completed_id);
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn thread_compact_start_rejects_invalid_thread_id() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = responses::start_mock_server().await;
let codex_home = TempDir::new()?;
write_mock_responses_config_toml(
codex_home.path(),
&server.uri(),
&BTreeMap::default(),
AUTO_COMPACT_LIMIT,
None,
"mock_provider",
COMPACT_PROMPT,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_thread_compact_start_request(ThreadCompactStartParams {
thread_id: "not-a-thread-id".to_string(),
})
.await?;
let error: JSONRPCError = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_error_message(RequestId::Integer(request_id)),
)
.await??;
assert_eq!(error.error.code, INVALID_REQUEST_ERROR_CODE);
assert!(error.error.message.contains("invalid thread id"));
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn thread_compact_start_rejects_unknown_thread_id() -> Result<()> {
skip_if_no_network!(Ok(()));
let server = responses::start_mock_server().await;
let codex_home = TempDir::new()?;
write_mock_responses_config_toml(
codex_home.path(),
&server.uri(),
&BTreeMap::default(),
AUTO_COMPACT_LIMIT,
None,
"mock_provider",
COMPACT_PROMPT,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_thread_compact_start_request(ThreadCompactStartParams {
thread_id: "67e55044-10b1-426f-9247-bb680e5fe0c8".to_string(),
})
.await?;
let error: JSONRPCError = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_error_message(RequestId::Integer(request_id)),
)
.await??;
assert_eq!(error.error.code, INVALID_REQUEST_ERROR_CODE);
assert!(error.error.message.contains("thread not found"));
Ok(())
}
async fn start_thread(mcp: &mut McpProcess) -> Result<String> {
let thread_id = mcp
.send_thread_start_request(ThreadStartParams {

View File

@@ -4,7 +4,6 @@ use app_test_support::McpProcess;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
use codex_app_server_protocol::DynamicToolCallOutputContentItem;
use codex_app_server_protocol::DynamicToolCallParams;
use codex_app_server_protocol::DynamicToolCallResponse;
use codex_app_server_protocol::DynamicToolSpec;
@@ -16,9 +15,6 @@ use codex_app_server_protocol::ThreadStartResponse;
use codex_app_server_protocol::TurnStartParams;
use codex_app_server_protocol::TurnStartResponse;
use codex_app_server_protocol::UserInput as V2UserInput;
use codex_protocol::models::FunctionCallOutputBody;
use codex_protocol::models::FunctionCallOutputContentItem;
use codex_protocol::models::FunctionCallOutputPayload;
use core_test_support::responses;
use pretty_assertions::assert_eq;
use serde_json::Value;
@@ -115,7 +111,7 @@ async fn thread_start_injects_dynamic_tools_into_model_requests() -> Result<()>
/// Exercises the full dynamic tool call path (server request, client response, model output).
#[tokio::test]
async fn dynamic_tool_call_round_trip_sends_text_content_items_to_model() -> Result<()> {
async fn dynamic_tool_call_round_trip_sends_output_to_model() -> Result<()> {
let call_id = "dyn-call-1";
let tool_name = "demo_tool";
let tool_args = json!({ "city": "Paris" });
@@ -204,9 +200,7 @@ async fn dynamic_tool_call_round_trip_sends_text_content_items_to_model() -> Res
// Respond to the tool call so the model receives a function_call_output.
let response = DynamicToolCallResponse {
content_items: vec![DynamicToolCallOutputContentItem::InputText {
text: "dynamic-ok".to_string(),
}],
output: "dynamic-ok".to_string(),
success: true,
};
mcp.send_response(request_id, serde_json::to_value(response)?)
@@ -219,171 +213,11 @@ async fn dynamic_tool_call_round_trip_sends_text_content_items_to_model() -> Res
.await??;
let bodies = responses_bodies(&server).await?;
let payload = bodies
let output = bodies
.iter()
.find_map(|body| function_call_output_payload(body, call_id))
.find_map(|body| function_call_output_text(body, call_id))
.context("expected function_call_output in follow-up request")?;
let expected_payload = FunctionCallOutputPayload::from_content_items(vec![
FunctionCallOutputContentItem::InputText {
text: "dynamic-ok".to_string(),
},
]);
assert_eq!(payload, expected_payload);
Ok(())
}
/// Ensures dynamic tool call responses can include structured content items.
#[tokio::test]
async fn dynamic_tool_call_round_trip_sends_content_items_to_model() -> Result<()> {
let call_id = "dyn-call-items-1";
let tool_name = "demo_tool";
let tool_args = json!({ "city": "Paris" });
let tool_call_arguments = serde_json::to_string(&tool_args)?;
let responses = vec![
responses::sse(vec![
responses::ev_response_created("resp-1"),
responses::ev_function_call(call_id, tool_name, &tool_call_arguments),
responses::ev_completed("resp-1"),
]),
create_final_assistant_message_sse_response("Done")?,
];
let server = create_mock_responses_server_sequence_unchecked(responses).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let dynamic_tool = DynamicToolSpec {
name: tool_name.to_string(),
description: "Demo dynamic tool".to_string(),
input_schema: json!({
"type": "object",
"properties": {
"city": { "type": "string" }
},
"required": ["city"],
"additionalProperties": false,
}),
};
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
dynamic_tools: Some(vec![dynamic_tool]),
..Default::default()
})
.await?;
let thread_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(thread_req)),
)
.await??;
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(thread_resp)?;
let turn_req = mcp
.send_turn_start_request(TurnStartParams {
thread_id: thread.id.clone(),
input: vec![V2UserInput::Text {
text: "Run the tool".to_string(),
text_elements: Vec::new(),
}],
..Default::default()
})
.await?;
let turn_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(turn_req)),
)
.await??;
let TurnStartResponse { turn } = to_response::<TurnStartResponse>(turn_resp)?;
let request = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_request_message(),
)
.await??;
let (request_id, params) = match request {
ServerRequest::DynamicToolCall { request_id, params } => (request_id, params),
other => panic!("expected DynamicToolCall request, got {other:?}"),
};
let expected = DynamicToolCallParams {
thread_id: thread.id,
turn_id: turn.id,
call_id: call_id.to_string(),
tool: tool_name.to_string(),
arguments: tool_args,
};
assert_eq!(params, expected);
let response_content_items = vec![
DynamicToolCallOutputContentItem::InputText {
text: "dynamic-ok".to_string(),
},
DynamicToolCallOutputContentItem::InputImage {
image_url: "data:image/png;base64,AAA".to_string(),
},
];
let content_items = response_content_items
.clone()
.into_iter()
.map(|item| match item {
DynamicToolCallOutputContentItem::InputText { text } => {
FunctionCallOutputContentItem::InputText { text }
}
DynamicToolCallOutputContentItem::InputImage { image_url } => {
FunctionCallOutputContentItem::InputImage { image_url }
}
})
.collect::<Vec<FunctionCallOutputContentItem>>();
let response = DynamicToolCallResponse {
content_items: response_content_items,
success: true,
};
mcp.send_response(request_id, serde_json::to_value(response)?)
.await?;
timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_notification_message("turn/completed"),
)
.await??;
let bodies = responses_bodies(&server).await?;
let output_value = bodies
.iter()
.find_map(|body| function_call_output_raw_output(body, call_id))
.context("expected function_call_output output in follow-up request")?;
assert_eq!(
output_value,
json!([
{
"type": "input_text",
"text": "dynamic-ok"
},
{
"type": "input_image",
"image_url": "data:image/png;base64,AAA"
}
])
);
let payload = bodies
.iter()
.find_map(|body| function_call_output_payload(body, call_id))
.context("expected function_call_output in follow-up request")?;
assert_eq!(
payload.body,
FunctionCallOutputBody::ContentItems(content_items.clone())
);
assert_eq!(payload.success, None);
assert_eq!(
serde_json::to_string(&payload)?,
serde_json::to_string(&content_items)?
);
assert_eq!(output, "dynamic-ok");
Ok(())
}
@@ -414,12 +248,7 @@ fn find_tool<'a>(body: &'a Value, name: &str) -> Option<&'a Value> {
})
}
fn function_call_output_payload(body: &Value, call_id: &str) -> Option<FunctionCallOutputPayload> {
function_call_output_raw_output(body, call_id)
.and_then(|output| serde_json::from_value(output).ok())
}
fn function_call_output_raw_output(body: &Value, call_id: &str) -> Option<Value> {
fn function_call_output_text(body: &Value, call_id: &str) -> Option<String> {
body.get("input")
.and_then(Value::as_array)
.and_then(|items| {
@@ -429,7 +258,8 @@ fn function_call_output_raw_output(body: &Value, call_id: &str) -> Option<Value>
})
})
.and_then(|item| item.get("output"))
.cloned()
.and_then(Value::as_str)
.map(str::to_string)
}
fn create_config_toml(codex_home: &Path, server_uri: &str) -> std::io::Result<()> {

View File

@@ -12,7 +12,6 @@ use codex_app_server_protocol::ModelListParams;
use codex_app_server_protocol::ModelListResponse;
use codex_app_server_protocol::ReasoningEffortOption;
use codex_app_server_protocol::RequestId;
use codex_protocol::openai_models::InputModality;
use codex_protocol::openai_models::ReasoningEffort;
use pretty_assertions::assert_eq;
use tempfile::TempDir;
@@ -51,7 +50,6 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> {
Model {
id: "gpt-5.2-codex".to_string(),
model: "gpt-5.2-codex".to_string(),
upgrade: None,
display_name: "gpt-5.2-codex".to_string(),
description: "Latest frontier agentic coding model.".to_string(),
supported_reasoning_efforts: vec![
@@ -74,14 +72,12 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> {
},
],
default_reasoning_effort: ReasoningEffort::Medium,
input_modalities: vec![InputModality::Text, InputModality::Image],
supports_personality: false,
is_default: true,
},
Model {
id: "gpt-5.1-codex-max".to_string(),
model: "gpt-5.1-codex-max".to_string(),
upgrade: Some("gpt-5.2-codex".to_string()),
display_name: "gpt-5.1-codex-max".to_string(),
description: "Codex-optimized flagship for deep and fast reasoning.".to_string(),
supported_reasoning_efforts: vec![
@@ -104,14 +100,12 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> {
},
],
default_reasoning_effort: ReasoningEffort::Medium,
input_modalities: vec![InputModality::Text, InputModality::Image],
supports_personality: false,
is_default: false,
},
Model {
id: "gpt-5.1-codex-mini".to_string(),
model: "gpt-5.1-codex-mini".to_string(),
upgrade: Some("gpt-5.2-codex".to_string()),
display_name: "gpt-5.1-codex-mini".to_string(),
description: "Optimized for codex. Cheaper, faster, but less capable.".to_string(),
supported_reasoning_efforts: vec![
@@ -126,14 +120,12 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> {
},
],
default_reasoning_effort: ReasoningEffort::Medium,
input_modalities: vec![InputModality::Text, InputModality::Image],
supports_personality: false,
is_default: false,
},
Model {
id: "gpt-5.2".to_string(),
model: "gpt-5.2".to_string(),
upgrade: Some("gpt-5.2-codex".to_string()),
display_name: "gpt-5.2".to_string(),
description:
"Latest frontier model with improvements across knowledge, reasoning and coding"
@@ -162,7 +154,6 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> {
},
],
default_reasoning_effort: ReasoningEffort::Medium,
input_modalities: vec![InputModality::Text, InputModality::Image],
supports_personality: false,
is_default: false,
},

View File

@@ -1,9 +1,6 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::create_shell_command_sse_response;
use app_test_support::to_response;
use codex_app_server_protocol::ItemCompletedNotification;
use codex_app_server_protocol::ItemStartedNotification;
@@ -15,7 +12,6 @@ use codex_app_server_protocol::ReviewDelivery;
use codex_app_server_protocol::ReviewStartParams;
use codex_app_server_protocol::ReviewStartResponse;
use codex_app_server_protocol::ReviewTarget;
use codex_app_server_protocol::ServerRequest;
use codex_app_server_protocol::ThreadItem;
use codex_app_server_protocol::ThreadStartParams;
use codex_app_server_protocol::ThreadStartResponse;
@@ -133,91 +129,6 @@ async fn review_start_runs_review_turn_and_emits_code_review_item() -> Result<()
Ok(())
}
#[tokio::test]
async fn review_start_exec_approval_item_id_matches_command_execution_item() -> Result<()> {
let responses = vec![
create_shell_command_sse_response(
vec![
"git".to_string(),
"rev-parse".to_string(),
"HEAD".to_string(),
],
None,
Some(5000),
"review-call-1",
)?,
create_final_assistant_message_sse_response("done")?,
];
let server = create_mock_responses_server_sequence(responses).await;
let codex_home = TempDir::new()?;
create_config_toml_with_approval_policy(codex_home.path(), &server.uri(), "untrusted")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
let review_req = mcp
.send_review_start_request(ReviewStartParams {
thread_id,
delivery: Some(ReviewDelivery::Inline),
target: ReviewTarget::Commit {
sha: "1234567deadbeef".to_string(),
title: Some("Check review approvals".to_string()),
},
})
.await?;
let review_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(review_req)),
)
.await??;
let ReviewStartResponse { turn, .. } = to_response::<ReviewStartResponse>(review_resp)?;
let turn_id = turn.id.clone();
let server_req = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_request_message(),
)
.await??;
let ServerRequest::CommandExecutionRequestApproval { request_id, params } = server_req else {
panic!("expected CommandExecutionRequestApproval request");
};
assert_eq!(params.item_id, "review-call-1");
assert_eq!(params.turn_id, turn_id);
let mut command_item_id = None;
for _ in 0..10 {
let item_started: JSONRPCNotification = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_notification_message("item/started"),
)
.await??;
let started: ItemStartedNotification =
serde_json::from_value(item_started.params.expect("params must be present"))?;
if let ThreadItem::CommandExecution { id, .. } = started.item {
command_item_id = Some(id);
break;
}
}
let command_item_id = command_item_id.expect("did not observe command execution item");
assert_eq!(command_item_id, params.item_id);
mcp.send_response(
request_id,
serde_json::json!({ "decision": codex_core::protocol::ReviewDecision::Approved }),
)
.await?;
timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_notification_message("turn/completed"),
)
.await??;
Ok(())
}
#[tokio::test]
async fn review_start_rejects_empty_base_branch() -> Result<()> {
let server = create_mock_responses_server_repeating_assistant("Done").await;
@@ -388,21 +299,13 @@ async fn start_default_thread(mcp: &mut McpProcess) -> Result<String> {
}
fn create_config_toml(codex_home: &std::path::Path, server_uri: &str) -> std::io::Result<()> {
create_config_toml_with_approval_policy(codex_home, server_uri, "never")
}
fn create_config_toml_with_approval_policy(
codex_home: &std::path::Path,
server_uri: &str,
approval_policy: &str,
) -> std::io::Result<()> {
let config_toml = codex_home.join("config.toml");
std::fs::write(
config_toml,
format!(
r#"
model = "mock-model"
approval_policy = "{approval_policy}"
approval_policy = "never"
sandbox_mode = "read-only"
model_provider = "mock_provider"

View File

@@ -338,7 +338,6 @@ async fn thread_resume_supports_history_and_overrides() -> Result<()> {
text: history_text.to_string(),
}],
end_turn: None,
phase: None,
}];
// Resume with explicit history and override the model.

View File

@@ -129,7 +129,7 @@ fn create_config_toml(codex_home: &std::path::Path, server_uri: &str) -> std::io
r#"
model = "mock-model"
approval_policy = "never"
sandbox_mode = "danger-full-access"
sandbox_mode = "workspace-write"
model_provider = "mock_provider"

Some files were not shown because too many files have changed in this diff Show More