mirror of
https://github.com/openai/codex.git
synced 2026-06-03 03:41:58 +00:00
Compare commits
3 Commits
dev/adrian
...
btraut/fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
908d721305 | ||
|
|
c8d8c0e622 | ||
|
|
8e85a35ec6 |
46
.bazelrc
46
.bazelrc
@@ -38,50 +38,24 @@ common:windows --test_env=WINDIR
|
||||
common --test_env=RUST_MIN_STACK=8388608 # 8 MiB
|
||||
|
||||
common --test_output=errors
|
||||
common --nobuild_runfile_links
|
||||
# These settings tune BuildBuddy/RBE behavior but do not contact a remote
|
||||
# service unless a `buildbuddy-*` configuration below supplies an endpoint.
|
||||
common --bes_results_url=https://app.buildbuddy.io/invocation/
|
||||
common --bes_backend=grpcs://remote.buildbuddy.io
|
||||
common --remote_cache=grpcs://remote.buildbuddy.io
|
||||
common --remote_download_toplevel
|
||||
common --nobuild_runfile_links
|
||||
common --remote_timeout=3600
|
||||
common --noexperimental_throttle_remote_action_building
|
||||
common --experimental_remote_execution_keepalive
|
||||
common --grpc_keepalive_time=30s
|
||||
|
||||
# Opt-in remote configurations selected by
|
||||
# `.github/scripts/run_bazel_with_buildbuddy.py`. Plain Bazel commands do not
|
||||
# contact BuildBuddy unless a user selects one of these configurations.
|
||||
# Use the generic host for cache, BES, and downloads without remote execution.
|
||||
common:buildbuddy-generic --bes_backend=grpcs://remote.buildbuddy.io
|
||||
common:buildbuddy-generic --bes_results_url=https://app.buildbuddy.io/invocation/
|
||||
common:buildbuddy-generic --remote_cache=grpcs://remote.buildbuddy.io
|
||||
common:buildbuddy-generic --experimental_remote_downloader=grpcs://remote.buildbuddy.io
|
||||
|
||||
# Add remote execution on the generic host.
|
||||
common:buildbuddy-generic-rbe --config=buildbuddy-generic
|
||||
common:buildbuddy-generic-rbe --config=remote
|
||||
common:buildbuddy-generic-rbe --remote_executor=grpcs://remote.buildbuddy.io
|
||||
|
||||
# Use the OpenAI tenant for cache, BES, and downloads without remote execution.
|
||||
common:buildbuddy-openai --bes_backend=grpcs://openai.buildbuddy.io
|
||||
common:buildbuddy-openai --bes_results_url=https://openai.buildbuddy.io/invocation/
|
||||
common:buildbuddy-openai --remote_cache=grpcs://openai.buildbuddy.io
|
||||
common:buildbuddy-openai --experimental_remote_downloader=grpcs://openai.buildbuddy.io
|
||||
|
||||
# Add remote execution on the OpenAI tenant.
|
||||
common:buildbuddy-openai-rbe --config=buildbuddy-openai
|
||||
common:buildbuddy-openai-rbe --config=remote
|
||||
common:buildbuddy-openai-rbe --remote_executor=grpcs://openai.buildbuddy.io
|
||||
common --experimental_remote_downloader=grpcs://remote.buildbuddy.io
|
||||
|
||||
# This limits both in-flight executions and concurrent downloads. Even with high number
|
||||
# of jobs execution will still be limited by CPU cores, so this just pays a bit of
|
||||
# memory in exchange for higher download concurrency.
|
||||
common --jobs=30
|
||||
|
||||
# Shared remote execution policy. The endpoint-bearing `buildbuddy-*-rbe`
|
||||
# configurations include this group; CI configs override TestRunner below
|
||||
# when tests must remain local on their runner.
|
||||
common:remote --strategy=remote
|
||||
common:remote --extra_execution_platforms=//:rbe
|
||||
common:remote --remote_executor=grpcs://remote.buildbuddy.io
|
||||
common:remote --jobs=800
|
||||
# TODO(team): Evaluate if this actually helps, zbarsky is not sure, everything seems bottlenecked on `core` either way.
|
||||
# Enable pipelined compilation since we are not bound by local CPU count.
|
||||
@@ -172,11 +146,15 @@ common:ci-windows --repo_contents_cache=D:/a/.cache/bazel-repo-contents-cache
|
||||
# Linux crossbuilds don't work until we untangle the libc constraint mess.
|
||||
common:ci-linux --config=ci-bazel
|
||||
common:ci-linux --build_metadata=TAG_os=linux
|
||||
common:ci-linux --config=remote
|
||||
common:ci-linux --strategy=remote
|
||||
common:ci-linux --platforms=//:rbe
|
||||
|
||||
# On mac, we can run all the build actions remotely but test actions locally.
|
||||
common:ci-macos --config=ci-bazel
|
||||
common:ci-macos --build_metadata=TAG_os=macos
|
||||
common:ci-macos --config=remote
|
||||
common:ci-macos --strategy=remote
|
||||
common:ci-macos --strategy=TestRunner=darwin-sandbox,local
|
||||
|
||||
# On Windows, use Linux remote execution for build actions but keep test actions
|
||||
@@ -184,7 +162,9 @@ common:ci-macos --strategy=TestRunner=darwin-sandbox,local
|
||||
# still run against Windows binaries.
|
||||
common:ci-windows-cross --config=ci-windows
|
||||
common:ci-windows-cross --build_metadata=TAG_windows_cross_compile=true
|
||||
common:ci-windows-cross --config=remote
|
||||
common:ci-windows-cross --host_platform=//:rbe
|
||||
common:ci-windows-cross --strategy=remote
|
||||
common:ci-windows-cross --strategy=TestRunner=local
|
||||
common:ci-windows-cross --local_test_jobs=4
|
||||
common:ci-windows-cross --test_env=RUST_TEST_THREADS=1
|
||||
@@ -200,6 +180,8 @@ common:ci-windows-cross --extra_toolchains=//:windows_gnullvm_tests_on_msvc_host
|
||||
common:ci-v8 --config=ci
|
||||
common:ci-v8 --build_metadata=TAG_workflow=v8
|
||||
common:ci-v8 --build_metadata=TAG_os=linux
|
||||
common:ci-v8 --config=remote
|
||||
common:ci-v8 --strategy=remote
|
||||
|
||||
# Source-built Bazel V8 artifacts use the in-process sandbox by default. This
|
||||
# does not affect Cargo's default prebuilt rusty_v8 path.
|
||||
|
||||
@@ -8,4 +8,4 @@ script = ""
|
||||
[[actions]]
|
||||
name = "Run"
|
||||
icon = "run"
|
||||
command = "cargo +1.95.0 run --manifest-path=codex-rs/Cargo.toml --bin codex -- -c mcp_oauth_credentials_store=file"
|
||||
command = "cargo +1.93.0 run --manifest-path=codex-rs/Cargo.toml --bin codex -- -c mcp_oauth_credentials_store=file"
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04
|
||||
ARG TZ
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG NODE_MAJOR=22
|
||||
ARG RUST_TOOLCHAIN=1.95.0
|
||||
ARG RUST_TOOLCHAIN=1.92.0
|
||||
# Keep this in sync with .devcontainer/codex-install/package.json and pnpm-lock.yaml.
|
||||
ARG CODEX_NPM_VERSION=0.121.0
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"args": {
|
||||
"TZ": "${localEnv:TZ:UTC}",
|
||||
"NODE_MAJOR": "22",
|
||||
"RUST_TOOLCHAIN": "1.95.0",
|
||||
"RUST_TOOLCHAIN": "1.92.0",
|
||||
"CODEX_NPM_VERSION": "0.121.0"
|
||||
}
|
||||
},
|
||||
|
||||
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@@ -1,7 +1,6 @@
|
||||
# Core crate ownership.
|
||||
/codex-rs/core/ @openai/codex-core-agent-team
|
||||
/codex-rs/ext/extension-api/ @openai/codex-core-agent-team
|
||||
/codex-rs/prompts/ @openai/codex-core-agent-team
|
||||
|
||||
# Keep ownership changes reviewed by the same team.
|
||||
/.github/CODEOWNERS @openai/codex-core-agent-team
|
||||
|
||||
13
.github/scripts/install-musl-build-tools.sh
vendored
13
.github/scripts/install-musl-build-tools.sh
vendored
@@ -150,9 +150,7 @@ for arg in "\$@"; do
|
||||
args+=("\${arg}")
|
||||
done
|
||||
|
||||
# Zig enables UBSan for debug C builds by default. Rust links these objects
|
||||
# without Zig's sanitizer runtime, so keep native dependencies uninstrumented.
|
||||
exec "${zig_bin}" cc -target "${zig_target}" "\${args[@]}" -fno-sanitize=undefined
|
||||
exec "${zig_bin}" cc -target "${zig_target}" "\${args[@]}"
|
||||
EOF
|
||||
cat >"${cxx}" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
@@ -209,9 +207,7 @@ for arg in "\$@"; do
|
||||
args+=("\${arg}")
|
||||
done
|
||||
|
||||
# Zig enables UBSan for debug C++ builds by default. Rust links these objects
|
||||
# without Zig's sanitizer runtime, so keep native dependencies uninstrumented.
|
||||
exec "${zig_bin}" c++ -target "${zig_target}" "\${args[@]}" -fno-sanitize=undefined
|
||||
exec "${zig_bin}" c++ -target "${zig_target}" "\${args[@]}"
|
||||
EOF
|
||||
chmod +x "${cc}" "${cxx}"
|
||||
|
||||
@@ -274,11 +270,6 @@ echo "PKG_CONFIG_PATH=${pkg_config_path}" >> "$GITHUB_ENV"
|
||||
pkg_config_path_var="PKG_CONFIG_PATH_${TARGET}"
|
||||
pkg_config_path_var="${pkg_config_path_var//-/_}"
|
||||
echo "${pkg_config_path_var}=${libcap_pkgconfig_dir}" >> "$GITHUB_ENV"
|
||||
pkg_config_libdir_var="PKG_CONFIG_LIBDIR_${TARGET}"
|
||||
pkg_config_libdir_var="${pkg_config_libdir_var//-/_}"
|
||||
# Do not let musl cross-builds resolve native libraries from the host glibc
|
||||
# pkg-config directories. libcap is the only target package provided here.
|
||||
echo "${pkg_config_libdir_var}=${libcap_pkgconfig_dir}" >> "$GITHUB_ENV"
|
||||
|
||||
if [[ -n "${sysroot}" && "${sysroot}" != "/" ]]; then
|
||||
echo "PKG_CONFIG_SYSROOT_DIR=${sysroot}" >> "$GITHUB_ENV"
|
||||
|
||||
126
.github/scripts/run-bazel-ci.sh
vendored
126
.github/scripts/run-bazel-ci.sh
vendored
@@ -53,20 +53,11 @@ fi
|
||||
|
||||
run_bazel() {
|
||||
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
|
||||
MSYS2_ARG_CONV_EXCL='*' "$(dirname "${BASH_SOURCE[0]}")/run_bazel_with_buildbuddy.py" "$@"
|
||||
MSYS2_ARG_CONV_EXCL='*' bazel "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
"$(dirname "${BASH_SOURCE[0]}")/run_bazel_with_buildbuddy.py" "$@"
|
||||
}
|
||||
|
||||
run_bazel_with_startup_args() {
|
||||
if (( ${#bazel_startup_args[@]} > 0 )); then
|
||||
run_bazel "${bazel_startup_args[@]}" "$@"
|
||||
return
|
||||
fi
|
||||
|
||||
run_bazel "$@"
|
||||
bazel "$@"
|
||||
}
|
||||
|
||||
ci_config=ci-linux
|
||||
@@ -86,16 +77,23 @@ esac
|
||||
print_bazel_test_log_tails() {
|
||||
local console_log="$1"
|
||||
local testlogs_dir
|
||||
|
||||
local -a bazel_info_cmd=(bazel)
|
||||
local -a bazel_info_args=(info)
|
||||
if [[ -n "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
# `bazel info` needs the same CI config as the failed test invocation so
|
||||
# platform-specific output roots match. On Windows, omitting `ci-windows`
|
||||
# would point at `local_windows-fastbuild` even when the test ran with the
|
||||
# MSVC host platform under `local_windows_msvc-fastbuild`.
|
||||
bazel_info_args+=("--config=${ci_config}")
|
||||
|
||||
if (( ${#bazel_startup_args[@]} > 0 )); then
|
||||
bazel_info_cmd+=("${bazel_startup_args[@]}")
|
||||
fi
|
||||
|
||||
# `bazel info` needs the same CI config as the failed test invocation so
|
||||
# platform-specific output roots match. On Windows, omitting `ci-windows`
|
||||
# would point at `local_windows-fastbuild` even when the test ran with the
|
||||
# MSVC host platform under `local_windows_msvc-fastbuild`.
|
||||
if [[ -n "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
bazel_info_args+=(
|
||||
"--config=${ci_config}"
|
||||
"--remote_header=x-buildbuddy-api-key=${BUILDBUDDY_API_KEY}"
|
||||
)
|
||||
fi
|
||||
# Only pass flags that affect Bazel's output-root selection or repository
|
||||
# lookup. Test/build-only flags such as execution logs or remote download
|
||||
# mode can make `bazel info` fail, which would hide the real test log path.
|
||||
@@ -107,7 +105,7 @@ print_bazel_test_log_tails() {
|
||||
esac
|
||||
done
|
||||
|
||||
testlogs_dir="$(run_bazel_with_startup_args \
|
||||
testlogs_dir="$(run_bazel "${bazel_info_cmd[@]:1}" \
|
||||
--noexperimental_remote_repo_contents_cache \
|
||||
"${bazel_info_args[@]}" \
|
||||
bazel-testlogs 2>/dev/null || echo bazel-testlogs)"
|
||||
@@ -256,9 +254,8 @@ if [[ ${#bazel_args[@]} -eq 0 || ${#bazel_targets[@]} -eq 0 ]]; then
|
||||
fi
|
||||
|
||||
if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 && -z "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
# Windows cross-compilation depends on authenticated RBE. Preserve the local
|
||||
# Windows build shape when credentials are unavailable.
|
||||
ci_config=ci-windows
|
||||
# Fork PRs do not receive the BuildBuddy secret needed for the remote
|
||||
# cross-compile config. Preserve the previous local Windows build shape.
|
||||
windows_msvc_host_platform=1
|
||||
fi
|
||||
|
||||
@@ -300,9 +297,9 @@ if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 && -n "${BUI
|
||||
fi
|
||||
|
||||
if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 && -z "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
# The Windows cross-compile config depends on authenticated remote
|
||||
# execution. When credentials are unavailable, keep the local build shape
|
||||
# and its lower concurrency cap.
|
||||
# The Windows cross-compile config depends on remote execution. Fork PRs do
|
||||
# not receive the BuildBuddy secret, so fall back to the existing local build
|
||||
# shape and keep its lower concurrency cap.
|
||||
post_config_bazel_args+=(--jobs=8)
|
||||
fi
|
||||
|
||||
@@ -380,31 +377,70 @@ fi
|
||||
bazel_console_log="$(mktemp)"
|
||||
trap 'rm -f "$bazel_console_log"' EXIT
|
||||
|
||||
bazel_run_args=(
|
||||
"${bazel_args[@]}"
|
||||
)
|
||||
bazel_cmd=(bazel)
|
||||
if (( ${#bazel_startup_args[@]} > 0 )); then
|
||||
bazel_cmd+=("${bazel_startup_args[@]}")
|
||||
fi
|
||||
|
||||
if [[ -n "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
echo "BuildBuddy API key is available; using remote Bazel configuration."
|
||||
bazel_run_args+=("--config=${ci_config}")
|
||||
# Work around Bazel 9 remote repo contents cache / overlay materialization failures
|
||||
# seen in CI (for example "is not a symlink" or permission errors while
|
||||
# materializing external repos such as rules_perl). We still use BuildBuddy for
|
||||
# remote execution/cache; this only disables the startup-level repo contents cache.
|
||||
bazel_run_args=(
|
||||
"${bazel_args[@]}"
|
||||
"--config=${ci_config}"
|
||||
"--remote_header=x-buildbuddy-api-key=${BUILDBUDDY_API_KEY}"
|
||||
)
|
||||
if (( ${#post_config_bazel_args[@]} > 0 )); then
|
||||
bazel_run_args+=("${post_config_bazel_args[@]}")
|
||||
fi
|
||||
set +e
|
||||
run_bazel "${bazel_cmd[@]:1}" \
|
||||
--noexperimental_remote_repo_contents_cache \
|
||||
"${bazel_run_args[@]}" \
|
||||
-- \
|
||||
"${bazel_targets[@]}" \
|
||||
2>&1 | tee "$bazel_console_log"
|
||||
bazel_status=${PIPESTATUS[0]}
|
||||
set -e
|
||||
else
|
||||
echo "BuildBuddy API key is not available; using local Bazel configuration."
|
||||
# Keep fork/community PRs on Bazel but disable remote services that are
|
||||
# configured in .bazelrc and require auth.
|
||||
#
|
||||
# Flag docs:
|
||||
# - Command-line reference: https://bazel.build/reference/command-line-reference
|
||||
# - Remote caching overview: https://bazel.build/remote/caching
|
||||
# - Remote execution overview: https://bazel.build/remote/rbe
|
||||
# - Build Event Protocol overview: https://bazel.build/remote/bep
|
||||
#
|
||||
# --noexperimental_remote_repo_contents_cache:
|
||||
# disable remote repo contents cache enabled in .bazelrc startup options.
|
||||
# https://bazel.build/reference/command-line-reference#startup_options-flag--experimental_remote_repo_contents_cache
|
||||
# --remote_cache= and --remote_executor=:
|
||||
# clear remote cache/execution endpoints configured in .bazelrc.
|
||||
# https://bazel.build/reference/command-line-reference#common_options-flag--remote_cache
|
||||
# https://bazel.build/reference/command-line-reference#common_options-flag--remote_executor
|
||||
bazel_run_args=(
|
||||
"${bazel_args[@]}"
|
||||
--remote_cache=
|
||||
--remote_executor=
|
||||
)
|
||||
if (( ${#post_config_bazel_args[@]} > 0 )); then
|
||||
bazel_run_args+=("${post_config_bazel_args[@]}")
|
||||
fi
|
||||
set +e
|
||||
run_bazel "${bazel_cmd[@]:1}" \
|
||||
--noexperimental_remote_repo_contents_cache \
|
||||
"${bazel_run_args[@]}" \
|
||||
-- \
|
||||
"${bazel_targets[@]}" \
|
||||
2>&1 | tee "$bazel_console_log"
|
||||
bazel_status=${PIPESTATUS[0]}
|
||||
set -e
|
||||
fi
|
||||
if (( ${#post_config_bazel_args[@]} > 0 )); then
|
||||
bazel_run_args+=("${post_config_bazel_args[@]}")
|
||||
fi
|
||||
set +e
|
||||
# Work around Bazel 9 remote repo contents cache / overlay materialization
|
||||
# failures seen in CI (for example "is not a symlink" or permission errors
|
||||
# while materializing external repos such as rules_perl). This only disables
|
||||
# the startup-level repo contents cache; keyed runs still use BuildBuddy.
|
||||
run_bazel_with_startup_args \
|
||||
--noexperimental_remote_repo_contents_cache \
|
||||
"${bazel_run_args[@]}" \
|
||||
-- \
|
||||
"${bazel_targets[@]}" \
|
||||
2>&1 | tee "$bazel_console_log"
|
||||
bazel_status=${PIPESTATUS[0]}
|
||||
set -e
|
||||
|
||||
if [[ ${bazel_status:-0} -ne 0 ]]; then
|
||||
if [[ $print_failed_bazel_action_summary -eq 1 ]]; then
|
||||
|
||||
56
.github/scripts/run-bazel-query-ci.sh
vendored
56
.github/scripts/run-bazel-query-ci.sh
vendored
@@ -2,17 +2,48 @@
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Run target-discovery queries with the same startup settings as the main
|
||||
# build/test invocation so they can reuse the same Bazel server. Queries only
|
||||
# enumerate labels, so they intentionally do not select CI or remote configs.
|
||||
# Run Bazel queries with the same CI startup settings as the main build/test
|
||||
# invocation so target-discovery queries can reuse the same Bazel server.
|
||||
|
||||
if [[ $# -lt 2 || "${@: -2:1}" != "--" ]]; then
|
||||
echo "Usage: $0 [<bazel query args>...] -- <query expression>" >&2
|
||||
query_args=()
|
||||
windows_cross_compile=0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--windows-cross-compile)
|
||||
windows_cross_compile=1
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
query_args+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: $0 [--windows-cross-compile] [<bazel query args>...] -- <query expression>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
query_args=("${@:1:$#-2}")
|
||||
query_expression="${@: -1}"
|
||||
query_expression="$1"
|
||||
|
||||
ci_config=ci-linux
|
||||
case "${RUNNER_OS:-}" in
|
||||
macOS)
|
||||
ci_config=ci-macos
|
||||
;;
|
||||
Windows)
|
||||
if [[ $windows_cross_compile -eq 1 ]]; then
|
||||
ci_config=ci-windows-cross
|
||||
else
|
||||
ci_config=ci-windows
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
bazel_startup_args=()
|
||||
if [[ -n "${BAZEL_OUTPUT_USER_ROOT:-}" ]]; then
|
||||
@@ -29,6 +60,12 @@ run_bazel() {
|
||||
}
|
||||
|
||||
bazel_query_args=(--noexperimental_remote_repo_contents_cache query)
|
||||
if [[ -n "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
bazel_query_args+=(
|
||||
"--config=${ci_config}"
|
||||
"--remote_header=x-buildbuddy-api-key=${BUILDBUDDY_API_KEY}"
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ -n "${BAZEL_REPO_CONTENTS_CACHE:-}" ]]; then
|
||||
bazel_query_args+=("--repo_contents_cache=${BAZEL_REPO_CONTENTS_CACHE}")
|
||||
@@ -38,10 +75,7 @@ if [[ -n "${BAZEL_REPOSITORY_CACHE:-}" ]]; then
|
||||
bazel_query_args+=("--repository_cache=${BAZEL_REPOSITORY_CACHE}")
|
||||
fi
|
||||
|
||||
if (( ${#query_args[@]} > 0 )); then
|
||||
bazel_query_args+=("${query_args[@]}")
|
||||
fi
|
||||
bazel_query_args+=("$query_expression")
|
||||
bazel_query_args+=("${query_args[@]}" "$query_expression")
|
||||
|
||||
if (( ${#bazel_startup_args[@]} > 0 )); then
|
||||
run_bazel "${bazel_startup_args[@]}" "${bazel_query_args[@]}"
|
||||
|
||||
147
.github/scripts/run_bazel_with_buildbuddy.py
vendored
147
.github/scripts/run_bazel_with_buildbuddy.py
vendored
@@ -1,147 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from collections.abc import Mapping
|
||||
from collections.abc import Sequence
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
OPENAI_REPOSITORY = "openai/codex"
|
||||
# Remote configurations select cache/BES/download endpoints. Their -rbe forms
|
||||
# also select the matching remote executor endpoint.
|
||||
GENERIC_REMOTE_CONFIG = "buildbuddy-generic"
|
||||
OPENAI_REMOTE_CONFIG = "buildbuddy-openai"
|
||||
# These CI configurations require remote build execution. The wrapper supplies
|
||||
# an RBE configuration, which also includes the common `remote` settings.
|
||||
REMOTE_EXECUTION_CONFIGS = {
|
||||
"--config=ci-linux",
|
||||
"--config=ci-macos",
|
||||
"--config=ci-v8",
|
||||
"--config=ci-windows-cross",
|
||||
}
|
||||
# Only authenticated workflow runs executing trusted upstream code may use the
|
||||
# OpenAI BuildBuddy host. A pull request event without proof that its head is
|
||||
# in the upstream repository fails closed to the generic host.
|
||||
def is_trusted_upstream_run(env: Mapping[str, str]) -> bool:
|
||||
# `GITHUB_REPOSITORY` is easy to set locally. Requiring GitHub's workflow
|
||||
# marker prevents a local command from opting itself into the OpenAI host.
|
||||
if (
|
||||
env.get("GITHUB_ACTIONS") != "true"
|
||||
or env.get("GITHUB_REPOSITORY") != OPENAI_REPOSITORY
|
||||
):
|
||||
return False
|
||||
# Non-PR workflow runs in `openai/codex` execute upstream refs, so they are
|
||||
# trusted. Fork code reaches these workflows only through pull requests.
|
||||
if env.get("GITHUB_EVENT_NAME") != "pull_request":
|
||||
return True
|
||||
|
||||
event_path = env.get("GITHUB_EVENT_PATH")
|
||||
if not event_path:
|
||||
return False
|
||||
try:
|
||||
event = json.loads(Path(event_path).read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
return False
|
||||
|
||||
try:
|
||||
return event["pull_request"]["head"]["repo"]["fork"] is False
|
||||
except (KeyError, TypeError):
|
||||
return False
|
||||
|
||||
|
||||
def uses_openai_host(env: Mapping[str, str]) -> bool:
|
||||
return bool(env.get("BUILDBUDDY_API_KEY")) and is_trusted_upstream_run(env)
|
||||
|
||||
|
||||
def uses_remote_execution(args: Sequence[str]) -> bool:
|
||||
try:
|
||||
separator_idx = args.index("--")
|
||||
except ValueError:
|
||||
separator_idx = len(args)
|
||||
return any(arg in REMOTE_EXECUTION_CONFIGS for arg in args[:separator_idx])
|
||||
|
||||
|
||||
def remote_config(args: Sequence[str], env: Mapping[str, str]) -> str | None:
|
||||
if not env.get("BUILDBUDDY_API_KEY"):
|
||||
return None
|
||||
|
||||
config = OPENAI_REMOTE_CONFIG if uses_openai_host(env) else GENERIC_REMOTE_CONFIG
|
||||
if uses_remote_execution(args):
|
||||
config += "-rbe"
|
||||
return config
|
||||
|
||||
|
||||
def bazel_args_without_remote_execution(args: Sequence[str]) -> list[str]:
|
||||
# Remote CI configs require BuildBuddy credentials. Removing them preserves
|
||||
# the local fallback used for fork pull requests.
|
||||
try:
|
||||
separator_idx = args.index("--")
|
||||
except ValueError:
|
||||
separator_idx = len(args)
|
||||
return [
|
||||
*(arg for arg in args[:separator_idx] if arg not in REMOTE_EXECUTION_CONFIGS),
|
||||
*args[separator_idx:],
|
||||
]
|
||||
|
||||
|
||||
def bazel_args_with_remote_config(
|
||||
args: Sequence[str], env: Mapping[str, str]
|
||||
) -> list[str]:
|
||||
config = remote_config(args, env)
|
||||
if config is None:
|
||||
return bazel_args_without_remote_execution(args)
|
||||
|
||||
# `remote_config()` returns a configuration only when this key is present.
|
||||
api_key = env["BUILDBUDDY_API_KEY"]
|
||||
remote_args = [
|
||||
f"--config={config}",
|
||||
f"--remote_header=x-buildbuddy-api-key={api_key}",
|
||||
]
|
||||
|
||||
# Insert immediately after the Bazel command. This keeps wrapper-added
|
||||
# options out of positional payloads and lets later CI configs override
|
||||
# shared RBE defaults such as the Windows cross-compilation exec platforms.
|
||||
insertion_idx = next(
|
||||
(idx + 1 for idx, arg in enumerate(args) if not arg.startswith("-")),
|
||||
len(args),
|
||||
)
|
||||
return [*args[:insertion_idx], *remote_args, *args[insertion_idx:]]
|
||||
|
||||
|
||||
def bazel_command(*args: str, env: Mapping[str, str] | None = None) -> list[str]:
|
||||
env = os.environ if env is None else env
|
||||
bazel = env.get("CODEX_BAZEL_BIN", "bazel")
|
||||
return [bazel, *bazel_args_with_remote_config(args, env)]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
config = remote_config(sys.argv[1:], os.environ)
|
||||
if config is None:
|
||||
print(
|
||||
"BuildBuddy key unavailable; using local Bazel configuration.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
else:
|
||||
host_description = (
|
||||
"OpenAI tenant" if uses_openai_host(os.environ) else "generic"
|
||||
)
|
||||
print(
|
||||
f"Using {host_description} BuildBuddy configuration: {config}.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
command = bazel_command(*sys.argv[1:])
|
||||
if os.name == "nt":
|
||||
# Windows CRT exec can split arguments containing spaces and lose the
|
||||
# eventual child exit status. Wait for Bazel and propagate its status.
|
||||
result = subprocess.run(command, check=False)
|
||||
raise SystemExit(result.returncode)
|
||||
|
||||
os.execvp(command[0], command)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
63
.github/scripts/rusty_v8_bazel.py
vendored
63
.github/scripts/rusty_v8_bazel.py
vendored
@@ -5,6 +5,7 @@ from __future__ import annotations
|
||||
import argparse
|
||||
import gzip
|
||||
import hashlib
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
@@ -12,7 +13,6 @@ import sys
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
|
||||
from run_bazel_with_buildbuddy import bazel_command
|
||||
from rusty_v8_module_bazel import (
|
||||
RustyV8ChecksumError,
|
||||
check_module_bazel,
|
||||
@@ -29,22 +29,33 @@ SANDBOX_ARTIFACT_PROFILE = "ptrcomp_sandbox_release"
|
||||
ARTIFACT_BAZEL_CONFIGS = ["rusty-v8-upstream-libcxx"]
|
||||
|
||||
|
||||
def bazel_remote_args() -> list[str]:
|
||||
buildbuddy_api_key = os.environ.get("BUILDBUDDY_API_KEY")
|
||||
if not buildbuddy_api_key:
|
||||
return []
|
||||
return [f"--remote_header=x-buildbuddy-api-key={buildbuddy_api_key}"]
|
||||
|
||||
|
||||
def bazel_execroot() -> Path:
|
||||
output = subprocess.check_output(
|
||||
bazel_command("info", "execution_root"),
|
||||
result = subprocess.run(
|
||||
["bazel", "info", "execution_root"],
|
||||
cwd=ROOT,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
return Path(output.strip())
|
||||
return Path(result.stdout.strip())
|
||||
|
||||
|
||||
def bazel_output_base() -> Path:
|
||||
output = subprocess.check_output(
|
||||
bazel_command("info", "output_base"),
|
||||
result = subprocess.run(
|
||||
["bazel", "info", "output_base"],
|
||||
cwd=ROOT,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
return Path(output.strip())
|
||||
return Path(result.stdout.strip())
|
||||
|
||||
|
||||
def bazel_output_path(path: str) -> Path:
|
||||
@@ -61,22 +72,24 @@ def bazel_output_files(
|
||||
) -> list[Path]:
|
||||
expression = "set(" + " ".join(labels) + ")"
|
||||
bazel_configs = bazel_configs or []
|
||||
output = subprocess.check_output(
|
||||
bazel_command(
|
||||
result = subprocess.run(
|
||||
[
|
||||
"bazel",
|
||||
"cquery",
|
||||
"-c",
|
||||
compilation_mode,
|
||||
f"--platforms=@llvm//platforms:{platform}",
|
||||
*[f"--config={config}" for config in bazel_configs],
|
||||
*bazel_remote_args(),
|
||||
"--output=files",
|
||||
expression,
|
||||
),
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
return [
|
||||
bazel_output_path(line.strip()) for line in output.splitlines() if line.strip()
|
||||
]
|
||||
return [bazel_output_path(line.strip()) for line in result.stdout.splitlines() if line.strip()]
|
||||
|
||||
|
||||
def bazel_build(
|
||||
@@ -89,15 +102,17 @@ def bazel_build(
|
||||
bazel_configs = bazel_configs or []
|
||||
download_args = ["--remote_download_toplevel"] if download_toplevel else []
|
||||
subprocess.run(
|
||||
bazel_command(
|
||||
[
|
||||
"bazel",
|
||||
"build",
|
||||
"-c",
|
||||
compilation_mode,
|
||||
f"--platforms=@llvm//platforms:{platform}",
|
||||
*[f"--config={config}" for config in bazel_configs],
|
||||
*bazel_remote_args(),
|
||||
*download_args,
|
||||
*labels,
|
||||
),
|
||||
],
|
||||
cwd=ROOT,
|
||||
check=True,
|
||||
)
|
||||
@@ -157,7 +172,7 @@ def resolved_v8_crate_version() -> str:
|
||||
matches = sorted(
|
||||
set(
|
||||
re.findall(
|
||||
r"https://static\.crates\.io/crates/v8/v8-([0-9]+\.[0-9]+\.[0-9]+)\.crate",
|
||||
r'https://static\.crates\.io/crates/v8/v8-([0-9]+\.[0-9]+\.[0-9]+)\.crate',
|
||||
module_bazel,
|
||||
)
|
||||
)
|
||||
@@ -219,17 +234,13 @@ def stage_artifacts(
|
||||
output_dir: Path,
|
||||
sandbox: bool,
|
||||
) -> None:
|
||||
missing_paths = [
|
||||
str(path) for path in [lib_path, binding_path] if not path.exists()
|
||||
]
|
||||
missing_paths = [str(path) for path in [lib_path, binding_path] if not path.exists()]
|
||||
if missing_paths:
|
||||
raise SystemExit(f"missing release outputs for {target}: {missing_paths}")
|
||||
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
artifact_profile = SANDBOX_ARTIFACT_PROFILE if sandbox else RELEASE_ARTIFACT_PROFILE
|
||||
staged_library = output_dir / staged_archive_name(
|
||||
target, lib_path, artifact_profile
|
||||
)
|
||||
staged_library = output_dir / staged_archive_name(target, lib_path, artifact_profile)
|
||||
staged_binding = output_dir / staged_binding_name(target, artifact_profile)
|
||||
|
||||
with lib_path.open("rb") as src, staged_library.open("wb") as dst:
|
||||
@@ -259,9 +270,7 @@ def stage_artifacts(
|
||||
|
||||
|
||||
def upstream_release_pair_paths(source_root: Path, target: str) -> tuple[Path, Path]:
|
||||
lib_name = (
|
||||
"rusty_v8.lib" if target.endswith("-pc-windows-msvc") else "librusty_v8.a"
|
||||
)
|
||||
lib_name = "rusty_v8.lib" if target.endswith("-pc-windows-msvc") else "librusty_v8.a"
|
||||
gn_out = source_root / "target" / target / "release" / "gn_out"
|
||||
return gn_out / "obj" / lib_name, gn_out / "src_binding.rs"
|
||||
|
||||
@@ -329,9 +338,7 @@ def parse_args() -> argparse.Namespace:
|
||||
stage_upstream_release_pair_parser = subparsers.add_parser(
|
||||
"stage-upstream-release-pair"
|
||||
)
|
||||
stage_upstream_release_pair_parser.add_argument(
|
||||
"--source-root", type=Path, required=True
|
||||
)
|
||||
stage_upstream_release_pair_parser.add_argument("--source-root", type=Path, required=True)
|
||||
stage_upstream_release_pair_parser.add_argument("--target", required=True)
|
||||
stage_upstream_release_pair_parser.add_argument("--output-dir", required=True)
|
||||
stage_upstream_release_pair_parser.add_argument("--sandbox", action="store_true")
|
||||
|
||||
214
.github/scripts/test_run_bazel_with_buildbuddy.py
vendored
214
.github/scripts/test_run_bazel_with_buildbuddy.py
vendored
@@ -1,214 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
import run_bazel_with_buildbuddy
|
||||
|
||||
|
||||
class RunBazelWithBuildBuddyTest(unittest.TestCase):
|
||||
def github_env(
|
||||
self,
|
||||
temp_dir: str,
|
||||
*,
|
||||
repository: str = "openai/codex",
|
||||
fork: bool = False,
|
||||
event_name: str = "pull_request",
|
||||
) -> dict[str, str]:
|
||||
event_path = Path(temp_dir) / "event.json"
|
||||
event_path.write_text(
|
||||
json.dumps({"pull_request": {"head": {"repo": {"fork": fork}}}}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
return {
|
||||
"BUILDBUDDY_API_KEY": "token",
|
||||
"GITHUB_ACTIONS": "true",
|
||||
"GITHUB_EVENT_NAME": event_name,
|
||||
"GITHUB_EVENT_PATH": str(event_path),
|
||||
"GITHUB_REPOSITORY": repository,
|
||||
}
|
||||
|
||||
def test_keyless_invocation_drops_remote_ci_configuration(self) -> None:
|
||||
self.assertIsNone(
|
||||
run_bazel_with_buildbuddy.remote_config(
|
||||
["build", "--config=ci-linux", "//codex-rs/cli:codex"],
|
||||
{},
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.bazel_args_with_remote_config(
|
||||
["build", "--config=ci-linux", "--", "//codex-rs/cli:codex"],
|
||||
{},
|
||||
),
|
||||
["build", "--", "//codex-rs/cli:codex"],
|
||||
)
|
||||
|
||||
def test_program_arguments_after_separator_do_not_select_or_lose_rbe(self) -> None:
|
||||
args = ["run", "//codex-rs/cli:codex", "--", "--config=remote"]
|
||||
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.bazel_args_with_remote_config(args, {}),
|
||||
args,
|
||||
)
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.remote_config(
|
||||
args, {"BUILDBUDDY_API_KEY": "fork-token"}
|
||||
),
|
||||
"buildbuddy-generic",
|
||||
)
|
||||
|
||||
def test_upstream_push_selects_openai_rbe_before_target_separator(self) -> None:
|
||||
with TemporaryDirectory() as temp_dir:
|
||||
env = self.github_env(temp_dir, event_name="push")
|
||||
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.bazel_args_with_remote_config(
|
||||
["build", "--config=ci-linux", "--", "//codex-rs/cli:codex"],
|
||||
env,
|
||||
),
|
||||
[
|
||||
"build",
|
||||
"--config=buildbuddy-openai-rbe",
|
||||
"--remote_header=x-buildbuddy-api-key=token",
|
||||
"--config=ci-linux",
|
||||
"--",
|
||||
"//codex-rs/cli:codex",
|
||||
],
|
||||
)
|
||||
|
||||
def test_windows_cross_ci_configuration_follows_remote_configuration(self) -> None:
|
||||
env = {"BUILDBUDDY_API_KEY": "fork-token"}
|
||||
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.bazel_args_with_remote_config(
|
||||
["build", "--config=ci-windows-cross", "//codex-rs/cli:codex"],
|
||||
env,
|
||||
),
|
||||
[
|
||||
"build",
|
||||
"--config=buildbuddy-generic-rbe",
|
||||
"--remote_header=x-buildbuddy-api-key=fork-token",
|
||||
"--config=ci-windows-cross",
|
||||
"//codex-rs/cli:codex",
|
||||
],
|
||||
)
|
||||
|
||||
def test_query_remote_configuration_is_inserted_before_expression(self) -> None:
|
||||
expression = 'kind("rust_library rule", //codex-rs/...)'
|
||||
env = {"BUILDBUDDY_API_KEY": "fork-token"}
|
||||
|
||||
for command in ("query", "cquery", "aquery"):
|
||||
with self.subTest(command=command):
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.bazel_args_with_remote_config(
|
||||
[
|
||||
command,
|
||||
"--config=ci-windows-cross",
|
||||
"--output=label",
|
||||
expression,
|
||||
],
|
||||
env,
|
||||
),
|
||||
[
|
||||
command,
|
||||
"--config=buildbuddy-generic-rbe",
|
||||
"--remote_header=x-buildbuddy-api-key=fork-token",
|
||||
"--config=ci-windows-cross",
|
||||
"--output=label",
|
||||
expression,
|
||||
],
|
||||
)
|
||||
|
||||
def test_same_repository_pull_request_selects_openai_host(self) -> None:
|
||||
with TemporaryDirectory() as temp_dir:
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.remote_config(
|
||||
["build", "--config=ci-v8"], self.github_env(temp_dir)
|
||||
),
|
||||
"buildbuddy-openai-rbe",
|
||||
)
|
||||
|
||||
def test_fork_pull_request_cannot_select_openai_host(self) -> None:
|
||||
with TemporaryDirectory() as temp_dir:
|
||||
env = self.github_env(temp_dir, fork=True)
|
||||
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.remote_config(
|
||||
["build", "--config=ci-v8"], env
|
||||
),
|
||||
"buildbuddy-generic-rbe",
|
||||
)
|
||||
|
||||
def test_run_in_fork_repository_cannot_select_openai_host(self) -> None:
|
||||
with TemporaryDirectory() as temp_dir:
|
||||
env = self.github_env(temp_dir, repository="contributor/codex")
|
||||
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.remote_config(
|
||||
["build", "--config=ci-v8"], env
|
||||
),
|
||||
"buildbuddy-generic-rbe",
|
||||
)
|
||||
|
||||
def test_pull_request_without_readable_event_payload_fails_closed(self) -> None:
|
||||
for event_path in (None, "missing-event.json"):
|
||||
env = {
|
||||
"BUILDBUDDY_API_KEY": "token",
|
||||
"GITHUB_ACTIONS": "true",
|
||||
"GITHUB_EVENT_NAME": "pull_request",
|
||||
"GITHUB_REPOSITORY": "openai/codex",
|
||||
}
|
||||
if event_path is not None:
|
||||
env["GITHUB_EVENT_PATH"] = event_path
|
||||
|
||||
with self.subTest(event_path=event_path):
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.remote_config(["build"], env),
|
||||
"buildbuddy-generic",
|
||||
)
|
||||
|
||||
def test_bazel_command_uses_configured_binary_locally(self) -> None:
|
||||
self.assertEqual(
|
||||
run_bazel_with_buildbuddy.bazel_command(
|
||||
"info",
|
||||
"execution_root",
|
||||
env={"CODEX_BAZEL_BIN": "fake-bazel"},
|
||||
),
|
||||
["fake-bazel", "info", "execution_root"],
|
||||
)
|
||||
|
||||
def test_main_preserves_spaced_argument_and_child_exit_status(self) -> None:
|
||||
spaced_arg = (
|
||||
r"--test_env=PATH=C:\Program Files\PowerShell\7;C:\Program Files\Git\bin"
|
||||
)
|
||||
child_code = (
|
||||
f"import sys; sys.exit(37 if sys.argv[1] == {spaced_arg!r} else 91)"
|
||||
)
|
||||
env = os.environ.copy()
|
||||
env["CODEX_BAZEL_BIN"] = sys.executable
|
||||
env.pop("BUILDBUDDY_API_KEY", None)
|
||||
|
||||
result = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
str(Path(run_bazel_with_buildbuddy.__file__)),
|
||||
"-c",
|
||||
child_code,
|
||||
spaced_arg,
|
||||
],
|
||||
env=env,
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
|
||||
self.assertEqual(result.returncode, 37, result.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
49
.github/scripts/test_rusty_v8_bazel.py
vendored
49
.github/scripts/test_rusty_v8_bazel.py
vendored
@@ -88,49 +88,24 @@ class RustyV8BazelTest(unittest.TestCase):
|
||||
),
|
||||
)
|
||||
|
||||
def test_bazel_commands_use_shared_buildbuddy_remote_config_library(self) -> None:
|
||||
with patch.dict(environ, {}, clear=True):
|
||||
def test_bazel_remote_args_include_buildbuddy_header_when_present(self) -> None:
|
||||
with patch.dict(environ, {"BUILDBUDDY_API_KEY": "token"}, clear=False):
|
||||
self.assertEqual(
|
||||
[
|
||||
"bazel",
|
||||
"build",
|
||||
"//third_party/v8:release",
|
||||
],
|
||||
rusty_v8_bazel.bazel_command(
|
||||
"build",
|
||||
"--config=ci-v8",
|
||||
"//third_party/v8:release",
|
||||
),
|
||||
)
|
||||
with patch.dict(environ, {"BUILDBUDDY_API_KEY": "token"}, clear=True):
|
||||
self.assertEqual(
|
||||
[
|
||||
"bazel",
|
||||
"build",
|
||||
"--config=buildbuddy-generic-rbe",
|
||||
"--remote_header=x-buildbuddy-api-key=token",
|
||||
"--config=ci-v8",
|
||||
"//third_party/v8:release",
|
||||
],
|
||||
rusty_v8_bazel.bazel_command(
|
||||
"build",
|
||||
"--config=ci-v8",
|
||||
"//third_party/v8:release",
|
||||
),
|
||||
["--remote_header=x-buildbuddy-api-key=token"],
|
||||
rusty_v8_bazel.bazel_remote_args(),
|
||||
)
|
||||
|
||||
def test_release_pair_labels_and_staged_names_distinguish_sandbox_artifacts(
|
||||
self,
|
||||
) -> None:
|
||||
with patch.dict(environ, {}, clear=True):
|
||||
self.assertEqual([], rusty_v8_bazel.bazel_remote_args())
|
||||
|
||||
def test_release_pair_labels_and_staged_names_distinguish_sandbox_artifacts(self) -> None:
|
||||
self.assertEqual(
|
||||
"//third_party/v8:rusty_v8_release_pair_x86_64_unknown_linux_musl",
|
||||
rusty_v8_bazel.release_pair_label("x86_64-unknown-linux-musl"),
|
||||
)
|
||||
self.assertEqual(
|
||||
"//third_party/v8:rusty_v8_sandbox_release_pair_x86_64_unknown_linux_musl",
|
||||
rusty_v8_bazel.release_pair_label(
|
||||
"x86_64-unknown-linux-musl", sandbox=True
|
||||
),
|
||||
rusty_v8_bazel.release_pair_label("x86_64-unknown-linux-musl", sandbox=True),
|
||||
)
|
||||
self.assertEqual(
|
||||
"//third_party/v8:rusty_v8_sandbox_release_pair_x86_64_apple_darwin",
|
||||
@@ -230,7 +205,11 @@ class RustyV8BazelTest(unittest.TestCase):
|
||||
with TemporaryDirectory() as source_dir, TemporaryDirectory() as output_dir:
|
||||
source_root = Path(source_dir)
|
||||
gn_out = (
|
||||
source_root / "target" / "x86_64-pc-windows-msvc" / "release" / "gn_out"
|
||||
source_root
|
||||
/ "target"
|
||||
/ "x86_64-pc-windows-msvc"
|
||||
/ "release"
|
||||
/ "gn_out"
|
||||
)
|
||||
(gn_out / "obj").mkdir(parents=True)
|
||||
(gn_out / "obj" / "rusty_v8.lib").write_bytes(b"archive")
|
||||
|
||||
31
.github/workflows/bazel.yml
vendored
31
.github/workflows/bazel.yml
vendored
@@ -15,7 +15,6 @@ concurrency:
|
||||
# See https://docs.github.com/en/actions/using-jobs/using-concurrency and https://docs.github.com/en/actions/learn-github-actions/contexts for more info.
|
||||
group: concurrency-group::${{ github.workflow }}::${{ github.event.pull_request.number > 0 && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}${{ github.ref_name == 'main' && format('::{0}', github.run_id) || ''}}
|
||||
cancel-in-progress: ${{ github.ref_name != 'main' }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
# PRs use the sharded Windows cross-compiled test jobs below. Post-merge
|
||||
@@ -56,17 +55,12 @@ jobs:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
|
||||
if: matrix.os == 'ubuntu-24.04' && matrix.target == 'x86_64-unknown-linux-gnu'
|
||||
with:
|
||||
tool: just
|
||||
|
||||
- name: Check rusty_v8 MODULE.bazel checksums
|
||||
if: matrix.os == 'ubuntu-24.04' && matrix.target == 'x86_64-unknown-linux-gnu'
|
||||
shell: bash
|
||||
run: |
|
||||
python3 .github/scripts/rusty_v8_bazel.py check-module-bazel
|
||||
just test-github-scripts
|
||||
python3 -m unittest discover -s .github/scripts -p test_rusty_v8_bazel.py
|
||||
|
||||
- name: Prepare Bazel CI
|
||||
id: prepare_bazel
|
||||
@@ -147,9 +141,7 @@ jobs:
|
||||
- 2
|
||||
- 3
|
||||
- 4
|
||||
runs-on:
|
||||
group: codex-runners
|
||||
labels: codex-windows-x64
|
||||
runs-on: windows-latest
|
||||
name: Bazel test on windows-latest for x86_64-pc-windows-gnullvm shard ${{ matrix.shard }}/4
|
||||
|
||||
steps:
|
||||
@@ -158,11 +150,6 @@ jobs:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Test BuildBuddy Bazel wrapper
|
||||
if: matrix.shard == 1
|
||||
shell: pwsh
|
||||
run: python .github/scripts/test_run_bazel_with_buildbuddy.py
|
||||
|
||||
- name: Prepare Bazel CI
|
||||
id: prepare_bazel
|
||||
uses: ./.github/actions/prepare-bazel-ci
|
||||
@@ -259,9 +246,7 @@ jobs:
|
||||
# it a larger timeout.
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
timeout-minutes: 40
|
||||
runs-on:
|
||||
group: codex-runners
|
||||
labels: codex-windows-x64
|
||||
runs-on: windows-latest
|
||||
name: Bazel test on windows-latest for x86_64-pc-windows-gnullvm (native main)
|
||||
|
||||
steps:
|
||||
@@ -347,10 +332,7 @@ jobs:
|
||||
target: aarch64-apple-darwin
|
||||
- os: windows-latest
|
||||
target: x86_64-pc-windows-gnullvm
|
||||
runs_on:
|
||||
group: codex-runners
|
||||
labels: codex-windows-x64
|
||||
runs-on: ${{ matrix.runs_on || matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
name: Bazel clippy on ${{ matrix.os }} for ${{ matrix.target }}
|
||||
|
||||
steps:
|
||||
@@ -440,10 +422,7 @@ jobs:
|
||||
target: aarch64-apple-darwin
|
||||
- os: windows-latest
|
||||
target: x86_64-pc-windows-gnullvm
|
||||
runs_on:
|
||||
group: codex-runners
|
||||
labels: codex-windows-x64
|
||||
runs-on: ${{ matrix.runs_on || matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
name: Verify release build on ${{ matrix.os }} for ${{ matrix.target }}
|
||||
|
||||
steps:
|
||||
|
||||
9
.github/workflows/cargo-deny.yml
vendored
9
.github/workflows/cargo-deny.yml
vendored
@@ -6,11 +6,6 @@ on:
|
||||
branches:
|
||||
- main
|
||||
|
||||
# Cargo's libgit2 transport has been flaky when fetching git dependencies with
|
||||
# nested submodules. Prefer the system git CLI across every Cargo invocation.
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
|
||||
|
||||
jobs:
|
||||
cargo-deny:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -25,10 +20,10 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
|
||||
- name: Run cargo-deny
|
||||
uses: EmbarkStudios/cargo-deny-action@82eb9f621fbc699dd0918f3ea06864c14cc84246 # v2
|
||||
with:
|
||||
rust-version: 1.95.0
|
||||
rust-version: 1.93.0
|
||||
manifest-path: ./codex-rs/Cargo.toml
|
||||
|
||||
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@@ -74,15 +74,5 @@ jobs:
|
||||
- name: Check root README ToC
|
||||
run: python3 scripts/readme_toc.py README.md
|
||||
|
||||
- uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
|
||||
with:
|
||||
tool: just@1.51.0
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
||||
with:
|
||||
version: "0.11.3"
|
||||
- name: Check formatting (run `just fmt` to fix)
|
||||
run: just fmt-check
|
||||
|
||||
- name: Prettier (run `pnpm run format:fix` to fix)
|
||||
run: pnpm run format
|
||||
|
||||
2
.github/workflows/issue-deduplicator.yml
vendored
2
.github/workflows/issue-deduplicator.yml
vendored
@@ -12,7 +12,6 @@ jobs:
|
||||
# Prevent runs on forks (requires OpenAI API key, wastes Actions minutes)
|
||||
if: github.repository == 'openai/codex' && (github.event.action == 'opened' || (github.event.action == 'labeled' && github.event.label.name == 'codex-deduplicate'))
|
||||
runs-on: ubuntu-latest
|
||||
environment: issue-triage
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
@@ -158,7 +157,6 @@ jobs:
|
||||
needs: normalize-duplicates-all
|
||||
if: ${{ needs.normalize-duplicates-all.result == 'success' && needs.normalize-duplicates-all.outputs.has_matches != 'true' }}
|
||||
runs-on: ubuntu-latest
|
||||
environment: issue-triage
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
|
||||
1
.github/workflows/issue-labeler.yml
vendored
1
.github/workflows/issue-labeler.yml
vendored
@@ -12,7 +12,6 @@ jobs:
|
||||
# Prevent runs on forks (requires OpenAI API key, wastes Actions minutes)
|
||||
if: github.repository == 'openai/codex' && (github.event.action == 'opened' || (github.event.action == 'labeled' && github.event.label.name == 'codex-label'))
|
||||
runs-on: ubuntu-latest
|
||||
environment: issue-triage
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
|
||||
232
.github/workflows/python-sdk-release.yml
vendored
232
.github/workflows/python-sdk-release.yml
vendored
@@ -1,232 +0,0 @@
|
||||
name: python-sdk-release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "python-v*"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
runtime_version:
|
||||
description: "Runtime version to publish before updating the SDK pin, for example 0.136.0 or 0.136.0a2."
|
||||
required: true
|
||||
type: string
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Publish the platform-specific Python runtime wheels before building the SDK
|
||||
# package that pins them, or explicitly before updating the SDK runtime pin.
|
||||
# PyPI project configuration must trust this workflow and job for publishing.
|
||||
publish-python-runtime:
|
||||
if: github.repository == 'openai/codex'
|
||||
name: publish-python-runtime
|
||||
runs-on: ubuntu-latest
|
||||
environment: pypi
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write # Required for PyPI trusted publishing.
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Validate SDK tag and resolve Python runtime release
|
||||
id: python_runtime
|
||||
shell: bash
|
||||
env:
|
||||
REQUESTED_RUNTIME_VERSION: ${{ inputs.runtime_version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
python3 - <<'PY'
|
||||
import os
|
||||
import re
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
|
||||
event_name = os.environ["GITHUB_EVENT_NAME"]
|
||||
if event_name == "workflow_dispatch":
|
||||
python_version = os.environ["REQUESTED_RUNTIME_VERSION"]
|
||||
elif event_name == "push":
|
||||
sdk_version = os.environ["GITHUB_REF_NAME"].removeprefix("python-v")
|
||||
if not re.fullmatch(r"[0-9]+\.[0-9]+\.[0-9]+b[0-9]+", sdk_version):
|
||||
raise SystemExit(
|
||||
"Python SDK release tags must identify a beta release, "
|
||||
"for example python-v0.1.0b1."
|
||||
)
|
||||
|
||||
pyproject = tomllib.loads(Path("sdk/python/pyproject.toml").read_text())
|
||||
prefix = "openai-codex-cli-bin=="
|
||||
versions = [
|
||||
dependency.removeprefix(prefix)
|
||||
for dependency in pyproject["project"]["dependencies"]
|
||||
if dependency.startswith(prefix)
|
||||
]
|
||||
if len(versions) != 1:
|
||||
raise SystemExit(f"Expected exactly one pinned {prefix} dependency, found {versions}")
|
||||
python_version = versions[0]
|
||||
else:
|
||||
raise SystemExit(f"Unsupported workflow event: {event_name}")
|
||||
|
||||
if match := re.fullmatch(r"([0-9]+\.[0-9]+\.[0-9]+)a([0-9]+)", python_version):
|
||||
release_version = f"{match.group(1)}-alpha.{match.group(2)}"
|
||||
elif re.fullmatch(r"[0-9]+\.[0-9]+\.[0-9]+", python_version):
|
||||
release_version = python_version
|
||||
else:
|
||||
raise SystemExit(
|
||||
"Python runtime version must be stable or a numbered alpha, "
|
||||
f"for example 0.136.0 or 0.136.0a2; found {python_version}"
|
||||
)
|
||||
|
||||
with Path(os.environ["GITHUB_OUTPUT"]).open("a") as output:
|
||||
print(f"python_version={python_version}", file=output)
|
||||
print(f"release_tag=rust-v{release_version}", file=output)
|
||||
PY
|
||||
|
||||
- name: Download Python runtime release artifacts
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PYTHON_RUNTIME_VERSION: ${{ steps.python_runtime.outputs.python_version }}
|
||||
RELEASE_TAG: ${{ steps.python_runtime.outputs.release_tag }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p dist/python-runtime dist/python-runtime-packages
|
||||
gh release download "$RELEASE_TAG" \
|
||||
--repo "${GITHUB_REPOSITORY}" \
|
||||
--pattern "openai_codex_cli_bin-${PYTHON_RUNTIME_VERSION}-*.whl" \
|
||||
--dir dist/python-runtime
|
||||
gh release download "$RELEASE_TAG" \
|
||||
--repo "${GITHUB_REPOSITORY}" \
|
||||
--pattern "codex-package-*-unknown-linux-musl.tar.gz" \
|
||||
--dir dist/python-runtime-packages
|
||||
|
||||
shopt -s nullglob
|
||||
wheels=(dist/python-runtime/*.whl)
|
||||
if [[ "${#wheels[@]}" -ne 6 ]]; then
|
||||
echo "Expected 6 Python runtime wheels for ${PYTHON_RUNTIME_VERSION}, found ${#wheels[@]}."
|
||||
exit 1
|
||||
fi
|
||||
packages=(dist/python-runtime-packages/*.tar.gz)
|
||||
if [[ "${#packages[@]}" -ne 2 ]]; then
|
||||
echo "Expected 2 Linux package archives for ${PYTHON_RUNTIME_VERSION}, found ${#packages[@]}."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Build musllinux Python runtime wheels
|
||||
env:
|
||||
RELEASE_TAG: ${{ steps.python_runtime.outputs.release_tag }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
python3 -m venv "${RUNNER_TEMP}/python-runtime-build-venv"
|
||||
"${RUNNER_TEMP}/python-runtime-build-venv/bin/python" -m pip install build
|
||||
|
||||
while read -r target platform_tag; do
|
||||
stage_dir="${RUNNER_TEMP}/openai-codex-cli-bin-${target}-${platform_tag}"
|
||||
python3 sdk/python/scripts/update_sdk_artifacts.py \
|
||||
stage-runtime \
|
||||
"$stage_dir" \
|
||||
"dist/python-runtime-packages/codex-package-${target}.tar.gz" \
|
||||
--codex-version "$RELEASE_TAG" \
|
||||
--platform-tag "$platform_tag"
|
||||
"${RUNNER_TEMP}/python-runtime-build-venv/bin/python" -m build \
|
||||
--wheel \
|
||||
--outdir dist/python-runtime \
|
||||
"$stage_dir"
|
||||
done <<'EOF'
|
||||
aarch64-unknown-linux-musl musllinux_1_1_aarch64
|
||||
x86_64-unknown-linux-musl musllinux_1_1_x86_64
|
||||
EOF
|
||||
|
||||
shopt -s nullglob
|
||||
wheels=(dist/python-runtime/*.whl)
|
||||
if [[ "${#wheels[@]}" -ne 8 ]]; then
|
||||
echo "Expected 8 Python runtime wheels, found ${#wheels[@]}."
|
||||
exit 1
|
||||
fi
|
||||
ls -lh dist/python-runtime
|
||||
|
||||
- name: Publish Python runtime wheels to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
|
||||
with:
|
||||
packages-dir: dist/python-runtime
|
||||
skip-existing: true
|
||||
|
||||
build-python-sdk:
|
||||
if: github.event_name == 'push' && github.repository == 'openai/codex'
|
||||
name: build-python-sdk
|
||||
needs: publish-python-runtime
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Validate tag and build Python SDK package
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
sdk_version="${GITHUB_REF_NAME#python-v}"
|
||||
# Build in a glibc Linux image so release type generation installs
|
||||
# the pinned manylinux runtime wheel.
|
||||
docker run --rm \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
-e HOME=/tmp/codex-python-sdk-home \
|
||||
-e UV_LINK_MODE=copy \
|
||||
-e SDK_VERSION="${sdk_version}" \
|
||||
-e SDK_STAGE_DIR="${RUNNER_TEMP}/openai-codex" \
|
||||
-e SDK_DIST_DIR="${GITHUB_WORKSPACE}/dist/python-sdk" \
|
||||
-v "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}" \
|
||||
-v "${RUNNER_TEMP}:${RUNNER_TEMP}" \
|
||||
-w "${GITHUB_WORKSPACE}/sdk/python" \
|
||||
python:3.12-slim \
|
||||
sh -euxc '
|
||||
python -m venv /tmp/release-tools
|
||||
/tmp/release-tools/bin/python -m pip install build twine uv==0.11.3
|
||||
/tmp/release-tools/bin/uv sync --extra dev --frozen
|
||||
/tmp/release-tools/bin/uv run --extra dev --frozen python scripts/update_sdk_artifacts.py \
|
||||
stage-sdk "${SDK_STAGE_DIR}" \
|
||||
--sdk-version "${SDK_VERSION}"
|
||||
/tmp/release-tools/bin/python -m build \
|
||||
--wheel \
|
||||
--sdist \
|
||||
--outdir "${SDK_DIST_DIR}" \
|
||||
"${SDK_STAGE_DIR}"
|
||||
/tmp/release-tools/bin/python -m twine check --strict "${SDK_DIST_DIR}/"*
|
||||
'
|
||||
|
||||
- name: Upload Python SDK package
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: python-sdk-package
|
||||
path: dist/python-sdk/*
|
||||
if-no-files-found: error
|
||||
|
||||
publish-python-sdk:
|
||||
name: publish-python-sdk
|
||||
needs: build-python-sdk
|
||||
runs-on: ubuntu-latest
|
||||
environment: pypi
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write # Required for PyPI trusted publishing.
|
||||
|
||||
steps:
|
||||
- name: Download Python SDK package
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
name: python-sdk-package
|
||||
path: dist/python-sdk
|
||||
|
||||
- name: Publish Python SDK to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
|
||||
with:
|
||||
packages-dir: dist/python-sdk
|
||||
@@ -94,7 +94,7 @@ jobs:
|
||||
- name: Install DotSlash
|
||||
uses: facebook/install-dotslash@1e4e7b3e07eaca387acb98f1d4720e0bee8dbb6a # v2
|
||||
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
targets: ${{ inputs.target }}
|
||||
|
||||
@@ -319,7 +319,7 @@ jobs:
|
||||
- name: Install DotSlash
|
||||
uses: facebook/install-dotslash@1e4e7b3e07eaca387acb98f1d4720e0bee8dbb6a # v2
|
||||
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
targets: ${{ inputs.target }}
|
||||
|
||||
|
||||
74
.github/workflows/rust-ci-full.yml
vendored
74
.github/workflows/rust-ci-full.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
components: rustfmt
|
||||
- uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
- uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
|
||||
with:
|
||||
tool: cargo-shear@1.11.2
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
toolchain: nightly-2025-09-18
|
||||
components: llvm-tools-preview, rustc-dev, rust-src
|
||||
@@ -260,9 +260,13 @@ jobs:
|
||||
set -euo pipefail
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
sudo apt-get update -y
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
|
||||
packages=(pkg-config libcap-dev)
|
||||
if [[ "${{ matrix.target }}" == 'x86_64-unknown-linux-musl' || "${{ matrix.target }}" == 'aarch64-unknown-linux-musl' ]]; then
|
||||
packages+=(libubsan1)
|
||||
fi
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "${packages[@]}"
|
||||
fi
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
components: clippy
|
||||
@@ -344,6 +348,14 @@ jobs:
|
||||
sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-${{ steps.lockhash.outputs.hash }}-
|
||||
sccache-${{ matrix.runner }}-${{ matrix.target }}-${{ matrix.profile }}-
|
||||
|
||||
- if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}}
|
||||
name: Disable sccache wrapper (musl)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "RUSTC_WRAPPER=" >> "$GITHUB_ENV"
|
||||
echo "RUSTC_WORKSPACE_WRAPPER=" >> "$GITHUB_ENV"
|
||||
|
||||
- if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}}
|
||||
name: Prepare APT cache directories (musl)
|
||||
shell: bash
|
||||
@@ -377,6 +389,58 @@ jobs:
|
||||
shell: bash
|
||||
run: bash "${GITHUB_WORKSPACE}/.github/scripts/install-musl-build-tools.sh"
|
||||
|
||||
- if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}}
|
||||
name: Configure rustc UBSan wrapper (musl host)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ubsan=""
|
||||
if command -v ldconfig >/dev/null 2>&1; then
|
||||
ubsan="$(ldconfig -p | grep -m1 'libubsan\.so\.1' | sed -E 's/.*=> (.*)$/\1/')"
|
||||
fi
|
||||
wrapper_root="${RUNNER_TEMP:-/tmp}"
|
||||
wrapper="${wrapper_root}/rustc-ubsan-wrapper"
|
||||
cat > "${wrapper}" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ -n "${ubsan}" ]]; then
|
||||
export LD_PRELOAD="${ubsan}\${LD_PRELOAD:+:\${LD_PRELOAD}}"
|
||||
fi
|
||||
exec "\$1" "\${@:2}"
|
||||
EOF
|
||||
chmod +x "${wrapper}"
|
||||
echo "RUSTC_WRAPPER=${wrapper}" >> "$GITHUB_ENV"
|
||||
echo "RUSTC_WORKSPACE_WRAPPER=" >> "$GITHUB_ENV"
|
||||
|
||||
- if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}}
|
||||
name: Clear sanitizer flags (musl)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Clear global Rust flags so host/proc-macro builds don't pull in UBSan.
|
||||
echo "RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "RUSTDOCFLAGS=" >> "$GITHUB_ENV"
|
||||
# Override any runner-level Cargo config rustflags as well.
|
||||
echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
|
||||
sanitize_flags() {
|
||||
local input="$1"
|
||||
input="${input//-fsanitize=undefined/}"
|
||||
input="${input//-fno-sanitize-recover=undefined/}"
|
||||
input="${input//-fno-sanitize-trap=undefined/}"
|
||||
echo "$input"
|
||||
}
|
||||
|
||||
cflags="$(sanitize_flags "${CFLAGS-}")"
|
||||
cxxflags="$(sanitize_flags "${CXXFLAGS-}")"
|
||||
echo "CFLAGS=${cflags}" >> "$GITHUB_ENV"
|
||||
echo "CXXFLAGS=${cxxflags}" >> "$GITHUB_ENV"
|
||||
|
||||
- if: ${{ !contains(matrix.target, 'windows') }}
|
||||
name: Configure rusty_v8 artifact overrides and verify checksums
|
||||
uses: ./.github/actions/setup-rusty-v8
|
||||
|
||||
11
.github/workflows/rust-ci.yml
vendored
11
.github/workflows/rust-ci.yml
vendored
@@ -3,11 +3,6 @@ on:
|
||||
pull_request: {}
|
||||
workflow_dispatch:
|
||||
|
||||
# Cargo's libgit2 transport has been flaky when fetching git dependencies with
|
||||
# nested submodules. Prefer the system git CLI across every Cargo invocation.
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
|
||||
|
||||
jobs:
|
||||
# --- Detect what changed so the fast PR workflow only runs relevant jobs ----
|
||||
changed:
|
||||
@@ -72,7 +67,7 @@ jobs:
|
||||
with:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
components: rustfmt
|
||||
- uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
|
||||
@@ -96,7 +91,7 @@ jobs:
|
||||
with:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
- uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
|
||||
with:
|
||||
tool: cargo-shear@1.11.2
|
||||
@@ -116,7 +111,7 @@ jobs:
|
||||
with:
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
- name: Install nightly argument-comment-lint toolchain
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
@@ -7,11 +7,6 @@ on:
|
||||
required: true
|
||||
type: boolean
|
||||
|
||||
# Cargo's libgit2 transport has been flaky when fetching git dependencies with
|
||||
# nested submodules. Prefer the system git CLI across every Cargo invocation.
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
|
||||
|
||||
jobs:
|
||||
skip:
|
||||
if: ${{ !inputs.publish }}
|
||||
@@ -65,7 +60,7 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
toolchain: nightly-2025-09-18
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
13
.github/workflows/rust-release-windows.yml
vendored
13
.github/workflows/rust-release-windows.yml
vendored
@@ -20,11 +20,6 @@ on:
|
||||
AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE_NAME:
|
||||
required: true
|
||||
|
||||
# Cargo's libgit2 transport has been flaky when fetching git dependencies with
|
||||
# nested submodules. Prefer the system git CLI across every Cargo invocation.
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
|
||||
|
||||
jobs:
|
||||
build-windows-binaries:
|
||||
name: Build Windows binaries - ${{ matrix.runner }} - ${{ matrix.target }} - ${{ matrix.bundle }}
|
||||
@@ -105,22 +100,18 @@ jobs:
|
||||
Write-Host "Total RAM: $ramGiB GiB"
|
||||
Write-Host "Disk usage:"
|
||||
Get-PSDrive -PSProvider FileSystem | Format-Table -AutoSize Name, @{Name='Size(GB)';Expression={[math]::Round(($_.Used + $_.Free) / 1GB, 1)}}, @{Name='Free(GB)';Expression={[math]::Round($_.Free / 1GB, 1)}}
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- name: Cargo build (Windows binaries)
|
||||
shell: bash
|
||||
run: |
|
||||
target="${{ matrix.target }}"
|
||||
if [[ "$target" == "x86_64-pc-windows-msvc" ]]; then
|
||||
export LIBSQLITE3_FLAGS=SQLITE_DISABLE_INTRINSIC
|
||||
fi
|
||||
build_args=()
|
||||
for binary in ${{ matrix.binaries }}; do
|
||||
build_args+=(--bin "$binary")
|
||||
done
|
||||
cargo build --target "$target" --release --timings "${build_args[@]}"
|
||||
cargo build --target ${{ matrix.target }} --release --timings "${build_args[@]}"
|
||||
|
||||
- name: Upload Cargo timings
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
|
||||
161
.github/workflows/rust-release.yml
vendored
161
.github/workflows/rust-release.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
- name: Validate tag matches Cargo.toml version
|
||||
shell: bash
|
||||
env:
|
||||
@@ -149,11 +149,6 @@ jobs:
|
||||
# 2026-03-04: temporarily change releases to use thin LTO because
|
||||
# Ubuntu ARM is timing out at 60 minutes.
|
||||
CARGO_PROFILE_RELEASE_LTO: ${{ contains(github.ref_name, '-alpha') && 'thin' || 'thin' }}
|
||||
# Use the git CLI instead of Cargo's libgit2 path for git dependencies.
|
||||
# macOS release runners have intermittently failed to fetch nested
|
||||
# submodules through SecureTransport/libgit2, especially libwebrtc's
|
||||
# libyuv submodule from chromium.googlesource.com.
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
|
||||
SIGN_MACOS: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
|
||||
strategy:
|
||||
@@ -250,7 +245,16 @@ jobs:
|
||||
set -euo pipefail
|
||||
sudo apt-get update -y
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- name: Install UBSan runtime (musl)
|
||||
if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
sudo apt-get update -y
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libubsan1
|
||||
fi
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
@@ -279,7 +283,30 @@ jobs:
|
||||
run: bash "${GITHUB_WORKSPACE}/.github/scripts/install-musl-build-tools.sh"
|
||||
|
||||
- if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}}
|
||||
name: Disable aws-lc jitter entropy (musl)
|
||||
name: Configure rustc UBSan wrapper (musl host)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
ubsan=""
|
||||
if command -v ldconfig >/dev/null 2>&1; then
|
||||
ubsan="$(ldconfig -p | grep -m1 'libubsan\.so\.1' | sed -E 's/.*=> (.*)$/\1/')"
|
||||
fi
|
||||
wrapper_root="${RUNNER_TEMP:-/tmp}"
|
||||
wrapper="${wrapper_root}/rustc-ubsan-wrapper"
|
||||
cat > "${wrapper}" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ -n "${ubsan}" ]]; then
|
||||
export LD_PRELOAD="${ubsan}\${LD_PRELOAD:+:\${LD_PRELOAD}}"
|
||||
fi
|
||||
exec "\$1" "\${@:2}"
|
||||
EOF
|
||||
chmod +x "${wrapper}"
|
||||
echo "RUSTC_WRAPPER=${wrapper}" >> "$GITHUB_ENV"
|
||||
echo "RUSTC_WORKSPACE_WRAPPER=" >> "$GITHUB_ENV"
|
||||
|
||||
- if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}}
|
||||
name: Clear sanitizer flags (musl)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -289,6 +316,30 @@ jobs:
|
||||
target_no_jitter="${target_no_jitter//-/_}"
|
||||
echo "${target_no_jitter}=1" >> "$GITHUB_ENV"
|
||||
|
||||
# Clear global Rust flags so host/proc-macro builds don't pull in UBSan.
|
||||
echo "RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_ENCODED_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "RUSTDOCFLAGS=" >> "$GITHUB_ENV"
|
||||
# Override any runner-level Cargo config rustflags as well.
|
||||
echo "CARGO_BUILD_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_RUSTFLAGS=" >> "$GITHUB_ENV"
|
||||
|
||||
sanitize_flags() {
|
||||
local input="$1"
|
||||
input="${input//-fsanitize=undefined/}"
|
||||
input="${input//-fno-sanitize-recover=undefined/}"
|
||||
input="${input//-fno-sanitize-trap=undefined/}"
|
||||
echo "$input"
|
||||
}
|
||||
|
||||
cflags="$(sanitize_flags "${CFLAGS-}")"
|
||||
cxxflags="$(sanitize_flags "${CXXFLAGS-}")"
|
||||
echo "CFLAGS=${cflags}" >> "$GITHUB_ENV"
|
||||
echo "CXXFLAGS=${cxxflags}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Configure rusty_v8 artifact overrides and verify checksums
|
||||
uses: ./.github/actions/setup-rusty-v8
|
||||
with:
|
||||
@@ -315,16 +366,12 @@ jobs:
|
||||
- name: Cargo build
|
||||
shell: bash
|
||||
run: |
|
||||
target="${{ matrix.target }}"
|
||||
if [[ "$target" == "x86_64-pc-windows-msvc" ]]; then
|
||||
export LIBSQLITE3_FLAGS=SQLITE_DISABLE_INTRINSIC
|
||||
fi
|
||||
build_args=()
|
||||
for binary in ${{ matrix.binaries }}; do
|
||||
build_args+=(--bin "$binary")
|
||||
done
|
||||
echo "CARGO_PROFILE_RELEASE_LTO: ${CARGO_PROFILE_RELEASE_LTO}"
|
||||
cargo build --target "$target" --release --timings "${build_args[@]}"
|
||||
cargo build --target ${{ matrix.target }} --release --timings "${build_args[@]}"
|
||||
|
||||
- name: Upload Cargo timings
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
@@ -891,6 +938,7 @@ jobs:
|
||||
sign_macos: ${{ steps.release_mode.outputs.sign_macos }}
|
||||
should_publish_npm: ${{ steps.npm_publish_settings.outputs.should_publish }}
|
||||
npm_tag: ${{ steps.npm_publish_settings.outputs.npm_tag }}
|
||||
should_publish_python_runtime: ${{ steps.python_runtime_publish_settings.outputs.should_publish }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -1114,6 +1162,27 @@ jobs:
|
||||
echo "npm_tag=" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Determine Python runtime publish settings
|
||||
id: python_runtime_publish_settings
|
||||
env:
|
||||
VERSION: ${{ steps.release_name.outputs.name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
version="${VERSION}"
|
||||
|
||||
if [[ "${SIGN_MACOS}" != "true" ]]; then
|
||||
echo "should_publish=false" >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "should_publish=true" >> "$GITHUB_OUTPUT"
|
||||
elif [[ "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+-alpha\.[0-9]+$ ]]; then
|
||||
echo "should_publish=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "should_publish=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Setup pnpm
|
||||
if: ${{ env.SIGN_MACOS == 'true' }}
|
||||
uses: pnpm/action-setup@a8198c4bff370c8506180b035930dea56dbd5288 # v5
|
||||
@@ -1213,6 +1282,19 @@ jobs:
|
||||
tag: ${{ github.ref_name }}
|
||||
config: .github/dotslash-argument-comment-lint-config.json
|
||||
|
||||
- name: Trigger developers.openai.com deploy
|
||||
# Only trigger the deploy if the release is not a pre-release.
|
||||
# The deploy is used to update the developers.openai.com website with the new config schema json file.
|
||||
if: ${{ env.SIGN_MACOS == 'true' && !contains(steps.release_name.outputs.name, '-') }}
|
||||
continue-on-error: true
|
||||
env:
|
||||
DEV_WEBSITE_VERCEL_DEPLOY_HOOK_URL: ${{ secrets.DEV_WEBSITE_VERCEL_DEPLOY_HOOK_URL }}
|
||||
run: |
|
||||
if ! curl -sS -f -o /dev/null -X POST "$DEV_WEBSITE_VERCEL_DEPLOY_HOOK_URL"; then
|
||||
echo "::warning title=developers.openai.com deploy hook failed::Vercel deploy hook POST failed for ${GITHUB_REF_NAME}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Publish to npm using OIDC authentication.
|
||||
# July 31, 2025: https://github.blog/changelog/2025-07-31-npm-trusted-publishing-with-oidc-is-generally-available/
|
||||
# npm docs: https://docs.npmjs.com/trusted-publishers
|
||||
@@ -1378,35 +1460,52 @@ jobs:
|
||||
exit "${publish_status}"
|
||||
done
|
||||
|
||||
deploy-dev-website:
|
||||
name: Trigger developers.openai.com deploy
|
||||
needs: release
|
||||
# Only trigger the deploy for a stable signed release.
|
||||
# The deploy updates developers.openai.com with the new config schema json file.
|
||||
# Publish the platform-specific Python runtime wheels using PyPI trusted publishing.
|
||||
# PyPI project configuration must trust this workflow and job. Keep this
|
||||
# non-blocking while the Python runtime publishing path is new; failures still
|
||||
# need release follow-up, but should not invalidate the Rust release itself.
|
||||
publish-python-runtime:
|
||||
# Publish to PyPI for stable releases and alpha pre-releases with numeric suffixes.
|
||||
if: >-
|
||||
${{
|
||||
!cancelled() &&
|
||||
needs.release.result == 'success' &&
|
||||
needs.release.outputs.sign_macos == 'true' &&
|
||||
!contains(needs.release.outputs.version, '-')
|
||||
needs.release.outputs.should_publish_python_runtime == 'true'
|
||||
}}
|
||||
name: publish-python-runtime
|
||||
needs: release
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
permissions: {}
|
||||
environment:
|
||||
name: dev-website-vercel-deploy
|
||||
deployment: false
|
||||
environment: pypi
|
||||
permissions:
|
||||
id-token: write # Required for PyPI trusted publishing.
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Trigger developers.openai.com deploy
|
||||
continue-on-error: true
|
||||
- name: Download Python runtime wheels from release
|
||||
env:
|
||||
DEV_WEBSITE_VERCEL_DEPLOY_HOOK_URL: ${{ secrets.DEV_WEBSITE_VERCEL_DEPLOY_HOOK_URL }}
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RELEASE_TAG: ${{ needs.release.outputs.tag }}
|
||||
RELEASE_VERSION: ${{ needs.release.outputs.version }}
|
||||
run: |
|
||||
if ! curl -sS -f -o /dev/null -X POST "$DEV_WEBSITE_VERCEL_DEPLOY_HOOK_URL"; then
|
||||
echo "::warning title=developers.openai.com deploy hook failed::Vercel deploy hook POST failed for ${GITHUB_REF_NAME}"
|
||||
exit 1
|
||||
fi
|
||||
set -euo pipefail
|
||||
python_version="$RELEASE_VERSION"
|
||||
python_version="${python_version/-alpha./a}"
|
||||
python_version="${python_version/-beta./b}"
|
||||
python_version="${python_version/-rc./rc}"
|
||||
|
||||
mkdir -p dist/python-runtime
|
||||
gh release download "$RELEASE_TAG" \
|
||||
--repo "${GITHUB_REPOSITORY}" \
|
||||
--pattern "openai_codex_cli_bin-${python_version}-*.whl" \
|
||||
--dir dist/python-runtime
|
||||
ls -lh dist/python-runtime
|
||||
|
||||
- name: Publish Python runtime wheels to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
|
||||
with:
|
||||
packages-dir: dist/python-runtime
|
||||
skip-existing: true
|
||||
|
||||
winget:
|
||||
name: winget
|
||||
|
||||
14
.github/workflows/rusty-v8-release.yml
vendored
14
.github/workflows/rusty-v8-release.yml
vendored
@@ -5,11 +5,6 @@ on:
|
||||
tags:
|
||||
- "rusty-v8-v*.*.*"
|
||||
|
||||
# Cargo's libgit2 transport has been flaky when fetching git dependencies with
|
||||
# nested submodules. Prefer the system git CLI for Cargo smoke tests.
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}::${{ github.ref_name }}
|
||||
cancel-in-progress: false
|
||||
@@ -157,9 +152,9 @@ jobs:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Set up Rust toolchain for Cargo smoke
|
||||
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
toolchain: "1.95.0"
|
||||
toolchain: "1.93.0"
|
||||
|
||||
- name: Build Bazel V8 release pair
|
||||
env:
|
||||
@@ -191,10 +186,11 @@ jobs:
|
||||
bazel_args+=(--config=v8-release-compat)
|
||||
fi
|
||||
|
||||
./.github/scripts/run_bazel_with_buildbuddy.py \
|
||||
bazel \
|
||||
--noexperimental_remote_repo_contents_cache \
|
||||
"${bazel_args[@]}" \
|
||||
"--config=${{ matrix.bazel_config }}"
|
||||
"--config=${{ matrix.bazel_config }}" \
|
||||
"--remote_header=x-buildbuddy-api-key=${BUILDBUDDY_API_KEY}"
|
||||
|
||||
- name: Stage release pair
|
||||
env:
|
||||
|
||||
6
.github/workflows/sdk.yml
vendored
6
.github/workflows/sdk.yml
vendored
@@ -23,15 +23,15 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
# Run inside a glibc Linux image so dependency resolution exercises
|
||||
# the pinned manylinux runtime wheel that users install.
|
||||
# Run inside Alpine so dependency resolution exercises the pinned
|
||||
# runtime wheel on the same Linux wheel family that CI installs.
|
||||
docker run --rm \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
-e HOME=/tmp/codex-python-sdk-home \
|
||||
-e UV_LINK_MODE=copy \
|
||||
-v "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}" \
|
||||
-w "${GITHUB_WORKSPACE}/sdk/python" \
|
||||
python:3.12-slim \
|
||||
python:3.12-alpine \
|
||||
sh -euxc '
|
||||
python -m venv /tmp/uv
|
||||
/tmp/uv/bin/python -m pip install uv==0.11.3
|
||||
|
||||
22
.github/workflows/v8-canary.yml
vendored
22
.github/workflows/v8-canary.yml
vendored
@@ -5,7 +5,6 @@ on:
|
||||
paths:
|
||||
- ".bazelrc"
|
||||
- ".github/actions/setup-bazel-ci/**"
|
||||
- ".github/scripts/run_bazel_with_buildbuddy.py"
|
||||
- ".github/scripts/rusty_v8_bazel.py"
|
||||
- ".github/scripts/rusty_v8_module_bazel.py"
|
||||
- ".github/workflows/rusty-v8-release.yml"
|
||||
@@ -24,7 +23,6 @@ on:
|
||||
paths:
|
||||
- ".bazelrc"
|
||||
- ".github/actions/setup-bazel-ci/**"
|
||||
- ".github/scripts/run_bazel_with_buildbuddy.py"
|
||||
- ".github/scripts/rusty_v8_bazel.py"
|
||||
- ".github/scripts/rusty_v8_module_bazel.py"
|
||||
- ".github/workflows/rusty-v8-release.yml"
|
||||
@@ -39,11 +37,6 @@ on:
|
||||
- "third_party/v8/**"
|
||||
workflow_dispatch:
|
||||
|
||||
# Cargo's libgit2 transport has been flaky when fetching git dependencies with
|
||||
# nested submodules. Prefer the system git CLI for Cargo builds and smoke tests.
|
||||
env:
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}::${{ github.event.pull_request.number > 0 && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}
|
||||
cancel-in-progress: ${{ github.ref_name != 'main' }}
|
||||
@@ -173,9 +166,9 @@ jobs:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Set up Rust toolchain for Cargo smoke
|
||||
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
toolchain: "1.95.0"
|
||||
toolchain: "1.93.0"
|
||||
|
||||
- name: Build Bazel V8 release pair
|
||||
env:
|
||||
@@ -205,10 +198,11 @@ jobs:
|
||||
bazel_args+=(--config=v8-release-compat)
|
||||
fi
|
||||
|
||||
./.github/scripts/run_bazel_with_buildbuddy.py \
|
||||
bazel \
|
||||
--noexperimental_remote_repo_contents_cache \
|
||||
"${bazel_args[@]}" \
|
||||
"--config=${{ matrix.bazel_config }}"
|
||||
"--config=${{ matrix.bazel_config }}" \
|
||||
"--remote_header=x-buildbuddy-api-key=${BUILDBUDDY_API_KEY}"
|
||||
|
||||
- name: Stage release pair
|
||||
env:
|
||||
@@ -316,9 +310,9 @@ jobs:
|
||||
architecture: x64
|
||||
|
||||
- name: Set up Codex Rust toolchain for Cargo smoke
|
||||
uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
with:
|
||||
toolchain: "1.95.0"
|
||||
toolchain: "1.93.0"
|
||||
targets: ${{ matrix.target }}
|
||||
|
||||
- name: Install rusty_v8 Rust toolchain
|
||||
@@ -407,7 +401,7 @@ jobs:
|
||||
cd codex-rs
|
||||
RUSTY_V8_ARCHIVE="${GITHUB_WORKSPACE}/${archive}" \
|
||||
RUSTY_V8_SRC_BINDING_PATH="${GITHUB_WORKSPACE}/${binding}" \
|
||||
cargo +1.95.0 test -p codex-v8-poc --target "${TARGET}" --features sandbox --no-run
|
||||
cargo +1.93.0 test -p codex-v8-poc --target "${TARGET}" --features sandbox --no-run
|
||||
)
|
||||
|
||||
- name: Upload staged artifacts
|
||||
|
||||
1
.vscode/extensions.json
vendored
1
.vscode/extensions.json
vendored
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"BazelBuild.vscode-bazel",
|
||||
"rust-lang.rust-analyzer",
|
||||
"charliermarsh.ruff",
|
||||
"tamasfe.even-better-toml",
|
||||
|
||||
67
AGENTS.md
67
AGENTS.md
@@ -55,7 +55,7 @@ In the codex-rs folder where the rust code lives:
|
||||
trivial; prefer new modules/files and keep `chatwidget.rs` focused on orchestration.
|
||||
- When running Rust commands (e.g. `just fix` or `just test`) be patient with the command and never try to kill them using the PID. Rust lock can make the execution slow, this is expected.
|
||||
|
||||
Run `just fmt` (in the `codex-rs` directory) automatically after you have finished making code changes anywhere in this repository; do not ask for approval to run it. Additionally, run the tests:
|
||||
Run `just fmt` (in `codex-rs` directory) automatically after you have finished making Rust code changes; do not ask for approval to run it. Additionally, run the tests:
|
||||
|
||||
1. Do not run `cargo test` directly. Use `just test` so test execution follows the repo defaults.
|
||||
2. Run the test for the specific project that was changed. For example, if changes were made in `codex-rs/tui`, run `just test -p codex-tui`.
|
||||
@@ -76,49 +76,6 @@ Particularly when introducing a new concept/feature/API, before adding to `codex
|
||||
|
||||
Likewise, when reviewing code, do not hesitate to push back on PRs that would unnecessarily add code to `codex-core`.
|
||||
|
||||
## Code Review Rules
|
||||
|
||||
### Model visible context
|
||||
|
||||
Codex maintains a context (history of messages) that is sent to the model in inference requests.
|
||||
|
||||
1. No history rewrite - the context must be built up incrementally.
|
||||
2. Avoid frequent changes to context that cause cache misses.
|
||||
3. No unbounded items - everything injected in the model context must have a bounded size and a hard cap.
|
||||
4. No items larger than 10K tokens.
|
||||
5. Highlight new individual items that can cross >1k tokens as P0. These need an additional manual review.
|
||||
6. All injected fragments must be defined as structs in `core/context` and implement ContextualUserFragment trait
|
||||
|
||||
### Breaking changes
|
||||
|
||||
Search for breaking changes in external integration surfaces:
|
||||
|
||||
- app-server APIs
|
||||
- CLI parameters
|
||||
- configuration loading
|
||||
- resuming sessions from existing rollouts
|
||||
|
||||
### Test authoring guidance
|
||||
|
||||
For agent changes prefer integration tests over unit tests. Integration tests are under `core/suite` and use `test_codex` to set up a test instance of codex.
|
||||
|
||||
Features that change the agent logic MUST add an integration test:
|
||||
|
||||
- Provide a list of major logic changes and user-facing behaviors that need to be tested.
|
||||
|
||||
If unit tests are needed, put them in a dedicated test file (\*\_tests.rs).
|
||||
Avoid test-only functions in the main implementation.
|
||||
|
||||
Check whether there are existing helpers to make tests more streamlined and readable.
|
||||
|
||||
### Change size guidance (800 lines)
|
||||
|
||||
Unless the change is mechanical the total number of changed lines should not exceed 800 lines.
|
||||
For complex logic changes the size should be under 500 lines.
|
||||
|
||||
If the change is larger, explore whether it can be split into reviewable stages and identify the smallest coherent stage to land first.
|
||||
Base the staging suggestion on the actual diff, dependencies, and affected call sites.
|
||||
|
||||
## TUI style conventions
|
||||
|
||||
See `codex-rs/tui/styles.md`.
|
||||
@@ -153,19 +110,6 @@ See `codex-rs/tui/styles.md`.
|
||||
|
||||
## Tests
|
||||
|
||||
### Test module organization
|
||||
|
||||
- When adding a new test module, define its contents in a separate sibling file rather than inline in the implementation file.
|
||||
- Use an explicit `#[path = "..._tests.rs"]` attribute so the test filename is descriptive and easy to locate:
|
||||
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
#[path = "parser_tests.rs"]
|
||||
mod tests;
|
||||
```
|
||||
|
||||
- This applies only when introducing a new test module. Do not move or rewrite existing inline `#[cfg(test)] mod tests { ... }` modules solely to follow this convention.
|
||||
|
||||
### Snapshot tests
|
||||
|
||||
This repo uses snapshot tests (via `insta`), especially in `codex-rs/tui`, to validate rendered output.
|
||||
@@ -275,12 +219,3 @@ These guidelines apply to app-server protocol work in `codex-rs`, especially:
|
||||
- Validate with `just test -p codex-app-server-protocol`.
|
||||
- Avoid boilerplate tests that only assert experimental field markers for individual
|
||||
request fields in `common.rs`; rely on schema generation/tests and behavioral coverage instead.
|
||||
|
||||
## Python Development Best Practices
|
||||
|
||||
### Ignore Python 2 compatibility
|
||||
|
||||
This project uses Python 3+. You should not use the `__future__` module.
|
||||
|
||||
If you need to worry about feature compatibility between different 3.xx point releases, check the
|
||||
closest `pyproject.toml`'s `requires-python` field to see what minimum runtime version is supported.
|
||||
|
||||
@@ -163,7 +163,7 @@ use_repo(nightly_rust, "rust_toolchains")
|
||||
toolchains = use_extension("@rules_rs//rs/experimental/toolchains:module_extension.bzl", "toolchains")
|
||||
toolchains.toolchain(
|
||||
edition = "2024",
|
||||
version = "1.95.0",
|
||||
version = "1.93.0",
|
||||
)
|
||||
use_repo(toolchains, "default_rust_toolchains")
|
||||
|
||||
|
||||
280
MODULE.bazel.lock
generated
280
MODULE.bazel.lock
generated
File diff suppressed because one or more lines are too long
2
codex-rs/.github/workflows/cargo-audit.yml
vendored
2
codex-rs/.github/workflows/cargo-audit.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
working-directory: codex-rs
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@e081816240890017053eacbb1bdf337761dc5582 # 1.95.0
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
- name: Install cargo-audit
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
|
||||
975
codex-rs/Cargo.lock
generated
975
codex-rs/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@ members = [
|
||||
"app-server-client",
|
||||
"app-server-protocol",
|
||||
"app-server-test-client",
|
||||
"debug-client",
|
||||
"apply-patch",
|
||||
"arg0",
|
||||
"feedback",
|
||||
@@ -21,7 +22,7 @@ members = [
|
||||
"install-context",
|
||||
"codex-backend-openapi-models",
|
||||
"code-mode",
|
||||
"cloud-config",
|
||||
"cloud-requirements",
|
||||
"cloud-tasks",
|
||||
"cloud-tasks-client",
|
||||
"cloud-tasks-mock-client",
|
||||
@@ -46,9 +47,7 @@ members = [
|
||||
"ext/extension-api",
|
||||
"ext/goal",
|
||||
"ext/guardian",
|
||||
"ext/image-generation",
|
||||
"ext/memories",
|
||||
"ext/skills",
|
||||
"ext/web-search",
|
||||
"external-agent-migration",
|
||||
"external-agent-sessions",
|
||||
@@ -69,7 +68,6 @@ members = [
|
||||
"process-hardening",
|
||||
"protocol",
|
||||
"realtime-webrtc",
|
||||
"prompts",
|
||||
"rollout",
|
||||
"rollout-trace",
|
||||
"rmcp-client",
|
||||
@@ -150,7 +148,7 @@ codex-chatgpt = { path = "chatgpt" }
|
||||
codex-cli = { path = "cli" }
|
||||
codex-client = { path = "codex-client" }
|
||||
codex-collaboration-mode-templates = { path = "collaboration-mode-templates" }
|
||||
codex-cloud-config = { path = "cloud-config" }
|
||||
codex-cloud-requirements = { path = "cloud-requirements" }
|
||||
codex-cloud-tasks-client = { path = "cloud-tasks-client" }
|
||||
codex-cloud-tasks-mock-client = { path = "cloud-tasks-mock-client" }
|
||||
codex-code-mode = { path = "code-mode" }
|
||||
@@ -167,7 +165,6 @@ codex-execpolicy = { path = "execpolicy" }
|
||||
codex-extension-api = { path = "ext/extension-api" }
|
||||
codex-goal-extension = { path = "ext/goal" }
|
||||
codex-guardian = { path = "ext/guardian" }
|
||||
codex-image-generation-extension = { path = "ext/image-generation" }
|
||||
codex-external-agent-migration = { path = "external-agent-migration" }
|
||||
codex-external-agent-sessions = { path = "external-agent-sessions" }
|
||||
codex-experimental-api-macros = { path = "codex-experimental-api-macros" }
|
||||
@@ -199,7 +196,6 @@ codex-model-provider = { path = "model-provider" }
|
||||
codex-process-hardening = { path = "process-hardening" }
|
||||
codex-protocol = { path = "protocol" }
|
||||
codex-realtime-webrtc = { path = "realtime-webrtc" }
|
||||
codex-prompts = { path = "prompts" }
|
||||
codex-responses-api-proxy = { path = "responses-api-proxy" }
|
||||
codex-response-debug-context = { path = "response-debug-context" }
|
||||
codex-rmcp-client = { path = "rmcp-client" }
|
||||
@@ -346,7 +342,7 @@ rcgen = { version = "0.14.7", default-features = false, features = [
|
||||
regex = "1.12.3"
|
||||
regex-lite = "0.1.8"
|
||||
reqwest = { version = "0.12", features = ["cookies"] }
|
||||
rmcp = { version = "1.7.0", default-features = false }
|
||||
rmcp = { version = "0.15.0", default-features = false }
|
||||
runfiles = { git = "https://github.com/dzbarsky/rules_rust", rev = "b56cbaa8465e74127f1ea216f813cd377295ad81" }
|
||||
rustls = { version = "0.23", default-features = false, features = [
|
||||
"ring",
|
||||
@@ -370,14 +366,13 @@ sha2 = "0.10"
|
||||
shlex = "1.3.0"
|
||||
similar = "2.7.0"
|
||||
socket2 = "0.6.1"
|
||||
sqlx = { version = "0.9.0", default-features = false, features = [
|
||||
sqlx = { version = "0.8.6", default-features = false, features = [
|
||||
"chrono",
|
||||
"json",
|
||||
"macros",
|
||||
"migrate",
|
||||
"runtime-tokio",
|
||||
"tls-rustls",
|
||||
"sqlite-bundled",
|
||||
"runtime-tokio-rustls",
|
||||
"sqlite",
|
||||
"time",
|
||||
"uuid",
|
||||
] }
|
||||
@@ -520,6 +515,10 @@ inherits = "test"
|
||||
opt-level = 0
|
||||
|
||||
[patch.crates-io]
|
||||
# TODO(sqlite-wal-reset): Use a pinned external sqlx-sqlite 0.8.6 patch that
|
||||
# permits libsqlite3-sys 0.37.0 (bundled SQLite 3.51.3+) once its owning
|
||||
# repository is selected. Pooled WAL-mode state DBs remain exposed while
|
||||
# bundled SQLite 3.46.0 is shipped.
|
||||
# Uncomment to debug local changes.
|
||||
# ratatui = { path = "../../ratatui" }
|
||||
crossterm = { git = "https://github.com/nornagon/crossterm", rev = "87db8bfa6dc99427fd3b071681b07fc31c6ce995" }
|
||||
|
||||
@@ -34,7 +34,6 @@ const AGENT_TASK_REGISTRATION_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
const AGENT_IDENTITY_JWKS_TIMEOUT: Duration = Duration::from_secs(10);
|
||||
const AGENT_IDENTITY_JWT_AUDIENCE: &str = "codex-app-server";
|
||||
const AGENT_IDENTITY_JWT_ISSUER: &str = "https://chatgpt.com/codex-backend/agent-identity";
|
||||
const AGENT_REGISTRATION_TIMEOUT: Duration = Duration::from_secs(15);
|
||||
|
||||
/// Stored key material for a registered agent identity.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
@@ -50,133 +49,6 @@ pub struct AgentTaskAuthorizationTarget<'a> {
|
||||
pub task_id: &'a str,
|
||||
}
|
||||
|
||||
/// Runtime identity that owns one or more registered agent tasks.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct AgentRuntimeId(String);
|
||||
|
||||
impl AgentRuntimeId {
|
||||
pub fn new(agent_runtime_id: impl Into<String>) -> Self {
|
||||
Self(agent_runtime_id.into())
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn into_string(self) -> String {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for AgentRuntimeId {
|
||||
fn from(agent_runtime_id: String) -> Self {
|
||||
Self::new(agent_runtime_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for AgentRuntimeId {
|
||||
fn from(agent_runtime_id: &str) -> Self {
|
||||
Self::new(agent_runtime_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Task identifier granted to an agent runtime for a scoped objective.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct AgentTaskId(String);
|
||||
|
||||
impl AgentTaskId {
|
||||
pub fn new(task_id: impl Into<String>) -> Self {
|
||||
Self(task_id.into())
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn into_string(self) -> String {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for AgentTaskId {
|
||||
fn from(task_id: String) -> Self {
|
||||
Self::new(task_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for AgentTaskId {
|
||||
fn from(task_id: &str) -> Self {
|
||||
Self::new(task_id)
|
||||
}
|
||||
}
|
||||
|
||||
/// Caller-owned stable reference that HAI can resolve to an opaque task id.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
pub struct AgentTaskExternalRef(String);
|
||||
|
||||
impl AgentTaskExternalRef {
|
||||
pub fn new(external_ref: impl Into<String>) -> Self {
|
||||
Self(external_ref.into())
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn into_string(self) -> String {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for AgentTaskExternalRef {
|
||||
fn from(external_ref: String) -> Self {
|
||||
Self::new(external_ref)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for AgentTaskExternalRef {
|
||||
fn from(external_ref: &str) -> Self {
|
||||
Self::new(external_ref)
|
||||
}
|
||||
}
|
||||
|
||||
/// Purpose of a registered task binding.
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AgentTaskKind {
|
||||
Thread,
|
||||
Background,
|
||||
}
|
||||
|
||||
/// Registered task binding used to authorize work for an agent runtime.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct RegisteredAgentTask {
|
||||
pub agent_runtime_id: AgentRuntimeId,
|
||||
pub task_id: AgentTaskId,
|
||||
pub kind: AgentTaskKind,
|
||||
}
|
||||
|
||||
impl RegisteredAgentTask {
|
||||
pub fn new(
|
||||
agent_runtime_id: impl Into<AgentRuntimeId>,
|
||||
task_id: impl Into<AgentTaskId>,
|
||||
kind: AgentTaskKind,
|
||||
) -> Self {
|
||||
Self {
|
||||
agent_runtime_id: agent_runtime_id.into(),
|
||||
task_id: task_id.into(),
|
||||
kind,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn authorization_target(&self) -> AgentTaskAuthorizationTarget<'_> {
|
||||
AgentTaskAuthorizationTarget {
|
||||
agent_runtime_id: self.agent_runtime_id.as_str(),
|
||||
task_id: self.task_id.as_str(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct AgentBillOfMaterials {
|
||||
pub agent_version: String,
|
||||
@@ -214,11 +86,9 @@ struct AgentAssertionEnvelope {
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct RegisterTaskRequest<'a> {
|
||||
struct RegisterTaskRequest {
|
||||
timestamp: String,
|
||||
signature: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
external_task_ref: Option<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -233,18 +103,6 @@ struct RegisterTaskResponse {
|
||||
encrypted_task_id_camel: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct RegisterAgentRequest {
|
||||
abom: AgentBillOfMaterials,
|
||||
agent_public_key: String,
|
||||
capabilities: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct RegisterAgentResponse {
|
||||
agent_runtime_id: String,
|
||||
}
|
||||
|
||||
pub fn authorization_header_for_agent_task(
|
||||
key: AgentIdentityKey<'_>,
|
||||
target: AgentTaskAuthorizationTarget<'_>,
|
||||
@@ -267,13 +125,6 @@ pub fn authorization_header_for_agent_task(
|
||||
Ok(format!("AgentAssertion {serialized_assertion}"))
|
||||
}
|
||||
|
||||
pub fn authorization_header_for_registered_task(
|
||||
key: AgentIdentityKey<'_>,
|
||||
task: &RegisteredAgentTask,
|
||||
) -> Result<String> {
|
||||
authorization_header_for_agent_task(key, task.authorization_target())
|
||||
}
|
||||
|
||||
pub async fn fetch_agent_identity_jwks(
|
||||
client: &reqwest::Client,
|
||||
chatgpt_base_url: &str,
|
||||
@@ -346,22 +197,11 @@ pub async fn register_agent_task(
|
||||
client: &reqwest::Client,
|
||||
chatgpt_base_url: &str,
|
||||
key: AgentIdentityKey<'_>,
|
||||
) -> Result<String> {
|
||||
register_agent_task_with_external_ref(client, chatgpt_base_url, key, /*external_ref*/ None)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn register_agent_task_with_external_ref(
|
||||
client: &reqwest::Client,
|
||||
chatgpt_base_url: &str,
|
||||
key: AgentIdentityKey<'_>,
|
||||
external_ref: Option<&AgentTaskExternalRef>,
|
||||
) -> Result<String> {
|
||||
let timestamp = Utc::now().to_rfc3339_opts(SecondsFormat::Secs, true);
|
||||
let request = RegisterTaskRequest {
|
||||
signature: sign_task_registration_payload(key, ×tamp)?,
|
||||
timestamp,
|
||||
external_task_ref: external_ref.map(AgentTaskExternalRef::as_str),
|
||||
};
|
||||
let url = agent_task_registration_url(chatgpt_base_url, key.agent_runtime_id);
|
||||
|
||||
@@ -391,45 +231,6 @@ pub async fn register_agent_task_with_external_ref(
|
||||
task_id_from_register_task_response(key, response)
|
||||
}
|
||||
|
||||
pub async fn register_agent_identity(
|
||||
client: &reqwest::Client,
|
||||
chatgpt_base_url: &str,
|
||||
access_token: &str,
|
||||
account_id: &str,
|
||||
is_fedramp_account: bool,
|
||||
key_material: &GeneratedAgentKeyMaterial,
|
||||
abom: AgentBillOfMaterials,
|
||||
) -> Result<AgentRuntimeId> {
|
||||
let url = agent_registration_url(chatgpt_base_url);
|
||||
let request = RegisterAgentRequest {
|
||||
abom,
|
||||
agent_public_key: key_material.public_key_ssh.clone(),
|
||||
capabilities: Vec::new(),
|
||||
};
|
||||
|
||||
let mut request_builder = client
|
||||
.post(&url)
|
||||
.bearer_auth(access_token)
|
||||
.header("ChatGPT-Account-ID", account_id)
|
||||
.json(&request)
|
||||
.timeout(AGENT_REGISTRATION_TIMEOUT);
|
||||
if is_fedramp_account {
|
||||
request_builder = request_builder.header("X-OpenAI-Fedramp", "true");
|
||||
}
|
||||
|
||||
let response = request_builder
|
||||
.send()
|
||||
.await
|
||||
.with_context(|| format!("failed to send agent identity registration request to {url}"))?
|
||||
.error_for_status()
|
||||
.with_context(|| format!("agent identity registration failed for {url}"))?
|
||||
.json::<RegisterAgentResponse>()
|
||||
.await
|
||||
.with_context(|| format!("failed to parse agent identity response from {url}"))?;
|
||||
|
||||
Ok(AgentRuntimeId::new(response.agent_runtime_id))
|
||||
}
|
||||
|
||||
fn task_id_from_register_task_response(
|
||||
key: AgentIdentityKey<'_>,
|
||||
response: RegisterTaskResponse,
|
||||
@@ -505,6 +306,11 @@ pub fn agent_task_registration_url(chatgpt_base_url: &str, agent_runtime_id: &st
|
||||
format!("{trimmed}/v1/agent/{agent_runtime_id}/task/register")
|
||||
}
|
||||
|
||||
pub fn agent_identity_biscuit_url(chatgpt_base_url: &str) -> String {
|
||||
let trimmed = chatgpt_base_url.trim_end_matches('/');
|
||||
format!("{trimmed}/authenticate_app_v2")
|
||||
}
|
||||
|
||||
pub fn agent_identity_jwks_url(chatgpt_base_url: &str) -> String {
|
||||
let trimmed = chatgpt_base_url.trim_end_matches('/');
|
||||
if trimmed.contains("/backend-api") {
|
||||
@@ -514,27 +320,15 @@ pub fn agent_identity_jwks_url(chatgpt_base_url: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn normalize_chatgpt_base_url(chatgpt_base_url: &str) -> String {
|
||||
let mut base_url = chatgpt_base_url.trim_end_matches('/').to_string();
|
||||
for suffix in [
|
||||
"/wham/remote/control/server/enroll",
|
||||
"/wham/remote/control/server",
|
||||
] {
|
||||
if let Some(stripped) = base_url.strip_suffix(suffix) {
|
||||
base_url = stripped.to_string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(stripped) = base_url.strip_suffix("/codex") {
|
||||
base_url = stripped.to_string();
|
||||
}
|
||||
if (base_url.starts_with("https://chatgpt.com")
|
||||
|| base_url.starts_with("https://chat.openai.com"))
|
||||
&& !base_url.contains("/backend-api")
|
||||
{
|
||||
base_url = format!("{base_url}/backend-api");
|
||||
}
|
||||
base_url
|
||||
pub fn agent_identity_request_id() -> Result<String> {
|
||||
let mut request_id_bytes = [0u8; 16];
|
||||
OsRng
|
||||
.try_fill_bytes(&mut request_id_bytes)
|
||||
.context("failed to generate agent identity request id")?;
|
||||
Ok(format!(
|
||||
"codex-agent-identity-{}",
|
||||
URL_SAFE_NO_PAD.encode(request_id_bytes)
|
||||
))
|
||||
}
|
||||
|
||||
pub fn build_abom(session_source: SessionSource) -> AgentBillOfMaterials {
|
||||
@@ -618,63 +412,6 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn registered_agent_task_builds_authorization_target() {
|
||||
let task = RegisteredAgentTask::new(
|
||||
"agent-runtime-123",
|
||||
"task-thread-456",
|
||||
AgentTaskKind::Thread,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
task.authorization_target(),
|
||||
AgentTaskAuthorizationTarget {
|
||||
agent_runtime_id: "agent-runtime-123",
|
||||
task_id: "task-thread-456",
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_task_request_omits_external_ref_by_default() {
|
||||
let request = RegisterTaskRequest {
|
||||
timestamp: "2026-04-23T00:00:00Z".to_string(),
|
||||
signature: "signature".to_string(),
|
||||
external_task_ref: None,
|
||||
};
|
||||
|
||||
let serialized = serde_json::to_value(request).expect("serialize request");
|
||||
|
||||
assert_eq!(
|
||||
serialized,
|
||||
serde_json::json!({
|
||||
"timestamp": "2026-04-23T00:00:00Z",
|
||||
"signature": "signature",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn register_task_request_includes_external_ref_when_provided() {
|
||||
let external_ref = AgentTaskExternalRef::new("thread-123");
|
||||
let request = RegisterTaskRequest {
|
||||
timestamp: "2026-04-23T00:00:00Z".to_string(),
|
||||
signature: "signature".to_string(),
|
||||
external_task_ref: Some(external_ref.as_str()),
|
||||
};
|
||||
|
||||
let serialized = serde_json::to_value(request).expect("serialize request");
|
||||
|
||||
assert_eq!(
|
||||
serialized,
|
||||
serde_json::json!({
|
||||
"timestamp": "2026-04-23T00:00:00Z",
|
||||
"signature": "signature",
|
||||
"external_task_ref": "thread-123",
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authorization_header_for_agent_task_serializes_signed_agent_assertion() {
|
||||
let signing_key = SigningKey::from_bytes(&[7u8; 32]);
|
||||
@@ -752,41 +489,6 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn authorization_header_for_registered_task_uses_existing_wire_shape() {
|
||||
let signing_key = SigningKey::from_bytes(&[7u8; 32]);
|
||||
let private_key = signing_key
|
||||
.to_pkcs8_der()
|
||||
.expect("encode test key material");
|
||||
let private_key_pkcs8_base64 = BASE64_STANDARD.encode(private_key.as_bytes());
|
||||
let key = AgentIdentityKey {
|
||||
agent_runtime_id: "agent-123",
|
||||
private_key_pkcs8_base64: &private_key_pkcs8_base64,
|
||||
};
|
||||
let task = RegisteredAgentTask::new("agent-123", "task-123", AgentTaskKind::Background);
|
||||
|
||||
let header = authorization_header_for_registered_task(key, &task)
|
||||
.expect("build registered task assertion header");
|
||||
let token = header
|
||||
.strip_prefix("AgentAssertion ")
|
||||
.expect("agent assertion scheme");
|
||||
let payload = URL_SAFE_NO_PAD
|
||||
.decode(token)
|
||||
.expect("valid base64url payload");
|
||||
let envelope: AgentAssertionEnvelope =
|
||||
serde_json::from_slice(&payload).expect("valid assertion envelope");
|
||||
|
||||
assert_eq!(
|
||||
envelope,
|
||||
AgentAssertionEnvelope {
|
||||
agent_runtime_id: "agent-123".to_string(),
|
||||
task_id: "task-123".to_string(),
|
||||
timestamp: envelope.timestamp.clone(),
|
||||
signature: envelope.signature.clone(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn decode_agent_identity_jwt_reads_claims() {
|
||||
let jwt = jwt_with_payload(serde_json::json!({
|
||||
@@ -1001,14 +703,6 @@ J1bwkqKZTB5dHolX9A58e/xXnfZ5P8f3Z83+Izap3FwqQulk7b1WO1MQcHuVg2NN
|
||||
.expect("test JWKS should parse")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn normalize_chatgpt_base_url_strips_codex_before_backend_api() {
|
||||
assert_eq!(
|
||||
normalize_chatgpt_base_url("https://chatgpt.com/codex"),
|
||||
"https://chatgpt.com/backend-api"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn agent_identity_jwks_url_uses_backend_api_base_url() {
|
||||
assert_eq!(
|
||||
|
||||
@@ -62,7 +62,6 @@ use crate::facts::SkillInvokedInput;
|
||||
use crate::facts::SubAgentThreadStartedInput;
|
||||
use crate::facts::ThreadInitializationMode;
|
||||
use crate::facts::TrackEventsContext;
|
||||
use crate::facts::TurnCodexErrorFact;
|
||||
use crate::facts::TurnResolvedConfigFact;
|
||||
use crate::facts::TurnStatus;
|
||||
use crate::facts::TurnSteerRequestError;
|
||||
@@ -133,7 +132,6 @@ use codex_plugin::PluginTelemetryMetadata;
|
||||
use codex_protocol::approvals::NetworkApprovalProtocol;
|
||||
use codex_protocol::config_types::ApprovalsReviewer;
|
||||
use codex_protocol::config_types::ModeKind;
|
||||
use codex_protocol::error::CodexErr;
|
||||
use codex_protocol::models::NetworkPermissions as CoreNetworkPermissions;
|
||||
use codex_protocol::models::PermissionProfile as CorePermissionProfile;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
@@ -162,13 +160,11 @@ fn sample_thread_with_metadata(
|
||||
ephemeral: bool,
|
||||
source: AppServerSessionSource,
|
||||
thread_source: Option<AppServerThreadSource>,
|
||||
parent_thread_id: Option<String>,
|
||||
) -> Thread {
|
||||
Thread {
|
||||
id: thread_id.to_string(),
|
||||
session_id: format!("session-{thread_id}"),
|
||||
forked_from_id: None,
|
||||
parent_thread_id,
|
||||
preview: "first prompt".to_string(),
|
||||
ephemeral,
|
||||
model_provider: "openai".to_string(),
|
||||
@@ -199,7 +195,6 @@ fn sample_thread_start_response(
|
||||
ephemeral,
|
||||
AppServerSessionSource::Exec,
|
||||
Some(AppServerThreadSource::User),
|
||||
/*parent_thread_id*/ None,
|
||||
),
|
||||
model: model.to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
@@ -245,7 +240,6 @@ fn sample_thread_resume_response(
|
||||
model,
|
||||
AppServerSessionSource::Exec,
|
||||
Some(AppServerThreadSource::User),
|
||||
/*parent_thread_id*/ None,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -255,16 +249,9 @@ fn sample_thread_resume_response_with_source(
|
||||
model: &str,
|
||||
source: AppServerSessionSource,
|
||||
thread_source: Option<AppServerThreadSource>,
|
||||
parent_thread_id: Option<String>,
|
||||
) -> ClientResponsePayload {
|
||||
ClientResponsePayload::ThreadResume(ThreadResumeResponse {
|
||||
thread: sample_thread_with_metadata(
|
||||
thread_id,
|
||||
ephemeral,
|
||||
source,
|
||||
thread_source,
|
||||
parent_thread_id,
|
||||
),
|
||||
thread: sample_thread_with_metadata(thread_id, ephemeral, source, thread_source),
|
||||
model: model.to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
service_tier: None,
|
||||
@@ -276,7 +263,6 @@ fn sample_thread_resume_response_with_source(
|
||||
sandbox: AppServerSandboxPolicy::DangerFullAccess,
|
||||
active_permission_profile: None,
|
||||
reasoning_effort: None,
|
||||
initial_turns_page: None,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -285,7 +271,6 @@ fn sample_turn_start_request(thread_id: &str, request_id: i64) -> ClientRequest
|
||||
request_id: RequestId::Integer(request_id),
|
||||
params: TurnStartParams {
|
||||
thread_id: thread_id.to_string(),
|
||||
client_user_message_id: None,
|
||||
input: vec![
|
||||
UserInput::Text {
|
||||
text: "hello".to_string(),
|
||||
@@ -391,7 +376,6 @@ fn sample_turn_resolved_config(thread_id: &str, turn_id: &str) -> TurnResolvedCo
|
||||
sandbox_network_access: true,
|
||||
collaboration_mode: ModeKind::Plan,
|
||||
personality: None,
|
||||
workspace_kind: None,
|
||||
is_first_turn: true,
|
||||
}
|
||||
}
|
||||
@@ -406,7 +390,6 @@ fn sample_turn_steer_request(
|
||||
params: TurnSteerParams {
|
||||
thread_id: thread_id.to_string(),
|
||||
expected_turn_id: expected_turn_id.to_string(),
|
||||
client_user_message_id: None,
|
||||
input: vec![
|
||||
UserInput::Text {
|
||||
text: "more".to_string(),
|
||||
@@ -418,7 +401,6 @@ fn sample_turn_steer_request(
|
||||
},
|
||||
],
|
||||
responsesapi_client_metadata: None,
|
||||
additional_context: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -836,7 +818,6 @@ fn sample_permissions_approval_request(request_id: i64) -> ServerRequest {
|
||||
thread_id: "thread-1".to_string(),
|
||||
turn_id: "turn-1".to_string(),
|
||||
item_id: "permissions-1".to_string(),
|
||||
environment_id: None,
|
||||
started_at_ms: 1_000,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
reason: Some("need network".to_string()),
|
||||
@@ -1231,7 +1212,6 @@ fn compaction_event_serializes_expected_shape() {
|
||||
completed_at: 106,
|
||||
duration_ms: Some(6543),
|
||||
},
|
||||
"session-thread-1".to_string(),
|
||||
sample_app_server_client_metadata(),
|
||||
sample_runtime_metadata(),
|
||||
Some(ThreadSource::User),
|
||||
@@ -1248,7 +1228,6 @@ fn compaction_event_serializes_expected_shape() {
|
||||
"event_type": "codex_compaction_event",
|
||||
"event_params": {
|
||||
"thread_id": "thread-1",
|
||||
"session_id": "session-thread-1",
|
||||
"turn_id": "turn-1",
|
||||
"app_server_client": {
|
||||
"product_client_id": DEFAULT_ORIGINATOR,
|
||||
@@ -1327,7 +1306,6 @@ fn thread_initialized_event_serializes_expected_shape() {
|
||||
event_type: "codex_thread_initialized",
|
||||
event_params: ThreadInitializedEventParams {
|
||||
thread_id: "thread-0".to_string(),
|
||||
session_id: "session-thread-0".to_string(),
|
||||
app_server_client: CodexAppServerClientMetadata {
|
||||
product_client_id: DEFAULT_ORIGINATOR.to_string(),
|
||||
client_name: Some("codex-tui".to_string()),
|
||||
@@ -1359,7 +1337,6 @@ fn thread_initialized_event_serializes_expected_shape() {
|
||||
"event_type": "codex_thread_initialized",
|
||||
"event_params": {
|
||||
"thread_id": "thread-0",
|
||||
"session_id": "session-thread-0",
|
||||
"app_server_client": {
|
||||
"product_client_id": DEFAULT_ORIGINATOR,
|
||||
"client_name": "codex-tui",
|
||||
@@ -1627,7 +1604,6 @@ async fn initialize_caches_client_and_thread_lifecycle_publishes_once_initialize
|
||||
let payload = serde_json::to_value(&events).expect("serialize events");
|
||||
assert_eq!(payload.as_array().expect("events array").len(), 1);
|
||||
assert_eq!(payload[0]["event_type"], "codex_thread_initialized");
|
||||
assert_eq!(payload[0]["event_params"]["session_id"], "session-thread-1");
|
||||
assert_eq!(
|
||||
payload[0]["event_params"]["app_server_client"]["product_client_id"],
|
||||
DEFAULT_ORIGINATOR
|
||||
@@ -1770,7 +1746,6 @@ async fn compaction_event_ingests_custom_fact() {
|
||||
agent_role: None,
|
||||
}),
|
||||
Some(AppServerThreadSource::Subagent),
|
||||
Some(parent_thread_id.to_string()),
|
||||
)),
|
||||
},
|
||||
&mut events,
|
||||
@@ -1805,7 +1780,6 @@ async fn compaction_event_ingests_custom_fact() {
|
||||
let payload = serde_json::to_value(&events).expect("serialize events");
|
||||
assert_eq!(payload.as_array().expect("events array").len(), 1);
|
||||
assert_eq!(payload[0]["event_type"], "codex_compaction_event");
|
||||
assert_eq!(payload[0]["event_params"]["session_id"], "session-thread-1");
|
||||
assert_eq!(payload[0]["event_params"]["thread_id"], "thread-1");
|
||||
assert_eq!(payload[0]["event_params"]["turn_id"], "turn-compact");
|
||||
assert_eq!(
|
||||
@@ -1930,10 +1904,6 @@ async fn guardian_review_event_ingests_custom_fact_with_optional_target_item() {
|
||||
let payload = serde_json::to_value(&events).expect("serialize events");
|
||||
assert_eq!(payload.as_array().expect("events array").len(), 1);
|
||||
assert_eq!(payload[0]["event_type"], "codex_guardian_review");
|
||||
assert_eq!(
|
||||
payload[0]["event_params"]["session_id"],
|
||||
"session-thread-guardian"
|
||||
);
|
||||
assert_eq!(payload[0]["event_params"]["thread_id"], "thread-guardian");
|
||||
assert_eq!(payload[0]["event_params"]["turn_id"], "turn-guardian");
|
||||
assert_eq!(payload[0]["event_params"]["review_id"], "review-guardian");
|
||||
@@ -2426,7 +2396,6 @@ async fn item_review_summaries_do_not_cross_threads_with_reused_item_ids() {
|
||||
fn subagent_thread_started_review_serializes_expected_shape() {
|
||||
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||
SubAgentThreadStartedInput {
|
||||
session_id: "session-root".to_string(),
|
||||
thread_id: "thread-review".to_string(),
|
||||
parent_thread_id: None,
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
@@ -2470,9 +2439,8 @@ fn subagent_thread_started_thread_spawn_serializes_parent_thread_id() {
|
||||
.expect("valid thread id");
|
||||
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||
SubAgentThreadStartedInput {
|
||||
session_id: "session-root".to_string(),
|
||||
thread_id: "thread-spawn".to_string(),
|
||||
parent_thread_id: Some(parent_thread_id.to_string()),
|
||||
parent_thread_id: None,
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
client_name: "codex-tui".to_string(),
|
||||
client_version: "1.0.0".to_string(),
|
||||
@@ -2490,21 +2458,18 @@ fn subagent_thread_started_thread_spawn_serializes_parent_thread_id() {
|
||||
));
|
||||
|
||||
let payload = serde_json::to_value(&event).expect("serialize thread spawn subagent event");
|
||||
assert_eq!(payload["event_params"]["thread_id"], "thread-spawn");
|
||||
assert_eq!(payload["event_params"]["thread_source"], "subagent");
|
||||
assert_eq!(payload["event_params"]["subagent_source"], "thread_spawn");
|
||||
assert_eq!(
|
||||
payload["event_params"]["parent_thread_id"],
|
||||
"11111111-1111-1111-1111-111111111111"
|
||||
);
|
||||
assert_eq!(payload["event_params"]["session_id"], "session-root");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subagent_thread_started_memory_consolidation_serializes_expected_shape() {
|
||||
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||
SubAgentThreadStartedInput {
|
||||
session_id: "session-root".to_string(),
|
||||
thread_id: "thread-memory".to_string(),
|
||||
parent_thread_id: None,
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
@@ -2530,7 +2495,6 @@ fn subagent_thread_started_memory_consolidation_serializes_expected_shape() {
|
||||
fn subagent_thread_started_other_serializes_expected_shape() {
|
||||
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||
SubAgentThreadStartedInput {
|
||||
session_id: "session-root".to_string(),
|
||||
thread_id: "thread-guardian".to_string(),
|
||||
parent_thread_id: None,
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
@@ -2550,14 +2514,10 @@ fn subagent_thread_started_other_serializes_expected_shape() {
|
||||
|
||||
#[test]
|
||||
fn subagent_thread_started_other_serializes_explicit_parent_thread_id() {
|
||||
let parent_thread_id =
|
||||
codex_protocol::ThreadId::from_string("33333333-3333-4333-8333-333333333333")
|
||||
.expect("valid thread id");
|
||||
let event = TrackEventRequest::ThreadInitialized(subagent_thread_started_event_request(
|
||||
SubAgentThreadStartedInput {
|
||||
session_id: "session-root".to_string(),
|
||||
thread_id: "thread-guardian".to_string(),
|
||||
parent_thread_id: Some(parent_thread_id.to_string()),
|
||||
parent_thread_id: Some("parent-thread-guardian".to_string()),
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
client_name: "codex-tui".to_string(),
|
||||
client_version: "1.0.0".to_string(),
|
||||
@@ -2572,7 +2532,7 @@ fn subagent_thread_started_other_serializes_explicit_parent_thread_id() {
|
||||
assert_eq!(payload["event_params"]["subagent_source"], "guardian");
|
||||
assert_eq!(
|
||||
payload["event_params"]["parent_thread_id"],
|
||||
"33333333-3333-4333-8333-333333333333"
|
||||
"parent-thread-guardian"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2585,7 +2545,6 @@ async fn subagent_thread_started_publishes_without_initialize() {
|
||||
.ingest(
|
||||
AnalyticsFact::Custom(CustomAnalyticsFact::SubAgentThreadStarted(
|
||||
SubAgentThreadStartedInput {
|
||||
session_id: "session-root".to_string(),
|
||||
thread_id: "thread-review".to_string(),
|
||||
parent_thread_id: None,
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
@@ -2659,9 +2618,8 @@ async fn subagent_thread_started_inherits_parent_connection_for_new_thread() {
|
||||
.ingest(
|
||||
AnalyticsFact::Custom(CustomAnalyticsFact::SubAgentThreadStarted(
|
||||
SubAgentThreadStartedInput {
|
||||
session_id: "session-root".to_string(),
|
||||
thread_id: "thread-review".to_string(),
|
||||
parent_thread_id: Some(parent_thread_id.to_string()),
|
||||
parent_thread_id: None,
|
||||
product_client_id: "parent-client".to_string(),
|
||||
client_name: "parent-client".to_string(),
|
||||
client_version: "1.0.0".to_string(),
|
||||
@@ -2707,8 +2665,6 @@ async fn subagent_thread_started_inherits_parent_connection_for_new_thread() {
|
||||
.await;
|
||||
|
||||
let payload = serde_json::to_value(&events).expect("serialize events");
|
||||
assert_eq!(payload[0]["event_params"]["session_id"], "session-root");
|
||||
assert_eq!(payload[0]["event_params"]["thread_id"], "thread-review");
|
||||
assert_eq!(
|
||||
payload[0]["event_params"]["app_server_client"]["product_client_id"],
|
||||
"parent-client"
|
||||
@@ -2729,7 +2685,6 @@ async fn subagent_tool_items_inherit_parent_connection_metadata() {
|
||||
.ingest(
|
||||
AnalyticsFact::Custom(CustomAnalyticsFact::SubAgentThreadStarted(
|
||||
SubAgentThreadStartedInput {
|
||||
session_id: "session-root".to_string(),
|
||||
thread_id: "thread-subagent".to_string(),
|
||||
parent_thread_id: Some("thread-1".to_string()),
|
||||
product_client_id: "codex-tui".to_string(),
|
||||
@@ -3235,7 +3190,6 @@ fn turn_event_serializes_expected_shape() {
|
||||
event_type: "codex_turn_event",
|
||||
event_params: crate::events::CodexTurnEventParams {
|
||||
thread_id: "thread-2".to_string(),
|
||||
session_id: "session-thread-2".to_string(),
|
||||
turn_id: "turn-2".to_string(),
|
||||
app_server_client: sample_app_server_client_metadata(),
|
||||
runtime: sample_runtime_metadata(),
|
||||
@@ -3256,14 +3210,10 @@ fn turn_event_serializes_expected_shape() {
|
||||
sandbox_network_access: true,
|
||||
collaboration_mode: Some("plan"),
|
||||
personality: Some("pragmatic".to_string()),
|
||||
workspace_kind: Some("projectless".to_string()),
|
||||
num_input_images: 2,
|
||||
is_first_turn: true,
|
||||
status: Some(TurnStatus::Completed),
|
||||
turn_error: None,
|
||||
codex_error_kind: None,
|
||||
codex_error_subreason: None,
|
||||
codex_error_http_status_code: None,
|
||||
steer_count: Some(0),
|
||||
total_tool_call_count: None,
|
||||
shell_command_count: None,
|
||||
@@ -3290,7 +3240,6 @@ fn turn_event_serializes_expected_shape() {
|
||||
"event_type": "codex_turn_event",
|
||||
"event_params": {
|
||||
"thread_id": "thread-2",
|
||||
"session_id": "session-thread-2",
|
||||
"turn_id": "turn-2",
|
||||
"submission_type": null,
|
||||
"app_server_client": {
|
||||
@@ -3322,14 +3271,10 @@ fn turn_event_serializes_expected_shape() {
|
||||
"sandbox_network_access": true,
|
||||
"collaboration_mode": "plan",
|
||||
"personality": "pragmatic",
|
||||
"workspace_kind": "projectless",
|
||||
"num_input_images": 2,
|
||||
"is_first_turn": true,
|
||||
"status": "completed",
|
||||
"turn_error": null,
|
||||
"codex_error_kind": null,
|
||||
"codex_error_subreason": null,
|
||||
"codex_error_http_status_code": null,
|
||||
"steer_count": 0,
|
||||
"total_tool_call_count": null,
|
||||
"shell_command_count": null,
|
||||
@@ -3396,10 +3341,6 @@ async fn accepted_turn_steer_emits_expected_event() {
|
||||
let payload = serde_json::to_value(&out[0]).expect("serialize turn steer event");
|
||||
assert_eq!(payload["event_type"], json!("codex_turn_steer_event"));
|
||||
assert_eq!(payload["event_params"]["thread_id"], json!("thread-2"));
|
||||
assert_eq!(
|
||||
payload["event_params"]["session_id"],
|
||||
json!("session-thread-2")
|
||||
);
|
||||
assert_eq!(payload["event_params"]["expected_turn_id"], json!("turn-2"));
|
||||
assert_eq!(payload["event_params"]["accepted_turn_id"], json!("turn-2"));
|
||||
assert_eq!(payload["event_params"]["num_input_images"], json!(1));
|
||||
@@ -3617,10 +3558,6 @@ async fn turn_lifecycle_emits_turn_event() {
|
||||
let payload = serde_json::to_value(&out[0]).expect("serialize turn event");
|
||||
assert_eq!(payload["event_type"], json!("codex_turn_event"));
|
||||
assert_eq!(payload["event_params"]["thread_id"], json!("thread-2"));
|
||||
assert_eq!(
|
||||
payload["event_params"]["session_id"],
|
||||
json!("session-thread-2")
|
||||
);
|
||||
assert_eq!(payload["event_params"]["turn_id"], json!("turn-2"));
|
||||
assert_eq!(
|
||||
payload["event_params"]["app_server_client"],
|
||||
@@ -3643,7 +3580,6 @@ async fn turn_lifecycle_emits_turn_event() {
|
||||
);
|
||||
assert!(payload["event_params"].get("product_client_id").is_none());
|
||||
assert_eq!(payload["event_params"]["ephemeral"], json!(false));
|
||||
assert_eq!(payload["event_params"]["workspace_kind"], json!(null));
|
||||
assert_eq!(payload["event_params"]["num_input_images"], json!(1));
|
||||
assert_eq!(payload["event_params"]["status"], json!("completed"));
|
||||
assert_eq!(payload["event_params"]["steer_count"], json!(0));
|
||||
@@ -3996,18 +3932,6 @@ async fn turn_lifecycle_emits_failed_turn_event() {
|
||||
/*include_token_usage*/ false,
|
||||
)
|
||||
.await;
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Custom(CustomAnalyticsFact::TurnCodexError(Box::new(
|
||||
TurnCodexErrorFact::from_codex_err(
|
||||
"thread-2".to_string(),
|
||||
"turn-2".to_string(),
|
||||
&CodexErr::InvalidRequest("unknown turn environment id `env-2`".to_string()),
|
||||
),
|
||||
))),
|
||||
&mut out,
|
||||
)
|
||||
.await;
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Notification(Box::new(sample_turn_completed_notification(
|
||||
@@ -4024,18 +3948,6 @@ async fn turn_lifecycle_emits_failed_turn_event() {
|
||||
let payload = serde_json::to_value(&out[0]).expect("serialize turn event");
|
||||
assert_eq!(payload["event_params"]["status"], json!("failed"));
|
||||
assert_eq!(payload["event_params"]["turn_error"], json!("badRequest"));
|
||||
assert_eq!(
|
||||
payload["event_params"]["codex_error_kind"],
|
||||
json!("invalid_request")
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["codex_error_subreason"],
|
||||
json!("unknown turn environment id `env-2`")
|
||||
);
|
||||
assert_eq!(
|
||||
payload["event_params"]["codex_error_http_status_code"],
|
||||
json!(null)
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -4068,7 +3980,6 @@ async fn turn_lifecycle_emits_interrupted_turn_event_without_error() {
|
||||
let payload = serde_json::to_value(&out[0]).expect("serialize turn event");
|
||||
assert_eq!(payload["event_params"]["status"], json!("interrupted"));
|
||||
assert_eq!(payload["event_params"]["turn_error"], json!(null));
|
||||
assert_eq!(payload["event_params"]["codex_error_kind"], json!(null));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@@ -18,7 +18,6 @@ use crate::facts::SkillInvocation;
|
||||
use crate::facts::SkillInvokedInput;
|
||||
use crate::facts::SubAgentThreadStartedInput;
|
||||
use crate::facts::TrackEventsContext;
|
||||
use crate::facts::TurnCodexErrorFact;
|
||||
use crate::facts::TurnResolvedConfigFact;
|
||||
use crate::facts::TurnTokenUsageFact;
|
||||
use crate::reducer::AnalyticsReducer;
|
||||
@@ -257,12 +256,6 @@ impl AnalyticsEventsClient {
|
||||
)));
|
||||
}
|
||||
|
||||
pub fn track_turn_codex_error(&self, fact: TurnCodexErrorFact) {
|
||||
self.record_fact(AnalyticsFact::Custom(CustomAnalyticsFact::TurnCodexError(
|
||||
Box::new(fact),
|
||||
)));
|
||||
}
|
||||
|
||||
pub fn track_plugin_installed(&self, plugin: PluginTelemetryMetadata) {
|
||||
self.record_fact(AnalyticsFact::Custom(
|
||||
CustomAnalyticsFact::PluginStateChanged(PluginStateChangedInput {
|
||||
|
||||
@@ -89,7 +89,6 @@ fn sample_turn_start_request() -> ClientRequest {
|
||||
request_id: RequestId::Integer(1),
|
||||
params: TurnStartParams {
|
||||
thread_id: "thread-1".to_string(),
|
||||
client_user_message_id: None,
|
||||
input: Vec::new(),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -102,10 +101,8 @@ fn sample_turn_steer_request() -> ClientRequest {
|
||||
params: TurnSteerParams {
|
||||
thread_id: "thread-1".to_string(),
|
||||
expected_turn_id: "turn-1".to_string(),
|
||||
client_user_message_id: None,
|
||||
input: Vec::new(),
|
||||
responsesapi_client_metadata: None,
|
||||
additional_context: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -124,7 +121,6 @@ fn sample_thread(thread_id: &str) -> Thread {
|
||||
id: thread_id.to_string(),
|
||||
session_id: format!("session-{thread_id}"),
|
||||
forked_from_id: None,
|
||||
parent_thread_id: None,
|
||||
preview: "first prompt".to_string(),
|
||||
ephemeral: false,
|
||||
model_provider: "openai".to_string(),
|
||||
@@ -175,7 +171,6 @@ fn sample_thread_resume_response() -> ClientResponsePayload {
|
||||
sandbox: AppServerSandboxPolicy::DangerFullAccess,
|
||||
active_permission_profile: None,
|
||||
reasoning_effort: None,
|
||||
initial_turns_page: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ use std::time::Instant;
|
||||
use crate::facts::AcceptedLineFingerprint;
|
||||
use crate::facts::AppInvocation;
|
||||
use crate::facts::CodexCompactionEvent;
|
||||
use crate::facts::CodexErrKind;
|
||||
use crate::facts::CompactionImplementation;
|
||||
use crate::facts::CompactionPhase;
|
||||
use crate::facts::CompactionReason;
|
||||
@@ -148,7 +147,6 @@ pub(crate) struct CodexRuntimeMetadata {
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct ThreadInitializedEventParams {
|
||||
pub(crate) thread_id: String,
|
||||
pub(crate) session_id: String,
|
||||
pub(crate) app_server_client: CodexAppServerClientMetadata,
|
||||
pub(crate) runtime: CodexRuntimeMetadata,
|
||||
pub(crate) model: String,
|
||||
@@ -422,7 +420,6 @@ impl GuardianReviewAnalyticsResult {
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct GuardianReviewEventPayload {
|
||||
pub(crate) session_id: String,
|
||||
pub(crate) app_server_client: CodexAppServerClientMetadata,
|
||||
pub(crate) runtime: CodexRuntimeMetadata,
|
||||
#[serde(flatten)]
|
||||
@@ -741,7 +738,6 @@ pub(crate) struct CodexHookRunEventRequest {
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct CodexCompactionEventParams {
|
||||
pub(crate) thread_id: String,
|
||||
pub(crate) session_id: String,
|
||||
pub(crate) turn_id: String,
|
||||
pub(crate) app_server_client: CodexAppServerClientMetadata,
|
||||
pub(crate) runtime: CodexRuntimeMetadata,
|
||||
@@ -771,7 +767,6 @@ pub(crate) struct CodexCompactionEventRequest {
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct CodexTurnEventParams {
|
||||
pub(crate) thread_id: String,
|
||||
pub(crate) session_id: String,
|
||||
pub(crate) turn_id: String,
|
||||
// TODO(rhan-oai): Populate once queued/default submission type is plumbed from
|
||||
// the turn/start callsites instead of always being reported as None.
|
||||
@@ -794,14 +789,10 @@ pub(crate) struct CodexTurnEventParams {
|
||||
pub(crate) sandbox_network_access: bool,
|
||||
pub(crate) collaboration_mode: Option<&'static str>,
|
||||
pub(crate) personality: Option<String>,
|
||||
pub(crate) workspace_kind: Option<String>,
|
||||
pub(crate) num_input_images: usize,
|
||||
pub(crate) is_first_turn: bool,
|
||||
pub(crate) status: Option<TurnStatus>,
|
||||
pub(crate) turn_error: Option<CodexErrorInfo>,
|
||||
pub(crate) codex_error_kind: Option<CodexErrKind>,
|
||||
pub(crate) codex_error_subreason: Option<String>,
|
||||
pub(crate) codex_error_http_status_code: Option<u16>,
|
||||
pub(crate) steer_count: Option<usize>,
|
||||
pub(crate) total_tool_call_count: Option<usize>,
|
||||
pub(crate) shell_command_count: Option<usize>,
|
||||
@@ -830,7 +821,6 @@ pub(crate) struct CodexTurnEventRequest {
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct CodexTurnSteerEventParams {
|
||||
pub(crate) thread_id: String,
|
||||
pub(crate) session_id: String,
|
||||
pub(crate) expected_turn_id: Option<String>,
|
||||
pub(crate) accepted_turn_id: Option<String>,
|
||||
pub(crate) app_server_client: CodexAppServerClientMetadata,
|
||||
@@ -936,7 +926,6 @@ pub(crate) fn codex_plugin_metadata(plugin: PluginTelemetryMetadata) -> CodexPlu
|
||||
|
||||
pub(crate) fn codex_compaction_event_params(
|
||||
input: CodexCompactionEvent,
|
||||
session_id: String,
|
||||
app_server_client: CodexAppServerClientMetadata,
|
||||
runtime: CodexRuntimeMetadata,
|
||||
thread_source: Option<ThreadSource>,
|
||||
@@ -945,7 +934,6 @@ pub(crate) fn codex_compaction_event_params(
|
||||
) -> CodexCompactionEventParams {
|
||||
CodexCompactionEventParams {
|
||||
thread_id: input.thread_id,
|
||||
session_id,
|
||||
turn_id: input.turn_id,
|
||||
app_server_client,
|
||||
runtime,
|
||||
@@ -1017,7 +1005,6 @@ fn analytics_hook_source(source: HookSource) -> &'static str {
|
||||
HookSource::SessionFlags => "session_flags",
|
||||
HookSource::Plugin => "plugin",
|
||||
HookSource::CloudRequirements => "cloud_requirements",
|
||||
HookSource::CloudManagedConfig => "cloud_managed_config",
|
||||
HookSource::LegacyManagedConfigFile => "legacy_managed_config_file",
|
||||
HookSource::LegacyManagedConfigMdm => "legacy_managed_config_mdm",
|
||||
HookSource::Unknown => "unknown",
|
||||
@@ -1039,7 +1026,6 @@ pub(crate) fn subagent_thread_started_event_request(
|
||||
) -> ThreadInitializedEvent {
|
||||
let event_params = ThreadInitializedEventParams {
|
||||
thread_id: input.thread_id,
|
||||
session_id: input.session_id,
|
||||
app_server_client: CodexAppServerClientMetadata {
|
||||
product_client_id: input.product_client_id,
|
||||
client_name: Some(input.client_name),
|
||||
@@ -1053,7 +1039,9 @@ pub(crate) fn subagent_thread_started_event_request(
|
||||
thread_source: Some(ThreadSource::Subagent),
|
||||
initialization_mode: ThreadInitializationMode::New,
|
||||
subagent_source: Some(subagent_source_name(&input.subagent_source)),
|
||||
parent_thread_id: input.parent_thread_id,
|
||||
parent_thread_id: input
|
||||
.parent_thread_id
|
||||
.or_else(|| subagent_parent_thread_id(&input.subagent_source)),
|
||||
created_at: input.created_at,
|
||||
};
|
||||
ThreadInitializedEvent {
|
||||
@@ -1063,7 +1051,22 @@ pub(crate) fn subagent_thread_started_event_request(
|
||||
}
|
||||
|
||||
pub(crate) fn subagent_source_name(subagent_source: &SubAgentSource) -> String {
|
||||
subagent_source.kind().to_string()
|
||||
match subagent_source {
|
||||
SubAgentSource::Review => "review".to_string(),
|
||||
SubAgentSource::Compact => "compact".to_string(),
|
||||
SubAgentSource::ThreadSpawn { .. } => "thread_spawn".to_string(),
|
||||
SubAgentSource::MemoryConsolidation => "memory_consolidation".to_string(),
|
||||
SubAgentSource::Other(other) => other.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn subagent_parent_thread_id(subagent_source: &SubAgentSource) -> Option<String> {
|
||||
match subagent_source {
|
||||
SubAgentSource::ThreadSpawn {
|
||||
parent_thread_id, ..
|
||||
} => Some(parent_thread_id.to_string()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn analytics_hook_status(status: HookRunStatus) -> HookRunStatus {
|
||||
|
||||
@@ -15,7 +15,6 @@ use codex_protocol::config_types::ModeKind;
|
||||
use codex_protocol::config_types::Personality;
|
||||
use codex_protocol::config_types::ReasoningSummary;
|
||||
use codex_protocol::config_types::ServiceTier;
|
||||
use codex_protocol::error::CodexErr;
|
||||
use codex_protocol::models::PermissionProfile;
|
||||
use codex_protocol::openai_models::ReasoningEffort;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
@@ -30,9 +29,6 @@ use codex_protocol::request_permissions::RequestPermissionsResponse;
|
||||
use serde::Serialize;
|
||||
use std::path::PathBuf;
|
||||
|
||||
const INVALID_REQUEST_SUBREASON_MAX_BYTES: usize = 512;
|
||||
const INVALID_REQUEST_SUBREASON_TRUNCATION_SUFFIX: &str = "...";
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
|
||||
pub struct AcceptedLineFingerprint {
|
||||
pub path_hash: String,
|
||||
@@ -85,7 +81,6 @@ pub struct TurnResolvedConfigFact {
|
||||
pub sandbox_network_access: bool,
|
||||
pub collaboration_mode: ModeKind,
|
||||
pub personality: Option<Personality>,
|
||||
pub workspace_kind: Option<String>,
|
||||
pub is_first_turn: bool,
|
||||
}
|
||||
|
||||
@@ -104,147 +99,6 @@ pub struct TurnTokenUsageFact {
|
||||
pub token_usage: TokenUsage,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TurnCodexErrorFact {
|
||||
pub(crate) turn_id: String,
|
||||
pub(crate) thread_id: String,
|
||||
pub(crate) error: TurnCodexError,
|
||||
}
|
||||
|
||||
impl TurnCodexErrorFact {
|
||||
pub fn from_codex_err(thread_id: String, turn_id: String, error: &CodexErr) -> Self {
|
||||
Self {
|
||||
turn_id,
|
||||
thread_id,
|
||||
error: TurnCodexError::from_codex_err(error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub(crate) enum CodexErrKind {
|
||||
TurnAborted,
|
||||
Stream,
|
||||
ContextWindowExceeded,
|
||||
ThreadNotFound,
|
||||
AgentLimitReached,
|
||||
SessionConfiguredNotFirstEvent,
|
||||
Timeout,
|
||||
RequestTimeout,
|
||||
Spawn,
|
||||
Interrupted,
|
||||
UnexpectedStatus,
|
||||
InvalidRequest,
|
||||
InvalidImageRequest,
|
||||
UsageLimitReached,
|
||||
ServerOverloaded,
|
||||
CyberPolicy,
|
||||
ResponseStreamFailed,
|
||||
ConnectionFailed,
|
||||
QuotaExceeded,
|
||||
UsageNotIncluded,
|
||||
InternalServerError,
|
||||
RetryLimit,
|
||||
InternalAgentDied,
|
||||
Sandbox,
|
||||
LandlockSandboxExecutableNotProvided,
|
||||
UnsupportedOperation,
|
||||
RefreshTokenFailed,
|
||||
Fatal,
|
||||
Io,
|
||||
Json,
|
||||
#[cfg(target_os = "linux")]
|
||||
LandlockRuleset,
|
||||
#[cfg(target_os = "linux")]
|
||||
LandlockPathFd,
|
||||
TokioJoin,
|
||||
EnvVar,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct TurnCodexError {
|
||||
pub(crate) kind: CodexErrKind,
|
||||
pub(crate) subreason: Option<String>,
|
||||
pub(crate) http_status_code: Option<u16>,
|
||||
}
|
||||
|
||||
impl TurnCodexError {
|
||||
fn from_codex_err(error: &CodexErr) -> Self {
|
||||
Self {
|
||||
kind: error.into(),
|
||||
subreason: match error {
|
||||
CodexErr::InvalidRequest(message) => {
|
||||
// InvalidRequest can contain raw provider response bodies, so bound the
|
||||
// analytics copy without changing the source CodexErr.
|
||||
let subreason = if message.len() <= INVALID_REQUEST_SUBREASON_MAX_BYTES {
|
||||
message.clone()
|
||||
} else {
|
||||
let truncated_len = message.floor_char_boundary(
|
||||
INVALID_REQUEST_SUBREASON_MAX_BYTES
|
||||
.saturating_sub(INVALID_REQUEST_SUBREASON_TRUNCATION_SUFFIX.len()),
|
||||
);
|
||||
format!(
|
||||
"{}{INVALID_REQUEST_SUBREASON_TRUNCATION_SUFFIX}",
|
||||
&message[..truncated_len]
|
||||
)
|
||||
};
|
||||
Some(subreason)
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
http_status_code: error.http_status_code_value(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&CodexErr> for CodexErrKind {
|
||||
fn from(error: &CodexErr) -> Self {
|
||||
match error {
|
||||
CodexErr::TurnAborted => CodexErrKind::TurnAborted,
|
||||
CodexErr::Stream(..) => CodexErrKind::Stream,
|
||||
CodexErr::ContextWindowExceeded => CodexErrKind::ContextWindowExceeded,
|
||||
CodexErr::ThreadNotFound(_) => CodexErrKind::ThreadNotFound,
|
||||
CodexErr::AgentLimitReached { .. } => CodexErrKind::AgentLimitReached,
|
||||
CodexErr::SessionConfiguredNotFirstEvent => {
|
||||
CodexErrKind::SessionConfiguredNotFirstEvent
|
||||
}
|
||||
CodexErr::Timeout => CodexErrKind::Timeout,
|
||||
CodexErr::RequestTimeout => CodexErrKind::RequestTimeout,
|
||||
CodexErr::Spawn => CodexErrKind::Spawn,
|
||||
CodexErr::Interrupted => CodexErrKind::Interrupted,
|
||||
CodexErr::UnexpectedStatus(_) => CodexErrKind::UnexpectedStatus,
|
||||
CodexErr::InvalidRequest(_) => CodexErrKind::InvalidRequest,
|
||||
CodexErr::InvalidImageRequest() => CodexErrKind::InvalidImageRequest,
|
||||
CodexErr::UsageLimitReached(_) => CodexErrKind::UsageLimitReached,
|
||||
CodexErr::ServerOverloaded => CodexErrKind::ServerOverloaded,
|
||||
CodexErr::CyberPolicy { .. } => CodexErrKind::CyberPolicy,
|
||||
CodexErr::ResponseStreamFailed(_) => CodexErrKind::ResponseStreamFailed,
|
||||
CodexErr::ConnectionFailed(_) => CodexErrKind::ConnectionFailed,
|
||||
CodexErr::QuotaExceeded => CodexErrKind::QuotaExceeded,
|
||||
CodexErr::UsageNotIncluded => CodexErrKind::UsageNotIncluded,
|
||||
CodexErr::InternalServerError => CodexErrKind::InternalServerError,
|
||||
CodexErr::RetryLimit(_) => CodexErrKind::RetryLimit,
|
||||
CodexErr::InternalAgentDied => CodexErrKind::InternalAgentDied,
|
||||
CodexErr::Sandbox(_) => CodexErrKind::Sandbox,
|
||||
CodexErr::LandlockSandboxExecutableNotProvided => {
|
||||
CodexErrKind::LandlockSandboxExecutableNotProvided
|
||||
}
|
||||
CodexErr::UnsupportedOperation(_) => CodexErrKind::UnsupportedOperation,
|
||||
CodexErr::RefreshTokenFailed(_) => CodexErrKind::RefreshTokenFailed,
|
||||
CodexErr::Fatal(_) => CodexErrKind::Fatal,
|
||||
CodexErr::Io(_) => CodexErrKind::Io,
|
||||
CodexErr::Json(_) => CodexErrKind::Json,
|
||||
#[cfg(target_os = "linux")]
|
||||
CodexErr::LandlockRuleset(_) => CodexErrKind::LandlockRuleset,
|
||||
#[cfg(target_os = "linux")]
|
||||
CodexErr::LandlockPathFd(_) => CodexErrKind::LandlockPathFd,
|
||||
CodexErr::TokioJoin(_) => CodexErrKind::TokioJoin,
|
||||
CodexErr::EnvVar(_) => CodexErrKind::EnvVar,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum TurnStatus {
|
||||
@@ -345,7 +199,6 @@ pub struct AppInvocation {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SubAgentThreadStartedInput {
|
||||
pub session_id: String,
|
||||
pub thread_id: String,
|
||||
pub parent_thread_id: Option<String>,
|
||||
pub product_client_id: String,
|
||||
@@ -475,7 +328,6 @@ pub(crate) enum CustomAnalyticsFact {
|
||||
GuardianReview(Box<GuardianReviewEventParams>),
|
||||
TurnResolvedConfig(Box<TurnResolvedConfigFact>),
|
||||
TurnTokenUsage(Box<TurnTokenUsageFact>),
|
||||
TurnCodexError(Box<TurnCodexErrorFact>),
|
||||
SkillInvoked(SkillInvokedInput),
|
||||
AppMentioned(AppMentionedInput),
|
||||
AppUsed(AppUsedInput),
|
||||
|
||||
@@ -38,7 +38,6 @@ pub use facts::SkillInvocation;
|
||||
pub use facts::SubAgentThreadStartedInput;
|
||||
pub use facts::ThreadInitializationMode;
|
||||
pub use facts::TrackEventsContext;
|
||||
pub use facts::TurnCodexErrorFact;
|
||||
pub use facts::TurnResolvedConfigFact;
|
||||
pub use facts::TurnStatus;
|
||||
pub use facts::TurnSteerRejectionReason;
|
||||
|
||||
@@ -55,6 +55,7 @@ use crate::events::codex_hook_run_metadata;
|
||||
use crate::events::codex_plugin_metadata;
|
||||
use crate::events::codex_plugin_used_metadata;
|
||||
use crate::events::plugin_state_event_type;
|
||||
use crate::events::subagent_parent_thread_id;
|
||||
use crate::events::subagent_source_name;
|
||||
use crate::events::subagent_thread_started_event_request;
|
||||
use crate::facts::AnalyticsFact;
|
||||
@@ -70,8 +71,6 @@ use crate::facts::PluginUsedInput;
|
||||
use crate::facts::SkillInvokedInput;
|
||||
use crate::facts::SubAgentThreadStartedInput;
|
||||
use crate::facts::ThreadInitializationMode;
|
||||
use crate::facts::TurnCodexError;
|
||||
use crate::facts::TurnCodexErrorFact;
|
||||
use crate::facts::TurnResolvedConfigFact;
|
||||
use crate::facts::TurnStatus;
|
||||
use crate::facts::TurnSteerRejectionReason;
|
||||
@@ -256,7 +255,6 @@ struct ItemReviewSummary {
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ThreadMetadataState {
|
||||
session_id: String,
|
||||
thread_source: Option<ThreadSource>,
|
||||
initialization_mode: ThreadInitializationMode,
|
||||
subagent_source: Option<String>,
|
||||
@@ -265,24 +263,24 @@ struct ThreadMetadataState {
|
||||
|
||||
impl ThreadMetadataState {
|
||||
fn from_thread_metadata(
|
||||
session_id: String,
|
||||
session_source: &SessionSource,
|
||||
thread_source: Option<ThreadSource>,
|
||||
parent_thread_id: Option<String>,
|
||||
initialization_mode: ThreadInitializationMode,
|
||||
) -> Self {
|
||||
let subagent_source = match session_source {
|
||||
SessionSource::SubAgent(subagent_source) => Some(subagent_source_name(subagent_source)),
|
||||
let (subagent_source, parent_thread_id) = match session_source {
|
||||
SessionSource::SubAgent(subagent_source) => (
|
||||
Some(subagent_source_name(subagent_source)),
|
||||
subagent_parent_thread_id(subagent_source),
|
||||
),
|
||||
SessionSource::Cli
|
||||
| SessionSource::VSCode
|
||||
| SessionSource::Exec
|
||||
| SessionSource::Mcp
|
||||
| SessionSource::Custom(_)
|
||||
| SessionSource::Internal(_)
|
||||
| SessionSource::Unknown => None,
|
||||
| SessionSource::Unknown => (None, None),
|
||||
};
|
||||
Self {
|
||||
session_id,
|
||||
thread_source,
|
||||
initialization_mode,
|
||||
subagent_source,
|
||||
@@ -324,7 +322,6 @@ struct TurnState {
|
||||
started_at: Option<u64>,
|
||||
token_usage: Option<TokenUsage>,
|
||||
completed: Option<CompletedTurnState>,
|
||||
codex_error: Option<TurnCodexError>,
|
||||
latest_diff: Option<String>,
|
||||
steer_count: usize,
|
||||
tool_counts: TurnToolCounts,
|
||||
@@ -464,9 +461,6 @@ impl AnalyticsReducer {
|
||||
CustomAnalyticsFact::TurnTokenUsage(input) => {
|
||||
self.ingest_turn_token_usage(*input, out).await;
|
||||
}
|
||||
CustomAnalyticsFact::TurnCodexError(input) => {
|
||||
self.ingest_turn_codex_error(*input);
|
||||
}
|
||||
CustomAnalyticsFact::SkillInvoked(input) => {
|
||||
self.ingest_skill_invoked(input, out).await;
|
||||
}
|
||||
@@ -519,7 +513,10 @@ impl AnalyticsReducer {
|
||||
input: SubAgentThreadStartedInput,
|
||||
out: &mut Vec<TrackEventRequest>,
|
||||
) {
|
||||
let parent_thread_id = input.parent_thread_id.clone();
|
||||
let parent_thread_id = input
|
||||
.parent_thread_id
|
||||
.clone()
|
||||
.or_else(|| subagent_parent_thread_id(&input.subagent_source));
|
||||
let parent_connection_id = parent_thread_id
|
||||
.as_ref()
|
||||
.and_then(|parent_thread_id| self.threads.get(parent_thread_id))
|
||||
@@ -528,7 +525,6 @@ impl AnalyticsReducer {
|
||||
thread_state
|
||||
.metadata
|
||||
.get_or_insert_with(|| ThreadMetadataState {
|
||||
session_id: input.session_id.clone(),
|
||||
thread_source: Some(ThreadSource::Subagent),
|
||||
initialization_mode: ThreadInitializationMode::New,
|
||||
subagent_source: Some(subagent_source_name(&input.subagent_source)),
|
||||
@@ -547,8 +543,8 @@ impl AnalyticsReducer {
|
||||
input: GuardianReviewEventParams,
|
||||
out: &mut Vec<TrackEventRequest>,
|
||||
) {
|
||||
let Some((connection_state, thread_metadata)) =
|
||||
self.thread_context_or_warn(AnalyticsDropSite::guardian(&input))
|
||||
let Some(connection_state) =
|
||||
self.thread_connection_or_warn(AnalyticsDropSite::guardian(&input))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
@@ -556,7 +552,6 @@ impl AnalyticsReducer {
|
||||
GuardianReviewEventRequest {
|
||||
event_type: "codex_guardian_review",
|
||||
event_params: GuardianReviewEventPayload {
|
||||
session_id: thread_metadata.session_id.clone(),
|
||||
app_server_client: connection_state.app_server_client.clone(),
|
||||
runtime: connection_state.runtime.clone(),
|
||||
guardian_review: input,
|
||||
@@ -612,7 +607,6 @@ impl AnalyticsReducer {
|
||||
started_at: None,
|
||||
token_usage: None,
|
||||
completed: None,
|
||||
codex_error: None,
|
||||
latest_diff: None,
|
||||
steer_count: 0,
|
||||
tool_counts: TurnToolCounts::default(),
|
||||
@@ -637,7 +631,6 @@ impl AnalyticsReducer {
|
||||
started_at: None,
|
||||
token_usage: None,
|
||||
completed: None,
|
||||
codex_error: None,
|
||||
latest_diff: None,
|
||||
steer_count: 0,
|
||||
tool_counts: TurnToolCounts::default(),
|
||||
@@ -647,29 +640,6 @@ impl AnalyticsReducer {
|
||||
self.maybe_emit_turn_event(&turn_id, out).await;
|
||||
}
|
||||
|
||||
fn ingest_turn_codex_error(&mut self, input: TurnCodexErrorFact) {
|
||||
let TurnCodexErrorFact {
|
||||
turn_id,
|
||||
thread_id,
|
||||
error,
|
||||
} = input;
|
||||
let turn_state = self.turns.entry(turn_id).or_insert(TurnState {
|
||||
connection_id: None,
|
||||
thread_id: None,
|
||||
num_input_images: None,
|
||||
resolved_config: None,
|
||||
started_at: None,
|
||||
token_usage: None,
|
||||
completed: None,
|
||||
codex_error: None,
|
||||
latest_diff: None,
|
||||
steer_count: 0,
|
||||
tool_counts: TurnToolCounts::default(),
|
||||
});
|
||||
turn_state.thread_id.get_or_insert(thread_id);
|
||||
turn_state.codex_error = Some(error);
|
||||
}
|
||||
|
||||
async fn ingest_skill_invoked(
|
||||
&mut self,
|
||||
input: SkillInvokedInput,
|
||||
@@ -826,7 +796,6 @@ impl AnalyticsReducer {
|
||||
started_at: None,
|
||||
token_usage: None,
|
||||
completed: None,
|
||||
codex_error: None,
|
||||
latest_diff: None,
|
||||
steer_count: 0,
|
||||
tool_counts: TurnToolCounts::default(),
|
||||
@@ -1186,7 +1155,6 @@ impl AnalyticsReducer {
|
||||
started_at: None,
|
||||
token_usage: None,
|
||||
completed: None,
|
||||
codex_error: None,
|
||||
latest_diff: None,
|
||||
steer_count: 0,
|
||||
tool_counts: TurnToolCounts::default(),
|
||||
@@ -1208,7 +1176,6 @@ impl AnalyticsReducer {
|
||||
started_at: None,
|
||||
token_usage: None,
|
||||
completed: None,
|
||||
codex_error: None,
|
||||
latest_diff: None,
|
||||
steer_count: 0,
|
||||
tool_counts: TurnToolCounts::default(),
|
||||
@@ -1228,7 +1195,6 @@ impl AnalyticsReducer {
|
||||
started_at: None,
|
||||
token_usage: None,
|
||||
completed: None,
|
||||
codex_error: None,
|
||||
latest_diff: None,
|
||||
steer_count: 0,
|
||||
tool_counts: TurnToolCounts::default(),
|
||||
@@ -1265,17 +1231,13 @@ impl AnalyticsReducer {
|
||||
out: &mut Vec<TrackEventRequest>,
|
||||
) {
|
||||
let session_source: SessionSource = thread.source.into();
|
||||
let session_id = thread.session_id;
|
||||
let thread_id = thread.id;
|
||||
let parent_thread_id = thread.parent_thread_id;
|
||||
let Some(connection_state) = self.connections.get(&connection_id) else {
|
||||
return;
|
||||
};
|
||||
let thread_metadata = ThreadMetadataState::from_thread_metadata(
|
||||
session_id.clone(),
|
||||
&session_source,
|
||||
thread.thread_source.map(Into::into),
|
||||
parent_thread_id,
|
||||
initialization_mode,
|
||||
);
|
||||
self.threads.insert(
|
||||
@@ -1290,7 +1252,6 @@ impl AnalyticsReducer {
|
||||
event_type: "codex_thread_initialized",
|
||||
event_params: ThreadInitializedEventParams {
|
||||
thread_id,
|
||||
session_id,
|
||||
app_server_client: connection_state.app_server_client.clone(),
|
||||
runtime: connection_state.runtime.clone(),
|
||||
model,
|
||||
@@ -1316,7 +1277,6 @@ impl AnalyticsReducer {
|
||||
event_type: "codex_compaction_event",
|
||||
event_params: codex_compaction_event_params(
|
||||
input,
|
||||
thread_metadata.session_id.clone(),
|
||||
connection_state.app_server_client.clone(),
|
||||
connection_state.runtime.clone(),
|
||||
thread_metadata.thread_source,
|
||||
@@ -1419,7 +1379,6 @@ impl AnalyticsReducer {
|
||||
event_type: "codex_turn_steer_event",
|
||||
event_params: CodexTurnSteerEventParams {
|
||||
thread_id: pending_request.thread_id,
|
||||
session_id: thread_metadata.session_id.clone(),
|
||||
expected_turn_id: Some(pending_request.expected_turn_id),
|
||||
accepted_turn_id,
|
||||
app_server_client: connection_state.app_server_client.clone(),
|
||||
@@ -2483,14 +2442,11 @@ fn codex_turn_event_params(
|
||||
sandbox_network_access,
|
||||
collaboration_mode,
|
||||
personality,
|
||||
workspace_kind,
|
||||
is_first_turn,
|
||||
} = resolved_config;
|
||||
let token_usage = turn_state.token_usage.clone();
|
||||
let codex_error = turn_state.codex_error.as_ref();
|
||||
CodexTurnEventParams {
|
||||
thread_id,
|
||||
session_id: thread_metadata.session_id.clone(),
|
||||
turn_id,
|
||||
app_server_client,
|
||||
runtime,
|
||||
@@ -2516,14 +2472,10 @@ fn codex_turn_event_params(
|
||||
sandbox_network_access,
|
||||
collaboration_mode: Some(collaboration_mode_mode(collaboration_mode)),
|
||||
personality: personality_mode(personality),
|
||||
workspace_kind,
|
||||
num_input_images,
|
||||
is_first_turn,
|
||||
status: completed.status,
|
||||
turn_error: completed.turn_error,
|
||||
codex_error_kind: codex_error.map(|error| error.kind),
|
||||
codex_error_subreason: codex_error.and_then(|error| error.subreason.clone()),
|
||||
codex_error_http_status_code: codex_error.and_then(|error| error.http_status_code),
|
||||
steer_count: Some(turn_state.steer_count),
|
||||
total_tool_call_count: Some(turn_state.tool_counts.total),
|
||||
shell_command_count: Some(turn_state.tool_counts.shell_command),
|
||||
|
||||
@@ -43,7 +43,7 @@ use codex_app_server_protocol::Result as JsonRpcResult;
|
||||
use codex_app_server_protocol::ServerNotification;
|
||||
use codex_app_server_protocol::ServerRequest;
|
||||
use codex_arg0::Arg0DispatchPaths;
|
||||
use codex_config::CloudConfigBundleLoader;
|
||||
use codex_config::CloudRequirementsLoader;
|
||||
use codex_config::LoaderOverrides;
|
||||
use codex_config::NoopThreadConfigLoader;
|
||||
use codex_config::RemoteThreadConfigLoader;
|
||||
@@ -339,8 +339,8 @@ pub struct InProcessClientStartArgs {
|
||||
pub loader_overrides: LoaderOverrides,
|
||||
/// Whether config API paths should reject unknown config fields.
|
||||
pub strict_config: bool,
|
||||
/// Preloaded cloud config bundle provider.
|
||||
pub cloud_config_bundle: CloudConfigBundleLoader,
|
||||
/// Preloaded cloud requirements provider.
|
||||
pub cloud_requirements: CloudRequirementsLoader,
|
||||
/// Feedback sink used by app-server/core telemetry and logs.
|
||||
pub feedback: CodexFeedback,
|
||||
/// SQLite tracing layer used to flush recently emitted logs before feedback upload.
|
||||
@@ -406,7 +406,7 @@ impl InProcessClientStartArgs {
|
||||
cli_overrides: self.cli_overrides,
|
||||
loader_overrides: self.loader_overrides,
|
||||
strict_config: self.strict_config,
|
||||
cloud_config_bundle: self.cloud_config_bundle,
|
||||
cloud_requirements: self.cloud_requirements,
|
||||
thread_config_loader,
|
||||
feedback: self.feedback,
|
||||
log_db: self.log_db,
|
||||
@@ -1035,7 +1035,7 @@ mod tests {
|
||||
cli_overrides: Vec::new(),
|
||||
loader_overrides: LoaderOverrides::default(),
|
||||
strict_config: false,
|
||||
cloud_config_bundle: CloudConfigBundleLoader::default(),
|
||||
cloud_requirements: CloudRequirementsLoader::default(),
|
||||
feedback: CodexFeedback::new(),
|
||||
log_db: None,
|
||||
state_db: Some(state_db),
|
||||
@@ -2199,7 +2199,7 @@ mod tests {
|
||||
cli_overrides: Vec::new(),
|
||||
loader_overrides: LoaderOverrides::default(),
|
||||
strict_config: false,
|
||||
cloud_config_bundle: CloudConfigBundleLoader::default(),
|
||||
cloud_requirements: CloudRequirementsLoader::default(),
|
||||
feedback: CodexFeedback::new(),
|
||||
log_db: None,
|
||||
state_db: None,
|
||||
@@ -2240,7 +2240,7 @@ mod tests {
|
||||
cli_overrides: Vec::new(),
|
||||
loader_overrides: LoaderOverrides::default(),
|
||||
strict_config: false,
|
||||
cloud_config_bundle: CloudConfigBundleLoader::default(),
|
||||
cloud_requirements: CloudRequirementsLoader::default(),
|
||||
feedback: CodexFeedback::new(),
|
||||
log_db: None,
|
||||
state_db: None,
|
||||
|
||||
@@ -12,28 +12,6 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AdditionalContextEntry": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"$ref": "#/definitions/AdditionalContextKind"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"value"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AdditionalContextKind": {
|
||||
"enum": [
|
||||
"untrusted",
|
||||
"application"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ApprovalsReviewer": {
|
||||
"description": "Configures who approval requests are routed to for review. Examples include sandbox escapes, blocked network access, MCP approval prompts, and ARC escalations. Defaults to `user`. `auto_review` uses a carefully prompted subagent to gather relevant context and apply a risk-based decision framework before approving or denying the request. The legacy value `guardian_subagent` is accepted for compatibility.",
|
||||
"enum": [
|
||||
@@ -1085,8 +1063,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -2988,20 +2964,6 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsExtraRootsSetParams": {
|
||||
"properties": {
|
||||
"extraRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"extraRoots"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsListParams": {
|
||||
"properties": {
|
||||
"cwds": {
|
||||
@@ -3557,42 +3519,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"ThreadResumeInitialTurnsPageParams": {
|
||||
"properties": {
|
||||
"itemsView": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/TurnItemsView"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "How much item detail to include for each returned turn; defaults to summary."
|
||||
},
|
||||
"limit": {
|
||||
"description": "Optional turn page size.",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortDirection": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SortDirection"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional turn pagination direction; defaults to descending."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadResumeParams": {
|
||||
"description": "There are three ways to resume a thread: 1. By thread_id: load the thread from disk by thread_id and resume it. 2. By history: instantiate the thread from memory and resume it. 3. By path: load the thread from disk by path and resume it.\n\nFor non-running threads, the precedence is: history > non-empty path > thread_id. If using history or a non-empty path for a non-running thread, the thread_id param will be ignored.\n\nIf thread_id identifies a running thread, app-server rejoins that thread and treats a non-empty path as a consistency check against the active rollout path. Empty string path values are treated as absent.\n\nPrefer using thread_id whenever possible.",
|
||||
"properties": {
|
||||
@@ -3999,12 +3925,6 @@
|
||||
],
|
||||
"description": "Override where approval requests are routed for review on this turn and subsequent turns."
|
||||
},
|
||||
"clientUserMessageId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cwd": {
|
||||
"description": "Override the working directory for this turn and subsequent turns.",
|
||||
"type": [
|
||||
@@ -4091,12 +4011,6 @@
|
||||
},
|
||||
"TurnSteerParams": {
|
||||
"properties": {
|
||||
"clientUserMessageId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"expectedTurnId": {
|
||||
"description": "Required active turn id precondition. The request fails when it does not match the currently active turn.",
|
||||
"type": "string"
|
||||
@@ -4797,30 +4711,6 @@
|
||||
"title": "Skills/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"skills/extraRoots/set"
|
||||
],
|
||||
"title": "Skills/extraRoots/setRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/SkillsExtraRootsSetParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Skills/extraRoots/setRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
|
||||
@@ -285,13 +285,6 @@
|
||||
"cwd": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"environmentId": {
|
||||
"default": null,
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"itemId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -326,4 +319,4 @@
|
||||
],
|
||||
"title": "PermissionsRequestApprovalParams",
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,6 @@
|
||||
"type": "object"
|
||||
},
|
||||
"AccountRateLimitsUpdatedNotification": {
|
||||
"description": "Sparse rolling rate-limit update.\n\nClients should merge available values into the most recent `account/rateLimits/read` response or refetch that snapshot. Nullable account metadata may be unavailable in a rolling update and does not clear a previously observed value.",
|
||||
"properties": {
|
||||
"rateLimits": {
|
||||
"$ref": "#/definitions/RateLimitSnapshot"
|
||||
@@ -2003,7 +2002,6 @@
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"cloudManagedConfig",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
@@ -2033,8 +2031,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -2678,16 +2674,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"individualLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SpendControlLimitSnapshot"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"limitId": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -3146,31 +3132,6 @@
|
||||
"description": "Notification emitted when watched local skill files change.\n\nTreat this as an invalidation signal and re-run `skills/list` with the client's current parameters when refreshed skill metadata is needed.",
|
||||
"type": "object"
|
||||
},
|
||||
"SpendControlLimitSnapshot": {
|
||||
"properties": {
|
||||
"limit": {
|
||||
"type": "string"
|
||||
},
|
||||
"remainingPercent": {
|
||||
"format": "int32",
|
||||
"type": "integer"
|
||||
},
|
||||
"resetsAt": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"used": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"limit",
|
||||
"remainingPercent",
|
||||
"resetsAt",
|
||||
"used"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SubAgentSource": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -3402,13 +3363,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -3605,12 +3559,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -1590,13 +1590,6 @@
|
||||
"cwd": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"environmentId": {
|
||||
"default": null,
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"itemId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -2005,4 +1998,4 @@
|
||||
}
|
||||
],
|
||||
"title": "ServerRequest"
|
||||
}
|
||||
}
|
||||
@@ -709,30 +709,6 @@
|
||||
"title": "Skills/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"skills/extraRoots/set"
|
||||
],
|
||||
"title": "Skills/extraRoots/setRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/SkillsExtraRootsSetParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Skills/extraRoots/setRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -3783,13 +3759,6 @@
|
||||
"cwd": {
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
},
|
||||
"environmentId": {
|
||||
"default": null,
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"itemId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -5727,7 +5696,6 @@
|
||||
},
|
||||
"AccountRateLimitsUpdatedNotification": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Sparse rolling rate-limit update.\n\nClients should merge available values into the most recent `account/rateLimits/read` response or refetch that snapshot. Nullable account metadata may be unavailable in a rolling update and does not clear a previously observed value.",
|
||||
"properties": {
|
||||
"rateLimits": {
|
||||
"$ref": "#/definitions/v2/RateLimitSnapshot"
|
||||
@@ -5800,28 +5768,6 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AdditionalContextEntry": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"$ref": "#/definitions/v2/AdditionalContextKind"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"value"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AdditionalContextKind": {
|
||||
"enum": [
|
||||
"untrusted",
|
||||
"application"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AdditionalFileSystemPermissions": {
|
||||
"properties": {
|
||||
"entries": {
|
||||
@@ -5959,16 +5905,6 @@
|
||||
},
|
||||
"AppConfig": {
|
||||
"properties": {
|
||||
"approvals_reviewer": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ApprovalsReviewer"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_tools_approval_mode": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -7621,33 +7557,6 @@
|
||||
"title": "SystemConfigLayerSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Enterprise-managed config layer delivered by the cloud config bundle.",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "Stable identifier for the delivered layer.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Admin-facing name for the delivered layer. This is surfaced in diagnostics so users know which cloud layer needs administrator attention.",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"enterpriseManaged"
|
||||
],
|
||||
"title": "EnterpriseManagedConfigLayerSourceType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"title": "EnterpriseManagedConfigLayerSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "User config layer from $CODEX_HOME/config.toml. This layer is special in that it is expected to be: - writable by the user - generally outside the workspace directory",
|
||||
"properties": {
|
||||
@@ -7854,15 +7763,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"allowedWindowsSandboxImplementations": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/WindowsSandboxSetupMode"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"computerUse": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -10136,7 +10036,6 @@
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"cloudManagedConfig",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
@@ -10239,8 +10138,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -11043,47 +10940,6 @@
|
||||
"title": "McpResourceReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"McpServerInfo": {
|
||||
"description": "Presentation metadata advertised by an initialized MCP server.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"icons": {
|
||||
"items": true,
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"websiteUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"version"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"McpServerMigration": {
|
||||
"properties": {
|
||||
"name": {
|
||||
@@ -11194,16 +11050,6 @@
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"serverInfo": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/McpServerInfo"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tools": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/v2/Tool"
|
||||
@@ -11924,7 +11770,7 @@
|
||||
"NetworkUnixSocketPermission": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -13345,16 +13191,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"individualLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/SpendControlLimitSnapshot"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"limitId": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -15210,27 +15046,6 @@
|
||||
"title": "SkillsConfigWriteResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsExtraRootsSetParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"extraRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"extraRoots"
|
||||
],
|
||||
"title": "SkillsExtraRootsSetParams",
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsExtraRootsSetResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "SkillsExtraRootsSetResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsListEntry": {
|
||||
"properties": {
|
||||
"cwd": {
|
||||
@@ -15297,31 +15112,6 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"SpendControlLimitSnapshot": {
|
||||
"properties": {
|
||||
"limit": {
|
||||
"type": "string"
|
||||
},
|
||||
"remainingPercent": {
|
||||
"format": "int32",
|
||||
"type": "integer"
|
||||
},
|
||||
"resetsAt": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"used": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"limit",
|
||||
"remainingPercent",
|
||||
"resetsAt",
|
||||
"used"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SubAgentSource": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -15566,13 +15356,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -16138,12 +15921,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/UserInput"
|
||||
@@ -17349,42 +17126,6 @@
|
||||
"title": "ThreadRealtimeTranscriptDoneNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadResumeInitialTurnsPageParams": {
|
||||
"properties": {
|
||||
"itemsView": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/TurnItemsView"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "How much item detail to include for each returned turn; defaults to summary."
|
||||
},
|
||||
"limit": {
|
||||
"description": "Optional turn page size.",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortDirection": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/SortDirection"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional turn pagination direction; defaults to descending."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadResumeParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "There are three ways to resume a thread: 1. By thread_id: load the thread from disk by thread_id and resume it. 2. By history: instantiate the thread from memory and resume it. 3. By path: load the thread from disk by path and resume it.\n\nFor non-running threads, the precedence is: history > non-empty path > thread_id. If using history or a non-empty path for a non-running thread, the thread_id param will be ignored.\n\nIf thread_id identifies a running thread, app-server rejoins that thread and treats a non-empty path as a consistency check against the active rollout path. Empty string path values are treated as absent.\n\nPrefer using thread_id whenever possible.",
|
||||
@@ -18561,12 +18302,6 @@
|
||||
],
|
||||
"description": "Override where approval requests are routed for review on this turn and subsequent turns."
|
||||
},
|
||||
"clientUserMessageId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cwd": {
|
||||
"description": "Override the working directory for this turn and subsequent turns.",
|
||||
"type": [
|
||||
@@ -18694,12 +18429,6 @@
|
||||
"TurnSteerParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"clientUserMessageId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"expectedTurnId": {
|
||||
"description": "Required active turn id precondition. The request fails when it does not match the currently active turn.",
|
||||
"type": "string"
|
||||
@@ -18735,32 +18464,6 @@
|
||||
"title": "TurnSteerResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"TurnsPage": {
|
||||
"properties": {
|
||||
"backwardsCursor": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/Turn"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"nextCursor": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UserInput": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -19239,4 +18942,4 @@
|
||||
},
|
||||
"title": "CodexAppServerProtocol",
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,6 @@
|
||||
},
|
||||
"AccountRateLimitsUpdatedNotification": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Sparse rolling rate-limit update.\n\nClients should merge available values into the most recent `account/rateLimits/read` response or refetch that snapshot. Nullable account metadata may be unavailable in a rolling update and does not clear a previously observed value.",
|
||||
"properties": {
|
||||
"rateLimits": {
|
||||
"$ref": "#/definitions/RateLimitSnapshot"
|
||||
@@ -165,28 +164,6 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AdditionalContextEntry": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"$ref": "#/definitions/AdditionalContextKind"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"value"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AdditionalContextKind": {
|
||||
"enum": [
|
||||
"untrusted",
|
||||
"application"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"AdditionalFileSystemPermissions": {
|
||||
"properties": {
|
||||
"entries": {
|
||||
@@ -324,16 +301,6 @@
|
||||
},
|
||||
"AppConfig": {
|
||||
"properties": {
|
||||
"approvals_reviewer": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ApprovalsReviewer"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_tools_approval_mode": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -1468,30 +1435,6 @@
|
||||
"title": "Skills/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"skills/extraRoots/set"
|
||||
],
|
||||
"title": "Skills/extraRoots/setRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/SkillsExtraRootsSetParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Skills/extraRoots/setRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -3983,33 +3926,6 @@
|
||||
"title": "SystemConfigLayerSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Enterprise-managed config layer delivered by the cloud config bundle.",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "Stable identifier for the delivered layer.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Admin-facing name for the delivered layer. This is surfaced in diagnostics so users know which cloud layer needs administrator attention.",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"enterpriseManaged"
|
||||
],
|
||||
"title": "EnterpriseManagedConfigLayerSourceType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"title": "EnterpriseManagedConfigLayerSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "User config layer from $CODEX_HOME/config.toml. This layer is special in that it is expected to be: - writable by the user - generally outside the workspace directory",
|
||||
"properties": {
|
||||
@@ -4216,15 +4132,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"allowedWindowsSandboxImplementations": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/WindowsSandboxSetupMode"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"computerUse": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -6609,7 +6516,6 @@
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"cloudManagedConfig",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
@@ -6712,8 +6618,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -7565,47 +7469,6 @@
|
||||
"title": "McpResourceReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"McpServerInfo": {
|
||||
"description": "Presentation metadata advertised by an initialized MCP server.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"icons": {
|
||||
"items": true,
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"websiteUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"version"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"McpServerMigration": {
|
||||
"properties": {
|
||||
"name": {
|
||||
@@ -7716,16 +7579,6 @@
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"serverInfo": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/McpServerInfo"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tools": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Tool"
|
||||
@@ -8446,7 +8299,7 @@
|
||||
"NetworkUnixSocketPermission": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -9867,16 +9720,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"individualLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SpendControlLimitSnapshot"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"limitId": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -13027,27 +12870,6 @@
|
||||
"title": "SkillsConfigWriteResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsExtraRootsSetParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"extraRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"extraRoots"
|
||||
],
|
||||
"title": "SkillsExtraRootsSetParams",
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsExtraRootsSetResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "SkillsExtraRootsSetResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsListEntry": {
|
||||
"properties": {
|
||||
"cwd": {
|
||||
@@ -13114,31 +12936,6 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"SpendControlLimitSnapshot": {
|
||||
"properties": {
|
||||
"limit": {
|
||||
"type": "string"
|
||||
},
|
||||
"remainingPercent": {
|
||||
"format": "int32",
|
||||
"type": "integer"
|
||||
},
|
||||
"resetsAt": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"used": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"limit",
|
||||
"remainingPercent",
|
||||
"resetsAt",
|
||||
"used"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SubAgentSource": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -13383,13 +13180,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -13955,12 +13745,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
@@ -15166,42 +14950,6 @@
|
||||
"title": "ThreadRealtimeTranscriptDoneNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadResumeInitialTurnsPageParams": {
|
||||
"properties": {
|
||||
"itemsView": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/TurnItemsView"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "How much item detail to include for each returned turn; defaults to summary."
|
||||
},
|
||||
"limit": {
|
||||
"description": "Optional turn page size.",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortDirection": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SortDirection"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional turn pagination direction; defaults to descending."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadResumeParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "There are three ways to resume a thread: 1. By thread_id: load the thread from disk by thread_id and resume it. 2. By history: instantiate the thread from memory and resume it. 3. By path: load the thread from disk by path and resume it.\n\nFor non-running threads, the precedence is: history > non-empty path > thread_id. If using history or a non-empty path for a non-running thread, the thread_id param will be ignored.\n\nIf thread_id identifies a running thread, app-server rejoins that thread and treats a non-empty path as a consistency check against the active rollout path. Empty string path values are treated as absent.\n\nPrefer using thread_id whenever possible.",
|
||||
@@ -16378,12 +16126,6 @@
|
||||
],
|
||||
"description": "Override where approval requests are routed for review on this turn and subsequent turns."
|
||||
},
|
||||
"clientUserMessageId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cwd": {
|
||||
"description": "Override the working directory for this turn and subsequent turns.",
|
||||
"type": [
|
||||
@@ -16511,12 +16253,6 @@
|
||||
"TurnSteerParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"clientUserMessageId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"expectedTurnId": {
|
||||
"description": "Required active turn id precondition. The request fails when it does not match the currently active turn.",
|
||||
"type": "string"
|
||||
@@ -16552,32 +16288,6 @@
|
||||
"title": "TurnSteerResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"TurnsPage": {
|
||||
"properties": {
|
||||
"backwardsCursor": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/Turn"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"nextCursor": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UserInput": {
|
||||
"oneOf": [
|
||||
{
|
||||
|
||||
@@ -61,16 +61,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"individualLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SpendControlLimitSnapshot"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"limitId": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -151,34 +141,8 @@
|
||||
"usedPercent"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SpendControlLimitSnapshot": {
|
||||
"properties": {
|
||||
"limit": {
|
||||
"type": "string"
|
||||
},
|
||||
"remainingPercent": {
|
||||
"format": "int32",
|
||||
"type": "integer"
|
||||
},
|
||||
"resetsAt": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"used": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"limit",
|
||||
"remainingPercent",
|
||||
"resetsAt",
|
||||
"used"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"description": "Sparse rolling rate-limit update.\n\nClients should merge available values into the most recent `account/rateLimits/read` response or refetch that snapshot. Nullable account metadata may be unavailable in a rolling update and does not clear a previously observed value.",
|
||||
"properties": {
|
||||
"rateLimits": {
|
||||
"$ref": "#/definitions/RateLimitSnapshot"
|
||||
|
||||
@@ -19,16 +19,6 @@
|
||||
},
|
||||
"AppConfig": {
|
||||
"properties": {
|
||||
"approvals_reviewer": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ApprovalsReviewer"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_tools_approval_mode": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -508,33 +498,6 @@
|
||||
"title": "SystemConfigLayerSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Enterprise-managed config layer delivered by the cloud config bundle.",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "Stable identifier for the delivered layer.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Admin-facing name for the delivered layer. This is surfaced in diagnostics so users know which cloud layer needs administrator attention.",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"enterpriseManaged"
|
||||
],
|
||||
"title": "EnterpriseManagedConfigLayerSourceType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"title": "EnterpriseManagedConfigLayerSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "User config layer from $CODEX_HOME/config.toml. This layer is special in that it is expected to be: - writable by the user - generally outside the workspace directory",
|
||||
"properties": {
|
||||
|
||||
@@ -121,15 +121,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"allowedWindowsSandboxImplementations": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/WindowsSandboxSetupMode"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"computerUse": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -469,7 +460,7 @@
|
||||
"NetworkUnixSocketPermission": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -494,13 +485,6 @@
|
||||
"live"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"WindowsSandboxSetupMode": {
|
||||
"enum": [
|
||||
"elevated",
|
||||
"unelevated"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
|
||||
@@ -73,33 +73,6 @@
|
||||
"title": "SystemConfigLayerSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Enterprise-managed config layer delivered by the cloud config bundle.",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "Stable identifier for the delivered layer.",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Admin-facing name for the delivered layer. This is surfaced in diagnostics so users know which cloud layer needs administrator attention.",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"enterpriseManaged"
|
||||
],
|
||||
"title": "EnterpriseManagedConfigLayerSourceType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"title": "EnterpriseManagedConfigLayerSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "User config layer from $CODEX_HOME/config.toml. This layer is special in that it is expected to be: - writable by the user - generally outside the workspace directory",
|
||||
"properties": {
|
||||
|
||||
@@ -61,16 +61,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"individualLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SpendControlLimitSnapshot"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"limitId": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -151,31 +141,6 @@
|
||||
"usedPercent"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SpendControlLimitSnapshot": {
|
||||
"properties": {
|
||||
"limit": {
|
||||
"type": "string"
|
||||
},
|
||||
"remainingPercent": {
|
||||
"format": "int32",
|
||||
"type": "integer"
|
||||
},
|
||||
"resetsAt": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"used": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"limit",
|
||||
"remainingPercent",
|
||||
"resetsAt",
|
||||
"used"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
|
||||
@@ -166,7 +166,6 @@
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"cloudManagedConfig",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
|
||||
@@ -166,7 +166,6 @@
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"cloudManagedConfig",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
|
||||
@@ -130,7 +130,6 @@
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"cloudManagedConfig",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
|
||||
@@ -287,8 +287,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -500,12 +498,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -287,8 +287,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -500,12 +498,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -10,47 +10,6 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"McpServerInfo": {
|
||||
"description": "Presentation metadata advertised by an initialized MCP server.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"icons": {
|
||||
"items": true,
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"version": {
|
||||
"type": "string"
|
||||
},
|
||||
"websiteUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"version"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"McpServerStatus": {
|
||||
"properties": {
|
||||
"authStatus": {
|
||||
@@ -71,16 +30,6 @@
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"serverInfo": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/McpServerInfo"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"tools": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/Tool"
|
||||
|
||||
@@ -165,8 +165,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
|
||||
@@ -424,8 +424,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -644,12 +642,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"AbsolutePathBuf": {
|
||||
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"extraRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"extraRoots"
|
||||
],
|
||||
"title": "SkillsExtraRootsSetParams",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "SkillsExtraRootsSetResponse",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -529,8 +529,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -1036,13 +1034,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -1128,12 +1119,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -450,8 +450,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -851,13 +849,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -943,12 +934,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -450,8 +450,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -851,13 +849,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -943,12 +934,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -450,8 +450,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -851,13 +849,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -943,12 +934,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -224,8 +224,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -983,74 +981,6 @@
|
||||
"danger-full-access"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"SortDirection": {
|
||||
"enum": [
|
||||
"asc",
|
||||
"desc"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ThreadResumeInitialTurnsPageParams": {
|
||||
"properties": {
|
||||
"itemsView": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/TurnItemsView"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "How much item detail to include for each returned turn; defaults to summary."
|
||||
},
|
||||
"limit": {
|
||||
"description": "Optional turn page size.",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortDirection": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SortDirection"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional turn pagination direction; defaults to descending."
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"TurnItemsView": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "`items` was not loaded for this turn. The field is intentionally empty.",
|
||||
"enum": [
|
||||
"notLoaded"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "`items` contains only a display summary for this turn.",
|
||||
"enum": [
|
||||
"summary"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "`items` contains every ThreadItem available from persisted app-server history for this turn.",
|
||||
"enum": [
|
||||
"full"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"description": "There are three ways to resume a thread: 1. By thread_id: load the thread from disk by thread_id and resume it. 2. By history: instantiate the thread from memory and resume it. 3. By path: load the thread from disk by path and resume it.\n\nFor non-running threads, the precedence is: history > non-empty path > thread_id. If using history or a non-empty path for a non-running thread, the thread_id param will be ignored.\n\nIf thread_id identifies a running thread, app-server rejoins that thread and treats a non-empty path as a consistency check against the active rollout path. Empty string path values are treated as absent.\n\nPrefer using thread_id whenever possible.",
|
||||
|
||||
@@ -529,8 +529,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -1036,13 +1034,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -1128,12 +1119,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
@@ -2008,32 +1993,6 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"TurnsPage": {
|
||||
"properties": {
|
||||
"backwardsCursor": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/Turn"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"nextCursor": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UserInput": {
|
||||
"oneOf": [
|
||||
{
|
||||
|
||||
@@ -450,8 +450,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -851,13 +849,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -943,12 +934,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -529,8 +529,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -1036,13 +1034,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -1128,12 +1119,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -450,8 +450,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -851,13 +849,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -943,12 +934,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -450,8 +450,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -851,13 +849,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"parentThreadId": {
|
||||
"description": "The ID of the parent thread. This will only be set if this thread is a subagent.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"path": {
|
||||
"description": "[UNSTABLE] Path to the thread on disk.",
|
||||
"type": [
|
||||
@@ -943,12 +934,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -424,8 +424,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -644,12 +642,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -5,28 +5,6 @@
|
||||
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
|
||||
"type": "string"
|
||||
},
|
||||
"AdditionalContextEntry": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"$ref": "#/definitions/AdditionalContextKind"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"value"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AdditionalContextKind": {
|
||||
"enum": [
|
||||
"untrusted",
|
||||
"application"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ApprovalsReviewer": {
|
||||
"description": "Configures who approval requests are routed to for review. Examples include sandbox escapes, blocked network access, MCP approval prompts, and ARC escalations. Defaults to `user`. `auto_review` uses a carefully prompted subagent to gather relevant context and apply a risk-based decision framework before approving or denying the request. The legacy value `guardian_subagent` is accepted for compatibility.",
|
||||
"enum": [
|
||||
@@ -123,8 +101,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -516,12 +492,6 @@
|
||||
],
|
||||
"description": "Override where approval requests are routed for review on this turn and subsequent turns."
|
||||
},
|
||||
"clientUserMessageId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"cwd": {
|
||||
"description": "Override the working directory for this turn and subsequent turns.",
|
||||
"type": [
|
||||
|
||||
@@ -424,8 +424,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -644,12 +642,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -424,8 +424,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -644,12 +642,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -1,28 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"AdditionalContextEntry": {
|
||||
"properties": {
|
||||
"kind": {
|
||||
"$ref": "#/definitions/AdditionalContextKind"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"value"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"AdditionalContextKind": {
|
||||
"enum": [
|
||||
"untrusted",
|
||||
"application"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ByteRange": {
|
||||
"properties": {
|
||||
"end": {
|
||||
@@ -44,8 +22,6 @@
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
"low",
|
||||
"high",
|
||||
"original"
|
||||
],
|
||||
@@ -218,12 +194,6 @@
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"clientUserMessageId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"expectedTurnId": {
|
||||
"description": "Required active turn id precondition. The request fails when it does not match the currently active turn.",
|
||||
"type": "string"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -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 ImageDetail = "auto" | "low" | "high" | "original";
|
||||
export type ImageDetail = "high" | "original";
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { JsonValue } from "./serde_json/JsonValue";
|
||||
|
||||
/**
|
||||
* Presentation metadata advertised by an initialized MCP server.
|
||||
*/
|
||||
export type McpServerInfo = { name: string, title: string | null, version: string, description: string | null, icons: Array<JsonValue> | null, websiteUrl: string | null, };
|
||||
@@ -42,7 +42,6 @@ export type { InternalSessionSource } from "./InternalSessionSource";
|
||||
export type { LocalShellAction } from "./LocalShellAction";
|
||||
export type { LocalShellExecAction } from "./LocalShellExecAction";
|
||||
export type { LocalShellStatus } from "./LocalShellStatus";
|
||||
export type { McpServerInfo } from "./McpServerInfo";
|
||||
export type { MessagePhase } from "./MessagePhase";
|
||||
export type { ModeKind } from "./ModeKind";
|
||||
export type { NetworkPolicyAmendment } from "./NetworkPolicyAmendment";
|
||||
|
||||
@@ -3,11 +3,4 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { RateLimitSnapshot } from "./RateLimitSnapshot";
|
||||
|
||||
/**
|
||||
* Sparse rolling rate-limit update.
|
||||
*
|
||||
* Clients should merge available values into the most recent `account/rateLimits/read` response
|
||||
* or refetch that snapshot. Nullable account metadata may be unavailable in a rolling update and
|
||||
* does not clear a previously observed value.
|
||||
*/
|
||||
export type AccountRateLimitsUpdatedNotification = { rateLimits: RateLimitSnapshot, };
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AdditionalContextKind } from "./AdditionalContextKind";
|
||||
|
||||
export type AdditionalContextEntry = { value: string, kind: AdditionalContextKind, };
|
||||
@@ -1,5 +0,0 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type AdditionalContextKind = "untrusted" | "application";
|
||||
@@ -3,7 +3,6 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AppToolApproval } from "./AppToolApproval";
|
||||
import type { AppToolsConfig } from "./AppToolsConfig";
|
||||
import type { ApprovalsReviewer } from "./ApprovalsReviewer";
|
||||
import type { AppsDefaultConfig } from "./AppsDefaultConfig";
|
||||
|
||||
export type AppsConfig = { _default: AppsDefaultConfig | null, } & ({ [key in string]?: { enabled: boolean, approvals_reviewer: ApprovalsReviewer | null, destructive_enabled: boolean | null, open_world_enabled: boolean | null, default_tools_approval_mode: AppToolApproval | null, default_tools_enabled: boolean | null, tools: AppToolsConfig | null, } });
|
||||
export type AppsConfig = { _default: AppsDefaultConfig | null, } & ({ [key in string]?: { enabled: boolean, destructive_enabled: boolean | null, open_world_enabled: boolean | null, default_tools_approval_mode: AppToolApproval | null, default_tools_enabled: boolean | null, tools: AppToolsConfig | null, } });
|
||||
|
||||
@@ -8,17 +8,7 @@ export type ConfigLayerSource = { "type": "mdm", domain: string, key: string, }
|
||||
* This is the path to the system config.toml file, though it is not
|
||||
* guaranteed to exist.
|
||||
*/
|
||||
file: AbsolutePathBuf, } | { "type": "enterpriseManaged",
|
||||
/**
|
||||
* Stable identifier for the delivered layer.
|
||||
*/
|
||||
id: string,
|
||||
/**
|
||||
* Admin-facing name for the delivered layer. This is surfaced in
|
||||
* diagnostics so users know which cloud layer needs administrator
|
||||
* attention.
|
||||
*/
|
||||
name: string, } | { "type": "user",
|
||||
file: AbsolutePathBuf, } | { "type": "user",
|
||||
/**
|
||||
* This is the path to the user's config.toml file, though it is not
|
||||
* guaranteed to exist.
|
||||
|
||||
@@ -6,6 +6,5 @@ import type { AskForApproval } from "./AskForApproval";
|
||||
import type { ComputerUseRequirements } from "./ComputerUseRequirements";
|
||||
import type { ResidencyRequirement } from "./ResidencyRequirement";
|
||||
import type { SandboxMode } from "./SandboxMode";
|
||||
import type { WindowsSandboxSetupMode } from "./WindowsSandboxSetupMode";
|
||||
|
||||
export type ConfigRequirements = {allowedApprovalPolicies: Array<AskForApproval> | null, allowedSandboxModes: Array<SandboxMode> | null, allowedWindowsSandboxImplementations: Array<WindowsSandboxSetupMode> | null, allowedPermissions: Array<string> | null, allowedWebSearchModes: Array<WebSearchMode> | null, allowManagedHooksOnly: boolean | null, allowAppshots: boolean | null, computerUse: ComputerUseRequirements | null, featureRequirements: { [key in string]?: boolean } | null, enforceResidency: ResidencyRequirement | null};
|
||||
export type ConfigRequirements = {allowedApprovalPolicies: Array<AskForApproval> | null, allowedSandboxModes: Array<SandboxMode> | null, allowedPermissions: Array<string> | null, allowedWebSearchModes: Array<WebSearchMode> | null, allowManagedHooksOnly: boolean | null, allowAppshots: boolean | null, computerUse: ComputerUseRequirements | null, featureRequirements: { [key in string]?: boolean } | null, enforceResidency: ResidencyRequirement | null};
|
||||
|
||||
@@ -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 HookSource = "system" | "user" | "project" | "mdm" | "sessionFlags" | "plugin" | "cloudRequirements" | "cloudManagedConfig" | "legacyManagedConfigFile" | "legacyManagedConfigMdm" | "unknown";
|
||||
export type HookSource = "system" | "user" | "project" | "mdm" | "sessionFlags" | "plugin" | "cloudRequirements" | "legacyManagedConfigFile" | "legacyManagedConfigMdm" | "unknown";
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { McpServerInfo } from "../McpServerInfo";
|
||||
import type { Resource } from "../Resource";
|
||||
import type { ResourceTemplate } from "../ResourceTemplate";
|
||||
import type { Tool } from "../Tool";
|
||||
import type { McpAuthStatus } from "./McpAuthStatus";
|
||||
|
||||
export type McpServerStatus = { name: string, serverInfo: McpServerInfo | null, tools: { [key in string]?: Tool }, resources: Array<Resource>, resourceTemplates: Array<ResourceTemplate>, authStatus: McpAuthStatus, };
|
||||
export type McpServerStatus = { name: string, tools: { [key in string]?: Tool }, resources: Array<Resource>, resourceTemplates: Array<ResourceTemplate>, authStatus: McpAuthStatus, };
|
||||
|
||||
@@ -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 NetworkUnixSocketPermission = "allow" | "deny";
|
||||
export type NetworkUnixSocketPermission = "allow" | "none";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
import type { RequestPermissionProfile } from "./RequestPermissionProfile";
|
||||
|
||||
export type PermissionsRequestApprovalParams = { threadId: string, turnId: string, itemId: string, environmentId: string | null,
|
||||
export type PermissionsRequestApprovalParams = { threadId: string, turnId: string, itemId: string,
|
||||
/**
|
||||
* Unix timestamp (in milliseconds) when this approval request started.
|
||||
*/
|
||||
|
||||
@@ -5,6 +5,5 @@ import type { PlanType } from "../PlanType";
|
||||
import type { CreditsSnapshot } from "./CreditsSnapshot";
|
||||
import type { RateLimitReachedType } from "./RateLimitReachedType";
|
||||
import type { RateLimitWindow } from "./RateLimitWindow";
|
||||
import type { SpendControlLimitSnapshot } from "./SpendControlLimitSnapshot";
|
||||
|
||||
export type RateLimitSnapshot = { limitId: string | null, limitName: string | null, primary: RateLimitWindow | null, secondary: RateLimitWindow | null, credits: CreditsSnapshot | null, individualLimit: SpendControlLimitSnapshot | null, planType: PlanType | null, rateLimitReachedType: RateLimitReachedType | null, };
|
||||
export type RateLimitSnapshot = { limitId: string | null, limitName: string | null, primary: RateLimitWindow | null, secondary: RateLimitWindow | null, credits: CreditsSnapshot | null, planType: PlanType | null, rateLimitReachedType: RateLimitReachedType | null, };
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
|
||||
export type SkillsExtraRootsSetParams = { extraRoots: Array<AbsolutePathBuf>, };
|
||||
@@ -1,5 +0,0 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type SkillsExtraRootsSetResponse = Record<string, never>;
|
||||
@@ -1,5 +0,0 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type SpendControlLimitSnapshot = { limit: string, used: string, remainingPercent: number, resetsAt: number, };
|
||||
@@ -17,10 +17,6 @@ sessionId: string,
|
||||
* Source thread id when this thread was created by forking another thread.
|
||||
*/
|
||||
forkedFromId: string | null,
|
||||
/**
|
||||
* The ID of the parent thread. This will only be set if this thread is a subagent.
|
||||
*/
|
||||
parentThreadId: string | null,
|
||||
/**
|
||||
* Usually the first user message in the thread, if available.
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,7 @@ import type { PatchApplyStatus } from "./PatchApplyStatus";
|
||||
import type { UserInput } from "./UserInput";
|
||||
import type { WebSearchAction } from "./WebSearchAction";
|
||||
|
||||
export type ThreadItem = { "type": "userMessage", id: string, clientId: string | null, content: Array<UserInput>, } | { "type": "hookPrompt", id: string, fragments: Array<HookPromptFragment>, } | { "type": "agentMessage", id: string, text: string, phase: MessagePhase | null, memoryCitation: MemoryCitation | null, } | { "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": "hookPrompt", id: string, fragments: Array<HookPromptFragment>, } | { "type": "agentMessage", id: string, text: string, phase: MessagePhase | null, memoryCitation: MemoryCitation | 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.
|
||||
*/
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { SortDirection } from "./SortDirection";
|
||||
import type { TurnItemsView } from "./TurnItemsView";
|
||||
|
||||
export type ThreadResumeInitialTurnsPageParams = {
|
||||
/**
|
||||
* Optional turn page size.
|
||||
*/
|
||||
limit?: number | null,
|
||||
/**
|
||||
* Optional turn pagination direction; defaults to descending.
|
||||
*/
|
||||
sortDirection?: SortDirection | null,
|
||||
/**
|
||||
* How much item detail to include for each returned turn; defaults to summary.
|
||||
*/
|
||||
itemsView?: TurnItemsView | null, };
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user