mirror of
https://github.com/openai/codex.git
synced 2026-05-07 04:47:13 +00:00
Compare commits
110 Commits
pr20276
...
codex/cent
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbff525377 | ||
|
|
c30a4d2756 | ||
|
|
11655ee6b3 | ||
|
|
27c2bdc3e7 | ||
|
|
7113173442 | ||
|
|
49d55626f6 | ||
|
|
280698fcf6 | ||
|
|
a1c0d3e5b3 | ||
|
|
f06870f376 | ||
|
|
ad605dc791 | ||
|
|
fd6644fd82 | ||
|
|
35aaa5d9fc | ||
|
|
f88701f5c8 | ||
|
|
15bb7f5530 | ||
|
|
127434cd8b | ||
|
|
9e905528bb | ||
|
|
cd2760fc08 | ||
|
|
466798aa83 | ||
|
|
a5fbcf1ab4 | ||
|
|
2952beb009 | ||
|
|
d55479488e | ||
|
|
443f6b831e | ||
|
|
aed74e5ee4 | ||
|
|
610eefb86b | ||
|
|
2817866a32 | ||
|
|
ff66b3c7eb | ||
|
|
be71b6fcd1 | ||
|
|
e4d6675632 | ||
|
|
78baa20780 | ||
|
|
9b8d585075 | ||
|
|
6784db51c0 | ||
|
|
41e171fcf2 | ||
|
|
5744b85b9a | ||
|
|
3d1d164aee | ||
|
|
227bee0445 | ||
|
|
f476338f93 | ||
|
|
0b04d1b3cc | ||
|
|
ff27d01676 | ||
|
|
70fc55b8f3 | ||
|
|
97aae46800 | ||
|
|
ad404c8400 | ||
|
|
48791920a8 | ||
|
|
96d2ea9058 | ||
|
|
a62b52f826 | ||
|
|
a93c89f497 | ||
|
|
d898cc8f3f | ||
|
|
fe05acad23 | ||
|
|
f50c02d7bc | ||
|
|
bb60b78c46 | ||
|
|
c39824c2fd | ||
|
|
6b1b227804 | ||
|
|
972b819213 | ||
|
|
af089fb21d | ||
|
|
4f96001fa7 | ||
|
|
0d9a5d20ec | ||
|
|
5affb7f9d5 | ||
|
|
acdf908268 | ||
|
|
b6f81257f8 | ||
|
|
a5ebedef67 | ||
|
|
5de7992ee5 | ||
|
|
2686873e77 | ||
|
|
9ddb267e9c | ||
|
|
6014b6679f | ||
|
|
8426edf71e | ||
|
|
7b3de63041 | ||
|
|
127be0612c | ||
|
|
9121132c8f | ||
|
|
70090c9ff7 | ||
|
|
8121710ffe | ||
|
|
7dd08e304c | ||
|
|
06f3b4836a | ||
|
|
31f8813e3e | ||
|
|
93d53f655b | ||
|
|
719431da6e | ||
|
|
b52083146c | ||
|
|
f2bc2f26a9 | ||
|
|
5cc5f12efc | ||
|
|
c70cdc108f | ||
|
|
487716ae74 | ||
|
|
a85d265097 | ||
|
|
c02814c106 | ||
|
|
3516cb9751 | ||
|
|
8a97f3cf03 | ||
|
|
c37f7434ba | ||
|
|
a73403a890 | ||
|
|
87d0cf1a62 | ||
|
|
ae863e72a2 | ||
|
|
8f3c06cc97 | ||
|
|
ac4332c05b | ||
|
|
ebe602d005 | ||
|
|
4e677d62da | ||
|
|
bb536d65bd | ||
|
|
8b07132e09 | ||
|
|
515aa9a4fb | ||
|
|
fedcefe9da | ||
|
|
c8abcbf925 | ||
|
|
7bcd4626c4 | ||
|
|
8774229a89 | ||
|
|
6eab7519b4 | ||
|
|
98f67b15d3 | ||
|
|
74f06dcdfb | ||
|
|
13dbcda28f | ||
|
|
8de2a7a16d | ||
|
|
782191547c | ||
|
|
e20391e567 | ||
|
|
4241df4d79 | ||
|
|
b1546008fc | ||
|
|
f63b19bedd | ||
|
|
8d5da3ffe5 | ||
|
|
72a39e3a96 |
19
.bazelrc
19
.bazelrc
@@ -153,6 +153,25 @@ 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
|
||||
# on the Windows runner so Bazel's normal test sharding and flaky-test retries
|
||||
# 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
|
||||
# Native Windows CI still covers these tests. The cross-built gnullvm binaries
|
||||
# currently crash in V8-backed code-mode tests and hang in PowerShell AST parser
|
||||
# tests when those binaries are run on the Windows runner.
|
||||
common:ci-windows-cross --test_env=CODEX_BAZEL_TEST_SKIP_FILTERS=suite::code_mode::,powershell
|
||||
common:ci-windows-cross --platforms=//:windows_x86_64_gnullvm
|
||||
common:ci-windows-cross --extra_execution_platforms=//:rbe,//:windows_x86_64_msvc
|
||||
common:ci-windows-cross --extra_toolchains=//:windows_gnullvm_tests_on_msvc_host_toolchain
|
||||
|
||||
# Linux-only V8 CI config.
|
||||
common:ci-v8 --config=ci
|
||||
common:ci-v8 --build_metadata=TAG_workflow=v8
|
||||
|
||||
11
.codex/environments/environment.toml
Normal file
11
.codex/environments/environment.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
# THIS IS AUTOGENERATED. DO NOT EDIT MANUALLY
|
||||
version = 1
|
||||
name = "codex"
|
||||
|
||||
[setup]
|
||||
script = ""
|
||||
|
||||
[[actions]]
|
||||
name = "Run"
|
||||
icon = "run"
|
||||
command = "cargo +1.93.0 run --manifest-path=codex-rs/Cargo.toml --bin codex -- -c mcp_oauth_credentials_store=file"
|
||||
@@ -27,10 +27,10 @@ Accept any of the following:
|
||||
2. Run the watcher script to snapshot PR/review/CI state (or consume each streamed snapshot from `--watch`).
|
||||
3. Inspect the `actions` list in the JSON response.
|
||||
4. If `diagnose_ci_failure` is present, inspect failed run logs and classify the failure.
|
||||
5. If the failure is likely caused by the current branch, patch code locally, commit, and push.
|
||||
5. If the failure is likely caused by the current branch, patch code locally, commit, and push. Do not patch random flaky tests, CI infrastructure, dependency outages, runner issues, or other failures that are unrelated to the branch.
|
||||
6. If `process_review_comment` is present, inspect surfaced review items and decide whether to address them.
|
||||
7. If a review item is actionable and correct, patch code locally, commit, push, and then mark the associated review thread/comment as resolved once the fix is on GitHub.
|
||||
8. If a review item from another author is non-actionable, already addressed, or not valid, post one reply on the comment/thread explaining that decision (for example answering the question or explaining why no change is needed). Prefix the GitHub reply body with `[codex]` so it is clear the response is automated. If the watcher later surfaces your own reply, treat that self-authored item as already handled and do not reply again.
|
||||
8. Do not post replies to human-authored review comments/threads unless the user explicitly confirms the exact response. If a human review item is non-actionable, already addressed, or not valid, surface the item and recommended response to the user instead of replying on GitHub.
|
||||
9. If the failure is likely flaky/unrelated and `retry_failed_checks` is present, rerun failed jobs with `--retry-failed-now`.
|
||||
10. If both actionable review feedback and `retry_failed_checks` are present, prioritize review feedback first; a new commit will retrigger CI, so avoid rerunning flaky checks on the old SHA unless you intentionally defer the review change.
|
||||
11. On every loop, look for newly surfaced review feedback before acting on CI failures or mergeability state, then verify mergeability / merge-conflict status (for example via `gh pr view`) alongside CI.
|
||||
@@ -69,12 +69,18 @@ python3 .codex/skills/babysit-pr/scripts/gh_pr_watch.py --pr <number-or-url> --o
|
||||
Use `gh` commands to inspect failed runs before deciding to rerun.
|
||||
|
||||
- `gh run view <run-id> --json jobs,name,workflowName,conclusion,status,url,headSha`
|
||||
- `gh run view <run-id> --log-failed`
|
||||
- `gh api repos/<owner>/<repo>/actions/runs/<run-id>/jobs -X GET -f per_page=100`
|
||||
- `gh api repos/<owner>/<repo>/actions/jobs/<job-id>/logs > /tmp/codex-gh-job-<job-id>-logs.zip`
|
||||
- `gh run view <run-id> --log-failed` as a fallback after the overall workflow run is complete
|
||||
|
||||
Prefer treating failures as branch-related when logs point to changed code (compile/test/lint/typecheck/snapshots/static analysis in touched areas).
|
||||
`gh run view --log-failed` is workflow-run scoped and may not expose failed-job logs until the overall run finishes. For faster diagnosis, poll the run's jobs first and, as soon as a specific job has failed, fetch that job's logs directly from the Actions job logs endpoint. The watcher includes a `failed_jobs` list with each failed job's `job_id` and `logs_endpoint` when GitHub exposes one.
|
||||
|
||||
Prefer treating failures as branch-related when failed-job logs point to changed code (compile/test/lint/typecheck/snapshots/static analysis in touched areas).
|
||||
|
||||
Prefer treating failures as flaky/unrelated when logs show transient infra/external issues (timeouts, runner provisioning failures, registry/network outages, GitHub Actions infra errors).
|
||||
|
||||
Do not attempt to fix flaky/unrelated failures by changing tests, build scripts, CI configuration, dependency pins, or infrastructure-adjacent code unless the logs clearly connect the failure to the PR branch. For flaky/unrelated failures, rerun only when the watcher recommends `retry_failed_checks`; otherwise wait or stop for user help.
|
||||
|
||||
If classification is ambiguous, perform one manual diagnosis attempt before choosing rerun.
|
||||
|
||||
Read `.codex/skills/babysit-pr/references/heuristics.md` for a concise checklist.
|
||||
@@ -99,7 +105,8 @@ When you agree with a comment and it is actionable:
|
||||
5. Resume watching on the new SHA immediately (do not stop after reporting the push).
|
||||
6. If monitoring was running in `--watch` mode, restart `--watch` immediately after the push in the same turn; do not wait for the user to ask again.
|
||||
|
||||
If you disagree or the comment is non-actionable/already addressed, reply once directly on the GitHub comment/thread so the reviewer gets an explicit answer, then continue the watcher loop. Prefix any GitHub reply to a code review comment/thread with `[codex]` so it is clear the response is automated and not from the human user. If the watcher later surfaces your own reply because the authenticated operator is treated as a trusted review author, treat that self-authored item as already handled and do not reply again.
|
||||
Do not post replies to human-authored GitHub review comments/threads automatically. If you disagree with a human comment, believe it is non-actionable/already addressed, or need to answer a question, report the item to the user with a suggested response and wait for explicit confirmation before posting anything on GitHub. If the user approves a response, prefix it with `[codex]` so it is clear the response is automated and not from the human user.
|
||||
If the watcher later surfaces your own approved reply because the authenticated operator is treated as a trusted review author, treat that self-authored item as already handled and do not reply again.
|
||||
If a code review comment/thread is already marked as resolved in GitHub, treat it as non-actionable and safely ignore it unless new unresolved follow-up feedback appears.
|
||||
|
||||
## Git Safety Rules
|
||||
@@ -125,11 +132,11 @@ Use this loop in a live Codex session:
|
||||
2. Read `actions`.
|
||||
3. First check whether the PR is now merged or otherwise closed; if so, report that terminal state and stop polling immediately.
|
||||
4. Check CI summary, new review items, and mergeability/conflict status.
|
||||
5. Diagnose CI failures and classify branch-related vs flaky/unrelated.
|
||||
6. For each surfaced review item from another author, either reply once with an explanation if it is non-actionable or patch/commit/push and then resolve it if it is actionable. If a later snapshot surfaces your own reply, treat it as informational and continue without responding again.
|
||||
5. Diagnose CI failures and classify branch-related vs flaky/unrelated. If the overall run is still pending but `failed_jobs` already includes a failed job, fetch that job's logs and diagnose immediately instead of waiting for the whole workflow run to finish. Patch only when the failure is branch-related.
|
||||
6. For each surfaced review item from another author, patch/commit/push and then resolve it if it is actionable. If it is non-actionable, already addressed, or requires a written answer, surface it to the user with a suggested response instead of posting automatically. If a later snapshot surfaces your own approved reply, treat it as informational and continue without responding again.
|
||||
7. Process actionable review comments before flaky reruns when both are present; if a review fix requires a commit, push it and skip rerunning failed checks on the old SHA.
|
||||
8. Retry failed checks only when `retry_failed_checks` is present and you are not about to replace the current SHA with a review/CI fix commit.
|
||||
9. If you pushed a commit, resolved a review thread, replied to a review comment, or triggered a rerun, report the action briefly and continue polling (do not stop).
|
||||
8. Retry failed checks only when `retry_failed_checks` is present and you are not about to replace the current SHA with a review/CI fix commit. Do not make code changes for unrelated flakes or infrastructure failures just to get CI green.
|
||||
9. If you pushed a commit, resolved a review thread, or triggered a rerun, report the action briefly and continue polling (do not stop). If a human review comment needs a written GitHub response, stop and ask for confirmation before posting.
|
||||
10. After a review-fix push, proactively restart continuous monitoring (`--watch`) in the same turn unless a strict stop condition has already been reached.
|
||||
11. If everything is passing, mergeable, not blocked on required review approval, and there are no unaddressed review items, report that the PR is currently ready to merge but keep the watcher running so new review comments are surfaced quickly while the PR remains open.
|
||||
12. If blocked on a user-help-required issue (infra outage, exhausted flaky retries, unclear reviewer request, permissions), report the blocker and stop.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
interface:
|
||||
display_name: "PR Babysitter"
|
||||
short_description: "Watch PR review comments, CI, and merge conflicts"
|
||||
default_prompt: "Babysit the current PR: monitor reviewer comments, CI, and merge-conflict status (prefer the watcher’s --watch mode for live monitoring); surface new review feedback before acting on CI or mergeability work, fix valid issues, push updates, and rerun flaky failures up to 3 times. Keep exactly one watcher session active for the PR (do not leave duplicate --watch terminals running). If you pause monitoring to patch review/CI feedback, restart --watch yourself immediately after the push in the same turn. If a watcher is still running and no strict stop condition has been reached, the task is still in progress: keep consuming watcher output and sending progress updates instead of ending the turn. Do not treat a green + mergeable PR as a terminal stop while it is still open; continue polling autonomously after any push/rerun so newly posted review comments are surfaced until a strict terminal stop condition is reached or the user interrupts."
|
||||
default_prompt: "Babysit the current PR: monitor reviewer comments, CI, and merge-conflict status (prefer the watcher’s --watch mode for live monitoring); surface new review feedback before acting on CI or mergeability work, fix valid issues, push updates, and rerun flaky failures up to 3 times. Do not post replies to human-authored review comments unless the user explicitly confirms the exact response. Do not patch unrelated flaky tests, CI infrastructure, dependency outages, runner issues, or other failures that are not caused by the branch. Keep exactly one watcher session active for the PR (do not leave duplicate --watch terminals running). If you pause monitoring to patch review/CI feedback, restart --watch yourself immediately after the push in the same turn. If a watcher is still running and no strict stop condition has been reached, the task is still in progress: keep consuming watcher output and sending progress updates instead of ending the turn. Do not treat a green + mergeable PR as a terminal stop while it is still open; continue polling autonomously after any push/rerun so newly posted review comments are surfaced until a strict terminal stop condition is reached or the user interrupts."
|
||||
|
||||
@@ -23,9 +23,11 @@ Used to discover failed workflow runs and rerunnable run IDs.
|
||||
### Failed log inspection
|
||||
|
||||
- `gh run view <run-id> --json jobs,name,workflowName,conclusion,status,url,headSha`
|
||||
- `gh api repos/{owner}/{repo}/actions/runs/{run_id}/jobs -X GET -f per_page=100`
|
||||
- `gh api repos/{owner}/{repo}/actions/jobs/{job_id}/logs > /tmp/codex-gh-job-{job_id}-logs.zip`
|
||||
- `gh run view <run-id> --log-failed`
|
||||
|
||||
Used by Codex to classify branch-related vs flaky/unrelated failures.
|
||||
Used by Codex to classify branch-related vs flaky/unrelated failures. Prefer the direct job log endpoint as soon as a job has failed because `gh run view --log-failed` may not produce failed-job logs until the overall workflow run completes.
|
||||
|
||||
### Retry failed jobs only
|
||||
|
||||
@@ -70,3 +72,11 @@ Reruns only failed jobs (and dependencies) for a workflow run.
|
||||
- `conclusion`
|
||||
- `html_url`
|
||||
- `head_sha`
|
||||
|
||||
### Actions run jobs API (`jobs[]`)
|
||||
|
||||
- `id`
|
||||
- `name`
|
||||
- `status`
|
||||
- `conclusion`
|
||||
- `html_url`
|
||||
|
||||
@@ -18,6 +18,8 @@ Treat as **likely flaky or unrelated** when evidence points to transient or exte
|
||||
- Cloud/service rate limits or transient API outages
|
||||
- Non-deterministic failures in unrelated integration tests with known flake patterns
|
||||
|
||||
Do not patch likely flaky/unrelated failures. Use the retry budget for rerunnable failures, wait for pending jobs, or stop and report the blocker when the failure is persistent or infrastructure-owned.
|
||||
|
||||
If uncertain, inspect failed logs once before choosing rerun.
|
||||
|
||||
## Decision tree (fix vs rerun vs stop)
|
||||
@@ -25,9 +27,11 @@ If uncertain, inspect failed logs once before choosing rerun.
|
||||
1. If PR is merged/closed: stop.
|
||||
2. If there are failed checks:
|
||||
- Diagnose first.
|
||||
- If checks are still pending but an individual job has already failed: fetch that job's logs and diagnose now.
|
||||
- If branch-related: fix locally, commit, push.
|
||||
- If likely flaky/unrelated and all checks for the current SHA are terminal: rerun failed jobs.
|
||||
- If checks are still pending: wait.
|
||||
- If likely flaky/unrelated and not safely rerunnable: stop and report the blocker; do not edit unrelated tests, build scripts, CI configuration, dependency pins, or infrastructure code.
|
||||
- If checks are still pending and no failed job is available yet: wait.
|
||||
3. If flaky reruns for the same SHA reach the configured limit (default 3): stop and report persistent failure.
|
||||
4. Independently, process any new human review comments.
|
||||
|
||||
@@ -40,12 +44,15 @@ Address the comment when:
|
||||
- The requested change does not conflict with the user’s intent or recent guidance.
|
||||
- The change can be made safely without unrelated refactors.
|
||||
|
||||
Fix valid human review feedback in code when possible, but do not post a GitHub reply to a human-authored comment/thread unless the user explicitly confirms the exact response.
|
||||
|
||||
Do not auto-fix when:
|
||||
|
||||
- The comment is ambiguous and needs clarification.
|
||||
- The request conflicts with explicit user instructions.
|
||||
- The proposed change requires product/design decisions the user has not made.
|
||||
- The codebase is in a dirty/unrelated state that makes safe editing uncertain.
|
||||
- The comment only needs a written answer or disagreement response; propose the reply to the user instead of posting it automatically.
|
||||
|
||||
## Stop-and-ask conditions
|
||||
|
||||
@@ -56,3 +63,4 @@ Stop and ask the user instead of continuing automatically when:
|
||||
- The PR branch cannot be pushed.
|
||||
- CI failures persist after the flaky retry budget.
|
||||
- Reviewer feedback requires a product decision or cross-team coordination.
|
||||
- A human review comment requires a written GitHub reply instead of a code change.
|
||||
|
||||
@@ -338,6 +338,66 @@ def failed_runs_from_workflow_runs(runs, head_sha):
|
||||
return failed_runs
|
||||
|
||||
|
||||
def get_jobs_for_run(repo, run_id):
|
||||
endpoint = f"repos/{repo}/actions/runs/{run_id}/jobs"
|
||||
data = gh_json(["api", endpoint, "-X", "GET", "-f", "per_page=100"], repo=repo)
|
||||
if not isinstance(data, dict):
|
||||
raise GhCommandError("Unexpected payload from actions run jobs API")
|
||||
jobs = data.get("jobs") or []
|
||||
if not isinstance(jobs, list):
|
||||
raise GhCommandError("Expected `jobs` to be a list")
|
||||
return jobs
|
||||
|
||||
|
||||
def failed_jobs_from_workflow_runs(repo, runs, head_sha):
|
||||
failed_jobs = []
|
||||
for run in runs:
|
||||
if not isinstance(run, dict):
|
||||
continue
|
||||
if str(run.get("head_sha") or "") != head_sha:
|
||||
continue
|
||||
run_id = run.get("id")
|
||||
if run_id in (None, ""):
|
||||
continue
|
||||
run_status = str(run.get("status") or "")
|
||||
run_conclusion = str(run.get("conclusion") or "")
|
||||
if run_status.lower() == "completed" and run_conclusion not in FAILED_RUN_CONCLUSIONS:
|
||||
continue
|
||||
jobs = get_jobs_for_run(repo, run_id)
|
||||
for job in jobs:
|
||||
if not isinstance(job, dict):
|
||||
continue
|
||||
conclusion = str(job.get("conclusion") or "")
|
||||
if conclusion not in FAILED_RUN_CONCLUSIONS:
|
||||
continue
|
||||
job_id = job.get("id")
|
||||
logs_endpoint = None
|
||||
if job_id not in (None, ""):
|
||||
logs_endpoint = f"repos/{repo}/actions/jobs/{job_id}/logs"
|
||||
failed_jobs.append(
|
||||
{
|
||||
"run_id": run_id,
|
||||
"workflow_name": run.get("name") or run.get("display_title") or "",
|
||||
"run_status": run_status,
|
||||
"run_conclusion": run_conclusion,
|
||||
"job_id": job_id,
|
||||
"job_name": str(job.get("name") or ""),
|
||||
"status": str(job.get("status") or ""),
|
||||
"conclusion": conclusion,
|
||||
"html_url": str(job.get("html_url") or ""),
|
||||
"logs_endpoint": logs_endpoint,
|
||||
}
|
||||
)
|
||||
failed_jobs.sort(
|
||||
key=lambda item: (
|
||||
str(item.get("workflow_name") or ""),
|
||||
str(item.get("job_name") or ""),
|
||||
str(item.get("job_id") or ""),
|
||||
)
|
||||
)
|
||||
return failed_jobs
|
||||
|
||||
|
||||
def get_authenticated_login():
|
||||
data = gh_json(["api", "user"])
|
||||
if not isinstance(data, dict) or not data.get("login"):
|
||||
@@ -568,7 +628,7 @@ def is_pr_ready_to_merge(pr, checks_summary, new_review_items):
|
||||
return True
|
||||
|
||||
|
||||
def recommend_actions(pr, checks_summary, failed_runs, new_review_items, retries_used, max_retries):
|
||||
def recommend_actions(pr, checks_summary, failed_runs, failed_jobs, new_review_items, retries_used, max_retries):
|
||||
actions = []
|
||||
if pr["closed"] or pr["merged"]:
|
||||
if new_review_items:
|
||||
@@ -583,7 +643,7 @@ def recommend_actions(pr, checks_summary, failed_runs, new_review_items, retries
|
||||
if new_review_items:
|
||||
actions.append("process_review_comment")
|
||||
|
||||
has_failed_pr_checks = checks_summary["failed_count"] > 0
|
||||
has_failed_pr_checks = checks_summary["failed_count"] > 0 or bool(failed_jobs)
|
||||
if has_failed_pr_checks:
|
||||
if checks_summary["all_terminal"] and retries_used >= max_retries:
|
||||
actions.append("stop_exhausted_retries")
|
||||
@@ -621,12 +681,14 @@ def collect_snapshot(args):
|
||||
checks_summary = summarize_checks(checks)
|
||||
workflow_runs = get_workflow_runs_for_sha(pr["repo"], pr["head_sha"])
|
||||
failed_runs = failed_runs_from_workflow_runs(workflow_runs, pr["head_sha"])
|
||||
failed_jobs = failed_jobs_from_workflow_runs(pr["repo"], workflow_runs, pr["head_sha"])
|
||||
|
||||
retries_used = current_retry_count(state, pr["head_sha"])
|
||||
actions = recommend_actions(
|
||||
pr,
|
||||
checks_summary,
|
||||
failed_runs,
|
||||
failed_jobs,
|
||||
new_review_items,
|
||||
retries_used,
|
||||
args.max_flaky_retries,
|
||||
@@ -641,6 +703,7 @@ def collect_snapshot(args):
|
||||
"pr": pr,
|
||||
"checks": checks_summary,
|
||||
"failed_runs": failed_runs,
|
||||
"failed_jobs": failed_jobs,
|
||||
"new_review_items": new_review_items,
|
||||
"actions": actions,
|
||||
"retry_state": {
|
||||
|
||||
@@ -75,6 +75,11 @@ def test_collect_snapshot_fetches_review_items_before_ci(monkeypatch, tmp_path):
|
||||
"failed_runs_from_workflow_runs",
|
||||
lambda *args, **kwargs: call_order.append("failed_runs") or [],
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gh_pr_watch,
|
||||
"failed_jobs_from_workflow_runs",
|
||||
lambda *args, **kwargs: call_order.append("failed_jobs") or [],
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
gh_pr_watch,
|
||||
"recommend_actions",
|
||||
@@ -100,6 +105,7 @@ def test_recommend_actions_prioritizes_review_comments():
|
||||
sample_pr(),
|
||||
sample_checks(failed_count=1),
|
||||
[{"run_id": 99}],
|
||||
[],
|
||||
[{"kind": "review_comment", "id": "1"}],
|
||||
0,
|
||||
3,
|
||||
@@ -119,6 +125,7 @@ def test_run_watch_keeps_polling_open_ready_to_merge_pr(monkeypatch):
|
||||
"pr": sample_pr(),
|
||||
"checks": sample_checks(),
|
||||
"failed_runs": [],
|
||||
"failed_jobs": [],
|
||||
"new_review_items": [],
|
||||
"actions": ["ready_to_merge"],
|
||||
"retry_state": {
|
||||
@@ -153,3 +160,58 @@ def test_run_watch_keeps_polling_open_ready_to_merge_pr(monkeypatch):
|
||||
|
||||
assert sleeps == [30, 30]
|
||||
assert [event for event, _ in events] == ["snapshot", "snapshot"]
|
||||
|
||||
|
||||
def test_failed_jobs_include_direct_logs_endpoint(monkeypatch):
|
||||
jobs_by_run = {
|
||||
99: [
|
||||
{
|
||||
"id": 555,
|
||||
"name": "unit tests",
|
||||
"status": "completed",
|
||||
"conclusion": "failure",
|
||||
"html_url": "https://github.com/openai/codex/actions/runs/99/job/555",
|
||||
},
|
||||
{
|
||||
"id": 556,
|
||||
"name": "lint",
|
||||
"status": "completed",
|
||||
"conclusion": "success",
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
monkeypatch.setattr(
|
||||
gh_pr_watch,
|
||||
"get_jobs_for_run",
|
||||
lambda repo, run_id: jobs_by_run[run_id],
|
||||
)
|
||||
|
||||
failed_jobs = gh_pr_watch.failed_jobs_from_workflow_runs(
|
||||
"openai/codex",
|
||||
[
|
||||
{
|
||||
"id": 99,
|
||||
"name": "CI",
|
||||
"status": "in_progress",
|
||||
"conclusion": "",
|
||||
"head_sha": "abc123",
|
||||
}
|
||||
],
|
||||
"abc123",
|
||||
)
|
||||
|
||||
assert failed_jobs == [
|
||||
{
|
||||
"run_id": 99,
|
||||
"workflow_name": "CI",
|
||||
"run_status": "in_progress",
|
||||
"run_conclusion": "",
|
||||
"job_id": 555,
|
||||
"job_name": "unit tests",
|
||||
"status": "completed",
|
||||
"conclusion": "failure",
|
||||
"html_url": "https://github.com/openai/codex/actions/runs/99/job/555",
|
||||
"logs_endpoint": "repos/openai/codex/actions/jobs/555/logs",
|
||||
}
|
||||
]
|
||||
|
||||
14
.github/scripts/compute-bazel-windows-path.ps1
vendored
14
.github/scripts/compute-bazel-windows-path.ps1
vendored
@@ -5,9 +5,9 @@ tool entries, such as Maven, that can change independently of this repo and
|
||||
cause avoidable cache misses.
|
||||
|
||||
This script derives a smaller, cache-stable PATH that keeps the Windows
|
||||
toolchain entries Bazel-backed CI tasks need: MSVC and Windows SDK paths, Git,
|
||||
PowerShell, Node, Python, DotSlash, and the standard Windows system
|
||||
directories.
|
||||
toolchain entries Bazel-backed CI tasks need: MSVC and Windows SDK paths,
|
||||
MinGW runtime DLL paths for gnullvm-built tests, Git, PowerShell, Node, Python,
|
||||
DotSlash, and the standard Windows system directories.
|
||||
`setup-bazel-ci` runs this after exporting the MSVC environment, and the script
|
||||
publishes the result via `GITHUB_ENV` as `CODEX_BAZEL_WINDOWS_PATH` so later
|
||||
steps can pass that explicit PATH to Bazel.
|
||||
@@ -49,6 +49,8 @@ foreach ($pathEntry in ($env:PATH -split ';')) {
|
||||
$pathEntry -like '*Microsoft Visual Studio*' -or
|
||||
$pathEntry -like '*Windows Kits*' -or
|
||||
$pathEntry -like '*Microsoft SDKs*' -or
|
||||
$pathEntry -eq 'C:\mingw64\bin' -or
|
||||
$pathEntry -like 'C:\msys64\*\bin' -or
|
||||
$pathEntry -like 'C:\Program Files\Git\*' -or
|
||||
$pathEntry -like 'C:\Program Files\PowerShell\*' -or
|
||||
$pathEntry -like 'C:\hostedtoolcache\windows\node\*' -or
|
||||
@@ -85,6 +87,12 @@ if ($pwshCommand) {
|
||||
Add-StablePathEntry (Split-Path $pwshCommand.Source -Parent)
|
||||
}
|
||||
|
||||
foreach ($mingwPath in @('C:\mingw64\bin', 'C:\msys64\mingw64\bin', 'C:\msys64\ucrt64\bin')) {
|
||||
if (Test-Path $mingwPath) {
|
||||
Add-StablePathEntry $mingwPath
|
||||
}
|
||||
}
|
||||
|
||||
if ($windowsAppsPath) {
|
||||
Add-StablePathEntry $windowsAppsPath
|
||||
}
|
||||
|
||||
110
.github/scripts/run-bazel-ci.sh
vendored
110
.github/scripts/run-bazel-ci.sh
vendored
@@ -6,6 +6,7 @@ print_failed_bazel_test_logs=0
|
||||
print_failed_bazel_action_summary=0
|
||||
remote_download_toplevel=0
|
||||
windows_msvc_host_platform=0
|
||||
windows_cross_compile=0
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
@@ -25,6 +26,10 @@ while [[ $# -gt 0 ]]; do
|
||||
windows_msvc_host_platform=1
|
||||
shift
|
||||
;;
|
||||
--windows-cross-compile)
|
||||
windows_cross_compile=1
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
@@ -37,7 +42,7 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
echo "Usage: $0 [--print-failed-test-logs] [--print-failed-action-summary] [--remote-download-toplevel] [--windows-msvc-host-platform] -- <bazel args> -- <targets>" >&2
|
||||
echo "Usage: $0 [--print-failed-test-logs] [--print-failed-action-summary] [--remote-download-toplevel] [--windows-msvc-host-platform] [--windows-cross-compile] -- <bazel args> -- <targets>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -61,7 +66,11 @@ case "${RUNNER_OS:-}" in
|
||||
ci_config=ci-macos
|
||||
;;
|
||||
Windows)
|
||||
ci_config=ci-windows
|
||||
if [[ $windows_cross_compile -eq 1 ]]; then
|
||||
ci_config=ci-windows-cross
|
||||
else
|
||||
ci_config=ci-windows
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -105,8 +114,8 @@ print_bazel_test_log_tails() {
|
||||
while IFS= read -r target; do
|
||||
failed_targets+=("$target")
|
||||
done < <(
|
||||
grep -E '^FAIL: //' "$console_log" \
|
||||
| sed -E 's#^FAIL: (//[^ ]+).*#\1#' \
|
||||
grep -E '^(FAIL: //|ERROR: .* Testing //)' "$console_log" \
|
||||
| sed -E 's#^FAIL: (//[^ ]+).*#\1#; s#^ERROR: .* Testing (//[^ ]+) failed:.*#\1#' \
|
||||
| sort -u
|
||||
)
|
||||
|
||||
@@ -244,6 +253,12 @@ if [[ ${#bazel_args[@]} -eq 0 || ${#bazel_targets[@]} -eq 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 && -z "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
# 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
|
||||
|
||||
post_config_bazel_args=()
|
||||
if [[ "${RUNNER_OS:-}" == "Windows" && $windows_msvc_host_platform -eq 1 ]]; then
|
||||
has_host_platform_override=0
|
||||
@@ -269,6 +284,25 @@ if [[ $remote_download_toplevel -eq 1 ]]; then
|
||||
post_config_bazel_args+=(--remote_download_toplevel)
|
||||
fi
|
||||
|
||||
if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 && -n "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
# `--enable_platform_specific_config` expands `common:windows` on Windows
|
||||
# hosts after ordinary rc configs, which can override `ci-windows-cross`'s
|
||||
# RBE host platform. Repeat the host platform on the command line so V8 and
|
||||
# other genrules execute on Linux RBE workers instead of Git Bash locally.
|
||||
#
|
||||
# Bazel also derives the default genrule shell from the client host. Without
|
||||
# an explicit shell executable, remote Linux actions can be asked to run
|
||||
# `C:\Program Files\Git\usr\bin\bash.exe`.
|
||||
post_config_bazel_args+=(--host_platform=//:rbe --shell_executable=/bin/bash)
|
||||
fi
|
||||
|
||||
if [[ "${RUNNER_OS:-}" == "Windows" && $windows_cross_compile -eq 1 && -z "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
# 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
|
||||
|
||||
if [[ -n "${BAZEL_REPO_CONTENTS_CACHE:-}" ]]; then
|
||||
# Windows self-hosted runners can run multiple Bazel jobs concurrently. Give
|
||||
# each job its own repo contents cache so they do not fight over the shared
|
||||
@@ -287,37 +321,57 @@ if [[ -n "${CODEX_BAZEL_EXECUTION_LOG_COMPACT_DIR:-}" ]]; then
|
||||
fi
|
||||
|
||||
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
|
||||
windows_action_env_vars=(
|
||||
INCLUDE
|
||||
LIB
|
||||
LIBPATH
|
||||
UCRTVersion
|
||||
UniversalCRTSdkDir
|
||||
VCINSTALLDIR
|
||||
VCToolsInstallDir
|
||||
WindowsLibPath
|
||||
WindowsSdkBinPath
|
||||
WindowsSdkDir
|
||||
WindowsSDKLibVersion
|
||||
WindowsSDKVersion
|
||||
)
|
||||
pass_windows_build_env=1
|
||||
if [[ $windows_cross_compile -eq 1 && -n "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
# Remote build actions execute on Linux RBE workers. Passing the Windows
|
||||
# runner's build environment there makes Bazel genrules try to execute
|
||||
# C:\Program Files\Git\usr\bin\bash.exe on Linux.
|
||||
pass_windows_build_env=0
|
||||
fi
|
||||
|
||||
for env_var in "${windows_action_env_vars[@]}"; do
|
||||
if [[ -n "${!env_var:-}" ]]; then
|
||||
post_config_bazel_args+=("--action_env=${env_var}" "--host_action_env=${env_var}")
|
||||
fi
|
||||
done
|
||||
if [[ $pass_windows_build_env -eq 1 ]]; then
|
||||
windows_action_env_vars=(
|
||||
INCLUDE
|
||||
LIB
|
||||
LIBPATH
|
||||
UCRTVersion
|
||||
UniversalCRTSdkDir
|
||||
VCINSTALLDIR
|
||||
VCToolsInstallDir
|
||||
WindowsLibPath
|
||||
WindowsSdkBinPath
|
||||
WindowsSdkDir
|
||||
WindowsSDKLibVersion
|
||||
WindowsSDKVersion
|
||||
)
|
||||
|
||||
for env_var in "${windows_action_env_vars[@]}"; do
|
||||
if [[ -n "${!env_var:-}" ]]; then
|
||||
post_config_bazel_args+=("--action_env=${env_var}" "--host_action_env=${env_var}")
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ -z "${CODEX_BAZEL_WINDOWS_PATH:-}" ]]; then
|
||||
echo "CODEX_BAZEL_WINDOWS_PATH must be set for Windows Bazel CI." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
post_config_bazel_args+=(
|
||||
"--action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}"
|
||||
"--host_action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}"
|
||||
"--test_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}"
|
||||
)
|
||||
if [[ $pass_windows_build_env -eq 1 ]]; then
|
||||
post_config_bazel_args+=(
|
||||
"--action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}"
|
||||
"--host_action_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}"
|
||||
)
|
||||
elif [[ $windows_cross_compile -eq 1 ]]; then
|
||||
# Remote build actions run on Linux RBE workers. Give their shell snippets
|
||||
# a Linux PATH while preserving CODEX_BAZEL_WINDOWS_PATH below for local
|
||||
# Windows test execution.
|
||||
post_config_bazel_args+=(
|
||||
"--action_env=PATH=/usr/bin:/bin"
|
||||
"--host_action_env=PATH=/usr/bin:/bin"
|
||||
)
|
||||
fi
|
||||
post_config_bazel_args+=("--test_env=PATH=${CODEX_BAZEL_WINDOWS_PATH}")
|
||||
fi
|
||||
|
||||
bazel_console_log="$(mktemp)"
|
||||
|
||||
13
.github/scripts/run-bazel-query-ci.sh
vendored
13
.github/scripts/run-bazel-query-ci.sh
vendored
@@ -6,8 +6,13 @@ set -euo pipefail
|
||||
# invocation so target-discovery queries can reuse the same Bazel server.
|
||||
|
||||
query_args=()
|
||||
windows_cross_compile=0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--windows-cross-compile)
|
||||
windows_cross_compile=1
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
@@ -20,7 +25,7 @@ while [[ $# -gt 0 ]]; do
|
||||
done
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
echo "Usage: $0 [<bazel query args>...] -- <query expression>" >&2
|
||||
echo "Usage: $0 [--windows-cross-compile] [<bazel query args>...] -- <query expression>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -32,7 +37,11 @@ case "${RUNNER_OS:-}" in
|
||||
ci_config=ci-macos
|
||||
;;
|
||||
Windows)
|
||||
ci_config=ci-windows
|
||||
if [[ $windows_cross_compile -eq 1 ]]; then
|
||||
ci_config=ci-windows-cross
|
||||
else
|
||||
ci_config=ci-windows
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
133
.github/workflows/bazel.yml
vendored
133
.github/workflows/bazel.yml
vendored
@@ -17,13 +17,10 @@ concurrency:
|
||||
cancel-in-progress: ${{ github.ref_name != 'main' }}
|
||||
jobs:
|
||||
test:
|
||||
# Even though a no-cache-hit Windows build seems to exceed the 30-minute
|
||||
# limit on occasion, the more common reason for exceeding the limit is a
|
||||
# true test failure in a rust_test() marked "flaky" that gets run 3x.
|
||||
# In that case, extra time generally does not give us more signal.
|
||||
#
|
||||
# Ultimately we need true distributed builds (e.g.,
|
||||
# https://www.buildbuddy.io/docs/rbe-setup/) to speed things up.
|
||||
# PRs use a fast Windows cross-compiled test leg for pre-merge signal.
|
||||
# Post-merge pushes to main also run the native Windows test job below,
|
||||
# which keeps V8/code-mode coverage without putting PR latency back on the
|
||||
# critical path.
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -47,13 +44,16 @@ jobs:
|
||||
# - os: ubuntu-24.04-arm
|
||||
# target: aarch64-unknown-linux-gnu
|
||||
|
||||
# Windows
|
||||
# Windows fast path: build the windows-gnullvm binaries with Linux
|
||||
# RBE, then run the resulting Windows tests on the Windows runner.
|
||||
# The main-only native Windows job below preserves full V8/code-mode
|
||||
# coverage post-merge.
|
||||
- os: windows-latest
|
||||
target: x86_64-pc-windows-gnullvm
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
# Configure a human readable name for each job
|
||||
name: Local Bazel build on ${{ matrix.os }} for ${{ matrix.target }}
|
||||
name: Bazel test on ${{ matrix.os }} for ${{ matrix.target }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
@@ -91,6 +91,7 @@ jobs:
|
||||
)
|
||||
|
||||
bazel_wrapper_args=(
|
||||
--print-failed-action-summary
|
||||
--print-failed-test-logs
|
||||
)
|
||||
bazel_test_args=(
|
||||
@@ -100,8 +101,19 @@ jobs:
|
||||
--build_metadata=COMMIT_SHA=${GITHUB_SHA}
|
||||
)
|
||||
if [[ "${RUNNER_OS}" == "Windows" ]]; then
|
||||
bazel_wrapper_args+=(--windows-msvc-host-platform)
|
||||
bazel_test_args+=(--jobs=8)
|
||||
bazel_wrapper_args+=(
|
||||
--windows-cross-compile
|
||||
--remote-download-toplevel
|
||||
)
|
||||
# Tradeoff: the Linux-RBE-built windows-gnullvm V8 archive
|
||||
# currently crashes during direct V8/code-mode smoke tests on the
|
||||
# Windows runner. Keep the broader fast Windows suite in PR CI and
|
||||
# rely on the main-only native Windows job below for full
|
||||
# V8/code-mode signal while we investigate the cross-built archive.
|
||||
bazel_targets+=(
|
||||
-//codex-rs/code-mode:code-mode-unit-tests
|
||||
-//codex-rs/v8-poc:v8-poc-unit-tests
|
||||
)
|
||||
fi
|
||||
|
||||
./.github/scripts/run-bazel-ci.sh \
|
||||
@@ -130,6 +142,75 @@ jobs:
|
||||
path: ${{ steps.prepare_bazel.outputs.repository-cache-path }}
|
||||
key: ${{ steps.prepare_bazel.outputs.repository-cache-key }}
|
||||
|
||||
test-windows-native-main:
|
||||
# Native Windows Bazel tests are slower and frequently approach the
|
||||
# 30-minute PR budget, but they provide the full V8/code-mode signal that
|
||||
# the fast cross-compiled PR leg intentionally trades away. Run this only
|
||||
# for post-merge commits to main and give it a larger timeout.
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
timeout-minutes: 40
|
||||
runs-on: windows-latest
|
||||
name: Bazel test on windows-latest for x86_64-pc-windows-gnullvm (native main)
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
|
||||
- name: Prepare Bazel CI
|
||||
id: prepare_bazel
|
||||
uses: ./.github/actions/prepare-bazel-ci
|
||||
with:
|
||||
target: x86_64-pc-windows-gnullvm
|
||||
cache-scope: bazel-${{ github.job }}
|
||||
install-test-prereqs: "true"
|
||||
|
||||
- name: bazel test //...
|
||||
env:
|
||||
BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }}
|
||||
shell: bash
|
||||
run: |
|
||||
bazel_targets=(
|
||||
//...
|
||||
# Keep standalone V8 library targets out of the ordinary Bazel CI
|
||||
# path. V8 consumers under `//codex-rs/...` still participate
|
||||
# transitively through `//...`.
|
||||
-//third_party/v8:all
|
||||
)
|
||||
|
||||
bazel_test_args=(
|
||||
test
|
||||
--test_tag_filters=-argument-comment-lint
|
||||
--test_verbose_timeout_warnings
|
||||
--build_metadata=COMMIT_SHA=${GITHUB_SHA}
|
||||
--build_metadata=TAG_windows_native_main=true
|
||||
)
|
||||
|
||||
./.github/scripts/run-bazel-ci.sh \
|
||||
--print-failed-action-summary \
|
||||
--print-failed-test-logs \
|
||||
-- \
|
||||
"${bazel_test_args[@]}" \
|
||||
-- \
|
||||
"${bazel_targets[@]}"
|
||||
|
||||
- name: Upload Bazel execution logs
|
||||
if: always() && !cancelled()
|
||||
continue-on-error: true
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
|
||||
with:
|
||||
name: bazel-execution-logs-test-windows-native-x86_64-pc-windows-gnullvm
|
||||
path: ${{ runner.temp }}/bazel-execution-logs
|
||||
if-no-files-found: ignore
|
||||
|
||||
# Save the job-scoped Bazel repository cache after cache misses. Keep the
|
||||
# upload non-fatal so cache service issues never fail the job itself.
|
||||
- name: Save bazel repository cache
|
||||
if: always() && !cancelled() && steps.prepare_bazel.outputs.repository-cache-hit != 'true'
|
||||
continue-on-error: true
|
||||
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
|
||||
with:
|
||||
path: ${{ steps.prepare_bazel.outputs.repository-cache-path }}
|
||||
key: ${{ steps.prepare_bazel.outputs.repository-cache-key }}
|
||||
|
||||
clippy:
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
@@ -170,17 +251,24 @@ jobs:
|
||||
--build_metadata=TAG_job=clippy
|
||||
)
|
||||
bazel_wrapper_args=()
|
||||
bazel_target_list_args=()
|
||||
if [[ "${RUNNER_OS}" == "Windows" ]]; then
|
||||
# Keep this aligned with the Windows Bazel test job. With the
|
||||
# default `//:local_windows` host platform, Windows `rust_test`
|
||||
# targets such as `//codex-rs/core:core-all-test` can be skipped
|
||||
# by `--skip_incompatible_explicit_targets`, which hides clippy
|
||||
# diagnostics from integration-test modules.
|
||||
bazel_wrapper_args+=(--windows-msvc-host-platform)
|
||||
bazel_clippy_args+=(--skip_incompatible_explicit_targets)
|
||||
# Keep this aligned with the fast Windows Bazel test job: use
|
||||
# Linux RBE for clippy build actions while targeting Windows
|
||||
# gnullvm. Fork/community PRs without the BuildBuddy secret fall
|
||||
# back inside `run-bazel-ci.sh` to the previous local Windows MSVC
|
||||
# host-platform shape.
|
||||
bazel_wrapper_args+=(--windows-cross-compile)
|
||||
bazel_target_list_args+=(--windows-cross-compile)
|
||||
if [[ -z "${BUILDBUDDY_API_KEY:-}" ]]; then
|
||||
# The fork fallback can see incompatible explicit Windows-cross
|
||||
# internal test binaries in the generated target list. Preserve
|
||||
# the old local-fallback behavior there.
|
||||
bazel_clippy_args+=(--skip_incompatible_explicit_targets)
|
||||
fi
|
||||
fi
|
||||
|
||||
bazel_target_lines="$(./scripts/list-bazel-clippy-targets.sh)"
|
||||
bazel_target_lines="$(./scripts/list-bazel-clippy-targets.sh "${bazel_target_list_args[@]}")"
|
||||
bazel_targets=()
|
||||
while IFS= read -r target; do
|
||||
bazel_targets+=("${target}")
|
||||
@@ -252,7 +340,12 @@ jobs:
|
||||
# Rust debug assertions explicitly.
|
||||
bazel_wrapper_args=()
|
||||
if [[ "${RUNNER_OS}" == "Windows" ]]; then
|
||||
bazel_wrapper_args+=(--windows-msvc-host-platform)
|
||||
# This is build-only signal, so use the same Linux-RBE
|
||||
# cross-compile path as the fast Windows test and clippy jobs.
|
||||
# Fork/community PRs without the BuildBuddy secret fall back
|
||||
# inside `run-bazel-ci.sh` to the previous local Windows MSVC
|
||||
# host-platform shape.
|
||||
bazel_wrapper_args+=(--windows-cross-compile)
|
||||
fi
|
||||
|
||||
bazel_build_args=(
|
||||
|
||||
4
.github/workflows/cargo-deny.yml
vendored
4
.github/workflows/cargo-deny.yml
vendored
@@ -17,10 +17,10 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable
|
||||
uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
|
||||
- name: Run cargo-deny
|
||||
uses: EmbarkStudios/cargo-deny-action@82eb9f621fbc699dd0918f3ea06864c14cc84246 # v2
|
||||
with:
|
||||
rust-version: stable
|
||||
rust-version: 1.93.0
|
||||
manifest-path: ./codex-rs/Cargo.toml
|
||||
|
||||
6
.github/workflows/rust-release-windows.yml
vendored
6
.github/workflows/rust-release-windows.yml
vendored
@@ -24,7 +24,9 @@ jobs:
|
||||
build-windows-binaries:
|
||||
name: Build Windows binaries - ${{ matrix.runner }} - ${{ matrix.target }} - ${{ matrix.bundle }}
|
||||
runs-on: ${{ matrix.runs_on }}
|
||||
timeout-minutes: 60
|
||||
# Windows release builds can exceed an hour on fat-LTO mainline releases,
|
||||
# so keep the timeout aligned with the top-level release build headroom.
|
||||
timeout-minutes: 90
|
||||
permissions:
|
||||
contents: read
|
||||
defaults:
|
||||
@@ -137,7 +139,7 @@ jobs:
|
||||
- build-windows-binaries
|
||||
name: Build - ${{ matrix.runner }} - ${{ matrix.target }}
|
||||
runs-on: ${{ matrix.runs_on }}
|
||||
timeout-minutes: 60
|
||||
timeout-minutes: 90
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
6
.github/workflows/rust-release.yml
vendored
6
.github/workflows/rust-release.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- uses: dtolnay/rust-toolchain@c2b55edffaf41a251c410bb32bed22afefa800f1 # 1.92
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
- name: Validate tag matches Cargo.toml version
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -49,7 +49,9 @@ jobs:
|
||||
needs: tag-check
|
||||
name: Build - ${{ matrix.runner }} - ${{ matrix.target }} - ${{ matrix.bundle }}
|
||||
runs-on: ${{ matrix.runs_on || matrix.runner }}
|
||||
timeout-minutes: 60
|
||||
# Release builds can take a long time, so leave some headroom to avoid
|
||||
# having to restart the full workflow due to a timeout.
|
||||
timeout-minutes: 90
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
@@ -19,6 +19,12 @@ In the codex-rs folder where the rust code lives:
|
||||
- You can run `just argument-comment-lint` to run the lint check locally. This is powered by Bazel, so running it the first time can be slow if Bazel is not warmed up, though incremental invocations should take <15s. Most of the time, it is best to update the PR and let CI take responsibility for checking this (or run it asynchronously in the background after submitting the PR). Note CI checks all three platforms, which the local run does not.
|
||||
- When possible, make `match` statements exhaustive and avoid wildcard arms.
|
||||
- Newly added traits should include doc comments that explain their role and how implementations are expected to use them.
|
||||
- Discourage both `#[async_trait]` and `#[allow(async_fn_in_trait)]` in Rust traits.
|
||||
- Prefer native RPITIT trait methods with explicit `Send` bounds on the returned future, as in `3c7f013f9735` / `#16630`.
|
||||
- Preferred trait shape:
|
||||
`fn foo(&self, ...) -> impl std::future::Future<Output = T> + Send;`
|
||||
- Implementations may still use `async fn foo(&self, ...) -> T` when they satisfy that contract.
|
||||
- Do not use `#[allow(async_fn_in_trait)]` as a shortcut around spelling the future contract explicitly.
|
||||
- When writing tests, prefer comparing the equality of entire objects over fields one by one.
|
||||
- When making a change that adds or changes an API, ensure that the documentation in the `docs/` folder is up to date if applicable.
|
||||
- Prefer private modules and explicitly exported public crate API.
|
||||
|
||||
34
BUILD.bazel
34
BUILD.bazel
@@ -30,6 +30,40 @@ platform(
|
||||
parents = ["@platforms//host"],
|
||||
)
|
||||
|
||||
platform(
|
||||
name = "windows_x86_64_gnullvm",
|
||||
constraint_values = [
|
||||
"@platforms//cpu:x86_64",
|
||||
"@platforms//os:windows",
|
||||
"@rules_rs//rs/experimental/platforms/constraints:windows_gnullvm",
|
||||
],
|
||||
)
|
||||
|
||||
platform(
|
||||
name = "windows_x86_64_msvc",
|
||||
constraint_values = [
|
||||
"@platforms//cpu:x86_64",
|
||||
"@platforms//os:windows",
|
||||
"@rules_rs//rs/experimental/platforms/constraints:windows_msvc",
|
||||
],
|
||||
)
|
||||
|
||||
toolchain(
|
||||
name = "windows_gnullvm_tests_on_msvc_host_toolchain",
|
||||
exec_compatible_with = [
|
||||
"@platforms//cpu:x86_64",
|
||||
"@platforms//os:windows",
|
||||
"@rules_rs//rs/experimental/platforms/constraints:windows_msvc",
|
||||
],
|
||||
target_compatible_with = [
|
||||
"@platforms//cpu:x86_64",
|
||||
"@platforms//os:windows",
|
||||
"@rules_rs//rs/experimental/platforms/constraints:windows_gnullvm",
|
||||
],
|
||||
toolchain = "@bazel_tools//tools/test:empty_toolchain",
|
||||
toolchain_type = "@bazel_tools//tools/test:default_test_toolchain_type",
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "rbe",
|
||||
actual = "@rbe_platform",
|
||||
|
||||
@@ -6,4 +6,6 @@ ignore = [
|
||||
"RUSTSEC-2024-0436", # paste 1.0.15 via starlark/ratatui; upstream crate is unmaintained
|
||||
"RUSTSEC-2024-0320", # yaml-rust via syntect; remove when syntect drops or updates it
|
||||
"RUSTSEC-2025-0141", # bincode via syntect; remove when syntect drops or updates it
|
||||
"RUSTSEC-2026-0118", # hickory-proto via rama-dns/rama-tcp; remove when rama updates to hickory 0.26.1 or hickory-net
|
||||
"RUSTSEC-2026-0119", # hickory-proto via rama-dns/rama-tcp; remove when rama updates to hickory 0.26.1 or hickory-net
|
||||
]
|
||||
|
||||
2
codex-rs/.github/workflows/cargo-audit.yml
vendored
2
codex-rs/.github/workflows/cargo-audit.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
working-directory: codex-rs
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- uses: dtolnay/rust-toolchain@a0b273b48ed29de4470960879e8381ff45632f26 # 1.93.0
|
||||
- name: Install cargo-audit
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
|
||||
106
codex-rs/Cargo.lock
generated
106
codex-rs/Cargo.lock
generated
@@ -1748,6 +1748,21 @@ dependencies = [
|
||||
"unicode-width 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-agent-graph-store"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"codex-protocol",
|
||||
"codex-state",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
"thiserror 2.0.18",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-agent-identity"
|
||||
version = "0.0.0"
|
||||
@@ -1842,8 +1857,8 @@ dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
"codex-analytics",
|
||||
"codex-api",
|
||||
"codex-app-server-protocol",
|
||||
"codex-app-server-transport",
|
||||
"codex-arg0",
|
||||
"codex-backend-client",
|
||||
"codex-chatgpt",
|
||||
@@ -1859,6 +1874,7 @@ dependencies = [
|
||||
"codex-feedback",
|
||||
"codex-file-search",
|
||||
"codex-git-utils",
|
||||
"codex-hooks",
|
||||
"codex-login",
|
||||
"codex-mcp",
|
||||
"codex-memories-write",
|
||||
@@ -1866,6 +1882,7 @@ dependencies = [
|
||||
"codex-model-provider-info",
|
||||
"codex-models-manager",
|
||||
"codex-otel",
|
||||
"codex-plugin",
|
||||
"codex-protocol",
|
||||
"codex-rmcp-client",
|
||||
"codex-rollout",
|
||||
@@ -1874,23 +1891,17 @@ dependencies = [
|
||||
"codex-state",
|
||||
"codex-thread-store",
|
||||
"codex-tools",
|
||||
"codex-uds",
|
||||
"codex-utils-absolute-path",
|
||||
"codex-utils-cargo-bin",
|
||||
"codex-utils-cli",
|
||||
"codex-utils-json-to-toml",
|
||||
"codex-utils-pty",
|
||||
"codex-utils-rustls-provider",
|
||||
"constant_time_eq 0.3.1",
|
||||
"core_test_support",
|
||||
"flate2",
|
||||
"futures",
|
||||
"gethostname",
|
||||
"hmac",
|
||||
"jsonwebtoken",
|
||||
"opentelemetry",
|
||||
"opentelemetry_sdk",
|
||||
"owo-colors",
|
||||
"pretty_assertions",
|
||||
"reqwest",
|
||||
"rmcp",
|
||||
@@ -1988,6 +1999,45 @@ dependencies = [
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-app-server-transport"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"axum",
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"clap",
|
||||
"codex-api",
|
||||
"codex-app-server-protocol",
|
||||
"codex-config",
|
||||
"codex-core",
|
||||
"codex-login",
|
||||
"codex-model-provider",
|
||||
"codex-state",
|
||||
"codex-uds",
|
||||
"codex-utils-absolute-path",
|
||||
"codex-utils-rustls-provider",
|
||||
"constant_time_eq 0.3.1",
|
||||
"futures",
|
||||
"gethostname",
|
||||
"hmac",
|
||||
"jsonwebtoken",
|
||||
"owo-colors",
|
||||
"pretty_assertions",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"tempfile",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-tungstenite",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-apply-patch"
|
||||
version = "0.0.0"
|
||||
@@ -2084,9 +2134,11 @@ dependencies = [
|
||||
"codex-app-server-protocol",
|
||||
"codex-connectors",
|
||||
"codex-core",
|
||||
"codex-core-plugins",
|
||||
"codex-git-utils",
|
||||
"codex-login",
|
||||
"codex-model-provider",
|
||||
"codex-plugin",
|
||||
"codex-utils-cargo-bin",
|
||||
"codex-utils-cli",
|
||||
"pretty_assertions",
|
||||
@@ -2168,6 +2220,7 @@ dependencies = [
|
||||
"opentelemetry_sdk",
|
||||
"pretty_assertions",
|
||||
"rand 0.9.3",
|
||||
"rcgen",
|
||||
"reqwest",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
@@ -2464,12 +2517,31 @@ dependencies = [
|
||||
"zstd 0.13.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-core-api"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"codex-analytics",
|
||||
"codex-app-server-protocol",
|
||||
"codex-arg0",
|
||||
"codex-config",
|
||||
"codex-core",
|
||||
"codex-exec-server",
|
||||
"codex-features",
|
||||
"codex-login",
|
||||
"codex-model-provider-info",
|
||||
"codex-models-manager",
|
||||
"codex-protocol",
|
||||
"codex-utils-absolute-path",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codex-core-plugins"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"codex-analytics",
|
||||
"codex-app-server-protocol",
|
||||
"codex-config",
|
||||
"codex-core-skills",
|
||||
@@ -2944,9 +3016,7 @@ dependencies = [
|
||||
"codex-config",
|
||||
"codex-core",
|
||||
"codex-exec-server",
|
||||
"codex-features",
|
||||
"codex-login",
|
||||
"codex-models-manager",
|
||||
"codex-protocol",
|
||||
"codex-shell-command",
|
||||
"codex-utils-absolute-path",
|
||||
@@ -3483,18 +3553,8 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"codex-arg0",
|
||||
"codex-config",
|
||||
"codex-core",
|
||||
"codex-exec-server",
|
||||
"codex-features",
|
||||
"codex-login",
|
||||
"codex-model-provider-info",
|
||||
"codex-models-manager",
|
||||
"codex-protocol",
|
||||
"codex-rollout",
|
||||
"codex-thread-store",
|
||||
"codex-utils-absolute-path",
|
||||
"codex-core-api",
|
||||
"serde_json",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
@@ -3569,6 +3629,7 @@ dependencies = [
|
||||
"codex-install-context",
|
||||
"codex-login",
|
||||
"codex-mcp",
|
||||
"codex-model-provider",
|
||||
"codex-model-provider-info",
|
||||
"codex-models-manager",
|
||||
"codex-otel",
|
||||
@@ -3856,6 +3917,8 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"pretty_assertions",
|
||||
"regex-lite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3880,6 +3943,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.22.1",
|
||||
"chrono",
|
||||
"codex-otel",
|
||||
"codex-protocol",
|
||||
"codex-utils-absolute-path",
|
||||
"codex-utils-pty",
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
members = [
|
||||
"aws-auth",
|
||||
"analytics",
|
||||
"agent-graph-store",
|
||||
"agent-identity",
|
||||
"backend-client",
|
||||
"ansi-escape",
|
||||
"async-utils",
|
||||
"app-server",
|
||||
"app-server-transport",
|
||||
"app-server-client",
|
||||
"app-server-protocol",
|
||||
"app-server-test-client",
|
||||
@@ -31,6 +33,7 @@ members = [
|
||||
"shell-escalation",
|
||||
"skills",
|
||||
"core",
|
||||
"core-api",
|
||||
"core-plugins",
|
||||
"core-skills",
|
||||
"hooks",
|
||||
@@ -119,11 +122,13 @@ license = "Apache-2.0"
|
||||
# Internal
|
||||
app_test_support = { path = "app-server/tests/common" }
|
||||
codex-analytics = { path = "analytics" }
|
||||
codex-agent-graph-store = { path = "agent-graph-store" }
|
||||
codex-agent-identity = { path = "agent-identity" }
|
||||
codex-ansi-escape = { path = "ansi-escape" }
|
||||
codex-api = { path = "codex-api" }
|
||||
codex-aws-auth = { path = "aws-auth" }
|
||||
codex-app-server = { path = "app-server" }
|
||||
codex-app-server-transport = { path = "app-server-transport" }
|
||||
codex-app-server-client = { path = "app-server-client" }
|
||||
codex-app-server-protocol = { path = "app-server-protocol" }
|
||||
codex-app-server-test-client = { path = "app-server-test-client" }
|
||||
@@ -142,6 +147,7 @@ codex-code-mode = { path = "code-mode" }
|
||||
codex-config = { path = "config" }
|
||||
codex-connectors = { path = "connectors" }
|
||||
codex-core = { path = "core" }
|
||||
codex-core-api = { path = "core-api" }
|
||||
codex-core-plugins = { path = "core-plugins" }
|
||||
codex-core-skills = { path = "core-skills" }
|
||||
codex-device-key = { path = "device-key" }
|
||||
@@ -316,6 +322,10 @@ quick-xml = "0.38.4"
|
||||
rand = "0.9"
|
||||
ratatui = "0.29.0"
|
||||
ratatui-macros = "0.6.0"
|
||||
rcgen = { version = "0.14.7", default-features = false, features = [
|
||||
"aws_lc_rs",
|
||||
"pem",
|
||||
] }
|
||||
regex = "1.12.3"
|
||||
regex-lite = "0.1.8"
|
||||
reqwest = { version = "0.12", features = ["cookies"] }
|
||||
@@ -450,6 +460,7 @@ unwrap_used = "deny"
|
||||
# silence the false positive here instead of deleting a real dependency.
|
||||
[workspace.metadata.cargo-shear]
|
||||
ignored = [
|
||||
"codex-agent-graph-store",
|
||||
"icu_provider",
|
||||
"openssl-sys",
|
||||
"codex-utils-readiness",
|
||||
|
||||
@@ -46,7 +46,7 @@ Use `codex mcp` to add/list/get/remove MCP server launchers defined in `config.t
|
||||
|
||||
### Notifications
|
||||
|
||||
You can enable notifications by configuring a script that is run whenever the agent finishes a turn. The [notify documentation](../docs/config.md#notify) includes a detailed example that explains how to get desktop notifications via [terminal-notifier](https://github.com/julienXX/terminal-notifier) on macOS. When Codex detects that it is running under WSL 2 inside Windows Terminal (`WT_SESSION` is set), the TUI automatically falls back to native Windows toast notifications so approval prompts and completed turns surface even though Windows Terminal does not implement OSC 9.
|
||||
The legacy `notify` setting is deprecated and will be removed in a future release. Existing configurations still work, but new automation should use lifecycle hooks instead. The [notify documentation](../docs/config.md#notify) explains the remaining compatibility behavior. When Codex detects that it is running under WSL 2 inside Windows Terminal (`WT_SESSION` is set), the TUI automatically falls back to native Windows toast notifications so approval prompts and completed turns surface even though Windows Terminal does not implement OSC 9.
|
||||
|
||||
### `codex exec` to run Codex programmatically/non-interactively
|
||||
|
||||
|
||||
6
codex-rs/agent-graph-store/BUILD.bazel
Normal file
6
codex-rs/agent-graph-store/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "agent-graph-store",
|
||||
crate_name = "codex_agent_graph_store",
|
||||
)
|
||||
25
codex-rs/agent-graph-store/Cargo.toml
Normal file
25
codex-rs/agent-graph-store/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
name = "codex-agent-graph-store"
|
||||
version.workspace = true
|
||||
|
||||
[lib]
|
||||
name = "codex_agent_graph_store"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
async-trait = { workspace = true }
|
||||
codex-protocol = { workspace = true }
|
||||
codex-state = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tempfile = { workspace = true }
|
||||
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
|
||||
20
codex-rs/agent-graph-store/src/error.rs
Normal file
20
codex-rs/agent-graph-store/src/error.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
/// Result type returned by agent graph store operations.
|
||||
pub type AgentGraphStoreResult<T> = Result<T, AgentGraphStoreError>;
|
||||
|
||||
/// Error type shared by agent graph store implementations.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AgentGraphStoreError {
|
||||
/// The caller supplied invalid request data.
|
||||
#[error("invalid agent graph store request: {message}")]
|
||||
InvalidRequest {
|
||||
/// User-facing explanation of the invalid request.
|
||||
message: String,
|
||||
},
|
||||
|
||||
/// Catch-all for implementation failures that do not fit a more specific category.
|
||||
#[error("agent graph store internal error: {message}")]
|
||||
Internal {
|
||||
/// User-facing explanation of the implementation failure.
|
||||
message: String,
|
||||
},
|
||||
}
|
||||
12
codex-rs/agent-graph-store/src/lib.rs
Normal file
12
codex-rs/agent-graph-store/src/lib.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
//! Storage-neutral parent/child topology for thread-spawned agents.
|
||||
|
||||
mod error;
|
||||
mod local;
|
||||
mod store;
|
||||
mod types;
|
||||
|
||||
pub use error::AgentGraphStoreError;
|
||||
pub use error::AgentGraphStoreResult;
|
||||
pub use local::LocalAgentGraphStore;
|
||||
pub use store::AgentGraphStore;
|
||||
pub use types::ThreadSpawnEdgeStatus;
|
||||
325
codex-rs/agent-graph-store/src/local.rs
Normal file
325
codex-rs/agent-graph-store/src/local.rs
Normal file
@@ -0,0 +1,325 @@
|
||||
use async_trait::async_trait;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_state::StateRuntime;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::AgentGraphStore;
|
||||
use crate::AgentGraphStoreError;
|
||||
use crate::AgentGraphStoreResult;
|
||||
use crate::ThreadSpawnEdgeStatus;
|
||||
|
||||
/// SQLite-backed implementation of [`AgentGraphStore`] using an existing state runtime.
|
||||
#[derive(Clone)]
|
||||
pub struct LocalAgentGraphStore {
|
||||
state_db: Arc<StateRuntime>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for LocalAgentGraphStore {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("LocalAgentGraphStore")
|
||||
.field("codex_home", &self.state_db.codex_home())
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalAgentGraphStore {
|
||||
/// Create a local graph store from an already-initialized state runtime.
|
||||
pub fn new(state_db: Arc<StateRuntime>) -> Self {
|
||||
Self { state_db }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AgentGraphStore for LocalAgentGraphStore {
|
||||
async fn upsert_thread_spawn_edge(
|
||||
&self,
|
||||
parent_thread_id: ThreadId,
|
||||
child_thread_id: ThreadId,
|
||||
status: ThreadSpawnEdgeStatus,
|
||||
) -> AgentGraphStoreResult<()> {
|
||||
self.state_db
|
||||
.upsert_thread_spawn_edge(parent_thread_id, child_thread_id, to_state_status(status))
|
||||
.await
|
||||
.map_err(internal_error)
|
||||
}
|
||||
|
||||
async fn set_thread_spawn_edge_status(
|
||||
&self,
|
||||
child_thread_id: ThreadId,
|
||||
status: ThreadSpawnEdgeStatus,
|
||||
) -> AgentGraphStoreResult<()> {
|
||||
self.state_db
|
||||
.set_thread_spawn_edge_status(child_thread_id, to_state_status(status))
|
||||
.await
|
||||
.map_err(internal_error)
|
||||
}
|
||||
|
||||
async fn list_thread_spawn_children(
|
||||
&self,
|
||||
parent_thread_id: ThreadId,
|
||||
status_filter: Option<ThreadSpawnEdgeStatus>,
|
||||
) -> AgentGraphStoreResult<Vec<ThreadId>> {
|
||||
if let Some(status) = status_filter {
|
||||
return self
|
||||
.state_db
|
||||
.list_thread_spawn_children_with_status(parent_thread_id, to_state_status(status))
|
||||
.await
|
||||
.map_err(internal_error);
|
||||
}
|
||||
|
||||
self.state_db
|
||||
.list_thread_spawn_children(parent_thread_id)
|
||||
.await
|
||||
.map_err(internal_error)
|
||||
}
|
||||
|
||||
async fn list_thread_spawn_descendants(
|
||||
&self,
|
||||
root_thread_id: ThreadId,
|
||||
status_filter: Option<ThreadSpawnEdgeStatus>,
|
||||
) -> AgentGraphStoreResult<Vec<ThreadId>> {
|
||||
match status_filter {
|
||||
Some(status) => self
|
||||
.state_db
|
||||
.list_thread_spawn_descendants_with_status(root_thread_id, to_state_status(status))
|
||||
.await
|
||||
.map_err(internal_error),
|
||||
None => self
|
||||
.state_db
|
||||
.list_thread_spawn_descendants(root_thread_id)
|
||||
.await
|
||||
.map_err(internal_error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn to_state_status(status: ThreadSpawnEdgeStatus) -> codex_state::DirectionalThreadSpawnEdgeStatus {
|
||||
match status {
|
||||
ThreadSpawnEdgeStatus::Open => codex_state::DirectionalThreadSpawnEdgeStatus::Open,
|
||||
ThreadSpawnEdgeStatus::Closed => codex_state::DirectionalThreadSpawnEdgeStatus::Closed,
|
||||
}
|
||||
}
|
||||
|
||||
fn internal_error(err: impl std::fmt::Display) -> AgentGraphStoreError {
|
||||
AgentGraphStoreError::Internal {
|
||||
message: err.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use codex_state::DirectionalThreadSpawnEdgeStatus;
|
||||
use pretty_assertions::assert_eq;
|
||||
use tempfile::TempDir;
|
||||
|
||||
struct TestRuntime {
|
||||
state_db: Arc<StateRuntime>,
|
||||
_codex_home: TempDir,
|
||||
}
|
||||
|
||||
fn thread_id(suffix: u128) -> ThreadId {
|
||||
ThreadId::from_string(&format!("00000000-0000-0000-0000-{suffix:012}"))
|
||||
.expect("valid thread id")
|
||||
}
|
||||
|
||||
async fn state_runtime() -> TestRuntime {
|
||||
let codex_home = TempDir::new().expect("tempdir should be created");
|
||||
let state_db =
|
||||
StateRuntime::init(codex_home.path().to_path_buf(), "test-provider".to_string())
|
||||
.await
|
||||
.expect("state db should initialize");
|
||||
TestRuntime {
|
||||
state_db,
|
||||
_codex_home: codex_home,
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn local_store_upserts_and_lists_direct_children_with_status_filters() {
|
||||
let fixture = state_runtime().await;
|
||||
let state_db = fixture.state_db;
|
||||
let store = LocalAgentGraphStore::new(state_db.clone());
|
||||
let parent_thread_id = thread_id(/*suffix*/ 1);
|
||||
let first_child_thread_id = thread_id(/*suffix*/ 2);
|
||||
let second_child_thread_id = thread_id(/*suffix*/ 3);
|
||||
|
||||
store
|
||||
.upsert_thread_spawn_edge(
|
||||
parent_thread_id,
|
||||
second_child_thread_id,
|
||||
ThreadSpawnEdgeStatus::Closed,
|
||||
)
|
||||
.await
|
||||
.expect("closed child edge should insert");
|
||||
store
|
||||
.upsert_thread_spawn_edge(
|
||||
parent_thread_id,
|
||||
first_child_thread_id,
|
||||
ThreadSpawnEdgeStatus::Open,
|
||||
)
|
||||
.await
|
||||
.expect("open child edge should insert");
|
||||
|
||||
let all_children = store
|
||||
.list_thread_spawn_children(parent_thread_id, /*status_filter*/ None)
|
||||
.await
|
||||
.expect("all children should load");
|
||||
assert_eq!(
|
||||
all_children,
|
||||
vec![first_child_thread_id, second_child_thread_id]
|
||||
);
|
||||
|
||||
let open_children = store
|
||||
.list_thread_spawn_children(parent_thread_id, Some(ThreadSpawnEdgeStatus::Open))
|
||||
.await
|
||||
.expect("open children should load");
|
||||
let state_open_children = state_db
|
||||
.list_thread_spawn_children_with_status(
|
||||
parent_thread_id,
|
||||
DirectionalThreadSpawnEdgeStatus::Open,
|
||||
)
|
||||
.await
|
||||
.expect("state open children should load");
|
||||
assert_eq!(open_children, state_open_children);
|
||||
assert_eq!(open_children, vec![first_child_thread_id]);
|
||||
|
||||
let closed_children = store
|
||||
.list_thread_spawn_children(parent_thread_id, Some(ThreadSpawnEdgeStatus::Closed))
|
||||
.await
|
||||
.expect("closed children should load");
|
||||
assert_eq!(closed_children, vec![second_child_thread_id]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn local_store_updates_edge_status() {
|
||||
let fixture = state_runtime().await;
|
||||
let state_db = fixture.state_db;
|
||||
let store = LocalAgentGraphStore::new(state_db);
|
||||
let parent_thread_id = thread_id(/*suffix*/ 10);
|
||||
let child_thread_id = thread_id(/*suffix*/ 11);
|
||||
|
||||
store
|
||||
.upsert_thread_spawn_edge(
|
||||
parent_thread_id,
|
||||
child_thread_id,
|
||||
ThreadSpawnEdgeStatus::Open,
|
||||
)
|
||||
.await
|
||||
.expect("child edge should insert");
|
||||
store
|
||||
.set_thread_spawn_edge_status(child_thread_id, ThreadSpawnEdgeStatus::Closed)
|
||||
.await
|
||||
.expect("child edge should close");
|
||||
|
||||
let open_children = store
|
||||
.list_thread_spawn_children(parent_thread_id, Some(ThreadSpawnEdgeStatus::Open))
|
||||
.await
|
||||
.expect("open children should load");
|
||||
assert_eq!(open_children, Vec::<ThreadId>::new());
|
||||
|
||||
let closed_children = store
|
||||
.list_thread_spawn_children(parent_thread_id, Some(ThreadSpawnEdgeStatus::Closed))
|
||||
.await
|
||||
.expect("closed children should load");
|
||||
assert_eq!(closed_children, vec![child_thread_id]);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn local_store_lists_descendants_breadth_first_with_status_filters() {
|
||||
let fixture = state_runtime().await;
|
||||
let state_db = fixture.state_db;
|
||||
let store = LocalAgentGraphStore::new(state_db.clone());
|
||||
let root_thread_id = thread_id(/*suffix*/ 20);
|
||||
let later_child_thread_id = thread_id(/*suffix*/ 22);
|
||||
let earlier_child_thread_id = thread_id(/*suffix*/ 21);
|
||||
let closed_grandchild_thread_id = thread_id(/*suffix*/ 23);
|
||||
let open_grandchild_thread_id = thread_id(/*suffix*/ 24);
|
||||
let closed_child_thread_id = thread_id(/*suffix*/ 25);
|
||||
let closed_great_grandchild_thread_id = thread_id(/*suffix*/ 26);
|
||||
|
||||
for (parent_thread_id, child_thread_id, status) in [
|
||||
(
|
||||
root_thread_id,
|
||||
later_child_thread_id,
|
||||
ThreadSpawnEdgeStatus::Open,
|
||||
),
|
||||
(
|
||||
root_thread_id,
|
||||
earlier_child_thread_id,
|
||||
ThreadSpawnEdgeStatus::Open,
|
||||
),
|
||||
(
|
||||
earlier_child_thread_id,
|
||||
open_grandchild_thread_id,
|
||||
ThreadSpawnEdgeStatus::Open,
|
||||
),
|
||||
(
|
||||
later_child_thread_id,
|
||||
closed_grandchild_thread_id,
|
||||
ThreadSpawnEdgeStatus::Closed,
|
||||
),
|
||||
(
|
||||
root_thread_id,
|
||||
closed_child_thread_id,
|
||||
ThreadSpawnEdgeStatus::Closed,
|
||||
),
|
||||
(
|
||||
closed_child_thread_id,
|
||||
closed_great_grandchild_thread_id,
|
||||
ThreadSpawnEdgeStatus::Closed,
|
||||
),
|
||||
] {
|
||||
store
|
||||
.upsert_thread_spawn_edge(parent_thread_id, child_thread_id, status)
|
||||
.await
|
||||
.expect("edge should insert");
|
||||
}
|
||||
|
||||
let all_descendants = store
|
||||
.list_thread_spawn_descendants(root_thread_id, /*status_filter*/ None)
|
||||
.await
|
||||
.expect("all descendants should load");
|
||||
assert_eq!(
|
||||
all_descendants,
|
||||
vec![
|
||||
earlier_child_thread_id,
|
||||
later_child_thread_id,
|
||||
closed_child_thread_id,
|
||||
closed_grandchild_thread_id,
|
||||
open_grandchild_thread_id,
|
||||
closed_great_grandchild_thread_id,
|
||||
]
|
||||
);
|
||||
|
||||
let open_descendants = store
|
||||
.list_thread_spawn_descendants(root_thread_id, Some(ThreadSpawnEdgeStatus::Open))
|
||||
.await
|
||||
.expect("open descendants should load");
|
||||
let state_open_descendants = state_db
|
||||
.list_thread_spawn_descendants_with_status(
|
||||
root_thread_id,
|
||||
DirectionalThreadSpawnEdgeStatus::Open,
|
||||
)
|
||||
.await
|
||||
.expect("state open descendants should load");
|
||||
assert_eq!(open_descendants, state_open_descendants);
|
||||
assert_eq!(
|
||||
open_descendants,
|
||||
vec![
|
||||
earlier_child_thread_id,
|
||||
later_child_thread_id,
|
||||
open_grandchild_thread_id,
|
||||
]
|
||||
);
|
||||
|
||||
let closed_descendants = store
|
||||
.list_thread_spawn_descendants(root_thread_id, Some(ThreadSpawnEdgeStatus::Closed))
|
||||
.await
|
||||
.expect("closed descendants should load");
|
||||
assert_eq!(
|
||||
closed_descendants,
|
||||
vec![closed_child_thread_id, closed_great_grandchild_thread_id]
|
||||
);
|
||||
}
|
||||
}
|
||||
55
codex-rs/agent-graph-store/src/store.rs
Normal file
55
codex-rs/agent-graph-store/src/store.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
use async_trait::async_trait;
|
||||
use codex_protocol::ThreadId;
|
||||
|
||||
use crate::AgentGraphStoreResult;
|
||||
use crate::ThreadSpawnEdgeStatus;
|
||||
|
||||
/// Storage-neutral boundary for persisted thread-spawn parent/child topology.
|
||||
///
|
||||
/// Implementations are expected to return stable ordering for list methods so callers can merge
|
||||
/// persisted graph state with live in-memory state without introducing nondeterministic output.
|
||||
#[async_trait]
|
||||
pub trait AgentGraphStore: Send + Sync {
|
||||
/// Insert or replace the directional parent/child edge for a spawned thread.
|
||||
///
|
||||
/// `child_thread_id` has at most one persisted parent. Re-inserting the same child should
|
||||
/// update both the parent and status to match the supplied values.
|
||||
async fn upsert_thread_spawn_edge(
|
||||
&self,
|
||||
parent_thread_id: ThreadId,
|
||||
child_thread_id: ThreadId,
|
||||
status: ThreadSpawnEdgeStatus,
|
||||
) -> AgentGraphStoreResult<()>;
|
||||
|
||||
/// Update the persisted lifecycle status of a spawned thread's incoming edge.
|
||||
///
|
||||
/// Implementations should treat missing children as a successful no-op.
|
||||
async fn set_thread_spawn_edge_status(
|
||||
&self,
|
||||
child_thread_id: ThreadId,
|
||||
status: ThreadSpawnEdgeStatus,
|
||||
) -> AgentGraphStoreResult<()>;
|
||||
|
||||
/// List direct spawned children of a parent thread.
|
||||
///
|
||||
/// When `status_filter` is `Some`, only child edges with that exact status are returned. When
|
||||
/// it is `None`, all direct child edges are returned regardless of status, including statuses
|
||||
/// that may be added by a future store implementation.
|
||||
async fn list_thread_spawn_children(
|
||||
&self,
|
||||
parent_thread_id: ThreadId,
|
||||
status_filter: Option<ThreadSpawnEdgeStatus>,
|
||||
) -> AgentGraphStoreResult<Vec<ThreadId>>;
|
||||
|
||||
/// List spawned descendants breadth-first by depth, then by thread id.
|
||||
///
|
||||
/// `status_filter` is applied to every traversed edge, not just to the returned descendants.
|
||||
/// For example, `Some(Open)` walks only open edges, so descendants under a closed edge are not
|
||||
/// included even if their own incoming edge is open. `None` walks and returns every persisted
|
||||
/// edge regardless of status.
|
||||
async fn list_thread_spawn_descendants(
|
||||
&self,
|
||||
root_thread_id: ThreadId,
|
||||
status_filter: Option<ThreadSpawnEdgeStatus>,
|
||||
) -> AgentGraphStoreResult<Vec<ThreadId>>;
|
||||
}
|
||||
42
codex-rs/agent-graph-store/src/types.rs
Normal file
42
codex-rs/agent-graph-store/src/types.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Lifecycle status attached to a directional thread-spawn edge.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ThreadSpawnEdgeStatus {
|
||||
/// The child thread is still live or resumable as an open spawned agent.
|
||||
Open,
|
||||
/// The child thread has been closed from the parent/child graph's perspective.
|
||||
Closed,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn thread_spawn_edge_status_serializes_as_snake_case() {
|
||||
assert_eq!(
|
||||
serde_json::to_string(&ThreadSpawnEdgeStatus::Open)
|
||||
.expect("open status should serialize"),
|
||||
"\"open\""
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::to_string(&ThreadSpawnEdgeStatus::Closed)
|
||||
.expect("closed status should serialize"),
|
||||
"\"closed\""
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::from_str::<ThreadSpawnEdgeStatus>("\"open\"")
|
||||
.expect("open status should deserialize"),
|
||||
ThreadSpawnEdgeStatus::Open
|
||||
);
|
||||
assert_eq!(
|
||||
serde_json::from_str::<ThreadSpawnEdgeStatus>("\"closed\"")
|
||||
.expect("closed status should deserialize"),
|
||||
ThreadSpawnEdgeStatus::Closed
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -59,18 +59,19 @@ use codex_app_server_protocol::ApprovalsReviewer as AppServerApprovalsReviewer;
|
||||
use codex_app_server_protocol::AskForApproval as AppServerAskForApproval;
|
||||
use codex_app_server_protocol::ClientInfo;
|
||||
use codex_app_server_protocol::ClientRequest;
|
||||
use codex_app_server_protocol::ClientResponse;
|
||||
use codex_app_server_protocol::ClientResponsePayload;
|
||||
use codex_app_server_protocol::CodexErrorInfo;
|
||||
use codex_app_server_protocol::InitializeCapabilities;
|
||||
use codex_app_server_protocol::InitializeParams;
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
use codex_app_server_protocol::NonSteerableTurnKind;
|
||||
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
use codex_app_server_protocol::SandboxPolicy as AppServerSandboxPolicy;
|
||||
use codex_app_server_protocol::ServerNotification;
|
||||
use codex_app_server_protocol::SessionSource as AppServerSessionSource;
|
||||
use codex_app_server_protocol::Thread;
|
||||
use codex_app_server_protocol::ThreadArchiveParams;
|
||||
use codex_app_server_protocol::ThreadArchiveResponse;
|
||||
use codex_app_server_protocol::ThreadResumeResponse;
|
||||
use codex_app_server_protocol::ThreadStartResponse;
|
||||
use codex_app_server_protocol::ThreadStatus as AppServerThreadStatus;
|
||||
@@ -141,27 +142,25 @@ fn sample_thread_with_source(
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_thread_start_response(thread_id: &str, ephemeral: bool, model: &str) -> ClientResponse {
|
||||
ClientResponse::ThreadStart {
|
||||
request_id: RequestId::Integer(1),
|
||||
response: ThreadStartResponse {
|
||||
thread: sample_thread(thread_id, ephemeral),
|
||||
model: model.to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
service_tier: None,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
instruction_sources: Vec::new(),
|
||||
approval_policy: AppServerAskForApproval::OnFailure,
|
||||
approvals_reviewer: AppServerApprovalsReviewer::User,
|
||||
sandbox: AppServerSandboxPolicy::DangerFullAccess,
|
||||
permission_profile: Some(sample_permission_profile()),
|
||||
reasoning_effort: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_permission_profile() -> AppServerPermissionProfile {
|
||||
CorePermissionProfile::Disabled.into()
|
||||
fn sample_thread_start_response(
|
||||
thread_id: &str,
|
||||
ephemeral: bool,
|
||||
model: &str,
|
||||
) -> ClientResponsePayload {
|
||||
ClientResponsePayload::ThreadStart(ThreadStartResponse {
|
||||
thread: sample_thread(thread_id, ephemeral),
|
||||
model: model.to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
service_tier: None,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
instruction_sources: Vec::new(),
|
||||
approval_policy: AppServerAskForApproval::OnFailure,
|
||||
approvals_reviewer: AppServerApprovalsReviewer::User,
|
||||
sandbox: AppServerSandboxPolicy::DangerFullAccess,
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
reasoning_effort: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn sample_app_server_client_metadata() -> CodexAppServerClientMetadata {
|
||||
@@ -183,7 +182,11 @@ fn sample_runtime_metadata() -> CodexRuntimeMetadata {
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_thread_resume_response(thread_id: &str, ephemeral: bool, model: &str) -> ClientResponse {
|
||||
fn sample_thread_resume_response(
|
||||
thread_id: &str,
|
||||
ephemeral: bool,
|
||||
model: &str,
|
||||
) -> ClientResponsePayload {
|
||||
sample_thread_resume_response_with_source(
|
||||
thread_id,
|
||||
ephemeral,
|
||||
@@ -197,23 +200,21 @@ fn sample_thread_resume_response_with_source(
|
||||
ephemeral: bool,
|
||||
model: &str,
|
||||
source: AppServerSessionSource,
|
||||
) -> ClientResponse {
|
||||
ClientResponse::ThreadResume {
|
||||
request_id: RequestId::Integer(2),
|
||||
response: ThreadResumeResponse {
|
||||
thread: sample_thread_with_source(thread_id, ephemeral, source),
|
||||
model: model.to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
service_tier: None,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
instruction_sources: Vec::new(),
|
||||
approval_policy: AppServerAskForApproval::OnFailure,
|
||||
approvals_reviewer: AppServerApprovalsReviewer::User,
|
||||
sandbox: AppServerSandboxPolicy::DangerFullAccess,
|
||||
permission_profile: Some(sample_permission_profile()),
|
||||
reasoning_effort: None,
|
||||
},
|
||||
}
|
||||
) -> ClientResponsePayload {
|
||||
ClientResponsePayload::ThreadResume(ThreadResumeResponse {
|
||||
thread: sample_thread_with_source(thread_id, ephemeral, source),
|
||||
model: model.to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
service_tier: None,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
instruction_sources: Vec::new(),
|
||||
approval_policy: AppServerAskForApproval::OnFailure,
|
||||
approvals_reviewer: AppServerApprovalsReviewer::User,
|
||||
sandbox: AppServerSandboxPolicy::DangerFullAccess,
|
||||
permission_profile: None,
|
||||
active_permission_profile: None,
|
||||
reasoning_effort: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn sample_turn_start_request(thread_id: &str, request_id: i64) -> ClientRequest {
|
||||
@@ -235,21 +236,18 @@ fn sample_turn_start_request(thread_id: &str, request_id: i64) -> ClientRequest
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_turn_start_response(turn_id: &str, request_id: i64) -> ClientResponse {
|
||||
ClientResponse::TurnStart {
|
||||
request_id: RequestId::Integer(request_id),
|
||||
response: codex_app_server_protocol::TurnStartResponse {
|
||||
turn: Turn {
|
||||
id: turn_id.to_string(),
|
||||
items: vec![],
|
||||
status: AppServerTurnStatus::InProgress,
|
||||
error: None,
|
||||
started_at: None,
|
||||
completed_at: None,
|
||||
duration_ms: None,
|
||||
},
|
||||
fn sample_turn_start_response(turn_id: &str) -> ClientResponsePayload {
|
||||
ClientResponsePayload::TurnStart(codex_app_server_protocol::TurnStartResponse {
|
||||
turn: Turn {
|
||||
id: turn_id.to_string(),
|
||||
items: vec![],
|
||||
status: AppServerTurnStatus::InProgress,
|
||||
error: None,
|
||||
started_at: None,
|
||||
completed_at: None,
|
||||
duration_ms: None,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn sample_turn_started_notification(thread_id: &str, turn_id: &str) -> ServerNotification {
|
||||
@@ -305,10 +303,10 @@ fn sample_turn_completed_notification(
|
||||
})
|
||||
}
|
||||
|
||||
fn sample_turn_resolved_config(turn_id: &str) -> TurnResolvedConfigFact {
|
||||
fn sample_turn_resolved_config(thread_id: &str, turn_id: &str) -> TurnResolvedConfigFact {
|
||||
TurnResolvedConfigFact {
|
||||
turn_id: turn_id.to_string(),
|
||||
thread_id: "thread-2".to_string(),
|
||||
thread_id: thread_id.to_string(),
|
||||
num_input_images: 1,
|
||||
submission_type: None,
|
||||
ephemeral: false,
|
||||
@@ -355,13 +353,10 @@ fn sample_turn_steer_request(
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_turn_steer_response(turn_id: &str, request_id: i64) -> ClientResponse {
|
||||
ClientResponse::TurnSteer {
|
||||
request_id: RequestId::Integer(request_id),
|
||||
response: TurnSteerResponse {
|
||||
turn_id: turn_id.to_string(),
|
||||
},
|
||||
}
|
||||
fn sample_turn_steer_response(turn_id: &str) -> ClientResponsePayload {
|
||||
ClientResponsePayload::TurnSteer(TurnSteerResponse {
|
||||
turn_id: turn_id.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
fn no_active_turn_steer_error() -> JSONRPCErrorError {
|
||||
@@ -424,6 +419,38 @@ async fn ingest_rejected_turn_steer(
|
||||
/*include_started*/ false, /*include_token_usage*/ false,
|
||||
)
|
||||
.await;
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Initialize {
|
||||
connection_id: 8,
|
||||
params: InitializeParams {
|
||||
client_info: ClientInfo {
|
||||
name: "codex-web".to_string(),
|
||||
title: None,
|
||||
version: "1.0.0".to_string(),
|
||||
},
|
||||
capabilities: None,
|
||||
},
|
||||
product_client_id: "codex-web".to_string(),
|
||||
runtime: sample_runtime_metadata(),
|
||||
rpc_transport: AppServerRpcTransport::Stdio,
|
||||
},
|
||||
out,
|
||||
)
|
||||
.await;
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 8,
|
||||
request_id: RequestId::Integer(6),
|
||||
response: Box::new(sample_thread_resume_response(
|
||||
"thread-2", /*ephemeral*/ false, "gpt-5",
|
||||
)),
|
||||
},
|
||||
out,
|
||||
)
|
||||
.await;
|
||||
out.clear();
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::ClientRequest {
|
||||
@@ -488,6 +515,7 @@ async fn ingest_turn_prerequisites(
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(1),
|
||||
response: Box::new(sample_thread_start_response(
|
||||
"thread-2", /*ephemeral*/ false, "gpt-5",
|
||||
)),
|
||||
@@ -512,7 +540,8 @@ async fn ingest_turn_prerequisites(
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
response: Box::new(sample_turn_start_response("turn-2", /*request_id*/ 3)),
|
||||
request_id: RequestId::Integer(3),
|
||||
response: Box::new(sample_turn_start_response("turn-2")),
|
||||
},
|
||||
out,
|
||||
)
|
||||
@@ -522,7 +551,7 @@ async fn ingest_turn_prerequisites(
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Custom(CustomAnalyticsFact::TurnResolvedConfig(Box::new(
|
||||
sample_turn_resolved_config("turn-2"),
|
||||
sample_turn_resolved_config("thread-2", "turn-2"),
|
||||
))),
|
||||
out,
|
||||
)
|
||||
@@ -864,6 +893,7 @@ async fn initialize_caches_client_and_thread_lifecycle_publishes_once_initialize
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(1),
|
||||
response: Box::new(sample_thread_start_response(
|
||||
"thread-no-client",
|
||||
/*ephemeral*/ false,
|
||||
@@ -908,6 +938,7 @@ async fn initialize_caches_client_and_thread_lifecycle_publishes_once_initialize
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(2),
|
||||
response: Box::new(sample_thread_resume_response(
|
||||
"thread-1", /*ephemeral*/ true, "gpt-5",
|
||||
)),
|
||||
@@ -954,6 +985,65 @@ async fn initialize_caches_client_and_thread_lifecycle_publishes_once_initialize
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn unrelated_client_requests_are_ignored_by_reducer() {
|
||||
let mut reducer = AnalyticsReducer::default();
|
||||
let mut events = Vec::new();
|
||||
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::ClientRequest {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(3),
|
||||
request: Box::new(ClientRequest::ThreadArchive {
|
||||
request_id: RequestId::Integer(3),
|
||||
params: ThreadArchiveParams {
|
||||
thread_id: "thread-2".to_string(),
|
||||
},
|
||||
}),
|
||||
},
|
||||
&mut events,
|
||||
)
|
||||
.await;
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(3),
|
||||
response: Box::new(sample_turn_start_response("turn-2")),
|
||||
},
|
||||
&mut events,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(
|
||||
events.is_empty(),
|
||||
"unrelated requests must not create pending turn state"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn unrelated_client_responses_are_ignored_by_reducer() {
|
||||
let mut reducer = AnalyticsReducer::default();
|
||||
let mut events = Vec::new();
|
||||
|
||||
ingest_initialize(&mut reducer, &mut events).await;
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(9),
|
||||
response: Box::new(ClientResponsePayload::ThreadArchive(
|
||||
ThreadArchiveResponse {},
|
||||
)),
|
||||
},
|
||||
&mut events,
|
||||
)
|
||||
.await;
|
||||
|
||||
assert!(events.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn compaction_event_ingests_custom_fact() {
|
||||
let mut reducer = AnalyticsReducer::default();
|
||||
@@ -988,6 +1078,7 @@ async fn compaction_event_ingests_custom_fact() {
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(2),
|
||||
response: Box::new(sample_thread_resume_response_with_source(
|
||||
"thread-1",
|
||||
/*ephemeral*/ false,
|
||||
@@ -1099,6 +1190,7 @@ async fn guardian_review_event_ingests_custom_fact_with_optional_target_item() {
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(1),
|
||||
response: Box::new(sample_thread_start_response(
|
||||
"thread-guardian",
|
||||
/*ephemeral*/ false,
|
||||
@@ -1376,6 +1468,110 @@ async fn subagent_thread_started_publishes_without_initialize() {
|
||||
assert_eq!(payload[0]["event_params"]["subagent_source"], "review");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn subagent_thread_started_inherits_parent_connection_for_new_thread() {
|
||||
let mut reducer = AnalyticsReducer::default();
|
||||
let mut events = Vec::new();
|
||||
let parent_thread_id =
|
||||
codex_protocol::ThreadId::from_string("44444444-4444-4444-4444-444444444444")
|
||||
.expect("valid parent thread id");
|
||||
let parent_thread_id_string = parent_thread_id.to_string();
|
||||
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Initialize {
|
||||
connection_id: 7,
|
||||
params: InitializeParams {
|
||||
client_info: ClientInfo {
|
||||
name: "parent-client".to_string(),
|
||||
title: None,
|
||||
version: "1.0.0".to_string(),
|
||||
},
|
||||
capabilities: None,
|
||||
},
|
||||
product_client_id: "parent-client".to_string(),
|
||||
runtime: sample_runtime_metadata(),
|
||||
rpc_transport: AppServerRpcTransport::Stdio,
|
||||
},
|
||||
&mut events,
|
||||
)
|
||||
.await;
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
request_id: RequestId::Integer(1),
|
||||
response: Box::new(sample_thread_start_response(
|
||||
&parent_thread_id_string,
|
||||
/*ephemeral*/ false,
|
||||
"gpt-5",
|
||||
)),
|
||||
},
|
||||
&mut events,
|
||||
)
|
||||
.await;
|
||||
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Custom(CustomAnalyticsFact::SubAgentThreadStarted(
|
||||
SubAgentThreadStartedInput {
|
||||
thread_id: "thread-review".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(),
|
||||
model: "gpt-5".to_string(),
|
||||
ephemeral: false,
|
||||
subagent_source: SubAgentSource::ThreadSpawn {
|
||||
parent_thread_id,
|
||||
depth: 1,
|
||||
agent_path: None,
|
||||
agent_nickname: None,
|
||||
agent_role: None,
|
||||
},
|
||||
created_at: 130,
|
||||
},
|
||||
)),
|
||||
&mut events,
|
||||
)
|
||||
.await;
|
||||
|
||||
events.clear();
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Custom(CustomAnalyticsFact::Compaction(Box::new(
|
||||
CodexCompactionEvent {
|
||||
thread_id: "thread-review".to_string(),
|
||||
turn_id: "turn-compact".to_string(),
|
||||
trigger: CompactionTrigger::Manual,
|
||||
reason: CompactionReason::UserRequested,
|
||||
implementation: CompactionImplementation::Responses,
|
||||
phase: CompactionPhase::StandaloneTurn,
|
||||
strategy: CompactionStrategy::Memento,
|
||||
status: CompactionStatus::Completed,
|
||||
error: None,
|
||||
active_context_tokens_before: 131_000,
|
||||
active_context_tokens_after: 64_000,
|
||||
started_at: 100,
|
||||
completed_at: 101,
|
||||
duration_ms: Some(1200),
|
||||
},
|
||||
))),
|
||||
&mut events,
|
||||
)
|
||||
.await;
|
||||
|
||||
let payload = serde_json::to_value(&events).expect("serialize events");
|
||||
assert_eq!(
|
||||
payload[0]["event_params"]["app_server_client"]["product_client_id"],
|
||||
"parent-client"
|
||||
);
|
||||
assert_eq!(
|
||||
payload[0]["event_params"]["parent_thread_id"],
|
||||
"44444444-4444-4444-4444-444444444444"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugin_used_event_serializes_expected_shape() {
|
||||
let tracking = TrackEventsContext {
|
||||
@@ -1436,6 +1632,25 @@ fn plugin_management_event_serializes_expected_shape() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugin_management_event_can_use_remote_plugin_id_override() {
|
||||
let mut plugin = sample_plugin_metadata();
|
||||
plugin.remote_plugin_id = Some("plugins~Plugin_remote".to_string());
|
||||
let event = TrackEventRequest::PluginInstalled(CodexPluginEventRequest {
|
||||
event_type: "codex_plugin_installed",
|
||||
event_params: codex_plugin_metadata(plugin),
|
||||
});
|
||||
|
||||
let payload = serde_json::to_value(&event).expect("serialize plugin installed event");
|
||||
|
||||
assert_eq!(
|
||||
payload["event_params"]["plugin_id"],
|
||||
"plugins~Plugin_remote"
|
||||
);
|
||||
assert_eq!(payload["event_params"]["plugin_name"], "sample");
|
||||
assert_eq!(payload["event_params"]["marketplace_name"], "test");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hook_run_event_serializes_expected_shape() {
|
||||
let tracking = TrackEventsContext {
|
||||
@@ -1499,6 +1714,15 @@ fn hook_run_metadata_maps_sources_and_statuses() {
|
||||
},
|
||||
))
|
||||
.expect("serialize project hook");
|
||||
let cloud_requirements = serde_json::to_value(codex_hook_run_metadata(
|
||||
&tracking,
|
||||
HookRunFact {
|
||||
event_name: HookEventName::Stop,
|
||||
hook_source: HookSource::CloudRequirements,
|
||||
status: HookRunStatus::Blocked,
|
||||
},
|
||||
))
|
||||
.expect("serialize cloud requirements hook");
|
||||
let unknown = serde_json::to_value(codex_hook_run_metadata(
|
||||
&tracking,
|
||||
HookRunFact {
|
||||
@@ -1513,6 +1737,8 @@ fn hook_run_metadata_maps_sources_and_statuses() {
|
||||
assert_eq!(system["status"], "completed");
|
||||
assert_eq!(project["hook_source"], "project");
|
||||
assert_eq!(project["status"], "blocked");
|
||||
assert_eq!(cloud_requirements["hook_source"], "cloud_requirements");
|
||||
assert_eq!(cloud_requirements["status"], "blocked");
|
||||
assert_eq!(unknown["hook_source"], "unknown");
|
||||
assert_eq!(unknown["status"], "failed");
|
||||
}
|
||||
@@ -1881,7 +2107,8 @@ async fn accepted_turn_steer_emits_expected_event() {
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
response: Box::new(sample_turn_steer_response("turn-2", /*request_id*/ 4)),
|
||||
request_id: RequestId::Integer(4),
|
||||
response: Box::new(sample_turn_steer_response("turn-2")),
|
||||
},
|
||||
&mut out,
|
||||
)
|
||||
@@ -2047,7 +2274,8 @@ async fn turn_start_error_response_discards_pending_start_request() {
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
response: Box::new(sample_turn_start_response("turn-2", /*request_id*/ 3)),
|
||||
request_id: RequestId::Integer(3),
|
||||
response: Box::new(sample_turn_start_response("turn-2")),
|
||||
},
|
||||
&mut out,
|
||||
)
|
||||
@@ -2057,7 +2285,7 @@ async fn turn_start_error_response_discards_pending_start_request() {
|
||||
reducer
|
||||
.ingest(
|
||||
AnalyticsFact::Custom(CustomAnalyticsFact::TurnResolvedConfig(Box::new(
|
||||
sample_turn_resolved_config("turn-2"),
|
||||
sample_turn_resolved_config("thread-2", "turn-2"),
|
||||
))),
|
||||
&mut out,
|
||||
)
|
||||
@@ -2176,7 +2404,8 @@ async fn accepted_steers_increment_turn_steer_count() {
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
response: Box::new(sample_turn_steer_response("turn-2", /*request_id*/ 4)),
|
||||
request_id: RequestId::Integer(4),
|
||||
response: Box::new(sample_turn_steer_response("turn-2")),
|
||||
},
|
||||
&mut out,
|
||||
)
|
||||
@@ -2222,7 +2451,8 @@ async fn accepted_steers_increment_turn_steer_count() {
|
||||
.ingest(
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id: 7,
|
||||
response: Box::new(sample_turn_steer_response("turn-2", /*request_id*/ 6)),
|
||||
request_id: RequestId::Integer(6),
|
||||
response: Box::new(sample_turn_steer_response("turn-2")),
|
||||
},
|
||||
&mut out,
|
||||
)
|
||||
@@ -2407,6 +2637,7 @@ async fn turn_completed_without_started_notification_emits_null_started_at() {
|
||||
fn sample_plugin_metadata() -> PluginTelemetryMetadata {
|
||||
PluginTelemetryMetadata {
|
||||
plugin_id: PluginId::parse("sample@test").expect("valid plugin id"),
|
||||
remote_plugin_id: None,
|
||||
capability_summary: Some(PluginCapabilitySummary {
|
||||
config_name: "sample@test".to_string(),
|
||||
display_name: "sample".to_string(),
|
||||
|
||||
@@ -22,7 +22,7 @@ use crate::facts::TurnResolvedConfigFact;
|
||||
use crate::facts::TurnTokenUsageFact;
|
||||
use crate::reducer::AnalyticsReducer;
|
||||
use codex_app_server_protocol::ClientRequest;
|
||||
use codex_app_server_protocol::ClientResponse;
|
||||
use codex_app_server_protocol::ClientResponsePayload;
|
||||
use codex_app_server_protocol::InitializeParams;
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
@@ -295,9 +295,25 @@ impl AnalyticsEventsClient {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn track_response(&self, connection_id: u64, response: ClientResponse) {
|
||||
pub fn track_response(
|
||||
&self,
|
||||
connection_id: u64,
|
||||
request_id: RequestId,
|
||||
response: ClientResponsePayload,
|
||||
) {
|
||||
if !matches!(
|
||||
response,
|
||||
ClientResponsePayload::ThreadStart(_)
|
||||
| ClientResponsePayload::ThreadResume(_)
|
||||
| ClientResponsePayload::ThreadFork(_)
|
||||
| ClientResponsePayload::TurnStart(_)
|
||||
| ClientResponsePayload::TurnSteer(_)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
self.record_fact(AnalyticsFact::ClientResponse {
|
||||
connection_id,
|
||||
request_id,
|
||||
response: Box::new(response),
|
||||
});
|
||||
}
|
||||
@@ -335,10 +351,6 @@ impl AnalyticsEventsClient {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "client_tests.rs"]
|
||||
mod tests;
|
||||
|
||||
async fn send_track_events(
|
||||
auth_manager: &AuthManager,
|
||||
base_url: &str,
|
||||
@@ -379,3 +391,7 @@ async fn send_track_events(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "client_tests.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -1,11 +1,30 @@
|
||||
use super::AnalyticsEventsClient;
|
||||
use super::AnalyticsEventsQueue;
|
||||
use crate::facts::AnalyticsFact;
|
||||
use codex_app_server_protocol::ApprovalsReviewer as AppServerApprovalsReviewer;
|
||||
use codex_app_server_protocol::AskForApproval as AppServerAskForApproval;
|
||||
use codex_app_server_protocol::ClientRequest;
|
||||
use codex_app_server_protocol::ClientResponsePayload;
|
||||
use codex_app_server_protocol::PermissionProfile as AppServerPermissionProfile;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
use codex_app_server_protocol::SandboxPolicy as AppServerSandboxPolicy;
|
||||
use codex_app_server_protocol::SessionSource as AppServerSessionSource;
|
||||
use codex_app_server_protocol::Thread;
|
||||
use codex_app_server_protocol::ThreadArchiveParams;
|
||||
use codex_app_server_protocol::ThreadArchiveResponse;
|
||||
use codex_app_server_protocol::ThreadForkResponse;
|
||||
use codex_app_server_protocol::ThreadResumeResponse;
|
||||
use codex_app_server_protocol::ThreadStartResponse;
|
||||
use codex_app_server_protocol::ThreadStatus as AppServerThreadStatus;
|
||||
use codex_app_server_protocol::Turn;
|
||||
use codex_app_server_protocol::TurnStartParams;
|
||||
use codex_app_server_protocol::TurnStartResponse;
|
||||
use codex_app_server_protocol::TurnStatus as AppServerTurnStatus;
|
||||
use codex_app_server_protocol::TurnSteerParams;
|
||||
use codex_app_server_protocol::TurnSteerResponse;
|
||||
use codex_protocol::models::PermissionProfile as CorePermissionProfile;
|
||||
use codex_utils_absolute_path::test_support::PathBufExt;
|
||||
use codex_utils_absolute_path::test_support::test_path_buf;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
@@ -13,7 +32,7 @@ use tokio::sync::mpsc;
|
||||
use tokio::sync::mpsc::error::TryRecvError;
|
||||
|
||||
fn client_with_receiver() -> (AnalyticsEventsClient, mpsc::Receiver<AnalyticsFact>) {
|
||||
let (sender, receiver) = mpsc::channel(4);
|
||||
let (sender, receiver) = mpsc::channel(8);
|
||||
let queue = AnalyticsEventsQueue {
|
||||
sender,
|
||||
app_used_emitted_keys: Arc::new(Mutex::new(HashSet::new())),
|
||||
@@ -54,6 +73,103 @@ fn sample_thread_archive_request() -> ClientRequest {
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_thread(thread_id: &str) -> Thread {
|
||||
Thread {
|
||||
id: thread_id.to_string(),
|
||||
forked_from_id: None,
|
||||
preview: "first prompt".to_string(),
|
||||
ephemeral: false,
|
||||
model_provider: "openai".to_string(),
|
||||
created_at: 1,
|
||||
updated_at: 2,
|
||||
status: AppServerThreadStatus::Idle,
|
||||
path: None,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
cli_version: "0.0.0".to_string(),
|
||||
source: AppServerSessionSource::Exec,
|
||||
agent_nickname: None,
|
||||
agent_role: None,
|
||||
git_info: None,
|
||||
name: None,
|
||||
turns: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn sample_permission_profile() -> AppServerPermissionProfile {
|
||||
CorePermissionProfile::Disabled.into()
|
||||
}
|
||||
|
||||
fn sample_thread_start_response() -> ClientResponsePayload {
|
||||
ClientResponsePayload::ThreadStart(ThreadStartResponse {
|
||||
thread: sample_thread("thread-1"),
|
||||
model: "gpt-5".to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
service_tier: None,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
instruction_sources: Vec::new(),
|
||||
approval_policy: AppServerAskForApproval::OnFailure,
|
||||
approvals_reviewer: AppServerApprovalsReviewer::User,
|
||||
sandbox: AppServerSandboxPolicy::DangerFullAccess,
|
||||
permission_profile: Some(sample_permission_profile()),
|
||||
active_permission_profile: None,
|
||||
reasoning_effort: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn sample_thread_resume_response() -> ClientResponsePayload {
|
||||
ClientResponsePayload::ThreadResume(ThreadResumeResponse {
|
||||
thread: sample_thread("thread-2"),
|
||||
model: "gpt-5".to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
service_tier: None,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
instruction_sources: Vec::new(),
|
||||
approval_policy: AppServerAskForApproval::OnFailure,
|
||||
approvals_reviewer: AppServerApprovalsReviewer::User,
|
||||
sandbox: AppServerSandboxPolicy::DangerFullAccess,
|
||||
permission_profile: Some(sample_permission_profile()),
|
||||
active_permission_profile: None,
|
||||
reasoning_effort: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn sample_thread_fork_response() -> ClientResponsePayload {
|
||||
ClientResponsePayload::ThreadFork(ThreadForkResponse {
|
||||
thread: sample_thread("thread-3"),
|
||||
model: "gpt-5".to_string(),
|
||||
model_provider: "openai".to_string(),
|
||||
service_tier: None,
|
||||
cwd: test_path_buf("/tmp").abs(),
|
||||
instruction_sources: Vec::new(),
|
||||
approval_policy: AppServerAskForApproval::OnFailure,
|
||||
approvals_reviewer: AppServerApprovalsReviewer::User,
|
||||
sandbox: AppServerSandboxPolicy::DangerFullAccess,
|
||||
permission_profile: Some(sample_permission_profile()),
|
||||
active_permission_profile: None,
|
||||
reasoning_effort: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn sample_turn_start_response() -> ClientResponsePayload {
|
||||
ClientResponsePayload::TurnStart(TurnStartResponse {
|
||||
turn: Turn {
|
||||
id: "turn-1".to_string(),
|
||||
items: Vec::new(),
|
||||
status: AppServerTurnStatus::InProgress,
|
||||
error: None,
|
||||
started_at: None,
|
||||
completed_at: None,
|
||||
duration_ms: None,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn sample_turn_steer_response() -> ClientResponsePayload {
|
||||
ClientResponsePayload::TurnSteer(TurnSteerResponse {
|
||||
turn_id: "turn-2".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn track_request_only_enqueues_analytics_relevant_requests() {
|
||||
let (client, mut receiver) = client_with_receiver();
|
||||
@@ -77,3 +193,29 @@ fn track_request_only_enqueues_analytics_relevant_requests() {
|
||||
);
|
||||
assert!(matches!(receiver.try_recv(), Err(TryRecvError::Empty)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn track_response_only_enqueues_analytics_relevant_responses() {
|
||||
let (client, mut receiver) = client_with_receiver();
|
||||
|
||||
for (request_id, response) in [
|
||||
(RequestId::Integer(1), sample_thread_start_response()),
|
||||
(RequestId::Integer(2), sample_thread_resume_response()),
|
||||
(RequestId::Integer(3), sample_thread_fork_response()),
|
||||
(RequestId::Integer(4), sample_turn_start_response()),
|
||||
(RequestId::Integer(5), sample_turn_steer_response()),
|
||||
] {
|
||||
client.track_response(/*connection_id*/ 7, request_id, response);
|
||||
assert!(matches!(
|
||||
receiver.try_recv(),
|
||||
Ok(AnalyticsFact::ClientResponse { .. })
|
||||
));
|
||||
}
|
||||
|
||||
client.track_response(
|
||||
/*connection_id*/ 7,
|
||||
RequestId::Integer(6),
|
||||
ClientResponsePayload::ThreadArchive(ThreadArchiveResponse {}),
|
||||
);
|
||||
assert!(matches!(receiver.try_recv(), Err(TryRecvError::Empty)));
|
||||
}
|
||||
|
||||
@@ -587,11 +587,16 @@ pub(crate) fn codex_app_metadata(
|
||||
}
|
||||
|
||||
pub(crate) fn codex_plugin_metadata(plugin: PluginTelemetryMetadata) -> CodexPluginMetadata {
|
||||
let capability_summary = plugin.capability_summary;
|
||||
let PluginTelemetryMetadata {
|
||||
plugin_id,
|
||||
remote_plugin_id,
|
||||
capability_summary,
|
||||
} = plugin;
|
||||
let event_plugin_id = remote_plugin_id.unwrap_or_else(|| plugin_id.as_key());
|
||||
CodexPluginMetadata {
|
||||
plugin_id: Some(plugin.plugin_id.as_key()),
|
||||
plugin_name: Some(plugin.plugin_id.plugin_name),
|
||||
marketplace_name: Some(plugin.plugin_id.marketplace_name),
|
||||
plugin_id: Some(event_plugin_id),
|
||||
plugin_name: Some(plugin_id.plugin_name),
|
||||
marketplace_name: Some(plugin_id.marketplace_name),
|
||||
has_skills: capability_summary
|
||||
.as_ref()
|
||||
.map(|summary| summary.has_skills),
|
||||
@@ -685,6 +690,7 @@ fn analytics_hook_source(source: HookSource) -> &'static str {
|
||||
HookSource::Mdm => "mdm",
|
||||
HookSource::SessionFlags => "session_flags",
|
||||
HookSource::Plugin => "plugin",
|
||||
HookSource::CloudRequirements => "cloud_requirements",
|
||||
HookSource::LegacyManagedConfigFile => "legacy_managed_config_file",
|
||||
HookSource::LegacyManagedConfigMdm => "legacy_managed_config_mdm",
|
||||
HookSource::Unknown => "unknown",
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::events::AppServerRpcTransport;
|
||||
use crate::events::CodexRuntimeMetadata;
|
||||
use crate::events::GuardianReviewEventParams;
|
||||
use codex_app_server_protocol::ClientRequest;
|
||||
use codex_app_server_protocol::ClientResponse;
|
||||
use codex_app_server_protocol::ClientResponsePayload;
|
||||
use codex_app_server_protocol::InitializeParams;
|
||||
use codex_app_server_protocol::JSONRPCErrorError;
|
||||
use codex_app_server_protocol::RequestId;
|
||||
@@ -281,7 +281,8 @@ pub(crate) enum AnalyticsFact {
|
||||
},
|
||||
ClientResponse {
|
||||
connection_id: u64,
|
||||
response: Box<ClientResponse>,
|
||||
request_id: RequestId,
|
||||
response: Box<ClientResponsePayload>,
|
||||
},
|
||||
ErrorResponse {
|
||||
connection_id: u64,
|
||||
|
||||
@@ -74,8 +74,7 @@ pub(crate) struct AnalyticsReducer {
|
||||
requests: HashMap<(u64, RequestId), RequestState>,
|
||||
turns: HashMap<String, TurnState>,
|
||||
connections: HashMap<u64, ConnectionState>,
|
||||
thread_connections: HashMap<String, u64>,
|
||||
thread_metadata: HashMap<String, ThreadMetadataState>,
|
||||
threads: HashMap<String, ThreadAnalyticsState>,
|
||||
}
|
||||
|
||||
struct ConnectionState {
|
||||
@@ -83,6 +82,69 @@ struct ConnectionState {
|
||||
runtime: CodexRuntimeMetadata,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ThreadAnalyticsState {
|
||||
connection_id: Option<u64>,
|
||||
metadata: Option<ThreadMetadataState>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct AnalyticsDropSite<'a> {
|
||||
event_name: &'static str,
|
||||
thread_id: &'a str,
|
||||
turn_id: Option<&'a str>,
|
||||
review_id: Option<&'a str>,
|
||||
item_id: Option<&'a str>,
|
||||
}
|
||||
|
||||
impl<'a> AnalyticsDropSite<'a> {
|
||||
fn guardian(input: &'a GuardianReviewEventParams) -> Self {
|
||||
Self {
|
||||
event_name: "guardian",
|
||||
thread_id: &input.thread_id,
|
||||
turn_id: Some(&input.turn_id),
|
||||
review_id: Some(&input.review_id),
|
||||
item_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn compaction(input: &'a CodexCompactionEvent) -> Self {
|
||||
Self {
|
||||
event_name: "compaction",
|
||||
thread_id: &input.thread_id,
|
||||
turn_id: Some(&input.turn_id),
|
||||
review_id: None,
|
||||
item_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn turn_steer(thread_id: &'a str) -> Self {
|
||||
Self {
|
||||
event_name: "turn steer",
|
||||
thread_id,
|
||||
turn_id: None,
|
||||
review_id: None,
|
||||
item_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn turn(thread_id: &'a str, turn_id: &'a str) -> Self {
|
||||
Self {
|
||||
event_name: "turn",
|
||||
thread_id,
|
||||
turn_id: Some(turn_id),
|
||||
review_id: None,
|
||||
item_id: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum MissingAnalyticsContext {
|
||||
ThreadConnection,
|
||||
Connection { connection_id: u64 },
|
||||
ThreadMetadata,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ThreadMetadataState {
|
||||
thread_source: Option<&'static str>,
|
||||
@@ -181,9 +243,12 @@ impl AnalyticsReducer {
|
||||
}
|
||||
AnalyticsFact::ClientResponse {
|
||||
connection_id,
|
||||
request_id,
|
||||
response,
|
||||
} => {
|
||||
self.ingest_response(connection_id, *response, out);
|
||||
if let Some(response) = response.into_client_response(request_id) {
|
||||
self.ingest_response(connection_id, response, out);
|
||||
}
|
||||
}
|
||||
AnalyticsFact::ErrorResponse {
|
||||
connection_id,
|
||||
@@ -271,6 +336,26 @@ impl AnalyticsReducer {
|
||||
input: SubAgentThreadStartedInput,
|
||||
out: &mut Vec<TrackEventRequest>,
|
||||
) {
|
||||
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))
|
||||
.and_then(|thread| thread.connection_id);
|
||||
let thread_state = self.threads.entry(input.thread_id.clone()).or_default();
|
||||
thread_state
|
||||
.metadata
|
||||
.get_or_insert_with(|| ThreadMetadataState {
|
||||
thread_source: Some("subagent"),
|
||||
initialization_mode: ThreadInitializationMode::New,
|
||||
subagent_source: Some(subagent_source_name(&input.subagent_source)),
|
||||
parent_thread_id,
|
||||
});
|
||||
if thread_state.connection_id.is_none() {
|
||||
thread_state.connection_id = parent_connection_id;
|
||||
}
|
||||
out.push(TrackEventRequest::ThreadInitialized(
|
||||
subagent_thread_started_event_request(input),
|
||||
));
|
||||
@@ -281,23 +366,9 @@ impl AnalyticsReducer {
|
||||
input: GuardianReviewEventParams,
|
||||
out: &mut Vec<TrackEventRequest>,
|
||||
) {
|
||||
let Some(connection_id) = self.thread_connections.get(&input.thread_id) else {
|
||||
tracing::warn!(
|
||||
thread_id = %input.thread_id,
|
||||
turn_id = %input.turn_id,
|
||||
review_id = %input.review_id,
|
||||
"dropping guardian analytics event: missing thread connection metadata"
|
||||
);
|
||||
return;
|
||||
};
|
||||
let Some(connection_state) = self.connections.get(connection_id) else {
|
||||
tracing::warn!(
|
||||
thread_id = %input.thread_id,
|
||||
turn_id = %input.turn_id,
|
||||
review_id = %input.review_id,
|
||||
connection_id,
|
||||
"dropping guardian analytics event: missing connection metadata"
|
||||
);
|
||||
let Some(connection_state) =
|
||||
self.thread_connection_or_warn(AnalyticsDropSite::guardian(&input))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
out.push(TrackEventRequest::GuardianReview(Box::new(
|
||||
@@ -683,10 +754,13 @@ impl AnalyticsReducer {
|
||||
};
|
||||
let thread_metadata =
|
||||
ThreadMetadataState::from_thread_metadata(&thread_source, initialization_mode);
|
||||
self.thread_connections
|
||||
.insert(thread_id.clone(), connection_id);
|
||||
self.thread_metadata
|
||||
.insert(thread_id.clone(), thread_metadata.clone());
|
||||
self.threads.insert(
|
||||
thread_id.clone(),
|
||||
ThreadAnalyticsState {
|
||||
connection_id: Some(connection_id),
|
||||
metadata: Some(thread_metadata.clone()),
|
||||
},
|
||||
);
|
||||
out.push(TrackEventRequest::ThreadInitialized(
|
||||
ThreadInitializedEvent {
|
||||
event_type: "codex_thread_initialized",
|
||||
@@ -707,29 +781,9 @@ impl AnalyticsReducer {
|
||||
}
|
||||
|
||||
fn ingest_compaction(&mut self, input: CodexCompactionEvent, out: &mut Vec<TrackEventRequest>) {
|
||||
let Some(connection_id) = self.thread_connections.get(&input.thread_id) else {
|
||||
tracing::warn!(
|
||||
thread_id = %input.thread_id,
|
||||
turn_id = %input.turn_id,
|
||||
"dropping compaction analytics event: missing thread connection metadata"
|
||||
);
|
||||
return;
|
||||
};
|
||||
let Some(connection_state) = self.connections.get(connection_id) else {
|
||||
tracing::warn!(
|
||||
thread_id = %input.thread_id,
|
||||
turn_id = %input.turn_id,
|
||||
connection_id,
|
||||
"dropping compaction analytics event: missing connection metadata"
|
||||
);
|
||||
return;
|
||||
};
|
||||
let Some(thread_metadata) = self.thread_metadata.get(&input.thread_id) else {
|
||||
tracing::warn!(
|
||||
thread_id = %input.thread_id,
|
||||
turn_id = %input.turn_id,
|
||||
"dropping compaction analytics event: missing thread lifecycle metadata"
|
||||
);
|
||||
let Some((connection_state, thread_metadata)) =
|
||||
self.thread_context_or_warn(AnalyticsDropSite::compaction(&input))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
out.push(TrackEventRequest::Compaction(Box::new(
|
||||
@@ -784,11 +838,13 @@ impl AnalyticsReducer {
|
||||
let Some(connection_state) = self.connections.get(&connection_id) else {
|
||||
return;
|
||||
};
|
||||
let Some(thread_metadata) = self.thread_metadata.get(&pending_request.thread_id) else {
|
||||
tracing::warn!(
|
||||
thread_id = %pending_request.thread_id,
|
||||
"dropping turn steer analytics event: missing thread lifecycle metadata"
|
||||
);
|
||||
let drop_site = AnalyticsDropSite::turn_steer(&pending_request.thread_id);
|
||||
let Some(thread_metadata) = self
|
||||
.threads
|
||||
.get(drop_site.thread_id)
|
||||
.and_then(|thread| thread.metadata.as_ref())
|
||||
else {
|
||||
warn_missing_analytics_context(&drop_site, MissingAnalyticsContext::ThreadMetadata);
|
||||
return;
|
||||
};
|
||||
out.push(TrackEventRequest::TurnSteer(CodexTurnSteerEventRequest {
|
||||
@@ -821,42 +877,34 @@ impl AnalyticsReducer {
|
||||
{
|
||||
return;
|
||||
}
|
||||
let connection_metadata = turn_state
|
||||
.connection_id
|
||||
.and_then(|connection_id| self.connections.get(&connection_id))
|
||||
.map(|connection_state| {
|
||||
(
|
||||
connection_state.app_server_client.clone(),
|
||||
connection_state.runtime.clone(),
|
||||
)
|
||||
});
|
||||
let Some((app_server_client, runtime)) = connection_metadata else {
|
||||
if let Some(connection_id) = turn_state.connection_id {
|
||||
tracing::warn!(
|
||||
turn_id,
|
||||
connection_id,
|
||||
"dropping turn analytics event: missing connection metadata"
|
||||
);
|
||||
}
|
||||
return;
|
||||
};
|
||||
let Some(thread_id) = turn_state.thread_id.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let Some(thread_metadata) = self.thread_metadata.get(thread_id) else {
|
||||
tracing::warn!(
|
||||
thread_id,
|
||||
turn_id,
|
||||
"dropping turn analytics event: missing thread lifecycle metadata"
|
||||
let Some(connection_id) = turn_state.connection_id else {
|
||||
return;
|
||||
};
|
||||
let Some(connection_state) = self.connections.get(&connection_id) else {
|
||||
warn_missing_analytics_context(
|
||||
&AnalyticsDropSite::turn(thread_id, turn_id),
|
||||
MissingAnalyticsContext::Connection { connection_id },
|
||||
);
|
||||
return;
|
||||
};
|
||||
let drop_site = AnalyticsDropSite::turn(thread_id, turn_id);
|
||||
let Some(thread_metadata) = self
|
||||
.threads
|
||||
.get(drop_site.thread_id)
|
||||
.and_then(|thread| thread.metadata.as_ref())
|
||||
else {
|
||||
warn_missing_analytics_context(&drop_site, MissingAnalyticsContext::ThreadMetadata);
|
||||
return;
|
||||
};
|
||||
out.push(TrackEventRequest::TurnEvent(Box::new(
|
||||
CodexTurnEventRequest {
|
||||
event_type: "codex_turn_event",
|
||||
event_params: codex_turn_event_params(
|
||||
app_server_client,
|
||||
runtime,
|
||||
connection_state.app_server_client.clone(),
|
||||
connection_state.runtime.clone(),
|
||||
turn_id.to_string(),
|
||||
turn_state,
|
||||
thread_metadata,
|
||||
@@ -865,6 +913,67 @@ impl AnalyticsReducer {
|
||||
)));
|
||||
self.turns.remove(turn_id);
|
||||
}
|
||||
|
||||
fn thread_connection_or_warn(
|
||||
&self,
|
||||
drop_site: AnalyticsDropSite<'_>,
|
||||
) -> Option<&ConnectionState> {
|
||||
let Some(thread_state) = self.threads.get(drop_site.thread_id) else {
|
||||
warn_missing_analytics_context(&drop_site, MissingAnalyticsContext::ThreadConnection);
|
||||
return None;
|
||||
};
|
||||
let Some(connection_id) = thread_state.connection_id else {
|
||||
warn_missing_analytics_context(&drop_site, MissingAnalyticsContext::ThreadConnection);
|
||||
return None;
|
||||
};
|
||||
let Some(connection_state) = self.connections.get(&connection_id) else {
|
||||
warn_missing_analytics_context(
|
||||
&drop_site,
|
||||
MissingAnalyticsContext::Connection { connection_id },
|
||||
);
|
||||
return None;
|
||||
};
|
||||
Some(connection_state)
|
||||
}
|
||||
|
||||
fn thread_context_or_warn(
|
||||
&self,
|
||||
drop_site: AnalyticsDropSite<'_>,
|
||||
) -> Option<(&ConnectionState, &ThreadMetadataState)> {
|
||||
let connection_state = self.thread_connection_or_warn(drop_site)?;
|
||||
let Some(thread_metadata) = self
|
||||
.threads
|
||||
.get(drop_site.thread_id)
|
||||
.and_then(|thread| thread.metadata.as_ref())
|
||||
else {
|
||||
warn_missing_analytics_context(&drop_site, MissingAnalyticsContext::ThreadMetadata);
|
||||
return None;
|
||||
};
|
||||
Some((connection_state, thread_metadata))
|
||||
}
|
||||
}
|
||||
|
||||
fn warn_missing_analytics_context(
|
||||
drop_site: &AnalyticsDropSite<'_>,
|
||||
missing: MissingAnalyticsContext,
|
||||
) {
|
||||
let (missing_context, connection_id) = match missing {
|
||||
MissingAnalyticsContext::ThreadConnection => ("thread_connection", None),
|
||||
MissingAnalyticsContext::Connection { connection_id } => {
|
||||
("connection", Some(connection_id))
|
||||
}
|
||||
MissingAnalyticsContext::ThreadMetadata => ("thread_metadata", None),
|
||||
};
|
||||
tracing::warn!(
|
||||
thread_id = %drop_site.thread_id,
|
||||
turn_id = ?drop_site.turn_id,
|
||||
review_id = ?drop_site.review_id,
|
||||
item_id = ?drop_site.item_id,
|
||||
missing_context,
|
||||
connection_id,
|
||||
"dropping {} analytics event: missing analytics context",
|
||||
drop_site.event_name
|
||||
);
|
||||
}
|
||||
|
||||
fn codex_turn_event_params(
|
||||
|
||||
@@ -99,10 +99,6 @@ pub mod legacy_core {
|
||||
pub use codex_core::personality_migration::*;
|
||||
}
|
||||
|
||||
pub mod plugins {
|
||||
pub use codex_core::plugins::PluginsManager;
|
||||
}
|
||||
|
||||
pub mod review_format {
|
||||
pub use codex_core::review_format::*;
|
||||
}
|
||||
@@ -304,7 +300,15 @@ impl fmt::Display for TypedRequestError {
|
||||
write!(f, "{method} transport error: {source}")
|
||||
}
|
||||
Self::Server { method, source } => {
|
||||
write!(f, "{method} failed: {}", source.message)
|
||||
write!(
|
||||
f,
|
||||
"{method} failed: {} (code {})",
|
||||
source.message, source.code
|
||||
)?;
|
||||
if let Some(data) = source.data.as_ref() {
|
||||
write!(f, ", data: {data}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Self::Deserialize { method, source } => {
|
||||
write!(f, "{method} response decode error: {source}")
|
||||
@@ -1919,11 +1923,15 @@ mod tests {
|
||||
method: "thread/read".to_string(),
|
||||
source: JSONRPCErrorError {
|
||||
code: -32603,
|
||||
data: None,
|
||||
data: Some(serde_json::json!({"detail": "config lock mismatch"})),
|
||||
message: "internal".to_string(),
|
||||
},
|
||||
};
|
||||
assert_eq!(std::error::Error::source(&server).is_some(), false);
|
||||
assert_eq!(
|
||||
server.to_string(),
|
||||
"thread/read failed: internal (code -32603), data: {\"detail\":\"config lock mismatch\"}"
|
||||
);
|
||||
|
||||
let deserialize = TypedRequestError::Deserialize {
|
||||
method: "thread/start".to_string(),
|
||||
|
||||
@@ -1415,6 +1415,18 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HooksListParams": {
|
||||
"properties": {
|
||||
"cwds": {
|
||||
"description": "When empty, defaults to the current session working directory.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
@@ -1586,6 +1598,9 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"codexStreamlinedLogin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"chatgpt"
|
||||
@@ -2024,6 +2039,31 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileModificationParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileNetworkPermissions": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
@@ -2035,6 +2075,40 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PermissionProfileSelectionParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"modifications": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionProfileModificationParams"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"profile"
|
||||
],
|
||||
"title": "ProfilePermissionProfileSelectionParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"type"
|
||||
],
|
||||
"title": "ProfilePermissionProfileSelectionParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Personality": {
|
||||
"enum": [
|
||||
"none",
|
||||
@@ -2112,6 +2186,56 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareDeleteParams": {
|
||||
"properties": {
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareListParams": {
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareSaveParams": {
|
||||
"properties": {
|
||||
"pluginPath": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"pluginPath"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSkillReadParams": {
|
||||
"properties": {
|
||||
"remoteMarketplaceName": {
|
||||
"type": "string"
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
},
|
||||
"skillName": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remoteMarketplaceName",
|
||||
"remotePluginId",
|
||||
"skillName"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginUninstallParams": {
|
||||
"properties": {
|
||||
"pluginId": {
|
||||
@@ -3348,10 +3472,6 @@
|
||||
"ephemeral": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"excludeTurns": {
|
||||
"description": "When true, return only thread metadata and live fork state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after forking.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"model": {
|
||||
"description": "Configuration overrides for the forked thread, if any.",
|
||||
"type": [
|
||||
@@ -3753,10 +3873,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"excludeTurns": {
|
||||
"description": "When true, return only thread metadata and live-resume state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after resuming.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"model": {
|
||||
"description": "Configuration overrides for the resumed thread, if any.",
|
||||
"type": [
|
||||
@@ -4016,44 +4132,6 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"ThreadTurnsListParams": {
|
||||
"properties": {
|
||||
"cursor": {
|
||||
"description": "Opaque cursor to pass to the next call to continue after the last turn.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"limit": {
|
||||
"description": "Optional turn page size.",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortDirection": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SortDirection"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional turn pagination direction; defaults to descending."
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadUnarchiveParams": {
|
||||
"properties": {
|
||||
"threadId": {
|
||||
@@ -4784,30 +4862,6 @@
|
||||
"title": "Thread/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/turns/list"
|
||||
],
|
||||
"title": "Thread/turns/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ThreadTurnsListParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/turns/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Append raw Responses API items to the thread history without starting a user turn.",
|
||||
"properties": {
|
||||
@@ -4857,6 +4911,30 @@
|
||||
"title": "Skills/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"hooks/list"
|
||||
],
|
||||
"title": "Hooks/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/HooksListParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Hooks/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -4977,6 +5055,102 @@
|
||||
"title": "Plugin/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/skill/read"
|
||||
],
|
||||
"title": "Plugin/skill/readRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/PluginSkillReadParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/skill/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/share/save"
|
||||
],
|
||||
"title": "Plugin/share/saveRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/PluginShareSaveParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/share/saveRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/share/list"
|
||||
],
|
||||
"title": "Plugin/share/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/PluginShareListParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/share/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/share/delete"
|
||||
],
|
||||
"title": "Plugin/share/deleteRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/PluginShareDeleteParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/share/deleteRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
|
||||
@@ -1032,6 +1032,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"FileChangeOutputDeltaNotification": {
|
||||
"description": "Deprecated legacy notification for `apply_patch` textual output.\n\nThe server no longer emits this notification.",
|
||||
"properties": {
|
||||
"delta": {
|
||||
"type": "string"
|
||||
@@ -1901,6 +1902,7 @@
|
||||
"mdm",
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
@@ -3929,7 +3931,7 @@
|
||||
"ThreadRealtimeStartedNotification": {
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime startup is accepted.",
|
||||
"properties": {
|
||||
"sessionId": {
|
||||
"realtimeSessionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
@@ -5190,6 +5192,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Deprecated legacy apply_patch output stream notification.",
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
|
||||
@@ -569,30 +569,6 @@
|
||||
"title": "Thread/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/turns/list"
|
||||
],
|
||||
"title": "Thread/turns/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/ThreadTurnsListParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/turns/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Append raw Responses API items to the thread history without starting a user turn.",
|
||||
"properties": {
|
||||
@@ -642,6 +618,30 @@
|
||||
"title": "Skills/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"hooks/list"
|
||||
],
|
||||
"title": "Hooks/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/HooksListParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Hooks/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -762,6 +762,102 @@
|
||||
"title": "Plugin/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/skill/read"
|
||||
],
|
||||
"title": "Plugin/skill/readRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/PluginSkillReadParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/skill/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/share/save"
|
||||
],
|
||||
"title": "Plugin/share/saveRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/PluginShareSaveParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/share/saveRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/share/list"
|
||||
],
|
||||
"title": "Plugin/share/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/PluginShareListParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/share/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/v2/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/share/delete"
|
||||
],
|
||||
"title": "Plugin/share/deleteRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/v2/PluginShareDeleteParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/share/deleteRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -4193,6 +4289,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Deprecated legacy apply_patch output stream notification.",
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
@@ -5389,6 +5486,59 @@
|
||||
"title": "AccountUpdatedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"ActivePermissionProfile": {
|
||||
"properties": {
|
||||
"extends": {
|
||||
"default": null,
|
||||
"description": "Parent profile identifier once permissions profiles support inheritance. This is currently always `null`.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"description": "Identifier from `default_permissions` or the implicit built-in default, such as `:workspace` or a user-defined `[permissions.<id>]` profile.",
|
||||
"type": "string"
|
||||
},
|
||||
"modifications": {
|
||||
"default": [],
|
||||
"description": "Bounded user-requested modifications applied on top of the named profile, if any.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/ActivePermissionProfileModification"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ActivePermissionProfileModification": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModificationType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModification",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"AddCreditsNudgeCreditType": {
|
||||
"enum": [
|
||||
"credits",
|
||||
@@ -8451,6 +8601,7 @@
|
||||
},
|
||||
"FileChangeOutputDeltaNotification": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Deprecated legacy notification for `apply_patch` textual output.\n\nThe server no longer emits this notification.",
|
||||
"properties": {
|
||||
"delta": {
|
||||
"type": "string"
|
||||
@@ -9568,6 +9719,21 @@
|
||||
"title": "HookCompletedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"HookErrorInfo": {
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HookEventName": {
|
||||
"enum": [
|
||||
"preToolUse",
|
||||
@@ -9594,6 +9760,76 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"HookMetadata": {
|
||||
"properties": {
|
||||
"command": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"displayOrder": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"eventName": {
|
||||
"$ref": "#/definitions/v2/HookEventName"
|
||||
},
|
||||
"handlerType": {
|
||||
"$ref": "#/definitions/v2/HookHandlerType"
|
||||
},
|
||||
"isManaged": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"matcher": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"pluginId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/definitions/v2/HookSource"
|
||||
},
|
||||
"sourcePath": {
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
},
|
||||
"statusMessage": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"timeoutSec": {
|
||||
"format": "uint64",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"displayOrder",
|
||||
"enabled",
|
||||
"eventName",
|
||||
"handlerType",
|
||||
"isManaged",
|
||||
"key",
|
||||
"source",
|
||||
"sourcePath",
|
||||
"timeoutSec"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HookMigration": {
|
||||
"properties": {
|
||||
"name": {
|
||||
@@ -9750,6 +9986,7 @@
|
||||
"mdm",
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
@@ -9779,6 +10016,68 @@
|
||||
"title": "HookStartedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"HooksListEntry": {
|
||||
"properties": {
|
||||
"cwd": {
|
||||
"type": "string"
|
||||
},
|
||||
"errors": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/HookErrorInfo"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"hooks": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/HookMetadata"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"warnings": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"cwd",
|
||||
"errors",
|
||||
"hooks",
|
||||
"warnings"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HooksListParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"cwds": {
|
||||
"description": "When empty, defaults to the current session working directory.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"title": "HooksListParams",
|
||||
"type": "object"
|
||||
},
|
||||
"HooksListResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/HooksListEntry"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"title": "HooksListResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
@@ -10075,6 +10374,9 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"codexStreamlinedLogin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"chatgpt"
|
||||
@@ -11526,6 +11828,31 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileModificationParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileNetworkPermissions": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
@@ -11537,6 +11864,40 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PermissionProfileSelectionParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"modifications": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/PermissionProfileModificationParams"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"profile"
|
||||
],
|
||||
"title": "ProfilePermissionProfileSelectionParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"type"
|
||||
],
|
||||
"title": "ProfilePermissionProfileSelectionParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Personality": {
|
||||
"enum": [
|
||||
"none",
|
||||
@@ -11595,6 +11956,23 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PluginAvailability": {
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
"DISABLED_BY_ADMIN"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Plugin-service currently sends `\"ENABLED\"` for available remote plugins. Codex app-server exposes `\"AVAILABLE\"` in its API; the alias keeps decoding compatible with that upstream response.",
|
||||
"enum": [
|
||||
"AVAILABLE"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PluginDetail": {
|
||||
"properties": {
|
||||
"apps": {
|
||||
@@ -11962,6 +12340,140 @@
|
||||
"title": "PluginReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareDeleteParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId"
|
||||
],
|
||||
"title": "PluginShareDeleteParams",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareDeleteResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PluginShareDeleteResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareListItem": {
|
||||
"properties": {
|
||||
"localPluginPath": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"plugin": {
|
||||
"$ref": "#/definitions/v2/PluginSummary"
|
||||
},
|
||||
"shareUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"plugin",
|
||||
"shareUrl"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareListParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PluginShareListParams",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareListResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/PluginShareListItem"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"title": "PluginShareListResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareSaveParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"pluginPath": {
|
||||
"$ref": "#/definitions/v2/AbsolutePathBuf"
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"pluginPath"
|
||||
],
|
||||
"title": "PluginShareSaveParams",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareSaveResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
},
|
||||
"shareUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId",
|
||||
"shareUrl"
|
||||
],
|
||||
"title": "PluginShareSaveResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSkillReadParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"remoteMarketplaceName": {
|
||||
"type": "string"
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
},
|
||||
"skillName": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remoteMarketplaceName",
|
||||
"remotePluginId",
|
||||
"skillName"
|
||||
],
|
||||
"title": "PluginSkillReadParams",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSkillReadResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"contents": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": "PluginSkillReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSource": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -12046,6 +12558,15 @@
|
||||
"authPolicy": {
|
||||
"$ref": "#/definitions/v2/PluginAuthPolicy"
|
||||
},
|
||||
"availability": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/PluginAvailability"
|
||||
}
|
||||
],
|
||||
"default": "AVAILABLE",
|
||||
"description": "Availability state for installing and using the plugin."
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -14617,10 +15138,6 @@
|
||||
"ephemeral": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"excludeTurns": {
|
||||
"description": "When true, return only thread metadata and live fork state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after forking.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"model": {
|
||||
"description": "Configuration overrides for the forked thread, if any.",
|
||||
"type": [
|
||||
@@ -14718,7 +15235,7 @@
|
||||
"$ref": "#/definitions/v2/SandboxPolicy"
|
||||
}
|
||||
],
|
||||
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` when present as the canonical active permissions view."
|
||||
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
|
||||
},
|
||||
"serviceTier": {
|
||||
"anyOf": [
|
||||
@@ -16002,7 +16519,7 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime startup is accepted.",
|
||||
"properties": {
|
||||
"sessionId": {
|
||||
"realtimeSessionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
@@ -16118,10 +16635,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"excludeTurns": {
|
||||
"description": "When true, return only thread metadata and live-resume state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after resuming.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"model": {
|
||||
"description": "Configuration overrides for the resumed thread, if any.",
|
||||
"type": [
|
||||
@@ -16229,7 +16742,7 @@
|
||||
"$ref": "#/definitions/v2/SandboxPolicy"
|
||||
}
|
||||
],
|
||||
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` when present as the canonical active permissions view."
|
||||
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
|
||||
},
|
||||
"serviceTier": {
|
||||
"anyOf": [
|
||||
@@ -16533,7 +17046,7 @@
|
||||
"$ref": "#/definitions/v2/SandboxPolicy"
|
||||
}
|
||||
],
|
||||
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` when present as the canonical active permissions view."
|
||||
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
|
||||
},
|
||||
"serviceTier": {
|
||||
"anyOf": [
|
||||
@@ -16716,76 +17229,6 @@
|
||||
"title": "ThreadTokenUsageUpdatedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadTurnsListParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"cursor": {
|
||||
"description": "Opaque cursor to pass to the next call to continue after the last turn.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"limit": {
|
||||
"description": "Optional turn page size.",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortDirection": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/SortDirection"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional turn pagination direction; defaults to descending."
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadTurnsListParams",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadTurnsListResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"backwardsCursor": {
|
||||
"description": "Opaque cursor to pass as `cursor` when reversing `sortDirection`. This is only populated when the page contains at least one turn. Use it with the opposite `sortDirection` to include the anchor turn again and catch updates to that turn.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/Turn"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"nextCursor": {
|
||||
"description": "Opaque cursor to pass to the next call to continue after the last turn. if None, there are no more turns to return.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"title": "ThreadTurnsListResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadUnarchiveParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
|
||||
@@ -130,6 +130,59 @@
|
||||
"title": "AccountUpdatedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"ActivePermissionProfile": {
|
||||
"properties": {
|
||||
"extends": {
|
||||
"default": null,
|
||||
"description": "Parent profile identifier once permissions profiles support inheritance. This is currently always `null`.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"description": "Identifier from `default_permissions` or the implicit built-in default, such as `:workspace` or a user-defined `[permissions.<id>]` profile.",
|
||||
"type": "string"
|
||||
},
|
||||
"modifications": {
|
||||
"default": [],
|
||||
"description": "Bounded user-requested modifications applied on top of the named profile, if any.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ActivePermissionProfileModification"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ActivePermissionProfileModification": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModificationType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModification",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"AddCreditsNudgeCreditType": {
|
||||
"enum": [
|
||||
"credits",
|
||||
@@ -1275,30 +1328,6 @@
|
||||
"title": "Thread/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"thread/turns/list"
|
||||
],
|
||||
"title": "Thread/turns/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/ThreadTurnsListParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Thread/turns/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Append raw Responses API items to the thread history without starting a user turn.",
|
||||
"properties": {
|
||||
@@ -1348,6 +1377,30 @@
|
||||
"title": "Skills/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"hooks/list"
|
||||
],
|
||||
"title": "Hooks/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/HooksListParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Hooks/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -1468,6 +1521,102 @@
|
||||
"title": "Plugin/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/skill/read"
|
||||
],
|
||||
"title": "Plugin/skill/readRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/PluginSkillReadParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/skill/readRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/share/save"
|
||||
],
|
||||
"title": "Plugin/share/saveRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/PluginShareSaveParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/share/saveRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/share/list"
|
||||
],
|
||||
"title": "Plugin/share/listRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/PluginShareListParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/share/listRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/definitions/RequestId"
|
||||
},
|
||||
"method": {
|
||||
"enum": [
|
||||
"plugin/share/delete"
|
||||
],
|
||||
"title": "Plugin/share/deleteRequestMethod",
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"$ref": "#/definitions/PluginShareDeleteParams"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"method",
|
||||
"params"
|
||||
],
|
||||
"title": "Plugin/share/deleteRequest",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"id": {
|
||||
@@ -4950,6 +5099,7 @@
|
||||
},
|
||||
"FileChangeOutputDeltaNotification": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Deprecated legacy notification for `apply_patch` textual output.\n\nThe server no longer emits this notification.",
|
||||
"properties": {
|
||||
"delta": {
|
||||
"type": "string"
|
||||
@@ -6178,6 +6328,21 @@
|
||||
"title": "HookCompletedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"HookErrorInfo": {
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HookEventName": {
|
||||
"enum": [
|
||||
"preToolUse",
|
||||
@@ -6204,6 +6369,76 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"HookMetadata": {
|
||||
"properties": {
|
||||
"command": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"displayOrder": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"eventName": {
|
||||
"$ref": "#/definitions/HookEventName"
|
||||
},
|
||||
"handlerType": {
|
||||
"$ref": "#/definitions/HookHandlerType"
|
||||
},
|
||||
"isManaged": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"matcher": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"pluginId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/definitions/HookSource"
|
||||
},
|
||||
"sourcePath": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"statusMessage": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"timeoutSec": {
|
||||
"format": "uint64",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"displayOrder",
|
||||
"enabled",
|
||||
"eventName",
|
||||
"handlerType",
|
||||
"isManaged",
|
||||
"key",
|
||||
"source",
|
||||
"sourcePath",
|
||||
"timeoutSec"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HookMigration": {
|
||||
"properties": {
|
||||
"name": {
|
||||
@@ -6360,6 +6595,7 @@
|
||||
"mdm",
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
@@ -6389,6 +6625,68 @@
|
||||
"title": "HookStartedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"HooksListEntry": {
|
||||
"properties": {
|
||||
"cwd": {
|
||||
"type": "string"
|
||||
},
|
||||
"errors": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/HookErrorInfo"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"hooks": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/HookMetadata"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"warnings": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"cwd",
|
||||
"errors",
|
||||
"hooks",
|
||||
"warnings"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HooksListParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"cwds": {
|
||||
"description": "When empty, defaults to the current session working directory.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"title": "HooksListParams",
|
||||
"type": "object"
|
||||
},
|
||||
"HooksListResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/HooksListEntry"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"title": "HooksListResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"ImageDetail": {
|
||||
"enum": [
|
||||
"auto",
|
||||
@@ -6729,6 +7027,9 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"codexStreamlinedLogin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"chatgpt"
|
||||
@@ -8180,6 +8481,31 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileModificationParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileNetworkPermissions": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
@@ -8191,6 +8517,40 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PermissionProfileSelectionParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"modifications": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionProfileModificationParams"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"profile"
|
||||
],
|
||||
"title": "ProfilePermissionProfileSelectionParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"type"
|
||||
],
|
||||
"title": "ProfilePermissionProfileSelectionParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Personality": {
|
||||
"enum": [
|
||||
"none",
|
||||
@@ -8249,6 +8609,23 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PluginAvailability": {
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
"DISABLED_BY_ADMIN"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Plugin-service currently sends `\"ENABLED\"` for available remote plugins. Codex app-server exposes `\"AVAILABLE\"` in its API; the alias keeps decoding compatible with that upstream response.",
|
||||
"enum": [
|
||||
"AVAILABLE"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PluginDetail": {
|
||||
"properties": {
|
||||
"apps": {
|
||||
@@ -8616,6 +8993,140 @@
|
||||
"title": "PluginReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareDeleteParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId"
|
||||
],
|
||||
"title": "PluginShareDeleteParams",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareDeleteResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PluginShareDeleteResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareListItem": {
|
||||
"properties": {
|
||||
"localPluginPath": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"plugin": {
|
||||
"$ref": "#/definitions/PluginSummary"
|
||||
},
|
||||
"shareUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"plugin",
|
||||
"shareUrl"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareListParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PluginShareListParams",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareListResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/PluginShareListItem"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"title": "PluginShareListResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareSaveParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"pluginPath": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"pluginPath"
|
||||
],
|
||||
"title": "PluginShareSaveParams",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareSaveResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
},
|
||||
"shareUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId",
|
||||
"shareUrl"
|
||||
],
|
||||
"title": "PluginShareSaveResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSkillReadParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"remoteMarketplaceName": {
|
||||
"type": "string"
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
},
|
||||
"skillName": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remoteMarketplaceName",
|
||||
"remotePluginId",
|
||||
"skillName"
|
||||
],
|
||||
"title": "PluginSkillReadParams",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSkillReadResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"contents": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": "PluginSkillReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSource": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -8700,6 +9211,15 @@
|
||||
"authPolicy": {
|
||||
"$ref": "#/definitions/PluginAuthPolicy"
|
||||
},
|
||||
"availability": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PluginAvailability"
|
||||
}
|
||||
],
|
||||
"default": "AVAILABLE",
|
||||
"description": "Availability state for installing and using the plugin."
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -10873,6 +11393,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Deprecated legacy apply_patch output stream notification.",
|
||||
"properties": {
|
||||
"method": {
|
||||
"enum": [
|
||||
@@ -12503,10 +13024,6 @@
|
||||
"ephemeral": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"excludeTurns": {
|
||||
"description": "When true, return only thread metadata and live fork state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after forking.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"model": {
|
||||
"description": "Configuration overrides for the forked thread, if any.",
|
||||
"type": [
|
||||
@@ -12604,7 +13121,7 @@
|
||||
"$ref": "#/definitions/SandboxPolicy"
|
||||
}
|
||||
],
|
||||
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` when present as the canonical active permissions view."
|
||||
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
|
||||
},
|
||||
"serviceTier": {
|
||||
"anyOf": [
|
||||
@@ -13888,7 +14405,7 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime startup is accepted.",
|
||||
"properties": {
|
||||
"sessionId": {
|
||||
"realtimeSessionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
@@ -14004,10 +14521,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"excludeTurns": {
|
||||
"description": "When true, return only thread metadata and live-resume state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after resuming.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"model": {
|
||||
"description": "Configuration overrides for the resumed thread, if any.",
|
||||
"type": [
|
||||
@@ -14115,7 +14628,7 @@
|
||||
"$ref": "#/definitions/SandboxPolicy"
|
||||
}
|
||||
],
|
||||
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` when present as the canonical active permissions view."
|
||||
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
|
||||
},
|
||||
"serviceTier": {
|
||||
"anyOf": [
|
||||
@@ -14419,7 +14932,7 @@
|
||||
"$ref": "#/definitions/SandboxPolicy"
|
||||
}
|
||||
],
|
||||
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` when present as the canonical active permissions view."
|
||||
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
|
||||
},
|
||||
"serviceTier": {
|
||||
"anyOf": [
|
||||
@@ -14602,76 +15115,6 @@
|
||||
"title": "ThreadTokenUsageUpdatedNotification",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadTurnsListParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"cursor": {
|
||||
"description": "Opaque cursor to pass to the next call to continue after the last turn.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"limit": {
|
||||
"description": "Optional turn page size.",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortDirection": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SortDirection"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional turn pagination direction; defaults to descending."
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadTurnsListParams",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadTurnsListResponse": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"backwardsCursor": {
|
||||
"description": "Opaque cursor to pass as `cursor` when reversing `sortDirection`. This is only populated when the page contains at least one turn. Use it with the opposite `sortDirection` to include the anchor turn again and catch updates to that turn.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/Turn"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"nextCursor": {
|
||||
"description": "Opaque cursor to pass to the next call to continue after the last turn. if None, there are no more turns to return.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"title": "ThreadTurnsListResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"ThreadUnarchiveParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Deprecated legacy notification for `apply_patch` textual output.\n\nThe server no longer emits this notification.",
|
||||
"properties": {
|
||||
"delta": {
|
||||
"type": "string"
|
||||
|
||||
@@ -161,6 +161,7 @@
|
||||
"mdm",
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
|
||||
@@ -161,6 +161,7 @@
|
||||
"mdm",
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
|
||||
14
codex-rs/app-server-protocol/schema/json/v2/HooksListParams.json
generated
Normal file
14
codex-rs/app-server-protocol/schema/json/v2/HooksListParams.json
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"cwds": {
|
||||
"description": "When empty, defaults to the current session working directory.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"title": "HooksListParams",
|
||||
"type": "object"
|
||||
}
|
||||
173
codex-rs/app-server-protocol/schema/json/v2/HooksListResponse.json
generated
Normal file
173
codex-rs/app-server-protocol/schema/json/v2/HooksListResponse.json
generated
Normal file
@@ -0,0 +1,173 @@
|
||||
{
|
||||
"$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"
|
||||
},
|
||||
"HookErrorInfo": {
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HookEventName": {
|
||||
"enum": [
|
||||
"preToolUse",
|
||||
"permissionRequest",
|
||||
"postToolUse",
|
||||
"sessionStart",
|
||||
"userPromptSubmit",
|
||||
"stop"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"HookHandlerType": {
|
||||
"enum": [
|
||||
"command",
|
||||
"prompt",
|
||||
"agent"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"HookMetadata": {
|
||||
"properties": {
|
||||
"command": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"displayOrder": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"eventName": {
|
||||
"$ref": "#/definitions/HookEventName"
|
||||
},
|
||||
"handlerType": {
|
||||
"$ref": "#/definitions/HookHandlerType"
|
||||
},
|
||||
"isManaged": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"matcher": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"pluginId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/definitions/HookSource"
|
||||
},
|
||||
"sourcePath": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"statusMessage": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"timeoutSec": {
|
||||
"format": "uint64",
|
||||
"minimum": 0.0,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"displayOrder",
|
||||
"enabled",
|
||||
"eventName",
|
||||
"handlerType",
|
||||
"isManaged",
|
||||
"key",
|
||||
"source",
|
||||
"sourcePath",
|
||||
"timeoutSec"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"HookSource": {
|
||||
"enum": [
|
||||
"system",
|
||||
"user",
|
||||
"project",
|
||||
"mdm",
|
||||
"sessionFlags",
|
||||
"plugin",
|
||||
"cloudRequirements",
|
||||
"legacyManagedConfigFile",
|
||||
"legacyManagedConfigMdm",
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"HooksListEntry": {
|
||||
"properties": {
|
||||
"cwd": {
|
||||
"type": "string"
|
||||
},
|
||||
"errors": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/HookErrorInfo"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"hooks": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/HookMetadata"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"warnings": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"cwd",
|
||||
"errors",
|
||||
"hooks",
|
||||
"warnings"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/HooksListEntry"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"title": "HooksListResponse",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -23,6 +23,9 @@
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"codexStreamlinedLogin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"chatgpt"
|
||||
|
||||
@@ -38,6 +38,23 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PluginAvailability": {
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
"DISABLED_BY_ADMIN"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Plugin-service currently sends `\"ENABLED\"` for available remote plugins. Codex app-server exposes `\"AVAILABLE\"` in its API; the alias keeps decoding compatible with that upstream response.",
|
||||
"enum": [
|
||||
"AVAILABLE"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PluginInstallPolicy": {
|
||||
"enum": [
|
||||
"NOT_AVAILABLE",
|
||||
@@ -299,6 +316,15 @@
|
||||
"authPolicy": {
|
||||
"$ref": "#/definitions/PluginAuthPolicy"
|
||||
},
|
||||
"availability": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PluginAvailability"
|
||||
}
|
||||
],
|
||||
"default": "AVAILABLE",
|
||||
"description": "Availability state for installing and using the plugin."
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
||||
@@ -44,6 +44,23 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PluginAvailability": {
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
"DISABLED_BY_ADMIN"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Plugin-service currently sends `\"ENABLED\"` for available remote plugins. Codex app-server exposes `\"AVAILABLE\"` in its API; the alias keeps decoding compatible with that upstream response.",
|
||||
"enum": [
|
||||
"AVAILABLE"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PluginDetail": {
|
||||
"properties": {
|
||||
"apps": {
|
||||
@@ -318,6 +335,15 @@
|
||||
"authPolicy": {
|
||||
"$ref": "#/definitions/PluginAuthPolicy"
|
||||
},
|
||||
"availability": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PluginAvailability"
|
||||
}
|
||||
],
|
||||
"default": "AVAILABLE",
|
||||
"description": "Availability state for installing and using the plugin."
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
||||
13
codex-rs/app-server-protocol/schema/json/v2/PluginShareDeleteParams.json
generated
Normal file
13
codex-rs/app-server-protocol/schema/json/v2/PluginShareDeleteParams.json
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId"
|
||||
],
|
||||
"title": "PluginShareDeleteParams",
|
||||
"type": "object"
|
||||
}
|
||||
5
codex-rs/app-server-protocol/schema/json/v2/PluginShareDeleteResponse.json
generated
Normal file
5
codex-rs/app-server-protocol/schema/json/v2/PluginShareDeleteResponse.json
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PluginShareDeleteResponse",
|
||||
"type": "object"
|
||||
}
|
||||
5
codex-rs/app-server-protocol/schema/json/v2/PluginShareListParams.json
generated
Normal file
5
codex-rs/app-server-protocol/schema/json/v2/PluginShareListParams.json
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PluginShareListParams",
|
||||
"type": "object"
|
||||
}
|
||||
342
codex-rs/app-server-protocol/schema/json/v2/PluginShareListResponse.json
generated
Normal file
342
codex-rs/app-server-protocol/schema/json/v2/PluginShareListResponse.json
generated
Normal file
@@ -0,0 +1,342 @@
|
||||
{
|
||||
"$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"
|
||||
},
|
||||
"PluginAuthPolicy": {
|
||||
"enum": [
|
||||
"ON_INSTALL",
|
||||
"ON_USE"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PluginAvailability": {
|
||||
"oneOf": [
|
||||
{
|
||||
"enum": [
|
||||
"DISABLED_BY_ADMIN"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"description": "Plugin-service currently sends `\"ENABLED\"` for available remote plugins. Codex app-server exposes `\"AVAILABLE\"` in its API; the alias keeps decoding compatible with that upstream response.",
|
||||
"enum": [
|
||||
"AVAILABLE"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PluginInstallPolicy": {
|
||||
"enum": [
|
||||
"NOT_AVAILABLE",
|
||||
"AVAILABLE",
|
||||
"INSTALLED_BY_DEFAULT"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PluginInterface": {
|
||||
"properties": {
|
||||
"brandColor": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"capabilities": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"category": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"composerIcon": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Local composer icon path, resolved from the installed plugin package."
|
||||
},
|
||||
"composerIconUrl": {
|
||||
"description": "Remote composer icon URL from the plugin catalog.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"defaultPrompt": {
|
||||
"description": "Starter prompts for the plugin. Capped at 3 entries with a maximum of 128 characters per entry.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"developerName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"displayName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"logo": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Local logo path, resolved from the installed plugin package."
|
||||
},
|
||||
"logoUrl": {
|
||||
"description": "Remote logo URL from the plugin catalog.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"longDescription": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"privacyPolicyUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"screenshotUrls": {
|
||||
"description": "Remote screenshot URLs from the plugin catalog.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"screenshots": {
|
||||
"description": "Local screenshot paths, resolved from the installed plugin package.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"shortDescription": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"termsOfServiceUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"websiteUrl": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"capabilities",
|
||||
"screenshotUrls",
|
||||
"screenshots"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareListItem": {
|
||||
"properties": {
|
||||
"localPluginPath": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"plugin": {
|
||||
"$ref": "#/definitions/PluginSummary"
|
||||
},
|
||||
"shareUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"plugin",
|
||||
"shareUrl"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSource": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"local"
|
||||
],
|
||||
"title": "LocalPluginSourceType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "LocalPluginSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"refName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sha": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"git"
|
||||
],
|
||||
"title": "GitPluginSourceType",
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"url"
|
||||
],
|
||||
"title": "GitPluginSource",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "The plugin is available in the remote catalog. Download metadata is kept server-side and is not exposed through the app-server API.",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"remote"
|
||||
],
|
||||
"title": "RemotePluginSourceType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "RemotePluginSource",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PluginSummary": {
|
||||
"properties": {
|
||||
"authPolicy": {
|
||||
"$ref": "#/definitions/PluginAuthPolicy"
|
||||
},
|
||||
"availability": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PluginAvailability"
|
||||
}
|
||||
],
|
||||
"default": "AVAILABLE",
|
||||
"description": "Availability state for installing and using the plugin."
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"installPolicy": {
|
||||
"$ref": "#/definitions/PluginInstallPolicy"
|
||||
},
|
||||
"installed": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"interface": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PluginInterface"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/definitions/PluginSource"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"authPolicy",
|
||||
"enabled",
|
||||
"id",
|
||||
"installPolicy",
|
||||
"installed",
|
||||
"name",
|
||||
"source"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"data": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/PluginShareListItem"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data"
|
||||
],
|
||||
"title": "PluginShareListResponse",
|
||||
"type": "object"
|
||||
}
|
||||
25
codex-rs/app-server-protocol/schema/json/v2/PluginShareSaveParams.json
generated
Normal file
25
codex-rs/app-server-protocol/schema/json/v2/PluginShareSaveParams.json
generated
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$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": {
|
||||
"pluginPath": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"pluginPath"
|
||||
],
|
||||
"title": "PluginShareSaveParams",
|
||||
"type": "object"
|
||||
}
|
||||
17
codex-rs/app-server-protocol/schema/json/v2/PluginShareSaveResponse.json
generated
Normal file
17
codex-rs/app-server-protocol/schema/json/v2/PluginShareSaveResponse.json
generated
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
},
|
||||
"shareUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId",
|
||||
"shareUrl"
|
||||
],
|
||||
"title": "PluginShareSaveResponse",
|
||||
"type": "object"
|
||||
}
|
||||
21
codex-rs/app-server-protocol/schema/json/v2/PluginSkillReadParams.json
generated
Normal file
21
codex-rs/app-server-protocol/schema/json/v2/PluginSkillReadParams.json
generated
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"remoteMarketplaceName": {
|
||||
"type": "string"
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
},
|
||||
"skillName": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remoteMarketplaceName",
|
||||
"remotePluginId",
|
||||
"skillName"
|
||||
],
|
||||
"title": "PluginSkillReadParams",
|
||||
"type": "object"
|
||||
}
|
||||
13
codex-rs/app-server-protocol/schema/json/v2/PluginSkillReadResponse.json
generated
Normal file
13
codex-rs/app-server-protocol/schema/json/v2/PluginSkillReadResponse.json
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
"contents": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": "PluginSkillReadResponse",
|
||||
"type": "object"
|
||||
}
|
||||
@@ -64,26 +64,19 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"FileSystemAccessMode": {
|
||||
"enum": [
|
||||
"read",
|
||||
"write",
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileSystemPath": {
|
||||
"PermissionProfileModificationParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"path"
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "PathFileSystemPathType",
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -91,304 +84,45 @@
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "PathFileSystemPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"pattern": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"glob_pattern"
|
||||
],
|
||||
"title": "GlobPatternFileSystemPathType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"pattern",
|
||||
"type"
|
||||
],
|
||||
"title": "GlobPatternFileSystemPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"special"
|
||||
],
|
||||
"title": "SpecialFileSystemPathType",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/FileSystemSpecialPath"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"title": "SpecialFileSystemPath",
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"FileSystemSandboxEntry": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/FileSystemAccessMode"
|
||||
},
|
||||
"path": {
|
||||
"$ref": "#/definitions/FileSystemPath"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"access",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"FileSystemSpecialPath": {
|
||||
"PermissionProfileSelectionParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"root"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "RootFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"minimal"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "MinimalFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"project_roots"
|
||||
],
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"subpath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "KindFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"tmpdir"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "TmpdirFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"slash_tmp"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "SlashTmpFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"subpath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfile": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Codex owns sandbox construction for this profile.",
|
||||
"properties": {
|
||||
"fileSystem": {
|
||||
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
|
||||
},
|
||||
"network": {
|
||||
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"managed"
|
||||
],
|
||||
"title": "ManagedPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fileSystem",
|
||||
"network",
|
||||
"type"
|
||||
],
|
||||
"title": "ManagedPermissionProfile",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Do not apply an outer sandbox.",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"disabled"
|
||||
],
|
||||
"title": "DisabledPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "DisabledPermissionProfile",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Filesystem isolation is enforced by an external caller.",
|
||||
"properties": {
|
||||
"network": {
|
||||
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"external"
|
||||
],
|
||||
"title": "ExternalPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"network",
|
||||
"type"
|
||||
],
|
||||
"title": "ExternalPermissionProfile",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileFileSystemPermissions": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"entries": {
|
||||
"modifications": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/FileSystemSandboxEntry"
|
||||
"$ref": "#/definitions/PermissionProfileModificationParams"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"globScanMaxDepth": {
|
||||
"format": "uint",
|
||||
"minimum": 1.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"restricted"
|
||||
"profile"
|
||||
],
|
||||
"title": "RestrictedPermissionProfileFileSystemPermissionsType",
|
||||
"title": "ProfilePermissionProfileSelectionParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entries",
|
||||
"id",
|
||||
"type"
|
||||
],
|
||||
"title": "RestrictedPermissionProfileFileSystemPermissions",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"unrestricted"
|
||||
],
|
||||
"title": "UnrestrictedPermissionProfileFileSystemPermissionsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "UnrestrictedPermissionProfileFileSystemPermissions",
|
||||
"title": "ProfilePermissionProfileSelectionParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileNetworkPermissions": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"enabled"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SandboxMode": {
|
||||
"enum": [
|
||||
"read-only",
|
||||
@@ -456,10 +190,6 @@
|
||||
"ephemeral": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"excludeTurns": {
|
||||
"description": "When true, return only thread metadata and live fork state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after forking.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"model": {
|
||||
"description": "Configuration overrides for the forked thread, if any.",
|
||||
"type": [
|
||||
|
||||
@@ -5,6 +5,59 @@
|
||||
"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"
|
||||
},
|
||||
"ActivePermissionProfile": {
|
||||
"properties": {
|
||||
"extends": {
|
||||
"default": null,
|
||||
"description": "Parent profile identifier once permissions profiles support inheritance. This is currently always `null`.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"description": "Identifier from `default_permissions` or the implicit built-in default, such as `:workspace` or a user-defined `[permissions.<id>]` profile.",
|
||||
"type": "string"
|
||||
},
|
||||
"modifications": {
|
||||
"default": [],
|
||||
"description": "Bounded user-requested modifications applied on top of the named profile, if any.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ActivePermissionProfileModification"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ActivePermissionProfileModification": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModificationType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModification",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"AgentPath": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -2501,7 +2554,7 @@
|
||||
"$ref": "#/definitions/SandboxPolicy"
|
||||
}
|
||||
],
|
||||
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` when present as the canonical active permissions view."
|
||||
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
|
||||
},
|
||||
"serviceTier": {
|
||||
"anyOf": [
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"description": "EXPERIMENTAL - emitted when thread realtime startup is accepted.",
|
||||
"properties": {
|
||||
"sessionId": {
|
||||
"realtimeSessionId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
|
||||
@@ -138,202 +138,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"FileSystemAccessMode": {
|
||||
"enum": [
|
||||
"read",
|
||||
"write",
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileSystemPath": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"path"
|
||||
],
|
||||
"title": "PathFileSystemPathType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "PathFileSystemPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"pattern": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"glob_pattern"
|
||||
],
|
||||
"title": "GlobPatternFileSystemPathType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"pattern",
|
||||
"type"
|
||||
],
|
||||
"title": "GlobPatternFileSystemPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"special"
|
||||
],
|
||||
"title": "SpecialFileSystemPathType",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/FileSystemSpecialPath"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"title": "SpecialFileSystemPath",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"FileSystemSandboxEntry": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/FileSystemAccessMode"
|
||||
},
|
||||
"path": {
|
||||
"$ref": "#/definitions/FileSystemPath"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"access",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"FileSystemSpecialPath": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"root"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "RootFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"minimal"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "MinimalFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"project_roots"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"subpath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "KindFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"tmpdir"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "TmpdirFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"slash_tmp"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "SlashTmpFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"subpath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"FunctionCallOutputBody": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -494,135 +298,65 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfile": {
|
||||
"PermissionProfileModificationParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Codex owns sandbox construction for this profile.",
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"fileSystem": {
|
||||
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
|
||||
},
|
||||
"network": {
|
||||
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"managed"
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "ManagedPermissionProfileType",
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fileSystem",
|
||||
"network",
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "ManagedPermissionProfile",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Do not apply an outer sandbox.",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"disabled"
|
||||
],
|
||||
"title": "DisabledPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "DisabledPermissionProfile",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Filesystem isolation is enforced by an external caller.",
|
||||
"properties": {
|
||||
"network": {
|
||||
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"external"
|
||||
],
|
||||
"title": "ExternalPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"network",
|
||||
"type"
|
||||
],
|
||||
"title": "ExternalPermissionProfile",
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileFileSystemPermissions": {
|
||||
"PermissionProfileSelectionParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
|
||||
"properties": {
|
||||
"entries": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/FileSystemSandboxEntry"
|
||||
},
|
||||
"type": "array"
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"globScanMaxDepth": {
|
||||
"format": "uint",
|
||||
"minimum": 1.0,
|
||||
"modifications": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionProfileModificationParams"
|
||||
},
|
||||
"type": [
|
||||
"integer",
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"restricted"
|
||||
"profile"
|
||||
],
|
||||
"title": "RestrictedPermissionProfileFileSystemPermissionsType",
|
||||
"title": "ProfilePermissionProfileSelectionParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entries",
|
||||
"id",
|
||||
"type"
|
||||
],
|
||||
"title": "RestrictedPermissionProfileFileSystemPermissions",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"unrestricted"
|
||||
],
|
||||
"title": "UnrestrictedPermissionProfileFileSystemPermissionsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "UnrestrictedPermissionProfileFileSystemPermissions",
|
||||
"title": "ProfilePermissionProfileSelectionParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileNetworkPermissions": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"enabled"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"Personality": {
|
||||
"enum": [
|
||||
"none",
|
||||
@@ -1311,10 +1045,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"excludeTurns": {
|
||||
"description": "When true, return only thread metadata and live-resume state without populating `thread.turns`. This is useful when the client plans to call `thread/turns/list` immediately after resuming.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"model": {
|
||||
"description": "Configuration overrides for the resumed thread, if any.",
|
||||
"type": [
|
||||
|
||||
@@ -5,6 +5,59 @@
|
||||
"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"
|
||||
},
|
||||
"ActivePermissionProfile": {
|
||||
"properties": {
|
||||
"extends": {
|
||||
"default": null,
|
||||
"description": "Parent profile identifier once permissions profiles support inheritance. This is currently always `null`.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"description": "Identifier from `default_permissions` or the implicit built-in default, such as `:workspace` or a user-defined `[permissions.<id>]` profile.",
|
||||
"type": "string"
|
||||
},
|
||||
"modifications": {
|
||||
"default": [],
|
||||
"description": "Bounded user-requested modifications applied on top of the named profile, if any.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ActivePermissionProfileModification"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ActivePermissionProfileModification": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModificationType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModification",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"AgentPath": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -2501,7 +2554,7 @@
|
||||
"$ref": "#/definitions/SandboxPolicy"
|
||||
}
|
||||
],
|
||||
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` when present as the canonical active permissions view."
|
||||
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
|
||||
},
|
||||
"serviceTier": {
|
||||
"anyOf": [
|
||||
|
||||
@@ -90,26 +90,19 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"FileSystemAccessMode": {
|
||||
"enum": [
|
||||
"read",
|
||||
"write",
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileSystemPath": {
|
||||
"PermissionProfileModificationParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"path"
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "PathFileSystemPathType",
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
@@ -117,304 +110,45 @@
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "PathFileSystemPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"pattern": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"glob_pattern"
|
||||
],
|
||||
"title": "GlobPatternFileSystemPathType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"pattern",
|
||||
"type"
|
||||
],
|
||||
"title": "GlobPatternFileSystemPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"special"
|
||||
],
|
||||
"title": "SpecialFileSystemPathType",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/FileSystemSpecialPath"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"title": "SpecialFileSystemPath",
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"FileSystemSandboxEntry": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/FileSystemAccessMode"
|
||||
},
|
||||
"path": {
|
||||
"$ref": "#/definitions/FileSystemPath"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"access",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"FileSystemSpecialPath": {
|
||||
"PermissionProfileSelectionParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"root"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "RootFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"minimal"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "MinimalFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"project_roots"
|
||||
],
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"subpath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "KindFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"tmpdir"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "TmpdirFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"slash_tmp"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "SlashTmpFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"subpath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfile": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Codex owns sandbox construction for this profile.",
|
||||
"properties": {
|
||||
"fileSystem": {
|
||||
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
|
||||
},
|
||||
"network": {
|
||||
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"managed"
|
||||
],
|
||||
"title": "ManagedPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fileSystem",
|
||||
"network",
|
||||
"type"
|
||||
],
|
||||
"title": "ManagedPermissionProfile",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Do not apply an outer sandbox.",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"disabled"
|
||||
],
|
||||
"title": "DisabledPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "DisabledPermissionProfile",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Filesystem isolation is enforced by an external caller.",
|
||||
"properties": {
|
||||
"network": {
|
||||
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"external"
|
||||
],
|
||||
"title": "ExternalPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"network",
|
||||
"type"
|
||||
],
|
||||
"title": "ExternalPermissionProfile",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileFileSystemPermissions": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"entries": {
|
||||
"modifications": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/FileSystemSandboxEntry"
|
||||
"$ref": "#/definitions/PermissionProfileModificationParams"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"globScanMaxDepth": {
|
||||
"format": "uint",
|
||||
"minimum": 1.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"restricted"
|
||||
"profile"
|
||||
],
|
||||
"title": "RestrictedPermissionProfileFileSystemPermissionsType",
|
||||
"title": "ProfilePermissionProfileSelectionParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entries",
|
||||
"id",
|
||||
"type"
|
||||
],
|
||||
"title": "RestrictedPermissionProfileFileSystemPermissions",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"unrestricted"
|
||||
],
|
||||
"title": "UnrestrictedPermissionProfileFileSystemPermissionsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "UnrestrictedPermissionProfileFileSystemPermissions",
|
||||
"title": "ProfilePermissionProfileSelectionParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileNetworkPermissions": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"enabled"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"Personality": {
|
||||
"enum": [
|
||||
"none",
|
||||
|
||||
@@ -5,6 +5,59 @@
|
||||
"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"
|
||||
},
|
||||
"ActivePermissionProfile": {
|
||||
"properties": {
|
||||
"extends": {
|
||||
"default": null,
|
||||
"description": "Parent profile identifier once permissions profiles support inheritance. This is currently always `null`.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"description": "Identifier from `default_permissions` or the implicit built-in default, such as `:workspace` or a user-defined `[permissions.<id>]` profile.",
|
||||
"type": "string"
|
||||
},
|
||||
"modifications": {
|
||||
"default": [],
|
||||
"description": "Bounded user-requested modifications applied on top of the named profile, if any.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ActivePermissionProfileModification"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ActivePermissionProfileModification": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModificationType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "AdditionalWritableRootActivePermissionProfileModification",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"AgentPath": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -2501,7 +2554,7 @@
|
||||
"$ref": "#/definitions/SandboxPolicy"
|
||||
}
|
||||
],
|
||||
"description": "Legacy sandbox policy retained for compatibility. New clients should use `permissionProfile` when present as the canonical active permissions view."
|
||||
"description": "Legacy sandbox policy retained for compatibility. Experimental clients should prefer `permissionProfile` when they need exact runtime permissions."
|
||||
},
|
||||
"serviceTier": {
|
||||
"anyOf": [
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"definitions": {
|
||||
"SortDirection": {
|
||||
"enum": [
|
||||
"asc",
|
||||
"desc"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"cursor": {
|
||||
"description": "Opaque cursor to pass to the next call to continue after the last turn.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"limit": {
|
||||
"description": "Optional turn page size.",
|
||||
"format": "uint32",
|
||||
"minimum": 0.0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"sortDirection": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SortDirection"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Optional turn pagination direction; defaults to descending."
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"threadId"
|
||||
],
|
||||
"title": "ThreadTurnsListParams",
|
||||
"type": "object"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -99,202 +99,6 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"FileSystemAccessMode": {
|
||||
"enum": [
|
||||
"read",
|
||||
"write",
|
||||
"none"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"FileSystemPath": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"path"
|
||||
],
|
||||
"title": "PathFileSystemPathType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "PathFileSystemPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"pattern": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"glob_pattern"
|
||||
],
|
||||
"title": "GlobPatternFileSystemPathType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"pattern",
|
||||
"type"
|
||||
],
|
||||
"title": "GlobPatternFileSystemPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"special"
|
||||
],
|
||||
"title": "SpecialFileSystemPathType",
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/definitions/FileSystemSpecialPath"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type",
|
||||
"value"
|
||||
],
|
||||
"title": "SpecialFileSystemPath",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"FileSystemSandboxEntry": {
|
||||
"properties": {
|
||||
"access": {
|
||||
"$ref": "#/definitions/FileSystemAccessMode"
|
||||
},
|
||||
"path": {
|
||||
"$ref": "#/definitions/FileSystemPath"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"access",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"FileSystemSpecialPath": {
|
||||
"oneOf": [
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"root"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "RootFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"minimal"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "MinimalFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"project_roots"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"subpath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "KindFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"tmpdir"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "TmpdirFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"slash_tmp"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"title": "SlashTmpFileSystemSpecialPath",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"kind": {
|
||||
"enum": [
|
||||
"unknown"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"subpath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"path"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ModeKind": {
|
||||
"description": "Initial collaboration mode to use when the TUI starts.",
|
||||
"enum": [
|
||||
@@ -310,135 +114,65 @@
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PermissionProfile": {
|
||||
"PermissionProfileModificationParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Codex owns sandbox construction for this profile.",
|
||||
"description": "Additional concrete directory that should be writable.",
|
||||
"properties": {
|
||||
"fileSystem": {
|
||||
"$ref": "#/definitions/PermissionProfileFileSystemPermissions"
|
||||
},
|
||||
"network": {
|
||||
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
|
||||
"path": {
|
||||
"$ref": "#/definitions/AbsolutePathBuf"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"managed"
|
||||
"additionalWritableRoot"
|
||||
],
|
||||
"title": "ManagedPermissionProfileType",
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fileSystem",
|
||||
"network",
|
||||
"path",
|
||||
"type"
|
||||
],
|
||||
"title": "ManagedPermissionProfile",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Do not apply an outer sandbox.",
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"disabled"
|
||||
],
|
||||
"title": "DisabledPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "DisabledPermissionProfile",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"description": "Filesystem isolation is enforced by an external caller.",
|
||||
"properties": {
|
||||
"network": {
|
||||
"$ref": "#/definitions/PermissionProfileNetworkPermissions"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"external"
|
||||
],
|
||||
"title": "ExternalPermissionProfileType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"network",
|
||||
"type"
|
||||
],
|
||||
"title": "ExternalPermissionProfile",
|
||||
"title": "AdditionalWritableRootPermissionProfileModificationParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileFileSystemPermissions": {
|
||||
"PermissionProfileSelectionParams": {
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Select a named built-in or user-defined profile and optionally apply bounded modifications that Codex knows how to validate.",
|
||||
"properties": {
|
||||
"entries": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/FileSystemSandboxEntry"
|
||||
},
|
||||
"type": "array"
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"globScanMaxDepth": {
|
||||
"format": "uint",
|
||||
"minimum": 1.0,
|
||||
"modifications": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/PermissionProfileModificationParams"
|
||||
},
|
||||
"type": [
|
||||
"integer",
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"restricted"
|
||||
"profile"
|
||||
],
|
||||
"title": "RestrictedPermissionProfileFileSystemPermissionsType",
|
||||
"title": "ProfilePermissionProfileSelectionParamsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"entries",
|
||||
"id",
|
||||
"type"
|
||||
],
|
||||
"title": "RestrictedPermissionProfileFileSystemPermissions",
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"unrestricted"
|
||||
],
|
||||
"title": "UnrestrictedPermissionProfileFileSystemPermissionsType",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"title": "UnrestrictedPermissionProfileFileSystemPermissions",
|
||||
"title": "ProfilePermissionProfileSelectionParams",
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"PermissionProfileNetworkPermissions": {
|
||||
"properties": {
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"enabled"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"Personality": {
|
||||
"enum": [
|
||||
"none",
|
||||
|
||||
File diff suppressed because one or more lines are too long
21
codex-rs/app-server-protocol/schema/typescript/v2/ActivePermissionProfile.ts
generated
Normal file
21
codex-rs/app-server-protocol/schema/typescript/v2/ActivePermissionProfile.ts
generated
Normal file
@@ -0,0 +1,21 @@
|
||||
// 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 { ActivePermissionProfileModification } from "./ActivePermissionProfileModification";
|
||||
|
||||
export type ActivePermissionProfile = {
|
||||
/**
|
||||
* Identifier from `default_permissions` or the implicit built-in default,
|
||||
* such as `:workspace` or a user-defined `[permissions.<id>]` profile.
|
||||
*/
|
||||
id: string,
|
||||
/**
|
||||
* Parent profile identifier once permissions profiles support
|
||||
* inheritance. This is currently always `null`.
|
||||
*/
|
||||
extends: string | null,
|
||||
/**
|
||||
* Bounded user-requested modifications applied on top of the named
|
||||
* profile, if any.
|
||||
*/
|
||||
modifications: Array<ActivePermissionProfileModification>, };
|
||||
6
codex-rs/app-server-protocol/schema/typescript/v2/ActivePermissionProfileModification.ts
generated
Normal file
6
codex-rs/app-server-protocol/schema/typescript/v2/ActivePermissionProfileModification.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 { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
|
||||
export type ActivePermissionProfileModification = { "type": "additionalWritableRoot", path: AbsolutePathBuf, };
|
||||
@@ -2,4 +2,9 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
/**
|
||||
* Deprecated legacy notification for `apply_patch` textual output.
|
||||
*
|
||||
* The server no longer emits this notification.
|
||||
*/
|
||||
export type FileChangeOutputDeltaNotification = { threadId: string, turnId: string, itemId: string, delta: string, };
|
||||
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/HookErrorInfo.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/HookErrorInfo.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type HookErrorInfo = { path: string, message: string, };
|
||||
9
codex-rs/app-server-protocol/schema/typescript/v2/HookMetadata.ts
generated
Normal file
9
codex-rs/app-server-protocol/schema/typescript/v2/HookMetadata.ts
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
import type { HookEventName } from "./HookEventName";
|
||||
import type { HookHandlerType } from "./HookHandlerType";
|
||||
import type { HookSource } from "./HookSource";
|
||||
|
||||
export type HookMetadata = { key: string, eventName: HookEventName, handlerType: HookHandlerType, matcher: string | null, command: string | null, timeoutSec: bigint, statusMessage: string | null, sourcePath: AbsolutePathBuf, source: HookSource, pluginId: string | null, displayOrder: bigint, enabled: boolean, isManaged: boolean, };
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type HookSource = "system" | "user" | "project" | "mdm" | "sessionFlags" | "plugin" | "legacyManagedConfigFile" | "legacyManagedConfigMdm" | "unknown";
|
||||
export type HookSource = "system" | "user" | "project" | "mdm" | "sessionFlags" | "plugin" | "cloudRequirements" | "legacyManagedConfigFile" | "legacyManagedConfigMdm" | "unknown";
|
||||
|
||||
7
codex-rs/app-server-protocol/schema/typescript/v2/HooksListEntry.ts
generated
Normal file
7
codex-rs/app-server-protocol/schema/typescript/v2/HooksListEntry.ts
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { HookErrorInfo } from "./HookErrorInfo";
|
||||
import type { HookMetadata } from "./HookMetadata";
|
||||
|
||||
export type HooksListEntry = { cwd: string, hooks: Array<HookMetadata>, warnings: Array<string>, errors: Array<HookErrorInfo>, };
|
||||
9
codex-rs/app-server-protocol/schema/typescript/v2/HooksListParams.ts
generated
Normal file
9
codex-rs/app-server-protocol/schema/typescript/v2/HooksListParams.ts
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type HooksListParams = {
|
||||
/**
|
||||
* When empty, defaults to the current session working directory.
|
||||
*/
|
||||
cwds?: Array<string>, };
|
||||
6
codex-rs/app-server-protocol/schema/typescript/v2/HooksListResponse.ts
generated
Normal file
6
codex-rs/app-server-protocol/schema/typescript/v2/HooksListResponse.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 { HooksListEntry } from "./HooksListEntry";
|
||||
|
||||
export type HooksListResponse = { data: Array<HooksListEntry>, };
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type LoginAccountParams = { "type": "apiKey", apiKey: string, } | { "type": "chatgpt" } | { "type": "chatgptDeviceCode" } | { "type": "chatgptAuthTokens",
|
||||
export type LoginAccountParams = { "type": "apiKey", apiKey: string, } | { "type": "chatgpt", codexStreamlinedLogin?: boolean, } | { "type": "chatgptDeviceCode" } | { "type": "chatgptAuthTokens",
|
||||
/**
|
||||
* Access token (JWT) supplied by the client.
|
||||
* This token is used for backend API requests and email extraction.
|
||||
|
||||
6
codex-rs/app-server-protocol/schema/typescript/v2/PermissionProfileModificationParams.ts
generated
Normal file
6
codex-rs/app-server-protocol/schema/typescript/v2/PermissionProfileModificationParams.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 { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
|
||||
export type PermissionProfileModificationParams = { "type": "additionalWritableRoot", path: AbsolutePathBuf, };
|
||||
6
codex-rs/app-server-protocol/schema/typescript/v2/PermissionProfileSelectionParams.ts
generated
Normal file
6
codex-rs/app-server-protocol/schema/typescript/v2/PermissionProfileSelectionParams.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 { PermissionProfileModificationParams } from "./PermissionProfileModificationParams";
|
||||
|
||||
export type PermissionProfileSelectionParams = { "type": "profile", id: string, modifications?: Array<PermissionProfileModificationParams> | null, };
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginAvailability.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginAvailability.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type PluginAvailability = "AVAILABLE" | "DISABLED_BY_ADMIN";
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareDeleteParams.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareDeleteParams.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type PluginShareDeleteParams = { remotePluginId: string, };
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareDeleteResponse.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareDeleteResponse.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type PluginShareDeleteResponse = Record<string, never>;
|
||||
7
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareListItem.ts
generated
Normal file
7
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareListItem.ts
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
import type { PluginSummary } from "./PluginSummary";
|
||||
|
||||
export type PluginShareListItem = { plugin: PluginSummary, shareUrl: string, localPluginPath: AbsolutePathBuf | null, };
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareListParams.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareListParams.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type PluginShareListParams = Record<string, never>;
|
||||
6
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareListResponse.ts
generated
Normal file
6
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareListResponse.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 { PluginShareListItem } from "./PluginShareListItem";
|
||||
|
||||
export type PluginShareListResponse = { data: Array<PluginShareListItem>, };
|
||||
6
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareSaveParams.ts
generated
Normal file
6
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareSaveParams.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 { AbsolutePathBuf } from "../AbsolutePathBuf";
|
||||
|
||||
export type PluginShareSaveParams = { pluginPath: AbsolutePathBuf, remotePluginId?: string | null, };
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareSaveResponse.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareSaveResponse.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type PluginShareSaveResponse = { remotePluginId: string, shareUrl: string, };
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginSkillReadParams.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginSkillReadParams.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type PluginSkillReadParams = { remoteMarketplaceName: string, remotePluginId: string, skillName: string, };
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginSkillReadResponse.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginSkillReadResponse.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type PluginSkillReadResponse = { contents: string | null, };
|
||||
@@ -2,8 +2,13 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { PluginAuthPolicy } from "./PluginAuthPolicy";
|
||||
import type { PluginAvailability } from "./PluginAvailability";
|
||||
import type { PluginInstallPolicy } from "./PluginInstallPolicy";
|
||||
import type { PluginInterface } from "./PluginInterface";
|
||||
import type { PluginSource } from "./PluginSource";
|
||||
|
||||
export type PluginSummary = { id: string, name: string, source: PluginSource, installed: boolean, enabled: boolean, installPolicy: PluginInstallPolicy, authPolicy: PluginAuthPolicy, interface: PluginInterface | null, };
|
||||
export type PluginSummary = { id: string, name: string, source: PluginSource, installed: boolean, enabled: boolean, installPolicy: PluginInstallPolicy, authPolicy: PluginAuthPolicy,
|
||||
/**
|
||||
* Availability state for installing and using the plugin.
|
||||
*/
|
||||
availability: PluginAvailability, interface: PluginInterface | null, };
|
||||
|
||||
@@ -23,9 +23,4 @@ model?: string | null, modelProvider?: string | null, serviceTier?: ServiceTier
|
||||
* Override where approval requests are routed for review on this thread
|
||||
* and subsequent turns.
|
||||
*/
|
||||
approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, ephemeral?: boolean, /**
|
||||
* When true, return only thread metadata and live fork state without
|
||||
* populating `thread.turns`. This is useful when the client plans to call
|
||||
* `thread/turns/list` immediately after forking.
|
||||
*/
|
||||
excludeTurns?: boolean};
|
||||
approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, ephemeral?: boolean};
|
||||
|
||||
@@ -16,8 +16,8 @@ instructionSources: Array<AbsolutePathBuf>, approvalPolicy: AskForApproval, /**
|
||||
* Reviewer currently used for approval requests on this thread.
|
||||
*/
|
||||
approvalsReviewer: ApprovalsReviewer, /**
|
||||
* Legacy sandbox policy retained for compatibility. New clients should use
|
||||
* `permissionProfile` when present as the canonical active permissions
|
||||
* view.
|
||||
* Legacy sandbox policy retained for compatibility. Experimental clients
|
||||
* should prefer `permissionProfile` when they need exact runtime
|
||||
* permissions.
|
||||
*/
|
||||
sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null};
|
||||
|
||||
@@ -6,4 +6,4 @@ import type { RealtimeConversationVersion } from "../RealtimeConversationVersion
|
||||
/**
|
||||
* EXPERIMENTAL - emitted when thread realtime startup is accepted.
|
||||
*/
|
||||
export type ThreadRealtimeStartedNotification = { threadId: string, sessionId: string | null, version: RealtimeConversationVersion, };
|
||||
export type ThreadRealtimeStartedNotification = { threadId: string, realtimeSessionId: string | null, version: RealtimeConversationVersion, };
|
||||
|
||||
@@ -26,9 +26,4 @@ model?: string | null, modelProvider?: string | null, serviceTier?: ServiceTier
|
||||
* Override where approval requests are routed for review on this thread
|
||||
* and subsequent turns.
|
||||
*/
|
||||
approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, personality?: Personality | null, /**
|
||||
* When true, return only thread metadata and live-resume state without
|
||||
* populating `thread.turns`. This is useful when the client plans to call
|
||||
* `thread/turns/list` immediately after resuming.
|
||||
*/
|
||||
excludeTurns?: boolean};
|
||||
approvalsReviewer?: ApprovalsReviewer | null, sandbox?: SandboxMode | null, config?: { [key in string]?: JsonValue } | null, baseInstructions?: string | null, developerInstructions?: string | null, personality?: Personality | null};
|
||||
|
||||
@@ -16,8 +16,8 @@ instructionSources: Array<AbsolutePathBuf>, approvalPolicy: AskForApproval, /**
|
||||
* Reviewer currently used for approval requests on this thread.
|
||||
*/
|
||||
approvalsReviewer: ApprovalsReviewer, /**
|
||||
* Legacy sandbox policy retained for compatibility. New clients should use
|
||||
* `permissionProfile` when present as the canonical active permissions
|
||||
* view.
|
||||
* Legacy sandbox policy retained for compatibility. Experimental clients
|
||||
* should prefer `permissionProfile` when they need exact runtime
|
||||
* permissions.
|
||||
*/
|
||||
sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null};
|
||||
|
||||
@@ -16,8 +16,8 @@ instructionSources: Array<AbsolutePathBuf>, approvalPolicy: AskForApproval, /**
|
||||
* Reviewer currently used for approval requests on this thread.
|
||||
*/
|
||||
approvalsReviewer: ApprovalsReviewer, /**
|
||||
* Legacy sandbox policy retained for compatibility. New clients should use
|
||||
* `permissionProfile` when present as the canonical active permissions
|
||||
* view.
|
||||
* Legacy sandbox policy retained for compatibility. Experimental clients
|
||||
* should prefer `permissionProfile` when they need exact runtime
|
||||
* permissions.
|
||||
*/
|
||||
sandbox: SandboxPolicy, reasoningEffort: ReasoningEffort | null};
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// GENERATED CODE! DO NOT MODIFY BY HAND!
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
import type { SortDirection } from "./SortDirection";
|
||||
|
||||
export type ThreadTurnsListParams = { threadId: string,
|
||||
/**
|
||||
* Opaque cursor to pass to the next call to continue after the last turn.
|
||||
*/
|
||||
cursor?: string | null,
|
||||
/**
|
||||
* Optional turn page size.
|
||||
*/
|
||||
limit?: number | null,
|
||||
/**
|
||||
* Optional turn pagination direction; defaults to descending.
|
||||
*/
|
||||
sortDirection?: SortDirection | null, };
|
||||
@@ -1,18 +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 { Turn } from "./Turn";
|
||||
|
||||
export type ThreadTurnsListResponse = { data: Array<Turn>,
|
||||
/**
|
||||
* Opaque cursor to pass to the next call to continue after the last turn.
|
||||
* if None, there are no more turns to return.
|
||||
*/
|
||||
nextCursor: string | null,
|
||||
/**
|
||||
* Opaque cursor to pass as `cursor` when reversing `sortDirection`.
|
||||
* This is only populated when the page contains at least one turn.
|
||||
* Use it with the opposite `sortDirection` to include the anchor turn again
|
||||
* and catch updates to that turn.
|
||||
*/
|
||||
backwardsCursor: string | null, };
|
||||
@@ -4,6 +4,8 @@ export type { Account } from "./Account";
|
||||
export type { AccountLoginCompletedNotification } from "./AccountLoginCompletedNotification";
|
||||
export type { AccountRateLimitsUpdatedNotification } from "./AccountRateLimitsUpdatedNotification";
|
||||
export type { AccountUpdatedNotification } from "./AccountUpdatedNotification";
|
||||
export type { ActivePermissionProfile } from "./ActivePermissionProfile";
|
||||
export type { ActivePermissionProfileModification } from "./ActivePermissionProfileModification";
|
||||
export type { AddCreditsNudgeCreditType } from "./AddCreditsNudgeCreditType";
|
||||
export type { AddCreditsNudgeEmailStatus } from "./AddCreditsNudgeEmailStatus";
|
||||
export type { AdditionalFileSystemPermissions } from "./AdditionalFileSystemPermissions";
|
||||
@@ -152,9 +154,11 @@ export type { GuardianRiskLevel } from "./GuardianRiskLevel";
|
||||
export type { GuardianUserAuthorization } from "./GuardianUserAuthorization";
|
||||
export type { GuardianWarningNotification } from "./GuardianWarningNotification";
|
||||
export type { HookCompletedNotification } from "./HookCompletedNotification";
|
||||
export type { HookErrorInfo } from "./HookErrorInfo";
|
||||
export type { HookEventName } from "./HookEventName";
|
||||
export type { HookExecutionMode } from "./HookExecutionMode";
|
||||
export type { HookHandlerType } from "./HookHandlerType";
|
||||
export type { HookMetadata } from "./HookMetadata";
|
||||
export type { HookMigration } from "./HookMigration";
|
||||
export type { HookOutputEntry } from "./HookOutputEntry";
|
||||
export type { HookOutputEntryKind } from "./HookOutputEntryKind";
|
||||
@@ -164,6 +168,9 @@ export type { HookRunSummary } from "./HookRunSummary";
|
||||
export type { HookScope } from "./HookScope";
|
||||
export type { HookSource } from "./HookSource";
|
||||
export type { HookStartedNotification } from "./HookStartedNotification";
|
||||
export type { HooksListEntry } from "./HooksListEntry";
|
||||
export type { HooksListParams } from "./HooksListParams";
|
||||
export type { HooksListResponse } from "./HooksListResponse";
|
||||
export type { ItemCompletedNotification } from "./ItemCompletedNotification";
|
||||
export type { ItemGuardianApprovalReviewCompletedNotification } from "./ItemGuardianApprovalReviewCompletedNotification";
|
||||
export type { ItemGuardianApprovalReviewStartedNotification } from "./ItemGuardianApprovalReviewStartedNotification";
|
||||
@@ -256,11 +263,14 @@ export type { PatchChangeKind } from "./PatchChangeKind";
|
||||
export type { PermissionGrantScope } from "./PermissionGrantScope";
|
||||
export type { PermissionProfile } from "./PermissionProfile";
|
||||
export type { PermissionProfileFileSystemPermissions } from "./PermissionProfileFileSystemPermissions";
|
||||
export type { PermissionProfileModificationParams } from "./PermissionProfileModificationParams";
|
||||
export type { PermissionProfileNetworkPermissions } from "./PermissionProfileNetworkPermissions";
|
||||
export type { PermissionProfileSelectionParams } from "./PermissionProfileSelectionParams";
|
||||
export type { PermissionsRequestApprovalParams } from "./PermissionsRequestApprovalParams";
|
||||
export type { PermissionsRequestApprovalResponse } from "./PermissionsRequestApprovalResponse";
|
||||
export type { PlanDeltaNotification } from "./PlanDeltaNotification";
|
||||
export type { PluginAuthPolicy } from "./PluginAuthPolicy";
|
||||
export type { PluginAvailability } from "./PluginAvailability";
|
||||
export type { PluginDetail } from "./PluginDetail";
|
||||
export type { PluginInstallParams } from "./PluginInstallParams";
|
||||
export type { PluginInstallPolicy } from "./PluginInstallPolicy";
|
||||
@@ -271,6 +281,15 @@ export type { PluginListResponse } from "./PluginListResponse";
|
||||
export type { PluginMarketplaceEntry } from "./PluginMarketplaceEntry";
|
||||
export type { PluginReadParams } from "./PluginReadParams";
|
||||
export type { PluginReadResponse } from "./PluginReadResponse";
|
||||
export type { PluginShareDeleteParams } from "./PluginShareDeleteParams";
|
||||
export type { PluginShareDeleteResponse } from "./PluginShareDeleteResponse";
|
||||
export type { PluginShareListItem } from "./PluginShareListItem";
|
||||
export type { PluginShareListParams } from "./PluginShareListParams";
|
||||
export type { PluginShareListResponse } from "./PluginShareListResponse";
|
||||
export type { PluginShareSaveParams } from "./PluginShareSaveParams";
|
||||
export type { PluginShareSaveResponse } from "./PluginShareSaveResponse";
|
||||
export type { PluginSkillReadParams } from "./PluginSkillReadParams";
|
||||
export type { PluginSkillReadResponse } from "./PluginSkillReadResponse";
|
||||
export type { PluginSource } from "./PluginSource";
|
||||
export type { PluginSummary } from "./PluginSummary";
|
||||
export type { PluginUninstallParams } from "./PluginUninstallParams";
|
||||
@@ -380,8 +399,6 @@ export type { ThreadStatus } from "./ThreadStatus";
|
||||
export type { ThreadStatusChangedNotification } from "./ThreadStatusChangedNotification";
|
||||
export type { ThreadTokenUsage } from "./ThreadTokenUsage";
|
||||
export type { ThreadTokenUsageUpdatedNotification } from "./ThreadTokenUsageUpdatedNotification";
|
||||
export type { ThreadTurnsListParams } from "./ThreadTurnsListParams";
|
||||
export type { ThreadTurnsListResponse } from "./ThreadTurnsListResponse";
|
||||
export type { ThreadUnarchiveParams } from "./ThreadUnarchiveParams";
|
||||
export type { ThreadUnarchiveResponse } from "./ThreadUnarchiveResponse";
|
||||
export type { ThreadUnarchivedNotification } from "./ThreadUnarchivedNotification";
|
||||
|
||||
@@ -14,6 +14,7 @@ pub use export::generate_ts_with_options;
|
||||
pub use export::generate_types;
|
||||
pub use jsonrpc_lite::*;
|
||||
pub use protocol::common::*;
|
||||
pub use protocol::event_mapping::*;
|
||||
pub use protocol::item_builders::*;
|
||||
pub use protocol::thread_history::*;
|
||||
pub use protocol::v1::ApplyPatchApprovalParams;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user