mirror of
https://github.com/openai/codex.git
synced 2026-06-04 04:12:03 +00:00
Compare commits
12 Commits
fcoury/mul
...
fcoury/usa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b04edfda9 | ||
|
|
14b8daa140 | ||
|
|
e4fe4716df | ||
|
|
8c5f7dd9da | ||
|
|
3f0045c005 | ||
|
|
83505d85cf | ||
|
|
8f460a1632 | ||
|
|
94b3e3e5eb | ||
|
|
43d4c2ee73 | ||
|
|
da401bd943 | ||
|
|
c59b2774e3 | ||
|
|
8fc9fa833b |
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.
|
||||
|
||||
@@ -3,7 +3,7 @@ version = 1
|
||||
name = "codex"
|
||||
|
||||
[setup]
|
||||
script = "python ./.codex/environments/setup.py"
|
||||
script = ""
|
||||
|
||||
[[actions]]
|
||||
name = "Run"
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
"""Set up ignored files that should be shared with Codex worktrees."""
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
from functools import cache
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@cache
|
||||
def worktree_paths() -> tuple[Path, Path]:
|
||||
script_dir = Path(__file__).resolve().parent
|
||||
worktree_root = git_path(script_dir / "../..", "--show-toplevel")
|
||||
common_git_dir = git_path(worktree_root, "--git-common-dir")
|
||||
return worktree_root, common_git_dir.parent
|
||||
|
||||
|
||||
def git_path(working_directory: Path, argument: str) -> Path:
|
||||
output = subprocess.check_output(
|
||||
[
|
||||
"git",
|
||||
"-C",
|
||||
str(working_directory),
|
||||
"rev-parse",
|
||||
"--path-format=absolute",
|
||||
argument,
|
||||
],
|
||||
text=True,
|
||||
)
|
||||
return Path(output.strip())
|
||||
|
||||
|
||||
def copy_from_main_worktree_to_worktree(repo_relative_path: str) -> None:
|
||||
relative_path = Path(repo_relative_path)
|
||||
if relative_path.is_absolute() or ".." in relative_path.parts:
|
||||
raise ValueError(f"path must be repository-relative: {repo_relative_path}")
|
||||
|
||||
worktree_root, main_worktree = worktree_paths()
|
||||
source_path = main_worktree / relative_path
|
||||
destination_path = worktree_root / relative_path
|
||||
|
||||
print(f" source: {source_path}")
|
||||
print(f" destination: {destination_path}")
|
||||
|
||||
if source_path == destination_path:
|
||||
print(" result: running in the main worktree; nothing to copy")
|
||||
elif destination_path.exists():
|
||||
print(" result: destination already exists; nothing to copy")
|
||||
elif not source_path.is_file():
|
||||
print(" result: source does not exist; nothing to copy")
|
||||
else:
|
||||
destination_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(source_path, destination_path)
|
||||
print(f" result: copied {repo_relative_path}")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print("Codex environment setup:")
|
||||
# See codex-rs/docs/bazel.md for the repository's Bazel workflow.
|
||||
copy_from_main_worktree_to_worktree("user.bazelrc")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
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
|
||||
|
||||
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:
|
||||
|
||||
5
.github/workflows/cargo-deny.yml
vendored
5
.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
|
||||
|
||||
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:
|
||||
|
||||
159
.github/workflows/python-sdk-release.yml
vendored
159
.github/workflows/python-sdk-release.yml
vendored
@@ -4,161 +4,15 @@ 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'
|
||||
if: github.repository == 'openai/codex'
|
||||
name: build-python-sdk
|
||||
needs: publish-python-runtime
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -175,8 +29,13 @@ jobs:
|
||||
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.
|
||||
if [[ ! "${sdk_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+b[0-9]+$ ]]; then
|
||||
echo "Python SDK release tags must identify a beta release, for example python-v0.1.0b1."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The pinned runtime currently publishes a musllinux Linux wheel.
|
||||
# Build in Alpine so release type generation installs that wheel.
|
||||
docker run --rm \
|
||||
--user "$(id -u):$(id -g)" \
|
||||
-e HOME=/tmp/codex-python-sdk-home \
|
||||
@@ -187,7 +46,7 @@ jobs:
|
||||
-v "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}" \
|
||||
-v "${RUNNER_TEMP}:${RUNNER_TEMP}" \
|
||||
-w "${GITHUB_WORKSPACE}/sdk/python" \
|
||||
python:3.12-slim \
|
||||
python:3.12-alpine \
|
||||
sh -euxc '
|
||||
python -m venv /tmp/release-tools
|
||||
/tmp/release-tools/bin/python -m pip install build twine uv==0.11.3
|
||||
|
||||
7
.github/workflows/rust-ci-full.yml
vendored
7
.github/workflows/rust-ci-full.yml
vendored
@@ -402,6 +402,13 @@ jobs:
|
||||
- name: cargo clippy
|
||||
run: cargo clippy --target ${{ matrix.target }} --tests --profile ${{ matrix.profile }} --timings -- -D warnings
|
||||
|
||||
- uses: taiki-e/install-action@44c6d64aa62cd779e873306675c7a58e86d6d532 # v2.62.49
|
||||
with:
|
||||
tool: just
|
||||
|
||||
- name: End-to-end benchmark smoke test
|
||||
run: just bench-e2e-smoke
|
||||
|
||||
- name: Upload Cargo timings (clippy)
|
||||
if: always()
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
|
||||
5
.github/workflows/rust-ci.yml
vendored
5
.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:
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
11
.github/workflows/rust-release-windows.yml
vendored
11
.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 }}
|
||||
@@ -112,15 +107,11 @@ jobs:
|
||||
- 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
|
||||
|
||||
80
.github/workflows/rust-release.yml
vendored
80
.github/workflows/rust-release.yml
vendored
@@ -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:
|
||||
@@ -315,16 +310,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 +882,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 +1106,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
|
||||
@@ -1378,6 +1391,53 @@ jobs:
|
||||
exit "${publish_status}"
|
||||
done
|
||||
|
||||
# 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.should_publish_python_runtime == 'true'
|
||||
}}
|
||||
name: publish-python-runtime
|
||||
needs: release
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
environment: pypi
|
||||
permissions:
|
||||
id-token: write # Required for PyPI trusted publishing.
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- name: Download Python runtime wheels from release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RELEASE_TAG: ${{ needs.release.outputs.tag }}
|
||||
RELEASE_VERSION: ${{ needs.release.outputs.version }}
|
||||
run: |
|
||||
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
|
||||
|
||||
deploy-dev-website:
|
||||
name: Trigger developers.openai.com deploy
|
||||
needs: release
|
||||
|
||||
10
.github/workflows/rusty-v8-release.yml
vendored
10
.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
|
||||
@@ -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
|
||||
|
||||
12
.github/workflows/v8-canary.yml
vendored
12
.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' }}
|
||||
@@ -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:
|
||||
|
||||
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.
|
||||
|
||||
106
codex-rs/Cargo.lock
generated
106
codex-rs/Cargo.lock
generated
@@ -1913,7 +1913,7 @@ dependencies = [
|
||||
"codex-arg0",
|
||||
"codex-backend-client",
|
||||
"codex-chatgpt",
|
||||
"codex-cloud-config",
|
||||
"codex-cloud-requirements",
|
||||
"codex-config",
|
||||
"codex-core",
|
||||
"codex-core-plugins",
|
||||
@@ -1928,7 +1928,6 @@ dependencies = [
|
||||
"codex-git-utils",
|
||||
"codex-guardian",
|
||||
"codex-hooks",
|
||||
"codex-image-generation-extension",
|
||||
"codex-login",
|
||||
"codex-mcp",
|
||||
"codex-memories-extension",
|
||||
@@ -2059,6 +2058,17 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-app-server-start-bench"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"codex-app-server-protocol",
|
||||
"divan",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-app-server-test-client"
|
||||
version = "0.0.0"
|
||||
@@ -2344,9 +2354,10 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-cloud-config"
|
||||
name = "codex-cloud-requirements"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"codex-backend-client",
|
||||
@@ -2355,6 +2366,7 @@ dependencies = [
|
||||
"codex-login",
|
||||
"codex-otel",
|
||||
"codex-protocol",
|
||||
"codex-utils-absolute-path",
|
||||
"hmac 0.12.1",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
@@ -2363,6 +2375,7 @@ dependencies = [
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
"toml 0.9.11+spec-1.1.0",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
@@ -2427,6 +2440,8 @@ dependencies = [
|
||||
name = "codex-code-mode"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-trait",
|
||||
"codex-protocol",
|
||||
"deno_core_icudata",
|
||||
"pretty_assertions",
|
||||
@@ -2506,14 +2521,6 @@ dependencies = [
|
||||
"urlencoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-context-fragments"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"codex-protocol",
|
||||
"codex-utils-string",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-core"
|
||||
version = "0.0.0"
|
||||
@@ -2536,7 +2543,6 @@ dependencies = [
|
||||
"codex-code-mode",
|
||||
"codex-config",
|
||||
"codex-connectors",
|
||||
"codex-context-fragments",
|
||||
"codex-core-plugins",
|
||||
"codex-core-skills",
|
||||
"codex-exec-server",
|
||||
@@ -2556,7 +2562,6 @@ dependencies = [
|
||||
"codex-network-proxy",
|
||||
"codex-otel",
|
||||
"codex-plugin",
|
||||
"codex-prompts",
|
||||
"codex-protocol",
|
||||
"codex-response-debug-context",
|
||||
"codex-rmcp-client",
|
||||
@@ -2581,6 +2586,7 @@ dependencies = [
|
||||
"codex-utils-pty",
|
||||
"codex-utils-stream-parser",
|
||||
"codex-utils-string",
|
||||
"codex-utils-template",
|
||||
"codex-windows-sandbox",
|
||||
"core_test_support",
|
||||
"csv",
|
||||
@@ -2675,7 +2681,6 @@ dependencies = [
|
||||
"codex-utils-plugins",
|
||||
"dirs",
|
||||
"flate2",
|
||||
"indexmap 2.13.0",
|
||||
"libc",
|
||||
"pretty_assertions",
|
||||
"reqwest 0.12.28",
|
||||
@@ -2701,7 +2706,6 @@ dependencies = [
|
||||
"codex-analytics",
|
||||
"codex-app-server-protocol",
|
||||
"codex-config",
|
||||
"codex-context-fragments",
|
||||
"codex-exec-server",
|
||||
"codex-login",
|
||||
"codex-model-provider",
|
||||
@@ -2725,6 +2729,18 @@ dependencies = [
|
||||
"zip 2.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-debug-client"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"codex-app-server-protocol",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-exec"
|
||||
version = "0.0.0"
|
||||
@@ -2736,7 +2752,7 @@ dependencies = [
|
||||
"codex-app-server-protocol",
|
||||
"codex-apply-patch",
|
||||
"codex-arg0",
|
||||
"codex-cloud-config",
|
||||
"codex-cloud-requirements",
|
||||
"codex-config",
|
||||
"codex-core",
|
||||
"codex-feedback",
|
||||
@@ -2863,7 +2879,6 @@ name = "codex-extension-api"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"codex-context-fragments",
|
||||
"codex-protocol",
|
||||
"codex-tools",
|
||||
]
|
||||
@@ -2994,7 +3009,6 @@ dependencies = [
|
||||
"codex-protocol",
|
||||
"codex-state",
|
||||
"codex-tools",
|
||||
"codex-utils-template",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -3036,27 +3050,6 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-image-generation-extension"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"codex-api",
|
||||
"codex-core",
|
||||
"codex-extension-api",
|
||||
"codex-features",
|
||||
"codex-login",
|
||||
"codex-model-provider",
|
||||
"codex-model-provider-info",
|
||||
"codex-protocol",
|
||||
"codex-tools",
|
||||
"http 1.4.0",
|
||||
"pretty_assertions",
|
||||
"schemars 0.8.22",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-install-context"
|
||||
version = "0.0.0"
|
||||
@@ -3367,7 +3360,6 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"clap",
|
||||
"codex-utils-absolute-path",
|
||||
@@ -3383,10 +3375,8 @@ dependencies = [
|
||||
"rama-tcp",
|
||||
"rama-tls-rustls",
|
||||
"rama-unix",
|
||||
"rustls-native-certs",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.9",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
@@ -3464,20 +3454,6 @@ dependencies = [
|
||||
"pretty_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-prompts"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"codex-context-fragments",
|
||||
"codex-execpolicy",
|
||||
"codex-git-utils",
|
||||
"codex-protocol",
|
||||
"codex-utils-absolute-path",
|
||||
"codex-utils-template",
|
||||
"pretty_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-protocol"
|
||||
version = "0.0.0"
|
||||
@@ -3607,6 +3583,7 @@ dependencies = [
|
||||
"codex-protocol",
|
||||
"codex-state",
|
||||
"codex-utils-path",
|
||||
"codex-utils-string",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
"serde",
|
||||
@@ -3616,7 +3593,6 @@ dependencies = [
|
||||
"tokio",
|
||||
"tracing",
|
||||
"uuid",
|
||||
"zstd 0.13.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3727,19 +3703,6 @@ dependencies = [
|
||||
"thiserror 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-skills-extension"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"codex-core",
|
||||
"codex-core-skills",
|
||||
"codex-extension-api",
|
||||
"codex-protocol",
|
||||
"pretty_assertions",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-state"
|
||||
version = "0.0.0"
|
||||
@@ -3863,7 +3826,7 @@ dependencies = [
|
||||
"codex-app-server-protocol",
|
||||
"codex-arg0",
|
||||
"codex-cli",
|
||||
"codex-cloud-config",
|
||||
"codex-cloud-requirements",
|
||||
"codex-config",
|
||||
"codex-connectors",
|
||||
"codex-core-plugins",
|
||||
@@ -4208,7 +4171,6 @@ dependencies = [
|
||||
"pretty_assertions",
|
||||
"schemars 0.8.22",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -14,6 +14,8 @@ members = [
|
||||
"app-server-client",
|
||||
"app-server-protocol",
|
||||
"app-server-test-client",
|
||||
"benchmarks/app-server-start",
|
||||
"debug-client",
|
||||
"apply-patch",
|
||||
"arg0",
|
||||
"feedback",
|
||||
@@ -21,7 +23,7 @@ members = [
|
||||
"install-context",
|
||||
"codex-backend-openapi-models",
|
||||
"code-mode",
|
||||
"cloud-config",
|
||||
"cloud-requirements",
|
||||
"cloud-tasks",
|
||||
"cloud-tasks-client",
|
||||
"cloud-tasks-mock-client",
|
||||
@@ -29,7 +31,6 @@ members = [
|
||||
"collaboration-mode-templates",
|
||||
"connectors",
|
||||
"config",
|
||||
"context-fragments",
|
||||
"shell-command",
|
||||
"shell-escalation",
|
||||
"skills",
|
||||
@@ -47,9 +48,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",
|
||||
@@ -70,7 +69,6 @@ members = [
|
||||
"process-hardening",
|
||||
"protocol",
|
||||
"realtime-webrtc",
|
||||
"prompts",
|
||||
"rollout",
|
||||
"rollout-trace",
|
||||
"rmcp-client",
|
||||
@@ -151,13 +149,12 @@ 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" }
|
||||
codex-config = { path = "config" }
|
||||
codex-connectors = { path = "connectors" }
|
||||
codex-context-fragments = { path = "context-fragments" }
|
||||
codex-core = { path = "core" }
|
||||
codex-core-api = { path = "core-api" }
|
||||
codex-core-plugins = { path = "core-plugins" }
|
||||
@@ -169,7 +166,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" }
|
||||
@@ -201,7 +197,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" }
|
||||
|
||||
@@ -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,
|
||||
@@ -285,7 +272,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 +377,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 +391,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(),
|
||||
@@ -836,7 +820,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()),
|
||||
@@ -846,7 +829,6 @@ fn sample_permissions_approval_request(request_id: i64) -> ServerRequest {
|
||||
}),
|
||||
file_system: None,
|
||||
},
|
||||
workspace_mutation: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1771,7 +1753,6 @@ async fn compaction_event_ingests_custom_fact() {
|
||||
agent_role: None,
|
||||
}),
|
||||
Some(AppServerThreadSource::Subagent),
|
||||
Some(parent_thread_id.to_string()),
|
||||
)),
|
||||
},
|
||||
&mut events,
|
||||
@@ -2473,7 +2454,7 @@ fn subagent_thread_started_thread_spawn_serializes_parent_thread_id() {
|
||||
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(),
|
||||
@@ -2551,14 +2532,11 @@ 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(),
|
||||
@@ -2573,7 +2551,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"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2662,7 +2640,7 @@ async fn subagent_thread_started_inherits_parent_connection_for_new_thread() {
|
||||
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(),
|
||||
@@ -3257,14 +3235,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,
|
||||
@@ -3323,14 +3297,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,
|
||||
@@ -3644,7 +3614,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));
|
||||
@@ -3997,18 +3966,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(
|
||||
@@ -4025,18 +3982,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]
|
||||
@@ -4069,7 +4014,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,7 +101,6 @@ 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 +122,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(),
|
||||
|
||||
@@ -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;
|
||||
@@ -794,14 +793,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>,
|
||||
@@ -1017,7 +1012,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",
|
||||
@@ -1053,7 +1047,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 +1059,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 {
|
||||
@@ -475,7 +329,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;
|
||||
@@ -268,18 +267,20 @@ impl ThreadMetadataState {
|
||||
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,
|
||||
@@ -324,7 +325,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 +464,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 +516,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))
|
||||
@@ -612,7 +612,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 +636,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 +645,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 +801,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 +1160,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 +1181,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 +1200,6 @@ impl AnalyticsReducer {
|
||||
started_at: None,
|
||||
token_usage: None,
|
||||
completed: None,
|
||||
codex_error: None,
|
||||
latest_diff: None,
|
||||
steer_count: 0,
|
||||
tool_counts: TurnToolCounts::default(),
|
||||
@@ -1267,7 +1238,6 @@ impl AnalyticsReducer {
|
||||
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;
|
||||
};
|
||||
@@ -1275,7 +1245,6 @@ impl AnalyticsReducer {
|
||||
session_id.clone(),
|
||||
&session_source,
|
||||
thread.thread_source.map(Into::into),
|
||||
parent_thread_id,
|
||||
initialization_mode,
|
||||
);
|
||||
self.threads.insert(
|
||||
@@ -2483,11 +2452,9 @@ 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(),
|
||||
@@ -2516,14 +2483,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,
|
||||
|
||||
@@ -2988,20 +2988,6 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsExtraRootsSetParams": {
|
||||
"properties": {
|
||||
"extraRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"extraRoots"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SkillsListParams": {
|
||||
"properties": {
|
||||
"cwds": {
|
||||
@@ -3999,12 +3985,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 +4071,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"
|
||||
@@ -4118,6 +4092,24 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageRange": {
|
||||
"enum": [
|
||||
"day",
|
||||
"week"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageReadParams": {
|
||||
"properties": {
|
||||
"range": {
|
||||
"$ref": "#/definitions/UsageRange"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"range"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UserInput": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -4797,30 +4789,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": {
|
||||
@@ -4941,6 +4909,30 @@
|
||||
"title": "Plugin/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"usage/read"
|
||||
],
|
||||
"title": "Usage/readRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/UsageReadParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Usage/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
|
||||
@@ -279,48 +279,12 @@
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationApprovalRequest": {
|
||||
"properties": {
|
||||
"operation": {
|
||||
"$ref": "#/definitions/WorkspaceMutationOperation"
|
||||
},
|
||||
"resultingWorkspaceRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation",
|
||||
"resultingWorkspaceRoots",
|
||||
"target"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationOperation": {
|
||||
"enum": [
|
||||
"setWorkingDirectory",
|
||||
"addWorkspaceRoot"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"cwd": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"environmentId": {
|
||||
"default": null,
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"itemId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -343,16 +307,6 @@
|
||||
},
|
||||
"turnId": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceMutation": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/WorkspaceMutationApprovalRequest"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -365,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"
|
||||
@@ -1740,16 +1739,6 @@
|
||||
],
|
||||
"title": "RequestPermissionsGuardianApprovalReviewActionType",
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceMutation": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/WorkspaceMutationApprovalRequest"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -2013,7 +2002,6 @@
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"cloudManagedConfig",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
@@ -2688,16 +2676,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"individualLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SpendControlLimitSnapshot"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"limitId": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -3156,31 +3134,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": [
|
||||
{
|
||||
@@ -3412,13 +3365,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": [
|
||||
@@ -3615,12 +3561,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
@@ -5314,35 +5254,6 @@
|
||||
"samplePaths"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationApprovalRequest": {
|
||||
"properties": {
|
||||
"operation": {
|
||||
"$ref": "#/definitions/WorkspaceMutationOperation"
|
||||
},
|
||||
"resultingWorkspaceRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation",
|
||||
"resultingWorkspaceRoots",
|
||||
"target"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationOperation": {
|
||||
"enum": [
|
||||
"setWorkingDirectory",
|
||||
"addWorkspaceRoot"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"description": "Notification sent from the server to the client.",
|
||||
|
||||
@@ -1590,13 +1590,6 @@
|
||||
"cwd": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"environmentId": {
|
||||
"default": null,
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"itemId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -1619,16 +1612,6 @@
|
||||
},
|
||||
"turnId": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceMutation": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/WorkspaceMutationApprovalRequest"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -1760,35 +1743,6 @@
|
||||
"question"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationApprovalRequest": {
|
||||
"properties": {
|
||||
"operation": {
|
||||
"$ref": "#/definitions/WorkspaceMutationOperation"
|
||||
},
|
||||
"resultingWorkspaceRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation",
|
||||
"resultingWorkspaceRoots",
|
||||
"target"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationOperation": {
|
||||
"enum": [
|
||||
"setWorkingDirectory",
|
||||
"addWorkspaceRoot"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"description": "Request initiated from the server and sent to the client.",
|
||||
@@ -2044,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": {
|
||||
@@ -853,6 +829,30 @@
|
||||
"title": "Plugin/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"usage/read"
|
||||
],
|
||||
"title": "Usage/readRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/UsageReadParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Usage/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -3783,13 +3783,6 @@
|
||||
"cwd": {
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
},
|
||||
"environmentId": {
|
||||
"default": null,
|
||||
"type": [
|
||||
"null",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"itemId": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -3812,16 +3805,6 @@
|
||||
},
|
||||
"turnId": {
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceMutation": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/WorkspaceMutationApprovalRequest"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -5737,7 +5720,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"
|
||||
@@ -5969,16 +5951,6 @@
|
||||
},
|
||||
"AppConfig": {
|
||||
"properties": {
|
||||
"approvals_reviewer": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/ApprovalsReviewer"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_tools_approval_mode": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -7631,33 +7603,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": {
|
||||
@@ -7864,15 +7809,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"allowedWindowsSandboxImplementations": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/WindowsSandboxSetupMode"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"computerUse": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -9775,16 +9711,6 @@
|
||||
],
|
||||
"title": "RequestPermissionsGuardianApprovalReviewActionType",
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceMutation": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/WorkspaceMutationApprovalRequest"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -10156,7 +10082,6 @@
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"cloudManagedConfig",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
@@ -11944,7 +11869,7 @@
|
||||
"NetworkUnixSocketPermission": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -13365,16 +13290,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"individualLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/SpendControlLimitSnapshot"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"limitId": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -15230,27 +15145,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": {
|
||||
@@ -15317,31 +15211,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": [
|
||||
{
|
||||
@@ -15586,13 +15455,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": [
|
||||
@@ -16158,12 +16020,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/UserInput"
|
||||
@@ -18581,12 +18437,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": [
|
||||
@@ -18714,12 +18564,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"
|
||||
@@ -18781,6 +18625,177 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageContributorKind": {
|
||||
"enum": [
|
||||
"skill",
|
||||
"subagent",
|
||||
"agentTask",
|
||||
"app",
|
||||
"mcpServer",
|
||||
"plugin"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageEntry": {
|
||||
"properties": {
|
||||
"attributedTokens": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"$ref": "#/definitions/v2/UsageContributorKind"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"percentOfUsage": {
|
||||
"format": "uint8",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"attributedTokens",
|
||||
"id",
|
||||
"kind",
|
||||
"label",
|
||||
"percentOfUsage"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageHeadline": {
|
||||
"properties": {
|
||||
"entry": {
|
||||
"$ref": "#/definitions/v2/UsageEntry"
|
||||
},
|
||||
"note": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entry"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageRange": {
|
||||
"enum": [
|
||||
"day",
|
||||
"week"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageReadParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"range": {
|
||||
"$ref": "#/definitions/v2/UsageRange"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"range"
|
||||
],
|
||||
"title": "UsageReadParams",
|
||||
"type": "object"
|
||||
},
|
||||
"UsageReadResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/v2/UsageReport"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"report"
|
||||
],
|
||||
"title": "UsageReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"UsageReport": {
|
||||
"properties": {
|
||||
"agentTasks": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"apps": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"generatedAt": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"headline": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/UsageHeadline"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mcpServers": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"plugins": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"range": {
|
||||
"$ref": "#/definitions/v2/UsageRange"
|
||||
},
|
||||
"skills": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"subagents": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"totalTokens": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"trackedFrom": {
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"agentTasks",
|
||||
"apps",
|
||||
"generatedAt",
|
||||
"mcpServers",
|
||||
"plugins",
|
||||
"range",
|
||||
"skills",
|
||||
"subagents",
|
||||
"totalTokens"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UserInput": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -19248,35 +19263,6 @@
|
||||
"title": "WindowsWorldWritableWarningNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationApprovalRequest": {
|
||||
"properties": {
|
||||
"operation": {
|
||||
"$ref": "#/definitions/v2/WorkspaceMutationOperation"
|
||||
},
|
||||
"resultingWorkspaceRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation",
|
||||
"resultingWorkspaceRoots",
|
||||
"target"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationOperation": {
|
||||
"enum": [
|
||||
"setWorkingDirectory",
|
||||
"addWorkspaceRoot"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"WriteStatus": {
|
||||
"enum": [
|
||||
"ok",
|
||||
@@ -19288,4 +19274,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"
|
||||
@@ -324,16 +323,6 @@
|
||||
},
|
||||
"AppConfig": {
|
||||
"properties": {
|
||||
"approvals_reviewer": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ApprovalsReviewer"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_tools_approval_mode": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -1468,30 +1457,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": {
|
||||
@@ -1612,6 +1577,30 @@
|
||||
"title": "Plugin/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"usage/read"
|
||||
],
|
||||
"title": "Usage/readRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/UsageReadParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Usage/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -3983,33 +3972,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 +4178,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"allowedWindowsSandboxImplementations": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/WindowsSandboxSetupMode"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"computerUse": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -6238,16 +6191,6 @@
|
||||
],
|
||||
"title": "RequestPermissionsGuardianApprovalReviewActionType",
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceMutation": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/WorkspaceMutationApprovalRequest"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -6619,7 +6562,6 @@
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"cloudManagedConfig",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
@@ -8456,7 +8398,7 @@
|
||||
"NetworkUnixSocketPermission": {
|
||||
"enum": [
|
||||
"allow",
|
||||
"deny"
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
@@ -9877,16 +9819,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"individualLimit": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SpendControlLimitSnapshot"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"limitId": {
|
||||
"type": [
|
||||
"string",
|
||||
@@ -13037,27 +12969,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": {
|
||||
@@ -13124,31 +13035,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": [
|
||||
{
|
||||
@@ -13393,13 +13279,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": [
|
||||
@@ -13965,12 +13844,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
@@ -16388,12 +16261,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": [
|
||||
@@ -16521,12 +16388,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"
|
||||
@@ -16588,6 +16449,177 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageContributorKind": {
|
||||
"enum": [
|
||||
"skill",
|
||||
"subagent",
|
||||
"agentTask",
|
||||
"app",
|
||||
"mcpServer",
|
||||
"plugin"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageEntry": {
|
||||
"properties": {
|
||||
"attributedTokens": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"$ref": "#/definitions/UsageContributorKind"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"percentOfUsage": {
|
||||
"format": "uint8",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"attributedTokens",
|
||||
"id",
|
||||
"kind",
|
||||
"label",
|
||||
"percentOfUsage"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageHeadline": {
|
||||
"properties": {
|
||||
"entry": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"note": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entry"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageRange": {
|
||||
"enum": [
|
||||
"day",
|
||||
"week"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageReadParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"range": {
|
||||
"$ref": "#/definitions/UsageRange"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"range"
|
||||
],
|
||||
"title": "UsageReadParams",
|
||||
"type": "object"
|
||||
},
|
||||
"UsageReadResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/UsageReport"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"report"
|
||||
],
|
||||
"title": "UsageReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"UsageReport": {
|
||||
"properties": {
|
||||
"agentTasks": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"apps": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"generatedAt": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"headline": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/UsageHeadline"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mcpServers": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"plugins": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"range": {
|
||||
"$ref": "#/definitions/UsageRange"
|
||||
},
|
||||
"skills": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"subagents": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"totalTokens": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"trackedFrom": {
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"agentTasks",
|
||||
"apps",
|
||||
"generatedAt",
|
||||
"mcpServers",
|
||||
"plugins",
|
||||
"range",
|
||||
"skills",
|
||||
"subagents",
|
||||
"totalTokens"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UserInput": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -17055,35 +17087,6 @@
|
||||
"title": "WindowsWorldWritableWarningNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationApprovalRequest": {
|
||||
"properties": {
|
||||
"operation": {
|
||||
"$ref": "#/definitions/WorkspaceMutationOperation"
|
||||
},
|
||||
"resultingWorkspaceRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation",
|
||||
"resultingWorkspaceRoots",
|
||||
"target"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationOperation": {
|
||||
"enum": [
|
||||
"setWorkingDirectory",
|
||||
"addWorkspaceRoot"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"WriteStatus": {
|
||||
"enum": [
|
||||
"ok",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -500,12 +500,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -484,16 +484,6 @@
|
||||
],
|
||||
"title": "RequestPermissionsGuardianApprovalReviewActionType",
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceMutation": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/WorkspaceMutationApprovalRequest"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -577,35 +567,6 @@
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationApprovalRequest": {
|
||||
"properties": {
|
||||
"operation": {
|
||||
"$ref": "#/definitions/WorkspaceMutationOperation"
|
||||
},
|
||||
"resultingWorkspaceRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation",
|
||||
"resultingWorkspaceRoots",
|
||||
"target"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationOperation": {
|
||||
"enum": [
|
||||
"setWorkingDirectory",
|
||||
"addWorkspaceRoot"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"description": "[UNSTABLE] Temporary notification payload for approval auto-review. This shape is expected to change soon.",
|
||||
|
||||
@@ -477,16 +477,6 @@
|
||||
],
|
||||
"title": "RequestPermissionsGuardianApprovalReviewActionType",
|
||||
"type": "string"
|
||||
},
|
||||
"workspaceMutation": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/WorkspaceMutationApprovalRequest"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -570,35 +560,6 @@
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationApprovalRequest": {
|
||||
"properties": {
|
||||
"operation": {
|
||||
"$ref": "#/definitions/WorkspaceMutationOperation"
|
||||
},
|
||||
"resultingWorkspaceRoots": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation",
|
||||
"resultingWorkspaceRoots",
|
||||
"target"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkspaceMutationOperation": {
|
||||
"enum": [
|
||||
"setWorkingDirectory",
|
||||
"addWorkspaceRoot"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"description": "[UNSTABLE] Temporary notification payload for approval auto-review. This shape is expected to change soon.",
|
||||
|
||||
@@ -500,12 +500,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -644,12 +644,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"
|
||||
}
|
||||
@@ -1036,13 +1036,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 +1121,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -851,13 +851,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 +936,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -851,13 +851,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 +936,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -851,13 +851,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 +936,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -1036,13 +1036,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 +1121,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -851,13 +851,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 +936,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -1036,13 +1036,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 +1121,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -851,13 +851,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 +936,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -851,13 +851,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 +936,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -644,12 +644,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -516,12 +516,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": [
|
||||
|
||||
@@ -644,12 +644,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -644,12 +644,6 @@
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"clientId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UserInput"
|
||||
|
||||
@@ -218,12 +218,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"
|
||||
|
||||
22
codex-rs/app-server-protocol/schema/json/v2/UsageReadParams.json
generated
Normal file
22
codex-rs/app-server-protocol/schema/json/v2/UsageReadParams.json
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"UsageRange": {
|
||||
"enum": [
|
||||
"day",
|
||||
"week"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"range": {
|
||||
"$ref": "#/definitions/UsageRange"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"range"
|
||||
],
|
||||
"title": "UsageReadParams",
|
||||
"type": "object"
|
||||
}
|
||||
160
codex-rs/app-server-protocol/schema/json/v2/UsageReadResponse.json
generated
Normal file
160
codex-rs/app-server-protocol/schema/json/v2/UsageReadResponse.json
generated
Normal file
@@ -0,0 +1,160 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"UsageContributorKind": {
|
||||
"enum": [
|
||||
"skill",
|
||||
"subagent",
|
||||
"agentTask",
|
||||
"app",
|
||||
"mcpServer",
|
||||
"plugin"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageEntry": {
|
||||
"properties": {
|
||||
"attributedTokens": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"kind": {
|
||||
"$ref": "#/definitions/UsageContributorKind"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"percentOfUsage": {
|
||||
"format": "uint8",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"attributedTokens",
|
||||
"id",
|
||||
"kind",
|
||||
"label",
|
||||
"percentOfUsage"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageHeadline": {
|
||||
"properties": {
|
||||
"entry": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"note": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entry"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"UsageRange": {
|
||||
"enum": [
|
||||
"day",
|
||||
"week"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"UsageReport": {
|
||||
"properties": {
|
||||
"agentTasks": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"apps": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"generatedAt": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"headline": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/UsageHeadline"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"mcpServers": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"plugins": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"range": {
|
||||
"$ref": "#/definitions/UsageRange"
|
||||
},
|
||||
"skills": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"subagents": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/UsageEntry"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"totalTokens": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"trackedFrom": {
|
||||
"format": "int64",
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"agentTasks",
|
||||
"apps",
|
||||
"generatedAt",
|
||||
"mcpServers",
|
||||
"plugins",
|
||||
"range",
|
||||
"skills",
|
||||
"subagents",
|
||||
"totalTokens"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"report": {
|
||||
"$ref": "#/definitions/UsageReport"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"report"
|
||||
],
|
||||
"title": "UsageReadResponse",
|
||||
"type": "object"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -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, };
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -5,6 +5,5 @@ import type { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
import type { GuardianCommandSource } from "./GuardianCommandSource";
|
||||
import type { NetworkApprovalProtocol } from "./NetworkApprovalProtocol";
|
||||
import type { RequestPermissionProfile } from "./RequestPermissionProfile";
|
||||
import type { WorkspaceMutationApprovalRequest } from "./WorkspaceMutationApprovalRequest";
|
||||
|
||||
export type GuardianApprovalReviewAction = { "type": "command", source: GuardianCommandSource, command: string, cwd: AbsolutePathBuf, } | { "type": "execve", source: GuardianCommandSource, program: string, argv: Array<string>, cwd: AbsolutePathBuf, } | { "type": "applyPatch", cwd: AbsolutePathBuf, files: Array<AbsolutePathBuf>, } | { "type": "networkAccess", target: string, host: string, protocol: NetworkApprovalProtocol, port: number, } | { "type": "mcpToolCall", server: string, toolName: string, connectorId: string | null, connectorName: string | null, toolTitle: string | null, } | { "type": "requestPermissions", reason: string | null, permissions: RequestPermissionProfile, workspaceMutation: WorkspaceMutationApprovalRequest | null, };
|
||||
export type GuardianApprovalReviewAction = { "type": "command", source: GuardianCommandSource, command: string, cwd: AbsolutePathBuf, } | { "type": "execve", source: GuardianCommandSource, program: string, argv: Array<string>, cwd: AbsolutePathBuf, } | { "type": "applyPatch", cwd: AbsolutePathBuf, files: Array<AbsolutePathBuf>, } | { "type": "networkAccess", target: string, host: string, protocol: NetworkApprovalProtocol, port: number, } | { "type": "mcpToolCall", server: string, toolName: string, connectorId: string | null, connectorName: string | null, toolTitle: string | null, } | { "type": "requestPermissions", reason: string | null, permissions: RequestPermissionProfile, };
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
import type { RequestPermissionProfile } from "./RequestPermissionProfile";
|
||||
import type { WorkspaceMutationApprovalRequest } from "./WorkspaceMutationApprovalRequest";
|
||||
|
||||
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.
|
||||
*/
|
||||
startedAtMs: number, cwd: AbsolutePathBuf, reason: string | null, permissions: RequestPermissionProfile, workspaceMutation: WorkspaceMutationApprovalRequest | null, };
|
||||
startedAtMs: number, cwd: AbsolutePathBuf, reason: string | null, permissions: RequestPermissionProfile, };
|
||||
|
||||
@@ -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, };
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { AskForApproval } from "./AskForApproval";
|
||||
import type { SandboxPolicy } from "./SandboxPolicy";
|
||||
import type { UserInput } from "./UserInput";
|
||||
|
||||
export type TurnStartParams = {threadId: string, clientUserMessageId?: string | null, input: Array<UserInput>, /**
|
||||
export type TurnStartParams = {threadId: string, input: Array<UserInput>, /**
|
||||
* Override the working directory for this turn and subsequent turns.
|
||||
*/
|
||||
cwd?: string | null, /**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { UserInput } from "./UserInput";
|
||||
|
||||
export type TurnSteerParams = {threadId: string, clientUserMessageId?: string | null, input: Array<UserInput>, /**
|
||||
export type TurnSteerParams = {threadId: string, input: Array<UserInput>, /**
|
||||
* Required active turn id precondition. The request fails when it does not
|
||||
* match the currently active turn.
|
||||
*/
|
||||
|
||||
@@ -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 SpendControlLimitSnapshot = { limit: string, used: string, remainingPercent: number, resetsAt: number, };
|
||||
export type UsageContributorKind = "skill" | "subagent" | "agentTask" | "app" | "mcpServer" | "plugin";
|
||||
6
codex-rs/app-server-protocol/schema/typescript/v2/UsageEntry.ts
generated
Normal file
6
codex-rs/app-server-protocol/schema/typescript/v2/UsageEntry.ts
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { UsageContributorKind } from "./UsageContributorKind";
|
||||
|
||||
export type UsageEntry = { kind: UsageContributorKind, id: string, label: string, attributedTokens: number, percentOfUsage: number, };
|
||||
@@ -1,6 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
import type { UsageEntry } from "./UsageEntry";
|
||||
|
||||
export type SkillsExtraRootsSetParams = { extraRoots: Array<AbsolutePathBuf>, };
|
||||
export type UsageHeadline = { entry: UsageEntry, note: string | 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 SkillsExtraRootsSetResponse = Record<string, never>;
|
||||
export type UsageRange = "day" | "week";
|
||||
@@ -1,5 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { UsageRange } from "./UsageRange";
|
||||
|
||||
export type WorkspaceMutationOperation = "setWorkingDirectory" | "addWorkspaceRoot";
|
||||
export type UsageReadParams = { range: UsageRange, };
|
||||
6
codex-rs/app-server-protocol/schema/typescript/v2/UsageReadResponse.ts
generated
Normal file
6
codex-rs/app-server-protocol/schema/typescript/v2/UsageReadResponse.ts
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { UsageReport } from "./UsageReport";
|
||||
|
||||
export type UsageReadResponse = { report: UsageReport, };
|
||||
8
codex-rs/app-server-protocol/schema/typescript/v2/UsageReport.ts
generated
Normal file
8
codex-rs/app-server-protocol/schema/typescript/v2/UsageReport.ts
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { UsageEntry } from "./UsageEntry";
|
||||
import type { UsageHeadline } from "./UsageHeadline";
|
||||
import type { UsageRange } from "./UsageRange";
|
||||
|
||||
export type UsageReport = { range: UsageRange, generatedAt: number, trackedFrom: number | null, totalTokens: number, headline: UsageHeadline | null, skills: Array<UsageEntry>, subagents: Array<UsageEntry>, agentTasks: Array<UsageEntry>, apps: Array<UsageEntry>, mcpServers: Array<UsageEntry>, plugins: Array<UsageEntry>, };
|
||||
@@ -1,7 +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";
|
||||
import type { WorkspaceMutationOperation } from "./WorkspaceMutationOperation";
|
||||
|
||||
export type WorkspaceMutationApprovalRequest = { operation: WorkspaceMutationOperation, target: AbsolutePathBuf, resultingWorkspaceRoots: Array<AbsolutePathBuf>, };
|
||||
@@ -344,13 +344,10 @@ export type { SkillToolDependency } from "./SkillToolDependency";
|
||||
export type { SkillsChangedNotification } from "./SkillsChangedNotification";
|
||||
export type { SkillsConfigWriteParams } from "./SkillsConfigWriteParams";
|
||||
export type { SkillsConfigWriteResponse } from "./SkillsConfigWriteResponse";
|
||||
export type { SkillsExtraRootsSetParams } from "./SkillsExtraRootsSetParams";
|
||||
export type { SkillsExtraRootsSetResponse } from "./SkillsExtraRootsSetResponse";
|
||||
export type { SkillsListEntry } from "./SkillsListEntry";
|
||||
export type { SkillsListParams } from "./SkillsListParams";
|
||||
export type { SkillsListResponse } from "./SkillsListResponse";
|
||||
export type { SortDirection } from "./SortDirection";
|
||||
export type { SpendControlLimitSnapshot } from "./SpendControlLimitSnapshot";
|
||||
export type { SubagentMigration } from "./SubagentMigration";
|
||||
export type { TerminalInteractionNotification } from "./TerminalInteractionNotification";
|
||||
export type { TextElement } from "./TextElement";
|
||||
@@ -455,6 +452,13 @@ export type { TurnStatus } from "./TurnStatus";
|
||||
export type { TurnSteerParams } from "./TurnSteerParams";
|
||||
export type { TurnSteerResponse } from "./TurnSteerResponse";
|
||||
export type { TurnsPage } from "./TurnsPage";
|
||||
export type { UsageContributorKind } from "./UsageContributorKind";
|
||||
export type { UsageEntry } from "./UsageEntry";
|
||||
export type { UsageHeadline } from "./UsageHeadline";
|
||||
export type { UsageRange } from "./UsageRange";
|
||||
export type { UsageReadParams } from "./UsageReadParams";
|
||||
export type { UsageReadResponse } from "./UsageReadResponse";
|
||||
export type { UsageReport } from "./UsageReport";
|
||||
export type { UserInput } from "./UserInput";
|
||||
export type { WarningNotification } from "./WarningNotification";
|
||||
export type { WebSearchAction } from "./WebSearchAction";
|
||||
@@ -465,6 +469,4 @@ export type { WindowsSandboxSetupMode } from "./WindowsSandboxSetupMode";
|
||||
export type { WindowsSandboxSetupStartParams } from "./WindowsSandboxSetupStartParams";
|
||||
export type { WindowsSandboxSetupStartResponse } from "./WindowsSandboxSetupStartResponse";
|
||||
export type { WindowsWorldWritableWarningNotification } from "./WindowsWorldWritableWarningNotification";
|
||||
export type { WorkspaceMutationApprovalRequest } from "./WorkspaceMutationApprovalRequest";
|
||||
export type { WorkspaceMutationOperation } from "./WorkspaceMutationOperation";
|
||||
export type { WriteStatus } from "./WriteStatus";
|
||||
|
||||
@@ -39,8 +39,6 @@ use ts_rs::TS;
|
||||
pub(crate) const GENERATED_TS_HEADER: &str = "// GENERATED CODE! DO NOT MODIFY BY HAND!\n\n";
|
||||
const IGNORED_DEFINITIONS: &[&str] = &["Option<()>"];
|
||||
const JSON_V1_ALLOWLIST: &[&str] = &["InitializeParams", "InitializeResponse"];
|
||||
const EXPERIMENTAL_CLIENT_METHOD_DEPENDENCY_TYPES: &[&str] =
|
||||
&["RemoteControlClient", "RemoteControlClientsListOrder"];
|
||||
const SPECIAL_DEFINITIONS: &[&str] = &[
|
||||
"ClientNotification",
|
||||
"ClientRequest",
|
||||
@@ -556,7 +554,6 @@ fn experimental_method_types() -> HashSet<String> {
|
||||
let mut type_names = HashSet::new();
|
||||
collect_experimental_type_names(EXPERIMENTAL_CLIENT_METHOD_PARAM_TYPES, &mut type_names);
|
||||
collect_experimental_type_names(EXPERIMENTAL_CLIENT_METHOD_RESPONSE_TYPES, &mut type_names);
|
||||
collect_experimental_type_names(EXPERIMENTAL_CLIENT_METHOD_DEPENDENCY_TYPES, &mut type_names);
|
||||
type_names
|
||||
}
|
||||
|
||||
@@ -2135,14 +2132,6 @@ mod tests {
|
||||
fixture_tree.contains_key(Path::new("v2/MockExperimentalMethodResponse.ts")),
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
fixture_tree.contains_key(Path::new("v2/RemoteControlClient.ts")),
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
fixture_tree.contains_key(Path::new("v2/RemoteControlClientsListOrder.ts")),
|
||||
false
|
||||
);
|
||||
|
||||
let mut undefined_offenders = Vec::new();
|
||||
let mut optional_nullable_offenders = BTreeSet::new();
|
||||
@@ -2858,11 +2847,6 @@ permissionProfile?: string | null};
|
||||
flat_v2_bundle_json.contains("MockExperimentalMethodResponse"),
|
||||
false
|
||||
);
|
||||
assert_eq!(flat_v2_bundle_json.contains("RemoteControlClient"), false);
|
||||
assert_eq!(
|
||||
flat_v2_bundle_json.contains("RemoteControlClientsListOrder"),
|
||||
false
|
||||
);
|
||||
assert_eq!(flat_v2_bundle_json.contains("#/definitions/v2/"), false);
|
||||
assert_eq!(
|
||||
flat_v2_bundle_json.contains("\"title\": \"CodexAppServerProtocolV2\""),
|
||||
@@ -2936,45 +2920,6 @@ permissionProfile?: string | null};
|
||||
.exists(),
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
output_dir
|
||||
.join("v2")
|
||||
.join("RemoteControlClient.json")
|
||||
.exists(),
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
output_dir
|
||||
.join("v2")
|
||||
.join("RemoteControlClientsListOrder.json")
|
||||
.exists(),
|
||||
false
|
||||
);
|
||||
|
||||
let _cleanup = fs::remove_dir_all(&output_dir);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn generate_json_includes_remote_control_methods_with_experimental_api() -> Result<()> {
|
||||
let output_dir = std::env::temp_dir().join(format!("codex_schema_{}", Uuid::now_v7()));
|
||||
fs::create_dir(&output_dir)?;
|
||||
generate_json_with_experimental(&output_dir, /*experimental_api*/ true)?;
|
||||
|
||||
let client_request_json = fs::read_to_string(output_dir.join("ClientRequest.json"))?;
|
||||
assert!(client_request_json.contains("remoteControl/pairing/start"));
|
||||
assert!(client_request_json.contains("remoteControl/client/list"));
|
||||
assert!(client_request_json.contains("remoteControl/client/revoke"));
|
||||
for schema in [
|
||||
"RemoteControlPairingStartParams.json",
|
||||
"RemoteControlPairingStartResponse.json",
|
||||
"RemoteControlClientsListParams.json",
|
||||
"RemoteControlClientsListResponse.json",
|
||||
"RemoteControlClientsRevokeParams.json",
|
||||
"RemoteControlClientsRevokeResponse.json",
|
||||
] {
|
||||
assert!(output_dir.join("v2").join(schema).exists());
|
||||
}
|
||||
|
||||
let _cleanup = fs::remove_dir_all(&output_dir);
|
||||
Ok(())
|
||||
|
||||
@@ -610,11 +610,6 @@ client_request_definitions! {
|
||||
serialization: global_shared_read("config"),
|
||||
response: v2::SkillsListResponse,
|
||||
},
|
||||
SkillsExtraRootsSet => "skills/extraRoots/set" {
|
||||
params: v2::SkillsExtraRootsSetParams,
|
||||
serialization: global("config"),
|
||||
response: v2::SkillsExtraRootsSetResponse,
|
||||
},
|
||||
HooksList => "hooks/list" {
|
||||
params: v2::HooksListParams,
|
||||
serialization: global("config"),
|
||||
@@ -640,6 +635,11 @@ client_request_definitions! {
|
||||
serialization: None,
|
||||
response: v2::PluginListResponse,
|
||||
},
|
||||
UsageRead => "usage/read" {
|
||||
params: v2::UsageReadParams,
|
||||
serialization: None,
|
||||
response: v2::UsageReadResponse,
|
||||
},
|
||||
PluginInstalled => "plugin/installed" {
|
||||
params: v2::PluginInstalledParams,
|
||||
serialization: None,
|
||||
@@ -843,24 +843,6 @@ client_request_definitions! {
|
||||
serialization: global_shared_read("remote-control"),
|
||||
response: v2::RemoteControlStatusReadResponse,
|
||||
},
|
||||
#[experimental("remoteControl/pairing/start")]
|
||||
RemoteControlPairingStart => "remoteControl/pairing/start" {
|
||||
params: v2::RemoteControlPairingStartParams,
|
||||
serialization: global("remote-control-pairing"),
|
||||
response: v2::RemoteControlPairingStartResponse,
|
||||
},
|
||||
#[experimental("remoteControl/client/list")]
|
||||
RemoteControlClientsList => "remoteControl/client/list" {
|
||||
params: v2::RemoteControlClientsListParams,
|
||||
serialization: global_shared_read("remote-control-clients"),
|
||||
response: v2::RemoteControlClientsListResponse,
|
||||
},
|
||||
#[experimental("remoteControl/client/revoke")]
|
||||
RemoteControlClientsRevoke => "remoteControl/client/revoke" {
|
||||
params: v2::RemoteControlClientsRevokeParams,
|
||||
serialization: global("remote-control-clients"),
|
||||
response: v2::RemoteControlClientsRevokeResponse,
|
||||
},
|
||||
#[experimental("collaborationMode/list")]
|
||||
/// Lists collaboration mode presets.
|
||||
CollaborationModeList => "collaborationMode/list" {
|
||||
@@ -1744,17 +1726,6 @@ mod tests {
|
||||
Some(ClientRequestSerializationScope::GlobalSharedRead("config"))
|
||||
);
|
||||
|
||||
let skills_extra_roots_set = ClientRequest::SkillsExtraRootsSet {
|
||||
request_id: request_id(),
|
||||
params: v2::SkillsExtraRootsSetParams {
|
||||
extra_roots: vec![absolute_path("/tmp/skills")],
|
||||
},
|
||||
};
|
||||
assert_eq!(
|
||||
skills_extra_roots_set.serialization_scope(),
|
||||
Some(ClientRequestSerializationScope::Global("config"))
|
||||
);
|
||||
|
||||
let plugin_list = ClientRequest::PluginList {
|
||||
request_id: request_id(),
|
||||
params: v2::PluginListParams {
|
||||
@@ -1995,40 +1966,6 @@ mod tests {
|
||||
},
|
||||
};
|
||||
assert_eq!(mcp_resource_read.serialization_scope(), None);
|
||||
|
||||
let remote_control_pairing_start = ClientRequest::RemoteControlPairingStart {
|
||||
request_id: request_id(),
|
||||
params: v2::RemoteControlPairingStartParams::default(),
|
||||
};
|
||||
assert_eq!(
|
||||
remote_control_pairing_start.serialization_scope(),
|
||||
Some(ClientRequestSerializationScope::Global(
|
||||
"remote-control-pairing"
|
||||
))
|
||||
);
|
||||
let remote_control_clients_list = ClientRequest::RemoteControlClientsList {
|
||||
request_id: request_id(),
|
||||
params: v2::RemoteControlClientsListParams::default(),
|
||||
};
|
||||
assert_eq!(
|
||||
remote_control_clients_list.serialization_scope(),
|
||||
Some(ClientRequestSerializationScope::GlobalSharedRead(
|
||||
"remote-control-clients"
|
||||
))
|
||||
);
|
||||
let remote_control_clients_revoke = ClientRequest::RemoteControlClientsRevoke {
|
||||
request_id: request_id(),
|
||||
params: v2::RemoteControlClientsRevokeParams {
|
||||
environment_id: "environment-id".to_string(),
|
||||
client_id: "client-id".to_string(),
|
||||
},
|
||||
};
|
||||
assert_eq!(
|
||||
remote_control_clients_revoke.serialization_scope(),
|
||||
Some(ClientRequestSerializationScope::Global(
|
||||
"remote-control-clients"
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2380,7 +2317,6 @@ mod tests {
|
||||
id: "67e55044-10b1-426f-9247-bb680e5fe0c8".to_string(),
|
||||
session_id: "67e55044-10b1-426f-9247-bb680e5fe0c7".to_string(),
|
||||
forked_from_id: None,
|
||||
parent_thread_id: None,
|
||||
preview: "first prompt".to_string(),
|
||||
ephemeral: true,
|
||||
model_provider: "openai".to_string(),
|
||||
@@ -2423,7 +2359,6 @@ mod tests {
|
||||
"id": "67e55044-10b1-426f-9247-bb680e5fe0c8",
|
||||
"sessionId": "67e55044-10b1-426f-9247-bb680e5fe0c7",
|
||||
"forkedFromId": null,
|
||||
"parentThreadId": null,
|
||||
"preview": "first prompt",
|
||||
"ephemeral": true,
|
||||
"modelProvider": "openai",
|
||||
|
||||
@@ -278,11 +278,7 @@ impl ThreadHistoryBuilder {
|
||||
.unwrap_or_else(|| self.new_turn(/*id*/ None));
|
||||
let id = self.next_item_id();
|
||||
let content = self.build_user_inputs(payload);
|
||||
turn.items.push(ThreadItem::UserMessage {
|
||||
id,
|
||||
client_id: payload.client_id.clone(),
|
||||
content,
|
||||
});
|
||||
turn.items.push(ThreadItem::UserMessage { id, content });
|
||||
self.current_turn = Some(turn);
|
||||
}
|
||||
|
||||
@@ -1250,7 +1246,6 @@ mod tests {
|
||||
fn builds_multiple_turns_with_reasoning_items() {
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "First turn".into(),
|
||||
images: Some(vec!["https://example.com/one.png".into()]),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1269,7 +1264,6 @@ mod tests {
|
||||
text: "full reasoning".into(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "Second turn".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1298,7 +1292,6 @@ mod tests {
|
||||
first.items[0],
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![
|
||||
UserInput::Text {
|
||||
text: "First turn".into(),
|
||||
@@ -1337,7 +1330,6 @@ mod tests {
|
||||
second.items[0],
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-4".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "Second turn".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1360,7 +1352,6 @@ mod tests {
|
||||
let local_path = PathBuf::from("/tmp/local.png");
|
||||
let events = vec![RolloutItem::EventMsg(EventMsg::UserMessage(
|
||||
UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "inspect these".into(),
|
||||
images: Some(vec!["https://example.com/image.png".into()]),
|
||||
image_details: vec![Some(ImageDetail::Original)],
|
||||
@@ -1377,7 +1368,6 @@ mod tests {
|
||||
turns[0].items[0],
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![
|
||||
UserInput::Text {
|
||||
text: "inspect these".into(),
|
||||
@@ -1409,7 +1399,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "hello".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1421,7 +1410,6 @@ mod tests {
|
||||
turn_id: turn_id.to_string(),
|
||||
item: CoreTurnItem::UserMessage(CoreUserMessageItem {
|
||||
id: "user-item-id".to_string(),
|
||||
client_id: None,
|
||||
content: Vec::new(),
|
||||
}),
|
||||
started_at_ms: 0,
|
||||
@@ -1446,7 +1434,6 @@ mod tests {
|
||||
turns[0].items[0],
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "hello".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1455,67 +1442,6 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preserves_user_message_client_id_from_legacy_event() {
|
||||
let turn_id = "turn-1";
|
||||
let thread_id = ThreadId::new();
|
||||
let events = vec![
|
||||
EventMsg::TurnStarted(TurnStartedEvent {
|
||||
turn_id: turn_id.to_string(),
|
||||
trace_id: None,
|
||||
started_at: None,
|
||||
model_context_window: None,
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::ItemStarted(ItemStartedEvent {
|
||||
thread_id,
|
||||
turn_id: turn_id.to_string(),
|
||||
item: CoreTurnItem::UserMessage(CoreUserMessageItem {
|
||||
id: "user-item-id".to_string(),
|
||||
client_id: Some("client-message-1".to_string()),
|
||||
content: vec![codex_protocol::user_input::UserInput::Text {
|
||||
text: "hello".into(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
}),
|
||||
started_at_ms: 0,
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: Some("client-message-1".to_string()),
|
||||
message: "hello".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
local_images: Vec::new(),
|
||||
..Default::default()
|
||||
}),
|
||||
EventMsg::TurnComplete(TurnCompleteEvent {
|
||||
turn_id: turn_id.to_string(),
|
||||
last_agent_message: None,
|
||||
completed_at: None,
|
||||
duration_ms: None,
|
||||
time_to_first_token_ms: None,
|
||||
}),
|
||||
];
|
||||
|
||||
let items = events
|
||||
.into_iter()
|
||||
.map(RolloutItem::EventMsg)
|
||||
.collect::<Vec<_>>();
|
||||
let turns = build_turns_from_rollout_items(&items);
|
||||
assert_eq!(turns.len(), 1);
|
||||
assert_eq!(
|
||||
turns[0].items,
|
||||
vec![ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: Some("client-message-1".to_string()),
|
||||
content: vec![UserInput::Text {
|
||||
text: "hello".into(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preserves_agent_message_phase_in_history() {
|
||||
let events = vec![EventMsg::AgentMessage(AgentMessageEvent {
|
||||
@@ -1552,7 +1478,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "generate an image".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1590,7 +1515,6 @@ mod tests {
|
||||
items: vec![
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "generate an image".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1612,7 +1536,6 @@ mod tests {
|
||||
fn splits_reasoning_when_interleaved() {
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "Turn start".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1666,7 +1589,6 @@ mod tests {
|
||||
fn marks_turn_as_interrupted_when_aborted() {
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "Please do the thing".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1685,7 +1607,6 @@ mod tests {
|
||||
duration_ms: None,
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "Let's try again".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1713,7 +1634,6 @@ mod tests {
|
||||
first_turn.items[0],
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "Please do the thing".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1737,7 +1657,6 @@ mod tests {
|
||||
second_turn.items[0],
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-3".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "Let's try again".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1759,7 +1678,6 @@ mod tests {
|
||||
fn drops_last_turns_on_thread_rollback() {
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "First".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1772,7 +1690,6 @@ mod tests {
|
||||
memory_citation: None,
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "Second".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1786,7 +1703,6 @@ mod tests {
|
||||
}),
|
||||
EventMsg::ThreadRolledBack(ThreadRolledBackEvent { num_turns: 1 }),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "Third".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1816,7 +1732,6 @@ mod tests {
|
||||
vec![
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "First".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1835,7 +1750,6 @@ mod tests {
|
||||
vec![
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-3".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "Third".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1855,7 +1769,6 @@ mod tests {
|
||||
fn thread_rollback_clears_all_turns_when_num_turns_exceeds_history() {
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "One".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1868,7 +1781,6 @@ mod tests {
|
||||
memory_citation: None,
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "Two".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1902,7 +1814,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "Start".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1910,7 +1821,6 @@ mod tests {
|
||||
..Default::default()
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "Steer".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -1938,7 +1848,6 @@ mod tests {
|
||||
vec![
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "Start".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1946,7 +1855,6 @@ mod tests {
|
||||
},
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-2".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "Steer".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -1967,7 +1875,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "run tools".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2147,7 +2054,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "run dynamic tool".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2215,7 +2121,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "run tools".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2307,7 +2212,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "review this command".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2393,7 +2297,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "run a subcommand".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2459,7 +2362,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "first".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2481,7 +2383,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "second".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2557,7 +2458,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "first".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2579,7 +2479,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "second".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2629,7 +2528,6 @@ mod tests {
|
||||
turns[1].items[0],
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-2".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "second".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -2651,7 +2549,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "apply patch".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2687,7 +2584,6 @@ mod tests {
|
||||
vec![
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "apply patch".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -2719,7 +2615,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "apply patch".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2757,7 +2652,6 @@ mod tests {
|
||||
vec![
|
||||
ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "apply patch".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -2787,7 +2681,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "first".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2809,7 +2702,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "second".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2859,7 +2751,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "first".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2881,7 +2772,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "second".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -2956,7 +2846,6 @@ mod tests {
|
||||
fn reconstructs_collab_resume_end_item() {
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "resume agent".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -3015,7 +2904,6 @@ mod tests {
|
||||
.expect("valid receiver thread id");
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "spawn agent".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -3078,7 +2966,6 @@ mod tests {
|
||||
.expect("valid receiver thread id");
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "redirect".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -3143,7 +3030,6 @@ mod tests {
|
||||
fn rollback_failed_error_does_not_mark_turn_failed() {
|
||||
let events = vec![
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "hello".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -3182,7 +3068,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "hello".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -3220,7 +3105,6 @@ mod tests {
|
||||
items_view: TurnItemsView::Full,
|
||||
items: vec![ThreadItem::UserMessage {
|
||||
id: "item-1".into(),
|
||||
client_id: None,
|
||||
content: vec![UserInput::Text {
|
||||
text: "hello".into(),
|
||||
text_elements: Vec::new(),
|
||||
@@ -3241,7 +3125,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
}),
|
||||
EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "hello".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
@@ -3301,7 +3184,6 @@ mod tests {
|
||||
collaboration_mode_kind: Default::default(),
|
||||
})),
|
||||
RolloutItem::EventMsg(EventMsg::UserMessage(UserMessageEvent {
|
||||
client_id: None,
|
||||
message: "hello".into(),
|
||||
images: None,
|
||||
text_elements: Vec::new(),
|
||||
|
||||
@@ -6,7 +6,6 @@ use codex_protocol::protocol::CreditsSnapshot as CoreCreditsSnapshot;
|
||||
use codex_protocol::protocol::RateLimitReachedType as CoreRateLimitReachedType;
|
||||
use codex_protocol::protocol::RateLimitSnapshot as CoreRateLimitSnapshot;
|
||||
use codex_protocol::protocol::RateLimitWindow as CoreRateLimitWindow;
|
||||
use codex_protocol::protocol::SpendControlLimitSnapshot as CoreSpendControlLimitSnapshot;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
@@ -248,11 +247,6 @@ pub struct AccountUpdatedNotification {
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
/// 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.
|
||||
pub struct AccountRateLimitsUpdatedNotification {
|
||||
pub rate_limits: RateLimitSnapshot,
|
||||
}
|
||||
@@ -266,7 +260,6 @@ pub struct RateLimitSnapshot {
|
||||
pub primary: Option<RateLimitWindow>,
|
||||
pub secondary: Option<RateLimitWindow>,
|
||||
pub credits: Option<CreditsSnapshot>,
|
||||
pub individual_limit: Option<SpendControlLimitSnapshot>,
|
||||
pub plan_type: Option<PlanType>,
|
||||
pub rate_limit_reached_type: Option<RateLimitReachedType>,
|
||||
}
|
||||
@@ -279,7 +272,6 @@ impl From<CoreRateLimitSnapshot> for RateLimitSnapshot {
|
||||
primary: value.primary.map(RateLimitWindow::from),
|
||||
secondary: value.secondary.map(RateLimitWindow::from),
|
||||
credits: value.credits.map(CreditsSnapshot::from),
|
||||
individual_limit: value.individual_limit.map(SpendControlLimitSnapshot::from),
|
||||
plan_type: value.plan_type,
|
||||
rate_limit_reached_type: value
|
||||
.rate_limit_reached_type
|
||||
@@ -379,28 +371,6 @@ impl From<CoreCreditsSnapshot> for CreditsSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct SpendControlLimitSnapshot {
|
||||
pub limit: String,
|
||||
pub used: String,
|
||||
pub remaining_percent: i32,
|
||||
#[ts(type = "number")]
|
||||
pub resets_at: i64,
|
||||
}
|
||||
|
||||
impl From<CoreSpendControlLimitSnapshot> for SpendControlLimitSnapshot {
|
||||
fn from(value: CoreSpendControlLimitSnapshot) -> Self {
|
||||
Self {
|
||||
limit: value.limit,
|
||||
used: value.used,
|
||||
remaining_percent: value.remaining_percent,
|
||||
resets_at: value.resets_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user