mirror of
https://github.com/openai/codex.git
synced 2026-04-23 06:04:53 +00:00
Compare commits
85 Commits
subagent-n
...
codex/turn
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
baf0a90cae | ||
|
|
d7602c3081 | ||
|
|
5d91f2b2c2 | ||
|
|
d52f1a5d37 | ||
|
|
e0ab8c645c | ||
|
|
d2f8b95bbf | ||
|
|
8b57fdd973 | ||
|
|
be5bca6f8d | ||
|
|
f6fdfbeb98 | ||
|
|
3f30746237 | ||
|
|
a0fd94bde6 | ||
|
|
73eaebbd1c | ||
|
|
648a420cbf | ||
|
|
9d7013eab0 | ||
|
|
7b39e76a66 | ||
|
|
947092283a | ||
|
|
0543d0a022 | ||
|
|
9a393c9b6f | ||
|
|
8362b79cb4 | ||
|
|
01f25a7b96 | ||
|
|
bccce0d75f | ||
|
|
8d49e0d0c4 | ||
|
|
e4bfa763f6 | ||
|
|
5441130e0a | ||
|
|
5a9a5b51b2 | ||
|
|
bcd6e68054 | ||
|
|
93efcfd50d | ||
|
|
6d6570d89d | ||
|
|
f46b767b7e | ||
|
|
a046849438 | ||
|
|
10c04e11b8 | ||
|
|
6a3233da64 | ||
|
|
c4ec6be4ab | ||
|
|
59398125f6 | ||
|
|
c086b36b58 | ||
|
|
9501669a24 | ||
|
|
ddfa032eb8 | ||
|
|
6cb2f02ef8 | ||
|
|
1151972fb2 | ||
|
|
8f3f2c3c02 | ||
|
|
16ca527c80 | ||
|
|
e6bb5d8553 | ||
|
|
125fbec317 | ||
|
|
74e112ea09 | ||
|
|
e88f74d140 | ||
|
|
448fb6ac22 | ||
|
|
63c2ac96cd | ||
|
|
5163850025 | ||
|
|
3d356723c4 | ||
|
|
8da40c9251 | ||
|
|
5571a022eb | ||
|
|
ee1520e79e | ||
|
|
61cd3a9700 | ||
|
|
fefdc03b25 | ||
|
|
dcab40123f | ||
|
|
bd192b54cd | ||
|
|
b6ab2214e3 | ||
|
|
3b5fc7547e | ||
|
|
daf0f03ac8 | ||
|
|
061d1d3b5e | ||
|
|
67d9261e2c | ||
|
|
0b6c2e5652 | ||
|
|
74cebceed7 | ||
|
|
3ca0e7673b | ||
|
|
8d3d58f992 | ||
|
|
ca556fa313 | ||
|
|
f6053fdfb3 | ||
|
|
9a8adbf6e5 | ||
|
|
97d0068658 | ||
|
|
0679e70bfc | ||
|
|
3fe365ad8a | ||
|
|
8758db5d5b | ||
|
|
15f6cfb047 | ||
|
|
68a7d98363 | ||
|
|
7e46e5b9c2 | ||
|
|
58763afa0f | ||
|
|
a4076ab4b1 | ||
|
|
09a82f364f | ||
|
|
fbeda61cc3 | ||
|
|
c3048ff90a | ||
|
|
af215eb390 | ||
|
|
38f84b6b29 | ||
|
|
5a3bdcb27b | ||
|
|
d580995957 | ||
|
|
10a3adad8e |
12
.github/workflows/bazel.yml
vendored
12
.github/workflows/bazel.yml
vendored
@@ -47,6 +47,11 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Set up Node.js for js_repl tests
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: codex-rs/node-version.txt
|
||||
|
||||
# Some integration tests rely on DotSlash being installed.
|
||||
# See https://github.com/openai/codex/pull/7617.
|
||||
- name: Install DotSlash
|
||||
@@ -156,6 +161,13 @@ jobs:
|
||||
--build_metadata=VISIBILITY=PUBLIC
|
||||
)
|
||||
|
||||
if [[ "${RUNNER_OS:-}" != "Windows" ]]; then
|
||||
# Bazel test sandboxes on macOS may resolve an older Homebrew `node`
|
||||
# before the `actions/setup-node` runtime on PATH.
|
||||
node_bin="$(which node)"
|
||||
bazel_args+=("--test_env=CODEX_JS_REPL_NODE_PATH=${node_bin}")
|
||||
fi
|
||||
|
||||
if [[ -n "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
echo "BuildBuddy API key is available; using remote Bazel configuration."
|
||||
# Work around Bazel 9 remote repo contents cache / overlay materialization failures
|
||||
|
||||
4
.github/workflows/rust-ci.yml
vendored
4
.github/workflows/rust-ci.yml
vendored
@@ -499,6 +499,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Node.js for js_repl tests
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: codex-rs/node-version.txt
|
||||
- name: Install Linux build dependencies
|
||||
if: ${{ runner.os == 'Linux' }}
|
||||
shell: bash
|
||||
|
||||
6
.github/workflows/rust-release.yml
vendored
6
.github/workflows/rust-release.yml
vendored
@@ -178,6 +178,12 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Avoid problematic aws-lc jitter entropy code path on musl builders.
|
||||
echo "AWS_LC_SYS_NO_JITTER_ENTROPY=1" >> "$GITHUB_ENV"
|
||||
target_no_jitter="AWS_LC_SYS_NO_JITTER_ENTROPY_${{ matrix.target }}"
|
||||
target_no_jitter="${target_no_jitter//-/_}"
|
||||
echo "${target_no_jitter}=1" >> "$GITHUB_ENV"
|
||||
|
||||
# Clear global Rust flags so host/proc-macro builds don't pull in UBSan.
|
||||
echo "RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
|
||||
126
.github/workflows/shell-tool-mcp.yml
vendored
126
.github/workflows/shell-tool-mcp.yml
vendored
@@ -67,128 +67,6 @@ jobs:
|
||||
echo "npm_tag=${npm_tag}" >> "$GITHUB_OUTPUT"
|
||||
echo "should_publish=${should_publish}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
rust-binaries:
|
||||
name: Build Rust - ${{ matrix.target }}
|
||||
needs: metadata
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
CARGO_PROFILE_RELEASE_LTO: ${{ contains(needs.metadata.outputs.version, '-alpha') && 'thin' || 'fat' }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: codex-rs
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- runner: macos-15-xlarge
|
||||
target: aarch64-apple-darwin
|
||||
- runner: macos-15-xlarge
|
||||
target: x86_64-apple-darwin
|
||||
- runner: ubuntu-24.04
|
||||
target: x86_64-unknown-linux-musl
|
||||
install_musl: true
|
||||
- runner: ubuntu-24.04-arm
|
||||
target: aarch64-unknown-linux-musl
|
||||
install_musl: true
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install UBSan runtime (musl)
|
||||
if: ${{ matrix.install_musl }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
sudo apt-get update -y
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libubsan1
|
||||
fi
|
||||
|
||||
- uses: dtolnay/rust-toolchain@1.93.0
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- if: ${{ matrix.install_musl }}
|
||||
name: Install Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.14.0
|
||||
|
||||
- if: ${{ matrix.install_musl }}
|
||||
name: Install musl build dependencies
|
||||
env:
|
||||
TARGET: ${{ matrix.target }}
|
||||
run: bash "${GITHUB_WORKSPACE}/.github/scripts/install-musl-build-tools.sh"
|
||||
|
||||
- if: ${{ matrix.install_musl }}
|
||||
name: Configure rustc UBSan wrapper (musl host)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ubsan=""
|
||||
if command -v ldconfig >/dev/null 2>&1; then
|
||||
ubsan="$(ldconfig -p | grep -m1 'libubsan\.so\.1' | sed -E 's/.*=> (.*)$/\1/')"
|
||||
fi
|
||||
wrapper_root="${RUNNER_TEMP:-/tmp}"
|
||||
wrapper="${wrapper_root}/rustc-ubsan-wrapper"
|
||||
cat > "${wrapper}" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ -n "${ubsan}" ]]; then
|
||||
export LD_PRELOAD="${ubsan}\${LD_PRELOAD:+:\${LD_PRELOAD}}"
|
||||
fi
|
||||
exec "\$1" "\${@:2}"
|
||||
EOF
|
||||
chmod +x "${wrapper}"
|
||||
echo "RUSTC_WRAPPER=${wrapper}" >> "$GITHUB_ENV"
|
||||
echo "RUSTC_WORKSPACE_WRAPPER=" >> "$GITHUB_ENV"
|
||||
|
||||
- if: ${{ matrix.install_musl }}
|
||||
name: Clear sanitizer flags (musl)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Clear global Rust flags so host/proc-macro builds don't pull in UBSan.
|
||||
echo "RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "RUSTDOCFLAGS=" >> "$GITHUB_ENV"
|
||||
# Override any runner-level Cargo config rustflags as well.
|
||||
echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
|
||||
sanitize_flags() {
|
||||
local input="$1"
|
||||
input="${input//-fsanitize=undefined/}"
|
||||
input="${input//-fno-sanitize-recover=undefined/}"
|
||||
input="${input//-fno-sanitize-trap=undefined/}"
|
||||
echo "$input"
|
||||
}
|
||||
|
||||
cflags="$(sanitize_flags "${CFLAGS-}")"
|
||||
cxxflags="$(sanitize_flags "${CXXFLAGS-}")"
|
||||
echo "CFLAGS=${cflags}" >> "$GITHUB_ENV"
|
||||
echo "CXXFLAGS=${cxxflags}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Build exec server binaries
|
||||
run: cargo build --release --target ${{ matrix.target }} --bin codex-exec-mcp-server --bin codex-execve-wrapper
|
||||
|
||||
- name: Stage exec server binaries
|
||||
run: |
|
||||
dest="${GITHUB_WORKSPACE}/artifacts/vendor/${{ matrix.target }}"
|
||||
mkdir -p "$dest"
|
||||
cp "target/${{ matrix.target }}/release/codex-exec-mcp-server" "$dest/"
|
||||
cp "target/${{ matrix.target }}/release/codex-execve-wrapper" "$dest/"
|
||||
|
||||
- uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: shell-tool-mcp-rust-${{ matrix.target }}
|
||||
path: artifacts/**
|
||||
if-no-files-found: error
|
||||
|
||||
bash-linux:
|
||||
name: Build Bash (Linux) - ${{ matrix.variant }} - ${{ matrix.target }}
|
||||
needs: metadata
|
||||
@@ -537,7 +415,6 @@ jobs:
|
||||
name: Package npm module
|
||||
needs:
|
||||
- metadata
|
||||
- rust-binaries
|
||||
- bash-linux
|
||||
- bash-darwin
|
||||
- zsh-linux
|
||||
@@ -579,7 +456,6 @@ jobs:
|
||||
mkdir -p "$staging" "$staging/vendor"
|
||||
cp shell-tool-mcp/README.md "$staging/"
|
||||
cp shell-tool-mcp/package.json "$staging/"
|
||||
cp -R shell-tool-mcp/bin "$staging/"
|
||||
|
||||
found_vendor="false"
|
||||
shopt -s nullglob
|
||||
@@ -613,8 +489,6 @@ jobs:
|
||||
set -euo pipefail
|
||||
staging="${{ steps.staging.outputs.dir }}"
|
||||
chmod +x \
|
||||
"$staging"/vendor/*/codex-exec-mcp-server \
|
||||
"$staging"/vendor/*/codex-execve-wrapper \
|
||||
"$staging"/vendor/*/bash/*/bash \
|
||||
"$staging"/vendor/*/zsh/*/zsh
|
||||
|
||||
|
||||
234
MODULE.bazel.lock
generated
234
MODULE.bazel.lock
generated
File diff suppressed because one or more lines are too long
960
codex-rs/Cargo.lock
generated
960
codex-rs/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,6 @@ members = [
|
||||
"hooks",
|
||||
"secrets",
|
||||
"exec",
|
||||
"exec-server",
|
||||
"execpolicy",
|
||||
"execpolicy-legacy",
|
||||
"keyring-store",
|
||||
@@ -59,10 +58,12 @@ members = [
|
||||
"utils/approval-presets",
|
||||
"utils/oss",
|
||||
"utils/fuzzy-match",
|
||||
"utils/stream-parser",
|
||||
"codex-client",
|
||||
"codex-api",
|
||||
"state",
|
||||
"codex-experimental-api-macros",
|
||||
"test-macros",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
@@ -117,6 +118,7 @@ codex-shell-command = { path = "shell-command" }
|
||||
codex-shell-escalation = { path = "shell-escalation" }
|
||||
codex-skills = { path = "skills" }
|
||||
codex-state = { path = "state" }
|
||||
codex-test-macros = { path = "test-macros" }
|
||||
codex-stdio-to-uds = { path = "stdio-to-uds" }
|
||||
codex-tui = { path = "tui" }
|
||||
codex-utils-absolute-path = { path = "utils/absolute-path" }
|
||||
@@ -136,9 +138,9 @@ codex-utils-rustls-provider = { path = "utils/rustls-provider" }
|
||||
codex-utils-sandbox-summary = { path = "utils/sandbox-summary" }
|
||||
codex-utils-sleep-inhibitor = { path = "utils/sleep-inhibitor" }
|
||||
codex-utils-string = { path = "utils/string" }
|
||||
codex-utils-stream-parser = { path = "utils/stream-parser" }
|
||||
codex-windows-sandbox = { path = "windows-sandbox-rs" }
|
||||
core_test_support = { path = "core/tests/common" }
|
||||
exec_server_test_support = { path = "exec-server/tests/common" }
|
||||
mcp_test_support = { path = "mcp-server/tests/common" }
|
||||
|
||||
# External
|
||||
@@ -147,6 +149,7 @@ allocative = "0.3.3"
|
||||
ansi-to-tui = "7.0.0"
|
||||
anyhow = "1"
|
||||
arboard = { version = "3", features = ["wayland-data-control"] }
|
||||
askama = "0.15.4"
|
||||
assert_cmd = "2"
|
||||
assert_matches = "1.5.0"
|
||||
async-channel = "2.3.1"
|
||||
@@ -162,6 +165,7 @@ clap = "4"
|
||||
clap_complete = "4"
|
||||
color-eyre = "0.6.3"
|
||||
crossbeam-channel = "0.5.15"
|
||||
csv = "1.3.1"
|
||||
crossterm = "0.28.1"
|
||||
ctor = "0.6.3"
|
||||
derive_more = "2"
|
||||
@@ -175,6 +179,7 @@ env_logger = "0.11.9"
|
||||
eventsource-stream = "0.2.3"
|
||||
futures = { version = "0.3", default-features = false }
|
||||
globset = "0.4"
|
||||
gethostname = "1.1.0"
|
||||
http = "1.3.1"
|
||||
icu_decimal = "2.1"
|
||||
icu_locale_core = "2.1"
|
||||
@@ -183,7 +188,6 @@ ignore = "0.4.23"
|
||||
image = { version = "^0.25.9", default-features = false }
|
||||
include_dir = "0.7.4"
|
||||
indexmap = "2.12.0"
|
||||
indoc = "2.0"
|
||||
insta = "1.46.3"
|
||||
inventory = "0.3.19"
|
||||
itertools = "0.14.0"
|
||||
|
||||
@@ -1,6 +1,28 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"NetworkPolicyAmendment": {
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/NetworkPolicyRuleAction"
|
||||
},
|
||||
"host": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"host"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"NetworkPolicyRuleAction": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ReviewDecision": {
|
||||
"description": "User's decision in response to an ExecApprovalRequest.",
|
||||
"oneOf": [
|
||||
@@ -43,6 +65,28 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"description": "User chose to persist a network policy rule (allow/deny) for future requests to the same host.",
|
||||
"properties": {
|
||||
"network_policy_amendment": {
|
||||
"properties": {
|
||||
"network_policy_amendment": {
|
||||
"$ref": "#/definitions/NetworkPolicyAmendment"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"network_policy_amendment"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"network_policy_amendment"
|
||||
],
|
||||
"title": "NetworkPolicyAmendmentReviewDecision",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "User has denied this command and the agent should not execute it, but it should continue the session and try something else.",
|
||||
"enum": [
|
||||
|
||||
@@ -376,6 +376,70 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ExternalAgentConfigDetectParams": {
|
||||
"properties": {
|
||||
"cwds": {
|
||||
"description": "Zero or more working directories to include for repo-scoped detection.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"includeHome": {
|
||||
"description": "If true, include detection under the user's home (~/.claude, ~/.codex, etc.).",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ExternalAgentConfigImportParams": {
|
||||
"properties": {
|
||||
"migrationItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ExternalAgentConfigMigrationItem"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"migrationItems"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ExternalAgentConfigMigrationItem": {
|
||||
"properties": {
|
||||
"cwd": {
|
||||
"description": "Null or empty means home-scoped migration; non-empty means repo-scoped migration.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemType": {
|
||||
"$ref": "#/definitions/ExternalAgentConfigMigrationItemType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"description",
|
||||
"itemType"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ExternalAgentConfigMigrationItemType": {
|
||||
"enum": [
|
||||
"AGENTS_MD",
|
||||
"CONFIG",
|
||||
"SKILLS",
|
||||
"MCP_SERVER_CONFIG"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FeedbackUploadParams": {
|
||||
"properties": {
|
||||
"classification": {
|
||||
@@ -1920,6 +1984,13 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"searchTerm": {
|
||||
"description": "Optional substring filter for the extracted thread title.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortKey": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -1981,6 +2052,38 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadRealtimeAudioChunk": {
|
||||
"description": "EXPERIMENTAL - thread realtime audio chunk.",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
},
|
||||
"numChannels": {
|
||||
"format": "uint16",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
},
|
||||
"sampleRate": {
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
},
|
||||
"samplesPerChannel": {
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data",
|
||||
"numChannels",
|
||||
"sampleRate"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadResumeParams": {
|
||||
"description": "There are three ways to resume a thread: 1. By thread_id: load the thread from disk by thread_id and resume it. 2. By history: instantiate the thread from memory and resume it. 3. By path: load the thread from disk by path and resume it.\n\nThe precedence is: history > path > thread_id. If using history or path, the thread_id param will be ignored.\n\nPrefer using thread_id whenever possible.",
|
||||
"properties": {
|
||||
@@ -2190,6 +2293,12 @@
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"serviceName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
@@ -3390,6 +3499,54 @@
|
||||
"title": "Config/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"externalAgentConfig/detect"
|
||||
],
|
||||
"title": "ExternalAgentConfig/detectRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ExternalAgentConfigDetectParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "ExternalAgentConfig/detectRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"externalAgentConfig/import"
|
||||
],
|
||||
"title": "ExternalAgentConfig/importRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ExternalAgentConfigImportParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "ExternalAgentConfig/importRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
|
||||
@@ -1,6 +1,97 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"AdditionalFileSystemPermissions": {
|
||||
"properties": {
|
||||
"read": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"write": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AdditionalMacOsPermissions": {
|
||||
"properties": {
|
||||
"accessibility": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"automations": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MacOsAutomationValue"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"calendar": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"preferences": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MacOsPreferencesValue"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AdditionalPermissionProfile": {
|
||||
"properties": {
|
||||
"fileSystem": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AdditionalFileSystemPermissions"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"macos": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AdditionalMacOsPermissions"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"network": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"CommandAction": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -111,6 +202,29 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"MacOsAutomationValue": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"MacOsPreferencesValue": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"NetworkApprovalContext": {
|
||||
"properties": {
|
||||
"host": {
|
||||
@@ -134,6 +248,28 @@
|
||||
"socks5Udp"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkPolicyAmendment": {
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/NetworkPolicyRuleAction"
|
||||
},
|
||||
"host": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"host"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"NetworkPolicyRuleAction": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
@@ -180,7 +316,7 @@
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional context for managed-network approval prompts."
|
||||
"description": "Optional context for a managed-network approval prompt."
|
||||
},
|
||||
"proposedExecpolicyAmendment": {
|
||||
"description": "Optional proposed execpolicy amendment to allow similar commands without prompting.",
|
||||
@@ -192,6 +328,16 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"proposedNetworkPolicyAmendments": {
|
||||
"description": "Optional proposed network policy amendments (allow/deny host) for future requests.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/NetworkPolicyAmendment"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"reason": {
|
||||
"description": "Optional explanatory reason (e.g. request for network access).",
|
||||
"type": [
|
||||
|
||||
@@ -42,6 +42,28 @@
|
||||
"title": "AcceptWithExecpolicyAmendmentCommandExecutionApprovalDecision",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"description": "User chose a persistent network policy rule (allow/deny) for this host.",
|
||||
"properties": {
|
||||
"applyNetworkPolicyAmendment": {
|
||||
"properties": {
|
||||
"network_policy_amendment": {
|
||||
"$ref": "#/definitions/NetworkPolicyAmendment"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"network_policy_amendment"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"applyNetworkPolicyAmendment"
|
||||
],
|
||||
"title": "ApplyNetworkPolicyAmendmentCommandExecutionApprovalDecision",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "User denied the command. The agent will continue the turn.",
|
||||
"enum": [
|
||||
@@ -57,6 +79,28 @@
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"NetworkPolicyAmendment": {
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/NetworkPolicyRuleAction"
|
||||
},
|
||||
"host": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"host"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"NetworkPolicyRuleAction": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
|
||||
@@ -500,6 +500,50 @@
|
||||
],
|
||||
"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"
|
||||
}
|
||||
]
|
||||
},
|
||||
"EventMsg": {
|
||||
"description": "Response event from the agent NOTE: Make sure none of these values have optional types, as it will mess up the extension code-gen.",
|
||||
"oneOf": [
|
||||
@@ -1613,6 +1657,17 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"additional_permissions": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PermissionProfile"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional additional filesystem permissions requested for this command."
|
||||
},
|
||||
"approval_id": {
|
||||
"description": "Identifier for this specific approval callback.\n\nWhen absent, the approval is for the command item itself (`call_id`). This is present for subcommand approvals (via execve intercept).",
|
||||
"type": [
|
||||
@@ -1662,6 +1717,16 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"proposed_network_policy_amendments": {
|
||||
"description": "Proposed network policy amendments (for example allow/deny this host in future).",
|
||||
"items": {
|
||||
"$ref": "#/definitions/NetworkPolicyAmendment"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"reason": {
|
||||
"description": "Optional human-readable reason for the approval (e.g. retry without sandbox).",
|
||||
"type": [
|
||||
@@ -1755,6 +1820,94 @@
|
||||
"title": "DynamicToolCallRequestEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": {
|
||||
"description": "Dynamic tool call arguments."
|
||||
},
|
||||
"call_id": {
|
||||
"description": "Identifier for the corresponding DynamicToolCallRequest.",
|
||||
"type": "string"
|
||||
},
|
||||
"content_items": {
|
||||
"description": "Dynamic tool response content items.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"duration": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Duration"
|
||||
}
|
||||
],
|
||||
"description": "The duration of the dynamic tool call."
|
||||
},
|
||||
"error": {
|
||||
"description": "Optional error text when the tool call failed before producing a response.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"success": {
|
||||
"description": "Whether the tool call succeeded.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"tool": {
|
||||
"description": "Dynamic tool name.",
|
||||
"type": "string"
|
||||
},
|
||||
"turn_id": {
|
||||
"description": "Turn ID that this dynamic tool call belongs to.",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamic_tool_call_response"
|
||||
],
|
||||
"title": "DynamicToolCallResponseEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"call_id",
|
||||
"content_items",
|
||||
"duration",
|
||||
"success",
|
||||
"tool",
|
||||
"turn_id",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallResponseEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"item_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"skill_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"skill_request_approval"
|
||||
],
|
||||
"title": "SkillRequestApprovalEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"item_id",
|
||||
"skill_name",
|
||||
"type"
|
||||
],
|
||||
"title": "SkillRequestApprovalEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -3268,6 +3421,29 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"FileSystemPermissions": {
|
||||
"properties": {
|
||||
"read": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"write": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"FunctionCallOutputBody": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -3461,6 +3637,66 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MacOsAutomationValue": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"MacOsPermissions": {
|
||||
"properties": {
|
||||
"accessibility": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"automations": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MacOsAutomationValue"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"calendar": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"preferences": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MacOsPreferencesValue"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"MacOsPreferencesValue": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"McpAuthStatus": {
|
||||
"enum": [
|
||||
"unsupported",
|
||||
@@ -3637,6 +3873,28 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkPolicyAmendment": {
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/NetworkPolicyRuleAction"
|
||||
},
|
||||
"host": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"host"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"NetworkPolicyRuleAction": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ParsedCommand": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -3756,6 +4014,37 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PermissionProfile": {
|
||||
"properties": {
|
||||
"file_system": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/FileSystemPermissions"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"macos": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MacOsPermissions"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"network": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"PlanItemArg": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
@@ -6858,6 +7147,17 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"additional_permissions": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PermissionProfile"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional additional filesystem permissions requested for this command."
|
||||
},
|
||||
"approval_id": {
|
||||
"description": "Identifier for this specific approval callback.\n\nWhen absent, the approval is for the command item itself (`call_id`). This is present for subcommand approvals (via execve intercept).",
|
||||
"type": [
|
||||
@@ -6907,6 +7207,16 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"proposed_network_policy_amendments": {
|
||||
"description": "Proposed network policy amendments (for example allow/deny this host in future).",
|
||||
"items": {
|
||||
"$ref": "#/definitions/NetworkPolicyAmendment"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"reason": {
|
||||
"description": "Optional human-readable reason for the approval (e.g. retry without sandbox).",
|
||||
"type": [
|
||||
@@ -7000,6 +7310,94 @@
|
||||
"title": "DynamicToolCallRequestEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": {
|
||||
"description": "Dynamic tool call arguments."
|
||||
},
|
||||
"call_id": {
|
||||
"description": "Identifier for the corresponding DynamicToolCallRequest.",
|
||||
"type": "string"
|
||||
},
|
||||
"content_items": {
|
||||
"description": "Dynamic tool response content items.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"duration": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Duration"
|
||||
}
|
||||
],
|
||||
"description": "The duration of the dynamic tool call."
|
||||
},
|
||||
"error": {
|
||||
"description": "Optional error text when the tool call failed before producing a response.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"success": {
|
||||
"description": "Whether the tool call succeeded.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"tool": {
|
||||
"description": "Dynamic tool name.",
|
||||
"type": "string"
|
||||
},
|
||||
"turn_id": {
|
||||
"description": "Turn ID that this dynamic tool call belongs to.",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamic_tool_call_response"
|
||||
],
|
||||
"title": "DynamicToolCallResponseEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"call_id",
|
||||
"content_items",
|
||||
"duration",
|
||||
"success",
|
||||
"tool",
|
||||
"turn_id",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallResponseEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"item_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"skill_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"skill_request_approval"
|
||||
],
|
||||
"title": "SkillRequestApprovalEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"item_id",
|
||||
"skill_name",
|
||||
"type"
|
||||
],
|
||||
"title": "SkillRequestApprovalEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
|
||||
@@ -1,6 +1,28 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"NetworkPolicyAmendment": {
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/NetworkPolicyRuleAction"
|
||||
},
|
||||
"host": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"host"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"NetworkPolicyRuleAction": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ReviewDecision": {
|
||||
"description": "User's decision in response to an ExecApprovalRequest.",
|
||||
"oneOf": [
|
||||
@@ -43,6 +65,28 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"description": "User chose to persist a network policy rule (allow/deny) for future requests to the same host.",
|
||||
"properties": {
|
||||
"network_policy_amendment": {
|
||||
"properties": {
|
||||
"network_policy_amendment": {
|
||||
"$ref": "#/definitions/NetworkPolicyAmendment"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"network_policy_amendment"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"network_policy_amendment"
|
||||
],
|
||||
"title": "NetworkPolicyAmendmentReviewDecision",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "User has denied this command and the agent should not execute it, but it should continue the session and try something else.",
|
||||
"enum": [
|
||||
|
||||
@@ -778,6 +778,58 @@
|
||||
],
|
||||
"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"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ErrorNotification": {
|
||||
"properties": {
|
||||
"error": {
|
||||
@@ -1965,6 +2017,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
@@ -2177,6 +2282,120 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadRealtimeAudioChunk": {
|
||||
"description": "EXPERIMENTAL - thread realtime audio chunk.",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
},
|
||||
"numChannels": {
|
||||
"format": "uint16",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
},
|
||||
"sampleRate": {
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
},
|
||||
"samplesPerChannel": {
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data",
|
||||
"numChannels",
|
||||
"sampleRate"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadRealtimeClosedNotification": {
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime transport closes.",
|
||||
"properties": {
|
||||
"reason": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadRealtimeErrorNotification": {
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime encounters an error.",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message",
|
||||
"threadId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadRealtimeItemAddedNotification": {
|
||||
"description": "EXPERIMENTAL - raw non-audio thread realtime item emitted by the backend.",
|
||||
"properties": {
|
||||
"item": true,
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"item",
|
||||
"threadId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadRealtimeOutputAudioDeltaNotification": {
|
||||
"description": "EXPERIMENTAL - streamed output audio emitted by thread realtime.",
|
||||
"properties": {
|
||||
"audio": {
|
||||
"$ref": "#/definitions/ThreadRealtimeAudioChunk"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"audio",
|
||||
"threadId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadRealtimeStartedNotification": {
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime startup is accepted.",
|
||||
"properties": {
|
||||
"sessionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadStartedNotification": {
|
||||
"properties": {
|
||||
"thread": {
|
||||
@@ -3453,6 +3672,106 @@
|
||||
"title": "FuzzyFileSearch/sessionCompletedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/realtime/started"
|
||||
],
|
||||
"title": "Thread/realtime/startedNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ThreadRealtimeStartedNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/realtime/startedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/realtime/itemAdded"
|
||||
],
|
||||
"title": "Thread/realtime/itemAddedNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ThreadRealtimeItemAddedNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/realtime/itemAddedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/realtime/outputAudio/delta"
|
||||
],
|
||||
"title": "Thread/realtime/outputAudio/deltaNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ThreadRealtimeOutputAudioDeltaNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/realtime/outputAudio/deltaNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/realtime/error"
|
||||
],
|
||||
"title": "Thread/realtime/errorNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ThreadRealtimeErrorNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/realtime/errorNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/realtime/closed"
|
||||
],
|
||||
"title": "Thread/realtime/closedNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ThreadRealtimeClosedNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/realtime/closedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Notifies the user of world-writable directories on Windows, which cannot be protected by the sandbox.",
|
||||
"properties": {
|
||||
|
||||
@@ -1,6 +1,97 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"AdditionalFileSystemPermissions": {
|
||||
"properties": {
|
||||
"read": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"write": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AdditionalMacOsPermissions": {
|
||||
"properties": {
|
||||
"accessibility": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"automations": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MacOsAutomationValue"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"calendar": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"preferences": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MacOsPreferencesValue"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AdditionalPermissionProfile": {
|
||||
"properties": {
|
||||
"fileSystem": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AdditionalFileSystemPermissions"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"macos": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AdditionalMacOsPermissions"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"network": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ApplyPatchApprovalParams": {
|
||||
"properties": {
|
||||
"callId": {
|
||||
@@ -222,7 +313,7 @@
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional context for managed-network approval prompts."
|
||||
"description": "Optional context for a managed-network approval prompt."
|
||||
},
|
||||
"proposedExecpolicyAmendment": {
|
||||
"description": "Optional proposed execpolicy amendment to allow similar commands without prompting.",
|
||||
@@ -234,6 +325,16 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"proposedNetworkPolicyAmendments": {
|
||||
"description": "Optional proposed network policy amendments (allow/deny host) for future requests.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/NetworkPolicyAmendment"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"reason": {
|
||||
"description": "Optional explanatory reason (e.g. request for network access).",
|
||||
"type": [
|
||||
@@ -430,6 +531,29 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"MacOsAutomationValue": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"MacOsPreferencesValue": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"NetworkApprovalContext": {
|
||||
"properties": {
|
||||
"host": {
|
||||
@@ -454,6 +578,28 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkPolicyAmendment": {
|
||||
"properties": {
|
||||
"action": {
|
||||
"$ref": "#/definitions/NetworkPolicyRuleAction"
|
||||
},
|
||||
"host": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"action",
|
||||
"host"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"NetworkPolicyRuleAction": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ParsedCommand": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -576,6 +722,21 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"SkillRequestApprovalParams": {
|
||||
"properties": {
|
||||
"itemId": {
|
||||
"type": "string"
|
||||
},
|
||||
"skillName": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"itemId",
|
||||
"skillName"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -737,6 +898,30 @@
|
||||
"title": "Item/tool/requestUserInputRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"skill/requestApproval"
|
||||
],
|
||||
"title": "Skill/requestApprovalRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/SkillRequestApprovalParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Skill/requestApprovalRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Execute a dynamic tool call on the client.",
|
||||
"properties": {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"itemId": {
|
||||
"type": "string"
|
||||
},
|
||||
"skillName": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"itemId",
|
||||
"skillName"
|
||||
],
|
||||
"title": "SkillRequestApprovalParams",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"SkillApprovalDecision": {
|
||||
"enum": [
|
||||
"approve",
|
||||
"decline"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"decision": {
|
||||
"$ref": "#/definitions/SkillApprovalDecision"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"decision"
|
||||
],
|
||||
"title": "SkillRequestApprovalResponse",
|
||||
"type": "object"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"cwds": {
|
||||
"description": "Zero or more working directories to include for repo-scoped detection.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"includeHome": {
|
||||
"description": "If true, include detection under the user's home (~/.claude, ~/.codex, etc.).",
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"title": "ExternalAgentConfigDetectParams",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"ExternalAgentConfigMigrationItem": {
|
||||
"properties": {
|
||||
"cwd": {
|
||||
"description": "Null or empty means home-scoped migration; non-empty means repo-scoped migration.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemType": {
|
||||
"$ref": "#/definitions/ExternalAgentConfigMigrationItemType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"description",
|
||||
"itemType"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ExternalAgentConfigMigrationItemType": {
|
||||
"enum": [
|
||||
"AGENTS_MD",
|
||||
"CONFIG",
|
||||
"SKILLS",
|
||||
"MCP_SERVER_CONFIG"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"items": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ExternalAgentConfigMigrationItem"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"items"
|
||||
],
|
||||
"title": "ExternalAgentConfigDetectResponse",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"ExternalAgentConfigMigrationItem": {
|
||||
"properties": {
|
||||
"cwd": {
|
||||
"description": "Null or empty means home-scoped migration; non-empty means repo-scoped migration.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"itemType": {
|
||||
"$ref": "#/definitions/ExternalAgentConfigMigrationItemType"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"description",
|
||||
"itemType"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ExternalAgentConfigMigrationItemType": {
|
||||
"enum": [
|
||||
"AGENTS_MD",
|
||||
"CONFIG",
|
||||
"SKILLS",
|
||||
"MCP_SERVER_CONFIG"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"migrationItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/ExternalAgentConfigMigrationItem"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"migrationItems"
|
||||
],
|
||||
"title": "ExternalAgentConfigImportParams",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "ExternalAgentConfigImportResponse",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -185,6 +185,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -633,6 +685,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -185,6 +185,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -633,6 +685,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -299,6 +299,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -747,6 +799,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -345,6 +345,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -1207,6 +1259,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -65,6 +65,13 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"searchTerm": {
|
||||
"description": "Optional substring filter for the extracted thread title.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortKey": {
|
||||
"anyOf": [
|
||||
{
|
||||
|
||||
@@ -299,6 +299,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -980,6 +1032,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -299,6 +299,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -980,6 +1032,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime transport closes.",
|
||||
"properties": {
|
||||
"reason": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadRealtimeClosedNotification",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime encounters an error.",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message",
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadRealtimeErrorNotification",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "EXPERIMENTAL - raw non-audio thread realtime item emitted by the backend.",
|
||||
"properties": {
|
||||
"item": true,
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"item",
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadRealtimeItemAddedNotification",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"ThreadRealtimeAudioChunk": {
|
||||
"description": "EXPERIMENTAL - thread realtime audio chunk.",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
},
|
||||
"numChannels": {
|
||||
"format": "uint16",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
},
|
||||
"sampleRate": {
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
},
|
||||
"samplesPerChannel": {
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data",
|
||||
"numChannels",
|
||||
"sampleRate"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"description": "EXPERIMENTAL - streamed output audio emitted by thread realtime.",
|
||||
"properties": {
|
||||
"audio": {
|
||||
"$ref": "#/definitions/ThreadRealtimeAudioChunk"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"audio",
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadRealtimeOutputAudioDeltaNotification",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime startup is accepted.",
|
||||
"properties": {
|
||||
"sessionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadRealtimeStartedNotification",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -345,6 +345,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -1207,6 +1259,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -299,6 +299,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -980,6 +1032,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -150,6 +150,12 @@
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"serviceName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": "ThreadStartParams",
|
||||
|
||||
@@ -345,6 +345,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -1207,6 +1259,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -299,6 +299,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -980,6 +1032,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -299,6 +299,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -980,6 +1032,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -299,6 +299,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -747,6 +799,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -299,6 +299,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -747,6 +799,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
@@ -299,6 +299,58 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"DynamicToolCallOutputContentItem": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputText"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"type"
|
||||
],
|
||||
"title": "InputTextDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"imageUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"inputImage"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"imageUrl",
|
||||
"type"
|
||||
],
|
||||
"title": "InputImageDynamicToolCallOutputContentItem",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DynamicToolCallStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
"completed",
|
||||
"failed"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileUpdateChange": {
|
||||
"properties": {
|
||||
"diff": {
|
||||
@@ -747,6 +799,59 @@
|
||||
"title": "McpToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"arguments": true,
|
||||
"contentItems": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/DynamicToolCallOutputContentItem"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"durationMs": {
|
||||
"description": "The duration of the dynamic tool call in milliseconds.",
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"$ref": "#/definitions/DynamicToolCallStatus"
|
||||
},
|
||||
"success": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tool": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"dynamicToolCall"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItemType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"arguments",
|
||||
"id",
|
||||
"status",
|
||||
"tool",
|
||||
"type"
|
||||
],
|
||||
"title": "DynamicToolCallThreadItem",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"agentsStates": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +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.
|
||||
|
||||
export type DynamicToolCallOutputContentItem = { "type": "inputText", text: string, } | { "type": "inputImage", imageUrl: string, };
|
||||
@@ -0,0 +1,39 @@
|
||||
// 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";
|
||||
import type { JsonValue } from "./serde_json/JsonValue";
|
||||
|
||||
export type DynamicToolCallResponseEvent = {
|
||||
/**
|
||||
* Identifier for the corresponding DynamicToolCallRequest.
|
||||
*/
|
||||
call_id: string,
|
||||
/**
|
||||
* Turn ID that this dynamic tool call belongs to.
|
||||
*/
|
||||
turn_id: string,
|
||||
/**
|
||||
* Dynamic tool name.
|
||||
*/
|
||||
tool: string,
|
||||
/**
|
||||
* Dynamic tool call arguments.
|
||||
*/
|
||||
arguments: JsonValue,
|
||||
/**
|
||||
* Dynamic tool response content items.
|
||||
*/
|
||||
content_items: Array<DynamicToolCallOutputContentItem>,
|
||||
/**
|
||||
* Whether the tool call succeeded.
|
||||
*/
|
||||
success: boolean,
|
||||
/**
|
||||
* Optional error text when the tool call failed before producing a response.
|
||||
*/
|
||||
error: string | null,
|
||||
/**
|
||||
* The duration of the dynamic tool call.
|
||||
*/
|
||||
duration: string, };
|
||||
@@ -24,6 +24,7 @@ import type { CollabWaitingEndEvent } from "./CollabWaitingEndEvent";
|
||||
import type { ContextCompactedEvent } from "./ContextCompactedEvent";
|
||||
import type { DeprecationNoticeEvent } from "./DeprecationNoticeEvent";
|
||||
import type { DynamicToolCallRequest } from "./DynamicToolCallRequest";
|
||||
import type { DynamicToolCallResponseEvent } from "./DynamicToolCallResponseEvent";
|
||||
import type { ElicitationRequestEvent } from "./ElicitationRequestEvent";
|
||||
import type { ErrorEvent } from "./ErrorEvent";
|
||||
import type { ExecApprovalRequestEvent } from "./ExecApprovalRequestEvent";
|
||||
@@ -56,6 +57,7 @@ import type { RemoteSkillDownloadedEvent } from "./RemoteSkillDownloadedEvent";
|
||||
import type { RequestUserInputEvent } from "./RequestUserInputEvent";
|
||||
import type { ReviewRequest } from "./ReviewRequest";
|
||||
import type { SessionConfiguredEvent } from "./SessionConfiguredEvent";
|
||||
import type { SkillRequestApprovalEvent } from "./SkillRequestApprovalEvent";
|
||||
import type { StreamErrorEvent } from "./StreamErrorEvent";
|
||||
import type { TerminalInteractionEvent } from "./TerminalInteractionEvent";
|
||||
import type { ThreadNameUpdatedEvent } from "./ThreadNameUpdatedEvent";
|
||||
@@ -78,4 +80,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": "realtime_conversation_started" } & RealtimeConversationStartedEvent | { "type": "realtime_conversation_realtime" } & RealtimeConversationRealtimeEvent | { "type": "realtime_conversation_closed" } & RealtimeConversationClosedEvent | { "type": "model_reroute" } & ModelRerouteEvent | { "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 | { "type": "collab_resume_begin" } & CollabResumeBeginEvent | { "type": "collab_resume_end" } & CollabResumeEndEvent;
|
||||
export type EventMsg = { "type": "error" } & ErrorEvent | { "type": "warning" } & WarningEvent | { "type": "realtime_conversation_started" } & RealtimeConversationStartedEvent | { "type": "realtime_conversation_realtime" } & RealtimeConversationRealtimeEvent | { "type": "realtime_conversation_closed" } & RealtimeConversationClosedEvent | { "type": "model_reroute" } & ModelRerouteEvent | { "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": "dynamic_tool_call_response" } & DynamicToolCallResponseEvent | { "type": "skill_request_approval" } & SkillRequestApprovalEvent | { "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 | { "type": "collab_resume_begin" } & CollabResumeBeginEvent | { "type": "collab_resume_end" } & CollabResumeEndEvent;
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
|
||||
import type { NetworkApprovalContext } from "./NetworkApprovalContext";
|
||||
import type { NetworkPolicyAmendment } from "./NetworkPolicyAmendment";
|
||||
import type { ParsedCommand } from "./ParsedCommand";
|
||||
import type { PermissionProfile } from "./PermissionProfile";
|
||||
|
||||
export type ExecApprovalRequestEvent = {
|
||||
/**
|
||||
@@ -41,4 +43,12 @@ network_approval_context?: NetworkApprovalContext,
|
||||
/**
|
||||
* Proposed execpolicy amendment that can be applied to allow future runs.
|
||||
*/
|
||||
proposed_execpolicy_amendment?: ExecPolicyAmendment, parsed_cmd: Array<ParsedCommand>, };
|
||||
proposed_execpolicy_amendment?: ExecPolicyAmendment,
|
||||
/**
|
||||
* Proposed network policy amendments (for example allow/deny this host in future).
|
||||
*/
|
||||
proposed_network_policy_amendments?: Array<NetworkPolicyAmendment>,
|
||||
/**
|
||||
* Optional additional filesystem permissions requested for this command.
|
||||
*/
|
||||
additional_permissions?: PermissionProfile, parsed_cmd: Array<ParsedCommand>, };
|
||||
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type FileSystemPermissions = { read: Array<string> | null, write: Array<string> | null, };
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type MacOsAutomationValue = boolean | Array<string>;
|
||||
@@ -0,0 +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 { MacOsAutomationValue } from "./MacOsAutomationValue";
|
||||
import type { MacOsPreferencesValue } from "./MacOsPreferencesValue";
|
||||
|
||||
export type MacOsPermissions = { preferences: MacOsPreferencesValue | null, automations: MacOsAutomationValue | null, accessibility: boolean | null, calendar: boolean | null, };
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type MacOsPreferencesValue = boolean | string;
|
||||
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { NetworkPolicyRuleAction } from "./NetworkPolicyRuleAction";
|
||||
|
||||
export type NetworkPolicyAmendment = { host: string, action: NetworkPolicyRuleAction, };
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type NetworkPolicyRuleAction = "allow" | "deny";
|
||||
@@ -0,0 +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 { FileSystemPermissions } from "./FileSystemPermissions";
|
||||
import type { MacOsPermissions } from "./MacOsPermissions";
|
||||
|
||||
export type PermissionProfile = { network: boolean | null, file_system: FileSystemPermissions | null, macos: MacOsPermissions | null, };
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
|
||||
import type { NetworkPolicyAmendment } from "./NetworkPolicyAmendment";
|
||||
|
||||
/**
|
||||
* User's decision in response to an ExecApprovalRequest.
|
||||
*/
|
||||
export type ReviewDecision = "approved" | { "approved_execpolicy_amendment": { proposed_execpolicy_amendment: ExecPolicyAmendment, } } | "approved_for_session" | "denied" | "abort";
|
||||
export type ReviewDecision = "approved" | { "approved_execpolicy_amendment": { proposed_execpolicy_amendment: ExecPolicyAmendment, } } | "approved_for_session" | { "network_policy_amendment": { network_policy_amendment: NetworkPolicyAmendment, } } | "denied" | "abort";
|
||||
|
||||
@@ -30,6 +30,11 @@ import type { ReasoningTextDeltaNotification } from "./v2/ReasoningTextDeltaNoti
|
||||
import type { TerminalInteractionNotification } from "./v2/TerminalInteractionNotification";
|
||||
import type { ThreadArchivedNotification } from "./v2/ThreadArchivedNotification";
|
||||
import type { ThreadNameUpdatedNotification } from "./v2/ThreadNameUpdatedNotification";
|
||||
import type { ThreadRealtimeClosedNotification } from "./v2/ThreadRealtimeClosedNotification";
|
||||
import type { ThreadRealtimeErrorNotification } from "./v2/ThreadRealtimeErrorNotification";
|
||||
import type { ThreadRealtimeItemAddedNotification } from "./v2/ThreadRealtimeItemAddedNotification";
|
||||
import type { ThreadRealtimeOutputAudioDeltaNotification } from "./v2/ThreadRealtimeOutputAudioDeltaNotification";
|
||||
import type { ThreadRealtimeStartedNotification } from "./v2/ThreadRealtimeStartedNotification";
|
||||
import type { ThreadStartedNotification } from "./v2/ThreadStartedNotification";
|
||||
import type { ThreadStatusChangedNotification } from "./v2/ThreadStatusChangedNotification";
|
||||
import type { ThreadTokenUsageUpdatedNotification } from "./v2/ThreadTokenUsageUpdatedNotification";
|
||||
@@ -44,4 +49,4 @@ import type { WindowsWorldWritableWarningNotification } from "./v2/WindowsWorldW
|
||||
/**
|
||||
* Notification sent from the server to the client.
|
||||
*/
|
||||
export type ServerNotification = { "method": "error", "params": ErrorNotification } | { "method": "thread/started", "params": ThreadStartedNotification } | { "method": "thread/status/changed", "params": ThreadStatusChangedNotification } | { "method": "thread/archived", "params": ThreadArchivedNotification } | { "method": "thread/unarchived", "params": ThreadUnarchivedNotification } | { "method": "thread/name/updated", "params": ThreadNameUpdatedNotification } | { "method": "thread/tokenUsage/updated", "params": ThreadTokenUsageUpdatedNotification } | { "method": "turn/started", "params": TurnStartedNotification } | { "method": "turn/completed", "params": TurnCompletedNotification } | { "method": "turn/diff/updated", "params": TurnDiffUpdatedNotification } | { "method": "turn/plan/updated", "params": TurnPlanUpdatedNotification } | { "method": "item/started", "params": ItemStartedNotification } | { "method": "item/completed", "params": ItemCompletedNotification } | { "method": "rawResponseItem/completed", "params": RawResponseItemCompletedNotification } | { "method": "item/agentMessage/delta", "params": AgentMessageDeltaNotification } | { "method": "item/plan/delta", "params": PlanDeltaNotification } | { "method": "item/commandExecution/outputDelta", "params": CommandExecutionOutputDeltaNotification } | { "method": "item/commandExecution/terminalInteraction", "params": TerminalInteractionNotification } | { "method": "item/fileChange/outputDelta", "params": FileChangeOutputDeltaNotification } | { "method": "item/mcpToolCall/progress", "params": McpToolCallProgressNotification } | { "method": "mcpServer/oauthLogin/completed", "params": McpServerOauthLoginCompletedNotification } | { "method": "account/updated", "params": AccountUpdatedNotification } | { "method": "account/rateLimits/updated", "params": AccountRateLimitsUpdatedNotification } | { "method": "app/list/updated", "params": AppListUpdatedNotification } | { "method": "item/reasoning/summaryTextDelta", "params": ReasoningSummaryTextDeltaNotification } | { "method": "item/reasoning/summaryPartAdded", "params": ReasoningSummaryPartAddedNotification } | { "method": "item/reasoning/textDelta", "params": ReasoningTextDeltaNotification } | { "method": "thread/compacted", "params": ContextCompactedNotification } | { "method": "model/rerouted", "params": ModelReroutedNotification } | { "method": "deprecationNotice", "params": DeprecationNoticeNotification } | { "method": "configWarning", "params": ConfigWarningNotification } | { "method": "fuzzyFileSearch/sessionUpdated", "params": FuzzyFileSearchSessionUpdatedNotification } | { "method": "fuzzyFileSearch/sessionCompleted", "params": FuzzyFileSearchSessionCompletedNotification } | { "method": "windows/worldWritableWarning", "params": WindowsWorldWritableWarningNotification } | { "method": "windowsSandbox/setupCompleted", "params": WindowsSandboxSetupCompletedNotification } | { "method": "account/login/completed", "params": AccountLoginCompletedNotification } | { "method": "authStatusChange", "params": AuthStatusChangeNotification } | { "method": "loginChatGptComplete", "params": LoginChatGptCompleteNotification } | { "method": "sessionConfigured", "params": SessionConfiguredNotification };
|
||||
export type ServerNotification = { "method": "error", "params": ErrorNotification } | { "method": "thread/started", "params": ThreadStartedNotification } | { "method": "thread/status/changed", "params": ThreadStatusChangedNotification } | { "method": "thread/archived", "params": ThreadArchivedNotification } | { "method": "thread/unarchived", "params": ThreadUnarchivedNotification } | { "method": "thread/name/updated", "params": ThreadNameUpdatedNotification } | { "method": "thread/tokenUsage/updated", "params": ThreadTokenUsageUpdatedNotification } | { "method": "turn/started", "params": TurnStartedNotification } | { "method": "turn/completed", "params": TurnCompletedNotification } | { "method": "turn/diff/updated", "params": TurnDiffUpdatedNotification } | { "method": "turn/plan/updated", "params": TurnPlanUpdatedNotification } | { "method": "item/started", "params": ItemStartedNotification } | { "method": "item/completed", "params": ItemCompletedNotification } | { "method": "rawResponseItem/completed", "params": RawResponseItemCompletedNotification } | { "method": "item/agentMessage/delta", "params": AgentMessageDeltaNotification } | { "method": "item/plan/delta", "params": PlanDeltaNotification } | { "method": "item/commandExecution/outputDelta", "params": CommandExecutionOutputDeltaNotification } | { "method": "item/commandExecution/terminalInteraction", "params": TerminalInteractionNotification } | { "method": "item/fileChange/outputDelta", "params": FileChangeOutputDeltaNotification } | { "method": "item/mcpToolCall/progress", "params": McpToolCallProgressNotification } | { "method": "mcpServer/oauthLogin/completed", "params": McpServerOauthLoginCompletedNotification } | { "method": "account/updated", "params": AccountUpdatedNotification } | { "method": "account/rateLimits/updated", "params": AccountRateLimitsUpdatedNotification } | { "method": "app/list/updated", "params": AppListUpdatedNotification } | { "method": "item/reasoning/summaryTextDelta", "params": ReasoningSummaryTextDeltaNotification } | { "method": "item/reasoning/summaryPartAdded", "params": ReasoningSummaryPartAddedNotification } | { "method": "item/reasoning/textDelta", "params": ReasoningTextDeltaNotification } | { "method": "thread/compacted", "params": ContextCompactedNotification } | { "method": "model/rerouted", "params": ModelReroutedNotification } | { "method": "deprecationNotice", "params": DeprecationNoticeNotification } | { "method": "configWarning", "params": ConfigWarningNotification } | { "method": "fuzzyFileSearch/sessionUpdated", "params": FuzzyFileSearchSessionUpdatedNotification } | { "method": "fuzzyFileSearch/sessionCompleted", "params": FuzzyFileSearchSessionCompletedNotification } | { "method": "thread/realtime/started", "params": ThreadRealtimeStartedNotification } | { "method": "thread/realtime/itemAdded", "params": ThreadRealtimeItemAddedNotification } | { "method": "thread/realtime/outputAudio/delta", "params": ThreadRealtimeOutputAudioDeltaNotification } | { "method": "thread/realtime/error", "params": ThreadRealtimeErrorNotification } | { "method": "thread/realtime/closed", "params": ThreadRealtimeClosedNotification } | { "method": "windows/worldWritableWarning", "params": WindowsWorldWritableWarningNotification } | { "method": "windowsSandbox/setupCompleted", "params": WindowsSandboxSetupCompletedNotification } | { "method": "account/login/completed", "params": AccountLoginCompletedNotification } | { "method": "authStatusChange", "params": AuthStatusChangeNotification } | { "method": "loginChatGptComplete", "params": LoginChatGptCompleteNotification } | { "method": "sessionConfigured", "params": SessionConfiguredNotification };
|
||||
|
||||
@@ -8,9 +8,10 @@ import type { ChatgptAuthTokensRefreshParams } from "./v2/ChatgptAuthTokensRefre
|
||||
import type { CommandExecutionRequestApprovalParams } from "./v2/CommandExecutionRequestApprovalParams";
|
||||
import type { DynamicToolCallParams } from "./v2/DynamicToolCallParams";
|
||||
import type { FileChangeRequestApprovalParams } from "./v2/FileChangeRequestApprovalParams";
|
||||
import type { SkillRequestApprovalParams } from "./v2/SkillRequestApprovalParams";
|
||||
import type { ToolRequestUserInputParams } from "./v2/ToolRequestUserInputParams";
|
||||
|
||||
/**
|
||||
* Request initiated from the server and sent to the client.
|
||||
*/
|
||||
export type ServerRequest = { "method": "item/commandExecution/requestApproval", id: RequestId, params: CommandExecutionRequestApprovalParams, } | { "method": "item/fileChange/requestApproval", id: RequestId, params: FileChangeRequestApprovalParams, } | { "method": "item/tool/requestUserInput", id: RequestId, params: ToolRequestUserInputParams, } | { "method": "item/tool/call", id: RequestId, params: DynamicToolCallParams, } | { "method": "account/chatgptAuthTokens/refresh", id: RequestId, params: ChatgptAuthTokensRefreshParams, } | { "method": "applyPatchApproval", id: RequestId, params: ApplyPatchApprovalParams, } | { "method": "execCommandApproval", id: RequestId, params: ExecCommandApprovalParams, };
|
||||
export type ServerRequest = { "method": "item/commandExecution/requestApproval", id: RequestId, params: CommandExecutionRequestApprovalParams, } | { "method": "item/fileChange/requestApproval", id: RequestId, params: FileChangeRequestApprovalParams, } | { "method": "item/tool/requestUserInput", id: RequestId, params: ToolRequestUserInputParams, } | { "method": "skill/requestApproval", id: RequestId, params: SkillRequestApprovalParams, } | { "method": "item/tool/call", id: RequestId, params: DynamicToolCallParams, } | { "method": "account/chatgptAuthTokens/refresh", id: RequestId, params: ChatgptAuthTokensRefreshParams, } | { "method": "applyPatchApproval", id: RequestId, params: ApplyPatchApprovalParams, } | { "method": "execCommandApproval", id: RequestId, params: ExecCommandApprovalParams, };
|
||||
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type SkillRequestApprovalEvent = { item_id: string, skill_name: string, };
|
||||
@@ -53,7 +53,9 @@ export type { ConversationSummary } from "./ConversationSummary";
|
||||
export type { CreditsSnapshot } from "./CreditsSnapshot";
|
||||
export type { CustomPrompt } from "./CustomPrompt";
|
||||
export type { DeprecationNoticeEvent } from "./DeprecationNoticeEvent";
|
||||
export type { DynamicToolCallOutputContentItem } from "./DynamicToolCallOutputContentItem";
|
||||
export type { DynamicToolCallRequest } from "./DynamicToolCallRequest";
|
||||
export type { DynamicToolCallResponseEvent } from "./DynamicToolCallResponseEvent";
|
||||
export type { ElicitationRequestEvent } from "./ElicitationRequestEvent";
|
||||
export type { ErrorEvent } from "./ErrorEvent";
|
||||
export type { EventMsg } from "./EventMsg";
|
||||
@@ -71,6 +73,7 @@ export type { ExecOutputStream } from "./ExecOutputStream";
|
||||
export type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
|
||||
export type { ExitedReviewModeEvent } from "./ExitedReviewModeEvent";
|
||||
export type { FileChange } from "./FileChange";
|
||||
export type { FileSystemPermissions } from "./FileSystemPermissions";
|
||||
export type { ForcedLoginMethod } from "./ForcedLoginMethod";
|
||||
export type { ForkConversationParams } from "./ForkConversationParams";
|
||||
export type { ForkConversationResponse } from "./ForkConversationResponse";
|
||||
@@ -116,6 +119,9 @@ export type { LoginApiKeyResponse } from "./LoginApiKeyResponse";
|
||||
export type { LoginChatGptCompleteNotification } from "./LoginChatGptCompleteNotification";
|
||||
export type { LoginChatGptResponse } from "./LoginChatGptResponse";
|
||||
export type { LogoutChatGptResponse } from "./LogoutChatGptResponse";
|
||||
export type { MacOsAutomationValue } from "./MacOsAutomationValue";
|
||||
export type { MacOsPermissions } from "./MacOsPermissions";
|
||||
export type { MacOsPreferencesValue } from "./MacOsPreferencesValue";
|
||||
export type { McpAuthStatus } from "./McpAuthStatus";
|
||||
export type { McpInvocation } from "./McpInvocation";
|
||||
export type { McpListToolsResponseEvent } from "./McpListToolsResponseEvent";
|
||||
@@ -132,12 +138,15 @@ export type { ModelRerouteReason } from "./ModelRerouteReason";
|
||||
export type { NetworkAccess } from "./NetworkAccess";
|
||||
export type { NetworkApprovalContext } from "./NetworkApprovalContext";
|
||||
export type { NetworkApprovalProtocol } from "./NetworkApprovalProtocol";
|
||||
export type { NetworkPolicyAmendment } from "./NetworkPolicyAmendment";
|
||||
export type { NetworkPolicyRuleAction } from "./NetworkPolicyRuleAction";
|
||||
export type { NewConversationParams } from "./NewConversationParams";
|
||||
export type { NewConversationResponse } from "./NewConversationResponse";
|
||||
export type { ParsedCommand } from "./ParsedCommand";
|
||||
export type { PatchApplyBeginEvent } from "./PatchApplyBeginEvent";
|
||||
export type { PatchApplyEndEvent } from "./PatchApplyEndEvent";
|
||||
export type { PatchApplyStatus } from "./PatchApplyStatus";
|
||||
export type { PermissionProfile } from "./PermissionProfile";
|
||||
export type { Personality } from "./Personality";
|
||||
export type { PlanDeltaEvent } from "./PlanDeltaEvent";
|
||||
export type { PlanItem } from "./PlanItem";
|
||||
@@ -201,6 +210,7 @@ export type { SkillDependencies } from "./SkillDependencies";
|
||||
export type { SkillErrorInfo } from "./SkillErrorInfo";
|
||||
export type { SkillInterface } from "./SkillInterface";
|
||||
export type { SkillMetadata } from "./SkillMetadata";
|
||||
export type { SkillRequestApprovalEvent } from "./SkillRequestApprovalEvent";
|
||||
export type { SkillScope } from "./SkillScope";
|
||||
export type { SkillToolDependency } from "./SkillToolDependency";
|
||||
export type { SkillsListEntry } from "./SkillsListEntry";
|
||||
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type AdditionalFileSystemPermissions = { read: Array<string> | null, write: Array<string> | null, };
|
||||
@@ -0,0 +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 { MacOsAutomationValue } from "../MacOsAutomationValue";
|
||||
import type { MacOsPreferencesValue } from "../MacOsPreferencesValue";
|
||||
|
||||
export type AdditionalMacOsPermissions = { preferences: MacOsPreferencesValue | null, automations: MacOsAutomationValue | null, accessibility: boolean | null, calendar: boolean | null, };
|
||||
@@ -0,0 +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 { AdditionalFileSystemPermissions } from "./AdditionalFileSystemPermissions";
|
||||
import type { AdditionalMacOsPermissions } from "./AdditionalMacOsPermissions";
|
||||
|
||||
export type AdditionalPermissionProfile = { network: boolean | null, fileSystem: AdditionalFileSystemPermissions | null, macos: AdditionalMacOsPermissions | null, };
|
||||
@@ -2,5 +2,6 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
|
||||
import type { NetworkPolicyAmendment } from "./NetworkPolicyAmendment";
|
||||
|
||||
export type CommandExecutionApprovalDecision = "accept" | "acceptForSession" | { "acceptWithExecpolicyAmendment": { execpolicy_amendment: ExecPolicyAmendment, } } | "decline" | "cancel";
|
||||
export type CommandExecutionApprovalDecision = "accept" | "acceptForSession" | { "acceptWithExecpolicyAmendment": { execpolicy_amendment: ExecPolicyAmendment, } } | { "applyNetworkPolicyAmendment": { network_policy_amendment: NetworkPolicyAmendment, } } | "decline" | "cancel";
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
// 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 { AdditionalPermissionProfile } from "./AdditionalPermissionProfile";
|
||||
import type { CommandAction } from "./CommandAction";
|
||||
import type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
|
||||
import type { NetworkApprovalContext } from "./NetworkApprovalContext";
|
||||
import type { NetworkPolicyAmendment } from "./NetworkPolicyAmendment";
|
||||
|
||||
export type CommandExecutionRequestApprovalParams = { threadId: string, turnId: string, itemId: string,
|
||||
/**
|
||||
@@ -21,7 +23,7 @@ approvalId?: string | null,
|
||||
*/
|
||||
reason?: string | null,
|
||||
/**
|
||||
* Optional context for managed-network approval prompts.
|
||||
* Optional context for a managed-network approval prompt.
|
||||
*/
|
||||
networkApprovalContext?: NetworkApprovalContext | null,
|
||||
/**
|
||||
@@ -36,7 +38,15 @@ cwd?: string | null,
|
||||
* Best-effort parsed command actions for friendly display.
|
||||
*/
|
||||
commandActions?: Array<CommandAction> | null,
|
||||
/**
|
||||
* Optional additional permissions requested for this command.
|
||||
*/
|
||||
additionalPermissions?: AdditionalPermissionProfile | null,
|
||||
/**
|
||||
* Optional proposed execpolicy amendment to allow similar commands without prompting.
|
||||
*/
|
||||
proposedExecpolicyAmendment?: ExecPolicyAmendment | null, };
|
||||
proposedExecpolicyAmendment?: ExecPolicyAmendment | null,
|
||||
/**
|
||||
* Optional proposed network policy amendments (allow/deny host) for future requests.
|
||||
*/
|
||||
proposedNetworkPolicyAmendments?: Array<NetworkPolicyAmendment> | null, };
|
||||
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type DynamicToolCallStatus = "inProgress" | "completed" | "failed";
|
||||
@@ -0,0 +1,13 @@
|
||||
// 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 ExternalAgentConfigDetectParams = {
|
||||
/**
|
||||
* If true, include detection under the user's home (~/.claude, ~/.codex, etc.).
|
||||
*/
|
||||
includeHome?: boolean,
|
||||
/**
|
||||
* Zero or more working directories to include for repo-scoped detection.
|
||||
*/
|
||||
cwds?: Array<string> | null, };
|
||||
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ExternalAgentConfigMigrationItem } from "./ExternalAgentConfigMigrationItem";
|
||||
|
||||
export type ExternalAgentConfigDetectResponse = { items: Array<ExternalAgentConfigMigrationItem>, };
|
||||
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { ExternalAgentConfigMigrationItem } from "./ExternalAgentConfigMigrationItem";
|
||||
|
||||
export type ExternalAgentConfigImportParams = { migrationItems: Array<ExternalAgentConfigMigrationItem>, };
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type ExternalAgentConfigImportResponse = Record<string, never>;
|
||||
@@ -0,0 +1,10 @@
|
||||
// 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 { ExternalAgentConfigMigrationItemType } from "./ExternalAgentConfigMigrationItemType";
|
||||
|
||||
export type ExternalAgentConfigMigrationItem = { itemType: ExternalAgentConfigMigrationItemType, description: string,
|
||||
/**
|
||||
* Null or empty means home-scoped migration; non-empty means repo-scoped migration.
|
||||
*/
|
||||
cwd: string | null, };
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type ExternalAgentConfigMigrationItemType = "AGENTS_MD" | "CONFIG" | "SKILLS" | "MCP_SERVER_CONFIG";
|
||||
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { NetworkPolicyRuleAction } from "./NetworkPolicyRuleAction";
|
||||
|
||||
export type NetworkPolicyAmendment = { host: string, action: NetworkPolicyRuleAction, };
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type NetworkPolicyRuleAction = "allow" | "deny";
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type SkillApprovalDecision = "approve" | "decline";
|
||||
@@ -0,0 +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.
|
||||
|
||||
export type SkillRequestApprovalParams = { itemId: string, skillName: string, };
|
||||
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { SkillApprovalDecision } from "./SkillApprovalDecision";
|
||||
|
||||
export type SkillRequestApprovalResponse = { decision: SkillApprovalDecision, };
|
||||
@@ -19,6 +19,15 @@ export type ThreadForkParams = {threadId: string, /**
|
||||
* If specified, the thread_id param will be ignored.
|
||||
*/
|
||||
path?: string | null, /**
|
||||
* [UNSTABLE] Fork after the specified historical turn (inclusive).
|
||||
* When omitted, the full thread history is copied.
|
||||
*
|
||||
* The value should come from `thread/read(includeTurns=true)` for the same source thread.
|
||||
* Requests are rejected for legacy histories whose replayed turn ids are not stable, for
|
||||
* in-progress turns, and for turns that do not yet contain both a user message and an agent
|
||||
* response.
|
||||
*/
|
||||
forkAfterTurnId?: 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, /**
|
||||
|
||||
@@ -8,6 +8,8 @@ import type { CollabAgentTool } from "./CollabAgentTool";
|
||||
import type { CollabAgentToolCallStatus } from "./CollabAgentToolCallStatus";
|
||||
import type { CommandAction } from "./CommandAction";
|
||||
import type { CommandExecutionStatus } from "./CommandExecutionStatus";
|
||||
import type { DynamicToolCallOutputContentItem } from "./DynamicToolCallOutputContentItem";
|
||||
import type { DynamicToolCallStatus } from "./DynamicToolCallStatus";
|
||||
import type { FileUpdateChange } from "./FileUpdateChange";
|
||||
import type { McpToolCallError } from "./McpToolCallError";
|
||||
import type { McpToolCallResult } from "./McpToolCallResult";
|
||||
@@ -50,6 +52,10 @@ durationMs: number | null, } | { "type": "fileChange", id: string, changes: Arra
|
||||
/**
|
||||
* The duration of the MCP tool call in milliseconds.
|
||||
*/
|
||||
durationMs: number | null, } | { "type": "dynamicToolCall", id: string, tool: string, arguments: JsonValue, status: DynamicToolCallStatus, contentItems: Array<DynamicToolCallOutputContentItem> | null, success: boolean | null,
|
||||
/**
|
||||
* The duration of the dynamic tool call in milliseconds.
|
||||
*/
|
||||
durationMs: number | null, } | { "type": "collabAgentToolCall",
|
||||
/**
|
||||
* Unique identifier for this collab tool call.
|
||||
|
||||
@@ -36,4 +36,8 @@ archived?: boolean | null,
|
||||
* Optional cwd filter; when set, only threads whose session cwd exactly
|
||||
* matches this path are returned.
|
||||
*/
|
||||
cwd?: string | null, };
|
||||
cwd?: string | null,
|
||||
/**
|
||||
* Optional substring filter for the extracted thread title.
|
||||
*/
|
||||
searchTerm?: string | null, };
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// 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.
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - thread realtime audio chunk.
|
||||
*/
|
||||
export type ThreadRealtimeAudioChunk = { data: string, sampleRate: number, numChannels: number, samplesPerChannel: number | null, };
|
||||
@@ -0,0 +1,8 @@
|
||||
// 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.
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - emitted when thread realtime transport closes.
|
||||
*/
|
||||
export type ThreadRealtimeClosedNotification = { threadId: string, reason: string | null, };
|
||||
@@ -0,0 +1,8 @@
|
||||
// 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.
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - emitted when thread realtime encounters an error.
|
||||
*/
|
||||
export type ThreadRealtimeErrorNotification = { threadId: string, message: string, };
|
||||
@@ -0,0 +1,9 @@
|
||||
// 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 { JsonValue } from "../serde_json/JsonValue";
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - raw non-audio thread realtime item emitted by the backend.
|
||||
*/
|
||||
export type ThreadRealtimeItemAddedNotification = { threadId: string, item: JsonValue, };
|
||||
@@ -0,0 +1,9 @@
|
||||
// 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 { ThreadRealtimeAudioChunk } from "./ThreadRealtimeAudioChunk";
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - streamed output audio emitted by thread realtime.
|
||||
*/
|
||||
export type ThreadRealtimeOutputAudioDeltaNotification = { threadId: string, audio: ThreadRealtimeAudioChunk, };
|
||||
@@ -0,0 +1,8 @@
|
||||
// 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.
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - emitted when thread realtime startup is accepted.
|
||||
*/
|
||||
export type ThreadRealtimeStartedNotification = { threadId: string, sessionId: string | null, };
|
||||
@@ -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, serviceName?: string | null, baseInstructions?: string | null, developerInstructions?: string | null, personality?: Personality | null, ephemeral?: boolean | null, /**
|
||||
* If true, opt into emitting raw Responses API items on the event stream.
|
||||
* This is for internal use only (e.g. Codex Cloud).
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,9 @@ export type { Account } from "./Account";
|
||||
export type { AccountLoginCompletedNotification } from "./AccountLoginCompletedNotification";
|
||||
export type { AccountRateLimitsUpdatedNotification } from "./AccountRateLimitsUpdatedNotification";
|
||||
export type { AccountUpdatedNotification } from "./AccountUpdatedNotification";
|
||||
export type { AdditionalFileSystemPermissions } from "./AdditionalFileSystemPermissions";
|
||||
export type { AdditionalMacOsPermissions } from "./AdditionalMacOsPermissions";
|
||||
export type { AdditionalPermissionProfile } from "./AdditionalPermissionProfile";
|
||||
export type { AgentMessageDeltaNotification } from "./AgentMessageDeltaNotification";
|
||||
export type { AnalyticsConfig } from "./AnalyticsConfig";
|
||||
export type { AppBranding } from "./AppBranding";
|
||||
@@ -58,6 +61,7 @@ export type { DeprecationNoticeNotification } from "./DeprecationNoticeNotificat
|
||||
export type { DynamicToolCallOutputContentItem } from "./DynamicToolCallOutputContentItem";
|
||||
export type { DynamicToolCallParams } from "./DynamicToolCallParams";
|
||||
export type { DynamicToolCallResponse } from "./DynamicToolCallResponse";
|
||||
export type { DynamicToolCallStatus } from "./DynamicToolCallStatus";
|
||||
export type { DynamicToolSpec } from "./DynamicToolSpec";
|
||||
export type { ErrorNotification } from "./ErrorNotification";
|
||||
export type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
|
||||
@@ -65,6 +69,12 @@ export type { ExperimentalFeature } from "./ExperimentalFeature";
|
||||
export type { ExperimentalFeatureListParams } from "./ExperimentalFeatureListParams";
|
||||
export type { ExperimentalFeatureListResponse } from "./ExperimentalFeatureListResponse";
|
||||
export type { ExperimentalFeatureStage } from "./ExperimentalFeatureStage";
|
||||
export type { ExternalAgentConfigDetectParams } from "./ExternalAgentConfigDetectParams";
|
||||
export type { ExternalAgentConfigDetectResponse } from "./ExternalAgentConfigDetectResponse";
|
||||
export type { ExternalAgentConfigImportParams } from "./ExternalAgentConfigImportParams";
|
||||
export type { ExternalAgentConfigImportResponse } from "./ExternalAgentConfigImportResponse";
|
||||
export type { ExternalAgentConfigMigrationItem } from "./ExternalAgentConfigMigrationItem";
|
||||
export type { ExternalAgentConfigMigrationItemType } from "./ExternalAgentConfigMigrationItemType";
|
||||
export type { FeedbackUploadParams } from "./FeedbackUploadParams";
|
||||
export type { FeedbackUploadResponse } from "./FeedbackUploadResponse";
|
||||
export type { FileChangeApprovalDecision } from "./FileChangeApprovalDecision";
|
||||
@@ -103,6 +113,8 @@ export type { ModelReroutedNotification } from "./ModelReroutedNotification";
|
||||
export type { NetworkAccess } from "./NetworkAccess";
|
||||
export type { NetworkApprovalContext } from "./NetworkApprovalContext";
|
||||
export type { NetworkApprovalProtocol } from "./NetworkApprovalProtocol";
|
||||
export type { NetworkPolicyAmendment } from "./NetworkPolicyAmendment";
|
||||
export type { NetworkPolicyRuleAction } from "./NetworkPolicyRuleAction";
|
||||
export type { NetworkRequirements } from "./NetworkRequirements";
|
||||
export type { OverriddenMetadata } from "./OverriddenMetadata";
|
||||
export type { PatchApplyStatus } from "./PatchApplyStatus";
|
||||
@@ -128,10 +140,13 @@ export type { SandboxMode } from "./SandboxMode";
|
||||
export type { SandboxPolicy } from "./SandboxPolicy";
|
||||
export type { SandboxWorkspaceWrite } from "./SandboxWorkspaceWrite";
|
||||
export type { SessionSource } from "./SessionSource";
|
||||
export type { SkillApprovalDecision } from "./SkillApprovalDecision";
|
||||
export type { SkillDependencies } from "./SkillDependencies";
|
||||
export type { SkillErrorInfo } from "./SkillErrorInfo";
|
||||
export type { SkillInterface } from "./SkillInterface";
|
||||
export type { SkillMetadata } from "./SkillMetadata";
|
||||
export type { SkillRequestApprovalParams } from "./SkillRequestApprovalParams";
|
||||
export type { SkillRequestApprovalResponse } from "./SkillRequestApprovalResponse";
|
||||
export type { SkillScope } from "./SkillScope";
|
||||
export type { SkillToolDependency } from "./SkillToolDependency";
|
||||
export type { SkillsConfigWriteParams } from "./SkillsConfigWriteParams";
|
||||
@@ -165,6 +180,12 @@ export type { ThreadLoadedListResponse } from "./ThreadLoadedListResponse";
|
||||
export type { ThreadNameUpdatedNotification } from "./ThreadNameUpdatedNotification";
|
||||
export type { ThreadReadParams } from "./ThreadReadParams";
|
||||
export type { ThreadReadResponse } from "./ThreadReadResponse";
|
||||
export type { ThreadRealtimeAudioChunk } from "./ThreadRealtimeAudioChunk";
|
||||
export type { ThreadRealtimeClosedNotification } from "./ThreadRealtimeClosedNotification";
|
||||
export type { ThreadRealtimeErrorNotification } from "./ThreadRealtimeErrorNotification";
|
||||
export type { ThreadRealtimeItemAddedNotification } from "./ThreadRealtimeItemAddedNotification";
|
||||
export type { ThreadRealtimeOutputAudioDeltaNotification } from "./ThreadRealtimeOutputAudioDeltaNotification";
|
||||
export type { ThreadRealtimeStartedNotification } from "./ThreadRealtimeStartedNotification";
|
||||
export type { ThreadResumeParams } from "./ThreadResumeParams";
|
||||
export type { ThreadResumeResponse } from "./ThreadResumeResponse";
|
||||
export type { ThreadRollbackParams } from "./ThreadRollbackParams";
|
||||
|
||||
@@ -1947,6 +1947,15 @@ mod tests {
|
||||
let thread_start_ts =
|
||||
fs::read_to_string(output_dir.join("v2").join("ThreadStartParams.ts"))?;
|
||||
assert_eq!(thread_start_ts.contains("mockExperimentalField"), true);
|
||||
let command_execution_request_approval_ts = fs::read_to_string(
|
||||
output_dir
|
||||
.join("v2")
|
||||
.join("CommandExecutionRequestApprovalParams.ts"),
|
||||
)?;
|
||||
assert_eq!(
|
||||
command_execution_request_approval_ts.contains("additionalPermissions"),
|
||||
true
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -2083,6 +2092,12 @@ export type Config = { stableField: Keep, unstableField: string | null } & ({ [k
|
||||
let thread_start_json =
|
||||
fs::read_to_string(output_dir.join("v2").join("ThreadStartParams.json"))?;
|
||||
assert_eq!(thread_start_json.contains("mockExperimentalField"), false);
|
||||
let command_execution_request_approval_json =
|
||||
fs::read_to_string(output_dir.join("CommandExecutionRequestApprovalParams.json"))?;
|
||||
assert_eq!(
|
||||
command_execution_request_approval_json.contains("additionalPermissions"),
|
||||
false
|
||||
);
|
||||
|
||||
let client_request_json = fs::read_to_string(output_dir.join("ClientRequest.json"))?;
|
||||
assert_eq!(
|
||||
@@ -2093,6 +2108,7 @@ export type Config = { stableField: Keep, unstableField: string | null } & ({ [k
|
||||
let bundle_json =
|
||||
fs::read_to_string(output_dir.join("codex_app_server_protocol.schemas.json"))?;
|
||||
assert_eq!(bundle_json.contains("mockExperimentalField"), false);
|
||||
assert_eq!(bundle_json.contains("additionalPermissions"), false);
|
||||
assert_eq!(bundle_json.contains("MockExperimentalMethodParams"), false);
|
||||
assert_eq!(
|
||||
bundle_json.contains("MockExperimentalMethodResponse"),
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::export::GeneratedSchema;
|
||||
use crate::export::write_json_schema;
|
||||
use crate::protocol::v1;
|
||||
use crate::protocol::v2;
|
||||
use codex_experimental_api_macros::ExperimentalApi;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
@@ -268,6 +269,26 @@ client_request_definitions! {
|
||||
params: v2::TurnInterruptParams,
|
||||
response: v2::TurnInterruptResponse,
|
||||
},
|
||||
#[experimental("thread/realtime/start")]
|
||||
ThreadRealtimeStart => "thread/realtime/start" {
|
||||
params: v2::ThreadRealtimeStartParams,
|
||||
response: v2::ThreadRealtimeStartResponse,
|
||||
},
|
||||
#[experimental("thread/realtime/appendAudio")]
|
||||
ThreadRealtimeAppendAudio => "thread/realtime/appendAudio" {
|
||||
params: v2::ThreadRealtimeAppendAudioParams,
|
||||
response: v2::ThreadRealtimeAppendAudioResponse,
|
||||
},
|
||||
#[experimental("thread/realtime/appendText")]
|
||||
ThreadRealtimeAppendText => "thread/realtime/appendText" {
|
||||
params: v2::ThreadRealtimeAppendTextParams,
|
||||
response: v2::ThreadRealtimeAppendTextResponse,
|
||||
},
|
||||
#[experimental("thread/realtime/stop")]
|
||||
ThreadRealtimeStop => "thread/realtime/stop" {
|
||||
params: v2::ThreadRealtimeStopParams,
|
||||
response: v2::ThreadRealtimeStopResponse,
|
||||
},
|
||||
ReviewStart => "review/start" {
|
||||
params: v2::ReviewStartParams,
|
||||
response: v2::ReviewStartResponse,
|
||||
@@ -350,6 +371,14 @@ client_request_definitions! {
|
||||
params: v2::ConfigReadParams,
|
||||
response: v2::ConfigReadResponse,
|
||||
},
|
||||
ExternalAgentConfigDetect => "externalAgentConfig/detect" {
|
||||
params: v2::ExternalAgentConfigDetectParams,
|
||||
response: v2::ExternalAgentConfigDetectResponse,
|
||||
},
|
||||
ExternalAgentConfigImport => "externalAgentConfig/import" {
|
||||
params: v2::ExternalAgentConfigImportParams,
|
||||
response: v2::ExternalAgentConfigImportResponse,
|
||||
},
|
||||
ConfigValueWrite => "config/value/write" {
|
||||
params: v2::ConfigValueWriteParams,
|
||||
response: v2::ConfigWriteResponse,
|
||||
@@ -501,6 +530,7 @@ macro_rules! server_request_definitions {
|
||||
) => {
|
||||
/// Request initiated from the server and sent to the client.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[serde(tag = "method", rename_all = "camelCase")]
|
||||
pub enum ServerRequest {
|
||||
$(
|
||||
@@ -515,6 +545,7 @@ macro_rules! server_request_definitions {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, JsonSchema)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
pub enum ServerRequestPayload {
|
||||
$( $variant($params), )*
|
||||
}
|
||||
@@ -576,7 +607,16 @@ macro_rules! server_notification_definitions {
|
||||
),* $(,)?
|
||||
) => {
|
||||
/// Notification sent from the server to the client.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, TS, Display)]
|
||||
#[derive(
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Debug,
|
||||
Clone,
|
||||
JsonSchema,
|
||||
TS,
|
||||
Display,
|
||||
ExperimentalApi,
|
||||
)]
|
||||
#[serde(tag = "method", content = "params", rename_all = "camelCase")]
|
||||
#[strum(serialize_all = "camelCase")]
|
||||
pub enum ServerNotification {
|
||||
@@ -671,6 +711,11 @@ server_request_definitions! {
|
||||
response: v2::ToolRequestUserInputResponse,
|
||||
},
|
||||
|
||||
SkillRequestApproval => "skill/requestApproval" {
|
||||
params: v2::SkillRequestApprovalParams,
|
||||
response: v2::SkillRequestApprovalResponse,
|
||||
},
|
||||
|
||||
/// Execute a dynamic tool call on the client.
|
||||
DynamicToolCall => "item/tool/call" {
|
||||
params: v2::DynamicToolCallParams,
|
||||
@@ -808,6 +853,16 @@ server_notification_definitions! {
|
||||
ConfigWarning => "configWarning" (v2::ConfigWarningNotification),
|
||||
FuzzyFileSearchSessionUpdated => "fuzzyFileSearch/sessionUpdated" (FuzzyFileSearchSessionUpdatedNotification),
|
||||
FuzzyFileSearchSessionCompleted => "fuzzyFileSearch/sessionCompleted" (FuzzyFileSearchSessionCompletedNotification),
|
||||
#[experimental("thread/realtime/started")]
|
||||
ThreadRealtimeStarted => "thread/realtime/started" (v2::ThreadRealtimeStartedNotification),
|
||||
#[experimental("thread/realtime/itemAdded")]
|
||||
ThreadRealtimeItemAdded => "thread/realtime/itemAdded" (v2::ThreadRealtimeItemAddedNotification),
|
||||
#[experimental("thread/realtime/outputAudio/delta")]
|
||||
ThreadRealtimeOutputAudioDelta => "thread/realtime/outputAudio/delta" (v2::ThreadRealtimeOutputAudioDeltaNotification),
|
||||
#[experimental("thread/realtime/error")]
|
||||
ThreadRealtimeError => "thread/realtime/error" (v2::ThreadRealtimeErrorNotification),
|
||||
#[experimental("thread/realtime/closed")]
|
||||
ThreadRealtimeClosed => "thread/realtime/closed" (v2::ThreadRealtimeClosedNotification),
|
||||
|
||||
/// Notifies the user of world-writable directories on Windows, which cannot be protected by the sandbox.
|
||||
WindowsWorldWritableWarning => "windows/worldWritableWarning" (v2::WindowsWorldWritableWarningNotification),
|
||||
@@ -1335,6 +1390,31 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_thread_realtime_start() -> Result<()> {
|
||||
let request = ClientRequest::ThreadRealtimeStart {
|
||||
request_id: RequestId::Integer(9),
|
||||
params: v2::ThreadRealtimeStartParams {
|
||||
thread_id: "thr_123".to_string(),
|
||||
prompt: "You are on a call".to_string(),
|
||||
session_id: Some("sess_456".to_string()),
|
||||
},
|
||||
};
|
||||
assert_eq!(
|
||||
json!({
|
||||
"method": "thread/realtime/start",
|
||||
"id": 9,
|
||||
"params": {
|
||||
"threadId": "thr_123",
|
||||
"prompt": "You are on a call",
|
||||
"sessionId": "sess_456"
|
||||
}
|
||||
}),
|
||||
serde_json::to_value(&request)?,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_thread_status_changed_notification() -> Result<()> {
|
||||
let notification =
|
||||
@@ -1357,6 +1437,37 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialize_thread_realtime_output_audio_delta_notification() -> Result<()> {
|
||||
let notification = ServerNotification::ThreadRealtimeOutputAudioDelta(
|
||||
v2::ThreadRealtimeOutputAudioDeltaNotification {
|
||||
thread_id: "thr_123".to_string(),
|
||||
audio: v2::ThreadRealtimeAudioChunk {
|
||||
data: "AQID".to_string(),
|
||||
sample_rate: 24_000,
|
||||
num_channels: 1,
|
||||
samples_per_channel: Some(512),
|
||||
},
|
||||
},
|
||||
);
|
||||
assert_eq!(
|
||||
json!({
|
||||
"method": "thread/realtime/outputAudio/delta",
|
||||
"params": {
|
||||
"threadId": "thr_123",
|
||||
"audio": {
|
||||
"data": "AQID",
|
||||
"sampleRate": 24000,
|
||||
"numChannels": 1,
|
||||
"samplesPerChannel": 512
|
||||
}
|
||||
}
|
||||
}),
|
||||
serde_json::to_value(¬ification)?,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mock_experimental_method_is_marked_experimental() {
|
||||
let request = ClientRequest::MockExperimentalMethod {
|
||||
@@ -1366,4 +1477,74 @@ mod tests {
|
||||
let reason = crate::experimental_api::ExperimentalApi::experimental_reason(&request);
|
||||
assert_eq!(reason, Some("mock/experimentalMethod"));
|
||||
}
|
||||
#[test]
|
||||
fn thread_realtime_start_is_marked_experimental() {
|
||||
let request = ClientRequest::ThreadRealtimeStart {
|
||||
request_id: RequestId::Integer(1),
|
||||
params: v2::ThreadRealtimeStartParams {
|
||||
thread_id: "thr_123".to_string(),
|
||||
prompt: "You are on a call".to_string(),
|
||||
session_id: None,
|
||||
},
|
||||
};
|
||||
let reason = crate::experimental_api::ExperimentalApi::experimental_reason(&request);
|
||||
assert_eq!(reason, Some("thread/realtime/start"));
|
||||
}
|
||||
#[test]
|
||||
fn thread_realtime_started_notification_is_marked_experimental() {
|
||||
let notification =
|
||||
ServerNotification::ThreadRealtimeStarted(v2::ThreadRealtimeStartedNotification {
|
||||
thread_id: "thr_123".to_string(),
|
||||
session_id: Some("sess_456".to_string()),
|
||||
});
|
||||
let reason = crate::experimental_api::ExperimentalApi::experimental_reason(¬ification);
|
||||
assert_eq!(reason, Some("thread/realtime/started"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn thread_realtime_output_audio_delta_notification_is_marked_experimental() {
|
||||
let notification = ServerNotification::ThreadRealtimeOutputAudioDelta(
|
||||
v2::ThreadRealtimeOutputAudioDeltaNotification {
|
||||
thread_id: "thr_123".to_string(),
|
||||
audio: v2::ThreadRealtimeAudioChunk {
|
||||
data: "AQID".to_string(),
|
||||
sample_rate: 24_000,
|
||||
num_channels: 1,
|
||||
samples_per_channel: Some(512),
|
||||
},
|
||||
},
|
||||
);
|
||||
let reason = crate::experimental_api::ExperimentalApi::experimental_reason(¬ification);
|
||||
assert_eq!(reason, Some("thread/realtime/outputAudio/delta"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn command_execution_request_approval_additional_permissions_is_marked_experimental() {
|
||||
let params = v2::CommandExecutionRequestApprovalParams {
|
||||
thread_id: "thr_123".to_string(),
|
||||
turn_id: "turn_123".to_string(),
|
||||
item_id: "call_123".to_string(),
|
||||
approval_id: None,
|
||||
reason: None,
|
||||
network_approval_context: None,
|
||||
command: Some("cat file".to_string()),
|
||||
cwd: None,
|
||||
command_actions: None,
|
||||
additional_permissions: Some(v2::AdditionalPermissionProfile {
|
||||
network: None,
|
||||
file_system: Some(v2::AdditionalFileSystemPermissions {
|
||||
read: Some(vec![std::path::PathBuf::from("/tmp/allowed")]),
|
||||
write: None,
|
||||
}),
|
||||
macos: None,
|
||||
}),
|
||||
proposed_execpolicy_amendment: None,
|
||||
proposed_network_policy_amendments: None,
|
||||
};
|
||||
let reason = crate::experimental_api::ExperimentalApi::experimental_reason(¶ms);
|
||||
assert_eq!(
|
||||
reason,
|
||||
Some("item/commandExecution/requestApproval.additionalPermissions")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
//! Reconstruct app-server turn history from persisted rollout items.
|
||||
//!
|
||||
//! This module translates the low-level rollout log into the higher-level `Turn` / `ThreadItem`
|
||||
//! structures returned by app-server APIs. The same reducer is used both for replaying stored
|
||||
//! rollouts and for incrementally rebuilding the current turn from live `EventMsg` values.
|
||||
//! Callers must feed items in recorded order; reordering lifecycle events can silently attach work
|
||||
//! to the wrong turn while still producing a superficially valid transcript.
|
||||
//!
|
||||
//! Modern rollouts persist explicit turn lifecycle events, which means replay can preserve stable
|
||||
//! turn ids. Legacy rollouts may only contain message/tool events, so replay has to synthesize
|
||||
//! turn ids while rebuilding them. Consumers that need durable turn anchors, such as turn-based
|
||||
//! `thread/fork`, should reject those synthesized ids rather than treating them as stable.
|
||||
|
||||
use crate::protocol::v2::CollabAgentState;
|
||||
use crate::protocol::v2::CollabAgentTool;
|
||||
use crate::protocol::v2::CollabAgentToolCallStatus;
|
||||
use crate::protocol::v2::CommandAction;
|
||||
use crate::protocol::v2::CommandExecutionStatus;
|
||||
use crate::protocol::v2::DynamicToolCallOutputContentItem;
|
||||
use crate::protocol::v2::DynamicToolCallStatus;
|
||||
use crate::protocol::v2::FileUpdateChange;
|
||||
use crate::protocol::v2::McpToolCallError;
|
||||
use crate::protocol::v2::McpToolCallResult;
|
||||
@@ -22,6 +37,7 @@ use codex_protocol::protocol::AgentReasoningRawContentEvent;
|
||||
use codex_protocol::protocol::AgentStatus;
|
||||
use codex_protocol::protocol::CompactedItem;
|
||||
use codex_protocol::protocol::ContextCompactedEvent;
|
||||
use codex_protocol::protocol::DynamicToolCallResponseEvent;
|
||||
use codex_protocol::protocol::ErrorEvent;
|
||||
use codex_protocol::protocol::EventMsg;
|
||||
use codex_protocol::protocol::ExecCommandBeginEvent;
|
||||
@@ -54,7 +70,10 @@ use codex_protocol::protocol::PatchApplyStatus as CorePatchApplyStatus;
|
||||
/// Convert persisted [`RolloutItem`] entries into a sequence of [`Turn`] values.
|
||||
///
|
||||
/// When available, this uses `TurnContext.turn_id` as the canonical turn id so
|
||||
/// resumed/rebuilt thread history preserves the original turn identifiers.
|
||||
/// resumed/rebuilt thread history preserves the original turn identifiers. Callers that also need
|
||||
/// to distinguish between stable and replay-synthesized turn ids should drive
|
||||
/// [`ThreadHistoryBuilder`] directly and inspect [`ThreadHistoryBuilder::has_synthetic_turn_ids`]
|
||||
/// before consuming the final turn list.
|
||||
pub fn build_turns_from_rollout_items(items: &[RolloutItem]) -> Vec<Turn> {
|
||||
let mut builder = ThreadHistoryBuilder::new();
|
||||
for item in items {
|
||||
@@ -63,10 +82,19 @@ pub fn build_turns_from_rollout_items(items: &[RolloutItem]) -> Vec<Turn> {
|
||||
builder.finish()
|
||||
}
|
||||
|
||||
/// Stateful reducer that groups rollout lifecycle items into app-server turns.
|
||||
///
|
||||
/// The builder owns the in-progress turn boundary while replay is in flight, then emits the
|
||||
/// finalized `Turn` list once all items have been applied. It also tracks whether replay had to
|
||||
/// synthesize any turn ids so app-server can share the same reduction rules for stored history
|
||||
/// and live notifications without exposing that metadata in every convenience return type.
|
||||
/// Reusing a builder across unrelated transcripts without calling [`Self::reset`] can leak late
|
||||
/// events from one transcript into the next.
|
||||
pub struct ThreadHistoryBuilder {
|
||||
turns: Vec<Turn>,
|
||||
current_turn: Option<PendingTurn>,
|
||||
next_item_index: i64,
|
||||
has_synthetic_turn_ids: bool,
|
||||
}
|
||||
|
||||
impl Default for ThreadHistoryBuilder {
|
||||
@@ -76,23 +104,47 @@ impl Default for ThreadHistoryBuilder {
|
||||
}
|
||||
|
||||
impl ThreadHistoryBuilder {
|
||||
/// Create an empty reducer with no active turn.
|
||||
///
|
||||
/// The builder expects to receive the rollout from the beginning of a transcript, in order.
|
||||
/// Starting midway through a rollout can still produce `Turn` values, but turn boundaries and
|
||||
/// synthetic-id detection may no longer describe the actual persisted history.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
turns: Vec::new(),
|
||||
current_turn: None,
|
||||
next_item_index: 1,
|
||||
has_synthetic_turn_ids: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear all accumulated turns and return the builder to its initial state.
|
||||
pub fn reset(&mut self) {
|
||||
*self = Self::new();
|
||||
}
|
||||
|
||||
pub fn finish(mut self) -> Vec<Turn> {
|
||||
self.finish_current_turn();
|
||||
self.turns
|
||||
/// Finalize replay and return only the reconstructed turns.
|
||||
pub fn finish(self) -> Vec<Turn> {
|
||||
let mut this = self;
|
||||
this.finish_current_turn();
|
||||
this.turns
|
||||
}
|
||||
|
||||
/// Return whether replay had to synthesize any turn ids so far.
|
||||
///
|
||||
/// This becomes true when replay encounters legacy history without explicit turn lifecycle
|
||||
/// events and must mint replacement ids while rebuilding turns. Callers that want to use turn
|
||||
/// ids as stable anchors should check this before trusting replayed ids.
|
||||
pub fn has_synthetic_turn_ids(&self) -> bool {
|
||||
self.has_synthetic_turn_ids
|
||||
}
|
||||
|
||||
/// Return the current turn view without consuming the builder.
|
||||
///
|
||||
/// When a turn is actively streaming, this returns that in-progress turn. Otherwise it falls
|
||||
/// back to the most recently completed turn. This is useful for live UI updates, but a caller
|
||||
/// that treats the result as committed persisted history can accidentally display incomplete
|
||||
/// state after a partially applied event stream.
|
||||
pub fn active_turn_snapshot(&self) -> Option<Turn> {
|
||||
self.current_turn
|
||||
.as_ref()
|
||||
@@ -100,6 +152,7 @@ impl ThreadHistoryBuilder {
|
||||
.or_else(|| self.turns.last().cloned())
|
||||
}
|
||||
|
||||
/// Return whether replay is currently inside an unfinished turn boundary.
|
||||
pub fn has_active_turn(&self) -> bool {
|
||||
self.current_turn.is_some()
|
||||
}
|
||||
@@ -125,6 +178,12 @@ impl ThreadHistoryBuilder {
|
||||
EventMsg::ExecCommandEnd(payload) => self.handle_exec_command_end(payload),
|
||||
EventMsg::PatchApplyBegin(payload) => self.handle_patch_apply_begin(payload),
|
||||
EventMsg::PatchApplyEnd(payload) => self.handle_patch_apply_end(payload),
|
||||
EventMsg::DynamicToolCallRequest(payload) => {
|
||||
self.handle_dynamic_tool_call_request(payload)
|
||||
}
|
||||
EventMsg::DynamicToolCallResponse(payload) => {
|
||||
self.handle_dynamic_tool_call_response(payload)
|
||||
}
|
||||
EventMsg::McpToolCallBegin(payload) => self.handle_mcp_tool_call_begin(payload),
|
||||
EventMsg::McpToolCallEnd(payload) => self.handle_mcp_tool_call_end(payload),
|
||||
EventMsg::ViewImageToolCall(payload) => self.handle_view_image_tool_call(payload),
|
||||
@@ -160,6 +219,12 @@ impl ThreadHistoryBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply one persisted rollout line to the reducer.
|
||||
///
|
||||
/// Unlike [`Self::handle_event`], this accepts the outer `RolloutItem` wrapper so replay can
|
||||
/// preserve rollback markers and explicit turn boundaries exactly as they were recorded on
|
||||
/// disk. Feed items in file order; replaying a suffix or shuffling lines can still produce
|
||||
/// syntactically valid turns while silently attaching items to the wrong exchange.
|
||||
pub fn handle_rollout_item(&mut self, item: &RolloutItem) {
|
||||
match item {
|
||||
RolloutItem::EventMsg(event) => self.handle_event(event),
|
||||
@@ -382,6 +447,49 @@ impl ThreadHistoryBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_dynamic_tool_call_request(
|
||||
&mut self,
|
||||
payload: &codex_protocol::dynamic_tools::DynamicToolCallRequest,
|
||||
) {
|
||||
let item = ThreadItem::DynamicToolCall {
|
||||
id: payload.call_id.clone(),
|
||||
tool: payload.tool.clone(),
|
||||
arguments: payload.arguments.clone(),
|
||||
status: DynamicToolCallStatus::InProgress,
|
||||
content_items: None,
|
||||
success: None,
|
||||
duration_ms: None,
|
||||
};
|
||||
if payload.turn_id.is_empty() {
|
||||
self.upsert_item_in_current_turn(item);
|
||||
} else {
|
||||
self.upsert_item_in_turn_id(&payload.turn_id, item);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_dynamic_tool_call_response(&mut self, payload: &DynamicToolCallResponseEvent) {
|
||||
let status = if payload.success {
|
||||
DynamicToolCallStatus::Completed
|
||||
} else {
|
||||
DynamicToolCallStatus::Failed
|
||||
};
|
||||
let duration_ms = i64::try_from(payload.duration.as_millis()).ok();
|
||||
let item = ThreadItem::DynamicToolCall {
|
||||
id: payload.call_id.clone(),
|
||||
tool: payload.tool.clone(),
|
||||
arguments: payload.arguments.clone(),
|
||||
status,
|
||||
content_items: Some(convert_dynamic_tool_content_items(&payload.content_items)),
|
||||
success: Some(payload.success),
|
||||
duration_ms,
|
||||
};
|
||||
if payload.turn_id.is_empty() {
|
||||
self.upsert_item_in_current_turn(item);
|
||||
} else {
|
||||
self.upsert_item_in_turn_id(&payload.turn_id, item);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_mcp_tool_call_begin(&mut self, payload: &McpToolCallBeginEvent) {
|
||||
let item = ThreadItem::McpToolCall {
|
||||
id: payload.call_id.clone(),
|
||||
@@ -809,8 +917,15 @@ impl ThreadHistoryBuilder {
|
||||
}
|
||||
|
||||
fn new_turn(&mut self, id: Option<String>) -> PendingTurn {
|
||||
let id = match id {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
self.has_synthetic_turn_ids = true;
|
||||
Uuid::now_v7().to_string()
|
||||
}
|
||||
};
|
||||
PendingTurn {
|
||||
id: id.unwrap_or_else(|| Uuid::now_v7().to_string()),
|
||||
id,
|
||||
items: Vec::new(),
|
||||
error: None,
|
||||
status: TurnStatus::Completed,
|
||||
@@ -898,6 +1013,10 @@ fn render_review_output_text(output: &ReviewOutputEvent) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert core patch-apply change records into the app-server wire format.
|
||||
///
|
||||
/// The returned list is sorted by path so repeated replays of the same patch event stay stable for
|
||||
/// clients and snapshot tests.
|
||||
pub fn convert_patch_changes(
|
||||
changes: &HashMap<std::path::PathBuf, codex_protocol::protocol::FileChange>,
|
||||
) -> Vec<FileUpdateChange> {
|
||||
@@ -913,6 +1032,23 @@ pub fn convert_patch_changes(
|
||||
converted
|
||||
}
|
||||
|
||||
fn convert_dynamic_tool_content_items(
|
||||
items: &[codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem],
|
||||
) -> Vec<DynamicToolCallOutputContentItem> {
|
||||
items
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|item| match item {
|
||||
codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem::InputText { text } => {
|
||||
DynamicToolCallOutputContentItem::InputText { text }
|
||||
}
|
||||
codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem::InputImage {
|
||||
image_url,
|
||||
} => DynamicToolCallOutputContentItem::InputImage { image_url },
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn map_patch_change_kind(change: &codex_protocol::protocol::FileChange) -> PatchChangeKind {
|
||||
match change {
|
||||
codex_protocol::protocol::FileChange::Add { .. } => PatchChangeKind::Add,
|
||||
@@ -1002,6 +1138,7 @@ impl From<&PendingTurn> for Turn {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem as CoreDynamicToolCallOutputContentItem;
|
||||
use codex_protocol::items::TurnItem as CoreTurnItem;
|
||||
use codex_protocol::items::UserMessageItem as CoreUserMessageItem;
|
||||
use codex_protocol::models::MessagePhase as CoreMessagePhase;
|
||||
@@ -1012,6 +1149,7 @@ mod tests {
|
||||
use codex_protocol::protocol::AgentReasoningRawContentEvent;
|
||||
use codex_protocol::protocol::CodexErrorInfo;
|
||||
use codex_protocol::protocol::CompactedItem;
|
||||
use codex_protocol::protocol::DynamicToolCallResponseEvent;
|
||||
use codex_protocol::protocol::ExecCommandEndEvent;
|
||||
use codex_protocol::protocol::ExecCommandSource;
|
||||
use codex_protocol::protocol::ItemStartedEvent;
|
||||
@@ -1127,6 +1265,66 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reports_synthetic_turn_ids_for_legacy_history() {
|
||||
let items = vec![
|
||||
RolloutItem::EventMsg(EventMsg::UserMessage(UserMessageEvent {
|
||||
message: "legacy".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
local_images: Vec::new(),
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::AgentMessage(AgentMessageEvent {
|
||||
message: "reply".into(),
|
||||
phase: None,
|
||||
})),
|
||||
];
|
||||
|
||||
let mut builder = ThreadHistoryBuilder::new();
|
||||
for item in &items {
|
||||
builder.handle_rollout_item(item);
|
||||
}
|
||||
|
||||
assert!(builder.has_synthetic_turn_ids());
|
||||
assert_eq!(builder.finish().len(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reports_no_synthetic_turn_ids_when_turn_boundaries_are_explicit() {
|
||||
let turn_id = "turn-explicit";
|
||||
let items = vec![
|
||||
RolloutItem::EventMsg(EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: turn_id.to_string(),
|
||||
model_context_window: Some(128_000),
|
||||
collaboration_mode_kind: Default::default(),
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::UserMessage(UserMessageEvent {
|
||||
message: "modern".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
local_images: Vec::new(),
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::AgentMessage(AgentMessageEvent {
|
||||
message: "reply".into(),
|
||||
phase: None,
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::TurnComplete(TurnCompleteEvent {
|
||||
turn_id: turn_id.to_string(),
|
||||
last_agent_message: Some("reply".into()),
|
||||
})),
|
||||
];
|
||||
|
||||
let mut builder = ThreadHistoryBuilder::new();
|
||||
for item in &items {
|
||||
builder.handle_rollout_item(item);
|
||||
}
|
||||
|
||||
assert!(!builder.has_synthetic_turn_ids());
|
||||
let turns = builder.finish();
|
||||
assert_eq!(turns.len(), 1);
|
||||
assert_eq!(turns[0].id, turn_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignores_non_plan_item_lifecycle_events() {
|
||||
let turn_id = "turn-1";
|
||||
@@ -1606,6 +1804,65 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reconstructs_dynamic_tool_items_from_request_and_response_events() {
|
||||
let events = vec![
|
||||
EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: "turn-1".into(),
|
||||
model_context_window: None,
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
message: "run dynamic tool".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
local_images: Vec::new(),
|
||||
}),
|
||||
EventMsg::DynamicToolCallRequest(
|
||||
codex_protocol::dynamic_tools::DynamicToolCallRequest {
|
||||
call_id: "dyn-1".into(),
|
||||
turn_id: "turn-1".into(),
|
||||
tool: "lookup_ticket".into(),
|
||||
arguments: serde_json::json!({"id":"ABC-123"}),
|
||||
},
|
||||
),
|
||||
EventMsg::DynamicToolCallResponse(DynamicToolCallResponseEvent {
|
||||
call_id: "dyn-1".into(),
|
||||
turn_id: "turn-1".into(),
|
||||
tool: "lookup_ticket".into(),
|
||||
arguments: serde_json::json!({"id":"ABC-123"}),
|
||||
content_items: vec![CoreDynamicToolCallOutputContentItem::InputText {
|
||||
text: "Ticket is open".into(),
|
||||
}],
|
||||
success: true,
|
||||
error: None,
|
||||
duration: Duration::from_millis(42),
|
||||
}),
|
||||
];
|
||||
|
||||
let items = events
|
||||
.into_iter()
|
||||
.map(RolloutItem::EventMsg)
|
||||
.collect::<Vec<_>>();
|
||||
let turns = build_turns_from_rollout_items(&items);
|
||||
assert_eq!(turns.len(), 1);
|
||||
assert_eq!(turns[0].items.len(), 2);
|
||||
assert_eq!(
|
||||
turns[0].items[1],
|
||||
ThreadItem::DynamicToolCall {
|
||||
id: "dyn-1".into(),
|
||||
tool: "lookup_ticket".into(),
|
||||
arguments: serde_json::json!({"id":"ABC-123"}),
|
||||
status: DynamicToolCallStatus::Completed,
|
||||
content_items: Some(vec![DynamicToolCallOutputContentItem::InputText {
|
||||
text: "Ticket is open".into(),
|
||||
}]),
|
||||
success: Some(true),
|
||||
duration_ms: Some(42),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reconstructs_declined_exec_and_patch_items() {
|
||||
let events = vec![
|
||||
|
||||
@@ -7,6 +7,8 @@ use codex_protocol::account::PlanType;
|
||||
use codex_protocol::approvals::ExecPolicyAmendment as CoreExecPolicyAmendment;
|
||||
use codex_protocol::approvals::NetworkApprovalContext as CoreNetworkApprovalContext;
|
||||
use codex_protocol::approvals::NetworkApprovalProtocol as CoreNetworkApprovalProtocol;
|
||||
use codex_protocol::approvals::NetworkPolicyAmendment as CoreNetworkPolicyAmendment;
|
||||
use codex_protocol::approvals::NetworkPolicyRuleAction as CoreNetworkPolicyRuleAction;
|
||||
use codex_protocol::config_types::CollaborationMode;
|
||||
use codex_protocol::config_types::CollaborationModeMask;
|
||||
use codex_protocol::config_types::ForcedLoginMethod;
|
||||
@@ -20,7 +22,12 @@ use codex_protocol::items::TurnItem as CoreTurnItem;
|
||||
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::FileSystemPermissions as CoreFileSystemPermissions;
|
||||
use codex_protocol::models::MacOsAutomationValue as CoreMacOsAutomationValue;
|
||||
use codex_protocol::models::MacOsPermissions as CoreMacOsPermissions;
|
||||
use codex_protocol::models::MacOsPreferencesValue as CoreMacOsPreferencesValue;
|
||||
use codex_protocol::models::MessagePhase;
|
||||
use codex_protocol::models::PermissionProfile as CorePermissionProfile;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::openai_models::InputModality;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
@@ -39,6 +46,7 @@ use codex_protocol::protocol::PatchApplyStatus as CorePatchApplyStatus;
|
||||
use codex_protocol::protocol::RateLimitSnapshot as CoreRateLimitSnapshot;
|
||||
use codex_protocol::protocol::RateLimitWindow as CoreRateLimitWindow;
|
||||
use codex_protocol::protocol::ReadOnlyAccess as CoreReadOnlyAccess;
|
||||
use codex_protocol::protocol::RealtimeAudioFrame as CoreRealtimeAudioFrame;
|
||||
use codex_protocol::protocol::RejectConfig as CoreRejectConfig;
|
||||
use codex_protocol::protocol::SessionSource as CoreSessionSource;
|
||||
use codex_protocol::protocol::SkillDependencies as CoreSkillDependencies;
|
||||
@@ -633,6 +641,64 @@ pub struct ConfigRequirementsReadResponse {
|
||||
pub requirements: Option<ConfigRequirements>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash, JsonSchema, TS)]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub enum ExternalAgentConfigMigrationItemType {
|
||||
#[serde(rename = "AGENTS_MD")]
|
||||
#[ts(rename = "AGENTS_MD")]
|
||||
AgentsMd,
|
||||
#[serde(rename = "CONFIG")]
|
||||
#[ts(rename = "CONFIG")]
|
||||
Config,
|
||||
#[serde(rename = "SKILLS")]
|
||||
#[ts(rename = "SKILLS")]
|
||||
Skills,
|
||||
#[serde(rename = "MCP_SERVER_CONFIG")]
|
||||
#[ts(rename = "MCP_SERVER_CONFIG")]
|
||||
McpServerConfig,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ExternalAgentConfigMigrationItem {
|
||||
pub item_type: ExternalAgentConfigMigrationItemType,
|
||||
pub description: String,
|
||||
/// Null or empty means home-scoped migration; non-empty means repo-scoped migration.
|
||||
pub cwd: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ExternalAgentConfigDetectResponse {
|
||||
pub items: Vec<ExternalAgentConfigMigrationItem>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ExternalAgentConfigDetectParams {
|
||||
/// If true, include detection under the user's home (~/.claude, ~/.codex, etc.).
|
||||
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
|
||||
pub include_home: bool,
|
||||
/// Zero or more working directories to include for repo-scoped detection.
|
||||
#[ts(optional = nullable)]
|
||||
pub cwds: Option<Vec<PathBuf>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ExternalAgentConfigImportParams {
|
||||
pub migration_items: Vec<ExternalAgentConfigMigrationItem>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ExternalAgentConfigImportResponse {}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
@@ -681,6 +747,10 @@ pub enum CommandExecutionApprovalDecision {
|
||||
AcceptWithExecpolicyAmendment {
|
||||
execpolicy_amendment: ExecPolicyAmendment,
|
||||
},
|
||||
/// User chose a persistent network policy rule (allow/deny) for this host.
|
||||
ApplyNetworkPolicyAmendment {
|
||||
network_policy_amendment: NetworkPolicyAmendment,
|
||||
},
|
||||
/// User denied the command. The agent will continue the turn.
|
||||
Decline,
|
||||
/// User denied the command. The turn will also be immediately interrupted.
|
||||
@@ -713,6 +783,63 @@ impl From<CoreNetworkApprovalContext> for NetworkApprovalContext {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct AdditionalFileSystemPermissions {
|
||||
pub read: Option<Vec<PathBuf>>,
|
||||
pub write: Option<Vec<PathBuf>>,
|
||||
}
|
||||
|
||||
impl From<CoreFileSystemPermissions> for AdditionalFileSystemPermissions {
|
||||
fn from(value: CoreFileSystemPermissions) -> Self {
|
||||
Self {
|
||||
read: value.read,
|
||||
write: value.write,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct AdditionalMacOsPermissions {
|
||||
pub preferences: Option<CoreMacOsPreferencesValue>,
|
||||
pub automations: Option<CoreMacOsAutomationValue>,
|
||||
pub accessibility: Option<bool>,
|
||||
pub calendar: Option<bool>,
|
||||
}
|
||||
|
||||
impl From<CoreMacOsPermissions> for AdditionalMacOsPermissions {
|
||||
fn from(value: CoreMacOsPermissions) -> Self {
|
||||
Self {
|
||||
preferences: value.preferences,
|
||||
automations: value.automations,
|
||||
accessibility: value.accessibility,
|
||||
calendar: value.calendar,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct AdditionalPermissionProfile {
|
||||
pub network: Option<bool>,
|
||||
pub file_system: Option<AdditionalFileSystemPermissions>,
|
||||
pub macos: Option<AdditionalMacOsPermissions>,
|
||||
}
|
||||
|
||||
impl From<CorePermissionProfile> for AdditionalPermissionProfile {
|
||||
fn from(value: CorePermissionProfile) -> Self {
|
||||
Self {
|
||||
network: value.network,
|
||||
file_system: value.file_system.map(AdditionalFileSystemPermissions::from),
|
||||
macos: value.macos.map(AdditionalMacOsPermissions::from),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
@@ -910,6 +1037,38 @@ impl From<CoreExecPolicyAmendment> for ExecPolicyAmendment {
|
||||
}
|
||||
}
|
||||
|
||||
v2_enum_from_core!(
|
||||
pub enum NetworkPolicyRuleAction from CoreNetworkPolicyRuleAction {
|
||||
Allow, Deny
|
||||
}
|
||||
);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct NetworkPolicyAmendment {
|
||||
pub host: String,
|
||||
pub action: NetworkPolicyRuleAction,
|
||||
}
|
||||
|
||||
impl NetworkPolicyAmendment {
|
||||
pub fn into_core(self) -> CoreNetworkPolicyAmendment {
|
||||
CoreNetworkPolicyAmendment {
|
||||
host: self.host,
|
||||
action: self.action.to_core(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CoreNetworkPolicyAmendment> for NetworkPolicyAmendment {
|
||||
fn from(value: CoreNetworkPolicyAmendment) -> Self {
|
||||
Self {
|
||||
host: value.host,
|
||||
action: NetworkPolicyRuleAction::from(value.action),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
#[ts(tag = "type")]
|
||||
@@ -1561,6 +1720,8 @@ pub struct ThreadStartParams {
|
||||
#[ts(optional = nullable)]
|
||||
pub config: Option<HashMap<String, JsonValue>>,
|
||||
#[ts(optional = nullable)]
|
||||
pub service_name: Option<String>,
|
||||
#[ts(optional = nullable)]
|
||||
pub base_instructions: Option<String>,
|
||||
#[ts(optional = nullable)]
|
||||
pub developer_instructions: Option<String>,
|
||||
@@ -1708,6 +1869,17 @@ pub struct ThreadForkParams {
|
||||
#[ts(optional = nullable)]
|
||||
pub path: Option<PathBuf>,
|
||||
|
||||
/// [UNSTABLE] Fork after the specified historical turn (inclusive).
|
||||
/// When omitted, the full thread history is copied.
|
||||
///
|
||||
/// The value should come from `thread/read(includeTurns=true)` for the same source thread.
|
||||
/// Requests are rejected for legacy histories whose replayed turn ids are not stable, for
|
||||
/// in-progress turns, and for turns that do not yet contain both a user message and an agent
|
||||
/// response.
|
||||
#[experimental("thread/fork.forkAfterTurnId")]
|
||||
#[ts(optional = nullable)]
|
||||
pub fork_after_turn_id: Option<String>,
|
||||
|
||||
/// Configuration overrides for the forked thread, if any.
|
||||
#[ts(optional = nullable)]
|
||||
pub model: Option<String>,
|
||||
@@ -1861,6 +2033,9 @@ pub struct ThreadListParams {
|
||||
/// matches this path are returned.
|
||||
#[ts(optional = nullable)]
|
||||
pub cwd: Option<String>,
|
||||
/// Optional substring filter for the extracted thread title.
|
||||
#[ts(optional = nullable)]
|
||||
pub search_term: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
|
||||
@@ -2388,6 +2563,157 @@ pub struct ErrorNotification {
|
||||
pub turn_id: String,
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - thread realtime audio chunk.
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeAudioChunk {
|
||||
pub data: String,
|
||||
pub sample_rate: u32,
|
||||
pub num_channels: u16,
|
||||
pub samples_per_channel: Option<u32>,
|
||||
}
|
||||
|
||||
impl From<CoreRealtimeAudioFrame> for ThreadRealtimeAudioChunk {
|
||||
fn from(value: CoreRealtimeAudioFrame) -> Self {
|
||||
let CoreRealtimeAudioFrame {
|
||||
data,
|
||||
sample_rate,
|
||||
num_channels,
|
||||
samples_per_channel,
|
||||
} = value;
|
||||
Self {
|
||||
data,
|
||||
sample_rate,
|
||||
num_channels,
|
||||
samples_per_channel,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ThreadRealtimeAudioChunk> for CoreRealtimeAudioFrame {
|
||||
fn from(value: ThreadRealtimeAudioChunk) -> Self {
|
||||
let ThreadRealtimeAudioChunk {
|
||||
data,
|
||||
sample_rate,
|
||||
num_channels,
|
||||
samples_per_channel,
|
||||
} = value;
|
||||
Self {
|
||||
data,
|
||||
sample_rate,
|
||||
num_channels,
|
||||
samples_per_channel,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - start a thread-scoped realtime session.
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeStartParams {
|
||||
pub thread_id: String,
|
||||
pub prompt: String,
|
||||
#[ts(optional = nullable)]
|
||||
pub session_id: Option<String>,
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - response for starting thread realtime.
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeStartResponse {}
|
||||
|
||||
/// EXPERIMENTAL - append audio input to thread realtime.
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeAppendAudioParams {
|
||||
pub thread_id: String,
|
||||
pub audio: ThreadRealtimeAudioChunk,
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - response for appending realtime audio input.
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeAppendAudioResponse {}
|
||||
|
||||
/// EXPERIMENTAL - append text input to thread realtime.
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeAppendTextParams {
|
||||
pub thread_id: String,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - response for appending realtime text input.
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeAppendTextResponse {}
|
||||
|
||||
/// EXPERIMENTAL - stop thread realtime.
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeStopParams {
|
||||
pub thread_id: String,
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - response for stopping thread realtime.
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeStopResponse {}
|
||||
|
||||
/// EXPERIMENTAL - emitted when thread realtime startup is accepted.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeStartedNotification {
|
||||
pub thread_id: String,
|
||||
pub session_id: Option<String>,
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - raw non-audio thread realtime item emitted by the backend.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeItemAddedNotification {
|
||||
pub thread_id: String,
|
||||
pub item: JsonValue,
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - streamed output audio emitted by thread realtime.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeOutputAudioDeltaNotification {
|
||||
pub thread_id: String,
|
||||
pub audio: ThreadRealtimeAudioChunk,
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - emitted when thread realtime encounters an error.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeErrorNotification {
|
||||
pub thread_id: String,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
/// EXPERIMENTAL - emitted when thread realtime transport closes.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadRealtimeClosedNotification {
|
||||
pub thread_id: String,
|
||||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
@@ -2742,6 +3068,19 @@ pub enum ThreadItem {
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(rename_all = "camelCase")]
|
||||
DynamicToolCall {
|
||||
id: String,
|
||||
tool: String,
|
||||
arguments: JsonValue,
|
||||
status: DynamicToolCallStatus,
|
||||
content_items: Option<Vec<DynamicToolCallOutputContentItem>>,
|
||||
success: Option<bool>,
|
||||
/// The duration of the dynamic tool call in milliseconds.
|
||||
#[ts(type = "number | null")]
|
||||
duration_ms: Option<i64>,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(rename_all = "camelCase")]
|
||||
CollabAgentToolCall {
|
||||
/// Unique identifier for this collab tool call.
|
||||
id: String,
|
||||
@@ -2790,6 +3129,7 @@ impl ThreadItem {
|
||||
| ThreadItem::CommandExecution { id, .. }
|
||||
| ThreadItem::FileChange { id, .. }
|
||||
| ThreadItem::McpToolCall { id, .. }
|
||||
| ThreadItem::DynamicToolCall { id, .. }
|
||||
| ThreadItem::CollabAgentToolCall { id, .. }
|
||||
| ThreadItem::WebSearch { id, .. }
|
||||
| ThreadItem::ImageView { id, .. }
|
||||
@@ -2970,6 +3310,15 @@ pub enum McpToolCallStatus {
|
||||
Failed,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub enum DynamicToolCallStatus {
|
||||
InProgress,
|
||||
Completed,
|
||||
Failed,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
@@ -3359,7 +3708,7 @@ pub struct ContextCompactedNotification {
|
||||
pub turn_id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS, ExperimentalApi)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct CommandExecutionRequestApprovalParams {
|
||||
@@ -3380,7 +3729,7 @@ pub struct CommandExecutionRequestApprovalParams {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional = nullable)]
|
||||
pub reason: Option<String>,
|
||||
/// Optional context for managed-network approval prompts.
|
||||
/// Optional context for a managed-network approval prompt.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional = nullable)]
|
||||
pub network_approval_context: Option<NetworkApprovalContext>,
|
||||
@@ -3396,10 +3745,28 @@ pub struct CommandExecutionRequestApprovalParams {
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional = nullable)]
|
||||
pub command_actions: Option<Vec<CommandAction>>,
|
||||
/// Optional additional permissions requested for this command.
|
||||
#[experimental("item/commandExecution/requestApproval.additionalPermissions")]
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional = nullable)]
|
||||
pub additional_permissions: Option<AdditionalPermissionProfile>,
|
||||
/// Optional proposed execpolicy amendment to allow similar commands without prompting.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional = nullable)]
|
||||
pub proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
|
||||
/// Optional proposed network policy amendments (allow/deny host) for future requests.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional = nullable)]
|
||||
pub proposed_network_policy_amendments: Option<Vec<NetworkPolicyAmendment>>,
|
||||
}
|
||||
|
||||
impl CommandExecutionRequestApprovalParams {
|
||||
pub fn strip_experimental_fields(&mut self) {
|
||||
// TODO: Avoid hardcoding individual experimental fields here.
|
||||
// We need a generic outbound compatibility design for stripping or
|
||||
// otherwise handling experimental server->client payloads.
|
||||
self.additional_permissions = None;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
@@ -3431,6 +3798,29 @@ pub struct FileChangeRequestApprovalResponse {
|
||||
pub decision: FileChangeApprovalDecision,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS, ExperimentalApi)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct SkillRequestApprovalParams {
|
||||
pub item_id: String,
|
||||
pub skill_name: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub enum SkillApprovalDecision {
|
||||
Approve,
|
||||
Decline,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct SkillRequestApprovalResponse {
|
||||
pub decision: SkillApprovalDecision,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
|
||||
@@ -57,6 +57,9 @@ use codex_app_server_protocol::SendUserMessageParams;
|
||||
use codex_app_server_protocol::SendUserMessageResponse;
|
||||
use codex_app_server_protocol::ServerNotification;
|
||||
use codex_app_server_protocol::ServerRequest;
|
||||
use codex_app_server_protocol::SkillApprovalDecision;
|
||||
use codex_app_server_protocol::SkillRequestApprovalParams;
|
||||
use codex_app_server_protocol::SkillRequestApprovalResponse;
|
||||
use codex_app_server_protocol::ThreadItem;
|
||||
use codex_app_server_protocol::ThreadListParams;
|
||||
use codex_app_server_protocol::ThreadListResponse;
|
||||
@@ -168,6 +171,9 @@ enum CliCommand {
|
||||
},
|
||||
/// Send a user message through the app-server V2 thread/turn APIs.
|
||||
SendMessageV2 {
|
||||
/// Opt into experimental app-server methods and fields.
|
||||
#[arg(long)]
|
||||
experimental_api: bool,
|
||||
/// User message to send to Codex.
|
||||
user_message: String,
|
||||
},
|
||||
@@ -257,9 +263,18 @@ pub fn run() -> Result<()> {
|
||||
let endpoint = resolve_endpoint(codex_bin, url)?;
|
||||
send_message(&endpoint, &config_overrides, user_message)
|
||||
}
|
||||
CliCommand::SendMessageV2 { user_message } => {
|
||||
CliCommand::SendMessageV2 {
|
||||
experimental_api,
|
||||
user_message,
|
||||
} => {
|
||||
let endpoint = resolve_endpoint(codex_bin, url)?;
|
||||
send_message_v2_endpoint(&endpoint, &config_overrides, user_message, &dynamic_tools)
|
||||
send_message_v2_endpoint(
|
||||
&endpoint,
|
||||
&config_overrides,
|
||||
user_message,
|
||||
experimental_api,
|
||||
&dynamic_tools,
|
||||
)
|
||||
}
|
||||
CliCommand::ResumeMessageV2 {
|
||||
thread_id,
|
||||
@@ -505,19 +520,31 @@ pub fn send_message_v2(
|
||||
dynamic_tools: &Option<Vec<DynamicToolSpec>>,
|
||||
) -> Result<()> {
|
||||
let endpoint = Endpoint::SpawnCodex(codex_bin.to_path_buf());
|
||||
send_message_v2_endpoint(&endpoint, config_overrides, user_message, dynamic_tools)
|
||||
send_message_v2_endpoint(
|
||||
&endpoint,
|
||||
config_overrides,
|
||||
user_message,
|
||||
true,
|
||||
dynamic_tools,
|
||||
)
|
||||
}
|
||||
|
||||
fn send_message_v2_endpoint(
|
||||
endpoint: &Endpoint,
|
||||
config_overrides: &[String],
|
||||
user_message: String,
|
||||
experimental_api: bool,
|
||||
dynamic_tools: &Option<Vec<DynamicToolSpec>>,
|
||||
) -> Result<()> {
|
||||
if dynamic_tools.is_some() && !experimental_api {
|
||||
bail!("--dynamic-tools requires --experimental-api for send-message-v2");
|
||||
}
|
||||
|
||||
send_message_v2_with_policies(
|
||||
endpoint,
|
||||
config_overrides,
|
||||
user_message,
|
||||
experimental_api,
|
||||
None,
|
||||
None,
|
||||
dynamic_tools,
|
||||
@@ -687,6 +714,7 @@ fn trigger_cmd_approval(
|
||||
endpoint,
|
||||
config_overrides,
|
||||
message,
|
||||
true,
|
||||
Some(AskForApproval::OnRequest),
|
||||
Some(SandboxPolicy::ReadOnly {
|
||||
access: ReadOnlyAccess::FullAccess,
|
||||
@@ -708,6 +736,7 @@ fn trigger_patch_approval(
|
||||
endpoint,
|
||||
config_overrides,
|
||||
message,
|
||||
true,
|
||||
Some(AskForApproval::OnRequest),
|
||||
Some(SandboxPolicy::ReadOnly {
|
||||
access: ReadOnlyAccess::FullAccess,
|
||||
@@ -726,6 +755,7 @@ fn no_trigger_cmd_approval(
|
||||
endpoint,
|
||||
config_overrides,
|
||||
prompt.to_string(),
|
||||
true,
|
||||
None,
|
||||
None,
|
||||
dynamic_tools,
|
||||
@@ -736,13 +766,14 @@ fn send_message_v2_with_policies(
|
||||
endpoint: &Endpoint,
|
||||
config_overrides: &[String],
|
||||
user_message: String,
|
||||
experimental_api: bool,
|
||||
approval_policy: Option<AskForApproval>,
|
||||
sandbox_policy: Option<SandboxPolicy>,
|
||||
dynamic_tools: &Option<Vec<DynamicToolSpec>>,
|
||||
) -> Result<()> {
|
||||
let mut client = CodexClient::connect(endpoint, config_overrides)?;
|
||||
|
||||
let initialize = client.initialize()?;
|
||||
let initialize = client.initialize_with_experimental_api(experimental_api)?;
|
||||
println!("< initialize response: {initialize:?}");
|
||||
|
||||
let thread_response = client.thread_start(ThreadStartParams {
|
||||
@@ -885,6 +916,7 @@ fn thread_list(endpoint: &Endpoint, config_overrides: &[String], limit: u32) ->
|
||||
source_kinds: None,
|
||||
archived: None,
|
||||
cwd: None,
|
||||
search_term: None,
|
||||
})?;
|
||||
println!("< thread/list response: {response:?}");
|
||||
|
||||
@@ -1029,6 +1061,13 @@ impl CodexClient {
|
||||
}
|
||||
|
||||
fn initialize(&mut self) -> Result<InitializeResponse> {
|
||||
self.initialize_with_experimental_api(true)
|
||||
}
|
||||
|
||||
fn initialize_with_experimental_api(
|
||||
&mut self,
|
||||
experimental_api: bool,
|
||||
) -> Result<InitializeResponse> {
|
||||
let request_id = self.request_id();
|
||||
let request = ClientRequest::Initialize {
|
||||
request_id: request_id.clone(),
|
||||
@@ -1039,7 +1078,7 @@ impl CodexClient {
|
||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
},
|
||||
capabilities: Some(InitializeCapabilities {
|
||||
experimental_api: true,
|
||||
experimental_api,
|
||||
opt_out_notification_methods: Some(
|
||||
NOTIFICATIONS_TO_OPT_OUT
|
||||
.iter()
|
||||
@@ -1472,6 +1511,9 @@ impl CodexClient {
|
||||
ServerRequest::FileChangeRequestApproval { request_id, params } => {
|
||||
self.approve_file_change_request(request_id, params)?;
|
||||
}
|
||||
ServerRequest::SkillRequestApproval { request_id, params } => {
|
||||
self.approve_skill_request(request_id, params)?;
|
||||
}
|
||||
other => {
|
||||
bail!("received unsupported server request: {other:?}");
|
||||
}
|
||||
@@ -1495,7 +1537,9 @@ impl CodexClient {
|
||||
command,
|
||||
cwd,
|
||||
command_actions,
|
||||
additional_permissions,
|
||||
proposed_execpolicy_amendment,
|
||||
proposed_network_policy_amendments,
|
||||
} = params;
|
||||
|
||||
println!(
|
||||
@@ -1521,9 +1565,15 @@ impl CodexClient {
|
||||
{
|
||||
println!("< command actions: {command_actions:?}");
|
||||
}
|
||||
if let Some(additional_permissions) = additional_permissions.as_ref() {
|
||||
println!("< additional permissions: {additional_permissions:?}");
|
||||
}
|
||||
if let Some(execpolicy_amendment) = proposed_execpolicy_amendment.as_ref() {
|
||||
println!("< proposed execpolicy amendment: {execpolicy_amendment:?}");
|
||||
}
|
||||
if let Some(network_policy_amendments) = proposed_network_policy_amendments.as_ref() {
|
||||
println!("< proposed network policy amendments: {network_policy_amendments:?}");
|
||||
}
|
||||
|
||||
let decision = match self.command_approval_behavior {
|
||||
CommandApprovalBehavior::AlwaysAccept => CommandExecutionApprovalDecision::Accept,
|
||||
@@ -1543,6 +1593,22 @@ impl CodexClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn approve_skill_request(
|
||||
&mut self,
|
||||
request_id: RequestId,
|
||||
params: SkillRequestApprovalParams,
|
||||
) -> Result<()> {
|
||||
println!(
|
||||
"\n< skill approval requested for item {}, skill {}",
|
||||
params.item_id, params.skill_name
|
||||
);
|
||||
let response = SkillRequestApprovalResponse {
|
||||
decision: SkillApprovalDecision::Approve,
|
||||
};
|
||||
self.send_server_request_response(request_id, &response)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn approve_file_change_request(
|
||||
&mut self,
|
||||
request_id: RequestId,
|
||||
|
||||
@@ -65,6 +65,7 @@ axum = { workspace = true, default-features = false, features = [
|
||||
base64 = { workspace = true }
|
||||
codex-execpolicy = { workspace = true }
|
||||
core_test_support = { workspace = true }
|
||||
codex-state = { workspace = true }
|
||||
codex-utils-cargo-bin = { workspace = true }
|
||||
os_info = { workspace = true }
|
||||
pretty_assertions = { workspace = true }
|
||||
|
||||
@@ -121,8 +121,8 @@ Example with notification opt-out:
|
||||
|
||||
- `thread/start` — create a new thread; emits `thread/started` and auto-subscribes you to turn/item events for that thread.
|
||||
- `thread/resume` — reopen an existing thread by id so subsequent `turn/start` calls append to it.
|
||||
- `thread/fork` — fork an existing thread into a new thread id by copying the stored history; emits `thread/started` and auto-subscribes you to turn/item events for the new thread.
|
||||
- `thread/list` — page through stored rollouts; supports cursor-based pagination and optional `modelProviders`, `sourceKinds`, `archived`, and `cwd` filters. Each returned `thread` includes `status` (`ThreadStatus`), defaulting to `notLoaded` when the thread is not currently loaded.
|
||||
- `thread/fork` — fork an existing thread into a new thread id by copying the stored history. Experimental `forkAfterTurnId` lets clients fork from a selected historical turn (modern turn-id-stable histories only); emits `thread/started` and auto-subscribes you to turn/item events for the new thread.
|
||||
- `thread/list` — page through stored rollouts; supports cursor-based pagination and optional `modelProviders`, `sourceKinds`, `archived`, `cwd`, and `searchTerm` filters. Each returned `thread` includes `status` (`ThreadStatus`), defaulting to `notLoaded` when the thread is not currently loaded.
|
||||
- `thread/loaded/list` — list the thread ids currently loaded in memory.
|
||||
- `thread/read` — read a stored thread by id without resuming it; optionally include turns via `includeTurns`. The returned `thread` includes `status` (`ThreadStatus`), defaulting to `notLoaded` when the thread is not currently loaded.
|
||||
- `thread/status/changed` — notification emitted when a loaded thread’s status changes (`threadId` + new `status`).
|
||||
@@ -135,6 +135,10 @@ Example with notification opt-out:
|
||||
- `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. For `collaborationMode`, `settings.developer_instructions: null` means "use built-in instructions for the selected mode".
|
||||
- `turn/steer` — add user input to an already in-flight turn without starting a new turn; returns the active `turnId` that accepted the input.
|
||||
- `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"`.
|
||||
- `thread/realtime/start` — start a thread-scoped realtime session (experimental); returns `{}` and streams `thread/realtime/*` notifications.
|
||||
- `thread/realtime/appendAudio` — append an input audio chunk to the active realtime session (experimental); returns `{}`.
|
||||
- `thread/realtime/appendText` — append text input to the active realtime session (experimental); returns `{}`.
|
||||
- `thread/realtime/stop` — stop the active realtime session for the thread (experimental); returns `{}`.
|
||||
- `review/start` — kick off Codex’s 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 (set `includeHidden: true` to include entries with `hidden: true`), with reasoning effort options and optional `upgrade` model ids.
|
||||
@@ -153,6 +157,8 @@ Example with notification opt-out:
|
||||
- `feedback/upload` — submit a feedback report (classification + optional reason/logs, conversation_id, and optional `extraLogFiles` attachments array); returns the tracking thread id.
|
||||
- `command/exec` — run a single command under the server sandbox without starting a thread/turn (handy for utilities and validation).
|
||||
- `config/read` — fetch the effective config on disk after resolving config layering.
|
||||
- `externalAgentConfig/detect` — detect migratable external-agent artifacts with `includeHome` and optional `cwds`; each detected item includes `cwd` (`null` for home).
|
||||
- `externalAgentConfig/import` — apply selected external-agent migration items by passing explicit `migrationItems` with `cwd` (`null` for home).
|
||||
- `config/value/write` — write a single config key/value to the user's config.toml on disk.
|
||||
- `config/batchWrite` — apply multiple config edits atomically to the user's config.toml on disk.
|
||||
- `configRequirements/read` — fetch loaded requirements constraints from `requirements.toml` and/or MDM (or `null` if none are configured), including allow-lists (`allowedApprovalPolicies`, `allowedSandboxModes`, `allowedWebSearchModes`), `enforceResidency`, and `network` constraints.
|
||||
@@ -170,6 +176,7 @@ Start a fresh thread when you need a new Codex conversation.
|
||||
"approvalPolicy": "never",
|
||||
"sandbox": "workspaceWrite",
|
||||
"personality": "friendly",
|
||||
"serviceName": "my_app_server_client", // optional metrics tag (`service_name`)
|
||||
// Experimental: requires opt-in
|
||||
"dynamicTools": [
|
||||
{
|
||||
@@ -208,7 +215,7 @@ To continue a stored session, call `thread/resume` with the `thread.id` you prev
|
||||
{ "id": 11, "result": { "thread": { "id": "thr_123", … } } }
|
||||
```
|
||||
|
||||
To branch from a stored session, call `thread/fork` with the `thread.id`. This creates a new thread id and emits a `thread/started` notification for it:
|
||||
To branch from a stored session, call `thread/fork` with the `thread.id`. This creates a new thread id and emits a `thread/started` notification for it. To fork from a selected prior turn instead of the full history, pass experimental `forkAfterTurnId`:
|
||||
|
||||
```json
|
||||
{ "method": "thread/fork", "id": 12, "params": { "threadId": "thr_123" } }
|
||||
@@ -216,6 +223,19 @@ To branch from a stored session, call `thread/fork` with the `thread.id`. This c
|
||||
{ "method": "thread/started", "params": { "thread": { … } } }
|
||||
```
|
||||
|
||||
```json
|
||||
{ "method": "thread/fork", "id": 13, "params": {
|
||||
"threadId": "thr_123",
|
||||
"forkAfterTurnId": "turn_abc",
|
||||
"cwd": "/Users/me/project-worktree"
|
||||
} }
|
||||
```
|
||||
|
||||
The `forkAfterTurnId` value should come from `thread/read(includeTurns=true)` for that source
|
||||
thread. Anchored forks are rejected for legacy histories that only have replay-synthesized turn
|
||||
ids, for turns that are still in progress, and for turns that do not yet include both the user's
|
||||
input and the model's response.
|
||||
|
||||
Experimental API: `thread/start`, `thread/resume`, and `thread/fork` accept `persistExtendedHistory: true` to persist a richer subset of ThreadItems for non-lossy history when calling `thread/read`, `thread/resume`, and `thread/fork` later. This does not backfill events that were not persisted previously.
|
||||
|
||||
### Example: List threads (with pagination & filters)
|
||||
@@ -229,6 +249,7 @@ Experimental API: `thread/start`, `thread/resume`, and `thread/fork` accept `per
|
||||
- `sourceKinds` — restrict results to specific sources; omit or pass `[]` for interactive sessions only (`cli`, `vscode`).
|
||||
- `archived` — when `true`, list archived threads only. When `false` or `null`, list non-archived threads (default).
|
||||
- `cwd` — restrict results to threads whose session cwd exactly matches this path.
|
||||
- `searchTerm` — restrict results to threads whose extracted title contains this substring (case-sensitive).
|
||||
- Responses include `agentNickname` and `agentRole` for AgentControl-spawned thread sub-agents when available.
|
||||
|
||||
Example:
|
||||
@@ -549,6 +570,8 @@ Notes:
|
||||
|
||||
Event notifications are the server-initiated event stream for thread lifecycles, turn lifecycles, and the items within them. After you start or resume a thread, keep reading stdout for `thread/started`, `thread/archived`, `thread/unarchived`, `turn/*`, and `item/*` notifications.
|
||||
|
||||
Thread realtime uses a separate thread-scoped notification surface. `thread/realtime/*` notifications are ephemeral transport events, not `ThreadItem`s, and are not returned by `thread/read`, `thread/resume`, or `thread/fork`.
|
||||
|
||||
### Notification opt-out
|
||||
|
||||
Clients can suppress specific notifications per connection by sending exact method names in `initialize.params.capabilities.optOutNotificationMethods`.
|
||||
@@ -570,6 +593,18 @@ The fuzzy file search session API emits per-query notifications:
|
||||
- `fuzzyFileSearch/sessionUpdated` — `{ sessionId, query, files }` with the current matching files for the active query.
|
||||
- `fuzzyFileSearch/sessionCompleted` — `{ sessionId, query }` once indexing/matching for that query has completed.
|
||||
|
||||
### Thread realtime events (experimental)
|
||||
|
||||
The thread realtime API emits thread-scoped notifications for session lifecycle and streaming media:
|
||||
|
||||
- `thread/realtime/started` — `{ threadId, sessionId }` once realtime starts for the thread (experimental).
|
||||
- `thread/realtime/itemAdded` — `{ threadId, item }` for non-audio realtime items (experimental). `item` is forwarded as raw JSON while the upstream websocket item schema remains unstable.
|
||||
- `thread/realtime/outputAudio/delta` — `{ threadId, audio }` for streamed output audio chunks (experimental). `audio` uses camelCase fields (`data`, `sampleRate`, `numChannels`, `samplesPerChannel`).
|
||||
- `thread/realtime/error` — `{ threadId, message }` when realtime encounters a transport or backend error (experimental).
|
||||
- `thread/realtime/closed` — `{ threadId, reason }` when the realtime transport closes (experimental).
|
||||
|
||||
Because audio is intentionally separate from `ThreadItem`, clients can opt out of `thread/realtime/outputAudio/delta` independently with `optOutNotificationMethods`.
|
||||
|
||||
### Windows sandbox setup events
|
||||
|
||||
- `windowsSandbox/setupCompleted` — `{ mode, success, error }` after a `windowsSandbox/setupStart` request finishes.
|
||||
@@ -660,15 +695,15 @@ When an upstream HTTP status is available (for example, from the Responses API o
|
||||
Certain actions (shell commands or modifying files) may require explicit user approval depending on the user's config. When `turn/start` is used, the app-server drives an approval flow by sending a server-initiated JSON-RPC request to the client. The client must respond to tell Codex whether to proceed. UIs should present these requests inline with the active turn so users can review the proposed command or diff before choosing.
|
||||
|
||||
- Requests include `threadId` and `turnId`—use them to scope UI state to the active conversation.
|
||||
- Respond with a single `{ "decision": "accept" | "decline" }` payload (plus optional `acceptSettings` on command executions). The server resumes or declines the work and ends the item with `item/completed`.
|
||||
- Respond with a single `{ "decision": ... }` payload. Command approvals support `accept`, `acceptForSession`, `acceptWithExecpolicyAmendment`, `applyNetworkPolicyAmendment`, `decline`, or `cancel`. The server resumes or declines the work and ends the item with `item/completed`.
|
||||
|
||||
### Command execution approvals
|
||||
|
||||
Order of messages:
|
||||
|
||||
1. `item/started` — shows the pending `commandExecution` item with `command`, `cwd`, and other fields so you can render the proposed action.
|
||||
2. `item/commandExecution/requestApproval` (request) — carries the same `itemId`, `threadId`, `turnId`, optionally `approvalId` (for subcommand callbacks), and `reason`. For normal command approvals, it also includes `command`, `cwd`, and `commandActions` for friendly display. For network-only approvals, those command fields may be omitted and `networkApprovalContext` is provided instead.
|
||||
3. Client response — `{ "decision": "accept", "acceptSettings": { "forSession": false } }` or `{ "decision": "decline" }`.
|
||||
2. `item/commandExecution/requestApproval` (request) — carries the same `itemId`, `threadId`, `turnId`, optionally `approvalId` (for subcommand callbacks), and `reason`. For normal command approvals, it also includes `command`, `cwd`, and `commandActions` for friendly display. When `initialize.params.capabilities.experimentalApi = true`, it may also include experimental `additionalPermissions` describing requested per-command sandbox access. For network-only approvals, those command fields may be omitted and `networkApprovalContext` is provided instead. Optional persistence hints may also be included via `proposedExecpolicyAmendment` and `proposedNetworkPolicyAmendments`.
|
||||
3. Client response — for example `{ "decision": "accept" }`, `{ "decision": "acceptForSession" }`, `{ "decision": { "acceptWithExecpolicyAmendment": { "execpolicy_amendment": [...] } } }`, `{ "decision": { "applyNetworkPolicyAmendment": { "network_policy_amendment": { "host": "example.com", "action": "allow" } } } }`, `{ "decision": "decline" }`, or `{ "decision": "cancel" }`.
|
||||
4. `item/completed` — final `commandExecution` item with `status: "completed" | "failed" | "declined"` and execution output. Render this as the authoritative result.
|
||||
|
||||
### File change approvals
|
||||
@@ -702,6 +737,13 @@ When a dynamic tool is invoked during a turn, the server sends an `item/tool/cal
|
||||
}
|
||||
```
|
||||
|
||||
The server also emits item lifecycle notifications around the request:
|
||||
|
||||
1. `item/started` with `item.type = "dynamicToolCall"`, `status = "inProgress"`, plus `tool` and `arguments`.
|
||||
2. `item/tool/call` request.
|
||||
3. Client response.
|
||||
4. `item/completed` with `item.type = "dynamicToolCall"`, final `status`, and the returned `contentItems`/`success`.
|
||||
|
||||
The client must respond with content items. Use `inputText` for text and `inputImage` for image URLs/data URLs:
|
||||
|
||||
```json
|
||||
@@ -1072,6 +1114,8 @@ At runtime, clients must send `initialize` with `capabilities.experimentalApi =
|
||||
|
||||
3. In `app-server-protocol/src/protocol/common.rs`, keep the method stable and use `inspect_params: true` when only some fields are experimental (like `thread/start`). If the entire method is experimental, annotate the method variant with `#[experimental("method/name")]`.
|
||||
|
||||
For server-initiated request payloads, annotate the field the same way so schema generation treats it as experimental, and make sure app-server omits that field when the client did not opt into `experimentalApi`.
|
||||
|
||||
4. Regenerate protocol fixtures:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::thread_state::TurnSummary;
|
||||
use crate::thread_status::ThreadWatchActiveGuard;
|
||||
use crate::thread_status::ThreadWatchManager;
|
||||
use codex_app_server_protocol::AccountRateLimitsUpdatedNotification;
|
||||
use codex_app_server_protocol::AdditionalPermissionProfile as V2AdditionalPermissionProfile;
|
||||
use codex_app_server_protocol::AgentMessageDeltaNotification;
|
||||
use codex_app_server_protocol::ApplyPatchApprovalParams;
|
||||
use codex_app_server_protocol::ApplyPatchApprovalResponse;
|
||||
@@ -26,7 +27,9 @@ use codex_app_server_protocol::CommandExecutionRequestApprovalResponse;
|
||||
use codex_app_server_protocol::CommandExecutionStatus;
|
||||
use codex_app_server_protocol::ContextCompactedNotification;
|
||||
use codex_app_server_protocol::DeprecationNoticeNotification;
|
||||
use codex_app_server_protocol::DynamicToolCallOutputContentItem;
|
||||
use codex_app_server_protocol::DynamicToolCallParams;
|
||||
use codex_app_server_protocol::DynamicToolCallStatus;
|
||||
use codex_app_server_protocol::ErrorNotification;
|
||||
use codex_app_server_protocol::ExecCommandApprovalParams;
|
||||
use codex_app_server_protocol::ExecCommandApprovalResponse;
|
||||
@@ -45,6 +48,8 @@ use codex_app_server_protocol::McpToolCallResult;
|
||||
use codex_app_server_protocol::McpToolCallStatus;
|
||||
use codex_app_server_protocol::ModelReroutedNotification;
|
||||
use codex_app_server_protocol::NetworkApprovalContext as V2NetworkApprovalContext;
|
||||
use codex_app_server_protocol::NetworkPolicyAmendment as V2NetworkPolicyAmendment;
|
||||
use codex_app_server_protocol::NetworkPolicyRuleAction as V2NetworkPolicyRuleAction;
|
||||
use codex_app_server_protocol::PatchApplyStatus;
|
||||
use codex_app_server_protocol::PlanDeltaNotification;
|
||||
use codex_app_server_protocol::RawResponseItemCompletedNotification;
|
||||
@@ -53,9 +58,17 @@ use codex_app_server_protocol::ReasoningSummaryTextDeltaNotification;
|
||||
use codex_app_server_protocol::ReasoningTextDeltaNotification;
|
||||
use codex_app_server_protocol::ServerNotification;
|
||||
use codex_app_server_protocol::ServerRequestPayload;
|
||||
use codex_app_server_protocol::SkillApprovalDecision as V2SkillApprovalDecision;
|
||||
use codex_app_server_protocol::SkillRequestApprovalParams;
|
||||
use codex_app_server_protocol::SkillRequestApprovalResponse;
|
||||
use codex_app_server_protocol::TerminalInteractionNotification;
|
||||
use codex_app_server_protocol::ThreadItem;
|
||||
use codex_app_server_protocol::ThreadNameUpdatedNotification;
|
||||
use codex_app_server_protocol::ThreadRealtimeClosedNotification;
|
||||
use codex_app_server_protocol::ThreadRealtimeErrorNotification;
|
||||
use codex_app_server_protocol::ThreadRealtimeItemAddedNotification;
|
||||
use codex_app_server_protocol::ThreadRealtimeOutputAudioDeltaNotification;
|
||||
use codex_app_server_protocol::ThreadRealtimeStartedNotification;
|
||||
use codex_app_server_protocol::ThreadRollbackResponse;
|
||||
use codex_app_server_protocol::ThreadTokenUsage;
|
||||
use codex_app_server_protocol::ThreadTokenUsageUpdatedNotification;
|
||||
@@ -91,12 +104,14 @@ use codex_protocol::protocol::ExecCommandEndEvent;
|
||||
use codex_protocol::protocol::McpToolCallBeginEvent;
|
||||
use codex_protocol::protocol::McpToolCallEndEvent;
|
||||
use codex_protocol::protocol::Op;
|
||||
use codex_protocol::protocol::RealtimeEvent;
|
||||
use codex_protocol::protocol::ReviewDecision;
|
||||
use codex_protocol::protocol::ReviewOutputEvent;
|
||||
use codex_protocol::protocol::TokenCountEvent;
|
||||
use codex_protocol::protocol::TurnDiffEvent;
|
||||
use codex_protocol::request_user_input::RequestUserInputAnswer as CoreRequestUserInputAnswer;
|
||||
use codex_protocol::request_user_input::RequestUserInputResponse as CoreRequestUserInputResponse;
|
||||
use codex_protocol::skill_approval::SkillApprovalResponse as CoreSkillApprovalResponse;
|
||||
use codex_shell_command::parse_command::shlex_join;
|
||||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
@@ -166,6 +181,73 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
.await;
|
||||
}
|
||||
}
|
||||
EventMsg::RealtimeConversationStarted(event) => {
|
||||
if let ApiVersion::V2 = api_version {
|
||||
let notification = ThreadRealtimeStartedNotification {
|
||||
thread_id: conversation_id.to_string(),
|
||||
session_id: event.session_id,
|
||||
};
|
||||
outgoing
|
||||
.send_server_notification(ServerNotification::ThreadRealtimeStarted(
|
||||
notification,
|
||||
))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
EventMsg::RealtimeConversationRealtime(event) => {
|
||||
if let ApiVersion::V2 = api_version {
|
||||
match event.payload {
|
||||
RealtimeEvent::SessionCreated { .. } => {}
|
||||
RealtimeEvent::SessionUpdated { .. } => {}
|
||||
RealtimeEvent::AudioOut(audio) => {
|
||||
let notification = ThreadRealtimeOutputAudioDeltaNotification {
|
||||
thread_id: conversation_id.to_string(),
|
||||
audio: audio.into(),
|
||||
};
|
||||
outgoing
|
||||
.send_server_notification(
|
||||
ServerNotification::ThreadRealtimeOutputAudioDelta(notification),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
RealtimeEvent::ConversationItemAdded(item) => {
|
||||
let notification = ThreadRealtimeItemAddedNotification {
|
||||
thread_id: conversation_id.to_string(),
|
||||
item,
|
||||
};
|
||||
outgoing
|
||||
.send_server_notification(ServerNotification::ThreadRealtimeItemAdded(
|
||||
notification,
|
||||
))
|
||||
.await;
|
||||
}
|
||||
RealtimeEvent::Error(message) => {
|
||||
let notification = ThreadRealtimeErrorNotification {
|
||||
thread_id: conversation_id.to_string(),
|
||||
message,
|
||||
};
|
||||
outgoing
|
||||
.send_server_notification(ServerNotification::ThreadRealtimeError(
|
||||
notification,
|
||||
))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EventMsg::RealtimeConversationClosed(event) => {
|
||||
if let ApiVersion::V2 = api_version {
|
||||
let notification = ThreadRealtimeClosedNotification {
|
||||
thread_id: conversation_id.to_string(),
|
||||
reason: event.reason,
|
||||
};
|
||||
outgoing
|
||||
.send_server_notification(ServerNotification::ThreadRealtimeClosed(
|
||||
notification,
|
||||
))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
EventMsg::ApplyPatchApprovalRequest(ApplyPatchApprovalRequestEvent {
|
||||
call_id,
|
||||
turn_id,
|
||||
@@ -263,6 +345,8 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
reason,
|
||||
network_approval_context,
|
||||
proposed_execpolicy_amendment,
|
||||
proposed_network_policy_amendments,
|
||||
additional_permissions,
|
||||
parsed_cmd,
|
||||
..
|
||||
} = ev;
|
||||
@@ -325,6 +409,15 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
};
|
||||
let proposed_execpolicy_amendment_v2 =
|
||||
proposed_execpolicy_amendment.map(V2ExecPolicyAmendment::from);
|
||||
let proposed_network_policy_amendments_v2 = proposed_network_policy_amendments
|
||||
.map(|amendments| {
|
||||
amendments
|
||||
.into_iter()
|
||||
.map(V2NetworkPolicyAmendment::from)
|
||||
.collect()
|
||||
});
|
||||
let additional_permissions =
|
||||
additional_permissions.map(V2AdditionalPermissionProfile::from);
|
||||
|
||||
let params = CommandExecutionRequestApprovalParams {
|
||||
thread_id: conversation_id.to_string(),
|
||||
@@ -336,7 +429,9 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
command,
|
||||
cwd,
|
||||
command_actions,
|
||||
additional_permissions,
|
||||
proposed_execpolicy_amendment: proposed_execpolicy_amendment_v2,
|
||||
proposed_network_policy_amendments: proposed_network_policy_amendments_v2,
|
||||
};
|
||||
let rx = outgoing
|
||||
.send_request(ServerRequestPayload::CommandExecutionRequestApproval(
|
||||
@@ -423,15 +518,66 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
}
|
||||
}
|
||||
}
|
||||
EventMsg::SkillRequestApproval(request) => {
|
||||
if matches!(api_version, ApiVersion::V2) {
|
||||
let item_id = request.item_id;
|
||||
let skill_name = request.skill_name;
|
||||
let params = SkillRequestApprovalParams {
|
||||
item_id: item_id.clone(),
|
||||
skill_name,
|
||||
};
|
||||
let rx = outgoing
|
||||
.send_request(ServerRequestPayload::SkillRequestApproval(params))
|
||||
.await;
|
||||
tokio::spawn(async move {
|
||||
let approved = match rx.await {
|
||||
Ok(Ok(value)) => {
|
||||
serde_json::from_value::<SkillRequestApprovalResponse>(value)
|
||||
.map(|response| {
|
||||
matches!(response.decision, V2SkillApprovalDecision::Approve)
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
let _ = conversation
|
||||
.submit(Op::SkillApproval {
|
||||
id: item_id,
|
||||
response: CoreSkillApprovalResponse { approved },
|
||||
})
|
||||
.await;
|
||||
});
|
||||
}
|
||||
}
|
||||
EventMsg::DynamicToolCallRequest(request) => {
|
||||
if matches!(api_version, ApiVersion::V2) {
|
||||
let call_id = request.call_id;
|
||||
let turn_id = request.turn_id;
|
||||
let tool = request.tool;
|
||||
let arguments = request.arguments;
|
||||
let item = ThreadItem::DynamicToolCall {
|
||||
id: call_id.clone(),
|
||||
tool: tool.clone(),
|
||||
arguments: arguments.clone(),
|
||||
status: DynamicToolCallStatus::InProgress,
|
||||
content_items: None,
|
||||
success: None,
|
||||
duration_ms: None,
|
||||
};
|
||||
let notification = ItemStartedNotification {
|
||||
thread_id: conversation_id.to_string(),
|
||||
turn_id: turn_id.clone(),
|
||||
item,
|
||||
};
|
||||
outgoing
|
||||
.send_server_notification(ServerNotification::ItemStarted(notification))
|
||||
.await;
|
||||
let params = DynamicToolCallParams {
|
||||
thread_id: conversation_id.to_string(),
|
||||
turn_id: request.turn_id,
|
||||
turn_id: turn_id.clone(),
|
||||
call_id: call_id.clone(),
|
||||
tool: request.tool,
|
||||
arguments: request.arguments,
|
||||
tool: tool.clone(),
|
||||
arguments: arguments.clone(),
|
||||
};
|
||||
let rx = outgoing
|
||||
.send_request(ServerRequestPayload::DynamicToolCall(params))
|
||||
@@ -458,6 +604,46 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
.await;
|
||||
}
|
||||
}
|
||||
EventMsg::DynamicToolCallResponse(response) => {
|
||||
if matches!(api_version, ApiVersion::V2) {
|
||||
let status = if response.success {
|
||||
DynamicToolCallStatus::Completed
|
||||
} else {
|
||||
DynamicToolCallStatus::Failed
|
||||
};
|
||||
let duration_ms = i64::try_from(response.duration.as_millis()).ok();
|
||||
let item = ThreadItem::DynamicToolCall {
|
||||
id: response.call_id,
|
||||
tool: response.tool,
|
||||
arguments: response.arguments,
|
||||
status,
|
||||
content_items: Some(
|
||||
response
|
||||
.content_items
|
||||
.into_iter()
|
||||
.map(|item| match item {
|
||||
CoreDynamicToolCallOutputContentItem::InputText { text } => {
|
||||
DynamicToolCallOutputContentItem::InputText { text }
|
||||
}
|
||||
CoreDynamicToolCallOutputContentItem::InputImage { image_url } => {
|
||||
DynamicToolCallOutputContentItem::InputImage { image_url }
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
success: Some(response.success),
|
||||
duration_ms,
|
||||
};
|
||||
let notification = ItemCompletedNotification {
|
||||
thread_id: conversation_id.to_string(),
|
||||
turn_id: response.turn_id,
|
||||
item,
|
||||
};
|
||||
outgoing
|
||||
.send_server_notification(ServerNotification::ItemCompleted(notification))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
// TODO(celia): properly construct McpToolCall TurnItem in core.
|
||||
EventMsg::McpToolCallBegin(begin_event) => {
|
||||
let notification = construct_mcp_tool_call_notification(
|
||||
@@ -1875,6 +2061,20 @@ async fn on_command_execution_request_approval_response(
|
||||
},
|
||||
None,
|
||||
),
|
||||
CommandExecutionApprovalDecision::ApplyNetworkPolicyAmendment {
|
||||
network_policy_amendment,
|
||||
} => {
|
||||
let completion_status = match network_policy_amendment.action {
|
||||
V2NetworkPolicyRuleAction::Allow => None,
|
||||
V2NetworkPolicyRuleAction::Deny => Some(CommandExecutionStatus::Declined),
|
||||
};
|
||||
(
|
||||
ReviewDecision::NetworkPolicyAmendment {
|
||||
network_policy_amendment: network_policy_amendment.into_core(),
|
||||
},
|
||||
completion_status,
|
||||
)
|
||||
}
|
||||
CommandExecutionApprovalDecision::Decline => (
|
||||
ReviewDecision::Denied,
|
||||
Some(CommandExecutionStatus::Declined),
|
||||
|
||||
@@ -131,6 +131,7 @@ 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::ThreadHistoryBuilder;
|
||||
use codex_app_server_protocol::ThreadItem;
|
||||
use codex_app_server_protocol::ThreadListParams;
|
||||
use codex_app_server_protocol::ThreadListResponse;
|
||||
@@ -138,6 +139,14 @@ use codex_app_server_protocol::ThreadLoadedListParams;
|
||||
use codex_app_server_protocol::ThreadLoadedListResponse;
|
||||
use codex_app_server_protocol::ThreadReadParams;
|
||||
use codex_app_server_protocol::ThreadReadResponse;
|
||||
use codex_app_server_protocol::ThreadRealtimeAppendAudioParams;
|
||||
use codex_app_server_protocol::ThreadRealtimeAppendAudioResponse;
|
||||
use codex_app_server_protocol::ThreadRealtimeAppendTextParams;
|
||||
use codex_app_server_protocol::ThreadRealtimeAppendTextResponse;
|
||||
use codex_app_server_protocol::ThreadRealtimeStartParams;
|
||||
use codex_app_server_protocol::ThreadRealtimeStartResponse;
|
||||
use codex_app_server_protocol::ThreadRealtimeStopParams;
|
||||
use codex_app_server_protocol::ThreadRealtimeStopResponse;
|
||||
use codex_app_server_protocol::ThreadResumeParams;
|
||||
use codex_app_server_protocol::ThreadResumeResponse;
|
||||
use codex_app_server_protocol::ThreadRollbackParams;
|
||||
@@ -168,6 +177,7 @@ use codex_app_server_protocol::WindowsSandboxSetupMode;
|
||||
use codex_app_server_protocol::WindowsSandboxSetupStartParams;
|
||||
use codex_app_server_protocol::WindowsSandboxSetupStartResponse;
|
||||
use codex_app_server_protocol::build_turns_from_rollout_items;
|
||||
use codex_arg0::Arg0DispatchPaths;
|
||||
use codex_backend_client::Client as BackendClient;
|
||||
use codex_chatgpt::connectors;
|
||||
use codex_cloud_requirements::cloud_requirements_loader;
|
||||
@@ -189,6 +199,7 @@ use codex_core::auth::login_with_chatgpt_auth_tokens;
|
||||
use codex_core::config::Config;
|
||||
use codex_core::config::ConfigOverrides;
|
||||
use codex_core::config::ConfigService;
|
||||
use codex_core::config::NetworkProxyAuditMetadata;
|
||||
use codex_core::config::edit::ConfigEdit;
|
||||
use codex_core::config::edit::ConfigEditsBuilder;
|
||||
use codex_core::config::types::McpServerTransportConfig;
|
||||
@@ -233,6 +244,9 @@ use codex_protocol::dynamic_tools::DynamicToolSpec as CoreDynamicToolSpec;
|
||||
use codex_protocol::items::TurnItem;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::protocol::AgentStatus;
|
||||
use codex_protocol::protocol::ConversationAudioParams;
|
||||
use codex_protocol::protocol::ConversationStartParams;
|
||||
use codex_protocol::protocol::ConversationTextParams;
|
||||
use codex_protocol::protocol::EventMsg;
|
||||
use codex_protocol::protocol::GitInfo as CoreGitInfo;
|
||||
use codex_protocol::protocol::InitialHistory;
|
||||
@@ -269,6 +283,7 @@ use std::time::SystemTime;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::sync::broadcast;
|
||||
use tokio::sync::oneshot;
|
||||
use tokio::sync::watch;
|
||||
use toml::Value as TomlValue;
|
||||
use tracing::error;
|
||||
use tracing::info;
|
||||
@@ -288,6 +303,7 @@ struct ThreadListFilters {
|
||||
source_kinds: Option<Vec<ThreadSourceKind>>,
|
||||
archived: bool,
|
||||
cwd: Option<PathBuf>,
|
||||
search_term: Option<String>,
|
||||
}
|
||||
|
||||
// Duration before a ChatGPT login attempt is abandoned.
|
||||
@@ -337,7 +353,7 @@ pub(crate) struct CodexMessageProcessor {
|
||||
auth_manager: Arc<AuthManager>,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
codex_linux_sandbox_exe: Option<PathBuf>,
|
||||
arg0_paths: Arg0DispatchPaths,
|
||||
config: Arc<Config>,
|
||||
single_client_mode: bool,
|
||||
cli_overrides: Vec<(String, TomlValue)>,
|
||||
@@ -361,7 +377,7 @@ pub(crate) struct CodexMessageProcessorArgs {
|
||||
pub(crate) auth_manager: Arc<AuthManager>,
|
||||
pub(crate) thread_manager: Arc<ThreadManager>,
|
||||
pub(crate) outgoing: Arc<OutgoingMessageSender>,
|
||||
pub(crate) codex_linux_sandbox_exe: Option<PathBuf>,
|
||||
pub(crate) arg0_paths: Arg0DispatchPaths,
|
||||
pub(crate) config: Arc<Config>,
|
||||
pub(crate) cli_overrides: Vec<(String, TomlValue)>,
|
||||
pub(crate) cloud_requirements: Arc<RwLock<CloudRequirementsLoader>>,
|
||||
@@ -398,7 +414,7 @@ impl CodexMessageProcessor {
|
||||
auth_manager,
|
||||
thread_manager,
|
||||
outgoing,
|
||||
codex_linux_sandbox_exe,
|
||||
arg0_paths,
|
||||
config,
|
||||
cli_overrides,
|
||||
cloud_requirements,
|
||||
@@ -409,7 +425,7 @@ impl CodexMessageProcessor {
|
||||
auth_manager,
|
||||
thread_manager,
|
||||
outgoing: outgoing.clone(),
|
||||
codex_linux_sandbox_exe,
|
||||
arg0_paths,
|
||||
config,
|
||||
single_client_mode,
|
||||
cli_overrides,
|
||||
@@ -425,7 +441,7 @@ impl CodexMessageProcessor {
|
||||
|
||||
async fn load_latest_config(&self) -> Result<Config, JSONRPCErrorError> {
|
||||
let cloud_requirements = self.current_cloud_requirements();
|
||||
codex_core::config::ConfigBuilder::default()
|
||||
let mut config = codex_core::config::ConfigBuilder::default()
|
||||
.cli_overrides(self.cli_overrides.clone())
|
||||
.cloud_requirements(cloud_requirements)
|
||||
.build()
|
||||
@@ -434,7 +450,10 @@ impl CodexMessageProcessor {
|
||||
code: INTERNAL_ERROR_CODE,
|
||||
message: format!("failed to reload config: {err}"),
|
||||
data: None,
|
||||
})
|
||||
})?;
|
||||
config.codex_linux_sandbox_exe = self.arg0_paths.codex_linux_sandbox_exe.clone();
|
||||
config.main_execve_wrapper_exe = self.arg0_paths.main_execve_wrapper_exe.clone();
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
fn current_cloud_requirements(&self) -> CloudRequirementsLoader {
|
||||
@@ -618,6 +637,22 @@ impl CodexMessageProcessor {
|
||||
self.turn_interrupt(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
}
|
||||
ClientRequest::ThreadRealtimeStart { request_id, params } => {
|
||||
self.thread_realtime_start(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
}
|
||||
ClientRequest::ThreadRealtimeAppendAudio { request_id, params } => {
|
||||
self.thread_realtime_append_audio(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
}
|
||||
ClientRequest::ThreadRealtimeAppendText { request_id, params } => {
|
||||
self.thread_realtime_append_text(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
}
|
||||
ClientRequest::ThreadRealtimeStop { request_id, params } => {
|
||||
self.thread_realtime_stop(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
}
|
||||
ClientRequest::ReviewStart { request_id, params } => {
|
||||
self.review_start(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
@@ -816,6 +851,10 @@ impl CodexMessageProcessor {
|
||||
ClientRequest::ConfigRequirementsRead { .. } => {
|
||||
warn!("ConfigRequirementsRead request reached CodexMessageProcessor unexpectedly");
|
||||
}
|
||||
ClientRequest::ExternalAgentConfigDetect { .. }
|
||||
| ClientRequest::ExternalAgentConfigImport { .. } => {
|
||||
warn!("ExternalAgentConfig request reached CodexMessageProcessor unexpectedly");
|
||||
}
|
||||
ClientRequest::GetAccountRateLimits {
|
||||
request_id,
|
||||
params: _,
|
||||
@@ -1741,6 +1780,7 @@ impl CodexMessageProcessor {
|
||||
None,
|
||||
None,
|
||||
managed_network_requirements_enabled,
|
||||
NetworkProxyAuditMetadata::default(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -1758,8 +1798,10 @@ impl CodexMessageProcessor {
|
||||
None => None,
|
||||
};
|
||||
let windows_sandbox_level = WindowsSandboxLevel::from_config(&self.config);
|
||||
let command = params.command;
|
||||
let exec_params = ExecParams {
|
||||
command: params.command,
|
||||
original_command: command.join(" "),
|
||||
command,
|
||||
cwd,
|
||||
expiration: timeout_ms.into(),
|
||||
env,
|
||||
@@ -1789,7 +1831,7 @@ impl CodexMessageProcessor {
|
||||
None => self.config.permissions.sandbox_policy.get().clone(),
|
||||
};
|
||||
|
||||
let codex_linux_sandbox_exe = self.config.codex_linux_sandbox_exe.clone();
|
||||
let codex_linux_sandbox_exe = self.arg0_paths.codex_linux_sandbox_exe.clone();
|
||||
let outgoing = self.outgoing.clone();
|
||||
let request_for_task = request;
|
||||
let sandbox_cwd = self.config.cwd.clone();
|
||||
@@ -1854,7 +1896,8 @@ impl CodexMessageProcessor {
|
||||
approval_policy,
|
||||
sandbox_mode,
|
||||
model_provider,
|
||||
codex_linux_sandbox_exe: self.codex_linux_sandbox_exe.clone(),
|
||||
codex_linux_sandbox_exe: self.arg0_paths.codex_linux_sandbox_exe.clone(),
|
||||
main_execve_wrapper_exe: self.arg0_paths.main_execve_wrapper_exe.clone(),
|
||||
base_instructions,
|
||||
developer_instructions,
|
||||
compact_prompt,
|
||||
@@ -1948,6 +1991,7 @@ impl CodexMessageProcessor {
|
||||
approval_policy,
|
||||
sandbox,
|
||||
config,
|
||||
service_name,
|
||||
base_instructions,
|
||||
developer_instructions,
|
||||
dynamic_tools,
|
||||
@@ -2015,7 +2059,12 @@ impl CodexMessageProcessor {
|
||||
|
||||
match self
|
||||
.thread_manager
|
||||
.start_thread_with_tools(config, core_dynamic_tools, persist_extended_history)
|
||||
.start_thread_with_tools_and_service_name(
|
||||
config,
|
||||
core_dynamic_tools,
|
||||
persist_extended_history,
|
||||
service_name,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(new_conv) => {
|
||||
@@ -2108,7 +2157,8 @@ impl CodexMessageProcessor {
|
||||
approval_policy: approval_policy
|
||||
.map(codex_app_server_protocol::AskForApproval::to_core),
|
||||
sandbox_mode: sandbox.map(SandboxMode::to_core),
|
||||
codex_linux_sandbox_exe: self.codex_linux_sandbox_exe.clone(),
|
||||
codex_linux_sandbox_exe: self.arg0_paths.codex_linux_sandbox_exe.clone(),
|
||||
main_execve_wrapper_exe: self.arg0_paths.main_execve_wrapper_exe.clone(),
|
||||
base_instructions,
|
||||
developer_instructions,
|
||||
personality,
|
||||
@@ -2188,7 +2238,7 @@ impl CodexMessageProcessor {
|
||||
return;
|
||||
};
|
||||
|
||||
let (_, thread) = match self.load_thread(&thread_id).await {
|
||||
let (thread_id, thread) = match self.load_thread(&thread_id).await {
|
||||
Ok(v) => v,
|
||||
Err(error) => {
|
||||
self.outgoing.send_error(request_id, error).await;
|
||||
@@ -2196,17 +2246,54 @@ impl CodexMessageProcessor {
|
||||
}
|
||||
};
|
||||
|
||||
let expected_name = name.clone();
|
||||
|
||||
if let Err(err) = thread.submit(Op::SetThreadName { name }).await {
|
||||
self.send_internal_error(request_id, format!("failed to set thread name: {err}"))
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(err) = self
|
||||
.wait_for_thread_name_persisted(thread_id, &expected_name)
|
||||
.await
|
||||
{
|
||||
self.send_internal_error(
|
||||
request_id,
|
||||
format!("failed to observe persisted thread name: {err}"),
|
||||
)
|
||||
.await;
|
||||
return;
|
||||
}
|
||||
|
||||
self.outgoing
|
||||
.send_response(request_id, ThreadSetNameResponse {})
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn wait_for_thread_name_persisted(
|
||||
&self,
|
||||
thread_id: ThreadId,
|
||||
expected_name: &str,
|
||||
) -> std::io::Result<()> {
|
||||
let codex_home = self.config.codex_home.clone();
|
||||
tokio::time::timeout(Duration::from_secs(2), async {
|
||||
loop {
|
||||
match find_thread_name_by_id(&codex_home, &thread_id).await? {
|
||||
Some(name) if name == expected_name => return Ok(()),
|
||||
_ => tokio::time::sleep(Duration::from_millis(10)).await,
|
||||
}
|
||||
}
|
||||
})
|
||||
.await
|
||||
.map_err(|_| {
|
||||
std::io::Error::new(
|
||||
std::io::ErrorKind::TimedOut,
|
||||
format!("timed out waiting for thread name {expected_name:?}"),
|
||||
)
|
||||
})?
|
||||
}
|
||||
|
||||
async fn thread_unarchive(
|
||||
&mut self,
|
||||
request_id: ConnectionRequestId,
|
||||
@@ -2522,6 +2609,7 @@ impl CodexMessageProcessor {
|
||||
source_kinds,
|
||||
archived,
|
||||
cwd,
|
||||
search_term,
|
||||
} = params;
|
||||
|
||||
let requested_page_size = limit
|
||||
@@ -2542,6 +2630,7 @@ impl CodexMessageProcessor {
|
||||
source_kinds,
|
||||
archived: archived.unwrap_or(false),
|
||||
cwd: cwd.map(PathBuf::from),
|
||||
search_term,
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -2794,6 +2883,10 @@ impl CodexMessageProcessor {
|
||||
.await;
|
||||
}
|
||||
|
||||
pub(crate) fn subscribe_running_assistant_turn_count(&self) -> watch::Receiver<usize> {
|
||||
self.thread_watch_manager.subscribe_running_turn_count()
|
||||
}
|
||||
|
||||
/// Best-effort: ensure initialized connections are subscribed to this thread.
|
||||
pub(crate) async fn try_attach_thread_listener(
|
||||
&mut self,
|
||||
@@ -3269,6 +3362,7 @@ impl CodexMessageProcessor {
|
||||
let ThreadForkParams {
|
||||
thread_id,
|
||||
path,
|
||||
fork_after_turn_id,
|
||||
model,
|
||||
model_provider,
|
||||
cwd,
|
||||
@@ -3382,21 +3476,71 @@ impl CodexMessageProcessor {
|
||||
};
|
||||
|
||||
let fallback_model_provider = config.model_provider_id.clone();
|
||||
let anchored_fork_history = if let Some(fork_after_turn_id) = fork_after_turn_id.as_deref()
|
||||
{
|
||||
let source_items = match read_rollout_items_from_rollout(rollout_path.as_path()).await {
|
||||
Ok(items) => items,
|
||||
Err(err) => {
|
||||
let (code, message) = match err.kind() {
|
||||
std::io::ErrorKind::NotFound => (
|
||||
INVALID_REQUEST_ERROR_CODE,
|
||||
format!("failed to load rollout `{}`: {err}", rollout_path.display()),
|
||||
),
|
||||
_ => (
|
||||
INTERNAL_ERROR_CODE,
|
||||
format!(
|
||||
"failed to read rollout `{}` for thread fork: {err}",
|
||||
rollout_path.display()
|
||||
),
|
||||
),
|
||||
};
|
||||
let error = JSONRPCErrorError {
|
||||
code,
|
||||
message,
|
||||
data: None,
|
||||
};
|
||||
self.outgoing.send_error(request_id, error).await;
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match resolve_thread_fork_history_from_anchor(
|
||||
source_items.as_slice(),
|
||||
fork_after_turn_id,
|
||||
) {
|
||||
Ok(history_items) => Some(InitialHistory::Forked(history_items)),
|
||||
Err(message) => {
|
||||
self.send_invalid_request_error(request_id, message).await;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let NewThread {
|
||||
thread_id,
|
||||
session_configured,
|
||||
..
|
||||
} = match self
|
||||
.thread_manager
|
||||
.fork_thread(
|
||||
usize::MAX,
|
||||
config,
|
||||
rollout_path.clone(),
|
||||
persist_extended_history,
|
||||
)
|
||||
.await
|
||||
{
|
||||
} = match if let Some(initial_history) = anchored_fork_history {
|
||||
self.thread_manager
|
||||
.resume_thread_with_history(
|
||||
config,
|
||||
initial_history,
|
||||
self.auth_manager.clone(),
|
||||
persist_extended_history,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
self.thread_manager
|
||||
.fork_thread(
|
||||
usize::MAX,
|
||||
config,
|
||||
rollout_path.clone(),
|
||||
persist_extended_history,
|
||||
)
|
||||
.await
|
||||
} {
|
||||
Ok(thread) => thread,
|
||||
Err(err) => {
|
||||
let (code, message) = match err {
|
||||
@@ -3599,6 +3743,7 @@ impl CodexMessageProcessor {
|
||||
source_kinds: None,
|
||||
archived: false,
|
||||
cwd: None,
|
||||
search_term: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
@@ -3625,6 +3770,7 @@ impl CodexMessageProcessor {
|
||||
source_kinds,
|
||||
archived,
|
||||
cwd,
|
||||
search_term,
|
||||
} = filters;
|
||||
let mut cursor_obj: Option<RolloutCursor> = match cursor.as_ref() {
|
||||
Some(cursor_str) => {
|
||||
@@ -3667,6 +3813,7 @@ impl CodexMessageProcessor {
|
||||
allowed_sources,
|
||||
model_provider_filter.as_deref(),
|
||||
fallback_provider.as_str(),
|
||||
search_term.as_deref(),
|
||||
)
|
||||
.await
|
||||
.map_err(|err| JSONRPCErrorError {
|
||||
@@ -3683,6 +3830,7 @@ impl CodexMessageProcessor {
|
||||
allowed_sources,
|
||||
model_provider_filter.as_deref(),
|
||||
fallback_provider.as_str(),
|
||||
search_term.as_deref(),
|
||||
)
|
||||
.await
|
||||
.map_err(|err| JSONRPCErrorError {
|
||||
@@ -4318,7 +4466,8 @@ impl CodexMessageProcessor {
|
||||
approval_policy,
|
||||
sandbox_mode,
|
||||
model_provider,
|
||||
codex_linux_sandbox_exe: self.codex_linux_sandbox_exe.clone(),
|
||||
codex_linux_sandbox_exe: self.arg0_paths.codex_linux_sandbox_exe.clone(),
|
||||
main_execve_wrapper_exe: self.arg0_paths.main_execve_wrapper_exe.clone(),
|
||||
base_instructions,
|
||||
developer_instructions,
|
||||
compact_prompt,
|
||||
@@ -4329,7 +4478,8 @@ impl CodexMessageProcessor {
|
||||
}
|
||||
None => (
|
||||
ConfigOverrides {
|
||||
codex_linux_sandbox_exe: self.codex_linux_sandbox_exe.clone(),
|
||||
codex_linux_sandbox_exe: self.arg0_paths.codex_linux_sandbox_exe.clone(),
|
||||
main_execve_wrapper_exe: self.arg0_paths.main_execve_wrapper_exe.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
None,
|
||||
@@ -4513,7 +4663,8 @@ impl CodexMessageProcessor {
|
||||
approval_policy,
|
||||
sandbox_mode,
|
||||
model_provider,
|
||||
codex_linux_sandbox_exe: self.codex_linux_sandbox_exe.clone(),
|
||||
codex_linux_sandbox_exe: self.arg0_paths.codex_linux_sandbox_exe.clone(),
|
||||
main_execve_wrapper_exe: self.arg0_paths.main_execve_wrapper_exe.clone(),
|
||||
base_instructions,
|
||||
developer_instructions,
|
||||
compact_prompt,
|
||||
@@ -4525,7 +4676,8 @@ impl CodexMessageProcessor {
|
||||
}
|
||||
None => (
|
||||
ConfigOverrides {
|
||||
codex_linux_sandbox_exe: self.codex_linux_sandbox_exe.clone(),
|
||||
codex_linux_sandbox_exe: self.arg0_paths.codex_linux_sandbox_exe.clone(),
|
||||
main_execve_wrapper_exe: self.arg0_paths.main_execve_wrapper_exe.clone(),
|
||||
..Default::default()
|
||||
},
|
||||
None,
|
||||
@@ -5482,6 +5634,177 @@ impl CodexMessageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
async fn prepare_realtime_conversation_thread(
|
||||
&mut self,
|
||||
request_id: ConnectionRequestId,
|
||||
thread_id: &str,
|
||||
) -> Option<(ThreadId, Arc<CodexThread>)> {
|
||||
let (thread_id, thread) = match self.load_thread(thread_id).await {
|
||||
Ok(v) => v,
|
||||
Err(error) => {
|
||||
self.outgoing.send_error(request_id, error).await;
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(error) = self
|
||||
.ensure_conversation_listener(
|
||||
thread_id,
|
||||
request_id.connection_id,
|
||||
false,
|
||||
ApiVersion::V2,
|
||||
)
|
||||
.await
|
||||
{
|
||||
self.outgoing.send_error(request_id, error).await;
|
||||
return None;
|
||||
}
|
||||
|
||||
if !thread.enabled(Feature::RealtimeConversation) {
|
||||
self.send_invalid_request_error(
|
||||
request_id,
|
||||
format!("thread {thread_id} does not support realtime conversation"),
|
||||
)
|
||||
.await;
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((thread_id, thread))
|
||||
}
|
||||
|
||||
async fn thread_realtime_start(
|
||||
&mut self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ThreadRealtimeStartParams,
|
||||
) {
|
||||
let Some((_, thread)) = self
|
||||
.prepare_realtime_conversation_thread(request_id.clone(), ¶ms.thread_id)
|
||||
.await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let submit = thread
|
||||
.submit(Op::RealtimeConversationStart(ConversationStartParams {
|
||||
prompt: params.prompt,
|
||||
session_id: params.session_id,
|
||||
}))
|
||||
.await;
|
||||
|
||||
match submit {
|
||||
Ok(_) => {
|
||||
self.outgoing
|
||||
.send_response(request_id, ThreadRealtimeStartResponse::default())
|
||||
.await;
|
||||
}
|
||||
Err(err) => {
|
||||
self.send_internal_error(
|
||||
request_id,
|
||||
format!("failed to start realtime conversation: {err}"),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn thread_realtime_append_audio(
|
||||
&mut self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ThreadRealtimeAppendAudioParams,
|
||||
) {
|
||||
let Some((_, thread)) = self
|
||||
.prepare_realtime_conversation_thread(request_id.clone(), ¶ms.thread_id)
|
||||
.await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let submit = thread
|
||||
.submit(Op::RealtimeConversationAudio(ConversationAudioParams {
|
||||
frame: params.audio.into(),
|
||||
}))
|
||||
.await;
|
||||
|
||||
match submit {
|
||||
Ok(_) => {
|
||||
self.outgoing
|
||||
.send_response(request_id, ThreadRealtimeAppendAudioResponse::default())
|
||||
.await;
|
||||
}
|
||||
Err(err) => {
|
||||
self.send_internal_error(
|
||||
request_id,
|
||||
format!("failed to append realtime conversation audio: {err}"),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn thread_realtime_append_text(
|
||||
&mut self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ThreadRealtimeAppendTextParams,
|
||||
) {
|
||||
let Some((_, thread)) = self
|
||||
.prepare_realtime_conversation_thread(request_id.clone(), ¶ms.thread_id)
|
||||
.await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let submit = thread
|
||||
.submit(Op::RealtimeConversationText(ConversationTextParams {
|
||||
text: params.text,
|
||||
}))
|
||||
.await;
|
||||
|
||||
match submit {
|
||||
Ok(_) => {
|
||||
self.outgoing
|
||||
.send_response(request_id, ThreadRealtimeAppendTextResponse::default())
|
||||
.await;
|
||||
}
|
||||
Err(err) => {
|
||||
self.send_internal_error(
|
||||
request_id,
|
||||
format!("failed to append realtime conversation text: {err}"),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn thread_realtime_stop(
|
||||
&mut self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ThreadRealtimeStopParams,
|
||||
) {
|
||||
let Some((_, thread)) = self
|
||||
.prepare_realtime_conversation_thread(request_id.clone(), ¶ms.thread_id)
|
||||
.await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let submit = thread.submit(Op::RealtimeConversationClose).await;
|
||||
|
||||
match submit {
|
||||
Ok(_) => {
|
||||
self.outgoing
|
||||
.send_response(request_id, ThreadRealtimeStopResponse::default())
|
||||
.await;
|
||||
}
|
||||
Err(err) => {
|
||||
self.send_internal_error(
|
||||
request_id,
|
||||
format!("failed to stop realtime conversation: {err}"),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn build_review_turn(turn_id: String, display_text: &str) -> Turn {
|
||||
let items = if display_text.is_empty() {
|
||||
Vec::new()
|
||||
@@ -5897,6 +6220,11 @@ impl CodexMessageProcessor {
|
||||
EventMsg::TurnComplete(_) => "task_complete",
|
||||
_ => &event.msg.to_string(),
|
||||
};
|
||||
let request_event_name = format!("codex/event/{event_formatted}");
|
||||
tracing::trace!(
|
||||
conversation_id = %conversation_id,
|
||||
"app-server event: {request_event_name}"
|
||||
);
|
||||
let mut params = match serde_json::to_value(event.clone()) {
|
||||
Ok(serde_json::Value::Object(map)) => map,
|
||||
Ok(_) => {
|
||||
@@ -5931,7 +6259,7 @@ impl CodexMessageProcessor {
|
||||
.send_notification_to_connections(
|
||||
&subscribed_connection_ids,
|
||||
OutgoingNotification {
|
||||
method: format!("codex/event/{event_formatted}"),
|
||||
method: request_event_name,
|
||||
params: Some(params.into()),
|
||||
},
|
||||
)
|
||||
@@ -6514,7 +6842,7 @@ fn skills_to_info(
|
||||
skills
|
||||
.iter()
|
||||
.map(|skill| {
|
||||
let enabled = !disabled_paths.contains(&skill.path);
|
||||
let enabled = !disabled_paths.contains(&skill.path_to_skills_md);
|
||||
codex_app_server_protocol::SkillMetadata {
|
||||
name: skill.name.clone(),
|
||||
description: skill.description.clone(),
|
||||
@@ -6545,7 +6873,7 @@ fn skills_to_info(
|
||||
.collect(),
|
||||
}
|
||||
}),
|
||||
path: skill.path.clone(),
|
||||
path: skill.path_to_skills_md.clone(),
|
||||
scope: skill.scope.into(),
|
||||
enabled,
|
||||
}
|
||||
@@ -6630,6 +6958,112 @@ async fn sync_default_client_residency_requirement(
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the exact rollout prefix that should seed a turn-anchored `thread/fork`.
|
||||
///
|
||||
/// The selected turn stays in the returned history, while every later turn is removed. The helper
|
||||
/// validates that the anchor is a stable, already-materialized exchange: legacy replay-synthesized
|
||||
/// ids are rejected, the turn must not still be in progress, and the turn must include both a
|
||||
/// user message and an agent response. The cutoff uses both the next explicit `TurnStarted` event
|
||||
/// and the next user-message boundary so the fork cannot accidentally retain trailing non-user
|
||||
/// events that conceptually belong to a later turn.
|
||||
fn resolve_thread_fork_history_from_anchor(
|
||||
rollout_items: &[RolloutItem],
|
||||
fork_after_turn_id: &str,
|
||||
) -> Result<Vec<RolloutItem>, String> {
|
||||
let mut history_builder = ThreadHistoryBuilder::new();
|
||||
for item in rollout_items {
|
||||
history_builder.handle_rollout_item(item);
|
||||
}
|
||||
if history_builder.has_synthetic_turn_ids() {
|
||||
return Err(
|
||||
"turn-based forking is not supported for legacy thread history; use full thread/fork"
|
||||
.to_string(),
|
||||
);
|
||||
}
|
||||
let turns = history_builder.finish();
|
||||
|
||||
let Some(target_turn_idx) = turns.iter().position(|turn| turn.id == fork_after_turn_id) else {
|
||||
return Err(format!(
|
||||
"fork turn not found in source thread history: {fork_after_turn_id}"
|
||||
));
|
||||
};
|
||||
let target_turn = &turns[target_turn_idx];
|
||||
let has_user_message = target_turn
|
||||
.items
|
||||
.iter()
|
||||
.any(|item| matches!(item, ThreadItem::UserMessage { .. }));
|
||||
let has_agent_message = target_turn
|
||||
.items
|
||||
.iter()
|
||||
.any(|item| matches!(item, ThreadItem::AgentMessage { .. }));
|
||||
|
||||
if matches!(target_turn.status, TurnStatus::InProgress) {
|
||||
return Err("fork turn must be completed/interrupted/failed, not in progress".to_string());
|
||||
}
|
||||
if !has_user_message {
|
||||
return Err("fork turn must contain a user message".to_string());
|
||||
}
|
||||
if !has_agent_message {
|
||||
return Err("fork turn must contain an agent message".to_string());
|
||||
}
|
||||
|
||||
let Some(next_turn) = turns.get(target_turn_idx.saturating_add(1)) else {
|
||||
return Ok(rollout_items.to_vec());
|
||||
};
|
||||
let next_turn_id = next_turn.id.as_str();
|
||||
|
||||
let next_turn_started_idx = rollout_items
|
||||
.iter()
|
||||
.position(|item| {
|
||||
matches!(
|
||||
item,
|
||||
RolloutItem::EventMsg(EventMsg::TurnStarted(payload))
|
||||
if payload.turn_id == next_turn_id
|
||||
)
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
format!("failed to locate boundary after fork turn: missing next turn `{next_turn_id}`")
|
||||
})?;
|
||||
|
||||
let target_terminal_idx = rollout_items.iter().rposition(|item| {
|
||||
matches!(
|
||||
item,
|
||||
RolloutItem::EventMsg(EventMsg::TurnComplete(payload))
|
||||
if payload.turn_id == fork_after_turn_id
|
||||
) || matches!(
|
||||
item,
|
||||
RolloutItem::EventMsg(EventMsg::TurnAborted(payload))
|
||||
if payload.turn_id.as_deref() == Some(fork_after_turn_id)
|
||||
)
|
||||
});
|
||||
|
||||
let next_user_boundary_idx = target_terminal_idx
|
||||
.and_then(|terminal_idx| {
|
||||
rollout_items
|
||||
.iter()
|
||||
.enumerate()
|
||||
.skip(terminal_idx.saturating_add(1))
|
||||
.find_map(|(idx, item)| is_user_turn_rollout_boundary(item).then_some(idx))
|
||||
})
|
||||
.unwrap_or(usize::MAX);
|
||||
let cut_idx = next_turn_started_idx.min(next_user_boundary_idx);
|
||||
|
||||
Ok(rollout_items[..cut_idx].to_vec())
|
||||
}
|
||||
|
||||
/// Return whether this rollout item starts a new user turn for truncation purposes.
|
||||
///
|
||||
/// Anchored forks use this as a fallback boundary when explicit turn lifecycle events are present
|
||||
/// but a later turn also emitted standalone user-message markers that should not leak into the
|
||||
/// forked prefix.
|
||||
fn is_user_turn_rollout_boundary(item: &RolloutItem) -> bool {
|
||||
match item {
|
||||
RolloutItem::ResponseItem(ResponseItem::Message { role, .. }) => role == "user",
|
||||
RolloutItem::EventMsg(EventMsg::UserMessage(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Derive the effective [`Config`] by layering three override sources.
|
||||
///
|
||||
/// Precedence (lowest to highest):
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use codex_app_server_protocol::DynamicToolCallOutputContentItem;
|
||||
use codex_app_server_protocol::DynamicToolCallResponse;
|
||||
use codex_core::CodexThread;
|
||||
use codex_protocol::dynamic_tools::DynamicToolCallOutputContentItem as CoreDynamicToolCallOutputContentItem;
|
||||
@@ -15,65 +16,23 @@ pub(crate) async fn on_call_response(
|
||||
conversation: Arc<CodexThread>,
|
||||
) {
|
||||
let response = receiver.await;
|
||||
let value = match response {
|
||||
Ok(Ok(value)) => value,
|
||||
let (response, _error) = match response {
|
||||
Ok(Ok(value)) => decode_response(value),
|
||||
Ok(Err(err)) => {
|
||||
error!("request failed with client error: {err:?}");
|
||||
let fallback = CoreDynamicToolResponse {
|
||||
content_items: vec![CoreDynamicToolCallOutputContentItem::InputText {
|
||||
text: "dynamic tool request failed".to_string(),
|
||||
}],
|
||||
success: false,
|
||||
};
|
||||
if let Err(err) = conversation
|
||||
.submit(Op::DynamicToolResponse {
|
||||
id: call_id.clone(),
|
||||
response: fallback,
|
||||
})
|
||||
.await
|
||||
{
|
||||
error!("failed to submit DynamicToolResponse: {err}");
|
||||
}
|
||||
return;
|
||||
fallback_response("dynamic tool request failed")
|
||||
}
|
||||
Err(err) => {
|
||||
error!("request failed: {err:?}");
|
||||
let fallback = CoreDynamicToolResponse {
|
||||
content_items: vec![CoreDynamicToolCallOutputContentItem::InputText {
|
||||
text: "dynamic tool request failed".to_string(),
|
||||
}],
|
||||
success: false,
|
||||
};
|
||||
if let Err(err) = conversation
|
||||
.submit(Op::DynamicToolResponse {
|
||||
id: call_id.clone(),
|
||||
response: fallback,
|
||||
})
|
||||
.await
|
||||
{
|
||||
error!("failed to submit DynamicToolResponse: {err}");
|
||||
}
|
||||
return;
|
||||
fallback_response("dynamic tool request failed")
|
||||
}
|
||||
};
|
||||
|
||||
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(),
|
||||
},
|
||||
],
|
||||
success: false,
|
||||
}
|
||||
});
|
||||
|
||||
let DynamicToolCallResponse {
|
||||
content_items,
|
||||
success,
|
||||
} = response;
|
||||
let response = CoreDynamicToolResponse {
|
||||
} = response.clone();
|
||||
let core_response = CoreDynamicToolResponse {
|
||||
content_items: content_items
|
||||
.into_iter()
|
||||
.map(CoreDynamicToolCallOutputContentItem::from)
|
||||
@@ -82,11 +41,33 @@ pub(crate) async fn on_call_response(
|
||||
};
|
||||
if let Err(err) = conversation
|
||||
.submit(Op::DynamicToolResponse {
|
||||
id: call_id,
|
||||
response,
|
||||
id: call_id.clone(),
|
||||
response: core_response,
|
||||
})
|
||||
.await
|
||||
{
|
||||
error!("failed to submit DynamicToolResponse: {err}");
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_response(value: serde_json::Value) -> (DynamicToolCallResponse, Option<String>) {
|
||||
match serde_json::from_value::<DynamicToolCallResponse>(value) {
|
||||
Ok(response) => (response, None),
|
||||
Err(err) => {
|
||||
error!("failed to deserialize DynamicToolCallResponse: {err}");
|
||||
fallback_response("dynamic tool response was invalid")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fallback_response(message: &str) -> (DynamicToolCallResponse, Option<String>) {
|
||||
(
|
||||
DynamicToolCallResponse {
|
||||
content_items: vec![DynamicToolCallOutputContentItem::InputText {
|
||||
text: message.to_string(),
|
||||
}],
|
||||
success: false,
|
||||
},
|
||||
Some(message.to_string()),
|
||||
)
|
||||
}
|
||||
|
||||
106
codex-rs/app-server/src/external_agent_config_api.rs
Normal file
106
codex-rs/app-server/src/external_agent_config_api.rs
Normal file
@@ -0,0 +1,106 @@
|
||||
use crate::error_code::INTERNAL_ERROR_CODE;
|
||||
use codex_app_server_protocol::ExternalAgentConfigDetectParams;
|
||||
use codex_app_server_protocol::ExternalAgentConfigDetectResponse;
|
||||
use codex_app_server_protocol::ExternalAgentConfigImportParams;
|
||||
use codex_app_server_protocol::ExternalAgentConfigImportResponse;
|
||||
use codex_app_server_protocol::ExternalAgentConfigMigrationItem;
|
||||
use codex_app_server_protocol::ExternalAgentConfigMigrationItemType;
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
use codex_core::external_agent_config::ExternalAgentConfigDetectOptions;
|
||||
use codex_core::external_agent_config::ExternalAgentConfigMigrationItem as CoreMigrationItem;
|
||||
use codex_core::external_agent_config::ExternalAgentConfigMigrationItemType as CoreMigrationItemType;
|
||||
use codex_core::external_agent_config::ExternalAgentConfigService;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct ExternalAgentConfigApi {
|
||||
migration_service: ExternalAgentConfigService,
|
||||
}
|
||||
|
||||
impl ExternalAgentConfigApi {
|
||||
pub(crate) fn new(codex_home: PathBuf) -> Self {
|
||||
Self {
|
||||
migration_service: ExternalAgentConfigService::new(codex_home),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn detect(
|
||||
&self,
|
||||
params: ExternalAgentConfigDetectParams,
|
||||
) -> Result<ExternalAgentConfigDetectResponse, JSONRPCErrorError> {
|
||||
let items = self
|
||||
.migration_service
|
||||
.detect(ExternalAgentConfigDetectOptions {
|
||||
include_home: params.include_home,
|
||||
cwds: params.cwds,
|
||||
})
|
||||
.map_err(map_io_error)?;
|
||||
|
||||
Ok(ExternalAgentConfigDetectResponse {
|
||||
items: items
|
||||
.into_iter()
|
||||
.map(|migration_item| ExternalAgentConfigMigrationItem {
|
||||
item_type: match migration_item.item_type {
|
||||
CoreMigrationItemType::Config => {
|
||||
ExternalAgentConfigMigrationItemType::Config
|
||||
}
|
||||
CoreMigrationItemType::Skills => {
|
||||
ExternalAgentConfigMigrationItemType::Skills
|
||||
}
|
||||
CoreMigrationItemType::AgentsMd => {
|
||||
ExternalAgentConfigMigrationItemType::AgentsMd
|
||||
}
|
||||
CoreMigrationItemType::McpServerConfig => {
|
||||
ExternalAgentConfigMigrationItemType::McpServerConfig
|
||||
}
|
||||
},
|
||||
description: migration_item.description,
|
||||
cwd: migration_item.cwd,
|
||||
})
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) async fn import(
|
||||
&self,
|
||||
params: ExternalAgentConfigImportParams,
|
||||
) -> Result<ExternalAgentConfigImportResponse, JSONRPCErrorError> {
|
||||
self.migration_service
|
||||
.import(
|
||||
params
|
||||
.migration_items
|
||||
.into_iter()
|
||||
.map(|migration_item| CoreMigrationItem {
|
||||
item_type: match migration_item.item_type {
|
||||
ExternalAgentConfigMigrationItemType::Config => {
|
||||
CoreMigrationItemType::Config
|
||||
}
|
||||
ExternalAgentConfigMigrationItemType::Skills => {
|
||||
CoreMigrationItemType::Skills
|
||||
}
|
||||
ExternalAgentConfigMigrationItemType::AgentsMd => {
|
||||
CoreMigrationItemType::AgentsMd
|
||||
}
|
||||
ExternalAgentConfigMigrationItemType::McpServerConfig => {
|
||||
CoreMigrationItemType::McpServerConfig
|
||||
}
|
||||
},
|
||||
description: migration_item.description,
|
||||
cwd: migration_item.cwd,
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
.map_err(map_io_error)?;
|
||||
|
||||
Ok(ExternalAgentConfigImportResponse {})
|
||||
}
|
||||
}
|
||||
|
||||
fn map_io_error(err: io::Error) -> JSONRPCErrorError {
|
||||
JSONRPCErrorError {
|
||||
code: INTERNAL_ERROR_CODE,
|
||||
message: err.to_string(),
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#![deny(clippy::print_stdout, clippy::print_stderr)]
|
||||
|
||||
use codex_arg0::Arg0DispatchPaths;
|
||||
use codex_cloud_requirements::cloud_requirements_loader;
|
||||
use codex_core::AuthManager;
|
||||
use codex_core::config::Config;
|
||||
@@ -12,7 +13,6 @@ use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::io::ErrorKind;
|
||||
use std::io::Result as IoResult;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::RwLock;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
@@ -57,6 +57,7 @@ mod codex_message_processor;
|
||||
mod config_api;
|
||||
mod dynamic_tools;
|
||||
mod error_code;
|
||||
mod external_agent_config_api;
|
||||
mod filters;
|
||||
mod fuzzy_file_search;
|
||||
mod message_processor;
|
||||
@@ -94,10 +95,77 @@ enum OutboundControlEvent {
|
||||
writer: mpsc::Sender<crate::outgoing_message::OutgoingMessage>,
|
||||
disconnect_sender: Option<CancellationToken>,
|
||||
initialized: Arc<AtomicBool>,
|
||||
experimental_api_enabled: Arc<AtomicBool>,
|
||||
opted_out_notification_methods: Arc<RwLock<HashSet<String>>>,
|
||||
},
|
||||
/// Remove state for a closed/disconnected connection.
|
||||
Closed { connection_id: ConnectionId },
|
||||
/// Disconnect all connection-oriented clients during graceful restart.
|
||||
DisconnectAll,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ShutdownState {
|
||||
requested: bool,
|
||||
forced: bool,
|
||||
last_logged_running_turn_count: Option<usize>,
|
||||
}
|
||||
|
||||
enum ShutdownAction {
|
||||
Noop,
|
||||
Finish,
|
||||
}
|
||||
|
||||
impl ShutdownState {
|
||||
fn requested(&self) -> bool {
|
||||
self.requested
|
||||
}
|
||||
|
||||
fn forced(&self) -> bool {
|
||||
self.forced
|
||||
}
|
||||
|
||||
fn on_ctrl_c(&mut self, connection_count: usize, running_turn_count: usize) {
|
||||
if self.requested {
|
||||
self.forced = true;
|
||||
return;
|
||||
}
|
||||
|
||||
self.requested = true;
|
||||
self.last_logged_running_turn_count = None;
|
||||
info!(
|
||||
"received Ctrl-C; entering graceful restart drain (connections={}, runningAssistantTurns={}, requests still accepted until no assistant turns are running)",
|
||||
connection_count, running_turn_count,
|
||||
);
|
||||
}
|
||||
|
||||
fn update(&mut self, running_turn_count: usize, connection_count: usize) -> ShutdownAction {
|
||||
if !self.requested {
|
||||
return ShutdownAction::Noop;
|
||||
}
|
||||
|
||||
if self.forced || running_turn_count == 0 {
|
||||
if self.forced {
|
||||
info!(
|
||||
"received second Ctrl-C; forcing restart with {running_turn_count} running assistant turn(s) and {connection_count} connection(s)"
|
||||
);
|
||||
} else {
|
||||
info!(
|
||||
"Ctrl-C restart: no assistant turns running; stopping acceptor and disconnecting {connection_count} connection(s)"
|
||||
);
|
||||
}
|
||||
return ShutdownAction::Finish;
|
||||
}
|
||||
|
||||
if self.last_logged_running_turn_count != Some(running_turn_count) {
|
||||
info!(
|
||||
"Ctrl-C restart: waiting for {running_turn_count} running assistant turn(s) to finish"
|
||||
);
|
||||
self.last_logged_running_turn_count = Some(running_turn_count);
|
||||
}
|
||||
|
||||
ShutdownAction::Noop
|
||||
}
|
||||
}
|
||||
|
||||
fn config_warning_from_error(
|
||||
@@ -225,13 +293,13 @@ fn log_format_from_env() -> LogFormat {
|
||||
}
|
||||
|
||||
pub async fn run_main(
|
||||
codex_linux_sandbox_exe: Option<PathBuf>,
|
||||
arg0_paths: Arg0DispatchPaths,
|
||||
cli_config_overrides: CliConfigOverrides,
|
||||
loader_overrides: LoaderOverrides,
|
||||
default_analytics_enabled: bool,
|
||||
) -> IoResult<()> {
|
||||
run_main_with_transport(
|
||||
codex_linux_sandbox_exe,
|
||||
arg0_paths,
|
||||
cli_config_overrides,
|
||||
loader_overrides,
|
||||
default_analytics_enabled,
|
||||
@@ -241,7 +309,7 @@ pub async fn run_main(
|
||||
}
|
||||
|
||||
pub async fn run_main_with_transport(
|
||||
codex_linux_sandbox_exe: Option<PathBuf>,
|
||||
arg0_paths: Arg0DispatchPaths,
|
||||
cli_config_overrides: CliConfigOverrides,
|
||||
loader_overrides: LoaderOverrides,
|
||||
default_analytics_enabled: bool,
|
||||
@@ -253,19 +321,37 @@ pub async fn run_main_with_transport(
|
||||
let (outbound_control_tx, mut outbound_control_rx) =
|
||||
mpsc::channel::<OutboundControlEvent>(CHANNEL_CAPACITY);
|
||||
|
||||
enum TransportRuntime {
|
||||
Stdio,
|
||||
WebSocket {
|
||||
accept_handle: JoinHandle<()>,
|
||||
shutdown_token: CancellationToken,
|
||||
},
|
||||
}
|
||||
|
||||
let mut stdio_handles = Vec::<JoinHandle<()>>::new();
|
||||
let mut websocket_accept_handle = None;
|
||||
match transport {
|
||||
let transport_runtime = match transport {
|
||||
AppServerTransport::Stdio => {
|
||||
start_stdio_connection(transport_event_tx.clone(), &mut stdio_handles).await?;
|
||||
TransportRuntime::Stdio
|
||||
}
|
||||
AppServerTransport::WebSocket { bind_address } => {
|
||||
websocket_accept_handle =
|
||||
Some(start_websocket_acceptor(bind_address, transport_event_tx.clone()).await?);
|
||||
let shutdown_token = CancellationToken::new();
|
||||
let accept_handle = start_websocket_acceptor(
|
||||
bind_address,
|
||||
transport_event_tx.clone(),
|
||||
shutdown_token.clone(),
|
||||
)
|
||||
.await?;
|
||||
TransportRuntime::WebSocket {
|
||||
accept_handle,
|
||||
shutdown_token,
|
||||
}
|
||||
}
|
||||
}
|
||||
let single_client_mode = matches!(transport, AppServerTransport::Stdio);
|
||||
};
|
||||
let single_client_mode = matches!(&transport_runtime, TransportRuntime::Stdio);
|
||||
let shutdown_when_no_connections = single_client_mode;
|
||||
let graceful_ctrl_c_restart_enabled = !single_client_mode;
|
||||
|
||||
// Parse CLI overrides once and derive the base Config eagerly so later
|
||||
// components do not need to work with raw TOML values.
|
||||
@@ -419,6 +505,7 @@ pub async fn run_main_with_transport(
|
||||
writer,
|
||||
disconnect_sender,
|
||||
initialized,
|
||||
experimental_api_enabled,
|
||||
opted_out_notification_methods,
|
||||
} => {
|
||||
outbound_connections.insert(
|
||||
@@ -426,6 +513,7 @@ pub async fn run_main_with_transport(
|
||||
OutboundConnectionState::new(
|
||||
writer,
|
||||
initialized,
|
||||
experimental_api_enabled,
|
||||
opted_out_notification_methods,
|
||||
disconnect_sender,
|
||||
),
|
||||
@@ -434,6 +522,16 @@ pub async fn run_main_with_transport(
|
||||
OutboundControlEvent::Closed { connection_id } => {
|
||||
outbound_connections.remove(&connection_id);
|
||||
}
|
||||
OutboundControlEvent::DisconnectAll => {
|
||||
info!(
|
||||
"disconnecting {} outbound websocket connection(s) for graceful restart",
|
||||
outbound_connections.len()
|
||||
);
|
||||
for connection_state in outbound_connections.values() {
|
||||
connection_state.request_disconnect();
|
||||
}
|
||||
outbound_connections.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
envelope = outgoing_rx.recv() => {
|
||||
@@ -454,7 +552,7 @@ pub async fn run_main_with_transport(
|
||||
let loader_overrides = loader_overrides_for_config_api;
|
||||
let mut processor = MessageProcessor::new(MessageProcessorArgs {
|
||||
outgoing: outgoing_message_sender,
|
||||
codex_linux_sandbox_exe,
|
||||
arg0_paths,
|
||||
config: Arc::new(config),
|
||||
single_client_mode,
|
||||
cli_overrides,
|
||||
@@ -464,11 +562,46 @@ pub async fn run_main_with_transport(
|
||||
config_warnings,
|
||||
});
|
||||
let mut thread_created_rx = processor.thread_created_receiver();
|
||||
let mut running_turn_count_rx = processor.subscribe_running_assistant_turn_count();
|
||||
let mut connections = HashMap::<ConnectionId, ConnectionState>::new();
|
||||
let websocket_accept_shutdown = match &transport_runtime {
|
||||
TransportRuntime::WebSocket { shutdown_token, .. } => Some(shutdown_token.clone()),
|
||||
TransportRuntime::Stdio => None,
|
||||
};
|
||||
async move {
|
||||
let mut listen_for_threads = true;
|
||||
let mut shutdown_state = ShutdownState::default();
|
||||
loop {
|
||||
let running_turn_count = {
|
||||
let running_turn_count = running_turn_count_rx.borrow();
|
||||
*running_turn_count
|
||||
};
|
||||
if matches!(
|
||||
shutdown_state.update(running_turn_count, connections.len()),
|
||||
ShutdownAction::Finish
|
||||
) {
|
||||
if let Some(shutdown_token) = &websocket_accept_shutdown {
|
||||
shutdown_token.cancel();
|
||||
}
|
||||
let _ = outbound_control_tx
|
||||
.send(OutboundControlEvent::DisconnectAll)
|
||||
.await;
|
||||
break;
|
||||
}
|
||||
|
||||
tokio::select! {
|
||||
ctrl_c_result = tokio::signal::ctrl_c(), if graceful_ctrl_c_restart_enabled && !shutdown_state.forced() => {
|
||||
if let Err(err) = ctrl_c_result {
|
||||
warn!("failed to listen for Ctrl-C during graceful restart drain: {err}");
|
||||
}
|
||||
let running_turn_count = *running_turn_count_rx.borrow();
|
||||
shutdown_state.on_ctrl_c(connections.len(), running_turn_count);
|
||||
}
|
||||
changed = running_turn_count_rx.changed(), if graceful_ctrl_c_restart_enabled && shutdown_state.requested() => {
|
||||
if changed.is_err() {
|
||||
warn!("running-turn watcher closed during graceful restart drain");
|
||||
}
|
||||
}
|
||||
event = transport_event_rx.recv() => {
|
||||
let Some(event) = event else {
|
||||
break;
|
||||
@@ -480,6 +613,8 @@ pub async fn run_main_with_transport(
|
||||
disconnect_sender,
|
||||
} => {
|
||||
let outbound_initialized = Arc::new(AtomicBool::new(false));
|
||||
let outbound_experimental_api_enabled =
|
||||
Arc::new(AtomicBool::new(false));
|
||||
let outbound_opted_out_notification_methods =
|
||||
Arc::new(RwLock::new(HashSet::new()));
|
||||
if outbound_control_tx
|
||||
@@ -488,6 +623,9 @@ pub async fn run_main_with_transport(
|
||||
writer,
|
||||
disconnect_sender,
|
||||
initialized: Arc::clone(&outbound_initialized),
|
||||
experimental_api_enabled: Arc::clone(
|
||||
&outbound_experimental_api_enabled,
|
||||
),
|
||||
opted_out_notification_methods: Arc::clone(
|
||||
&outbound_opted_out_notification_methods,
|
||||
),
|
||||
@@ -501,6 +639,7 @@ pub async fn run_main_with_transport(
|
||||
connection_id,
|
||||
ConnectionState::new(
|
||||
outbound_initialized,
|
||||
outbound_experimental_api_enabled,
|
||||
outbound_opted_out_notification_methods,
|
||||
),
|
||||
);
|
||||
@@ -550,6 +689,12 @@ pub async fn run_main_with_transport(
|
||||
"failed to update outbound opted-out notifications"
|
||||
);
|
||||
}
|
||||
connection_state
|
||||
.outbound_experimental_api_enabled
|
||||
.store(
|
||||
connection_state.session.experimental_api_enabled,
|
||||
std::sync::atomic::Ordering::Release,
|
||||
);
|
||||
if !was_initialized && connection_state.session.initialized {
|
||||
processor.send_initialize_notifications().await;
|
||||
}
|
||||
@@ -619,8 +764,13 @@ pub async fn run_main_with_transport(
|
||||
let _ = processor_handle.await;
|
||||
let _ = outbound_handle.await;
|
||||
|
||||
if let Some(handle) = websocket_accept_handle {
|
||||
handle.abort();
|
||||
if let TransportRuntime::WebSocket {
|
||||
accept_handle,
|
||||
shutdown_token,
|
||||
} = transport_runtime
|
||||
{
|
||||
shutdown_token.cancel();
|
||||
let _ = accept_handle.await;
|
||||
}
|
||||
|
||||
for handle in stdio_handles {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user