Commit Graph
267 Commits
Author SHA1 Message Date
jif 9abfbcea0d Restrict Guardian native multi-agent history to the OpenAI provider (#59737)
## What changed

Require the `openai` provider ID as well as `GuardianNativeMultiAgentHistory` to enable native agent history and review of multi-agent calls. Apply the same check to Guardian prompt construction, collaboration tool registration, and Guardian v2 configuration.

## Testing

Add coverage for fresh and resumed sessions with the feature enabled and disabled on OpenAI, and enabled on Bedrock and LiteLLM. Verify that only OpenAI sessions with the feature enabled request native review and include the agent call as evidence.

GitOrigin-RevId: bfbe547b0544e66763dca7d1e1376f805994bcb2
2026-11-05 20:57:03 +00:00
ioanbudea-OAI 86ac091659 Preserve turn configuration in Guardian scoring and approvals (#59642)
## Why

Guardian scoring and cached approvals need to use the requesting turn's captured policy even when the live thread configuration changes. Newly tightened mandatory review requirements must still prevent cached approvals.

## What changed

- Pass captured turn configuration through tool lifecycle and approval review inputs, and use it to resolve Guardian policy and classifier instructions.
- Apply current reviewer and model requirements before scoring and cached approval, including rechecking restrictions after collecting score authorization.
- Count computer-use JavaScript execution attempts even when background scoring is disabled, so a synchronous call consumes the initial-call allowance.
- Retain runtime configuration snapshots when applying agent role overrides, and share Guardian policy text resolution between configuration loading and runtime publication.

## Testing

Add and extend regression coverage for captured policy instructions, reviewer restrictions, stale cached evidence, and a synchronous computer-use call followed by an adaptive turn.

GitOrigin-RevId: 24ed4a1b6ce1733ad775790f30e440da614f9cd6
2026-11-05 11:41:09 +00:00
Rohan Mehta 41cbd5b9b2 Add per-turn prompt cache TTL options (#59480)
## What changed

- Expose `PromptCacheTtl` through `TurnStartOptions` and `RecoverTurnRequest`, supporting `30m` and `12h` minimum cache lifetimes.
- Carry the selected TTL through turn execution and compaction into `prompt_cache_options.ttl` on Responses HTTP and WebSocket requests. Omit the field when unset and keep the selection scoped to the turn.
- Include prompt cache options in WebSocket request reuse checks.

## Testing

Add coverage for both TTL values and omission on a subsequent turn without an override, and extend WebSocket serialization coverage to include prompt cache options.

GitOrigin-RevId: 8529306e6ad6030fe77c5e6bf19f3810717c0c5e
2026-11-04 19:58:24 +00:00
Ruslan Nigmatullin d84c872464 Route response item IDs through a shared generator (#59312)
## What changed

Introduce `ItemIdGenerator` and pass the runtime-owned generator through sessions, model clients, history, hooks, tool outputs, and memory requests. Keep UUIDv7 generation as the default and replace direct calls to `ResponseItemId::new` with the shared callable.

Preserve existing item IDs and backfill missing or empty IDs through the same generator, including forked history before reconstruction and persistence.

## Testing

Extend coverage for UUIDv7 IDs on user messages, agent messages, and additional tools, and assert that forked model context matches the backfilled items persisted to history.

GitOrigin-RevId: 0dd9ccf0f46f0f1005a6acfc740133b03ce82259
2026-11-04 04:02:00 +00:00
yuning-oai 0ed9d6fa4b Handle budget_reached as a terminal session budget error (#59228)
## What changed

Map provider `budget_reached` errors to `SessionBudgetExceeded` for HTTP 400 responses and streaming failures. End SSE streams immediately on this error, ignoring retry headers and later completion events, and display `budget reached` in the TUI.

## Testing

Add coverage for HTTP error classification, immediate SSE termination without retries, WebSocket error delivery and subsequent request recovery, and TUI error rendering and task-state cleanup.

GitOrigin-RevId: 6a62d699cdb9cb446214cacfacd0c9ed68bf21a6
2026-11-03 21:02:34 +00:00
Dylan Hurd 1f8bf31b8f Use the public managed-features constructor in the guardian config test (#59217)
Update the reviewer configuration test to call
`ManagedFeatures::from_configured_with_warnings` and pass
`parent_config.startup_warnings`, avoiding the crate-private
`from_configured` constructor.

GitOrigin-RevId: 2ba41ba6918e1007b3af013b7146940d919e4560
2026-11-03 19:58:14 +00:00
cooper-oai 079e17a422 Wire shared runtime authentication through threads and API clients (#59177)
## What changed

- Share a lazily registered runtime across threads, model discovery, and extension clients when `runtime_agent_instances` is enabled, while honoring each thread's authentication mode and credential owner.
- Bind model catalogs to the effective provider and authentication context while preserving cache policy and live API-key discovery settings.
- Resolve credentials, routing, and transport policy together for each request. Preserve proxy and TLS settings, validate runtime account selectors, and prevent pooled connections from crossing runtime identities.
- Accept supported ChatGPT subdomains when selecting the registration environment.

## Testing

Add integration coverage for shared runtime registration, dual-header and assertion-only modes, disabled and third-party providers, credential replacement, subagents, and delegated review. Add coverage for catalog cache policy and runtime-aware connection reuse.

GitOrigin-RevId: 99dd9d987c29c93597a648f6586f98ac6a932c3c
2026-11-03 15:02:57 +00:00
felixxia-oai 6163584549 Move Guardian unit tests into their owning crates (#59159)
## What changed

- Move approval-request and prompt-composition tests from `core` to `guardian-reviewer`.
- Move transcript collection, budgeting, and approval-reason truncation tests to `guardian-context`, removing the test-only rendering helper from `core`.
- Move the managed-feature reviewer configuration test to `guardian-v2`.

GitOrigin-RevId: 1886a10cd6aba07b7ca2bcce28d45e0a698111a6
2026-11-03 13:32:14 +00:00
Hung 5a7353f040 Treat audio validation failures as non-retryable input errors (#58434)
## What changed

Map audio size, data, format, and sample-rate validation failures to `InvalidAudioInput` for HTTP 400 responses and streamed errors. Preserve the provider's message, falling back to `Invalid audio input.` when it is absent or blank.

Classify these errors as non-retryable and expose them as `BadRequest`. Redact their messages in doctor diagnostics and group them as invalid requests in telemetry.

## Testing

Add coverage for all six audio validation codes across HTTP errors, streamed `error` events, and `response.failed` events, checking error classification, message preservation, and the absence of retries. Extend doctor diagnostic redaction coverage for `InvalidAudioInput`.

GitOrigin-RevId: 0a59964bcabd83997bdb32fc9318a5482dac33b0
2026-10-30 21:01:23 +00:00
Hung 2546265e3e Add audio file references with explicit runtime rejection (#58430)
## What changed

- Allow audio inputs to carry uploaded file references via `fileId` in the app-server API and `file_id` in model content, preserving existing inline audio shapes and Python class names.
- Preserve mixed inline and file-backed audio ordering through history reconstruction and migration, and budget file-backed audio conservatively when duration is unknown.
- Keep uploaded audio disabled at runtime: reject it before inference or raw history injection, preserve accompanying text, and prevent rejected attachments from reaching follow-up or resumed requests.

## Testing

Add coverage for wire-format round trips, SDK compatibility, mixed audio history ordering, and rejection during turn start, steering, task completion, and raw injection.

GitOrigin-RevId: 70895c47a2494c0c9936348ad1250eb1b7b892a6
2026-10-30 20:53:25 +00:00
ioanbudea-OAI dc40446064 Preserve model metadata origin through runtime resolution (#58361)
## What changed

Return `CatalogModel` from model lookups, keeping metadata together with its `Bundled`, `Provider`, `ExplicitConfig`, or `Synthetic` origin through config overrides and runtime snapshots. Replace `used_fallback_model_metadata` checks with explicit `Synthetic` origin checks.

Share the underlying `Arc<ModelInfo>` with extension stores and use copy-on-write for metadata changes. Keep origin tracking outside serialized model metadata.

## Testing

Extend coverage for origin retention across cache reloads, namespaced model lookups, catalog fallback, and config overrides. Verify that step snapshots and extension stores share the same model metadata allocation.

GitOrigin-RevId: bb6130c94a7a795aa168ee24664a1dd453579fba
2026-10-30 15:11:02 +00:00
jif 9def09afa7 Use serving assessments for adaptive Guardian review (#58075)
## What changed

- Match final serving assessments to their response and output item, then retain them with tool invocations and code cells across waits.
- Use matching assessments instead of asynchronous scoring for adaptive review: low-risk actions can skip synchronous review, while elevated-risk actions require it.
- Revalidate captured authorization and policy before approval. Require fresh review for stale or incomplete authorization, preserve explicit review requirements, and discard assessments when hooks rewrite tool input.
- Keep asynchronous scoring as the fallback when an assessment is missing or does not match.

## Testing

Add integration coverage for direct and nested tool calls, hook rewrites, explicit escalation, interrupted responses, catalog-driven policy, incomplete authorization, and assessment retention across code-cell yields and waits.

GitOrigin-RevId: 4346a227204137f018c03c34b302d6f1e9592c96
2026-10-29 12:54:39 +00:00
ioanbudea-OAI 603a7baff0 Centralize synchronous Guardian context preparation (#57494)
## What changed

- Retain captured root conversation sources until synchronous preparation applies request limits. Keep asynchronous snapshots limited to the bounded messages.
- Move approval-reason truncation and tool-description escaping and truncation from composition into preparation.
- Extract synchronous image preparation and admission into `guardian-context`, preserving the prompt token cap and model context-window checks.

GitOrigin-RevId: d3a864c77d8f16bd3e77df436d80c4d2738c43cc
2026-10-27 15:53:50 +00:00
jif 90de7b92b6 Centralize Guardian classification of multi-agent tool calls (#57455)
## What changed

Add `GuardianScope::for_multi_agent_tool` and use it for both tool review requirements and asynchronous scoring. Classify `spawn_agent`, `send_message`, `followup_task`, and `interrupt_agent` as native tools when they match the configured namespace, accepting default namespace spellings when none is configured. Keep review enablement checks at each call site.

GitOrigin-RevId: 9180ccdc629532f6c171d899dc5881e15b447141
2026-10-27 13:55:51 +00:00
Tom Leach (@toml) 6a6e2fb1f0 Distinguish policy-restricted capacity failures from server overloads (#57452)
## What changed

- Recognize `policy_capacity_unavailable` in HTTP and streaming API errors and expose it as `policyCapacityUnavailable` through the app-server protocol and generated bindings.
- Display “Policy-restricted capacity is unavailable. Please try again later.” while preserving overload retry behavior based on `Retry-After`.
- Handle the new error in TUI overload rendering, reviewer retries, and error telemetry.

## Testing

Add coverage for HTTP and streaming error classification, retry advice, WebSocket terminal error attribution, protocol serialization, and TUI rendering with and without an upstream message.

GitOrigin-RevId: 1b9536fba1e11cc891dcf689aee35410d82f5412
2026-10-27 13:31:38 +00:00
jif 824b7666fb Route state-changing multi-agent calls through Guardian review (#57451)
## What changed

When `GuardianNativeMultiAgentHistory` is enabled, require Guardian review for wrapped Multi-Agent V2 calls to `spawn_agent`, `send_message`, `followup_task`, and `interrupt_agent`.

Include these calls in Guardian's asynchronous native-tool scoring scope, honoring the configured multi-agent namespace and preserving that configuration across overrides.

## Testing

Extend the incremental-review scenario with an encrypted, namespaced `send_message` call. Verify that the encrypted parent reply remains present exactly once in both Guardian reviews and the subsequent agent request, and update the snapshot to cover native tool-call review evidence.

GitOrigin-RevId: 2af9561b0d69af4a8f878fa32365ce845368e02d
2026-10-27 13:21:20 +00:00
jif eec8bde1e9 Preserve native multi-agent calls in Guardian review history (#57448)
## Why

Native multi-agent calls must stay intact for backend decryption during Guardian review.

## What changed

When `guardian_native_multi_agent_history` is enabled for multi-agent v2, preserve `spawn_agent`, `send_message`, `followup_task`, and `interrupt_agent` function calls in the configured tool namespace as native transcript items. Use `functions` when no namespace is configured.

Include the paired evidence-only output in token accounting, and omit native evidence whole when limits require it.

## Testing

Extend transcript tests to cover native call ordering, paired-output budgeting, and whole-item omission. Add a native-history snapshot alongside the existing text-history delegation handoff scenario.

GitOrigin-RevId: e7d9b4f5ea772890bf14b79fdb53b0f9d0a842e4
2026-10-27 13:02:57 +00:00
jif e1dd7ed1ba Preserve Guardian request metadata with custom OpenAI base URLs (#57439)
## Why

Custom OpenAI base URLs caused Codex backend authentication to lose Responses headers and Guardian metadata when the URL did not match a recognized backend route.

## What changed

Apply model-scoped Responses headers, Guardian reviewer and classifier markers, and eligible ChatGPT parent credit requests based on the OpenAI provider and authentication configuration, regardless of the base URL. Keep API-key requests and other providers excluded from this behavior.

## Testing

Extend coverage for custom `/v1` URLs and direct `/api/codex` endpoints with ChatGPT, header-based, and API-key authentication, including HTTP fallback and WebSocket requests.

GitOrigin-RevId: cc4bb5b4a1a6596904ecf8965237c7a4f09e112b
2026-10-27 12:17:14 +00:00
jif ed1b92fa45 Add opt-in synchronous Guardian review for native tool calls (#57433)
## What changed

- Add `CoreToolRuntime::requires_guardian_review` to review opted-in function calls before dispatch and stop execution when review rejects the call.
- Deliver proposed calls as native review evidence, preserving encrypted argument metadata. When hooks rewrite arguments, review the updated arguments and discard the original encrypted replay content.
- Deduplicate native call evidence against reviewer history and include paired evidence outputs in input budgets.
- Keep review accounting and metrics for native calls without emitting action-specific client assessment events, and omit approval payloads from debug output.

## Testing

Extend regression coverage for rewritten native calls across review retries, denied calls that never execute their handlers, oversized native evidence, and review metrics without client events.

GitOrigin-RevId: c3b22c0220344581c2b38f233001abaed49cba34
2026-10-27 11:37:24 +00:00
ioanbudea-OAI 3e9264fb18 Defer synchronous Guardian evidence limits to preparation (#57295)
## What changed

Collect original retained instructions, assistant context, and verified answers before applying synchronous request limits in `guardian-context` preparation. Carry original record sizes through collection, preserving whole-record omission notices, source ordering, and host assistant-context framing.

Apply retained transcript source size checks during synchronous transcript preparation as well.

## Testing

Extend regression assertions for synchronous/asynchronous retained-context parity and equivalent verified-answer omissions when oversized records are filtered during preparation.

GitOrigin-RevId: 9042ee3fe60ebd455f6656b4008efb2acc44ac3d
2026-10-26 22:27:05 +00:00
felixxia-oai 7848e3393c Remove Guardian snapshot-specific context helpers (#56559)
## What changed

Remove snapshot instruction deduplication, separate retained-assistant framing, and the associated omission-metadata special cases. Use `retain_new_instructions` in transcript rendering tests and replace the test-only Decisions snapshot adapter with the conversation adapter.

## Testing

Extend retained-source delivery and incomplete-metadata coverage to both synchronous and asynchronous context profiles. Keep Decisions HTTP, eviction, and cancellation tests exercising the conversation adapter.

GitOrigin-RevId: 3906f7d7349f73931e570ffa649377c3a235317a
2026-10-23 18:50:29 +00:00
felixxia-oai 2d86506823 Exercise retained sampling in Guardian transport tests (#56557)
## Why

The transport tests used a separate, test-only snapshot sampler instead of the production retained sampler, leaving them exercising different response ownership and cancellation paths.

## What changed

Route the transport test helper through `sample_retained` and remove snapshot execution, its active-request supersession bookkeeping, and test-only compaction compatibility fields. Simplify request-token metrics to reflect the remaining admitted-request path.

## Testing

Update tests to verify early score delivery while the retained response remains pending, WebSocket cancellation and connection reuse, and HTTP cancellation before headers or during response draining. Assert that HTTP cancellation releases classification permits.

GitOrigin-RevId: 33250103ff376af6bcd0f81ef27cdcf057f2bc5f
2026-10-23 18:48:35 +00:00
felixxia-oai 4b1cf9a4c9 Use conversations for all Guardian v2 async classification (#56556)
## What changed

- Always use the retained conversation backend for asynchronous classification; keep snapshot sampling test-only.
- Accept legacy `async_classifier_mode` values in configuration and model metadata but ignore them. Emit a startup warning when `[features.guardianv2].async_classifier_mode` is configured.
- Ignore legacy classifier mode differences when checking model-switch compatibility, and fail closed if the conversation backend is missing.

## Testing

Update coverage for legacy configuration warnings, model-switch compatibility, retained approval-review context, and conversation-based scoring.

GitOrigin-RevId: 5e8bb7e4e6e7d1589572f38bfe2498c9fa6825a0
2026-10-23 18:48:10 +00:00
Charlie Marsh 60adfa8513 Treat model-not-found provider errors as terminal failures (#56445)
## Why

Provider errors with code `model_not_found` should end the turn immediately and preserve the provider's message instead of triggering retries.

## What changed

- Recognize `model_not_found` in HTTP 400, 403, and 404 responses and in streamed `error` and `response.failed` events.
- Preserve the provider message and any available HTTP status, and expose `modelNotFound` through the app-server protocol and generated schemas and SDK types.

## Testing

Add coverage for HTTP classification, statusless stream errors, and terminal failures without retries across HTTP, SSE, and WebSocket responses. Verify that `thread/read` preserves the error reported by the live notification.

GitOrigin-RevId: 88f824ac03c8c9669915b1e40c67b76c08326fbe
2026-10-23 11:43:14 +00:00
jif a6839a4812 Skip conversation scoring superseded by newer scores and history (#55913)
## Why

A delayed conversation classification can reach execution after a newer request has already published a score and committed history, leaving it with no useful work to contribute.

## What changed

Pass the classification's sampling timestamp into conversation requests and check for newer scores and retained history before starting inference. Return `Superseded` only when both have advanced; keep requests that can still contribute either a score or history.

## Testing

Add regression tests covering supersession of scores and history separately and together, including a classification delayed by permissions. Verify skipped requests send no inference request and preserve cached scores, approvals, and score progress.

GitOrigin-RevId: ef78a59e2010a82ac4f1fb93568a562447187099
2026-10-21 14:43:51 +00:00
swastik-oai 2f5e242d9f Omit reasoning and compaction from Decisions snapshot comparisons (#55666)
## Why

Decisions snapshot comparisons reject requests containing reasoning or compaction, while conversation comparisons already omit those items. A parent compaction also causes snapshot comparisons to be rejected.

## What changed

- Share filtering of reasoning, compaction, and context compaction across both comparison modes, and ignore parent compaction when building the Decisions request.
- Distinguish malformed request setup from unsupported input items. Record setup errors as failures and unsupported input items as skipped comparisons.

## Testing

Extend the HTTP contract test to cover both comparison modes with reasoning, compaction, context compaction, and parent compaction while preserving message content. Update assertions for the distinct setup and unsupported-input errors.

GitOrigin-RevId: e3ba0cce3b6457b3e3eab3589352b70288cbb1ef
2026-10-20 20:21:14 +00:00
swastik-oai a13ab7e4ed Enable Decisions comparisons for Guardian V2 conversation mode (#55635)
## Why

Guardian V2 previously skipped optional Decisions comparisons in conversation mode as unsupported evidence.

## What changed

- Start comparisons from the prepared conversation input, including retained history or rebuilt evidence after a history reset.
- Extract the classifier rubric and preserve evidence message roles, content order, and boundaries. Omit retained reasoning and compaction items while continuing to reject other unsupported evidence.
- Measure baseline sampling through the usable score, before history draining and commit, and report skipped comparisons when preparation fails or the request is superseded.

## Testing

Extend coverage to both classifier modes for comparison disagreements, failures, and disabled or uninitialized comparisons without changing baseline scores. Verify conversation evidence across history reuse and resets, malformed input rejection, and budget failures before either backend sends a request.

GitOrigin-RevId: ce32cf876d15d3b82e0b83ac02c33447e7724a51
2026-10-20 17:21:31 +00:00
swastik-oai aa081afb1b Refactor Guardian v2 Decisions snapshot comparison (#55623)
## What changed

- Rename the snapshot comparison entry point to `start_snapshot_comparison` and extract request spawning into `spawn_request`.
- Accept a `ContentItem` rubric and an iterator of evidence in the request adapter.
- Read the Decisions comparison feature flag once per classification and simplify the budget rejection test setup.

GitOrigin-RevId: b4a294eeecb6069db0f80ff6e4f13f558cbd7815
2026-10-20 16:31:41 +00:00
ioanbudea-OAI 60d78332fc Measure Guardian approval blocking time per turn (#55591)
## What changed

Record `codex.guardian.turn.blocking_ms` when a turn completes or aborts, with an `outcome` label. Count overlapping approval waits once, exclude idle gaps, and split pending reviews across the active turns they span. Use each turn's telemetry so samples retain the servicing turn's model attribution.

## Testing

Add unit coverage for overlapping waits, idle gaps, late turn completion, and duplicate stops. Extend integration coverage to verify attribution across turns and model changes for yielded command reviews and MCP elicitation, including aborted turns.

GitOrigin-RevId: a3e6a0c32a06fe58ea93119ecd941076100fb82c
2026-10-20 14:43:08 +00:00
swastik-oai 464add4958 Separate Guardian conversation preparation from execution (#55533)
## What changed

Split retained conversation scoring into `Reservation::prepare` and `PreparedConversation::run`, exposing the complete admitted input before model execution. Keep the history fork and capacity permit owned by the prepared conversation, and recheck authorization, score expiry, and backend generation before execution.

## Testing

Extend conversation tests to verify that preparation sends no model request, execution uses the prepared input, dropping a prepared conversation releases capacity, and stale prepared reviews cannot start model execution.

GitOrigin-RevId: c96cc6fac69179a78ecd7bcdb8e5a4b3087aa6e6
2026-10-20 10:52:46 +00:00
jif e645309723 Deduplicate native agent messages in Guardian review context (#55391)
## Why

Full-transcript fallback can select encrypted agent messages already present in the reviewer's history. These duplicates should not consume the input budget or displace new evidence.

## What changed

- Reconcile native agent messages with the effective reviewer history and earlier messages in the pending input before budgeting, including after compaction.
- Deduplicate messages with nonempty IDs while preserving messages without IDs. Allow delivery again when the prior copy is absent from the current history.
- Reject conflicting authors, recipients, or content under the same ID without modifying the pending context.

## Testing

Add coverage for duplicate admission, conflicting payloads, redelivery after history removal, and retained reviewer requests. Extend the history eviction regression to verify that full-transcript fallback reuses the reviewer and preserves a single encrypted agent message.

GitOrigin-RevId: 97e90f6359a7cf5a75d1c5967fc98cd885afb4e4
2026-10-19 22:01:41 +00:00
ioanbudea-OAI eb354a928b Add Guardian review routing and cached score metrics (#55237)
## What changed

- Count adaptive reviews and record synchronous review routes as `async_fallback` or `required_sync`, with the review reason in snake case.
- Record cached score readiness and score age in milliseconds, measured from input sampling time and including inference time.

## Testing

Extend approval tests to assert fallback routing, adaptive review counts, score readiness, and sampled score age.

GitOrigin-RevId: 1200b3297add6c4467e460de87b4a6d8d31e1fc4
2026-10-19 10:22:38 +00:00
ioanbudea-OAI 9dc3a1ce7e Record Guardian sampling retries, attempts, and delivery outcomes (#55234)
## What changed

- Add sampling retry counters that distinguish transport retries from authentication recovery, with failure reasons.
- Record attempt counts and final outcomes for successful, failed, cancelled, and superseded sampling requests.
- Carry retained-score telemetry until the consumer accepts or discards the score, so queued scores that expire are recorded as superseded and accepted early scores remain successful even if response draining fails.

## Testing

Add metric assertions for transient recovery, retry exhaustion, authentication recovery, cancellation, supersession, and retained-score acceptance or discard, including expiry while a score is queued.

GitOrigin-RevId: 36babd6f431f22cf15b73355e6e026a256a81004
2026-10-19 09:48:19 +00:00
ioanbudea-OAI 99f617bf74 Bucket admitted Guardian request metrics by input size (#55226)
## Why

Guardian request counts grouped by input size should reflect admitted sampling inputs without counting synchronous transport retries more than once.

## What changed

- Add a shared `token_bucket` label to admitted total-input observations in `codex.guardian.context.request_tokens` for synchronous and asynchronous reviews. Use inclusive upper bounds in 20k-token steps through 240k, followed by 256k and overflow buckets.
- Record synchronous request tokens after budget admission, once per sampling step, including the complete input. A fresh step counts again even when its input is identical.
- Preserve asynchronous component histograms for oversized classifications, but omit `token_bucket` so rejected inputs do not contribute to counts grouped by that label.

## Testing

Add coverage for bucket boundaries, synchronous retry deduplication and budget rejection, asynchronous retained-history reuse and reset, and admitted versus oversized classification metrics.

GitOrigin-RevId: fac2f102a4c48c5fd21d56bfa701b95a1ff852d0
2026-10-19 09:03:12 +00:00
Charlie Marsh 1cc7dc8f2a Share additional tool declarations across response item clones (#54945)
## Why

Cloning `ResponseItem::AdditionalTools` deep-copies its tool declarations for history and request copies.

## What changed

Store `tools` in an `Arc<[serde_json::Value]>` so clones share immutable declarations. Update constructors and existing test fixtures to use the shared representation.

GitOrigin-RevId: eb8831774afb45fe8431a796f34ae9d1243e884a
2026-10-17 23:17:51 +00:00
pakrym-oai ce0323f2f2 Support typed content in contextual prompt fragments (#54776)
## Why

Contextual fragments and extension-owned world-state sections currently return strings, limiting them to text content.

## What changed

- Return `ContentItem` from fragment bodies and rendering, preserving classification and attribution. Apply text markers only to `InputText`; pass other content through unchanged.
- Allow extension prompt and world-state contributions to carry typed content, and preserve media in context-window hints.
- Hash non-text world-state fragments by their serialized content and role while retaining the existing text hashing behavior.
- Add shared content-to-tool-output conversion that preserves image references, image detail, and audio.

## Testing

Add coverage for typed world-state hashing and preservation of image content and attribution. Expand code-mode output tests to cover input text, output text, file-backed and inline images, and audio.

GitOrigin-RevId: 2ed00d466a3f169b151202f3eef71e667ea64be1
2026-10-17 04:02:21 +00:00
swastik-oai 144779cd24 Preserve evidence message structure in Guardian Decisions requests (#54589)
## Why

The optional Guardian Decisions comparison rejected non-user messages and trusted skill evidence, and folded trusted tool evidence into the classification rubric.

## What changed

Send evidence as separate messages with their original roles, content order, boundaries, and optional `phase`. Support both `input_text` and `output_text`, keeping trusted tool and skill evidence separate from the rubric. Continue to accept inline images only in user messages and reject unsupported evidence.

## Testing

Update adapter and HTTP contract tests to cover mixed message roles and assistant output. Extend lifecycle coverage to verify that trusted skill evidence reaches Decisions while comparison results leave the baseline risk unchanged.

GitOrigin-RevId: 1b6814fe6db5891fb61604d6846a008c9e456054
2026-10-16 12:35:55 +00:00
felixxia-oai 5fff6378d6 Share Guardian image deduplication and checkpoint restoration (#54278)
## What changed

- Add `ComposedContext::retain_new_images` and use it in Guardian review sessions and the async scorer. Compare host-prepared image references against admitted history, ignoring image detail, and skip scanning history when no images need checking.
- Restore `ConversationState` directly from a checkpoint, retaining committed history for rollback or transferring it with `take_history` for ephemeral forks.

## Testing

Extend tests for prepared-image matching across differing detail levels, image-free continuations that avoid scanning history, and checkpoint restoration and history transfer.

GitOrigin-RevId: bafeb6de9babc721182be43d0eb1a653955a0ebb
2026-10-15 12:42:15 +00:00
swastik-oai 1f7fe9b0af Distinguish unsupported evidence in Decisions comparison metrics (#54057)
## Why

Unsupported evidence currently shares a single Decisions comparison reason, making it difficult to distinguish why a comparison was skipped.

## What changed

Report separate reasons for unsupported developer messages, other non-user messages, trusted skills, images, and audio. Keep these outcomes classified as `skipped` and retain the generic reason for other unsupported evidence. Expose `TrustedSkills::KIND` for identifying trusted skill fragments.

## Testing

Expand adapter tests for the distinct rejection reasons and add a lifecycle case verifying that trusted skill evidence skips the Decisions request, reports `trusted_skills`, and preserves the baseline score.

GitOrigin-RevId: 98f076d1aa6771d0209e7f5910eed0dcc40c6263
2026-10-14 17:57:29 +00:00
tongzhou wang 1b6e0d8145 Track content provenance through prompt assembly and compaction (#53831)
## Why

Message roles and content classifications do not identify who supplied each context part. Source attribution needs to survive prompt assembly and history truncation, including messages that combine text from different producers.

## What changed

- Add per-part `ContentItemMetadata` for user input, developer instructions, `AGENTS.md`, skills, harness context, command hooks, and tool context with optional callable namespaces.
- Carry attribution alongside content and classifications through contextual fragments, extension prompts, hook output, and agent messages. Keep tool-provided context-window hints separate from harness text.
- Preserve the source of retained text slices during compaction and attribute generated truncation notices to the harness. Default missing historical attribution to unknown.
- Attribute host MCP calls using cached tool namespaces only when catalog revisions remain stable, without starting servers or refreshing catalogs for attribution.
- Send the new metadata to Responses Lite and strip it from requests to endpoints that do not support it.

## Testing

Extend compaction tests to cover mixed sources, missing or extra metadata entries, and discarded media. Update Responses Lite request assertions to verify endpoint-specific attribution handling.

GitOrigin-RevId: b0ebc929b7c60f3ec49d1affbf897312d63edcc8
2026-10-14 02:01:49 +00:00
felixxia-oai 4d82d36ccf Default Guardian v2 async classification to conversation mode (#53733)
## What changed

Use `conversation` when neither a local `async_classifier_mode` override nor a model default specifies a mode. Keep `snapshot` available as an explicit override and update the configuration documentation and schema to describe the new fallback.

## Testing

Expand configuration tests to cover all local override and model default combinations. Update app-server approval tests to exercise conversation mode without an explicit override, and explicitly select snapshot mode in tests that depend on it.

GitOrigin-RevId: a62479a3f6454bf28d589373a236d8b0ab5023b9
2026-10-13 18:08:10 +00:00
felixxia-oai f6aca7dc46 Cancel Guardian V2 classifications that exceed the tool-call lag window (#53699)
## Why

Pending classifications can outlive the `max_tool_call_lag` window in which their scores are reusable, keeping metadata waits or classifier transports active after the result becomes stale.

## What changed

- Expire pending classifications when tool-call progress exceeds the configured lag allowance, preserving the wrapper discount while nested code-mode actions remain active.
- Cancel metadata waits and sampling in snapshot and conversation modes, including snapshot response drains after an early score.
- Treat expiry as supersession, preserving cached scores and the last completed conversation checkpoint and transcript cursor.

## Testing

Add regression coverage for lag boundaries, active wrapper discounts, transport cancellation before and after early scores, expired requests skipping preparation, and conversation history and transcript deltas surviving cancellation.

GitOrigin-RevId: 892ff13a05fd2b1573cef9842b934d1fc865d951
2026-10-13 15:25:12 +00:00
felixxia-oai ffc1402633 Interrupt and drain canceled classifier responses before socket reuse (#53698)
## Why

Canceled classifier requests need bounded cleanup that preserves received token usage and returns only safe WebSocket connections to the pool.

## What changed

- Own classifier response streams and connection leases together, interrupting dropped responses with a one-second cleanup deadline.
- Require a matching interruption acknowledgement and response completion before reusing a canceled response's socket. Retire sockets on rejection, invalid acknowledgements, or timeout while preserving any received completion and token usage.
- Skip requests canceled before dispatch and return their unused sockets to the pool.
- Distinguish cancellation from ordinary steering, which continues draining without requiring an interruption acknowledgement.

## Testing

Add regression coverage for cancellation, acknowledgement ordering and failures, cleanup timeouts, socket reuse, and token accounting under backpressure. Extend steering tests to cover rejected and missing acknowledgements.

GitOrigin-RevId: c4e7aac49d36cea2c2d0e9f2ba5f6147f67471dd
2026-10-13 15:24:00 +00:00
ioanbudea-OAI 979771476a Account for replay caches in encrypted compaction budgets (#53691)
## Why

Encrypted compaction payloads can include sampled-token replay caches that increase their size roughly threefold. Budgeting them as ordinary text can reject checkpoints that fit the model context budget.

## What changed

Use a shared estimate of one token per twelve ciphertext bytes, rounded up, for encrypted `Compaction` and `ContextCompaction` items in history and Guardian context budgeting. Guardian continues to count framing and metadata separately.

Check parent compactions against the configured token budget and a separate hard wire-size limit. Preserve the complete encrypted checkpoint when it fits. The token estimate remains a heuristic and can underestimate legacy checkpoints without replay caches.

## Testing

Add coverage for token-estimate rounding, parent compaction token and wire-size limits, and reviewer continuation with a cached compaction preserved intact.

GitOrigin-RevId: cc18ca29802491865167eef992830efcf93d97da
2026-10-13 15:05:16 +00:00
swastik-oai 90f00bd89e Add an environment API key fallback for Guardian Decisions (#53633)
## What changed

Allow Guardian Decisions to use `OPENAI_API_KEY` when the default `openai` provider has no custom base URL and neither `CODEX_GUARDIAN_DECISIONS_API_KEY` nor a cached API key is available. Preserve cached API key precedence over the environment fallback.

Report missing credentials as `credentials_unavailable` instead of `provider_error` in Decisions failure metrics.

## Testing

Add tests for cached API key precedence and the environment fallback with ChatGPT authentication. Run each test in a child process to isolate environment changes.

GitOrigin-RevId: fbb772dcb9287d9e1be1b34292ad9bdffeb3d6b3
2026-10-13 10:43:13 +00:00
jif bc9cad3473 Treat incomplete responses as terminal errors (#53451)
## Why

Incomplete responses such as `max_output_tokens` were classified as stream errors, allowing retries and compaction model fallback after the response had hit its output limit.

## What changed

Introduce `ResponseIncomplete` errors that preserve the server-provided reason and stop stream processing immediately. Make these errors non-retryable and stop compaction without falling back to the selected model. Record incomplete responses separately in sampler failure metrics.

## Testing

Add regression tests that verify incomplete responses surface a terminal error without retries over SSE and WebSocket, and that compaction stops without retrying or switching models for both local and remote compaction.

GitOrigin-RevId: 6e107d441b9bf03fa47ea47b88eeb94b71a9f729
2026-10-12 18:53:49 +00:00
ioanbudea-OAI cab328f275 Distinguish Guardian parent-compaction failure reasons (#53393)
## Why

The generic `parent_compaction_error` classification metric does not distinguish serialization failures, oversized compactions, and unusable compactions.

## What changed

Record separate `failure_reason` values for each case: `parent_compaction_serialization`, `parent_compaction_oversized`, and `parent_compaction_unusable`.

## Testing

Extend parent-compaction reuse tests to cover unusable checkpoints in parent-context mode and assert specific failure reasons. Verify rejected compactions receive the maximum risk score, provide no cached approval, and do not reuse stale context.

GitOrigin-RevId: 103c4173b2ebbdc33eb71bce7f8ecb56f73055f6
2026-10-12 14:16:27 +00:00
swastik-oai 27e6192e84 Use cached login credentials for Guardian decisions (#53389)
## Why

Reading `OPENAI_API_KEY` directly bypasses login credentials reloaded by `AuthManager`.

## What changed

Use the API key from `AuthManager`'s cached authentication for Guardian decisions when the provider is `openai` and has no custom base URL. Keep `CODEX_GUARDIAN_DECISIONS_API_KEY` as the highest-priority override.

## Testing

Add a regression test covering a reloaded API-key login, override precedence, and rejection of the login-key fallback for a custom base URL. Assertions avoid printing credentials on failure.

GitOrigin-RevId: 10b2e6c28d3268c3808c25b2be94d9b6c31f597a
2026-10-12 14:08:33 +00:00
pakrym-oai 5ef96ab278 Add opt-in output token replay for OpenAI requests (#52742)
## What changed

- Add the disabled-by-default `output_token_replay` feature to request `output.encrypted_content` from OpenAI providers.
- Preserve encrypted message and tool-call output, message and function-call status, and output-text `annotations` and `logprobs` through history and replay. Update the generated protocol schemas and SDK types.
- Strip output ciphertext from requests to other providers while retaining it in stored history, including after replay is disabled. Remove encrypted content from memory extraction inputs.

## Testing

Add integration coverage for the feature/provider combinations, metadata replay across follow-up requests, and history preservation when resuming with replay disabled.

GitOrigin-RevId: 77729a021b6771933402aebe74ece8eb39c057e2
2026-10-10 01:25:00 +00:00
Dane Schneider 10da569252 Forward per-turn Cyber access programs to Guardian (#52689)
## What changed

Pass the parent turn's `cyber_access_program` to Guardian reviewers and asynchronous classifiers. Use `daybreak_blue` for either Daybreak selection, preserve `standard`, and omit `access_programs` when no program is selected.

Capture the selection with the owning turn so asynchronous observations retain it across later turns. Resolve classifier programs using current authentication and the same provider and API-key feature policy as ordinary model requests.

## Testing

Add regression tests for program changes across reused reviewer sessions with API-key and ChatGPT authentication, snapshot and conversation classifiers at low and high risk, and enabled, disabled, and unsupported-provider API-key policies. Verify parent requests retain their selected program.

GitOrigin-RevId: 447f306df3a6bd6805464b819950690c751b04b4
2026-10-09 20:14:04 +00:00