## Why Attach notifications previously exposed only opaque protobuf bytes. Typed transcript events let callers access live text, command output, file changes, and turn state directly. ## What changed - Add `Event::Transcript` with typed agent-message, command-output, and file-change deltas; patch updates; and turn start/completion events. - Expose patch kinds and move paths, turn status and failure details, and server-provided timestamps and duration. - Validate transcript thread IDs. Preserve unsupported or incomplete notifications and other threads' turn lifecycle events as opaque payloads; reject deltas for another thread. - Keep transcript payloads redacted in `Debug` output. ## Testing Add independent protobuf fixtures covering Attach decoding, opaque fallback and stream continuation, patch ordering, turn timing and failures, thread validation, repeated oneof variants, unknown fields, and debug redaction. GitOrigin-RevId: f26b8d4a5b355bb12159136e83310cb57c1546ca
2.5 KiB
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. History, 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:
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.