mirror of
https://github.com/openai/codex.git
synced 2026-05-23 12:34:25 +00:00
Compare commits
48 Commits
shareable-
...
dh--apply-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
14cd993950 | ||
|
|
5810c1b13e | ||
|
|
57f4e37539 | ||
|
|
c16f9daaaf | ||
|
|
03ce01e71f | ||
|
|
189f592014 | ||
|
|
486e60bb55 | ||
|
|
edacbf7b6e | ||
|
|
fc810ba045 | ||
|
|
eb68767f2f | ||
|
|
db4d2599b5 | ||
|
|
b3a8571219 | ||
|
|
31cbebd3c2 | ||
|
|
709e2133bb | ||
|
|
c4bb7db159 | ||
|
|
f2ad519a87 | ||
|
|
ad53574d58 | ||
|
|
5341ad08f8 | ||
|
|
4c4255fcfc | ||
|
|
c5b513ba98 | ||
|
|
6398e9a2ec | ||
|
|
af3b1ae6cb | ||
|
|
15cd796749 | ||
|
|
16fa195fce | ||
|
|
41800fc876 | ||
|
|
314029ffa3 | ||
|
|
48018e9eac | ||
|
|
a1b8e34938 | ||
|
|
76283e6b4e | ||
|
|
05e9c2cd75 | ||
|
|
5296e06b61 | ||
|
|
31906cdb4d | ||
|
|
cab607befb | ||
|
|
281b0eae8b | ||
|
|
4ab44e2c5c | ||
|
|
31d4bfdde0 | ||
|
|
56cd85cd4b | ||
|
|
5ae84197b2 | ||
|
|
fcf16e97a6 | ||
|
|
77f74a5c17 | ||
|
|
b994b52994 | ||
|
|
846464e869 | ||
|
|
0fbe10a807 | ||
|
|
02e9006547 | ||
|
|
08f689843f | ||
|
|
b37555dd75 | ||
|
|
19afbc35c1 | ||
|
|
5b421bba34 |
26
.github/prompts/issue-labeler.txt
vendored
26
.github/prompts/issue-labeler.txt
vendored
@@ -1,26 +0,0 @@
|
||||
You are an assistant that reviews GitHub issues for the repository.
|
||||
|
||||
Your job is to choose the most appropriate existing labels for the issue described later in this prompt.
|
||||
Follow these rules:
|
||||
- Only pick labels out of the list below.
|
||||
- Prefer a small set of precise labels over many broad ones.
|
||||
- If none of the labels fit, respond with an empty JSON array: []
|
||||
- Output must be a JSON array of label names (strings) with no additional commentary.
|
||||
|
||||
Labels to apply:
|
||||
1. bug — Reproducible defects in Codex products (CLI, VS Code extension, web, auth).
|
||||
2. enhancement — Feature requests or usability improvements that ask for new capabilities, better ergonomics, or quality-of-life tweaks.
|
||||
3. extension — VS Code (or other IDE) extension-specific issues.
|
||||
4. windows-os — Bugs or friction specific to Windows environments (PowerShell behavior, path handling, copy/paste, OS-specific auth or tooling failures).
|
||||
5. mcp — Topics involving Model Context Protocol servers/clients.
|
||||
6. codex-web — Issues targeting the Codex web UI/Cloud experience.
|
||||
8. azure — Problems or requests tied to Azure OpenAI deployments.
|
||||
9. documentation — Updates or corrections needed in docs/README/config references (broken links, missing examples, outdated keys, clarification requests).
|
||||
10. model-behavior — Undesirable LLM behavior: forgetting goals, refusing work, hallucinating environment details, quota misreports, or other reasoning/performance anomalies.
|
||||
|
||||
Issue information is available in environment variables:
|
||||
|
||||
ISSUE_NUMBER
|
||||
ISSUE_TITLE
|
||||
ISSUE_BODY
|
||||
REPO_FULL_NAME
|
||||
17
.github/workflows/issue-labeler.yml
vendored
17
.github/workflows/issue-labeler.yml
vendored
@@ -50,14 +50,15 @@ jobs:
|
||||
4. azure — Problems or requests tied to Azure OpenAI deployments.
|
||||
5. model-behavior — Undesirable LLM behavior: forgetting goals, refusing work, hallucinating environment details, quota misreports, or other reasoning/performance anomalies.
|
||||
6. code-review — Issues related to the code review feature or functionality.
|
||||
7. auth - Problems related to authentication, login, or access tokens.
|
||||
8. codex-exec - Problems related to the "codex exec" command or functionality.
|
||||
9. context-management - Problems related to compaction, context windows, or available context reporting.
|
||||
10. custom-model - Problems that involve using custom model providers, local models, or OSS models.
|
||||
11. rate-limits - Problems related to token limits, rate limits, or token usage reporting.
|
||||
12. sandbox - Issues related to local sandbox environments or tool call approvals to override sandbox restrictions.
|
||||
13. tool-calls - Problems related to specific tool call invocations including unexpected errors, failures, or hangs.
|
||||
14. TUI - Problems with the terminal user interface (TUI) including keyboard shortcuts, copy & pasting, menus, or screen update issues.
|
||||
7. safety-check - Issues related to cyber risk detection or trusted access verification.
|
||||
8. auth - Problems related to authentication, login, or access tokens.
|
||||
9. codex-exec - Problems related to the "codex exec" command or functionality.
|
||||
10. context-management - Problems related to compaction, context windows, or available context reporting.
|
||||
11. custom-model - Problems that involve using custom model providers, local models, or OSS models.
|
||||
12. rate-limits - Problems related to token limits, rate limits, or token usage reporting.
|
||||
13. sandbox - Issues related to local sandbox environments or tool call approvals to override sandbox restrictions.
|
||||
14. tool-calls - Problems related to specific tool call invocations including unexpected errors, failures, or hangs.
|
||||
15. TUI - Problems with the terminal user interface (TUI) including keyboard shortcuts, copy & pasting, menus, or screen update issues.
|
||||
|
||||
Issue number: ${{ github.event.issue.number }}
|
||||
|
||||
|
||||
17
.github/workflows/rust-release.yml
vendored
17
.github/workflows/rust-release.yml
vendored
@@ -611,7 +611,22 @@ jobs:
|
||||
fi
|
||||
|
||||
echo "+ ${publish_cmd[*]}"
|
||||
"${publish_cmd[@]}"
|
||||
set +e
|
||||
publish_output="$("${publish_cmd[@]}" 2>&1)"
|
||||
publish_status=$?
|
||||
set -e
|
||||
|
||||
echo "${publish_output}"
|
||||
if [[ ${publish_status} -eq 0 ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if grep -qiE "previously published|cannot publish over|version already exists" <<< "${publish_output}"; then
|
||||
echo "Skipping already-published package version for ${filename}"
|
||||
continue
|
||||
fi
|
||||
|
||||
exit "${publish_status}"
|
||||
done
|
||||
|
||||
update-branch:
|
||||
|
||||
6
.github/workflows/shell-tool-mcp.yml
vendored
6
.github/workflows/shell-tool-mcp.yml
vendored
@@ -408,9 +408,8 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git clone --depth 1 https://git.code.sf.net/p/zsh/code /tmp/zsh
|
||||
git clone https://git.code.sf.net/p/zsh/code /tmp/zsh
|
||||
cd /tmp/zsh
|
||||
git fetch --depth 1 origin 77045ef899e53b9598bebc5a41db93a548a40ca6
|
||||
git checkout 77045ef899e53b9598bebc5a41db93a548a40ca6
|
||||
git apply "${GITHUB_WORKSPACE}/shell-tool-mcp/patches/zsh-exec-wrapper.patch"
|
||||
./Util/preconfig
|
||||
@@ -487,9 +486,8 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git clone --depth 1 https://git.code.sf.net/p/zsh/code /tmp/zsh
|
||||
git clone https://git.code.sf.net/p/zsh/code /tmp/zsh
|
||||
cd /tmp/zsh
|
||||
git fetch --depth 1 origin 77045ef899e53b9598bebc5a41db93a548a40ca6
|
||||
git checkout 77045ef899e53b9598bebc5a41db93a548a40ca6
|
||||
git apply "${GITHUB_WORKSPACE}/shell-tool-mcp/patches/zsh-exec-wrapper.patch"
|
||||
./Util/preconfig
|
||||
|
||||
12
MODULE.bazel.lock
generated
12
MODULE.bazel.lock
generated
@@ -608,7 +608,7 @@
|
||||
"anyhow_1.0.101": "{\"dependencies\":[{\"name\":\"backtrace\",\"optional\":true,\"req\":\"^0.3.51\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"futures\",\"req\":\"^0.3\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0.6\"},{\"features\":[\"full\"],\"kind\":\"dev\",\"name\":\"syn\",\"req\":\"^2.0\"},{\"kind\":\"dev\",\"name\":\"thiserror\",\"req\":\"^2\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.108\"}],\"features\":{\"default\":[\"std\"],\"std\":[]}}",
|
||||
"arbitrary_1.4.2": "{\"dependencies\":[{\"name\":\"derive_arbitrary\",\"optional\":true,\"req\":\"~1.4.0\"},{\"kind\":\"dev\",\"name\":\"exhaustigen\",\"req\":\"^0.1.0\"}],\"features\":{\"derive\":[\"derive_arbitrary\"]}}",
|
||||
"arboard_3.6.1": "{\"dependencies\":[{\"features\":[\"std\"],\"name\":\"clipboard-win\",\"req\":\"^5.3.1\",\"target\":\"cfg(windows)\"},{\"kind\":\"dev\",\"name\":\"env_logger\",\"req\":\"^0.10.2\"},{\"default_features\":false,\"features\":[\"png\"],\"name\":\"image\",\"optional\":true,\"req\":\"^0.25\",\"target\":\"cfg(all(unix, not(any(target_os=\\\"macos\\\", target_os=\\\"android\\\", target_os=\\\"emscripten\\\"))))\"},{\"default_features\":false,\"features\":[\"tiff\"],\"name\":\"image\",\"optional\":true,\"req\":\"^0.25\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"default_features\":false,\"features\":[\"png\",\"bmp\"],\"name\":\"image\",\"optional\":true,\"req\":\"^0.25\",\"target\":\"cfg(windows)\"},{\"name\":\"log\",\"req\":\"^0.4\",\"target\":\"cfg(all(unix, not(any(target_os=\\\"macos\\\", target_os=\\\"android\\\", target_os=\\\"emscripten\\\"))))\"},{\"name\":\"log\",\"req\":\"^0.4\",\"target\":\"cfg(windows)\"},{\"name\":\"objc2\",\"req\":\"^0.6.0\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"default_features\":false,\"features\":[\"std\",\"objc2-core-graphics\",\"NSPasteboard\",\"NSPasteboardItem\",\"NSImage\"],\"name\":\"objc2-app-kit\",\"req\":\"^0.3.0\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"default_features\":false,\"features\":[\"std\",\"CFCGTypes\"],\"name\":\"objc2-core-foundation\",\"optional\":true,\"req\":\"^0.3.0\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"default_features\":false,\"features\":[\"std\",\"CGImage\",\"CGColorSpace\",\"CGDataProvider\"],\"name\":\"objc2-core-graphics\",\"optional\":true,\"req\":\"^0.3.0\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"default_features\":false,\"features\":[\"std\",\"NSArray\",\"NSString\",\"NSEnumerator\",\"NSGeometry\",\"NSValue\"],\"name\":\"objc2-foundation\",\"req\":\"^0.3.0\",\"target\":\"cfg(target_os = \\\"macos\\\")\"},{\"name\":\"parking_lot\",\"req\":\"^0.12\",\"target\":\"cfg(all(unix, not(any(target_os=\\\"macos\\\", target_os=\\\"android\\\", target_os=\\\"emscripten\\\"))))\"},{\"name\":\"percent-encoding\",\"req\":\"^2.3.1\",\"target\":\"cfg(all(unix, not(any(target_os=\\\"macos\\\", target_os=\\\"android\\\", target_os=\\\"emscripten\\\"))))\"},{\"features\":[\"Win32_Foundation\",\"Win32_Storage_FileSystem\",\"Win32_System_DataExchange\",\"Win32_System_Memory\",\"Win32_System_Ole\",\"Win32_UI_Shell\"],\"name\":\"windows-sys\",\"req\":\">=0.52.0, <0.61.0\",\"target\":\"cfg(windows)\"},{\"name\":\"wl-clipboard-rs\",\"optional\":true,\"req\":\"^0.9.0\",\"target\":\"cfg(all(unix, not(any(target_os=\\\"macos\\\", target_os=\\\"android\\\", target_os=\\\"emscripten\\\"))))\"},{\"name\":\"x11rb\",\"req\":\"^0.13\",\"target\":\"cfg(all(unix, not(any(target_os=\\\"macos\\\", target_os=\\\"android\\\", target_os=\\\"emscripten\\\"))))\"}],\"features\":{\"core-graphics\":[\"dep:objc2-core-graphics\"],\"default\":[\"image-data\"],\"image\":[\"dep:image\"],\"image-data\":[\"dep:objc2-core-graphics\",\"dep:objc2-core-foundation\",\"image\",\"windows-sys\",\"core-graphics\"],\"wayland-data-control\":[\"wl-clipboard-rs\"],\"windows-sys\":[\"windows-sys/Win32_Graphics_Gdi\"],\"wl-clipboard-rs\":[\"dep:wl-clipboard-rs\"]}}",
|
||||
"arc-swap_1.8.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"adaptive-barrier\",\"req\":\"~1\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"~0.7\"},{\"kind\":\"dev\",\"name\":\"crossbeam-utils\",\"req\":\"~0.8\"},{\"kind\":\"dev\",\"name\":\"itertools\",\"req\":\"^0.14\"},{\"kind\":\"dev\",\"name\":\"num_cpus\",\"req\":\"~1\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"~1\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"~0.12\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"name\":\"rustversion\",\"req\":\"^1\"},{\"features\":[\"rc\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1.0.130\"},{\"kind\":\"dev\",\"name\":\"serde_test\",\"req\":\"^1.0.177\"}],\"features\":{\"experimental-strategies\":[],\"experimental-thread-local\":[],\"internal-test-strategies\":[],\"weak\":[]}}",
|
||||
"arc-swap_1.8.2": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"adaptive-barrier\",\"req\":\"~1\"},{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"~0.7\"},{\"kind\":\"dev\",\"name\":\"crossbeam-utils\",\"req\":\"~0.8\"},{\"kind\":\"dev\",\"name\":\"itertools\",\"req\":\"^0.14\"},{\"kind\":\"dev\",\"name\":\"num_cpus\",\"req\":\"~1\"},{\"kind\":\"dev\",\"name\":\"once_cell\",\"req\":\"~1\"},{\"kind\":\"dev\",\"name\":\"parking_lot\",\"req\":\"~0.12\"},{\"kind\":\"dev\",\"name\":\"proptest\",\"req\":\"^1\"},{\"name\":\"rustversion\",\"req\":\"^1\"},{\"features\":[\"rc\"],\"name\":\"serde\",\"optional\":true,\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1.0.130\"},{\"kind\":\"dev\",\"name\":\"serde_test\",\"req\":\"^1.0.177\"}],\"features\":{\"experimental-strategies\":[],\"experimental-thread-local\":[],\"internal-test-strategies\":[],\"weak\":[]}}",
|
||||
"arrayvec_0.7.6": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"bencher\",\"req\":\"^0.1.4\"},{\"default_features\":false,\"name\":\"borsh\",\"optional\":true,\"req\":\"^1.2.0\"},{\"kind\":\"dev\",\"name\":\"matches\",\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0\"},{\"kind\":\"dev\",\"name\":\"serde_test\",\"req\":\"^1.0\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1.4\"}],\"features\":{\"default\":[\"std\"],\"std\":[]}}",
|
||||
"ascii-canvas_3.0.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"diff\",\"req\":\"^0.1\"},{\"name\":\"term\",\"req\":\"^0.7\"}],\"features\":{}}",
|
||||
"ascii_1.1.0": "{\"dependencies\":[{\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.25\"},{\"name\":\"serde_test\",\"optional\":true,\"req\":\"^1.0\"}],\"features\":{\"alloc\":[],\"default\":[\"std\"],\"std\":[\"alloc\"]}}",
|
||||
@@ -686,11 +686,11 @@
|
||||
"chrono_0.4.43": "{\"dependencies\":[{\"features\":[\"derive\"],\"name\":\"arbitrary\",\"optional\":true,\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"bincode\",\"req\":\"^1.3.0\"},{\"name\":\"defmt\",\"optional\":true,\"req\":\"^1.0.1\"},{\"features\":[\"fallback\"],\"name\":\"iana-time-zone\",\"optional\":true,\"req\":\"^0.1.45\",\"target\":\"cfg(unix)\"},{\"name\":\"js-sys\",\"optional\":true,\"req\":\"^0.3\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", not(any(target_os = \\\"emscripten\\\", target_os = \\\"wasi\\\"))))\"},{\"default_features\":false,\"name\":\"num-traits\",\"req\":\"^0.2\"},{\"name\":\"pure-rust-locales\",\"optional\":true,\"req\":\"^0.8.2\"},{\"default_features\":false,\"name\":\"rkyv\",\"optional\":true,\"req\":\"^0.7.43\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.99\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1\"},{\"kind\":\"dev\",\"name\":\"similar-asserts\",\"req\":\"^1.6.1\"},{\"name\":\"wasm-bindgen\",\"optional\":true,\"req\":\"^0.2\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", not(any(target_os = \\\"emscripten\\\", target_os = \\\"wasi\\\"))))\"},{\"kind\":\"dev\",\"name\":\"wasm-bindgen-test\",\"req\":\"^0.3\",\"target\":\"cfg(all(target_arch = \\\"wasm32\\\", not(any(target_os = \\\"emscripten\\\", target_os = \\\"wasi\\\"))))\"},{\"kind\":\"dev\",\"name\":\"windows-bindgen\",\"req\":\"^0.66\"},{\"name\":\"windows-link\",\"optional\":true,\"req\":\"^0.2\",\"target\":\"cfg(windows)\"}],\"features\":{\"__internal_bench\":[],\"alloc\":[],\"clock\":[\"winapi\",\"iana-time-zone\",\"now\"],\"core-error\":[],\"default\":[\"clock\",\"std\",\"oldtime\",\"wasmbind\"],\"defmt\":[\"dep:defmt\",\"pure-rust-locales?/defmt\"],\"libc\":[],\"now\":[\"std\"],\"oldtime\":[],\"rkyv\":[\"dep:rkyv\",\"rkyv/size_32\"],\"rkyv-16\":[\"dep:rkyv\",\"rkyv?/size_16\"],\"rkyv-32\":[\"dep:rkyv\",\"rkyv?/size_32\"],\"rkyv-64\":[\"dep:rkyv\",\"rkyv?/size_64\"],\"rkyv-validation\":[\"rkyv?/validation\"],\"std\":[\"alloc\"],\"unstable-locales\":[\"pure-rust-locales\"],\"wasmbind\":[\"wasm-bindgen\",\"js-sys\"],\"winapi\":[\"windows-link\"]}}",
|
||||
"chunked_transfer_1.5.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"criterion\",\"req\":\"^0.3\"}],\"features\":{}}",
|
||||
"cipher_0.4.4": "{\"dependencies\":[{\"name\":\"blobby\",\"optional\":true,\"req\":\"^0.3\"},{\"name\":\"crypto-common\",\"req\":\"^0.1.6\"},{\"name\":\"inout\",\"req\":\"^0.1\"},{\"default_features\":false,\"name\":\"zeroize\",\"optional\":true,\"req\":\"^1.5\"}],\"features\":{\"alloc\":[],\"block-padding\":[\"inout/block-padding\"],\"dev\":[\"blobby\"],\"rand_core\":[\"crypto-common/rand_core\"],\"std\":[\"alloc\",\"crypto-common/std\",\"inout/std\"]}}",
|
||||
"clap_4.5.56": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"automod\",\"req\":\"^1.0.14\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"clap-cargo\",\"req\":\"^0.15.0\"},{\"default_features\":false,\"name\":\"clap_builder\",\"req\":\"=4.5.56\"},{\"name\":\"clap_derive\",\"optional\":true,\"req\":\"=4.5.55\"},{\"kind\":\"dev\",\"name\":\"jiff\",\"req\":\"^0.2.3\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0.15\"},{\"kind\":\"dev\",\"name\":\"semver\",\"req\":\"^1.0.26\"},{\"kind\":\"dev\",\"name\":\"shlex\",\"req\":\"^1.3.0\"},{\"features\":[\"term-svg\"],\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.16\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.91\"},{\"default_features\":false,\"features\":[\"color-auto\",\"diff\",\"examples\"],\"kind\":\"dev\",\"name\":\"trycmd\",\"req\":\"^0.15.3\"}],\"features\":{\"cargo\":[\"clap_builder/cargo\"],\"color\":[\"clap_builder/color\"],\"debug\":[\"clap_builder/debug\",\"clap_derive?/debug\"],\"default\":[\"std\",\"color\",\"help\",\"usage\",\"error-context\",\"suggestions\"],\"deprecated\":[\"clap_builder/deprecated\",\"clap_derive?/deprecated\"],\"derive\":[\"dep:clap_derive\"],\"env\":[\"clap_builder/env\"],\"error-context\":[\"clap_builder/error-context\"],\"help\":[\"clap_builder/help\"],\"std\":[\"clap_builder/std\"],\"string\":[\"clap_builder/string\"],\"suggestions\":[\"clap_builder/suggestions\"],\"unicode\":[\"clap_builder/unicode\"],\"unstable-derive-ui-tests\":[],\"unstable-doc\":[\"clap_builder/unstable-doc\",\"derive\"],\"unstable-ext\":[\"clap_builder/unstable-ext\"],\"unstable-markdown\":[\"clap_derive/unstable-markdown\"],\"unstable-styles\":[\"clap_builder/unstable-styles\"],\"unstable-v5\":[\"clap_builder/unstable-v5\",\"clap_derive?/unstable-v5\",\"deprecated\"],\"usage\":[\"clap_builder/usage\"],\"wrap_help\":[\"clap_builder/wrap_help\"]}}",
|
||||
"clap_builder_4.5.56": "{\"dependencies\":[{\"name\":\"anstream\",\"optional\":true,\"req\":\"^0.6.7\"},{\"name\":\"anstyle\",\"req\":\"^1.0.8\"},{\"name\":\"backtrace\",\"optional\":true,\"req\":\"^0.3.73\"},{\"name\":\"clap_lex\",\"req\":\"^0.7.4\"},{\"kind\":\"dev\",\"name\":\"color-print\",\"req\":\"^0.3.6\"},{\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.16\"},{\"kind\":\"dev\",\"name\":\"static_assertions\",\"req\":\"^1.1.0\"},{\"name\":\"strsim\",\"optional\":true,\"req\":\"^0.11.0\"},{\"name\":\"terminal_size\",\"optional\":true,\"req\":\"^0.4.0\"},{\"kind\":\"dev\",\"name\":\"unic-emoji-char\",\"req\":\"^0.9.0\"},{\"name\":\"unicase\",\"optional\":true,\"req\":\"^2.6.0\"},{\"name\":\"unicode-width\",\"optional\":true,\"req\":\"^0.2.0\"}],\"features\":{\"cargo\":[],\"color\":[\"dep:anstream\"],\"debug\":[\"dep:backtrace\"],\"default\":[\"std\",\"color\",\"help\",\"usage\",\"error-context\",\"suggestions\"],\"deprecated\":[],\"env\":[],\"error-context\":[],\"help\":[],\"std\":[\"anstyle/std\"],\"string\":[],\"suggestions\":[\"dep:strsim\",\"error-context\"],\"unicode\":[\"dep:unicode-width\",\"dep:unicase\"],\"unstable-doc\":[\"cargo\",\"wrap_help\",\"env\",\"unicode\",\"string\",\"unstable-ext\"],\"unstable-ext\":[],\"unstable-styles\":[\"color\"],\"unstable-v5\":[\"deprecated\"],\"usage\":[],\"wrap_help\":[\"help\",\"dep:terminal_size\"]}}",
|
||||
"clap_4.5.58": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"automod\",\"req\":\"^1.0.14\"},{\"default_features\":false,\"kind\":\"dev\",\"name\":\"clap-cargo\",\"req\":\"^0.15.0\"},{\"default_features\":false,\"name\":\"clap_builder\",\"req\":\"=4.5.58\"},{\"name\":\"clap_derive\",\"optional\":true,\"req\":\"=4.5.55\"},{\"kind\":\"dev\",\"name\":\"jiff\",\"req\":\"^0.2.3\"},{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0.15\"},{\"kind\":\"dev\",\"name\":\"semver\",\"req\":\"^1.0.26\"},{\"kind\":\"dev\",\"name\":\"shlex\",\"req\":\"^1.3.0\"},{\"features\":[\"term-svg\"],\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.16\"},{\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.91\"},{\"default_features\":false,\"features\":[\"color-auto\",\"diff\",\"examples\"],\"kind\":\"dev\",\"name\":\"trycmd\",\"req\":\"^0.15.3\"}],\"features\":{\"cargo\":[\"clap_builder/cargo\"],\"color\":[\"clap_builder/color\"],\"debug\":[\"clap_builder/debug\",\"clap_derive?/debug\"],\"default\":[\"std\",\"color\",\"help\",\"usage\",\"error-context\",\"suggestions\"],\"deprecated\":[\"clap_builder/deprecated\",\"clap_derive?/deprecated\"],\"derive\":[\"dep:clap_derive\"],\"env\":[\"clap_builder/env\"],\"error-context\":[\"clap_builder/error-context\"],\"help\":[\"clap_builder/help\"],\"std\":[\"clap_builder/std\"],\"string\":[\"clap_builder/string\"],\"suggestions\":[\"clap_builder/suggestions\"],\"unicode\":[\"clap_builder/unicode\"],\"unstable-derive-ui-tests\":[],\"unstable-doc\":[\"clap_builder/unstable-doc\",\"derive\"],\"unstable-ext\":[\"clap_builder/unstable-ext\"],\"unstable-markdown\":[\"clap_derive/unstable-markdown\"],\"unstable-styles\":[\"clap_builder/unstable-styles\"],\"unstable-v5\":[\"clap_builder/unstable-v5\",\"clap_derive?/unstable-v5\",\"deprecated\"],\"usage\":[\"clap_builder/usage\"],\"wrap_help\":[\"clap_builder/wrap_help\"]}}",
|
||||
"clap_builder_4.5.58": "{\"dependencies\":[{\"name\":\"anstream\",\"optional\":true,\"req\":\"^0.6.7\"},{\"name\":\"anstyle\",\"req\":\"^1.0.8\"},{\"name\":\"backtrace\",\"optional\":true,\"req\":\"^0.3.73\"},{\"name\":\"clap_lex\",\"req\":\"^1.0.0\"},{\"kind\":\"dev\",\"name\":\"color-print\",\"req\":\"^0.3.6\"},{\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.16\"},{\"kind\":\"dev\",\"name\":\"static_assertions\",\"req\":\"^1.1.0\"},{\"name\":\"strsim\",\"optional\":true,\"req\":\"^0.11.0\"},{\"name\":\"terminal_size\",\"optional\":true,\"req\":\"^0.4.0\"},{\"kind\":\"dev\",\"name\":\"unic-emoji-char\",\"req\":\"^0.9.0\"},{\"name\":\"unicase\",\"optional\":true,\"req\":\"^2.6.0\"},{\"name\":\"unicode-width\",\"optional\":true,\"req\":\"^0.2.0\"}],\"features\":{\"cargo\":[],\"color\":[\"dep:anstream\"],\"debug\":[\"dep:backtrace\"],\"default\":[\"std\",\"color\",\"help\",\"usage\",\"error-context\",\"suggestions\"],\"deprecated\":[],\"env\":[],\"error-context\":[],\"help\":[],\"std\":[\"anstyle/std\"],\"string\":[],\"suggestions\":[\"dep:strsim\",\"error-context\"],\"unicode\":[\"dep:unicode-width\",\"dep:unicase\"],\"unstable-doc\":[\"cargo\",\"wrap_help\",\"env\",\"unicode\",\"string\",\"unstable-ext\"],\"unstable-ext\":[],\"unstable-styles\":[\"color\"],\"unstable-v5\":[\"deprecated\"],\"usage\":[],\"wrap_help\":[\"help\",\"dep:terminal_size\"]}}",
|
||||
"clap_complete_4.5.65": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"automod\",\"req\":\"^1.0.14\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"clap\",\"req\":\"^4.5.20\"},{\"default_features\":false,\"features\":[\"std\",\"derive\",\"help\"],\"kind\":\"dev\",\"name\":\"clap\",\"req\":\"^4.5.20\"},{\"name\":\"clap_lex\",\"optional\":true,\"req\":\"^0.7.0\"},{\"name\":\"completest\",\"optional\":true,\"req\":\"^0.4.2\"},{\"name\":\"completest-pty\",\"optional\":true,\"req\":\"^0.5.5\"},{\"name\":\"is_executable\",\"optional\":true,\"req\":\"^1.0.1\"},{\"name\":\"shlex\",\"optional\":true,\"req\":\"^1.3.0\"},{\"features\":[\"diff\",\"dir\",\"examples\"],\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6.0\"},{\"default_features\":false,\"features\":[\"color-auto\",\"diff\",\"examples\"],\"kind\":\"dev\",\"name\":\"trycmd\",\"req\":\"^0.15.1\"}],\"features\":{\"debug\":[\"clap/debug\"],\"default\":[],\"unstable-doc\":[\"unstable-dynamic\"],\"unstable-dynamic\":[\"dep:clap_lex\",\"dep:shlex\",\"dep:is_executable\",\"clap/unstable-ext\"],\"unstable-shell-tests\":[\"dep:completest\",\"dep:completest-pty\"]}}",
|
||||
"clap_derive_4.5.55": "{\"dependencies\":[{\"name\":\"anstyle\",\"optional\":true,\"req\":\"^1.0.10\"},{\"name\":\"heck\",\"req\":\"^0.5.0\"},{\"name\":\"proc-macro2\",\"req\":\"^1.0.69\"},{\"default_features\":false,\"name\":\"pulldown-cmark\",\"optional\":true,\"req\":\"^0.13.0\"},{\"name\":\"quote\",\"req\":\"^1.0.9\"},{\"features\":[\"full\"],\"name\":\"syn\",\"req\":\"^2.0.8\"}],\"features\":{\"debug\":[],\"default\":[],\"deprecated\":[],\"raw-deprecated\":[\"deprecated\"],\"unstable-markdown\":[\"dep:pulldown-cmark\",\"dep:anstyle\"],\"unstable-v5\":[\"deprecated\"]}}",
|
||||
"clap_lex_0.7.7": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"automod\",\"req\":\"^1.0.14\"}],\"features\":{}}",
|
||||
"clap_lex_1.0.0": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"automod\",\"req\":\"^1.0.14\"}],\"features\":{}}",
|
||||
"clipboard-win_5.4.1": "{\"dependencies\":[{\"name\":\"error-code\",\"req\":\"^3\",\"target\":\"cfg(windows)\"},{\"name\":\"windows-win\",\"optional\":true,\"req\":\"^3\",\"target\":\"cfg(windows)\"}],\"features\":{\"monitor\":[\"windows-win\"],\"std\":[\"error-code/std\"]}}",
|
||||
"cmake_0.1.57": "{\"dependencies\":[{\"name\":\"cc\",\"req\":\"^1.2.46\"}],\"features\":{}}",
|
||||
"cmp_any_0.8.1": "{\"dependencies\":[],\"features\":{}}",
|
||||
@@ -790,9 +790,9 @@
|
||||
"enumflags2_0.7.12": "{\"dependencies\":[{\"name\":\"enumflags2_derive\",\"req\":\"=0.7.12\"},{\"default_features\":false,\"name\":\"serde\",\"optional\":true,\"req\":\"^1.0.0\"}],\"features\":{\"std\":[]}}",
|
||||
"enumflags2_derive_0.7.12": "{\"dependencies\":[{\"name\":\"proc-macro2\",\"req\":\"^1.0\"},{\"name\":\"quote\",\"req\":\"^1.0\"},{\"default_features\":false,\"features\":[\"parsing\",\"printing\",\"derive\",\"proc-macro\"],\"name\":\"syn\",\"req\":\"^2.0\"}],\"features\":{}}",
|
||||
"env-flags_0.1.1": "{\"dependencies\":[],\"features\":{}}",
|
||||
"env_filter_0.1.4": "{\"dependencies\":[{\"features\":[\"std\"],\"name\":\"log\",\"req\":\"^0.4.8\"},{\"default_features\":false,\"features\":[\"std\",\"perf\"],\"name\":\"regex\",\"optional\":true,\"req\":\"^1.0.3\"},{\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6\"}],\"features\":{\"default\":[\"regex\"],\"regex\":[\"dep:regex\"]}}",
|
||||
"env_filter_1.0.0": "{\"dependencies\":[{\"features\":[\"std\"],\"name\":\"log\",\"req\":\"^0.4.8\"},{\"default_features\":false,\"features\":[\"std\",\"perf\"],\"name\":\"regex\",\"optional\":true,\"req\":\"^1.0.3\"},{\"kind\":\"dev\",\"name\":\"snapbox\",\"req\":\"^0.6\"}],\"features\":{\"default\":[\"regex\"],\"regex\":[\"dep:regex\"]}}",
|
||||
"env_home_0.1.0": "{\"dependencies\":[],\"features\":{}}",
|
||||
"env_logger_0.11.8": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"wincon\"],\"name\":\"anstream\",\"optional\":true,\"req\":\"^0.6.11\"},{\"name\":\"anstyle\",\"optional\":true,\"req\":\"^1.0.6\"},{\"default_features\":false,\"name\":\"env_filter\",\"req\":\"^0.1.0\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"jiff\",\"optional\":true,\"req\":\"^0.2.3\"},{\"features\":[\"std\"],\"name\":\"log\",\"req\":\"^0.4.21\"}],\"features\":{\"auto-color\":[\"color\",\"anstream/auto\"],\"color\":[\"dep:anstream\",\"dep:anstyle\"],\"default\":[\"auto-color\",\"humantime\",\"regex\"],\"humantime\":[\"dep:jiff\"],\"kv\":[\"log/kv\"],\"regex\":[\"env_filter/regex\"],\"unstable-kv\":[\"kv\"]}}",
|
||||
"env_logger_0.11.9": "{\"dependencies\":[{\"default_features\":false,\"features\":[\"wincon\"],\"name\":\"anstream\",\"optional\":true,\"req\":\"^0.6.11\"},{\"name\":\"anstyle\",\"optional\":true,\"req\":\"^1.0.6\"},{\"default_features\":false,\"name\":\"env_filter\",\"req\":\"^1.0.0\"},{\"default_features\":false,\"features\":[\"std\"],\"name\":\"jiff\",\"optional\":true,\"req\":\"^0.2.3\"},{\"features\":[\"std\"],\"name\":\"log\",\"req\":\"^0.4.21\"}],\"features\":{\"auto-color\":[\"color\",\"anstream/auto\"],\"color\":[\"dep:anstream\",\"dep:anstyle\"],\"default\":[\"auto-color\",\"humantime\",\"regex\"],\"humantime\":[\"dep:jiff\"],\"kv\":[\"log/kv\"],\"regex\":[\"env_filter/regex\"],\"unstable-kv\":[\"kv\"]}}",
|
||||
"equivalent_1.0.2": "{\"dependencies\":[],\"features\":{}}",
|
||||
"erased-serde_0.3.31": "{\"dependencies\":[{\"kind\":\"dev\",\"name\":\"rustversion\",\"req\":\"^1.0.13\"},{\"default_features\":false,\"name\":\"serde\",\"req\":\"^1.0.166\"},{\"kind\":\"dev\",\"name\":\"serde_cbor\",\"req\":\"^0.11.2\"},{\"kind\":\"dev\",\"name\":\"serde_derive\",\"req\":\"^1.0.166\"},{\"kind\":\"dev\",\"name\":\"serde_json\",\"req\":\"^1.0.99\"},{\"features\":[\"diff\"],\"kind\":\"dev\",\"name\":\"trybuild\",\"req\":\"^1.0.83\"}],\"features\":{\"alloc\":[\"serde/alloc\"],\"default\":[\"std\"],\"std\":[\"serde/std\"],\"unstable-debug\":[]}}",
|
||||
"errno_0.3.14": "{\"dependencies\":[{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(target_os=\\\"hermit\\\")\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(target_os=\\\"wasi\\\")\"},{\"default_features\":false,\"name\":\"libc\",\"req\":\"^0.2\",\"target\":\"cfg(unix)\"},{\"features\":[\"Win32_Foundation\",\"Win32_System_Diagnostics_Debug\"],\"name\":\"windows-sys\",\"req\":\">=0.52, <0.62\",\"target\":\"cfg(windows)\"}],\"features\":{\"default\":[\"std\"],\"std\":[\"libc/std\"]}}",
|
||||
|
||||
@@ -4,74 +4,74 @@
|
||||
"name": "rg",
|
||||
"platforms": {
|
||||
"macos-aarch64": {
|
||||
"size": 1787248,
|
||||
"hash": "blake3",
|
||||
"digest": "8d9942032585ea8ee805937634238d9aee7b210069f4703c88fbe568e26fb78a",
|
||||
"size": 1777930,
|
||||
"hash": "sha256",
|
||||
"digest": "378e973289176ca0c6054054ee7f631a065874a352bf43f0fa60ef079b6ba715",
|
||||
"format": "tar.gz",
|
||||
"path": "ripgrep-14.1.1-aarch64-apple-darwin/rg",
|
||||
"path": "ripgrep-15.1.0-aarch64-apple-darwin/rg",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-aarch64-apple-darwin.tar.gz"
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-apple-darwin.tar.gz"
|
||||
}
|
||||
]
|
||||
},
|
||||
"linux-aarch64": {
|
||||
"size": 2047405,
|
||||
"hash": "blake3",
|
||||
"digest": "0b670b8fa0a3df2762af2fc82cc4932f684ca4c02dbd1260d4f3133fd4b2a515",
|
||||
"size": 1869959,
|
||||
"hash": "sha256",
|
||||
"digest": "2b661c6ef508e902f388e9098d9c4c5aca72c87b55922d94abdba830b4dc885e",
|
||||
"format": "tar.gz",
|
||||
"path": "ripgrep-14.1.1-aarch64-unknown-linux-gnu/rg",
|
||||
"path": "ripgrep-15.1.0-aarch64-unknown-linux-gnu/rg",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-aarch64-unknown-linux-gnu.tar.gz"
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-unknown-linux-gnu.tar.gz"
|
||||
}
|
||||
]
|
||||
},
|
||||
"macos-x86_64": {
|
||||
"size": 2082672,
|
||||
"hash": "blake3",
|
||||
"digest": "e9b862fc8da3127f92791f0ff6a799504154ca9d36c98bf3e60a81c6b1f7289e",
|
||||
"size": 1894127,
|
||||
"hash": "sha256",
|
||||
"digest": "64811cb24e77cac3057d6c40b63ac9becf9082eedd54ca411b475b755d334882",
|
||||
"format": "tar.gz",
|
||||
"path": "ripgrep-14.1.1-x86_64-apple-darwin/rg",
|
||||
"path": "ripgrep-15.1.0-x86_64-apple-darwin/rg",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-x86_64-apple-darwin.tar.gz"
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-x86_64-apple-darwin.tar.gz"
|
||||
}
|
||||
]
|
||||
},
|
||||
"linux-x86_64": {
|
||||
"size": 2566310,
|
||||
"hash": "blake3",
|
||||
"digest": "f73cca4e54d78c31f832c7f6e2c0b4db8b04fa3eaa747915727d570893dbee76",
|
||||
"size": 2263077,
|
||||
"hash": "sha256",
|
||||
"digest": "1c9297be4a084eea7ecaedf93eb03d058d6faae29bbc57ecdaf5063921491599",
|
||||
"format": "tar.gz",
|
||||
"path": "ripgrep-14.1.1-x86_64-unknown-linux-musl/rg",
|
||||
"path": "ripgrep-15.1.0-x86_64-unknown-linux-musl/rg",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-x86_64-unknown-linux-musl.tar.gz"
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-x86_64-unknown-linux-musl.tar.gz"
|
||||
}
|
||||
]
|
||||
},
|
||||
"windows-x86_64": {
|
||||
"size": 2058893,
|
||||
"hash": "blake3",
|
||||
"digest": "a8ce1a6fed4f8093ee997e57f33254e94b2cd18e26358b09db599c89882eadbd",
|
||||
"size": 1810687,
|
||||
"hash": "sha256",
|
||||
"digest": "124510b94b6baa3380d051fdf4650eaa80a302c876d611e9dba0b2e18d87493a",
|
||||
"format": "zip",
|
||||
"path": "ripgrep-14.1.1-x86_64-pc-windows-msvc/rg.exe",
|
||||
"path": "ripgrep-15.1.0-x86_64-pc-windows-msvc/rg.exe",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/14.1.1/ripgrep-14.1.1-x86_64-pc-windows-msvc.zip"
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-x86_64-pc-windows-msvc.zip"
|
||||
}
|
||||
]
|
||||
},
|
||||
"windows-aarch64": {
|
||||
"size": 1667740,
|
||||
"hash": "blake3",
|
||||
"digest": "47b971a8c4fca1d23a4e7c19bd4d88465ebc395598458133139406d3bf85f3fa",
|
||||
"size": 1675460,
|
||||
"hash": "sha256",
|
||||
"digest": "00d931fb5237c9696ca49308818edb76d8eb6fc132761cb2a1bd616b2df02f8e",
|
||||
"format": "zip",
|
||||
"path": "rg.exe",
|
||||
"path": "ripgrep-15.1.0-aarch64-pc-windows-msvc/rg.exe",
|
||||
"providers": [
|
||||
{
|
||||
"url": "https://github.com/microsoft/ripgrep-prebuilt/releases/download/v13.0.0-13/ripgrep-v13.0.0-13-aarch64-pc-windows-msvc.zip"
|
||||
"url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-pc-windows-msvc.zip"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
44
codex-rs/Cargo.lock
generated
44
codex-rs/Cargo.lock
generated
@@ -423,16 +423,16 @@ dependencies = [
|
||||
"objc2-foundation",
|
||||
"parking_lot",
|
||||
"percent-encoding",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.52.0",
|
||||
"wl-clipboard-rs",
|
||||
"x11rb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.8.0"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d03449bb8ca2cc2ef70869af31463d1ae5ccc8fa3e334b307203fbf815207e"
|
||||
checksum = "f9f3647c145568cec02c42054e07bdf9a5a698e15b466fb2341bfc393cd24aa5"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
@@ -1227,9 +1227,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.56"
|
||||
version = "4.5.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75ca66430e33a14957acc24c5077b503e7d374151b2b4b3a10c83b4ceb4be0e"
|
||||
checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@@ -1237,9 +1237,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.56"
|
||||
version = "4.5.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793207c7fa6300a0608d1080b858e5fdbe713cdc1c8db9fb17777d8a13e63df0"
|
||||
checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -1271,9 +1271,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.7"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32"
|
||||
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||
|
||||
[[package]]
|
||||
name = "clipboard-win"
|
||||
@@ -3293,7 +3293,7 @@ dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users 0.5.2",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3489,9 +3489,9 @@ checksum = "dbfd0e7fc632dec5e6c9396a27bc9f9975b4e039720e1fd3e34021d3ce28c415"
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.4"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2"
|
||||
checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
@@ -3505,9 +3505,9 @@ checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.8"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
|
||||
checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -3538,7 +3538,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4931,7 +4931,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5639,7 +5639,7 @@ version = "0.50.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6205,7 +6205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6766,7 +6766,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"socket2 0.6.2",
|
||||
"tracing",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7592,7 +7592,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.11.0",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8969,7 +8969,7 @@ dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"once_cell",
|
||||
"rustix 1.1.3",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -10329,7 +10329,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -170,7 +170,7 @@ dotenvy = "0.15.7"
|
||||
dunce = "1.0.4"
|
||||
encoding_rs = "0.8.35"
|
||||
env-flags = "0.1.1"
|
||||
env_logger = "0.11.5"
|
||||
env_logger = "0.11.9"
|
||||
eventsource-stream = "0.2.3"
|
||||
futures = { version = "0.3", default-features = false }
|
||||
globset = "0.4"
|
||||
|
||||
@@ -711,6 +711,15 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HazelnutScope": {
|
||||
"enum": [
|
||||
"example",
|
||||
"workspace-shared",
|
||||
"all-shared",
|
||||
"personal"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"InitializeCapabilities": {
|
||||
"description": "Client-declared capabilities negotiated during initialize.",
|
||||
"properties": {
|
||||
@@ -1250,6 +1259,15 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ProductSurface": {
|
||||
"enum": [
|
||||
"chatgpt",
|
||||
"codex",
|
||||
"api",
|
||||
"atlas"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ReadOnlyAccess": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -2421,20 +2439,38 @@
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsRemoteReadParams": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"hazelnutScope": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/HazelnutScope"
|
||||
}
|
||||
],
|
||||
"default": "example"
|
||||
},
|
||||
"productSurface": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ProductSurface"
|
||||
}
|
||||
],
|
||||
"default": "codex"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsRemoteWriteParams": {
|
||||
"properties": {
|
||||
"hazelnutId": {
|
||||
"type": "string"
|
||||
},
|
||||
"isPreload": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"hazelnutId",
|
||||
"isPreload"
|
||||
"hazelnutId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
@@ -3599,9 +3635,9 @@
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"skills/remote/read"
|
||||
"skills/remote/list"
|
||||
],
|
||||
"title": "Skills/remote/readRequestMethod",
|
||||
"title": "Skills/remote/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
@@ -3613,7 +3649,7 @@
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Skills/remote/readRequest",
|
||||
"title": "Skills/remote/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
@@ -3623,9 +3659,9 @@
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"skills/remote/write"
|
||||
"skills/remote/export"
|
||||
],
|
||||
"title": "Skills/remote/writeRequestMethod",
|
||||
"title": "Skills/remote/exportRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
@@ -3637,7 +3673,7 @@
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Skills/remote/writeRequest",
|
||||
"title": "Skills/remote/exportRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -113,6 +113,13 @@
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"approvalId": {
|
||||
"description": "Unique identifier for this specific approval callback.\n\nFor regular shell/unified_exec approvals, this is null.\n\nFor zsh-exec-bridge subcommand approvals, multiple callbacks can belong to one parent `itemId`, so `approvalId` is a distinct opaque callback id (a UUID) used to disambiguate routing.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"command": {
|
||||
"description": "The command to be executed.",
|
||||
"type": [
|
||||
|
||||
@@ -473,6 +473,35 @@
|
||||
"title": "WarningEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Model routing changed from the requested model to a different model.",
|
||||
"properties": {
|
||||
"from_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/ModelRerouteReason"
|
||||
},
|
||||
"to_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"model_reroute"
|
||||
],
|
||||
"title": "ModelRerouteEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"from_model",
|
||||
"reason",
|
||||
"to_model",
|
||||
"type"
|
||||
],
|
||||
"title": "ModelRerouteEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Conversation history was compacted (either automatically or manually).",
|
||||
"properties": {
|
||||
@@ -1423,8 +1452,15 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"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": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"call_id": {
|
||||
"description": "Identifier for the associated exec call, if available.",
|
||||
"description": "Identifier for the associated command execution item.",
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
@@ -3318,6 +3354,12 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ModelRerouteReason": {
|
||||
"enum": [
|
||||
"high_risk_cyber_activity"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"description": "Represents whether outbound network access is available to the agent.",
|
||||
"enum": [
|
||||
@@ -5378,6 +5420,35 @@
|
||||
"title": "WarningEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Model routing changed from the requested model to a different model.",
|
||||
"properties": {
|
||||
"from_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/ModelRerouteReason"
|
||||
},
|
||||
"to_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"model_reroute"
|
||||
],
|
||||
"title": "ModelRerouteEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"from_model",
|
||||
"reason",
|
||||
"to_model",
|
||||
"type"
|
||||
],
|
||||
"title": "ModelRerouteEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Conversation history was compacted (either automatically or manually).",
|
||||
"properties": {
|
||||
@@ -6328,8 +6399,15 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"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": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"call_id": {
|
||||
"description": "Identifier for the associated exec call, if available.",
|
||||
"description": "Identifier for the associated command execution item.",
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
|
||||
@@ -117,6 +117,13 @@
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"approvalId": {
|
||||
"description": "Identifier for this specific approval callback.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"callId": {
|
||||
"description": "Use to correlate this with [codex_core::protocol::ExecCommandBeginEvent] and [codex_core::protocol::ExecCommandEndEvent].",
|
||||
"type": "string"
|
||||
|
||||
@@ -165,9 +165,71 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"AppBranding": {
|
||||
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
|
||||
"properties": {
|
||||
"category": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"developer": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"isDiscoverableApp": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"privacyPolicy": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"termsOfService": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"website": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"isDiscoverableApp"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppInfo": {
|
||||
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
|
||||
"properties": {
|
||||
"appMetadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AppMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"branding": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AppBranding"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -198,6 +260,15 @@
|
||||
"description": "Whether this app is enabled in config.toml. Example: ```toml [apps.bad_app] enabled = false ```",
|
||||
"type": "boolean"
|
||||
},
|
||||
"labels": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"logoUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -235,6 +306,130 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppMetadata": {
|
||||
"properties": {
|
||||
"categories": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"developer": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"firstPartyRequiresInstall": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"firstPartyType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"review": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AppReview"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"screenshots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AppScreenshot"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"seoDescription": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"showInComposerWhenUnlinked": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"subCategories": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"versionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"versionNotes": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AppReview": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppScreenshot": {
|
||||
"properties": {
|
||||
"fileId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"userPrompt": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"userPrompt"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AskForApproval": {
|
||||
"description": "Determines the conditions under which the user is consulted to approve running the command proposed by Codex.",
|
||||
"oneOf": [
|
||||
@@ -1094,6 +1289,35 @@
|
||||
"title": "WarningEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Model routing changed from the requested model to a different model.",
|
||||
"properties": {
|
||||
"from_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/ModelRerouteReason2"
|
||||
},
|
||||
"to_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"model_reroute"
|
||||
],
|
||||
"title": "ModelRerouteEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"from_model",
|
||||
"reason",
|
||||
"to_model",
|
||||
"type"
|
||||
],
|
||||
"title": "ModelRerouteEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Conversation history was compacted (either automatically or manually).",
|
||||
"properties": {
|
||||
@@ -2044,8 +2268,15 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"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": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"call_id": {
|
||||
"description": "Identifier for the associated exec call, if available.",
|
||||
"description": "Identifier for the associated command execution item.",
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
@@ -4184,6 +4415,13 @@
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase2": {
|
||||
"description": "Classifies an assistant message as interim commentary or final answer text.\n\nProviders do not emit this consistently, so callers must treat `None` as \"phase unknown\" and keep compatibility behavior for legacy models.",
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -4210,6 +4448,45 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ModelRerouteReason": {
|
||||
"enum": [
|
||||
"highRiskCyberActivity"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ModelRerouteReason2": {
|
||||
"enum": [
|
||||
"high_risk_cyber_activity"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ModelReroutedNotification": {
|
||||
"properties": {
|
||||
"fromModel": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/ModelRerouteReason"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
},
|
||||
"toModel": {
|
||||
"type": "string"
|
||||
},
|
||||
"turnId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fromModel",
|
||||
"reason",
|
||||
"threadId",
|
||||
"toModel",
|
||||
"turnId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"description": "Represents whether outbound network access is available to the agent.",
|
||||
"enum": [
|
||||
@@ -5074,7 +5351,7 @@
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
"$ref": "#/definitions/MessagePhase2"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
@@ -6276,6 +6553,17 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadArchivedNotification": {
|
||||
"properties": {
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -6313,6 +6601,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -6820,6 +7119,17 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadUnarchivedNotification": {
|
||||
"properties": {
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"TokenUsage": {
|
||||
"properties": {
|
||||
"cached_input_tokens": {
|
||||
@@ -7091,7 +7401,7 @@
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
"$ref": "#/definitions/MessagePhase2"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
@@ -7813,6 +8123,46 @@
|
||||
"title": "Thread/startedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/archived"
|
||||
],
|
||||
"title": "Thread/archivedNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ThreadArchivedNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/archivedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/unarchived"
|
||||
],
|
||||
"title": "Thread/unarchivedNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ThreadUnarchivedNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/unarchivedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
@@ -8276,6 +8626,26 @@
|
||||
"title": "Thread/compactedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"model/rerouted"
|
||||
],
|
||||
"title": "Model/reroutedNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ModelReroutedNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Model/reroutedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
|
||||
@@ -179,6 +179,13 @@
|
||||
},
|
||||
"CommandExecutionRequestApprovalParams": {
|
||||
"properties": {
|
||||
"approvalId": {
|
||||
"description": "Unique identifier for this specific approval callback.\n\nFor regular shell/unified_exec approvals, this is null.\n\nFor zsh-exec-bridge subcommand approvals, multiple callbacks can belong to one parent `itemId`, so `approvalId` is a distinct opaque callback id (a UUID) used to disambiguate routing.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"command": {
|
||||
"description": "The command to be executed.",
|
||||
"type": [
|
||||
@@ -264,6 +271,13 @@
|
||||
},
|
||||
"ExecCommandApprovalParams": {
|
||||
"properties": {
|
||||
"approvalId": {
|
||||
"description": "Identifier for this specific approval callback.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"callId": {
|
||||
"description": "Use to correlate this with [codex_core::protocol::ExecCommandBeginEvent] and [codex_core::protocol::ExecCommandEndEvent].",
|
||||
"type": "string"
|
||||
|
||||
@@ -755,9 +755,9 @@
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"skills/remote/read"
|
||||
"skills/remote/list"
|
||||
],
|
||||
"title": "Skills/remote/readRequestMethod",
|
||||
"title": "Skills/remote/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
@@ -769,7 +769,7 @@
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Skills/remote/readRequest",
|
||||
"title": "Skills/remote/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
@@ -779,9 +779,9 @@
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"skills/remote/write"
|
||||
"skills/remote/export"
|
||||
],
|
||||
"title": "Skills/remote/writeRequestMethod",
|
||||
"title": "Skills/remote/exportRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
@@ -793,7 +793,7 @@
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Skills/remote/writeRequest",
|
||||
"title": "Skills/remote/exportRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
@@ -2051,6 +2051,13 @@
|
||||
"CommandExecutionRequestApprovalParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"approvalId": {
|
||||
"description": "Unique identifier for this specific approval callback.\n\nFor regular shell/unified_exec approvals, this is null.\n\nFor zsh-exec-bridge subcommand approvals, multiple callbacks can belong to one parent `itemId`, so `approvalId` is a distinct opaque callback id (a UUID) used to disambiguate routing.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"command": {
|
||||
"description": "The command to be executed.",
|
||||
"type": [
|
||||
@@ -2486,6 +2493,35 @@
|
||||
"title": "WarningEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Model routing changed from the requested model to a different model.",
|
||||
"properties": {
|
||||
"from_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/v2/ModelRerouteReason"
|
||||
},
|
||||
"to_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"model_reroute"
|
||||
],
|
||||
"title": "ModelRerouteEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"from_model",
|
||||
"reason",
|
||||
"to_model",
|
||||
"type"
|
||||
],
|
||||
"title": "ModelRerouteEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Conversation history was compacted (either automatically or manually).",
|
||||
"properties": {
|
||||
@@ -3436,8 +3472,15 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"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": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"call_id": {
|
||||
"description": "Identifier for the associated exec call, if available.",
|
||||
"description": "Identifier for the associated command execution item.",
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
@@ -4910,6 +4953,13 @@
|
||||
"ExecCommandApprovalParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"approvalId": {
|
||||
"description": "Identifier for this specific approval callback.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"callId": {
|
||||
"description": "Use to correlate this with [codex_core::protocol::ExecCommandBeginEvent] and [codex_core::protocol::ExecCommandEndEvent].",
|
||||
"type": "string"
|
||||
@@ -6266,6 +6316,12 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ModelRerouteReason": {
|
||||
"enum": [
|
||||
"high_risk_cyber_activity"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"description": "Represents whether outbound network access is available to the agent.",
|
||||
"enum": [
|
||||
@@ -8028,6 +8084,46 @@
|
||||
"title": "Thread/startedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/archived"
|
||||
],
|
||||
"title": "Thread/archivedNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/ThreadArchivedNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/archivedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/unarchived"
|
||||
],
|
||||
"title": "Thread/unarchivedNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/ThreadUnarchivedNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/unarchivedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
@@ -8491,6 +8587,26 @@
|
||||
"title": "Thread/compactedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
"model/rerouted"
|
||||
],
|
||||
"title": "Model/reroutedNotificationMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/ModelReroutedNotification"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Model/reroutedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"method": {
|
||||
@@ -10216,6 +10332,48 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AppBranding": {
|
||||
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
|
||||
"properties": {
|
||||
"category": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"developer": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"isDiscoverableApp": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"privacyPolicy": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"termsOfService": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"website": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"isDiscoverableApp"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppConfig": {
|
||||
"properties": {
|
||||
"disabled_reason": {
|
||||
@@ -10245,6 +10403,26 @@
|
||||
"AppInfo": {
|
||||
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
|
||||
"properties": {
|
||||
"appMetadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AppMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"branding": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AppBranding"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -10275,6 +10453,15 @@
|
||||
"description": "Whether this app is enabled in config.toml. Example: ```toml [apps.bad_app] enabled = false ```",
|
||||
"type": "boolean"
|
||||
},
|
||||
"labels": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"logoUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -10314,6 +10501,130 @@
|
||||
"title": "AppListUpdatedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"AppMetadata": {
|
||||
"properties": {
|
||||
"categories": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"developer": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"firstPartyRequiresInstall": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"firstPartyType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"review": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AppReview"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"screenshots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/AppScreenshot"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"seoDescription": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"showInComposerWhenUnlinked": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"subCategories": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"versionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"versionNotes": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AppReview": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppScreenshot": {
|
||||
"properties": {
|
||||
"fileId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"userPrompt": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"userPrompt"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppsConfig": {
|
||||
"type": "object"
|
||||
},
|
||||
@@ -12114,6 +12425,15 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"HazelnutScope": {
|
||||
"enum": [
|
||||
"example",
|
||||
"workspace-shared",
|
||||
"all-shared",
|
||||
"personal"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"InputModality": {
|
||||
"description": "Canonical user-input modality tags advertised by a model.",
|
||||
"oneOf": [
|
||||
@@ -12750,6 +13070,41 @@
|
||||
"title": "ModelListResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"ModelRerouteReason": {
|
||||
"enum": [
|
||||
"highRiskCyberActivity"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ModelReroutedNotification": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"fromModel": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/v2/ModelRerouteReason"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
},
|
||||
"toModel": {
|
||||
"type": "string"
|
||||
},
|
||||
"turnId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fromModel",
|
||||
"reason",
|
||||
"threadId",
|
||||
"toModel",
|
||||
"turnId"
|
||||
],
|
||||
"title": "ModelReroutedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"enum": [
|
||||
"restricted",
|
||||
@@ -12967,6 +13322,15 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ProductSurface": {
|
||||
"enum": [
|
||||
"chatgpt",
|
||||
"codex",
|
||||
"api",
|
||||
"atlas"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ProfileV2": {
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
@@ -14498,6 +14862,28 @@
|
||||
},
|
||||
"SkillsRemoteReadParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"hazelnutScope": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/HazelnutScope"
|
||||
}
|
||||
],
|
||||
"default": "example"
|
||||
},
|
||||
"productSurface": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ProductSurface"
|
||||
}
|
||||
],
|
||||
"default": "codex"
|
||||
}
|
||||
},
|
||||
"title": "SkillsRemoteReadParams",
|
||||
"type": "object"
|
||||
},
|
||||
@@ -14522,14 +14908,10 @@
|
||||
"properties": {
|
||||
"hazelnutId": {
|
||||
"type": "string"
|
||||
},
|
||||
"isPreload": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"hazelnutId",
|
||||
"isPreload"
|
||||
"hazelnutId"
|
||||
],
|
||||
"title": "SkillsRemoteWriteParams",
|
||||
"type": "object"
|
||||
@@ -14540,16 +14922,12 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"path"
|
||||
],
|
||||
"title": "SkillsRemoteWriteResponse",
|
||||
@@ -14790,6 +15168,19 @@
|
||||
"title": "ThreadArchiveResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadArchivedNotification": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadArchivedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadCompactStartParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
@@ -14960,6 +15351,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -15998,6 +16400,19 @@
|
||||
"title": "ThreadUnarchiveResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadUnarchivedNotification": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadUnarchivedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"TokenUsageBreakdown": {
|
||||
"properties": {
|
||||
"cachedInputTokens": {
|
||||
|
||||
@@ -473,6 +473,35 @@
|
||||
"title": "WarningEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Model routing changed from the requested model to a different model.",
|
||||
"properties": {
|
||||
"from_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/ModelRerouteReason"
|
||||
},
|
||||
"to_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"model_reroute"
|
||||
],
|
||||
"title": "ModelRerouteEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"from_model",
|
||||
"reason",
|
||||
"to_model",
|
||||
"type"
|
||||
],
|
||||
"title": "ModelRerouteEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Conversation history was compacted (either automatically or manually).",
|
||||
"properties": {
|
||||
@@ -1423,8 +1452,15 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"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": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"call_id": {
|
||||
"description": "Identifier for the associated exec call, if available.",
|
||||
"description": "Identifier for the associated command execution item.",
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
@@ -3318,6 +3354,12 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ModelRerouteReason": {
|
||||
"enum": [
|
||||
"high_risk_cyber_activity"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"description": "Represents whether outbound network access is available to the agent.",
|
||||
"enum": [
|
||||
|
||||
@@ -473,6 +473,35 @@
|
||||
"title": "WarningEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Model routing changed from the requested model to a different model.",
|
||||
"properties": {
|
||||
"from_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/ModelRerouteReason"
|
||||
},
|
||||
"to_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"model_reroute"
|
||||
],
|
||||
"title": "ModelRerouteEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"from_model",
|
||||
"reason",
|
||||
"to_model",
|
||||
"type"
|
||||
],
|
||||
"title": "ModelRerouteEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Conversation history was compacted (either automatically or manually).",
|
||||
"properties": {
|
||||
@@ -1423,8 +1452,15 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"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": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"call_id": {
|
||||
"description": "Identifier for the associated exec call, if available.",
|
||||
"description": "Identifier for the associated command execution item.",
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
@@ -3318,6 +3354,12 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ModelRerouteReason": {
|
||||
"enum": [
|
||||
"high_risk_cyber_activity"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"description": "Represents whether outbound network access is available to the agent.",
|
||||
"enum": [
|
||||
|
||||
@@ -473,6 +473,35 @@
|
||||
"title": "WarningEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Model routing changed from the requested model to a different model.",
|
||||
"properties": {
|
||||
"from_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/ModelRerouteReason"
|
||||
},
|
||||
"to_model": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"model_reroute"
|
||||
],
|
||||
"title": "ModelRerouteEventMsgType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"from_model",
|
||||
"reason",
|
||||
"to_model",
|
||||
"type"
|
||||
],
|
||||
"title": "ModelRerouteEventMsg",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Conversation history was compacted (either automatically or manually).",
|
||||
"properties": {
|
||||
@@ -1423,8 +1452,15 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"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": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"call_id": {
|
||||
"description": "Identifier for the associated exec call, if available.",
|
||||
"description": "Identifier for the associated command execution item.",
|
||||
"type": "string"
|
||||
},
|
||||
"command": {
|
||||
@@ -3318,6 +3354,12 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ModelRerouteReason": {
|
||||
"enum": [
|
||||
"high_risk_cyber_activity"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"description": "Represents whether outbound network access is available to the agent.",
|
||||
"enum": [
|
||||
|
||||
@@ -1,9 +1,71 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"AppBranding": {
|
||||
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
|
||||
"properties": {
|
||||
"category": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"developer": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"isDiscoverableApp": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"privacyPolicy": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"termsOfService": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"website": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"isDiscoverableApp"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppInfo": {
|
||||
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
|
||||
"properties": {
|
||||
"appMetadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AppMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"branding": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AppBranding"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -34,6 +96,15 @@
|
||||
"description": "Whether this app is enabled in config.toml. Example: ```toml [apps.bad_app] enabled = false ```",
|
||||
"type": "boolean"
|
||||
},
|
||||
"labels": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"logoUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -55,6 +126,130 @@
|
||||
"name"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppMetadata": {
|
||||
"properties": {
|
||||
"categories": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"developer": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"firstPartyRequiresInstall": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"firstPartyType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"review": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AppReview"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"screenshots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AppScreenshot"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"seoDescription": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"showInComposerWhenUnlinked": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"subCategories": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"versionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"versionNotes": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AppReview": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppScreenshot": {
|
||||
"properties": {
|
||||
"fileId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"userPrompt": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"userPrompt"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"description": "EXPERIMENTAL - notification emitted when the app list changes.",
|
||||
|
||||
@@ -1,9 +1,71 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"AppBranding": {
|
||||
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
|
||||
"properties": {
|
||||
"category": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"developer": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"isDiscoverableApp": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"privacyPolicy": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"termsOfService": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"website": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"isDiscoverableApp"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppInfo": {
|
||||
"description": "EXPERIMENTAL - app metadata returned by app-list APIs.",
|
||||
"properties": {
|
||||
"appMetadata": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AppMetadata"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"branding": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AppBranding"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -34,6 +96,15 @@
|
||||
"description": "Whether this app is enabled in config.toml. Example: ```toml [apps.bad_app] enabled = false ```",
|
||||
"type": "boolean"
|
||||
},
|
||||
"labels": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"object",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"logoUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -55,6 +126,130 @@
|
||||
"name"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppMetadata": {
|
||||
"properties": {
|
||||
"categories": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"developer": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"firstPartyRequiresInstall": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"firstPartyType": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"review": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AppReview"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"screenshots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AppScreenshot"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"seoDescription": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"showInComposerWhenUnlinked": {
|
||||
"type": [
|
||||
"boolean",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"subCategories": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"versionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"versionNotes": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"AppReview": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"status"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AppScreenshot": {
|
||||
"properties": {
|
||||
"fileId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"url": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"userPrompt": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"userPrompt"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"description": "EXPERIMENTAL - app list response.",
|
||||
|
||||
@@ -236,6 +236,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -360,6 +367,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -236,6 +236,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -360,6 +367,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"ModelRerouteReason": {
|
||||
"enum": [
|
||||
"highRiskCyberActivity"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"fromModel": {
|
||||
"type": "string"
|
||||
},
|
||||
"reason": {
|
||||
"$ref": "#/definitions/ModelRerouteReason"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
},
|
||||
"toModel": {
|
||||
"type": "string"
|
||||
},
|
||||
"turnId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fromModel",
|
||||
"reason",
|
||||
"threadId",
|
||||
"toModel",
|
||||
"turnId"
|
||||
],
|
||||
"title": "ModelReroutedNotification",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -350,6 +350,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -474,6 +481,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,47 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"HazelnutScope": {
|
||||
"enum": [
|
||||
"example",
|
||||
"workspace-shared",
|
||||
"all-shared",
|
||||
"personal"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ProductSurface": {
|
||||
"enum": [
|
||||
"chatgpt",
|
||||
"codex",
|
||||
"api",
|
||||
"atlas"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"hazelnutScope": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/HazelnutScope"
|
||||
}
|
||||
],
|
||||
"default": "example"
|
||||
},
|
||||
"productSurface": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ProductSurface"
|
||||
}
|
||||
],
|
||||
"default": "codex"
|
||||
}
|
||||
},
|
||||
"title": "SkillsRemoteReadParams",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -3,14 +3,10 @@
|
||||
"properties": {
|
||||
"hazelnutId": {
|
||||
"type": "string"
|
||||
},
|
||||
"isPreload": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"hazelnutId",
|
||||
"isPreload"
|
||||
"hazelnutId"
|
||||
],
|
||||
"title": "SkillsRemoteWriteParams",
|
||||
"type": "object"
|
||||
|
||||
@@ -4,16 +4,12 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"path"
|
||||
],
|
||||
"title": "SkillsRemoteWriteResponse",
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadArchivedNotification",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -386,6 +386,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"enum": [
|
||||
"restricted",
|
||||
@@ -850,6 +857,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -373,6 +373,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -656,6 +663,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -373,6 +373,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -656,6 +663,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -386,6 +386,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"enum": [
|
||||
"restricted",
|
||||
@@ -850,6 +857,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -373,6 +373,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -656,6 +663,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -386,6 +386,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"NetworkAccess": {
|
||||
"enum": [
|
||||
"restricted",
|
||||
@@ -850,6 +857,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -373,6 +373,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -656,6 +663,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -373,6 +373,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -656,6 +663,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadUnarchivedNotification",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -350,6 +350,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -474,6 +481,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -350,6 +350,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -474,6 +481,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -350,6 +350,13 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"MessagePhase": {
|
||||
"enum": [
|
||||
"commentary",
|
||||
"finalAnswer"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PatchApplyStatus": {
|
||||
"enum": [
|
||||
"inProgress",
|
||||
@@ -474,6 +481,17 @@
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"phase": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/MessagePhase"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -57,4 +57,4 @@ import type { TurnSteerParams } from "./v2/TurnSteerParams";
|
||||
/**
|
||||
* Request from the client to the server.
|
||||
*/
|
||||
export type ClientRequest ={ "method": "initialize", id: RequestId, params: InitializeParams, } | { "method": "thread/start", id: RequestId, params: ThreadStartParams, } | { "method": "thread/resume", id: RequestId, params: ThreadResumeParams, } | { "method": "thread/fork", id: RequestId, params: ThreadForkParams, } | { "method": "thread/archive", id: RequestId, params: ThreadArchiveParams, } | { "method": "thread/name/set", id: RequestId, params: ThreadSetNameParams, } | { "method": "thread/unarchive", id: RequestId, params: ThreadUnarchiveParams, } | { "method": "thread/compact/start", id: RequestId, params: ThreadCompactStartParams, } | { "method": "thread/rollback", id: RequestId, params: ThreadRollbackParams, } | { "method": "thread/list", id: RequestId, params: ThreadListParams, } | { "method": "thread/loaded/list", id: RequestId, params: ThreadLoadedListParams, } | { "method": "thread/read", id: RequestId, params: ThreadReadParams, } | { "method": "skills/list", id: RequestId, params: SkillsListParams, } | { "method": "skills/remote/read", id: RequestId, params: SkillsRemoteReadParams, } | { "method": "skills/remote/write", id: RequestId, params: SkillsRemoteWriteParams, } | { "method": "app/list", id: RequestId, params: AppsListParams, } | { "method": "skills/config/write", id: RequestId, params: SkillsConfigWriteParams, } | { "method": "turn/start", id: RequestId, params: TurnStartParams, } | { "method": "turn/steer", id: RequestId, params: TurnSteerParams, } | { "method": "turn/interrupt", id: RequestId, params: TurnInterruptParams, } | { "method": "review/start", id: RequestId, params: ReviewStartParams, } | { "method": "model/list", id: RequestId, params: ModelListParams, } | { "method": "experimentalFeature/list", id: RequestId, params: ExperimentalFeatureListParams, } | { "method": "mcpServer/oauth/login", id: RequestId, params: McpServerOauthLoginParams, } | { "method": "config/mcpServer/reload", id: RequestId, params: undefined, } | { "method": "mcpServerStatus/list", id: RequestId, params: ListMcpServerStatusParams, } | { "method": "account/login/start", id: RequestId, params: LoginAccountParams, } | { "method": "account/login/cancel", id: RequestId, params: CancelLoginAccountParams, } | { "method": "account/logout", id: RequestId, params: undefined, } | { "method": "account/rateLimits/read", id: RequestId, params: undefined, } | { "method": "feedback/upload", id: RequestId, params: FeedbackUploadParams, } | { "method": "command/exec", id: RequestId, params: CommandExecParams, } | { "method": "config/read", id: RequestId, params: ConfigReadParams, } | { "method": "config/value/write", id: RequestId, params: ConfigValueWriteParams, } | { "method": "config/batchWrite", id: RequestId, params: ConfigBatchWriteParams, } | { "method": "configRequirements/read", id: RequestId, params: undefined, } | { "method": "account/read", id: RequestId, params: GetAccountParams, } | { "method": "newConversation", id: RequestId, params: NewConversationParams, } | { "method": "getConversationSummary", id: RequestId, params: GetConversationSummaryParams, } | { "method": "listConversations", id: RequestId, params: ListConversationsParams, } | { "method": "resumeConversation", id: RequestId, params: ResumeConversationParams, } | { "method": "forkConversation", id: RequestId, params: ForkConversationParams, } | { "method": "archiveConversation", id: RequestId, params: ArchiveConversationParams, } | { "method": "sendUserMessage", id: RequestId, params: SendUserMessageParams, } | { "method": "sendUserTurn", id: RequestId, params: SendUserTurnParams, } | { "method": "interruptConversation", id: RequestId, params: InterruptConversationParams, } | { "method": "addConversationListener", id: RequestId, params: AddConversationListenerParams, } | { "method": "removeConversationListener", id: RequestId, params: RemoveConversationListenerParams, } | { "method": "gitDiffToRemote", id: RequestId, params: GitDiffToRemoteParams, } | { "method": "loginApiKey", id: RequestId, params: LoginApiKeyParams, } | { "method": "loginChatGpt", id: RequestId, params: undefined, } | { "method": "cancelLoginChatGpt", id: RequestId, params: CancelLoginChatGptParams, } | { "method": "logoutChatGpt", id: RequestId, params: undefined, } | { "method": "getAuthStatus", id: RequestId, params: GetAuthStatusParams, } | { "method": "getUserSavedConfig", id: RequestId, params: undefined, } | { "method": "setDefaultModel", id: RequestId, params: SetDefaultModelParams, } | { "method": "getUserAgent", id: RequestId, params: undefined, } | { "method": "userInfo", id: RequestId, params: undefined, } | { "method": "fuzzyFileSearch", id: RequestId, params: FuzzyFileSearchParams, } | { "method": "execOneOffCommand", id: RequestId, params: ExecOneOffCommandParams, };
|
||||
export type ClientRequest ={ "method": "initialize", id: RequestId, params: InitializeParams, } | { "method": "thread/start", id: RequestId, params: ThreadStartParams, } | { "method": "thread/resume", id: RequestId, params: ThreadResumeParams, } | { "method": "thread/fork", id: RequestId, params: ThreadForkParams, } | { "method": "thread/archive", id: RequestId, params: ThreadArchiveParams, } | { "method": "thread/name/set", id: RequestId, params: ThreadSetNameParams, } | { "method": "thread/unarchive", id: RequestId, params: ThreadUnarchiveParams, } | { "method": "thread/compact/start", id: RequestId, params: ThreadCompactStartParams, } | { "method": "thread/rollback", id: RequestId, params: ThreadRollbackParams, } | { "method": "thread/list", id: RequestId, params: ThreadListParams, } | { "method": "thread/loaded/list", id: RequestId, params: ThreadLoadedListParams, } | { "method": "thread/read", id: RequestId, params: ThreadReadParams, } | { "method": "skills/list", id: RequestId, params: SkillsListParams, } | { "method": "skills/remote/list", id: RequestId, params: SkillsRemoteReadParams, } | { "method": "skills/remote/export", id: RequestId, params: SkillsRemoteWriteParams, } | { "method": "app/list", id: RequestId, params: AppsListParams, } | { "method": "skills/config/write", id: RequestId, params: SkillsConfigWriteParams, } | { "method": "turn/start", id: RequestId, params: TurnStartParams, } | { "method": "turn/steer", id: RequestId, params: TurnSteerParams, } | { "method": "turn/interrupt", id: RequestId, params: TurnInterruptParams, } | { "method": "review/start", id: RequestId, params: ReviewStartParams, } | { "method": "model/list", id: RequestId, params: ModelListParams, } | { "method": "experimentalFeature/list", id: RequestId, params: ExperimentalFeatureListParams, } | { "method": "mcpServer/oauth/login", id: RequestId, params: McpServerOauthLoginParams, } | { "method": "config/mcpServer/reload", id: RequestId, params: undefined, } | { "method": "mcpServerStatus/list", id: RequestId, params: ListMcpServerStatusParams, } | { "method": "account/login/start", id: RequestId, params: LoginAccountParams, } | { "method": "account/login/cancel", id: RequestId, params: CancelLoginAccountParams, } | { "method": "account/logout", id: RequestId, params: undefined, } | { "method": "account/rateLimits/read", id: RequestId, params: undefined, } | { "method": "feedback/upload", id: RequestId, params: FeedbackUploadParams, } | { "method": "command/exec", id: RequestId, params: CommandExecParams, } | { "method": "config/read", id: RequestId, params: ConfigReadParams, } | { "method": "config/value/write", id: RequestId, params: ConfigValueWriteParams, } | { "method": "config/batchWrite", id: RequestId, params: ConfigBatchWriteParams, } | { "method": "configRequirements/read", id: RequestId, params: undefined, } | { "method": "account/read", id: RequestId, params: GetAccountParams, } | { "method": "newConversation", id: RequestId, params: NewConversationParams, } | { "method": "getConversationSummary", id: RequestId, params: GetConversationSummaryParams, } | { "method": "listConversations", id: RequestId, params: ListConversationsParams, } | { "method": "resumeConversation", id: RequestId, params: ResumeConversationParams, } | { "method": "forkConversation", id: RequestId, params: ForkConversationParams, } | { "method": "archiveConversation", id: RequestId, params: ArchiveConversationParams, } | { "method": "sendUserMessage", id: RequestId, params: SendUserMessageParams, } | { "method": "sendUserTurn", id: RequestId, params: SendUserTurnParams, } | { "method": "interruptConversation", id: RequestId, params: InterruptConversationParams, } | { "method": "addConversationListener", id: RequestId, params: AddConversationListenerParams, } | { "method": "removeConversationListener", id: RequestId, params: RemoveConversationListenerParams, } | { "method": "gitDiffToRemote", id: RequestId, params: GitDiffToRemoteParams, } | { "method": "loginApiKey", id: RequestId, params: LoginApiKeyParams, } | { "method": "loginChatGpt", id: RequestId, params: undefined, } | { "method": "cancelLoginChatGpt", id: RequestId, params: CancelLoginChatGptParams, } | { "method": "logoutChatGpt", id: RequestId, params: undefined, } | { "method": "getAuthStatus", id: RequestId, params: GetAuthStatusParams, } | { "method": "getUserSavedConfig", id: RequestId, params: undefined, } | { "method": "setDefaultModel", id: RequestId, params: SetDefaultModelParams, } | { "method": "getUserAgent", id: RequestId, params: undefined, } | { "method": "userInfo", id: RequestId, params: undefined, } | { "method": "fuzzyFileSearch", id: RequestId, params: FuzzyFileSearchParams, } | { "method": "execOneOffCommand", id: RequestId, params: ExecOneOffCommandParams, };
|
||||
|
||||
@@ -42,6 +42,7 @@ import type { McpStartupCompleteEvent } from "./McpStartupCompleteEvent";
|
||||
import type { McpStartupUpdateEvent } from "./McpStartupUpdateEvent";
|
||||
import type { McpToolCallBeginEvent } from "./McpToolCallBeginEvent";
|
||||
import type { McpToolCallEndEvent } from "./McpToolCallEndEvent";
|
||||
import type { ModelRerouteEvent } from "./ModelRerouteEvent";
|
||||
import type { PatchApplyBeginEvent } from "./PatchApplyBeginEvent";
|
||||
import type { PatchApplyEndEvent } from "./PatchApplyEndEvent";
|
||||
import type { PlanDeltaEvent } from "./PlanDeltaEvent";
|
||||
@@ -74,4 +75,4 @@ import type { WebSearchEndEvent } from "./WebSearchEndEvent";
|
||||
* Response event from the agent
|
||||
* NOTE: Make sure none of these values have optional types, as it will mess up the extension code-gen.
|
||||
*/
|
||||
export type EventMsg = { "type": "error" } & ErrorEvent | { "type": "warning" } & WarningEvent | { "type": "context_compacted" } & ContextCompactedEvent | { "type": "thread_rolled_back" } & ThreadRolledBackEvent | { "type": "task_started" } & TurnStartedEvent | { "type": "task_complete" } & TurnCompleteEvent | { "type": "token_count" } & TokenCountEvent | { "type": "agent_message" } & AgentMessageEvent | { "type": "user_message" } & UserMessageEvent | { "type": "agent_message_delta" } & AgentMessageDeltaEvent | { "type": "agent_reasoning" } & AgentReasoningEvent | { "type": "agent_reasoning_delta" } & AgentReasoningDeltaEvent | { "type": "agent_reasoning_raw_content" } & AgentReasoningRawContentEvent | { "type": "agent_reasoning_raw_content_delta" } & AgentReasoningRawContentDeltaEvent | { "type": "agent_reasoning_section_break" } & AgentReasoningSectionBreakEvent | { "type": "session_configured" } & SessionConfiguredEvent | { "type": "thread_name_updated" } & ThreadNameUpdatedEvent | { "type": "mcp_startup_update" } & McpStartupUpdateEvent | { "type": "mcp_startup_complete" } & McpStartupCompleteEvent | { "type": "mcp_tool_call_begin" } & McpToolCallBeginEvent | { "type": "mcp_tool_call_end" } & McpToolCallEndEvent | { "type": "web_search_begin" } & WebSearchBeginEvent | { "type": "web_search_end" } & WebSearchEndEvent | { "type": "exec_command_begin" } & ExecCommandBeginEvent | { "type": "exec_command_output_delta" } & ExecCommandOutputDeltaEvent | { "type": "terminal_interaction" } & TerminalInteractionEvent | { "type": "exec_command_end" } & ExecCommandEndEvent | { "type": "view_image_tool_call" } & ViewImageToolCallEvent | { "type": "exec_approval_request" } & ExecApprovalRequestEvent | { "type": "request_user_input" } & RequestUserInputEvent | { "type": "dynamic_tool_call_request" } & DynamicToolCallRequest | { "type": "elicitation_request" } & ElicitationRequestEvent | { "type": "apply_patch_approval_request" } & ApplyPatchApprovalRequestEvent | { "type": "deprecation_notice" } & DeprecationNoticeEvent | { "type": "background_event" } & BackgroundEventEvent | { "type": "undo_started" } & UndoStartedEvent | { "type": "undo_completed" } & UndoCompletedEvent | { "type": "stream_error" } & StreamErrorEvent | { "type": "patch_apply_begin" } & PatchApplyBeginEvent | { "type": "patch_apply_end" } & PatchApplyEndEvent | { "type": "turn_diff" } & TurnDiffEvent | { "type": "get_history_entry_response" } & GetHistoryEntryResponseEvent | { "type": "mcp_list_tools_response" } & McpListToolsResponseEvent | { "type": "list_custom_prompts_response" } & ListCustomPromptsResponseEvent | { "type": "list_skills_response" } & ListSkillsResponseEvent | { "type": "list_remote_skills_response" } & ListRemoteSkillsResponseEvent | { "type": "remote_skill_downloaded" } & RemoteSkillDownloadedEvent | { "type": "skills_update_available" } | { "type": "plan_update" } & UpdatePlanArgs | { "type": "turn_aborted" } & TurnAbortedEvent | { "type": "shutdown_complete" } | { "type": "entered_review_mode" } & ReviewRequest | { "type": "exited_review_mode" } & ExitedReviewModeEvent | { "type": "raw_response_item" } & RawResponseItemEvent | { "type": "item_started" } & ItemStartedEvent | { "type": "item_completed" } & ItemCompletedEvent | { "type": "agent_message_content_delta" } & AgentMessageContentDeltaEvent | { "type": "plan_delta" } & PlanDeltaEvent | { "type": "reasoning_content_delta" } & ReasoningContentDeltaEvent | { "type": "reasoning_raw_content_delta" } & ReasoningRawContentDeltaEvent | { "type": "collab_agent_spawn_begin" } & CollabAgentSpawnBeginEvent | { "type": "collab_agent_spawn_end" } & CollabAgentSpawnEndEvent | { "type": "collab_agent_interaction_begin" } & CollabAgentInteractionBeginEvent | { "type": "collab_agent_interaction_end" } & CollabAgentInteractionEndEvent | { "type": "collab_waiting_begin" } & CollabWaitingBeginEvent | { "type": "collab_waiting_end" } & CollabWaitingEndEvent | { "type": "collab_close_begin" } & CollabCloseBeginEvent | { "type": "collab_close_end" } & CollabCloseEndEvent | { "type": "collab_resume_begin" } & CollabResumeBeginEvent | { "type": "collab_resume_end" } & CollabResumeEndEvent;
|
||||
export type EventMsg = { "type": "error" } & ErrorEvent | { "type": "warning" } & WarningEvent | { "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;
|
||||
|
||||
@@ -7,9 +7,16 @@ import type { ParsedCommand } from "./ParsedCommand";
|
||||
|
||||
export type ExecApprovalRequestEvent = {
|
||||
/**
|
||||
* Identifier for the associated exec call, if available.
|
||||
* Identifier for the associated command execution item.
|
||||
*/
|
||||
call_id: string,
|
||||
/**
|
||||
* Identifier for this specific approval callback.
|
||||
*
|
||||
* When absent, the approval is for the command item itself (`call_id`).
|
||||
* This is present for subcommand approvals (via execve intercept).
|
||||
*/
|
||||
approval_id?: string,
|
||||
/**
|
||||
* Turn ID that this command belongs to.
|
||||
* Uses `#[serde(default)]` for backwards compatibility.
|
||||
|
||||
@@ -9,4 +9,8 @@ export type ExecCommandApprovalParams = { conversationId: ThreadId,
|
||||
* Use to correlate this with [codex_core::protocol::ExecCommandBeginEvent]
|
||||
* and [codex_core::protocol::ExecCommandEndEvent].
|
||||
*/
|
||||
callId: string, command: Array<string>, cwd: string, reason: string | null, parsedCmd: Array<ParsedCommand>, };
|
||||
callId: string,
|
||||
/**
|
||||
* Identifier for this specific approval callback.
|
||||
*/
|
||||
approvalId: string | null, command: Array<string>, cwd: string, reason: string | null, parsedCmd: Array<ParsedCommand>, };
|
||||
|
||||
@@ -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 { ModelRerouteReason } from "./ModelRerouteReason";
|
||||
|
||||
export type ModelRerouteEvent = { from_model: string, to_model: string, reason: ModelRerouteReason, };
|
||||
@@ -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 ModelRerouteReason = "high_risk_cyber_activity";
|
||||
@@ -21,15 +21,18 @@ import type { ItemCompletedNotification } from "./v2/ItemCompletedNotification";
|
||||
import type { ItemStartedNotification } from "./v2/ItemStartedNotification";
|
||||
import type { McpServerOauthLoginCompletedNotification } from "./v2/McpServerOauthLoginCompletedNotification";
|
||||
import type { McpToolCallProgressNotification } from "./v2/McpToolCallProgressNotification";
|
||||
import type { ModelReroutedNotification } from "./v2/ModelReroutedNotification";
|
||||
import type { PlanDeltaNotification } from "./v2/PlanDeltaNotification";
|
||||
import type { RawResponseItemCompletedNotification } from "./v2/RawResponseItemCompletedNotification";
|
||||
import type { ReasoningSummaryPartAddedNotification } from "./v2/ReasoningSummaryPartAddedNotification";
|
||||
import type { ReasoningSummaryTextDeltaNotification } from "./v2/ReasoningSummaryTextDeltaNotification";
|
||||
import type { ReasoningTextDeltaNotification } from "./v2/ReasoningTextDeltaNotification";
|
||||
import type { TerminalInteractionNotification } from "./v2/TerminalInteractionNotification";
|
||||
import type { ThreadArchivedNotification } from "./v2/ThreadArchivedNotification";
|
||||
import type { ThreadNameUpdatedNotification } from "./v2/ThreadNameUpdatedNotification";
|
||||
import type { ThreadStartedNotification } from "./v2/ThreadStartedNotification";
|
||||
import type { ThreadTokenUsageUpdatedNotification } from "./v2/ThreadTokenUsageUpdatedNotification";
|
||||
import type { ThreadUnarchivedNotification } from "./v2/ThreadUnarchivedNotification";
|
||||
import type { TurnCompletedNotification } from "./v2/TurnCompletedNotification";
|
||||
import type { TurnDiffUpdatedNotification } from "./v2/TurnDiffUpdatedNotification";
|
||||
import type { TurnPlanUpdatedNotification } from "./v2/TurnPlanUpdatedNotification";
|
||||
@@ -39,4 +42,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/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": "deprecationNotice", "params": DeprecationNoticeNotification } | { "method": "configWarning", "params": ConfigWarningNotification } | { "method": "fuzzyFileSearch/sessionUpdated", "params": FuzzyFileSearchSessionUpdatedNotification } | { "method": "fuzzyFileSearch/sessionCompleted", "params": FuzzyFileSearchSessionCompletedNotification } | { "method": "windows/worldWritableWarning", "params": WindowsWorldWritableWarningNotification } | { "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/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": "account/login/completed", "params": AccountLoginCompletedNotification } | { "method": "authStatusChange", "params": AuthStatusChangeNotification } | { "method": "loginChatGptComplete", "params": LoginChatGptCompleteNotification } | { "method": "sessionConfigured", "params": SessionConfiguredNotification };
|
||||
|
||||
@@ -125,6 +125,8 @@ export type { McpToolCallBeginEvent } from "./McpToolCallBeginEvent";
|
||||
export type { McpToolCallEndEvent } from "./McpToolCallEndEvent";
|
||||
export type { MessagePhase } from "./MessagePhase";
|
||||
export type { ModeKind } from "./ModeKind";
|
||||
export type { ModelRerouteEvent } from "./ModelRerouteEvent";
|
||||
export type { ModelRerouteReason } from "./ModelRerouteReason";
|
||||
export type { NetworkAccess } from "./NetworkAccess";
|
||||
export type { NetworkApprovalContext } from "./NetworkApprovalContext";
|
||||
export type { NetworkApprovalProtocol } from "./NetworkApprovalProtocol";
|
||||
|
||||
@@ -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 - app metadata returned by app-list APIs.
|
||||
*/
|
||||
export type AppBranding = { category: string | null, developer: string | null, website: string | null, privacyPolicy: string | null, termsOfService: string | null, isDiscoverableApp: boolean, };
|
||||
@@ -1,11 +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.
|
||||
import type { AppBranding } from "./AppBranding";
|
||||
import type { AppMetadata } from "./AppMetadata";
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - app metadata returned by app-list APIs.
|
||||
*/
|
||||
export type AppInfo = { id: string, name: string, description: string | null, logoUrl: string | null, logoUrlDark: string | null, distributionChannel: string | null, installUrl: string | null, isAccessible: boolean,
|
||||
export type AppInfo = { id: string, name: string, description: string | null, logoUrl: string | null, logoUrlDark: string | null, distributionChannel: string | null, branding: AppBranding | null, appMetadata: AppMetadata | null, labels: { [key in string]?: string } | null, installUrl: string | null, isAccessible: boolean,
|
||||
/**
|
||||
* Whether this app is enabled in config.toml.
|
||||
* Example:
|
||||
|
||||
@@ -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 { AppReview } from "./AppReview";
|
||||
import type { AppScreenshot } from "./AppScreenshot";
|
||||
|
||||
export type AppMetadata = { review: AppReview | null, categories: Array<string> | null, subCategories: Array<string> | null, seoDescription: string | null, screenshots: Array<AppScreenshot> | null, developer: string | null, version: string | null, versionId: string | null, versionNotes: string | null, firstPartyType: string | null, firstPartyRequiresInstall: boolean | null, showInComposerWhenUnlinked: 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 AppReview = { status: string, };
|
||||
@@ -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 AppScreenshot = { url: string | null, fileId: string | null, userPrompt: string, };
|
||||
@@ -5,6 +5,16 @@ import type { CommandAction } from "./CommandAction";
|
||||
import type { ExecPolicyAmendment } from "./ExecPolicyAmendment";
|
||||
|
||||
export type CommandExecutionRequestApprovalParams = { threadId: string, turnId: string, itemId: string,
|
||||
/**
|
||||
* Unique identifier for this specific approval callback.
|
||||
*
|
||||
* For regular shell/unified_exec approvals, this is null.
|
||||
*
|
||||
* For zsh-exec-bridge subcommand approvals, multiple callbacks can belong to
|
||||
* one parent `itemId`, so `approvalId` is a distinct opaque callback id
|
||||
* (a UUID) used to disambiguate routing.
|
||||
*/
|
||||
approvalId?: string | null,
|
||||
/**
|
||||
* Optional explanatory reason (e.g. request for network access).
|
||||
*/
|
||||
|
||||
@@ -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 HazelnutScope = "example" | "workspace-shared" | "all-shared" | "personal";
|
||||
@@ -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 MessagePhase = "commentary" | "finalAnswer";
|
||||
@@ -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 ModelRerouteReason = "highRiskCyberActivity";
|
||||
@@ -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 { ModelRerouteReason } from "./ModelRerouteReason";
|
||||
|
||||
export type ModelReroutedNotification = { threadId: string, turnId: string, fromModel: string, toModel: string, reason: ModelRerouteReason, };
|
||||
@@ -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 ProductSurface = "chatgpt" | "codex" | "api" | "atlas";
|
||||
@@ -1,5 +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 { HazelnutScope } from "./HazelnutScope";
|
||||
import type { ProductSurface } from "./ProductSurface";
|
||||
|
||||
export type SkillsRemoteReadParams = Record<string, never>;
|
||||
export type SkillsRemoteReadParams = { hazelnutScope: HazelnutScope, productSurface: ProductSurface, enabled: boolean, };
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type SkillsRemoteWriteParams = { hazelnutId: string, isPreload: boolean, };
|
||||
export type SkillsRemoteWriteParams = { hazelnutId: string, };
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type SkillsRemoteWriteResponse = { id: string, name: string, path: string, };
|
||||
export type SkillsRemoteWriteResponse = { id: string, path: string, };
|
||||
|
||||
@@ -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 ThreadArchivedNotification = { threadId: string, };
|
||||
@@ -11,11 +11,12 @@ import type { FileUpdateChange } from "./FileUpdateChange";
|
||||
import type { McpToolCallError } from "./McpToolCallError";
|
||||
import type { McpToolCallResult } from "./McpToolCallResult";
|
||||
import type { McpToolCallStatus } from "./McpToolCallStatus";
|
||||
import type { MessagePhase } from "./MessagePhase";
|
||||
import type { PatchApplyStatus } from "./PatchApplyStatus";
|
||||
import type { UserInput } from "./UserInput";
|
||||
import type { WebSearchAction } from "./WebSearchAction";
|
||||
|
||||
export type ThreadItem = { "type": "userMessage", id: string, content: Array<UserInput>, } | { "type": "agentMessage", id: string, text: string, } | { "type": "plan", id: string, text: string, } | { "type": "reasoning", id: string, summary: Array<string>, content: Array<string>, } | { "type": "commandExecution", id: string,
|
||||
export type ThreadItem = { "type": "userMessage", id: string, content: Array<UserInput>, } | { "type": "agentMessage", id: string, text: string, phase: MessagePhase | null, } | { "type": "plan", id: string, text: string, } | { "type": "reasoning", id: string, summary: Array<string>, content: Array<string>, } | { "type": "commandExecution", id: string,
|
||||
/**
|
||||
* The command to be executed.
|
||||
*/
|
||||
|
||||
@@ -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 ThreadUnarchivedNotification = { threadId: string, };
|
||||
@@ -6,9 +6,13 @@ export type { AccountRateLimitsUpdatedNotification } from "./AccountRateLimitsUp
|
||||
export type { AccountUpdatedNotification } from "./AccountUpdatedNotification";
|
||||
export type { AgentMessageDeltaNotification } from "./AgentMessageDeltaNotification";
|
||||
export type { AnalyticsConfig } from "./AnalyticsConfig";
|
||||
export type { AppBranding } from "./AppBranding";
|
||||
export type { AppDisabledReason } from "./AppDisabledReason";
|
||||
export type { AppInfo } from "./AppInfo";
|
||||
export type { AppListUpdatedNotification } from "./AppListUpdatedNotification";
|
||||
export type { AppMetadata } from "./AppMetadata";
|
||||
export type { AppReview } from "./AppReview";
|
||||
export type { AppScreenshot } from "./AppScreenshot";
|
||||
export type { AppsConfig } from "./AppsConfig";
|
||||
export type { AppsListParams } from "./AppsListParams";
|
||||
export type { AppsListResponse } from "./AppsListResponse";
|
||||
@@ -70,6 +74,7 @@ export type { GetAccountParams } from "./GetAccountParams";
|
||||
export type { GetAccountRateLimitsResponse } from "./GetAccountRateLimitsResponse";
|
||||
export type { GetAccountResponse } from "./GetAccountResponse";
|
||||
export type { GitInfo } from "./GitInfo";
|
||||
export type { HazelnutScope } from "./HazelnutScope";
|
||||
export type { ItemCompletedNotification } from "./ItemCompletedNotification";
|
||||
export type { ItemStartedNotification } from "./ItemStartedNotification";
|
||||
export type { ListMcpServerStatusParams } from "./ListMcpServerStatusParams";
|
||||
@@ -88,15 +93,19 @@ export type { McpToolCallProgressNotification } from "./McpToolCallProgressNotif
|
||||
export type { McpToolCallResult } from "./McpToolCallResult";
|
||||
export type { McpToolCallStatus } from "./McpToolCallStatus";
|
||||
export type { MergeStrategy } from "./MergeStrategy";
|
||||
export type { MessagePhase } from "./MessagePhase";
|
||||
export type { Model } from "./Model";
|
||||
export type { ModelListParams } from "./ModelListParams";
|
||||
export type { ModelListResponse } from "./ModelListResponse";
|
||||
export type { ModelRerouteReason } from "./ModelRerouteReason";
|
||||
export type { ModelReroutedNotification } from "./ModelReroutedNotification";
|
||||
export type { NetworkAccess } from "./NetworkAccess";
|
||||
export type { NetworkRequirements } from "./NetworkRequirements";
|
||||
export type { OverriddenMetadata } from "./OverriddenMetadata";
|
||||
export type { PatchApplyStatus } from "./PatchApplyStatus";
|
||||
export type { PatchChangeKind } from "./PatchChangeKind";
|
||||
export type { PlanDeltaNotification } from "./PlanDeltaNotification";
|
||||
export type { ProductSurface } from "./ProductSurface";
|
||||
export type { ProfileV2 } from "./ProfileV2";
|
||||
export type { RateLimitSnapshot } from "./RateLimitSnapshot";
|
||||
export type { RateLimitWindow } from "./RateLimitWindow";
|
||||
@@ -139,6 +148,7 @@ export type { TextRange } from "./TextRange";
|
||||
export type { Thread } from "./Thread";
|
||||
export type { ThreadArchiveParams } from "./ThreadArchiveParams";
|
||||
export type { ThreadArchiveResponse } from "./ThreadArchiveResponse";
|
||||
export type { ThreadArchivedNotification } from "./ThreadArchivedNotification";
|
||||
export type { ThreadCompactStartParams } from "./ThreadCompactStartParams";
|
||||
export type { ThreadCompactStartResponse } from "./ThreadCompactStartResponse";
|
||||
export type { ThreadForkParams } from "./ThreadForkParams";
|
||||
@@ -166,6 +176,7 @@ export type { ThreadTokenUsage } from "./ThreadTokenUsage";
|
||||
export type { ThreadTokenUsageUpdatedNotification } from "./ThreadTokenUsageUpdatedNotification";
|
||||
export type { ThreadUnarchiveParams } from "./ThreadUnarchiveParams";
|
||||
export type { ThreadUnarchiveResponse } from "./ThreadUnarchiveResponse";
|
||||
export type { ThreadUnarchivedNotification } from "./ThreadUnarchivedNotification";
|
||||
export type { TokenUsageBreakdown } from "./TokenUsageBreakdown";
|
||||
export type { ToolRequestUserInputAnswer } from "./ToolRequestUserInputAnswer";
|
||||
export type { ToolRequestUserInputOption } from "./ToolRequestUserInputOption";
|
||||
|
||||
@@ -239,11 +239,11 @@ client_request_definitions! {
|
||||
params: v2::SkillsListParams,
|
||||
response: v2::SkillsListResponse,
|
||||
},
|
||||
SkillsRemoteRead => "skills/remote/read" {
|
||||
SkillsRemoteList => "skills/remote/list" {
|
||||
params: v2::SkillsRemoteReadParams,
|
||||
response: v2::SkillsRemoteReadResponse,
|
||||
},
|
||||
SkillsRemoteWrite => "skills/remote/write" {
|
||||
SkillsRemoteExport => "skills/remote/export" {
|
||||
params: v2::SkillsRemoteWriteParams,
|
||||
response: v2::SkillsRemoteWriteResponse,
|
||||
},
|
||||
@@ -769,6 +769,8 @@ server_notification_definitions! {
|
||||
/// NEW NOTIFICATIONS
|
||||
Error => "error" (v2::ErrorNotification),
|
||||
ThreadStarted => "thread/started" (v2::ThreadStartedNotification),
|
||||
ThreadArchived => "thread/archived" (v2::ThreadArchivedNotification),
|
||||
ThreadUnarchived => "thread/unarchived" (v2::ThreadUnarchivedNotification),
|
||||
ThreadNameUpdated => "thread/name/updated" (v2::ThreadNameUpdatedNotification),
|
||||
ThreadTokenUsageUpdated => "thread/tokenUsage/updated" (v2::ThreadTokenUsageUpdatedNotification),
|
||||
TurnStarted => "turn/started" (v2::TurnStartedNotification),
|
||||
@@ -795,6 +797,7 @@ server_notification_definitions! {
|
||||
ReasoningTextDelta => "item/reasoning/textDelta" (v2::ReasoningTextDeltaNotification),
|
||||
/// Deprecated: Use `ContextCompaction` item type instead.
|
||||
ContextCompacted => "thread/compacted" (v2::ContextCompactedNotification),
|
||||
ModelRerouted => "model/rerouted" (v2::ModelReroutedNotification),
|
||||
DeprecationNotice => "deprecationNotice" (v2::DeprecationNoticeNotification),
|
||||
ConfigWarning => "configWarning" (v2::ConfigWarningNotification),
|
||||
FuzzyFileSearchSessionUpdated => "fuzzyFileSearch/sessionUpdated" (FuzzyFileSearchSessionUpdatedNotification),
|
||||
@@ -1000,6 +1003,7 @@ mod tests {
|
||||
let params = v1::ExecCommandApprovalParams {
|
||||
conversation_id,
|
||||
call_id: "call-42".to_string(),
|
||||
approval_id: Some("approval-42".to_string()),
|
||||
command: vec!["echo".to_string(), "hello".to_string()],
|
||||
cwd: PathBuf::from("/tmp"),
|
||||
reason: Some("because tests".to_string()),
|
||||
@@ -1019,6 +1023,7 @@ mod tests {
|
||||
"params": {
|
||||
"conversationId": "67e55044-10b1-426f-9247-bb680e5fe0c8",
|
||||
"callId": "call-42",
|
||||
"approvalId": "approval-42",
|
||||
"command": ["echo", "hello"],
|
||||
"cwd": "/tmp",
|
||||
"reason": "because tests",
|
||||
|
||||
@@ -149,9 +149,11 @@ impl ThreadHistoryBuilder {
|
||||
}
|
||||
|
||||
let id = self.next_item_id();
|
||||
self.ensure_turn()
|
||||
.items
|
||||
.push(ThreadItem::AgentMessage { id, text });
|
||||
self.ensure_turn().items.push(ThreadItem::AgentMessage {
|
||||
id,
|
||||
text,
|
||||
phase: None,
|
||||
});
|
||||
}
|
||||
|
||||
fn handle_agent_reasoning(&mut self, payload: &AgentReasoningEvent) {
|
||||
@@ -839,6 +841,7 @@ mod tests {
|
||||
ThreadItem::AgentMessage {
|
||||
id: "item-2".into(),
|
||||
text: "Hi there".into(),
|
||||
phase: None,
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -869,6 +872,7 @@ mod tests {
|
||||
ThreadItem::AgentMessage {
|
||||
id: "item-5".into(),
|
||||
text: "Reply two".into(),
|
||||
phase: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -975,6 +979,7 @@ mod tests {
|
||||
ThreadItem::AgentMessage {
|
||||
id: "item-2".into(),
|
||||
text: "Working...".into(),
|
||||
phase: None,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -996,6 +1001,7 @@ mod tests {
|
||||
ThreadItem::AgentMessage {
|
||||
id: "item-4".into(),
|
||||
text: "Second attempt complete.".into(),
|
||||
phase: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -1057,6 +1063,7 @@ mod tests {
|
||||
ThreadItem::AgentMessage {
|
||||
id: "item-2".into(),
|
||||
text: "A1".into(),
|
||||
phase: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
@@ -1073,6 +1080,7 @@ mod tests {
|
||||
ThreadItem::AgentMessage {
|
||||
id: "item-4".into(),
|
||||
text: "A3".into(),
|
||||
phase: None,
|
||||
},
|
||||
]
|
||||
);
|
||||
|
||||
@@ -258,6 +258,8 @@ pub struct ExecCommandApprovalParams {
|
||||
/// Use to correlate this with [codex_core::protocol::ExecCommandBeginEvent]
|
||||
/// and [codex_core::protocol::ExecCommandEndEvent].
|
||||
pub call_id: String,
|
||||
/// Identifier for this specific approval callback.
|
||||
pub approval_id: Option<String>,
|
||||
pub command: Vec<String>,
|
||||
pub cwd: PathBuf,
|
||||
pub reason: Option<String>,
|
||||
|
||||
@@ -18,6 +18,7 @@ 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::MessagePhase as CoreMessagePhase;
|
||||
use codex_protocol::models::ResponseItem;
|
||||
use codex_protocol::openai_models::InputModality;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
@@ -30,6 +31,7 @@ use codex_protocol::protocol::AskForApproval as CoreAskForApproval;
|
||||
use codex_protocol::protocol::CodexErrorInfo as CoreCodexErrorInfo;
|
||||
use codex_protocol::protocol::CreditsSnapshot as CoreCreditsSnapshot;
|
||||
use codex_protocol::protocol::ExecCommandStatus as CoreExecCommandStatus;
|
||||
use codex_protocol::protocol::ModelRerouteReason as CoreModelRerouteReason;
|
||||
use codex_protocol::protocol::NetworkAccess as CoreNetworkAccess;
|
||||
use codex_protocol::protocol::PatchApplyStatus as CorePatchApplyStatus;
|
||||
use codex_protocol::protocol::RateLimitSnapshot as CoreRateLimitSnapshot;
|
||||
@@ -229,6 +231,12 @@ v2_enum_from_core!(
|
||||
}
|
||||
);
|
||||
|
||||
v2_enum_from_core!(
|
||||
pub enum ModelRerouteReason from CoreModelRerouteReason {
|
||||
HighRiskCyberActivity
|
||||
}
|
||||
);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
#[ts(tag = "type")]
|
||||
@@ -1280,6 +1288,55 @@ pub struct AppsListParams {
|
||||
pub force_refetch: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
/// EXPERIMENTAL - app metadata returned by app-list APIs.
|
||||
pub struct AppBranding {
|
||||
pub category: Option<String>,
|
||||
pub developer: Option<String>,
|
||||
pub website: Option<String>,
|
||||
pub privacy_policy: Option<String>,
|
||||
pub terms_of_service: Option<String>,
|
||||
pub is_discoverable_app: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct AppReview {
|
||||
pub status: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct AppScreenshot {
|
||||
pub url: Option<String>,
|
||||
#[serde(alias = "file_id")]
|
||||
pub file_id: Option<String>,
|
||||
#[serde(alias = "user_prompt")]
|
||||
pub user_prompt: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct AppMetadata {
|
||||
pub review: Option<AppReview>,
|
||||
pub categories: Option<Vec<String>>,
|
||||
pub sub_categories: Option<Vec<String>>,
|
||||
pub seo_description: Option<String>,
|
||||
pub screenshots: Option<Vec<AppScreenshot>>,
|
||||
pub developer: Option<String>,
|
||||
pub version: Option<String>,
|
||||
pub version_id: Option<String>,
|
||||
pub version_notes: Option<String>,
|
||||
pub first_party_type: Option<String>,
|
||||
pub first_party_requires_install: Option<bool>,
|
||||
pub show_in_composer_when_unlinked: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
@@ -1291,6 +1348,9 @@ pub struct AppInfo {
|
||||
pub logo_url: Option<String>,
|
||||
pub logo_url_dark: Option<String>,
|
||||
pub distribution_channel: Option<String>,
|
||||
pub branding: Option<AppBranding>,
|
||||
pub app_metadata: Option<AppMetadata>,
|
||||
pub labels: Option<HashMap<String, String>>,
|
||||
pub install_url: Option<String>,
|
||||
#[serde(default)]
|
||||
pub is_accessible: bool,
|
||||
@@ -1830,7 +1890,38 @@ pub struct SkillsListResponse {
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct SkillsRemoteReadParams {}
|
||||
pub struct SkillsRemoteReadParams {
|
||||
#[serde(default)]
|
||||
pub hazelnut_scope: HazelnutScope,
|
||||
#[serde(default)]
|
||||
pub product_surface: ProductSurface,
|
||||
#[serde(default)]
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[ts(rename_all = "kebab-case")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub enum HazelnutScope {
|
||||
#[default]
|
||||
Example,
|
||||
WorkspaceShared,
|
||||
AllShared,
|
||||
Personal,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS, Default)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[ts(rename_all = "lowercase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub enum ProductSurface {
|
||||
Chatgpt,
|
||||
#[default]
|
||||
Codex,
|
||||
Api,
|
||||
Atlas,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@@ -1853,7 +1944,6 @@ pub struct SkillsRemoteReadResponse {
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct SkillsRemoteWriteParams {
|
||||
pub hazelnut_id: String,
|
||||
pub is_preload: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
@@ -1861,7 +1951,6 @@ pub struct SkillsRemoteWriteParams {
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct SkillsRemoteWriteResponse {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
@@ -2461,6 +2550,24 @@ impl From<CoreUserInput> for UserInput {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub enum MessagePhase {
|
||||
Commentary,
|
||||
FinalAnswer,
|
||||
}
|
||||
|
||||
impl From<CoreMessagePhase> for MessagePhase {
|
||||
fn from(value: CoreMessagePhase) -> Self {
|
||||
match value {
|
||||
CoreMessagePhase::Commentary => Self::Commentary,
|
||||
CoreMessagePhase::FinalAnswer => Self::FinalAnswer,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
#[ts(tag = "type")]
|
||||
@@ -2471,7 +2578,12 @@ pub enum ThreadItem {
|
||||
UserMessage { id: String, content: Vec<UserInput> },
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(rename_all = "camelCase")]
|
||||
AgentMessage { id: String, text: String },
|
||||
AgentMessage {
|
||||
id: String,
|
||||
text: String,
|
||||
#[serde(default)]
|
||||
phase: Option<MessagePhase>,
|
||||
},
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(rename_all = "camelCase")]
|
||||
/// EXPERIMENTAL - proposed plan item content. The completed plan item is
|
||||
@@ -2622,7 +2734,11 @@ impl From<CoreTurnItem> for ThreadItem {
|
||||
CoreAgentMessageContent::Text { text } => text,
|
||||
})
|
||||
.collect::<String>();
|
||||
ThreadItem::AgentMessage { id: agent.id, text }
|
||||
ThreadItem::AgentMessage {
|
||||
id: agent.id,
|
||||
text,
|
||||
phase: agent.phase.map(Into::into),
|
||||
}
|
||||
}
|
||||
CoreTurnItem::Plan(plan) => ThreadItem::Plan {
|
||||
id: plan.id,
|
||||
@@ -2825,6 +2941,20 @@ pub struct ThreadStartedNotification {
|
||||
pub thread: Thread,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadArchivedNotification {
|
||||
pub thread_id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ThreadUnarchivedNotification {
|
||||
pub thread_id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
@@ -3079,7 +3209,18 @@ pub struct CommandExecutionRequestApprovalParams {
|
||||
pub thread_id: String,
|
||||
pub turn_id: String,
|
||||
pub item_id: String,
|
||||
/// Unique identifier for this specific approval callback.
|
||||
///
|
||||
/// For regular shell/unified_exec approvals, this is null.
|
||||
///
|
||||
/// For zsh-exec-bridge subcommand approvals, multiple callbacks can belong to
|
||||
/// one parent `itemId`, so `approvalId` is a distinct opaque callback id
|
||||
/// (a UUID) used to disambiguate routing.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional = nullable)]
|
||||
pub approval_id: Option<String>,
|
||||
/// Optional explanatory reason (e.g. request for network access).
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
#[ts(optional = nullable)]
|
||||
pub reason: Option<String>,
|
||||
/// The command to be executed.
|
||||
@@ -3095,6 +3236,7 @@ pub struct CommandExecutionRequestApprovalParams {
|
||||
#[ts(optional = nullable)]
|
||||
pub command_actions: Option<Vec<CommandAction>>,
|
||||
/// 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>,
|
||||
}
|
||||
@@ -3305,6 +3447,17 @@ pub struct AccountLoginCompletedNotification {
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct ModelReroutedNotification {
|
||||
pub thread_id: String,
|
||||
pub turn_id: String,
|
||||
pub from_model: String,
|
||||
pub to_model: String,
|
||||
pub reason: ModelRerouteReason,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
@@ -3360,6 +3513,7 @@ mod tests {
|
||||
use codex_protocol::items::TurnItem;
|
||||
use codex_protocol::items::UserMessageItem;
|
||||
use codex_protocol::items::WebSearchItem;
|
||||
use codex_protocol::models::MessagePhase as CoreMessagePhase;
|
||||
use codex_protocol::models::WebSearchAction as CoreWebSearchAction;
|
||||
use codex_protocol::protocol::NetworkAccess as CoreNetworkAccess;
|
||||
use codex_protocol::protocol::ReadOnlyAccess as CoreReadOnlyAccess;
|
||||
@@ -3560,6 +3714,24 @@ mod tests {
|
||||
ThreadItem::AgentMessage {
|
||||
id: "agent-1".to_string(),
|
||||
text: "Hello world".to_string(),
|
||||
phase: None,
|
||||
}
|
||||
);
|
||||
|
||||
let agent_item_with_phase = TurnItem::AgentMessage(AgentMessageItem {
|
||||
id: "agent-2".to_string(),
|
||||
content: vec![AgentMessageContent::Text {
|
||||
text: "final".to_string(),
|
||||
}],
|
||||
phase: Some(CoreMessagePhase::FinalAnswer),
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
ThreadItem::from(agent_item_with_phase),
|
||||
ThreadItem::AgentMessage {
|
||||
id: "agent-2".to_string(),
|
||||
text: "final".to_string(),
|
||||
phase: Some(MessagePhase::FinalAnswer),
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::BufRead;
|
||||
@@ -29,6 +30,7 @@ use codex_app_server_protocol::ClientRequest;
|
||||
use codex_app_server_protocol::CommandExecutionApprovalDecision;
|
||||
use codex_app_server_protocol::CommandExecutionRequestApprovalParams;
|
||||
use codex_app_server_protocol::CommandExecutionRequestApprovalResponse;
|
||||
use codex_app_server_protocol::CommandExecutionStatus;
|
||||
use codex_app_server_protocol::DynamicToolSpec;
|
||||
use codex_app_server_protocol::FileChangeApprovalDecision;
|
||||
use codex_app_server_protocol::FileChangeRequestApprovalParams;
|
||||
@@ -55,6 +57,7 @@ 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::ThreadItem;
|
||||
use codex_app_server_protocol::ThreadListParams;
|
||||
use codex_app_server_protocol::ThreadListResponse;
|
||||
use codex_app_server_protocol::ThreadResumeParams;
|
||||
@@ -78,6 +81,30 @@ use tungstenite::stream::MaybeTlsStream;
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
||||
const NOTIFICATIONS_TO_OPT_OUT: &[&str] = &[
|
||||
// Legacy codex/event (v1-style) deltas.
|
||||
"codex/event/agent_message_content_delta",
|
||||
"codex/event/agent_message_delta",
|
||||
"codex/event/agent_reasoning_delta",
|
||||
"codex/event/reasoning_content_delta",
|
||||
"codex/event/reasoning_raw_content_delta",
|
||||
"codex/event/exec_command_output_delta",
|
||||
// Other legacy events.
|
||||
"codex/event/exec_approval_request",
|
||||
"codex/event/exec_command_begin",
|
||||
"codex/event/exec_command_end",
|
||||
"codex/event/exec_output",
|
||||
"codex/event/item_started",
|
||||
"codex/event/item_completed",
|
||||
// v2 item deltas.
|
||||
"item/agentMessage/delta",
|
||||
"item/plan/delta",
|
||||
"item/commandExecution/outputDelta",
|
||||
"item/fileChange/outputDelta",
|
||||
"item/reasoning/summaryTextDelta",
|
||||
"item/reasoning/textDelta",
|
||||
];
|
||||
|
||||
/// Minimal launcher that initializes the Codex app-server and logs the handshake.
|
||||
#[derive(Parser)]
|
||||
#[command(author = "Codex", version, about = "Bootstrap Codex app-server", long_about = None)]
|
||||
@@ -180,6 +207,18 @@ enum CliCommand {
|
||||
/// Follow-up user message for the second turn.
|
||||
follow_up_message: String,
|
||||
},
|
||||
/// Trigger zsh-fork multi-subcommand approvals and assert expected approval behavior.
|
||||
#[command(name = "trigger-zsh-fork-multi-cmd-approval")]
|
||||
TriggerZshForkMultiCmdApproval {
|
||||
/// Optional prompt; defaults to an explicit `/usr/bin/true && /usr/bin/true` command.
|
||||
user_message: Option<String>,
|
||||
/// Minimum number of command-approval callbacks expected in the turn.
|
||||
#[arg(long, default_value_t = 2)]
|
||||
min_approvals: usize,
|
||||
/// One-based approval index to abort (e.g. --abort-on 2 aborts the second approval).
|
||||
#[arg(long)]
|
||||
abort_on: Option<usize>,
|
||||
},
|
||||
/// Trigger the ChatGPT login flow and wait for completion.
|
||||
TestLogin,
|
||||
/// Fetch the current account rate limits from the Codex app-server.
|
||||
@@ -265,6 +304,21 @@ pub fn run() -> Result<()> {
|
||||
&dynamic_tools,
|
||||
)
|
||||
}
|
||||
CliCommand::TriggerZshForkMultiCmdApproval {
|
||||
user_message,
|
||||
min_approvals,
|
||||
abort_on,
|
||||
} => {
|
||||
let endpoint = resolve_endpoint(codex_bin, url)?;
|
||||
trigger_zsh_fork_multi_cmd_approval(
|
||||
&endpoint,
|
||||
&config_overrides,
|
||||
user_message,
|
||||
min_approvals,
|
||||
abort_on,
|
||||
&dynamic_tools,
|
||||
)
|
||||
}
|
||||
CliCommand::TestLogin => {
|
||||
ensure_dynamic_tools_unused(&dynamic_tools, "test-login")?;
|
||||
let endpoint = resolve_endpoint(codex_bin, url)?;
|
||||
@@ -470,6 +524,101 @@ fn send_message_v2_endpoint(
|
||||
)
|
||||
}
|
||||
|
||||
fn trigger_zsh_fork_multi_cmd_approval(
|
||||
endpoint: &Endpoint,
|
||||
config_overrides: &[String],
|
||||
user_message: Option<String>,
|
||||
min_approvals: usize,
|
||||
abort_on: Option<usize>,
|
||||
dynamic_tools: &Option<Vec<DynamicToolSpec>>,
|
||||
) -> Result<()> {
|
||||
if let Some(abort_on) = abort_on
|
||||
&& abort_on == 0
|
||||
{
|
||||
bail!("--abort-on must be >= 1 when provided");
|
||||
}
|
||||
|
||||
let default_prompt = "Run this exact command using shell command execution without rewriting or splitting it: /usr/bin/true && /usr/bin/true";
|
||||
let message = user_message.unwrap_or_else(|| default_prompt.to_string());
|
||||
|
||||
let mut client = CodexClient::connect(endpoint, config_overrides)?;
|
||||
let initialize = client.initialize()?;
|
||||
println!("< initialize response: {initialize:?}");
|
||||
|
||||
let thread_response = client.thread_start(ThreadStartParams {
|
||||
dynamic_tools: dynamic_tools.clone(),
|
||||
..Default::default()
|
||||
})?;
|
||||
println!("< thread/start response: {thread_response:?}");
|
||||
|
||||
client.command_approval_behavior = match abort_on {
|
||||
Some(index) => CommandApprovalBehavior::AbortOn(index),
|
||||
None => CommandApprovalBehavior::AlwaysAccept,
|
||||
};
|
||||
client.command_approval_count = 0;
|
||||
client.command_approval_item_ids.clear();
|
||||
client.command_execution_statuses.clear();
|
||||
client.last_turn_status = None;
|
||||
|
||||
let mut turn_params = TurnStartParams {
|
||||
thread_id: thread_response.thread.id.clone(),
|
||||
input: vec![V2UserInput::Text {
|
||||
text: message,
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
..Default::default()
|
||||
};
|
||||
turn_params.approval_policy = Some(AskForApproval::OnRequest);
|
||||
turn_params.sandbox_policy = Some(SandboxPolicy::ReadOnly {
|
||||
access: ReadOnlyAccess::FullAccess,
|
||||
});
|
||||
|
||||
let turn_response = client.turn_start(turn_params)?;
|
||||
println!("< turn/start response: {turn_response:?}");
|
||||
client.stream_turn(&thread_response.thread.id, &turn_response.turn.id)?;
|
||||
|
||||
if client.command_approval_count < min_approvals {
|
||||
bail!(
|
||||
"expected at least {min_approvals} command approvals, got {}",
|
||||
client.command_approval_count
|
||||
);
|
||||
}
|
||||
let mut approvals_per_item = std::collections::BTreeMap::new();
|
||||
for item_id in &client.command_approval_item_ids {
|
||||
*approvals_per_item.entry(item_id.clone()).or_insert(0usize) += 1;
|
||||
}
|
||||
let max_approvals_for_one_item = approvals_per_item.values().copied().max().unwrap_or(0);
|
||||
if max_approvals_for_one_item < min_approvals {
|
||||
bail!(
|
||||
"expected at least {min_approvals} approvals for one command item, got max {max_approvals_for_one_item} with map {approvals_per_item:?}"
|
||||
);
|
||||
}
|
||||
|
||||
let last_command_status = client.command_execution_statuses.last();
|
||||
if abort_on.is_none() {
|
||||
if last_command_status != Some(&CommandExecutionStatus::Completed) {
|
||||
bail!("expected completed command execution, got {last_command_status:?}");
|
||||
}
|
||||
if client.last_turn_status != Some(TurnStatus::Completed) {
|
||||
bail!(
|
||||
"expected completed turn in all-accept flow, got {:?}",
|
||||
client.last_turn_status
|
||||
);
|
||||
}
|
||||
} else if last_command_status == Some(&CommandExecutionStatus::Completed) {
|
||||
bail!(
|
||||
"expected non-completed command execution in mixed approval/decline flow, got {last_command_status:?}"
|
||||
);
|
||||
}
|
||||
|
||||
println!(
|
||||
"[zsh-fork multi-approval summary] approvals={}, approvals_per_item={approvals_per_item:?}, command_statuses={:?}, turn_status={:?}",
|
||||
client.command_approval_count, client.command_execution_statuses, client.last_turn_status
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resume_message_v2(
|
||||
endpoint: &Endpoint,
|
||||
config_overrides: &[String],
|
||||
@@ -791,6 +940,17 @@ enum ClientTransport {
|
||||
struct CodexClient {
|
||||
transport: ClientTransport,
|
||||
pending_notifications: VecDeque<JSONRPCNotification>,
|
||||
command_approval_behavior: CommandApprovalBehavior,
|
||||
command_approval_count: usize,
|
||||
command_approval_item_ids: Vec<String>,
|
||||
command_execution_statuses: Vec<CommandExecutionStatus>,
|
||||
last_turn_status: Option<TurnStatus>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum CommandApprovalBehavior {
|
||||
AlwaysAccept,
|
||||
AbortOn(usize),
|
||||
}
|
||||
|
||||
impl CodexClient {
|
||||
@@ -804,6 +964,14 @@ impl CodexClient {
|
||||
fn spawn_stdio(codex_bin: &Path, config_overrides: &[String]) -> Result<Self> {
|
||||
let codex_bin_display = codex_bin.display();
|
||||
let mut cmd = Command::new(codex_bin);
|
||||
if let Some(codex_bin_parent) = codex_bin.parent() {
|
||||
let mut path = OsString::from(codex_bin_parent.as_os_str());
|
||||
if let Some(existing_path) = std::env::var_os("PATH") {
|
||||
path.push(":");
|
||||
path.push(existing_path);
|
||||
}
|
||||
cmd.env("PATH", path);
|
||||
}
|
||||
for override_kv in config_overrides {
|
||||
cmd.arg("--config").arg(override_kv);
|
||||
}
|
||||
@@ -831,6 +999,11 @@ impl CodexClient {
|
||||
stdout: BufReader::new(stdout),
|
||||
},
|
||||
pending_notifications: VecDeque::new(),
|
||||
command_approval_behavior: CommandApprovalBehavior::AlwaysAccept,
|
||||
command_approval_count: 0,
|
||||
command_approval_item_ids: Vec::new(),
|
||||
command_execution_statuses: Vec::new(),
|
||||
last_turn_status: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -847,6 +1020,11 @@ impl CodexClient {
|
||||
socket: Box::new(socket),
|
||||
},
|
||||
pending_notifications: VecDeque::new(),
|
||||
command_approval_behavior: CommandApprovalBehavior::AlwaysAccept,
|
||||
command_approval_count: 0,
|
||||
command_approval_item_ids: Vec::new(),
|
||||
command_execution_statuses: Vec::new(),
|
||||
last_turn_status: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -862,7 +1040,12 @@ impl CodexClient {
|
||||
},
|
||||
capabilities: Some(InitializeCapabilities {
|
||||
experimental_api: true,
|
||||
opt_out_notification_methods: None,
|
||||
opt_out_notification_methods: Some(
|
||||
NOTIFICATIONS_TO_OPT_OUT
|
||||
.iter()
|
||||
.map(|method| (*method).to_string())
|
||||
.collect(),
|
||||
),
|
||||
}),
|
||||
},
|
||||
};
|
||||
@@ -1121,10 +1304,14 @@ impl CodexClient {
|
||||
println!("\n< item started: {:?}", payload.item);
|
||||
}
|
||||
ServerNotification::ItemCompleted(payload) => {
|
||||
if let ThreadItem::CommandExecution { status, .. } = payload.item.clone() {
|
||||
self.command_execution_statuses.push(status);
|
||||
}
|
||||
println!("< item completed: {:?}", payload.item);
|
||||
}
|
||||
ServerNotification::TurnCompleted(payload) => {
|
||||
if payload.turn.id == turn_id {
|
||||
self.last_turn_status = Some(payload.turn.status.clone());
|
||||
println!("\n< turn/completed notification: {:?}", payload.turn.status);
|
||||
if payload.turn.status == TurnStatus::Failed
|
||||
&& let Some(error) = payload.turn.error
|
||||
@@ -1302,6 +1489,7 @@ impl CodexClient {
|
||||
thread_id,
|
||||
turn_id,
|
||||
item_id,
|
||||
approval_id,
|
||||
reason,
|
||||
command,
|
||||
cwd,
|
||||
@@ -1310,8 +1498,11 @@ impl CodexClient {
|
||||
} = params;
|
||||
|
||||
println!(
|
||||
"\n< commandExecution approval requested for thread {thread_id}, turn {turn_id}, item {item_id}"
|
||||
"\n< commandExecution approval requested for thread {thread_id}, turn {turn_id}, item {item_id}, approval {}",
|
||||
approval_id.as_deref().unwrap_or("<none>")
|
||||
);
|
||||
self.command_approval_count += 1;
|
||||
self.command_approval_item_ids.push(item_id.clone());
|
||||
if let Some(reason) = reason.as_deref() {
|
||||
println!("< reason: {reason}");
|
||||
}
|
||||
@@ -1330,11 +1521,21 @@ impl CodexClient {
|
||||
println!("< proposed execpolicy amendment: {execpolicy_amendment:?}");
|
||||
}
|
||||
|
||||
let decision = match self.command_approval_behavior {
|
||||
CommandApprovalBehavior::AlwaysAccept => CommandExecutionApprovalDecision::Accept,
|
||||
CommandApprovalBehavior::AbortOn(index) if self.command_approval_count == index => {
|
||||
CommandExecutionApprovalDecision::Cancel
|
||||
}
|
||||
CommandApprovalBehavior::AbortOn(_) => CommandExecutionApprovalDecision::Accept,
|
||||
};
|
||||
let response = CommandExecutionRequestApprovalResponse {
|
||||
decision: CommandExecutionApprovalDecision::Accept,
|
||||
decision: decision.clone(),
|
||||
};
|
||||
self.send_server_request_response(request_id, &response)?;
|
||||
println!("< approved commandExecution request for item {item_id}");
|
||||
println!(
|
||||
"< commandExecution decision for approval #{} on item {item_id}: {:?}",
|
||||
self.command_approval_count, decision
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -120,9 +120,9 @@ Example with notification opt-out:
|
||||
- `thread/list` — page through stored rollouts; supports cursor-based pagination and optional `modelProviders`, `sourceKinds`, `archived`, and `cwd` filters.
|
||||
- `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`.
|
||||
- `thread/archive` — move a thread’s rollout file into the archived directory; returns `{}` on success.
|
||||
- `thread/archive` — move a thread’s rollout file into the archived directory; returns `{}` on success and emits `thread/archived`.
|
||||
- `thread/name/set` — set or update a thread’s user-facing name; returns `{}` on success. Thread names are not required to be unique; name lookups resolve to the most recently updated thread.
|
||||
- `thread/unarchive` — move an archived rollout file back into the sessions directory; returns the restored `thread` on success.
|
||||
- `thread/unarchive` — move an archived rollout file back into the sessions directory; returns the restored `thread` on success and emits `thread/unarchived`.
|
||||
- `thread/compact/start` — trigger conversation history compaction for a thread; returns `{}` immediately while progress streams through standard turn/item notifications.
|
||||
- `thread/backgroundTerminals/clean` — terminate all running background terminals for a thread (experimental; requires `capabilities.experimentalApi`); returns `{}` when the cleanup request is accepted.
|
||||
- `thread/rollback` — drop the last N turns from the agent’s in-memory context and persist a rollback marker in the rollout so future resumes see the pruned history; returns the updated `thread` (with `turns` populated) on success.
|
||||
@@ -135,8 +135,8 @@ Example with notification opt-out:
|
||||
- `experimentalFeature/list` — list feature flags with stage metadata (`beta`, `underDevelopment`, `stable`, etc.), enabled/default-enabled state, and cursor pagination. For non-beta flags, `displayName`/`description`/`announcement` are `null`.
|
||||
- `collaborationMode/list` — list available collaboration mode presets (experimental, no pagination).
|
||||
- `skills/list` — list skills for one or more `cwd` values (optional `forceReload`).
|
||||
- `skills/remote/read` — list public remote skills (**under development; do not call from production clients yet**).
|
||||
- `skills/remote/write` — download a public remote skill by `hazelnutId`; `isPreload=true` writes to `.codex/vendor_imports/skills` under `codex_home` (**under development; do not call from production clients yet**).
|
||||
- `skills/remote/list` — list public remote skills (**under development; do not call from production clients yet**).
|
||||
- `skills/remote/export` — download a remote skill by `hazelnutId` into `skills` under `codex_home` (**under development; do not call from production clients yet**).
|
||||
- `app/list` — list available apps.
|
||||
- `skills/config/write` — write user-level skill config by path.
|
||||
- `mcpServer/oauth/login` — start an OAuth login for a configured MCP server; returns an `authorization_url` and later emits `mcpServer/oauthLogin/completed` once the browser flow finishes.
|
||||
@@ -274,6 +274,7 @@ Use `thread/archive` to move the persisted rollout (stored as a JSONL file on di
|
||||
```json
|
||||
{ "method": "thread/archive", "id": 21, "params": { "threadId": "thr_b" } }
|
||||
{ "id": 21, "result": {} }
|
||||
{ "method": "thread/archived", "params": { "threadId": "thr_b" } }
|
||||
```
|
||||
|
||||
An archived thread will not appear in `thread/list` unless `archived` is set to `true`.
|
||||
@@ -285,6 +286,7 @@ Use `thread/unarchive` to move an archived rollout back into the sessions direct
|
||||
```json
|
||||
{ "method": "thread/unarchive", "id": 24, "params": { "threadId": "thr_b" } }
|
||||
{ "id": 24, "result": { "thread": { "id": "thr_b" } } }
|
||||
{ "method": "thread/unarchived", "params": { "threadId": "thr_b" } }
|
||||
```
|
||||
|
||||
### Example: Trigger thread compaction
|
||||
@@ -519,7 +521,7 @@ Notes:
|
||||
|
||||
## Events
|
||||
|
||||
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`, `turn/*`, and `item/*` notifications.
|
||||
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.
|
||||
|
||||
### Notification opt-out
|
||||
|
||||
@@ -550,6 +552,7 @@ The app-server streams JSON-RPC notifications while a turn is running. Each turn
|
||||
- `turn/completed` — `{ turn }` where `turn.status` is `completed`, `interrupted`, or `failed`; failures carry `{ error: { message, codexErrorInfo?, additionalDetails? } }`.
|
||||
- `turn/diff/updated` — `{ threadId, turnId, diff }` represents the up-to-date snapshot of the turn-level unified diff, emitted after every FileChange item. `diff` is the latest aggregated unified diff across every file change in the turn. UIs can render this to show the full "what changed" view without stitching individual `fileChange` items.
|
||||
- `turn/plan/updated` — `{ turnId, explanation?, plan }` whenever the agent shares or changes its plan; each `plan` entry is `{ step, status }` with `status` in `pending`, `inProgress`, or `completed`.
|
||||
- `model/rerouted` — `{ threadId, turnId, fromModel, toModel, reason }` when the backend reroutes a request to a different model (for example, due to high-risk cyber safety checks).
|
||||
|
||||
Today both notifications carry an empty `items` array even when item events were streamed; rely on `item/*` notifications for the canonical item list until this is fixed.
|
||||
|
||||
@@ -634,7 +637,7 @@ Certain actions (shell commands or modifying files) may require explicit user ap
|
||||
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 `reason`, plus `command`, `cwd`, and `commandActions` for friendly display.
|
||||
2. `item/commandExecution/requestApproval` (request) — carries the same `itemId`, `threadId`, `turnId`, optionally `approvalId` (for subcommand callbacks), `reason`, plus `command`, `cwd`, and `commandActions` for friendly display.
|
||||
3. Client response — `{ "decision": "accept", "acceptSettings": { "forSession": false } }` or `{ "decision": "decline" }`.
|
||||
4. `item/completed` — final `commandExecution` item with `status: "completed" | "failed" | "declined"` and execution output. Render this as the authoritative result.
|
||||
|
||||
@@ -771,7 +774,7 @@ To enable or disable a skill by path:
|
||||
|
||||
## Apps
|
||||
|
||||
Use `app/list` to fetch available apps (connectors). Each entry includes metadata like the app `id`, display `name`, `installUrl`, whether it is currently accessible, and whether it is enabled in config.
|
||||
Use `app/list` to fetch available apps (connectors). Each entry includes metadata like the app `id`, display `name`, `installUrl`, `branding`, `appMetadata`, `labels`, whether it is currently accessible, and whether it is enabled in config.
|
||||
|
||||
```json
|
||||
{ "method": "app/list", "id": 50, "params": {
|
||||
@@ -789,6 +792,9 @@ Use `app/list` to fetch available apps (connectors). Each entry includes metadat
|
||||
"logoUrl": "https://example.com/demo-app.png",
|
||||
"logoUrlDark": null,
|
||||
"distributionChannel": null,
|
||||
"branding": null,
|
||||
"appMetadata": null,
|
||||
"labels": null,
|
||||
"installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
|
||||
"isAccessible": true,
|
||||
"isEnabled": true
|
||||
@@ -816,6 +822,9 @@ The server also emits `app/list/updated` notifications whenever either source (a
|
||||
"logoUrl": "https://example.com/demo-app.png",
|
||||
"logoUrlDark": null,
|
||||
"distributionChannel": null,
|
||||
"branding": null,
|
||||
"appMetadata": null,
|
||||
"labels": null,
|
||||
"installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
|
||||
"isAccessible": true,
|
||||
"isEnabled": true
|
||||
|
||||
@@ -41,6 +41,7 @@ use codex_app_server_protocol::JSONRPCErrorError;
|
||||
use codex_app_server_protocol::McpToolCallError;
|
||||
use codex_app_server_protocol::McpToolCallResult;
|
||||
use codex_app_server_protocol::McpToolCallStatus;
|
||||
use codex_app_server_protocol::ModelReroutedNotification;
|
||||
use codex_app_server_protocol::PatchApplyStatus;
|
||||
use codex_app_server_protocol::PatchChangeKind as V2PatchChangeKind;
|
||||
use codex_app_server_protocol::PlanDeltaNotification;
|
||||
@@ -122,6 +123,21 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
EventMsg::TurnComplete(_ev) => {
|
||||
handle_turn_complete(conversation_id, event_turn_id, &outgoing, &thread_state).await;
|
||||
}
|
||||
EventMsg::Warning(_warning_event) => {}
|
||||
EventMsg::ModelReroute(event) => {
|
||||
if let ApiVersion::V2 = api_version {
|
||||
let notification = ModelReroutedNotification {
|
||||
thread_id: conversation_id.to_string(),
|
||||
turn_id: event_turn_id.clone(),
|
||||
from_model: event.from_model,
|
||||
to_model: event.to_model,
|
||||
reason: event.reason.into(),
|
||||
};
|
||||
outgoing
|
||||
.send_server_notification(ServerNotification::ModelRerouted(notification))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
EventMsg::ApplyPatchApprovalRequest(ApplyPatchApprovalRequestEvent {
|
||||
call_id,
|
||||
turn_id,
|
||||
@@ -198,76 +214,88 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
});
|
||||
}
|
||||
},
|
||||
EventMsg::ExecApprovalRequest(ExecApprovalRequestEvent {
|
||||
call_id,
|
||||
turn_id,
|
||||
command,
|
||||
cwd,
|
||||
reason,
|
||||
proposed_execpolicy_amendment,
|
||||
parsed_cmd,
|
||||
..
|
||||
}) => match api_version {
|
||||
ApiVersion::V1 => {
|
||||
let params = ExecCommandApprovalParams {
|
||||
conversation_id,
|
||||
call_id: call_id.clone(),
|
||||
command,
|
||||
cwd,
|
||||
reason,
|
||||
parsed_cmd,
|
||||
};
|
||||
let rx = outgoing
|
||||
.send_request(ServerRequestPayload::ExecCommandApproval(params))
|
||||
.await;
|
||||
tokio::spawn(async move {
|
||||
on_exec_approval_response(call_id, event_turn_id, rx, conversation).await;
|
||||
});
|
||||
}
|
||||
ApiVersion::V2 => {
|
||||
let item_id = call_id.clone();
|
||||
let command_actions = parsed_cmd
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(V2ParsedCommand::from)
|
||||
.collect::<Vec<_>>();
|
||||
let command_string = shlex_join(&command);
|
||||
let proposed_execpolicy_amendment_v2 =
|
||||
proposed_execpolicy_amendment.map(V2ExecPolicyAmendment::from);
|
||||
|
||||
let params = CommandExecutionRequestApprovalParams {
|
||||
thread_id: conversation_id.to_string(),
|
||||
turn_id: turn_id.clone(),
|
||||
// Until we migrate the core to be aware of a first class CommandExecutionItem
|
||||
// and emit the corresponding EventMsg, we repurpose the call_id as the item_id.
|
||||
item_id: item_id.clone(),
|
||||
reason,
|
||||
command: Some(command_string.clone()),
|
||||
cwd: Some(cwd.clone()),
|
||||
command_actions: Some(command_actions.clone()),
|
||||
proposed_execpolicy_amendment: proposed_execpolicy_amendment_v2,
|
||||
};
|
||||
let rx = outgoing
|
||||
.send_request(ServerRequestPayload::CommandExecutionRequestApproval(
|
||||
params,
|
||||
))
|
||||
.await;
|
||||
tokio::spawn(async move {
|
||||
on_command_execution_request_approval_response(
|
||||
event_turn_id,
|
||||
EventMsg::ExecApprovalRequest(ev) => {
|
||||
let approval_id_for_op = ev.effective_approval_id();
|
||||
let ExecApprovalRequestEvent {
|
||||
call_id,
|
||||
approval_id,
|
||||
turn_id,
|
||||
command,
|
||||
cwd,
|
||||
reason,
|
||||
proposed_execpolicy_amendment,
|
||||
parsed_cmd,
|
||||
..
|
||||
} = ev;
|
||||
match api_version {
|
||||
ApiVersion::V1 => {
|
||||
let params = ExecCommandApprovalParams {
|
||||
conversation_id,
|
||||
item_id,
|
||||
command_string,
|
||||
call_id: call_id.clone(),
|
||||
approval_id,
|
||||
command,
|
||||
cwd,
|
||||
command_actions,
|
||||
rx,
|
||||
conversation,
|
||||
outgoing,
|
||||
)
|
||||
.await;
|
||||
});
|
||||
reason,
|
||||
parsed_cmd,
|
||||
};
|
||||
let rx = outgoing
|
||||
.send_request(ServerRequestPayload::ExecCommandApproval(params))
|
||||
.await;
|
||||
tokio::spawn(async move {
|
||||
on_exec_approval_response(
|
||||
approval_id_for_op,
|
||||
event_turn_id,
|
||||
rx,
|
||||
conversation,
|
||||
)
|
||||
.await;
|
||||
});
|
||||
}
|
||||
ApiVersion::V2 => {
|
||||
let command_actions = parsed_cmd
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(V2ParsedCommand::from)
|
||||
.collect::<Vec<_>>();
|
||||
let command_string = shlex_join(&command);
|
||||
let proposed_execpolicy_amendment_v2 =
|
||||
proposed_execpolicy_amendment.map(V2ExecPolicyAmendment::from);
|
||||
|
||||
let params = CommandExecutionRequestApprovalParams {
|
||||
thread_id: conversation_id.to_string(),
|
||||
turn_id: turn_id.clone(),
|
||||
item_id: call_id.clone(),
|
||||
approval_id: approval_id.clone(),
|
||||
reason,
|
||||
command: Some(command_string.clone()),
|
||||
cwd: Some(cwd.clone()),
|
||||
command_actions: Some(command_actions.clone()),
|
||||
proposed_execpolicy_amendment: proposed_execpolicy_amendment_v2,
|
||||
};
|
||||
let rx = outgoing
|
||||
.send_request(ServerRequestPayload::CommandExecutionRequestApproval(
|
||||
params,
|
||||
))
|
||||
.await;
|
||||
tokio::spawn(async move {
|
||||
on_command_execution_request_approval_response(
|
||||
event_turn_id,
|
||||
conversation_id,
|
||||
approval_id,
|
||||
call_id,
|
||||
command_string,
|
||||
cwd,
|
||||
command_actions,
|
||||
rx,
|
||||
conversation,
|
||||
outgoing,
|
||||
thread_state.clone(),
|
||||
)
|
||||
.await;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
EventMsg::RequestUserInput(request) => {
|
||||
if matches!(api_version, ApiVersion::V2) {
|
||||
let questions = request
|
||||
@@ -917,6 +945,14 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
let cwd = exec_command_begin_event.cwd;
|
||||
let process_id = exec_command_begin_event.process_id;
|
||||
|
||||
{
|
||||
let mut state = thread_state.lock().await;
|
||||
state
|
||||
.turn_summary
|
||||
.command_execution_started
|
||||
.insert(item_id.clone());
|
||||
}
|
||||
|
||||
let item = ThreadItem::CommandExecution {
|
||||
id: item_id,
|
||||
command,
|
||||
@@ -1004,6 +1040,14 @@ pub(crate) async fn apply_bespoke_event_handling(
|
||||
..
|
||||
} = exec_command_end_event;
|
||||
|
||||
{
|
||||
let mut state = thread_state.lock().await;
|
||||
state
|
||||
.turn_summary
|
||||
.command_execution_started
|
||||
.remove(&call_id);
|
||||
}
|
||||
|
||||
let status: CommandExecutionStatus = (&status).into();
|
||||
let command_actions = parsed_cmd
|
||||
.into_iter()
|
||||
@@ -1723,6 +1767,7 @@ async fn on_file_change_request_approval_response(
|
||||
async fn on_command_execution_request_approval_response(
|
||||
event_turn_id: String,
|
||||
conversation_id: ThreadId,
|
||||
approval_id: Option<String>,
|
||||
item_id: String,
|
||||
command: String,
|
||||
cwd: PathBuf,
|
||||
@@ -1730,6 +1775,7 @@ async fn on_command_execution_request_approval_response(
|
||||
receiver: oneshot::Receiver<ClientRequestResult>,
|
||||
conversation: Arc<CodexThread>,
|
||||
outgoing: ThreadScopedOutgoingMessageSender,
|
||||
thread_state: Arc<Mutex<ThreadState>>,
|
||||
) {
|
||||
let response = receiver.await;
|
||||
let (decision, completion_status) = match response {
|
||||
@@ -1778,7 +1824,24 @@ async fn on_command_execution_request_approval_response(
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(status) = completion_status {
|
||||
let suppress_subcommand_completion_item = {
|
||||
// For regular shell/unified_exec approvals, approval_id is null.
|
||||
// For zsh-fork subcommand approvals, approval_id is present and
|
||||
// item_id points to the parent command item.
|
||||
if approval_id.is_some() {
|
||||
let state = thread_state.lock().await;
|
||||
state
|
||||
.turn_summary
|
||||
.command_execution_started
|
||||
.contains(&item_id)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(status) = completion_status
|
||||
&& !suppress_subcommand_completion_item
|
||||
{
|
||||
complete_command_execution_item(
|
||||
conversation_id,
|
||||
event_turn_id.clone(),
|
||||
@@ -1795,7 +1858,7 @@ async fn on_command_execution_request_approval_response(
|
||||
|
||||
if let Err(err) = conversation
|
||||
.submit(Op::ExecApproval {
|
||||
id: item_id,
|
||||
id: approval_id.unwrap_or_else(|| item_id.clone()),
|
||||
turn_id: Some(event_turn_id),
|
||||
decision,
|
||||
})
|
||||
|
||||
@@ -66,6 +66,7 @@ use codex_app_server_protocol::GetUserAgentResponse;
|
||||
use codex_app_server_protocol::GetUserSavedConfigResponse;
|
||||
use codex_app_server_protocol::GitDiffToRemoteResponse;
|
||||
use codex_app_server_protocol::GitInfo as ApiGitInfo;
|
||||
use codex_app_server_protocol::HazelnutScope as ApiHazelnutScope;
|
||||
use codex_app_server_protocol::InputItem as WireInputItem;
|
||||
use codex_app_server_protocol::InterruptConversationParams;
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
@@ -92,6 +93,7 @@ use codex_app_server_protocol::ModelListParams;
|
||||
use codex_app_server_protocol::ModelListResponse;
|
||||
use codex_app_server_protocol::NewConversationParams;
|
||||
use codex_app_server_protocol::NewConversationResponse;
|
||||
use codex_app_server_protocol::ProductSurface as ApiProductSurface;
|
||||
use codex_app_server_protocol::RemoveConversationListenerParams;
|
||||
use codex_app_server_protocol::RemoveConversationSubscriptionResponse;
|
||||
use codex_app_server_protocol::ResumeConversationParams;
|
||||
@@ -120,6 +122,7 @@ use codex_app_server_protocol::SkillsRemoteWriteResponse;
|
||||
use codex_app_server_protocol::Thread;
|
||||
use codex_app_server_protocol::ThreadArchiveParams;
|
||||
use codex_app_server_protocol::ThreadArchiveResponse;
|
||||
use codex_app_server_protocol::ThreadArchivedNotification;
|
||||
use codex_app_server_protocol::ThreadBackgroundTerminalsCleanParams;
|
||||
use codex_app_server_protocol::ThreadBackgroundTerminalsCleanResponse;
|
||||
use codex_app_server_protocol::ThreadCompactStartParams;
|
||||
@@ -145,6 +148,7 @@ use codex_app_server_protocol::ThreadStartResponse;
|
||||
use codex_app_server_protocol::ThreadStartedNotification;
|
||||
use codex_app_server_protocol::ThreadUnarchiveParams;
|
||||
use codex_app_server_protocol::ThreadUnarchiveResponse;
|
||||
use codex_app_server_protocol::ThreadUnarchivedNotification;
|
||||
use codex_app_server_protocol::Turn;
|
||||
use codex_app_server_protocol::TurnInterruptParams;
|
||||
use codex_app_server_protocol::TurnStartParams;
|
||||
@@ -207,7 +211,7 @@ use codex_core::read_head_for_summary;
|
||||
use codex_core::read_session_meta_line;
|
||||
use codex_core::rollout_date_parts;
|
||||
use codex_core::sandboxing::SandboxPermissions;
|
||||
use codex_core::skills::remote::download_remote_skill;
|
||||
use codex_core::skills::remote::export_remote_skill;
|
||||
use codex_core::skills::remote::list_remote_skills;
|
||||
use codex_core::state_db::StateDbHandle;
|
||||
use codex_core::state_db::get_state_db;
|
||||
@@ -229,6 +233,8 @@ use codex_protocol::protocol::GitInfo as CoreGitInfo;
|
||||
use codex_protocol::protocol::McpAuthStatus as CoreMcpAuthStatus;
|
||||
use codex_protocol::protocol::McpServerRefreshConfig;
|
||||
use codex_protocol::protocol::RateLimitSnapshot as CoreRateLimitSnapshot;
|
||||
use codex_protocol::protocol::RemoteSkillHazelnutScope;
|
||||
use codex_protocol::protocol::RemoteSkillProductSurface;
|
||||
use codex_protocol::protocol::RolloutItem;
|
||||
use codex_protocol::protocol::SessionMetaLine;
|
||||
use codex_protocol::protocol::USER_MESSAGE_BEGIN;
|
||||
@@ -291,6 +297,24 @@ enum AppListLoadResult {
|
||||
Directory(Result<Vec<AppInfo>, String>),
|
||||
}
|
||||
|
||||
fn convert_remote_scope(scope: ApiHazelnutScope) -> RemoteSkillHazelnutScope {
|
||||
match scope {
|
||||
ApiHazelnutScope::WorkspaceShared => RemoteSkillHazelnutScope::WorkspaceShared,
|
||||
ApiHazelnutScope::AllShared => RemoteSkillHazelnutScope::AllShared,
|
||||
ApiHazelnutScope::Personal => RemoteSkillHazelnutScope::Personal,
|
||||
ApiHazelnutScope::Example => RemoteSkillHazelnutScope::Example,
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_remote_product_surface(product_surface: ApiProductSurface) -> RemoteSkillProductSurface {
|
||||
match product_surface {
|
||||
ApiProductSurface::Chatgpt => RemoteSkillProductSurface::Chatgpt,
|
||||
ApiProductSurface::Codex => RemoteSkillProductSurface::Codex,
|
||||
ApiProductSurface::Api => RemoteSkillProductSurface::Api,
|
||||
ApiProductSurface::Atlas => RemoteSkillProductSurface::Atlas,
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ActiveLogin {
|
||||
fn drop(&mut self) {
|
||||
self.shutdown_handle.shutdown();
|
||||
@@ -549,12 +573,12 @@ impl CodexMessageProcessor {
|
||||
self.skills_list(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
}
|
||||
ClientRequest::SkillsRemoteRead { request_id, params } => {
|
||||
self.skills_remote_read(to_connection_request_id(request_id), params)
|
||||
ClientRequest::SkillsRemoteList { request_id, params } => {
|
||||
self.skills_remote_list(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
}
|
||||
ClientRequest::SkillsRemoteWrite { request_id, params } => {
|
||||
self.skills_remote_write(to_connection_request_id(request_id), params)
|
||||
ClientRequest::SkillsRemoteExport { request_id, params } => {
|
||||
self.skills_remote_export(to_connection_request_id(request_id), params)
|
||||
.await;
|
||||
}
|
||||
ClientRequest::AppsList { request_id, params } => {
|
||||
@@ -599,11 +623,10 @@ impl CodexMessageProcessor {
|
||||
ClientRequest::ModelList { request_id, params } => {
|
||||
let outgoing = self.outgoing.clone();
|
||||
let thread_manager = self.thread_manager.clone();
|
||||
let config = self.config.clone();
|
||||
let request_id = to_connection_request_id(request_id);
|
||||
|
||||
tokio::spawn(async move {
|
||||
Self::list_models(outgoing, thread_manager, config, request_id, params).await;
|
||||
Self::list_models(outgoing, thread_manager, request_id, params).await;
|
||||
});
|
||||
}
|
||||
ClientRequest::ExperimentalFeatureList { request_id, params } => {
|
||||
@@ -2105,10 +2128,17 @@ impl CodexMessageProcessor {
|
||||
}
|
||||
};
|
||||
|
||||
let thread_id_str = thread_id.to_string();
|
||||
match self.archive_thread_common(thread_id, &rollout_path).await {
|
||||
Ok(()) => {
|
||||
let response = ThreadArchiveResponse {};
|
||||
self.outgoing.send_response(request_id, response).await;
|
||||
let notification = ThreadArchivedNotification {
|
||||
thread_id: thread_id_str,
|
||||
};
|
||||
self.outgoing
|
||||
.send_server_notification(ServerNotification::ThreadArchived(notification))
|
||||
.await;
|
||||
}
|
||||
Err(err) => {
|
||||
self.outgoing.send_error(request_id, err).await;
|
||||
@@ -2314,8 +2344,13 @@ impl CodexMessageProcessor {
|
||||
|
||||
match result {
|
||||
Ok(thread) => {
|
||||
let thread_id = thread.id.clone();
|
||||
let response = ThreadUnarchiveResponse { thread };
|
||||
self.outgoing.send_response(request_id, response).await;
|
||||
let notification = ThreadUnarchivedNotification { thread_id };
|
||||
self.outgoing
|
||||
.send_server_notification(ServerNotification::ThreadUnarchived(notification))
|
||||
.await;
|
||||
}
|
||||
Err(err) => {
|
||||
self.outgoing.send_error(request_id, err).await;
|
||||
@@ -3599,7 +3634,6 @@ impl CodexMessageProcessor {
|
||||
async fn list_models(
|
||||
outgoing: Arc<OutgoingMessageSender>,
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
config: Arc<Config>,
|
||||
request_id: ConnectionRequestId,
|
||||
params: ModelListParams,
|
||||
) {
|
||||
@@ -3608,10 +3642,7 @@ impl CodexMessageProcessor {
|
||||
cursor,
|
||||
include_hidden,
|
||||
} = params;
|
||||
let mut config = (*config).clone();
|
||||
config.features.enable(Feature::RemoteModels);
|
||||
let models =
|
||||
supported_models(thread_manager, &config, include_hidden.unwrap_or(false)).await;
|
||||
let models = supported_models(thread_manager, include_hidden.unwrap_or(false)).await;
|
||||
let total = models.len();
|
||||
|
||||
if total == 0 {
|
||||
@@ -5048,12 +5079,25 @@ impl CodexMessageProcessor {
|
||||
.await;
|
||||
}
|
||||
|
||||
async fn skills_remote_read(
|
||||
async fn skills_remote_list(
|
||||
&self,
|
||||
request_id: ConnectionRequestId,
|
||||
_params: SkillsRemoteReadParams,
|
||||
params: SkillsRemoteReadParams,
|
||||
) {
|
||||
match list_remote_skills(&self.config).await {
|
||||
let hazelnut_scope = convert_remote_scope(params.hazelnut_scope);
|
||||
let product_surface = convert_remote_product_surface(params.product_surface);
|
||||
let enabled = if params.enabled { Some(true) } else { None };
|
||||
|
||||
let auth = self.auth_manager.auth().await;
|
||||
match list_remote_skills(
|
||||
&self.config,
|
||||
auth.as_ref(),
|
||||
hazelnut_scope,
|
||||
product_surface,
|
||||
enabled,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(skills) => {
|
||||
let data = skills
|
||||
.into_iter()
|
||||
@@ -5070,23 +5114,21 @@ impl CodexMessageProcessor {
|
||||
Err(err) => {
|
||||
self.send_internal_error(
|
||||
request_id,
|
||||
format!("failed to read remote skills: {err}"),
|
||||
format!("failed to list remote skills: {err}"),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn skills_remote_write(
|
||||
async fn skills_remote_export(
|
||||
&self,
|
||||
request_id: ConnectionRequestId,
|
||||
params: SkillsRemoteWriteParams,
|
||||
) {
|
||||
let SkillsRemoteWriteParams {
|
||||
hazelnut_id,
|
||||
is_preload,
|
||||
} = params;
|
||||
let response = download_remote_skill(&self.config, hazelnut_id.as_str(), is_preload).await;
|
||||
let SkillsRemoteWriteParams { hazelnut_id } = params;
|
||||
let auth = self.auth_manager.auth().await;
|
||||
let response = export_remote_skill(&self.config, auth.as_ref(), hazelnut_id.as_str()).await;
|
||||
|
||||
match response {
|
||||
Ok(downloaded) => {
|
||||
@@ -5095,7 +5137,6 @@ impl CodexMessageProcessor {
|
||||
request_id,
|
||||
SkillsRemoteWriteResponse {
|
||||
id: downloaded.id,
|
||||
name: downloaded.name,
|
||||
path: downloaded.path,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -23,6 +23,9 @@ struct AppServerArgs {
|
||||
}
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
if codex_core::maybe_run_zsh_exec_wrapper_mode()? {
|
||||
return Ok(());
|
||||
}
|
||||
arg0_dispatch_or_else(|codex_linux_sandbox_exe| async move {
|
||||
let args = AppServerArgs::parse();
|
||||
let managed_config_path = managed_config_path_from_debug_env();
|
||||
|
||||
@@ -3,18 +3,16 @@ use std::sync::Arc;
|
||||
use codex_app_server_protocol::Model;
|
||||
use codex_app_server_protocol::ReasoningEffortOption;
|
||||
use codex_core::ThreadManager;
|
||||
use codex_core::config::Config;
|
||||
use codex_core::models_manager::manager::RefreshStrategy;
|
||||
use codex_protocol::openai_models::ModelPreset;
|
||||
use codex_protocol::openai_models::ReasoningEffortPreset;
|
||||
|
||||
pub async fn supported_models(
|
||||
thread_manager: Arc<ThreadManager>,
|
||||
config: &Config,
|
||||
include_hidden: bool,
|
||||
) -> Vec<Model> {
|
||||
thread_manager
|
||||
.list_models(config, RefreshStrategy::OnlineIfUncached)
|
||||
.list_models(RefreshStrategy::OnlineIfUncached)
|
||||
.await
|
||||
.into_iter()
|
||||
.filter(|preset| include_hidden || preset.show_in_picker)
|
||||
|
||||
@@ -399,6 +399,8 @@ mod tests {
|
||||
use codex_app_server_protocol::AuthMode;
|
||||
use codex_app_server_protocol::ConfigWarningNotification;
|
||||
use codex_app_server_protocol::LoginChatGptCompleteNotification;
|
||||
use codex_app_server_protocol::ModelRerouteReason;
|
||||
use codex_app_server_protocol::ModelReroutedNotification;
|
||||
use codex_app_server_protocol::RateLimitSnapshot;
|
||||
use codex_app_server_protocol::RateLimitWindow;
|
||||
use codex_protocol::ThreadId;
|
||||
@@ -546,6 +548,34 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_model_rerouted_notification_serialization() {
|
||||
let notification = ServerNotification::ModelRerouted(ModelReroutedNotification {
|
||||
thread_id: "thread-1".to_string(),
|
||||
turn_id: "turn-1".to_string(),
|
||||
from_model: "gpt-5.3-codex".to_string(),
|
||||
to_model: "gpt-5.2".to_string(),
|
||||
reason: ModelRerouteReason::HighRiskCyberActivity,
|
||||
});
|
||||
|
||||
let jsonrpc_notification = OutgoingMessage::AppServerNotification(notification);
|
||||
assert_eq!(
|
||||
json!({
|
||||
"method": "model/rerouted",
|
||||
"params": {
|
||||
"threadId": "thread-1",
|
||||
"turnId": "turn-1",
|
||||
"fromModel": "gpt-5.3-codex",
|
||||
"toModel": "gpt-5.2",
|
||||
"reason": "highRiskCyberActivity",
|
||||
},
|
||||
}),
|
||||
serde_json::to_value(jsonrpc_notification)
|
||||
.expect("ensure the notification serializes correctly"),
|
||||
"ensure the notification serializes correctly"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn send_response_routes_to_target_connection() {
|
||||
let (tx, mut rx) = mpsc::channel::<OutgoingEnvelope>(4);
|
||||
|
||||
@@ -20,6 +20,7 @@ type PendingInterruptQueue = Vec<(
|
||||
#[derive(Default, Clone)]
|
||||
pub(crate) struct TurnSummary {
|
||||
pub(crate) file_change_started: HashSet<String>,
|
||||
pub(crate) command_execution_started: HashSet<String>,
|
||||
pub(crate) last_error: Option<TurnError>,
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ pub fn write_mock_responses_config_toml(
|
||||
compact_prompt: &str,
|
||||
) -> std::io::Result<()> {
|
||||
// Phase 1: build the features block for config.toml.
|
||||
let mut features = BTreeMap::from([(Feature::RemoteModels, false)]);
|
||||
let mut features = BTreeMap::new();
|
||||
for (feature, enabled) in feature_flags {
|
||||
features.insert(*feature, *enabled);
|
||||
}
|
||||
|
||||
@@ -298,6 +298,7 @@ async fn test_send_user_turn_changes_approval_policy_behavior() -> Result<()> {
|
||||
ExecCommandApprovalParams {
|
||||
conversation_id,
|
||||
call_id: "call1".to_string(),
|
||||
approval_id: None,
|
||||
command: format_with_current_shell("python3 -c 'print(42)'"),
|
||||
cwd: working_directory.clone(),
|
||||
reason: None,
|
||||
|
||||
@@ -477,7 +477,6 @@ fn assert_permissions_message(item: &ResponseItem) {
|
||||
&SandboxPolicy::DangerFullAccess,
|
||||
AskForApproval::Never,
|
||||
&Policy::empty(),
|
||||
false,
|
||||
&PathBuf::from("/tmp"),
|
||||
)
|
||||
.into_text();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex as StdMutex;
|
||||
use std::time::Duration;
|
||||
@@ -16,8 +17,12 @@ use axum::http::HeaderMap;
|
||||
use axum::http::StatusCode;
|
||||
use axum::http::header::AUTHORIZATION;
|
||||
use axum::routing::get;
|
||||
use codex_app_server_protocol::AppBranding;
|
||||
use codex_app_server_protocol::AppInfo;
|
||||
use codex_app_server_protocol::AppListUpdatedNotification;
|
||||
use codex_app_server_protocol::AppMetadata;
|
||||
use codex_app_server_protocol::AppReview;
|
||||
use codex_app_server_protocol::AppScreenshot;
|
||||
use codex_app_server_protocol::AppsListParams;
|
||||
use codex_app_server_protocol::AppsListResponse;
|
||||
use codex_app_server_protocol::JSONRPCError;
|
||||
@@ -85,6 +90,9 @@ async fn list_apps_uses_thread_feature_flag_when_thread_id_is_provided() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -184,6 +192,9 @@ async fn list_apps_reports_is_enabled_from_config() -> Result<()> {
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -249,6 +260,39 @@ enabled = false
|
||||
|
||||
#[tokio::test]
|
||||
async fn list_apps_emits_updates_and_returns_after_both_lists_load() -> Result<()> {
|
||||
let alpha_branding = Some(AppBranding {
|
||||
category: Some("PRODUCTIVITY".to_string()),
|
||||
developer: Some("Acme".to_string()),
|
||||
website: Some("https://acme.example".to_string()),
|
||||
privacy_policy: Some("https://acme.example/privacy".to_string()),
|
||||
terms_of_service: Some("https://acme.example/terms".to_string()),
|
||||
is_discoverable_app: true,
|
||||
});
|
||||
let alpha_app_metadata = Some(AppMetadata {
|
||||
review: Some(AppReview {
|
||||
status: "APPROVED".to_string(),
|
||||
}),
|
||||
categories: Some(vec!["PRODUCTIVITY".to_string()]),
|
||||
sub_categories: Some(vec!["WRITING".to_string()]),
|
||||
seo_description: Some("Alpha connector".to_string()),
|
||||
screenshots: Some(vec![AppScreenshot {
|
||||
url: Some("https://example.com/alpha-screenshot.png".to_string()),
|
||||
file_id: Some("file_123".to_string()),
|
||||
user_prompt: "Summarize this draft".to_string(),
|
||||
}]),
|
||||
developer: Some("Acme".to_string()),
|
||||
version: Some("1.2.3".to_string()),
|
||||
version_id: Some("version_123".to_string()),
|
||||
version_notes: Some("Fixes and improvements".to_string()),
|
||||
first_party_type: Some("internal".to_string()),
|
||||
first_party_requires_install: Some(true),
|
||||
show_in_composer_when_unlinked: Some(true),
|
||||
});
|
||||
let alpha_labels = Some(HashMap::from([
|
||||
("feature".to_string(), "beta".to_string()),
|
||||
("source".to_string(), "directory".to_string()),
|
||||
]));
|
||||
|
||||
let connectors = vec![
|
||||
AppInfo {
|
||||
id: "alpha".to_string(),
|
||||
@@ -257,6 +301,9 @@ async fn list_apps_emits_updates_and_returns_after_both_lists_load() -> Result<(
|
||||
logo_url: Some("https://example.com/alpha.png".to_string()),
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: alpha_branding.clone(),
|
||||
app_metadata: alpha_app_metadata.clone(),
|
||||
labels: alpha_labels.clone(),
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -268,6 +315,9 @@ async fn list_apps_emits_updates_and_returns_after_both_lists_load() -> Result<(
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -313,6 +363,9 @@ async fn list_apps_emits_updates_and_returns_after_both_lists_load() -> Result<(
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/beta-app/beta".to_string()),
|
||||
is_accessible: true,
|
||||
is_enabled: true,
|
||||
@@ -329,6 +382,9 @@ async fn list_apps_emits_updates_and_returns_after_both_lists_load() -> Result<(
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/beta/beta".to_string()),
|
||||
is_accessible: true,
|
||||
is_enabled: true,
|
||||
@@ -340,6 +396,9 @@ async fn list_apps_emits_updates_and_returns_after_both_lists_load() -> Result<(
|
||||
logo_url: Some("https://example.com/alpha.png".to_string()),
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: alpha_branding,
|
||||
app_metadata: alpha_app_metadata,
|
||||
labels: alpha_labels,
|
||||
install_url: Some("https://chatgpt.com/apps/alpha/alpha".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -377,6 +436,9 @@ async fn list_apps_returns_connectors_with_accessible_flags() -> Result<()> {
|
||||
logo_url: Some("https://example.com/alpha.png".to_string()),
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -388,6 +450,9 @@ async fn list_apps_returns_connectors_with_accessible_flags() -> Result<()> {
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -437,6 +502,9 @@ async fn list_apps_returns_connectors_with_accessible_flags() -> Result<()> {
|
||||
logo_url: Some("https://example.com/alpha.png".to_string()),
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/alpha/alpha".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -448,6 +516,9 @@ async fn list_apps_returns_connectors_with_accessible_flags() -> Result<()> {
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/beta/beta".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -463,6 +534,9 @@ async fn list_apps_returns_connectors_with_accessible_flags() -> Result<()> {
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/beta/beta".to_string()),
|
||||
is_accessible: true,
|
||||
is_enabled: true,
|
||||
@@ -474,6 +548,9 @@ async fn list_apps_returns_connectors_with_accessible_flags() -> Result<()> {
|
||||
logo_url: Some("https://example.com/alpha.png".to_string()),
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/alpha/alpha".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -506,6 +583,9 @@ async fn list_apps_paginates_results() -> Result<()> {
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -517,6 +597,9 @@ async fn list_apps_paginates_results() -> Result<()> {
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -571,6 +654,9 @@ async fn list_apps_paginates_results() -> Result<()> {
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/beta/beta".to_string()),
|
||||
is_accessible: true,
|
||||
is_enabled: true,
|
||||
@@ -611,6 +697,9 @@ async fn list_apps_paginates_results() -> Result<()> {
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/alpha/alpha".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -632,6 +721,9 @@ async fn list_apps_force_refetch_preserves_previous_cache_on_failure() -> Result
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -733,6 +825,9 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -744,6 +839,9 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -790,6 +888,9 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/beta-app/beta".to_string()),
|
||||
is_accessible: true,
|
||||
is_enabled: true,
|
||||
@@ -807,6 +908,9 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/beta-app/beta".to_string()),
|
||||
is_accessible: true,
|
||||
is_enabled: true,
|
||||
@@ -818,6 +922,9 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/alpha/alpha".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -844,6 +951,9 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: None,
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -870,6 +980,9 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/alpha/alpha".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -881,6 +994,9 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/beta-app/beta".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
@@ -895,6 +1011,9 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
|
||||
logo_url: None,
|
||||
logo_url_dark: None,
|
||||
distribution_channel: None,
|
||||
branding: None,
|
||||
app_metadata: None,
|
||||
labels: None,
|
||||
install_url: Some("https://chatgpt.com/apps/alpha/alpha".to_string()),
|
||||
is_accessible: false,
|
||||
is_enabled: true,
|
||||
|
||||
@@ -15,6 +15,7 @@ mod plan_item;
|
||||
mod rate_limits;
|
||||
mod request_user_input;
|
||||
mod review;
|
||||
mod safety_check_downgrade;
|
||||
mod skills_list;
|
||||
mod thread_archive;
|
||||
mod thread_fork;
|
||||
@@ -27,4 +28,5 @@ mod thread_start;
|
||||
mod thread_unarchive;
|
||||
mod turn_interrupt;
|
||||
mod turn_start;
|
||||
mod turn_start_zsh_fork;
|
||||
mod turn_steer;
|
||||
|
||||
@@ -215,10 +215,7 @@ async fn collect_turn_notifications(
|
||||
}
|
||||
|
||||
fn create_config_toml(codex_home: &Path, server_uri: &str) -> std::io::Result<()> {
|
||||
let features = BTreeMap::from([
|
||||
(Feature::RemoteModels, false),
|
||||
(Feature::CollaborationModes, true),
|
||||
]);
|
||||
let features = BTreeMap::from([(Feature::CollaborationModes, true)]);
|
||||
let feature_entries = features
|
||||
.into_iter()
|
||||
.map(|(feature, enabled)| {
|
||||
|
||||
@@ -437,7 +437,6 @@ sandbox_mode = "read-only"
|
||||
model_provider = "mock_provider"
|
||||
|
||||
[features]
|
||||
remote_models = false
|
||||
shell_snapshot = false
|
||||
|
||||
[model_providers.mock_provider]
|
||||
|
||||
246
codex-rs/app-server/tests/suite/v2/safety_check_downgrade.rs
Normal file
246
codex-rs/app-server/tests/suite/v2/safety_check_downgrade.rs
Normal file
@@ -0,0 +1,246 @@
|
||||
use anyhow::Result;
|
||||
use app_test_support::McpProcess;
|
||||
use app_test_support::to_response;
|
||||
use codex_app_server_protocol::ItemCompletedNotification;
|
||||
use codex_app_server_protocol::ItemStartedNotification;
|
||||
use codex_app_server_protocol::JSONRPCMessage;
|
||||
use codex_app_server_protocol::JSONRPCResponse;
|
||||
use codex_app_server_protocol::ModelRerouteReason;
|
||||
use codex_app_server_protocol::ModelReroutedNotification;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
use codex_app_server_protocol::ThreadItem;
|
||||
use codex_app_server_protocol::ThreadStartParams;
|
||||
use codex_app_server_protocol::ThreadStartResponse;
|
||||
use codex_app_server_protocol::TurnStartParams;
|
||||
use codex_app_server_protocol::TurnStartResponse;
|
||||
use codex_app_server_protocol::UserInput;
|
||||
use core_test_support::responses;
|
||||
use core_test_support::skip_if_no_network;
|
||||
use pretty_assertions::assert_eq;
|
||||
use tempfile::TempDir;
|
||||
use tokio::time::timeout;
|
||||
|
||||
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
|
||||
const REQUESTED_MODEL: &str = "gpt-5.1-codex-max";
|
||||
const SERVER_MODEL: &str = "gpt-5.2-codex";
|
||||
|
||||
#[tokio::test]
|
||||
async fn openai_model_header_mismatch_emits_model_rerouted_notification_v2() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = responses::start_mock_server().await;
|
||||
let body = responses::sse(vec![
|
||||
responses::ev_response_created("resp-1"),
|
||||
responses::ev_assistant_message("msg-1", "Done"),
|
||||
responses::ev_completed("resp-1"),
|
||||
]);
|
||||
let response = responses::sse_response(body).insert_header("OpenAI-Model", SERVER_MODEL);
|
||||
let _response_mock = responses::mount_response_once(&server, response).await;
|
||||
|
||||
let codex_home = TempDir::new()?;
|
||||
create_config_toml(codex_home.path(), &server.uri())?;
|
||||
|
||||
let mut mcp = McpProcess::new(codex_home.path()).await?;
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let thread_req = mcp
|
||||
.send_thread_start_request(ThreadStartParams {
|
||||
model: Some(REQUESTED_MODEL.to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let thread_resp: JSONRPCResponse = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(thread_req)),
|
||||
)
|
||||
.await??;
|
||||
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(thread_resp)?;
|
||||
|
||||
let turn_req = mcp
|
||||
.send_turn_start_request(TurnStartParams {
|
||||
thread_id: thread.id.clone(),
|
||||
input: vec![UserInput::Text {
|
||||
text: "trigger safeguard".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let turn_resp: JSONRPCResponse = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(turn_req)),
|
||||
)
|
||||
.await??;
|
||||
let turn_start: TurnStartResponse = to_response(turn_resp)?;
|
||||
|
||||
let rerouted = collect_turn_notifications_and_validate_no_warning_item(&mut mcp).await?;
|
||||
assert_eq!(
|
||||
rerouted,
|
||||
ModelReroutedNotification {
|
||||
thread_id: thread.id,
|
||||
turn_id: turn_start.turn.id,
|
||||
from_model: REQUESTED_MODEL.to_string(),
|
||||
to_model: SERVER_MODEL.to_string(),
|
||||
reason: ModelRerouteReason::HighRiskCyberActivity,
|
||||
}
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn response_model_field_mismatch_emits_model_rerouted_notification_v2_when_header_matches_requested()
|
||||
-> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let server = responses::start_mock_server().await;
|
||||
let body = responses::sse(vec![
|
||||
serde_json::json!({
|
||||
"type": "response.created",
|
||||
"response": {
|
||||
"id": "resp-1",
|
||||
"headers": {
|
||||
"OpenAI-Model": SERVER_MODEL
|
||||
}
|
||||
}
|
||||
}),
|
||||
responses::ev_assistant_message("msg-1", "Done"),
|
||||
responses::ev_completed("resp-1"),
|
||||
]);
|
||||
let response = responses::sse_response(body).insert_header("OpenAI-Model", REQUESTED_MODEL);
|
||||
let _response_mock = responses::mount_response_once(&server, response).await;
|
||||
|
||||
let codex_home = TempDir::new()?;
|
||||
create_config_toml(codex_home.path(), &server.uri())?;
|
||||
|
||||
let mut mcp = McpProcess::new(codex_home.path()).await?;
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let thread_req = mcp
|
||||
.send_thread_start_request(ThreadStartParams {
|
||||
model: Some(REQUESTED_MODEL.to_string()),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let thread_resp: JSONRPCResponse = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(thread_req)),
|
||||
)
|
||||
.await??;
|
||||
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(thread_resp)?;
|
||||
|
||||
let turn_req = mcp
|
||||
.send_turn_start_request(TurnStartParams {
|
||||
thread_id: thread.id.clone(),
|
||||
input: vec![UserInput::Text {
|
||||
text: "trigger response model check".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let turn_resp: JSONRPCResponse = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(turn_req)),
|
||||
)
|
||||
.await??;
|
||||
let turn_start: TurnStartResponse = to_response(turn_resp)?;
|
||||
|
||||
let rerouted = collect_turn_notifications_and_validate_no_warning_item(&mut mcp).await?;
|
||||
assert_eq!(
|
||||
rerouted,
|
||||
ModelReroutedNotification {
|
||||
thread_id: thread.id,
|
||||
turn_id: turn_start.turn.id,
|
||||
from_model: REQUESTED_MODEL.to_string(),
|
||||
to_model: SERVER_MODEL.to_string(),
|
||||
reason: ModelRerouteReason::HighRiskCyberActivity,
|
||||
}
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn collect_turn_notifications_and_validate_no_warning_item(
|
||||
mcp: &mut McpProcess,
|
||||
) -> Result<ModelReroutedNotification> {
|
||||
let mut rerouted = None;
|
||||
|
||||
loop {
|
||||
let message = timeout(DEFAULT_READ_TIMEOUT, mcp.read_next_message()).await??;
|
||||
let JSONRPCMessage::Notification(notification) = message else {
|
||||
continue;
|
||||
};
|
||||
match notification.method.as_str() {
|
||||
"model/rerouted" => {
|
||||
let params = notification.params.ok_or_else(|| {
|
||||
anyhow::anyhow!("model/rerouted notifications must include params")
|
||||
})?;
|
||||
let payload: ModelReroutedNotification = serde_json::from_value(params)?;
|
||||
rerouted = Some(payload);
|
||||
}
|
||||
"item/started" => {
|
||||
let params = notification.params.ok_or_else(|| {
|
||||
anyhow::anyhow!("item/started notifications must include params")
|
||||
})?;
|
||||
let payload: ItemStartedNotification = serde_json::from_value(params)?;
|
||||
assert!(!is_warning_user_message_item(&payload.item));
|
||||
}
|
||||
"item/completed" => {
|
||||
let params = notification.params.ok_or_else(|| {
|
||||
anyhow::anyhow!("item/completed notifications must include params")
|
||||
})?;
|
||||
let payload: ItemCompletedNotification = serde_json::from_value(params)?;
|
||||
assert!(!is_warning_user_message_item(&payload.item));
|
||||
}
|
||||
"turn/completed" => {
|
||||
return rerouted.ok_or_else(|| {
|
||||
anyhow::anyhow!("expected model/rerouted notification before turn/completed")
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn warning_text_from_item(item: &ThreadItem) -> Option<&str> {
|
||||
let ThreadItem::UserMessage { content, .. } = item else {
|
||||
return None;
|
||||
};
|
||||
|
||||
content.iter().find_map(|input| match input {
|
||||
UserInput::Text { text, .. } if text.starts_with("Warning: ") => Some(text.as_str()),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
fn is_warning_user_message_item(item: &ThreadItem) -> bool {
|
||||
warning_text_from_item(item).is_some()
|
||||
}
|
||||
|
||||
fn create_config_toml(codex_home: &std::path::Path, server_uri: &str) -> std::io::Result<()> {
|
||||
let config_toml = codex_home.join("config.toml");
|
||||
std::fs::write(
|
||||
config_toml,
|
||||
format!(
|
||||
r#"
|
||||
model = "{REQUESTED_MODEL}"
|
||||
approval_policy = "never"
|
||||
sandbox_mode = "read-only"
|
||||
|
||||
model_provider = "mock_provider"
|
||||
|
||||
[features]
|
||||
remote_models = false
|
||||
personality = true
|
||||
|
||||
[model_providers.mock_provider]
|
||||
name = "Mock provider for test"
|
||||
base_url = "{server_uri}/v1"
|
||||
wire_api = "responses"
|
||||
request_max_retries = 0
|
||||
stream_max_retries = 0
|
||||
"#
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -7,6 +7,7 @@ use codex_app_server_protocol::JSONRPCResponse;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
use codex_app_server_protocol::ThreadArchiveParams;
|
||||
use codex_app_server_protocol::ThreadArchiveResponse;
|
||||
use codex_app_server_protocol::ThreadArchivedNotification;
|
||||
use codex_app_server_protocol::ThreadStartParams;
|
||||
use codex_app_server_protocol::ThreadStartResponse;
|
||||
use codex_app_server_protocol::TurnStartParams;
|
||||
@@ -14,6 +15,7 @@ use codex_app_server_protocol::TurnStartResponse;
|
||||
use codex_app_server_protocol::UserInput;
|
||||
use codex_core::ARCHIVED_SESSIONS_SUBDIR;
|
||||
use codex_core::find_thread_path_by_id_str;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::path::Path;
|
||||
use tempfile::TempDir;
|
||||
use tokio::time::timeout;
|
||||
@@ -122,6 +124,17 @@ async fn thread_archive_requires_materialized_rollout() -> Result<()> {
|
||||
)
|
||||
.await??;
|
||||
let _: ThreadArchiveResponse = to_response::<ThreadArchiveResponse>(archive_resp)?;
|
||||
let archive_notification = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_notification_message("thread/archived"),
|
||||
)
|
||||
.await??;
|
||||
let archived_notification: ThreadArchivedNotification = serde_json::from_value(
|
||||
archive_notification
|
||||
.params
|
||||
.expect("thread/archived notification params"),
|
||||
)?;
|
||||
assert_eq!(archived_notification.thread_id, thread.id);
|
||||
|
||||
// Verify file moved.
|
||||
let archived_directory = codex_home.path().join(ARCHIVED_SESSIONS_SUBDIR);
|
||||
|
||||
@@ -1008,7 +1008,6 @@ sandbox_mode = "read-only"
|
||||
model_provider = "mock_provider"
|
||||
|
||||
[features]
|
||||
remote_models = false
|
||||
personality = true
|
||||
|
||||
[model_providers.mock_provider]
|
||||
@@ -1038,7 +1037,6 @@ sandbox_mode = "read-only"
|
||||
model_provider = "mock_provider"
|
||||
|
||||
[features]
|
||||
remote_models = false
|
||||
personality = true
|
||||
|
||||
[model_providers.mock_provider]
|
||||
|
||||
@@ -10,11 +10,13 @@ use codex_app_server_protocol::ThreadStartParams;
|
||||
use codex_app_server_protocol::ThreadStartResponse;
|
||||
use codex_app_server_protocol::ThreadUnarchiveParams;
|
||||
use codex_app_server_protocol::ThreadUnarchiveResponse;
|
||||
use codex_app_server_protocol::ThreadUnarchivedNotification;
|
||||
use codex_app_server_protocol::TurnStartParams;
|
||||
use codex_app_server_protocol::TurnStartResponse;
|
||||
use codex_app_server_protocol::UserInput;
|
||||
use codex_core::find_archived_thread_path_by_id_str;
|
||||
use codex_core::find_thread_path_by_id_str;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::fs::FileTimes;
|
||||
use std::fs::OpenOptions;
|
||||
use std::path::Path;
|
||||
@@ -120,6 +122,17 @@ async fn thread_unarchive_moves_rollout_back_into_sessions_directory() -> Result
|
||||
let ThreadUnarchiveResponse {
|
||||
thread: unarchived_thread,
|
||||
} = to_response::<ThreadUnarchiveResponse>(unarchive_resp)?;
|
||||
let unarchive_notification = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_notification_message("thread/unarchived"),
|
||||
)
|
||||
.await??;
|
||||
let unarchived_notification: ThreadUnarchivedNotification = serde_json::from_value(
|
||||
unarchive_notification
|
||||
.params
|
||||
.expect("thread/unarchived notification params"),
|
||||
)?;
|
||||
assert_eq!(unarchived_notification.thread_id, thread.id);
|
||||
assert!(
|
||||
unarchived_thread.updated_at > old_timestamp,
|
||||
"expected updated_at to be bumped on unarchive"
|
||||
|
||||
@@ -1871,7 +1871,7 @@ fn create_config_toml_with_sandbox(
|
||||
feature_flags: &BTreeMap<Feature, bool>,
|
||||
sandbox_mode: &str,
|
||||
) -> std::io::Result<()> {
|
||||
let mut features = BTreeMap::from([(Feature::RemoteModels, false)]);
|
||||
let mut features = BTreeMap::new();
|
||||
for (feature, enabled) in feature_flags {
|
||||
features.insert(*feature, *enabled);
|
||||
}
|
||||
|
||||
676
codex-rs/app-server/tests/suite/v2/turn_start_zsh_fork.rs
Normal file
676
codex-rs/app-server/tests/suite/v2/turn_start_zsh_fork.rs
Normal file
@@ -0,0 +1,676 @@
|
||||
#![cfg(not(windows))]
|
||||
//
|
||||
// Running these tests with the patched zsh fork:
|
||||
//
|
||||
// The suite uses `CODEX_TEST_ZSH_PATH` when set. Example:
|
||||
// CODEX_TEST_ZSH_PATH="$HOME/.local/codex-zsh-77045ef/bin/zsh" \
|
||||
// cargo test -p codex-app-server turn_start_zsh_fork -- --nocapture
|
||||
//
|
||||
// For a single test:
|
||||
// CODEX_TEST_ZSH_PATH="$HOME/.local/codex-zsh-77045ef/bin/zsh" \
|
||||
// cargo test -p codex-app-server turn_start_shell_zsh_fork_subcommand_decline_marks_parent_declined_v2 -- --nocapture
|
||||
|
||||
use anyhow::Result;
|
||||
use app_test_support::McpProcess;
|
||||
use app_test_support::create_final_assistant_message_sse_response;
|
||||
use app_test_support::create_mock_responses_server_sequence;
|
||||
use app_test_support::create_shell_command_sse_response;
|
||||
use app_test_support::to_response;
|
||||
use codex_app_server_protocol::CommandExecutionApprovalDecision;
|
||||
use codex_app_server_protocol::CommandExecutionRequestApprovalResponse;
|
||||
use codex_app_server_protocol::CommandExecutionStatus;
|
||||
use codex_app_server_protocol::ItemCompletedNotification;
|
||||
use codex_app_server_protocol::ItemStartedNotification;
|
||||
use codex_app_server_protocol::JSONRPCResponse;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
use codex_app_server_protocol::ServerRequest;
|
||||
use codex_app_server_protocol::ThreadItem;
|
||||
use codex_app_server_protocol::ThreadStartParams;
|
||||
use codex_app_server_protocol::ThreadStartResponse;
|
||||
use codex_app_server_protocol::TurnCompletedNotification;
|
||||
use codex_app_server_protocol::TurnStartParams;
|
||||
use codex_app_server_protocol::TurnStatus;
|
||||
use codex_app_server_protocol::UserInput as V2UserInput;
|
||||
use codex_core::features::FEATURES;
|
||||
use codex_core::features::Feature;
|
||||
use core_test_support::responses;
|
||||
use core_test_support::skip_if_no_network;
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::Path;
|
||||
use tempfile::TempDir;
|
||||
use tokio::time::timeout;
|
||||
|
||||
#[cfg(windows)]
|
||||
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(15);
|
||||
#[cfg(not(windows))]
|
||||
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_start_shell_zsh_fork_executes_command_v2() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let tmp = TempDir::new()?;
|
||||
let codex_home = tmp.path().join("codex_home");
|
||||
std::fs::create_dir(&codex_home)?;
|
||||
let workspace = tmp.path().join("workspace");
|
||||
std::fs::create_dir(&workspace)?;
|
||||
|
||||
let Some(zsh_path) = find_test_zsh_path() else {
|
||||
eprintln!("skipping zsh fork test: no zsh executable found");
|
||||
return Ok(());
|
||||
};
|
||||
eprintln!("using zsh path for zsh-fork test: {}", zsh_path.display());
|
||||
|
||||
let responses = vec![create_shell_command_sse_response(
|
||||
vec!["echo".to_string(), "hi".to_string()],
|
||||
None,
|
||||
Some(5000),
|
||||
"call-zsh-fork",
|
||||
)?];
|
||||
let server = create_mock_responses_server_sequence(responses).await;
|
||||
create_config_toml(
|
||||
&codex_home,
|
||||
&server.uri(),
|
||||
"never",
|
||||
&BTreeMap::from([
|
||||
(Feature::ShellZshFork, true),
|
||||
(Feature::UnifiedExec, false),
|
||||
(Feature::ShellSnapshot, false),
|
||||
]),
|
||||
&zsh_path,
|
||||
)?;
|
||||
|
||||
let mut mcp = McpProcess::new(&codex_home).await?;
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let start_id = mcp
|
||||
.send_thread_start_request(ThreadStartParams {
|
||||
model: Some("mock-model".to_string()),
|
||||
cwd: Some(workspace.to_string_lossy().into_owned()),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let start_resp: JSONRPCResponse = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(start_id)),
|
||||
)
|
||||
.await??;
|
||||
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(start_resp)?;
|
||||
|
||||
let turn_id = mcp
|
||||
.send_turn_start_request(TurnStartParams {
|
||||
thread_id: thread.id,
|
||||
input: vec![V2UserInput::Text {
|
||||
text: "run echo hi".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
cwd: Some(workspace.clone()),
|
||||
approval_policy: Some(codex_app_server_protocol::AskForApproval::Never),
|
||||
sandbox_policy: Some(codex_app_server_protocol::SandboxPolicy::DangerFullAccess),
|
||||
model: Some("mock-model".to_string()),
|
||||
effort: Some(codex_protocol::openai_models::ReasoningEffort::Medium),
|
||||
summary: Some(codex_core::protocol_config_types::ReasoningSummary::Auto),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(turn_id)),
|
||||
)
|
||||
.await??;
|
||||
|
||||
let started_command_execution = timeout(DEFAULT_READ_TIMEOUT, async {
|
||||
loop {
|
||||
let started_notif = mcp
|
||||
.read_stream_until_notification_message("item/started")
|
||||
.await?;
|
||||
let started: ItemStartedNotification =
|
||||
serde_json::from_value(started_notif.params.clone().expect("item/started params"))?;
|
||||
if let ThreadItem::CommandExecution { .. } = started.item {
|
||||
return Ok::<ThreadItem, anyhow::Error>(started.item);
|
||||
}
|
||||
}
|
||||
})
|
||||
.await??;
|
||||
let ThreadItem::CommandExecution {
|
||||
id,
|
||||
status,
|
||||
command,
|
||||
cwd,
|
||||
..
|
||||
} = started_command_execution
|
||||
else {
|
||||
unreachable!("loop ensures we break on command execution items");
|
||||
};
|
||||
assert_eq!(id, "call-zsh-fork");
|
||||
assert_eq!(status, CommandExecutionStatus::InProgress);
|
||||
assert!(command.starts_with(&zsh_path.display().to_string()));
|
||||
assert!(command.contains(" -lc 'echo hi'"));
|
||||
assert_eq!(cwd, workspace);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_start_shell_zsh_fork_exec_approval_decline_v2() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let tmp = TempDir::new()?;
|
||||
let codex_home = tmp.path().join("codex_home");
|
||||
std::fs::create_dir(&codex_home)?;
|
||||
let workspace = tmp.path().join("workspace");
|
||||
std::fs::create_dir(&workspace)?;
|
||||
|
||||
let Some(zsh_path) = find_test_zsh_path() else {
|
||||
eprintln!("skipping zsh fork decline test: no zsh executable found");
|
||||
return Ok(());
|
||||
};
|
||||
eprintln!("using zsh path for zsh-fork test: {}", zsh_path.display());
|
||||
|
||||
let responses = vec![
|
||||
create_shell_command_sse_response(
|
||||
vec![
|
||||
"python3".to_string(),
|
||||
"-c".to_string(),
|
||||
"print(42)".to_string(),
|
||||
],
|
||||
None,
|
||||
Some(5000),
|
||||
"call-zsh-fork-decline",
|
||||
)?,
|
||||
create_final_assistant_message_sse_response("done")?,
|
||||
];
|
||||
let server = create_mock_responses_server_sequence(responses).await;
|
||||
create_config_toml(
|
||||
&codex_home,
|
||||
&server.uri(),
|
||||
"untrusted",
|
||||
&BTreeMap::from([
|
||||
(Feature::ShellZshFork, true),
|
||||
(Feature::UnifiedExec, false),
|
||||
(Feature::ShellSnapshot, false),
|
||||
]),
|
||||
&zsh_path,
|
||||
)?;
|
||||
|
||||
let mut mcp = McpProcess::new(&codex_home).await?;
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let start_id = mcp
|
||||
.send_thread_start_request(ThreadStartParams {
|
||||
model: Some("mock-model".to_string()),
|
||||
cwd: Some(workspace.to_string_lossy().into_owned()),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let start_resp: JSONRPCResponse = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(start_id)),
|
||||
)
|
||||
.await??;
|
||||
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(start_resp)?;
|
||||
|
||||
let turn_id = mcp
|
||||
.send_turn_start_request(TurnStartParams {
|
||||
thread_id: thread.id.clone(),
|
||||
input: vec![V2UserInput::Text {
|
||||
text: "run python".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
cwd: Some(workspace.clone()),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(turn_id)),
|
||||
)
|
||||
.await??;
|
||||
|
||||
let server_req = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_request_message(),
|
||||
)
|
||||
.await??;
|
||||
let ServerRequest::CommandExecutionRequestApproval { request_id, params } = server_req else {
|
||||
panic!("expected CommandExecutionRequestApproval request");
|
||||
};
|
||||
assert_eq!(params.item_id, "call-zsh-fork-decline");
|
||||
assert_eq!(params.thread_id, thread.id);
|
||||
|
||||
mcp.send_response(
|
||||
request_id,
|
||||
serde_json::to_value(CommandExecutionRequestApprovalResponse {
|
||||
decision: CommandExecutionApprovalDecision::Decline,
|
||||
})?,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let completed_command_execution = timeout(DEFAULT_READ_TIMEOUT, async {
|
||||
loop {
|
||||
let completed_notif = mcp
|
||||
.read_stream_until_notification_message("item/completed")
|
||||
.await?;
|
||||
let completed: ItemCompletedNotification = serde_json::from_value(
|
||||
completed_notif
|
||||
.params
|
||||
.clone()
|
||||
.expect("item/completed params"),
|
||||
)?;
|
||||
if let ThreadItem::CommandExecution { .. } = completed.item {
|
||||
return Ok::<ThreadItem, anyhow::Error>(completed.item);
|
||||
}
|
||||
}
|
||||
})
|
||||
.await??;
|
||||
let ThreadItem::CommandExecution {
|
||||
id,
|
||||
status,
|
||||
exit_code,
|
||||
aggregated_output,
|
||||
..
|
||||
} = completed_command_execution
|
||||
else {
|
||||
unreachable!("loop ensures we break on command execution items");
|
||||
};
|
||||
assert_eq!(id, "call-zsh-fork-decline");
|
||||
assert_eq!(status, CommandExecutionStatus::Declined);
|
||||
assert!(exit_code.is_none());
|
||||
assert!(aggregated_output.is_none());
|
||||
|
||||
timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_notification_message("codex/event/task_complete"),
|
||||
)
|
||||
.await??;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_start_shell_zsh_fork_exec_approval_cancel_v2() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let tmp = TempDir::new()?;
|
||||
let codex_home = tmp.path().join("codex_home");
|
||||
std::fs::create_dir(&codex_home)?;
|
||||
let workspace = tmp.path().join("workspace");
|
||||
std::fs::create_dir(&workspace)?;
|
||||
|
||||
let Some(zsh_path) = find_test_zsh_path() else {
|
||||
eprintln!("skipping zsh fork cancel test: no zsh executable found");
|
||||
return Ok(());
|
||||
};
|
||||
eprintln!("using zsh path for zsh-fork test: {}", zsh_path.display());
|
||||
|
||||
let responses = vec![create_shell_command_sse_response(
|
||||
vec![
|
||||
"python3".to_string(),
|
||||
"-c".to_string(),
|
||||
"print(42)".to_string(),
|
||||
],
|
||||
None,
|
||||
Some(5000),
|
||||
"call-zsh-fork-cancel",
|
||||
)?];
|
||||
let server = create_mock_responses_server_sequence(responses).await;
|
||||
create_config_toml(
|
||||
&codex_home,
|
||||
&server.uri(),
|
||||
"untrusted",
|
||||
&BTreeMap::from([
|
||||
(Feature::ShellZshFork, true),
|
||||
(Feature::UnifiedExec, false),
|
||||
(Feature::ShellSnapshot, false),
|
||||
]),
|
||||
&zsh_path,
|
||||
)?;
|
||||
|
||||
let mut mcp = McpProcess::new(&codex_home).await?;
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let start_id = mcp
|
||||
.send_thread_start_request(ThreadStartParams {
|
||||
model: Some("mock-model".to_string()),
|
||||
cwd: Some(workspace.to_string_lossy().into_owned()),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let start_resp: JSONRPCResponse = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(start_id)),
|
||||
)
|
||||
.await??;
|
||||
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(start_resp)?;
|
||||
|
||||
let turn_id = mcp
|
||||
.send_turn_start_request(TurnStartParams {
|
||||
thread_id: thread.id.clone(),
|
||||
input: vec![V2UserInput::Text {
|
||||
text: "run python".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
cwd: Some(workspace.clone()),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(turn_id)),
|
||||
)
|
||||
.await??;
|
||||
|
||||
let server_req = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_request_message(),
|
||||
)
|
||||
.await??;
|
||||
let ServerRequest::CommandExecutionRequestApproval { request_id, params } = server_req else {
|
||||
panic!("expected CommandExecutionRequestApproval request");
|
||||
};
|
||||
assert_eq!(params.item_id, "call-zsh-fork-cancel");
|
||||
assert_eq!(params.thread_id, thread.id.clone());
|
||||
|
||||
mcp.send_response(
|
||||
request_id,
|
||||
serde_json::to_value(CommandExecutionRequestApprovalResponse {
|
||||
decision: CommandExecutionApprovalDecision::Cancel,
|
||||
})?,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let completed_command_execution = timeout(DEFAULT_READ_TIMEOUT, async {
|
||||
loop {
|
||||
let completed_notif = mcp
|
||||
.read_stream_until_notification_message("item/completed")
|
||||
.await?;
|
||||
let completed: ItemCompletedNotification = serde_json::from_value(
|
||||
completed_notif
|
||||
.params
|
||||
.clone()
|
||||
.expect("item/completed params"),
|
||||
)?;
|
||||
if let ThreadItem::CommandExecution { .. } = completed.item {
|
||||
return Ok::<ThreadItem, anyhow::Error>(completed.item);
|
||||
}
|
||||
}
|
||||
})
|
||||
.await??;
|
||||
let ThreadItem::CommandExecution { id, status, .. } = completed_command_execution else {
|
||||
unreachable!("loop ensures we break on command execution items");
|
||||
};
|
||||
assert_eq!(id, "call-zsh-fork-cancel");
|
||||
assert_eq!(status, CommandExecutionStatus::Declined);
|
||||
|
||||
let completed_notif = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_notification_message("turn/completed"),
|
||||
)
|
||||
.await??;
|
||||
let completed: TurnCompletedNotification = serde_json::from_value(
|
||||
completed_notif
|
||||
.params
|
||||
.expect("turn/completed params must be present"),
|
||||
)?;
|
||||
assert_eq!(completed.thread_id, thread.id);
|
||||
assert_eq!(completed.turn.status, TurnStatus::Interrupted);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn turn_start_shell_zsh_fork_subcommand_decline_marks_parent_declined_v2() -> Result<()> {
|
||||
skip_if_no_network!(Ok(()));
|
||||
|
||||
let tmp = TempDir::new()?;
|
||||
let codex_home = tmp.path().join("codex_home");
|
||||
std::fs::create_dir(&codex_home)?;
|
||||
let workspace = tmp.path().join("workspace");
|
||||
std::fs::create_dir(&workspace)?;
|
||||
|
||||
let Some(zsh_path) = find_test_zsh_path() else {
|
||||
eprintln!("skipping zsh fork subcommand decline test: no zsh executable found");
|
||||
return Ok(());
|
||||
};
|
||||
if !supports_exec_wrapper_intercept(&zsh_path) {
|
||||
eprintln!(
|
||||
"skipping zsh fork subcommand decline test: zsh does not support EXEC_WRAPPER intercepts ({})",
|
||||
zsh_path.display()
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
eprintln!("using zsh path for zsh-fork test: {}", zsh_path.display());
|
||||
|
||||
let tool_call_arguments = serde_json::to_string(&serde_json::json!({
|
||||
"command": "/usr/bin/true && /usr/bin/true",
|
||||
"workdir": serde_json::Value::Null,
|
||||
"timeout_ms": 5000
|
||||
}))?;
|
||||
let response = responses::sse(vec![
|
||||
responses::ev_response_created("resp-1"),
|
||||
responses::ev_function_call(
|
||||
"call-zsh-fork-subcommand-decline",
|
||||
"shell_command",
|
||||
&tool_call_arguments,
|
||||
),
|
||||
responses::ev_completed("resp-1"),
|
||||
]);
|
||||
let server = create_mock_responses_server_sequence(vec![response]).await;
|
||||
create_config_toml(
|
||||
&codex_home,
|
||||
&server.uri(),
|
||||
"on-request",
|
||||
&BTreeMap::from([
|
||||
(Feature::ShellZshFork, true),
|
||||
(Feature::UnifiedExec, false),
|
||||
(Feature::ShellSnapshot, false),
|
||||
]),
|
||||
&zsh_path,
|
||||
)?;
|
||||
|
||||
let mut mcp = McpProcess::new(&codex_home).await?;
|
||||
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
|
||||
|
||||
let start_id = mcp
|
||||
.send_thread_start_request(ThreadStartParams {
|
||||
model: Some("mock-model".to_string()),
|
||||
cwd: Some(workspace.to_string_lossy().into_owned()),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
let start_resp: JSONRPCResponse = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(start_id)),
|
||||
)
|
||||
.await??;
|
||||
let ThreadStartResponse { thread, .. } = to_response::<ThreadStartResponse>(start_resp)?;
|
||||
|
||||
let turn_id = mcp
|
||||
.send_turn_start_request(TurnStartParams {
|
||||
thread_id: thread.id.clone(),
|
||||
input: vec![V2UserInput::Text {
|
||||
text: "run true true".to_string(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
cwd: Some(workspace.clone()),
|
||||
approval_policy: Some(codex_app_server_protocol::AskForApproval::OnRequest),
|
||||
sandbox_policy: Some(codex_app_server_protocol::SandboxPolicy::ReadOnly {
|
||||
access: codex_app_server_protocol::ReadOnlyAccess::FullAccess,
|
||||
}),
|
||||
model: Some("mock-model".to_string()),
|
||||
effort: Some(codex_protocol::openai_models::ReasoningEffort::Medium),
|
||||
summary: Some(codex_core::protocol_config_types::ReasoningSummary::Auto),
|
||||
..Default::default()
|
||||
})
|
||||
.await?;
|
||||
timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_response_message(RequestId::Integer(turn_id)),
|
||||
)
|
||||
.await??;
|
||||
|
||||
let mut approval_ids = Vec::new();
|
||||
for decision in [
|
||||
CommandExecutionApprovalDecision::Accept,
|
||||
CommandExecutionApprovalDecision::Cancel,
|
||||
] {
|
||||
let server_req = timeout(
|
||||
DEFAULT_READ_TIMEOUT,
|
||||
mcp.read_stream_until_request_message(),
|
||||
)
|
||||
.await??;
|
||||
let ServerRequest::CommandExecutionRequestApproval { request_id, params } = server_req
|
||||
else {
|
||||
panic!("expected CommandExecutionRequestApproval request");
|
||||
};
|
||||
assert_eq!(params.item_id, "call-zsh-fork-subcommand-decline");
|
||||
approval_ids.push(
|
||||
params
|
||||
.approval_id
|
||||
.clone()
|
||||
.expect("approval_id must be present for zsh subcommand approvals"),
|
||||
);
|
||||
assert_eq!(params.thread_id, thread.id);
|
||||
mcp.send_response(
|
||||
request_id,
|
||||
serde_json::to_value(CommandExecutionRequestApprovalResponse { decision })?,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let parent_completed_command_execution = timeout(DEFAULT_READ_TIMEOUT, async {
|
||||
loop {
|
||||
let completed_notif = mcp
|
||||
.read_stream_until_notification_message("item/completed")
|
||||
.await?;
|
||||
let completed: ItemCompletedNotification = serde_json::from_value(
|
||||
completed_notif
|
||||
.params
|
||||
.clone()
|
||||
.expect("item/completed params"),
|
||||
)?;
|
||||
if let ThreadItem::CommandExecution { id, .. } = &completed.item
|
||||
&& id == "call-zsh-fork-subcommand-decline"
|
||||
{
|
||||
return Ok::<ThreadItem, anyhow::Error>(completed.item);
|
||||
}
|
||||
}
|
||||
})
|
||||
.await??;
|
||||
|
||||
let ThreadItem::CommandExecution {
|
||||
id,
|
||||
status,
|
||||
aggregated_output,
|
||||
..
|
||||
} = parent_completed_command_execution
|
||||
else {
|
||||
unreachable!("loop ensures we break on parent command execution item");
|
||||
};
|
||||
assert_eq!(id, "call-zsh-fork-subcommand-decline");
|
||||
assert_eq!(status, CommandExecutionStatus::Declined);
|
||||
assert!(
|
||||
aggregated_output.is_none()
|
||||
|| aggregated_output == Some("exec command rejected by user".to_string())
|
||||
);
|
||||
assert_eq!(approval_ids.len(), 2);
|
||||
assert_ne!(approval_ids[0], approval_ids[1]);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn create_config_toml(
|
||||
codex_home: &Path,
|
||||
server_uri: &str,
|
||||
approval_policy: &str,
|
||||
feature_flags: &BTreeMap<Feature, bool>,
|
||||
zsh_path: &Path,
|
||||
) -> std::io::Result<()> {
|
||||
let mut features = BTreeMap::from([(Feature::RemoteModels, false)]);
|
||||
for (feature, enabled) in feature_flags {
|
||||
features.insert(*feature, *enabled);
|
||||
}
|
||||
let feature_entries = features
|
||||
.into_iter()
|
||||
.map(|(feature, enabled)| {
|
||||
let key = FEATURES
|
||||
.iter()
|
||||
.find(|spec| spec.id == feature)
|
||||
.map(|spec| spec.key)
|
||||
.unwrap_or_else(|| panic!("missing feature key for {feature:?}"));
|
||||
format!("{key} = {enabled}")
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
let config_toml = codex_home.join("config.toml");
|
||||
std::fs::write(
|
||||
config_toml,
|
||||
format!(
|
||||
r#"
|
||||
model = "mock-model"
|
||||
approval_policy = "{approval_policy}"
|
||||
sandbox_mode = "read-only"
|
||||
zsh_path = "{zsh_path}"
|
||||
|
||||
model_provider = "mock_provider"
|
||||
|
||||
[features]
|
||||
{feature_entries}
|
||||
|
||||
[model_providers.mock_provider]
|
||||
name = "Mock provider for test"
|
||||
base_url = "{server_uri}/v1"
|
||||
wire_api = "responses"
|
||||
request_max_retries = 0
|
||||
stream_max_retries = 0
|
||||
"#,
|
||||
approval_policy = approval_policy,
|
||||
zsh_path = zsh_path.display()
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn find_test_zsh_path() -> Option<std::path::PathBuf> {
|
||||
if let Some(path) = std::env::var_os("CODEX_TEST_ZSH_PATH") {
|
||||
let path = std::path::PathBuf::from(path);
|
||||
if path.is_file() {
|
||||
return Some(path);
|
||||
}
|
||||
panic!(
|
||||
"CODEX_TEST_ZSH_PATH is set but is not a file: {}",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
|
||||
for candidate in ["/bin/zsh", "/usr/bin/zsh"] {
|
||||
let path = Path::new(candidate);
|
||||
if path.is_file() {
|
||||
return Some(path.to_path_buf());
|
||||
}
|
||||
}
|
||||
|
||||
let shell = std::env::var_os("SHELL")?;
|
||||
let shell_path = std::path::PathBuf::from(shell);
|
||||
if shell_path
|
||||
.file_name()
|
||||
.is_some_and(|file_name| file_name == "zsh")
|
||||
&& shell_path.is_file()
|
||||
{
|
||||
return Some(shell_path);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn supports_exec_wrapper_intercept(zsh_path: &Path) -> bool {
|
||||
let status = std::process::Command::new(zsh_path)
|
||||
.arg("-fc")
|
||||
.arg("/usr/bin/true")
|
||||
.env("EXEC_WRAPPER", "/usr/bin/false")
|
||||
.status();
|
||||
match status {
|
||||
Ok(status) => !status.success(),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
@@ -152,7 +152,7 @@ enum ParseMode {
|
||||
}
|
||||
|
||||
fn parse_patch_text(patch: &str, mode: ParseMode) -> Result<ApplyPatchArgs, ParseError> {
|
||||
let lines: Vec<&str> = patch.trim().lines().collect();
|
||||
let lines: Vec<&str> = patch.trim().split('\n').collect();
|
||||
let lines: &[&str] = match check_patch_boundaries_strict(&lines) {
|
||||
Ok(()) => &lines,
|
||||
Err(e) => match mode {
|
||||
@@ -206,7 +206,9 @@ fn check_patch_boundaries_lenient<'a>(
|
||||
) -> Result<&'a [&'a str], ParseError> {
|
||||
match original_lines {
|
||||
[first, .., last] => {
|
||||
if (first == &"<<EOF" || first == &"<<'EOF'" || first == &"<<\"EOF\"")
|
||||
let first = first.trim();
|
||||
let last = last.trim();
|
||||
if (first == "<<EOF" || first == "<<'EOF'" || first == "<<\"EOF\"")
|
||||
&& last.ends_with("EOF")
|
||||
&& original_lines.len() >= 4
|
||||
{
|
||||
@@ -282,9 +284,11 @@ fn parse_one_hunk(lines: &[&str], line_number: usize) -> Result<(Hunk, usize), P
|
||||
let mut parsed_lines = 1;
|
||||
|
||||
// Optional: move file line
|
||||
let move_path = remaining_lines
|
||||
.first()
|
||||
.and_then(|x| x.strip_prefix(MOVE_TO_MARKER));
|
||||
let move_path = remaining_lines.first().and_then(|x| {
|
||||
x.strip_suffix('\r')
|
||||
.unwrap_or(x)
|
||||
.strip_prefix(MOVE_TO_MARKER)
|
||||
});
|
||||
|
||||
if move_path.is_some() {
|
||||
remaining_lines = &remaining_lines[1..];
|
||||
@@ -353,9 +357,10 @@ fn parse_update_file_chunk(
|
||||
}
|
||||
// If we see an explicit context marker @@ or @@ <context>, consume it; otherwise, optionally
|
||||
// allow treating the chunk as starting directly with diff lines.
|
||||
let (change_context, start_index) = if lines[0] == EMPTY_CHANGE_CONTEXT_MARKER {
|
||||
let first_line = lines[0].strip_suffix('\r').unwrap_or(lines[0]);
|
||||
let (change_context, start_index) = if first_line == EMPTY_CHANGE_CONTEXT_MARKER {
|
||||
(None, 1)
|
||||
} else if let Some(context) = lines[0].strip_prefix(CHANGE_CONTEXT_MARKER) {
|
||||
} else if let Some(context) = first_line.strip_prefix(CHANGE_CONTEXT_MARKER) {
|
||||
(Some(context.to_string()), 1)
|
||||
} else {
|
||||
if !allow_missing_context {
|
||||
@@ -383,7 +388,8 @@ fn parse_update_file_chunk(
|
||||
};
|
||||
let mut parsed_lines = 0;
|
||||
for line in &lines[start_index..] {
|
||||
match *line {
|
||||
let line_contents = line.strip_suffix('\r').unwrap_or(line);
|
||||
match line_contents {
|
||||
EOF_MARKER => {
|
||||
if parsed_lines == 0 {
|
||||
return Err(InvalidHunkError {
|
||||
@@ -395,7 +401,7 @@ fn parse_update_file_chunk(
|
||||
parsed_lines += 1;
|
||||
break;
|
||||
}
|
||||
line_contents => {
|
||||
_ => {
|
||||
match line_contents.chars().next() {
|
||||
None => {
|
||||
// Interpret this as an empty line.
|
||||
@@ -403,14 +409,14 @@ fn parse_update_file_chunk(
|
||||
chunk.new_lines.push(String::new());
|
||||
}
|
||||
Some(' ') => {
|
||||
chunk.old_lines.push(line_contents[1..].to_string());
|
||||
chunk.new_lines.push(line_contents[1..].to_string());
|
||||
chunk.old_lines.push(line[1..].to_string());
|
||||
chunk.new_lines.push(line[1..].to_string());
|
||||
}
|
||||
Some('+') => {
|
||||
chunk.new_lines.push(line_contents[1..].to_string());
|
||||
chunk.new_lines.push(line[1..].to_string());
|
||||
}
|
||||
Some('-') => {
|
||||
chunk.old_lines.push(line_contents[1..].to_string());
|
||||
chunk.old_lines.push(line[1..].to_string());
|
||||
}
|
||||
_ => {
|
||||
if parsed_lines == 0 {
|
||||
@@ -669,6 +675,28 @@ fn test_parse_patch_lenient() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_patch_preserves_crlf() {
|
||||
let patch_text = "*** Begin Patch\r\n*** Update File: sample.txt\r\n@@\r\n-one\r\n+uno\r\n two\r\n*** End Patch\r\n";
|
||||
assert_eq!(
|
||||
parse_patch_text(patch_text, ParseMode::Strict),
|
||||
Ok(ApplyPatchArgs {
|
||||
hunks: vec![UpdateFile {
|
||||
path: PathBuf::from("sample.txt"),
|
||||
move_path: None,
|
||||
chunks: vec![UpdateFileChunk {
|
||||
change_context: None,
|
||||
old_lines: vec!["one\r".to_string(), "two\r".to_string()],
|
||||
new_lines: vec!["uno\r".to_string(), "two\r".to_string()],
|
||||
is_end_of_file: false,
|
||||
}],
|
||||
}],
|
||||
patch: patch_text.trim().to_string(),
|
||||
workdir: None,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_one_hunk() {
|
||||
assert_eq!(
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
* -text
|
||||
@@ -0,0 +1,2 @@
|
||||
uno
|
||||
two
|
||||
@@ -0,0 +1,2 @@
|
||||
one
|
||||
two
|
||||
7
codex-rs/apply-patch/tests/fixtures/scenarios/023_preserves_crlf_for_update_hunks/patch.txt
vendored
Normal file
7
codex-rs/apply-patch/tests/fixtures/scenarios/023_preserves_crlf_for_update_hunks/patch.txt
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
*** Begin Patch
|
||||
*** Update File: sample.txt
|
||||
@@
|
||||
-one
|
||||
+uno
|
||||
two
|
||||
*** End Patch
|
||||
@@ -0,0 +1 @@
|
||||
* -text
|
||||
@@ -0,0 +1,2 @@
|
||||
hello
|
||||
world
|
||||
@@ -0,0 +1,5 @@
|
||||
*** Begin Patch
|
||||
*** Add File: created.txt
|
||||
+hello
|
||||
+world
|
||||
*** End Patch
|
||||
@@ -0,0 +1 @@
|
||||
* -text
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user