mirror of
https://github.com/openai/codex.git
synced 2026-11-07 20:30:33 +00:00
## Why `Attach` delivers live events only. Clients also need access to stored turn metadata and item content. ## What changed - Add `Client::list_turns` and `Client::list_items` using native gRPC history endpoints, with optional turn filtering for items. - Expose page limits, sort order, access mode, and forward/backward cursors. Each call returns one page in server order without automatic pagination or retries. - Preserve raw response and row payloads alongside typed summaries and item timestamps. Retain unknown item variants and command sources without typed summaries. - Document cursor reuse and history/live overlap: history pages do not provide an atomic boundary with `Attach`, and coordinated reconciliation still requires caller-managed state. ## Testing Add wire-fixture tests for request encoding, explicit pagination, raw payload preservation, unknown data, malformed rows, empty pages, RPC errors without retries, and diagnostic redaction. GitOrigin-RevId: f507530b8e431236bc7e19d867517af56f74644f
62 lines
3.8 KiB
Markdown
62 lines
3.8 KiB
Markdown
# Codex cloud client
|
|
|
|
Reusable Rust client for native ThreadService gRPC over HTTP/2, with no TUI,
|
|
conventional app-server or private monorepo dependency. This slice supports
|
|
`Resume` and live `Attach`. It does not use the HTTP `/grpc` JSON gateway.
|
|
|
|
The caller supplies a trusted native gRPC origin (scheme/host/port, no path),
|
|
ChatGPT bearer token, selected account ID and configured `HttpClientFactory`.
|
|
HTTPS is required except for direct loopback HTTP with an unrestricted, unmanaged
|
|
factory. This exception bypasses proxies to keep plaintext credentials local.
|
|
For HTTPS, the shared HTTP client supplies proxy,
|
|
custom CA and network policy handling; redirects are rejected. Tonic supplies
|
|
gRPC framing, protobuf encoding, message bounds (64 MiB) and status/trailer handling.
|
|
Bind factory policy before loading credentials; rebuild on login/account changes.
|
|
|
|
`ResumeRequest.wait = false` acknowledges admission, not readiness. Requests are
|
|
never retried by this crate: a timeout or disconnect can leave work admitted.
|
|
`Attach` has no history snapshot or replay guarantee. Dropping it detaches without
|
|
stopping the thread or answering approvals. Streams end after their first error.
|
|
Resume and Attach setup have a 150-second local deadline; live streams have no idle
|
|
deadline. Setup does not send a gRPC deadline that would expire a healthy stream.
|
|
|
|
`Event::Transcript` decodes selected text, command output, patch, and turn updates.
|
|
It validates the thread ID and exposes the decoded fields. Turn updates include
|
|
start time, completion time, and duration when the server provides them.
|
|
Other notifications and server requests remain opaque protobuf payloads, preserving
|
|
unknown fields. These are not ProtoJSON or app-server JSON-RPC. Native status
|
|
code, message and binary details are available explicitly; credentials, event
|
|
and error diagnostics are redacted. Item lifecycle updates report supported
|
|
message, command, and file-change summaries. Agent message summaries retain
|
|
structured questions even when their text is empty. Unsupported item kinds stay opaque.
|
|
Approval replies and reconnect are subsequent slices.
|
|
The minimal envelopes in `wire.rs` and `ResumeRequest` mirror ThreadService field
|
|
numbers; no monorepo checkout or protobuf compiler is required to build this crate.
|
|
|
|
Provide `CODEX_CLOUD_ACCESS_TOKEN` and `CODEX_CLOUD_ACCOUNT_ID` through your environment, then run
|
|
this standalone consumer from `codex-rs`:
|
|
|
|
```sh
|
|
cargo run -p codex-cloud-client --example attach -- "$CODEX_CLOUD_GRPC_ENDPOINT" "$CODEX_CLOUD_THREAD_ID"
|
|
```
|
|
|
|
Use an existing authorized thread and native gRPC origin. No production URL is
|
|
assumed. Public native ingress is a rollout assumption, not proved by fixture
|
|
tests. This change does not publish a package to a registry.
|
|
|
|
History reads use native `ListTurns` (stored turn metadata) and `ListItems` (one
|
|
turn or the whole thread). Calls return one page with forward/backward opaque
|
|
cursors, preserve server order and retain raw responses and rows. Reuse a cursor
|
|
with the same account, thread and filters. Keep the sort order for `next_cursor`
|
|
and reverse it for `backwards_cursor`. Calls never paginate or retry automatically.
|
|
Items with an unknown variant or command source remain in the page with no typed summary.
|
|
|
|
History pages and Attach have no shared revision or replay cursor. A page is not
|
|
an atomic history/live boundary, and timestamps are not event offsets. Do not
|
|
append buffered deltas to a fetched snapshot: it may already include that text.
|
|
Full item snapshots can replace matching account/host/thread/turn/item identities;
|
|
they must not create duplicate transcript rows. Disconnects, untyped recovery
|
|
notifications and uncertain overlap require authoritative history reload. This
|
|
crate exposes the read primitives; a coordinated resync/display state machine is
|
|
still required before claiming lossless resume or live/history reconciliation.
|