Commit Graph

18171 Commits

Author SHA1 Message Date
Michael Bolin
86e4e32328 merge commit for archive created by Sapling 2026-07-03 13:04:18 -07:00
Michael Bolin
2057838fdf fix(install): reuse GitHub release metadata 2026-07-03 13:03:42 -07:00
Shijie Rao
da4c8ca57d [codex] Add configurable multi-agent mode hint text (#30493)
## Why

Multi-agent V2 normally derives its mode instructions from reasoning
effort: Ultra enables proactive delegation, while other efforts require
an explicit request. Some deployments need to provide one configured
delegation policy that replaces those built-ins and remains stable when
reasoning effort changes.

## What changed

- Add `features.multi_agent_v2.multi_agent_mode_hint_text` alongside the
existing root and subagent hint settings.
- Treat any configured value, including an empty string, as
`MultiAgentMode::Custom(hint_text)`, so the configured text replaces the
built-in explicit-only and proactive policies.
- Persist the full custom variant and hint text in the turn-context
snapshot, so the durable comparison baseline detects both
reasoning-effort changes and configured policy-text changes.
- Preserve the existing explicit-only/proactive behavior when the
setting is absent.
- Replace the ambiguous `MultiAgentMode::None` variant with
`MultiAgentMode::Custom(String)` in new rollouts and API schemas. A
compatibility wire type maps legacy serialized `none` values to
`Custom("")` when resuming existing rollouts.
- Regenerate the config and app-server schemas.

## Configuration examples

The distinction is whether `multi_agent_mode_hint_text` is present. An
empty string is still a configured value and intentionally suppresses
the built-in mode instructions.

### Unset: preserve existing effort-derived behavior

```toml
[features.multi_agent_v2]
enabled = true
# multi_agent_mode_hint_text is omitted
```

- Ultra reasoning uses the built-in proactive delegation instructions.
- Other reasoning efforts use the built-in explicit-request-only
instructions.

### Empty: suppress all mode hint text

```toml
[features.multi_agent_v2]
enabled = true
multi_agent_mode_hint_text = ""
```

This selects effective mode `custom` at every reasoning effort and
injects an empty mode body, suppressing both built-in policies.

### Set: always use the configured text

```toml
[features.multi_agent_v2]
enabled = true
multi_agent_mode_hint_text = "Delegate to subagents when it will materially improve the result."
```

This selects effective mode `custom` at every reasoning effort and
injects the configured text verbatim instead of either built-in policy.

## Verification

- `just test -p codex-core multi_agent_mode`
- Covers a configured hint across High and Ultra reasoning efforts and
verifies the full custom hint is recorded for both turns.
- Covers an empty-string override suppressing both built-in instruction
bodies.
- `just test -p codex-protocol -p codex-app-server-protocol`
- Covers legacy `none` turn-context deserialization as `Custom("")` and
verifies the regenerated schemas.
2026-07-02 18:44:34 -07:00
Michael Bolin
beca198b8a telemetry: log structured direct tool-call timing (#30334)
## Why

App-server deployments can consume structured JSON logs for operational
measurements without requiring an OTEL exporter. Existing tool-result
telemetry reports the handler outcome, but it does not separate time
spent waiting to dispatch from time spent executing the handler.

A compact completion event for the outer, direct tool call lets
consumers measure those phases and correlate them with a conversation
and turn. Code-mode calls are intentionally excluded so nested runtime
calls do not create overlapping events that are easy to double-count.

## What changed

- Added a
[`ToolCallTimingGuard`](141110a73c/codex-rs/core/src/tools/parallel.rs (L32))
around direct tool calls. Event-only strings and timing state are
captured only when the `codex_core::tools::parallel` `INFO` target is
enabled.
- Added a
[`codex.tool_call`](141110a73c/codex-rs/core/src/tools/parallel.rs (L313))
completion event with conversation, turn, tool, call, trace, dispatch,
handler, and total timing fields.
- Recorded the execution-start marker after the dispatch lock is
acquired. Event emission snapshots that marker once so a concurrently
starting dispatch cannot produce internally inconsistent fields.
- Limited the event to `ToolCallSource::Direct`; [unit
coverage](141110a73c/codex-rs/core/src/tools/parallel.rs (L365))
verifies code-mode calls are ignored.
- Added [cancellation
coverage](141110a73c/codex-rs/core/src/tools/parallel.rs (L408))
that holds the execution gate and verifies a call cancelled before
admission emits exactly one dispatch-only timing event.
- Added reusable
[`JsonLogCapture`](141110a73c/codex-rs/app-server/tests/common/json_logging.rs (L15))
support, a [JSON-logging-specific `TestAppServer`
constructor](141110a73c/codex-rs/app-server/tests/common/test_app_server.rs (L172)),
and an [end-to-end app-server
test](141110a73c/codex-rs/app-server/tests/suite/logging.rs (L52))
that drives a direct `exec_command` through the public v2 JSON-RPC API
and validates the emitted JSON event.

Exec-server-specific request and process timing remains in the stacked
PR #30901.

## Suggested logging filter

```bash
LOG_FORMAT=json \
RUST_LOG='warn,codex_core::tools::parallel=info' \
codex app-server
```

## Event example

Identifier and timing values are illustrative.

### `codex.tool_call`

```json
{
  "timestamp": "2026-06-27T03:45:20.443Z",
  "level": "INFO",
  "fields": {
    "message": "tool call completed",
    "event.name": "codex.tool_call",
    "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
    "conversation.id": "67e55044-10b1-426f-9247-bb680e5fe0c8",
    "turn_id": "019f04f8-6ac2-78f1-8625-f04a6d35af18",
    "tool_name": "exec_command",
    "call_id": "call_7b8483",
    "tool_source": "direct",
    "execution_started": true,
    "dispatch_duration_ms": 12,
    "handler_duration_ms": 431,
    "total_duration_ms": 443
  },
  "target": "codex_core::tools::parallel"
}
```

If execution never starts, `execution_started` is `false`,
`handler_duration_ms` is `0`, and `dispatch_duration_ms` covers the full
observed lifetime.

If a duration cannot be represented as an unsigned 64-bit millisecond
value, all three duration fields are omitted rather than populated with
a sentinel that could corrupt downstream calculations.

## Test plan

- `just test -p codex-core
tool_call_timing_guard_ignores_code_mode_source`
- `just test -p codex-core
cancellation_before_dispatch_admission_logs_dispatch_only_timing`
- `just test -p codex-app-server
app_server_emits_structured_tool_call_timing_event`

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/30334).
* __->__ #30334
2026-07-02 13:53:56 -07:00
Dylan Hurd
b35d4b6b9d fix(websockets) ignore metadata for incremental requests (#30770)
## Summary
The Responses API may or may not send back metadata on response items.
So when comparing request data to the last response, we should discard
it and only consider the content. This change results in a higher
success rate of incremental requests.

Notably, there is one subtle change to the behavior here - we are
now ignoring metadata when comparing the previous request items to the
new request items as well. This should be fine, since the metadata is
explicitly out of scope for the comparison, regardless of whether the
item is an item from the request or response.

## Testing
- [x] Added unit test coverage for both cases of metadata existence and
absence.
2026-07-02 13:33:28 -07:00
Michael Bolin
567ca5b638 Merge 141110a73c into sapling-pr-archive-bolinfest 2026-07-02 13:22:24 -07:00
Michael Bolin
141110a73c telemetry: log structured tool and inference timing events 2026-07-02 13:22:10 -07:00
Michael Bolin
7d416365a7 Merge 38d7926725 into sapling-pr-archive-bolinfest 2026-07-02 13:12:18 -07:00
Michael Bolin
38d7926725 telemetry: log structured tool and inference timing events 2026-07-02 13:12:08 -07:00
Michael Bolin
e1425a5939 merge commit for archive created by Sapling 2026-07-02 13:08:03 -07:00
Michael Bolin
26ac654c05 telemetry: log structured tool and inference timing events 2026-07-02 13:07:52 -07:00
Michael Bolin
ec5ad8a17f merge commit for archive created by Sapling 2026-07-02 11:28:23 -07:00
Michael Bolin
bb7c083fff telemetry: log structured tool and inference timing events 2026-07-02 11:28:12 -07:00
Michael Bolin
c4fa8164d4 merge commit for archive created by Sapling 2026-07-02 11:16:55 -07:00
Michael Bolin
04de4bbe39 telemetry: log structured tool and inference timing events 2026-07-02 11:16:45 -07:00
Michael Bolin
4d3cb65095 merge commit for archive created by Sapling 2026-07-02 11:09:27 -07:00
Michael Bolin
e3f05310da telemetry: log structured tool and inference timing events 2026-07-02 11:09:02 -07:00
Michael Bolin
e06cf4ec33 Merge af8b746ccf into sapling-pr-archive-bolinfest 2026-07-02 10:59:59 -07:00
Michael Bolin
af8b746ccf telemetry: log structured tool and inference timing events 2026-07-02 10:59:52 -07:00
Michael Bolin
0ccb676dd0 fix: address quick-xml security advisories (#30941)
## Why

The `cargo-deny` job on `main` began failing after
[RUSTSEC-2026-0194](https://rustsec.org/advisories/RUSTSEC-2026-0194)
and
[RUSTSEC-2026-0195](https://rustsec.org/advisories/RUSTSEC-2026-0195)
flagged the workspace `quick-xml 0.38.4`. Both denial-of-service issues
are fixed in `quick-xml 0.41.0`.

A `quick-xml 0.39.4` copy must temporarily remain because the latest
`plist` and `wayland-scanner` releases have not adopted 0.41 yet.
Neither retained path accepts attacker-controlled XML at runtime:
`plist` does not exercise the affected APIs, and `wayland-scanner`
parses trusted protocol definitions at build time. Compatible upstream
bumps are already open in
[rust-plist#191](https://github.com/ebarnard/rust-plist/pull/191) and
[wayland-rs#938](https://github.com/Smithay/wayland-rs/pull/938).

## What changed

- Upgrade the workspace `quick-xml` dependency used by `codex-protocol`
to 0.41.0.
- Refresh `Cargo.lock` and `MODULE.bazel.lock`; this also updates
`plist` to 1.9.0 and `wayland-scanner` to 0.31.10.
- Add synchronized, temporary `cargo-deny` and `cargo-audit` exceptions
for the trusted `quick-xml 0.39.4` paths, with both upstream releases
recorded as the removal condition.

## Testing

- `cargo deny check`
- `just test -p codex-protocol` (238 tests)
- `just bazel-lock-check`
2026-07-02 10:59:00 -07:00
Michael Bolin
a6a4230b98 merge commit for archive created by Sapling 2026-07-02 10:55:29 -07:00
npancha-openai
38006a282e [codex] telemetry: narrow structured tool call timing (#30911)
## Summary

- restore the existing `codex.tool_result` behavior and remove the added
`codex.inference` event
- emit `codex.tool_call` timing events only for direct tool calls
- snapshot the execution-start marker once when emitting
`codex.tool_call` so a concurrent dispatch start cannot produce
internally inconsistent timing fields

## Why

This keeps the stacked change focused on direct tool-call timing without
expanding result or inference telemetry. The timing-marker fix addresses
repeated reads of the marker during event emission, which could
otherwise observe different states if dispatch begins concurrently.

## Validation

- `just fmt`
- `git diff --check HEAD~3..HEAD`
- `just test -p codex-core
tool_call_timing_guard_ignores_code_mode_source`
- `just test -p codex-app-server
app_server_emits_structured_tool_call_timing_event`
- `just test -p codex-otel
otel_export_routing_policy_routes_tool_result_log_and_trace_events`

I also attempted `just test -p codex-core -p codex-otel -p
codex-app-server`; that broader run was not completed after multiple
app-server tests timed out.
2026-07-02 10:55:05 -07:00
Michael Bolin
1adf6c71b0 telemetry: log structured tool and inference timing events 2026-07-02 10:55:05 -07:00
Michael Bolin
38034a6526 Merge 038c8d9fea into sapling-pr-archive-bolinfest 2026-07-02 10:54:31 -07:00
Michael Bolin
038c8d9fea fix: address quick-xml security advisories 2026-07-02 10:54:13 -07:00
Shijie Rao
cbdd7f0047 Fix inherited availability metadata for Bedrock models (#30897)
## Why

Amazon Bedrock's static catalog derives its GPT model definitions from
bundled OpenAI model metadata. The GPT-5.6 variants introduced in #30285
clone GPT-5.5, which carries an `availability_nux`; because app-server
forwards that metadata through `model/list`, clients can show GPT-5.5
launch copy for a GPT-5.6 Bedrock model.

`upgrade` is also model-catalog availability metadata and should not be
inherited by provider-specific Bedrock models.

## What changed

- Clear `availability_nux` and `upgrade` when constructing static
Bedrock GPT models.
- Add a regression test asserting that every static Bedrock model omits
both fields.

## Testing

- `just test -p codex-model-provider`
2026-07-02 10:01:06 -07:00
xli-oai
6ff670bd03 [codex] emit per-request TTFT completion telemetry (#30883)
## Why

Codex telemetry pipeline needs a per-request TTFT value. The existing
`codex.turn_ttft` is recorded once per turn, so it cannot represent
later inference requests in the same turn and can miss the beginning of
hidden reasoning.

This restores the low-volume per-request signal proposed in
https://github.com/bk-nvidia/codex/pull/3 without bringing back
per-WebSocket-event TRACE logging.

## What changed

- start a timer when each mapped Responses stream begins
- latch the timer on the first `response.output_item.added`, including
an empty hidden-reasoning item
- attach `ttft_ms` to the existing `codex.sse_event` /
`response.completed` telemetry record
- cover the new completion field with an integration test

## Semantics

The value is per inference request, not per turn. It measures
mapped-stream-to-first-output-item latency, matching the
customer-proposed metric. For HTTP, the stream is already established
before timing begins, so request setup and response-header latency are
excluded.

`response.output_item.added` is a client-visible proxy for the start of
hidden reasoning; this does not claim access to the server's internal
first raw-token timestamp.

## Validation

- `just test -p codex-otel` (47 passed)
- `just test -p codex-core process_sse_emits_completed_telemetry` (1
passed after the final timer-placement change)
- attempted `just test -p codex-core`: 2,855 passed and 53 failed
because of unrelated local-environment failures (missing
`test_stdio_server` fixture binary, shell startup noise, and
timing-sensitive tests); the focused telemetry test passed in that run
as well
2026-07-02 04:45:03 -07:00
Michael Bolin
6aaca8ca40 merge commit for archive created by Sapling 2026-07-01 22:58:40 -07:00
Michael Bolin
8b6f7077be exec-server: log structured timing events 2026-07-01 22:56:14 -07:00
Michael Bolin
c899466b7d telemetry: log structured tool and inference timing events 2026-07-01 22:56:14 -07:00
Michael Bolin
77d79135d0 merge commit for archive created by Sapling 2026-07-01 22:42:06 -07:00
Michael Bolin
441a453cc1 exec-server: log structured timing events 2026-07-01 22:40:53 -07:00
Michael Bolin
39af213361 telemetry: log structured tool and inference timing events 2026-07-01 22:40:44 -07:00
Michael Bolin
b0dc58a2c1 Merge f530914a54 into sapling-pr-archive-bolinfest 2026-07-01 22:14:43 -07:00
Michael Bolin
f530914a54 telemetry: log structured tool timing events 2026-07-01 22:14:36 -07:00
Michael Bolin
129ea2aaf5 Log multi-agent communication lifecycle (#30872)
## Why

[#30867](https://github.com/openai/codex/pull/30867) makes
`submit_inter_agent_communication` the common outbound sink for
multi-agent v2 communications. This follow-up uses that single point to
log every communication lifecycle without requiring new hooks as spawn,
messaging, follow-up, or result paths evolve.

For each communication, the logs need to identify its type, sender and
receiver threads, and content, while correlating the successful send
with receipt by the destination mailbox. The logging path must not query
externally supplied time providers because those calls can be expensive
for app-server clients.

## What changed

- Added structured `INFO` events on the OpenTelemetry-exported
`codex_otel.agent_communication` target for `spawn`, `message`,
`followup`, and `result` communications.
- Logged successful sends from `submit_inter_agent_communication` with
the communication kind, sender and receiver thread IDs, content, and
submission ID.
- Logged receives after the communication has been enqueued in the
receiver mailbox, using the same submission ID.
- Avoided time-provider calls and other asynchronous work in the logging
path.
- Narrowed ordinary spawn and send-input APIs to `Vec<UserInput>` so
`Op::InterAgentCommunication` cannot bypass the context-bearing
centralized path.

The refactor does not change submission IDs, capacity checks, last-task
bookkeeping, mailbox ordering, protocol types, rollout data, or
model-visible context.

## Event shape

Illustrative JSON representation of the two independently emitted
records:

```json
[
  {
    "event.name": "codex.agent_communication",
    "communication_id": "019f20e1-40d1-7890-a123-456789abcdef",
    "kind": "spawn",
    "state": "send",
    "sender_thread_id": "019f20df-fbe1-7890-a123-456789abcdef",
    "receiver_thread_id": "019f20e1-3f79-7890-a123-456789abcdef",
    "content": "inspect the repository"
  },
  {
    "event.name": "codex.agent_communication",
    "communication_id": "019f20e1-40d1-7890-a123-456789abcdef",
    "state": "receive"
  }
]
```

Consumers join the receive record to the send record by
`communication_id` for the immutable communication metadata.

## Testing

- Extended the existing end-to-end multi-agent v2 spawn test to verify
content, both thread IDs, and a correlated send/receive submission ID.
- Re-ran focused control and handler coverage for direct messages,
follow-up tasks, and completion results.
2026-07-01 18:11:09 -07:00
Michael Bolin
7245964ad8 merge commit for archive created by Sapling 2026-07-01 17:51:23 -07:00
Michael Bolin
2af759b764 Log multi-agent communication lifecycle 2026-07-01 17:51:10 -07:00
Michael Bolin
a0e6052ed1 Merge be18a5e07f into sapling-pr-archive-bolinfest 2026-07-01 17:38:46 -07:00
Michael Bolin
be18a5e07f Log multi-agent communication lifecycle 2026-07-01 17:38:37 -07:00
Michael Bolin
2fd8feb389 Merge 4123e516f3 into sapling-pr-archive-bolinfest 2026-07-01 17:33:18 -07:00
Michael Bolin
4123e516f3 Log multi-agent communication lifecycle 2026-07-01 17:33:11 -07:00
Michael Bolin
4cc5b85972 merge commit for archive created by Sapling 2026-07-01 17:19:14 -07:00
Michael Bolin
5a2bbd4b2e Log multi-agent communication lifecycle 2026-07-01 17:19:03 -07:00
Michael Bolin
83044192b8 Merge 64280aa283 into sapling-pr-archive-bolinfest 2026-07-01 17:08:45 -07:00
Michael Bolin
64280aa283 Log multi-agent communication lifecycle 2026-07-01 17:08:27 -07:00
Michael Bolin
a98a21798c Consolidate multi-agent v2 communication sends (#30867)
## Why

Multi-agent v2 communications currently use separate outbound paths:
direct messages, follow-up tasks, and completion results go through
`send_inter_agent_communication`, while a spawn's initial message goes
through the generic input submission path. That split makes it difficult
to add complete communication lifecycle logging in one place.

This refactor makes `submit_inter_agent_communication` the common sink
for those paths, preparing the follow-up observability work discussed in
[#30516](https://github.com/openai/codex/pull/30516).

## What changed

- Routed all current outbound `InterAgentCommunication` paths in
`AgentControl`—direct messages, follow-up tasks, completion results, and
multi-agent v2 spawn initial messages—through
`submit_inter_agent_communication`.
- Centralized the actual submission and last-task-message bookkeeping
there, providing one place for the follow-up PR to instrument
communication creation and successful enqueue.
- Left non-communication input handling and the multi-agent v1 spawn
flow unchanged.

## Testing

- `just test -p codex-core 'agent::control::tests::'` (51 passed)
- `just test -p codex-core
'suite::subagent_notifications::encrypted_multi_agent_v2_spawn_sends_agent_message_to_child'`
(passed)








---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/30867).
* #30872
* __->__ #30867
2026-07-01 17:08:11 -07:00
Michael Bolin
9b09317904 merge commit for archive created by Sapling 2026-07-01 16:36:30 -07:00
Michael Bolin
82ed1d2426 Log multi-agent communication lifecycle 2026-07-01 16:36:21 -07:00
Michael Bolin
9268f6b90e merge commit for archive created by Sapling 2026-07-01 16:11:24 -07:00