Expand description
Postgres-backed log writer.
The logs.* schema (defined in schema.sql) is a hybrid:
- Six tier blob tables (request + response × agent / vector / function) store the full chunk body as JSONB. Requests are written once on first chunk arrival; responses get UPDATEd per tick when their body changes.
- Fourteen streaming-content tables carry the per-message,
per-part incrementally-updating content yielded by the SDK’s
chunk-type
log_rows()iterators.
Diff detection: every row written has a deterministic PK shape
(response_id, index[, sub_index]). The writer holds a shadow map
keyed identically and hashes each row’s body columns. Three
verdicts come out: Insert (first sight), Update (changed
body), Skip (unchanged). The SQL helpers in write dispatch
flat INSERT or UPDATE per verdict — no ON CONFLICT ambiguity.
The writer is the sole caller and is single-instance per stream, so the shadow’s verdict is authoritative — concurrent races on the same row id can’t happen.
Structs§
- LogWriter
- Background-task-fronted log writer.
- Session
Lookup - What
lookup_sessionreturns when a prior session exists for the queriedagent_instance_hierarchy. - Shadow
Enums§
- Message
Table - The subset of
RowTablethat produces aobjectiveai.messagesevent row when written. Maps 1:1 to the postgresobjectiveai.message_tableENUM inschema.sql— same names, same order. The three response-blob tables are intentionally absent; they’re not events, just the latest snapshot. - Owned
RowKey - Owned counterpart to
RowKey. Stored in the shadow map. Built only on Insert. - RowBody
- Owned body stored in the shadow map. Compared by
PartialEqagainst an incomingRowValueviaRowValue::body_eq. - RowKey
- Borrowed key that identifies one row’s slot in postgres. Two
RowKeys with equal variant + fields hash identically to anOwnedRowKeywith the matching shape — that invariant lets the shadow’s hashbrownraw_entry_mutlook up by borrowed key without converting to owned first. - RowTable
- Every table in the
logs.*schema, plus the syntheticMessageQueueContentvariant for queue-consumption rows. The latter writes toobjectiveai.messageswith a"table"value chosen at write time via SQL CASE (one ofmessage_queue_text,_image,_audio,_video,_file) — the Rust-side variant is kind-less because the dispatch happens in SQL. - RowValue
- One streaming-content row to INSERT or UPDATE. Borrowed: every
variant lifts string / media payloads from the owning chunk by
reference. Every variant also carries the enclosing chunk’s
agent_instance_hierarchyso the writer can populateobjectiveai.messages.agent_instance_hierarchyand key theobjectiveai.messages_queuedowngrade against the right spawned agent. - Tier
- WriteOp
- What the writer should do with a particular row.
Traits§
- Chunk
Push - CLI-side wrapper exposing the SDK’s intrinsic
push(&mut self, other: &Self)method via a uniform trait. Each impl simply delegates to the chunk type’s inherent method — the SDK already guaranteespushis a correct accumulator for the tier’s cumulative-state semantics. - Writer
Chunk
Functions§
- agent_
completion_ chunk_ rows - Entry: walk an agent-completion chunk’s
messagesand yield every streaming-content row keyed by the chunk’s ownidandagent_instance_hierarchy. - any_
pending_ matching_ kinds - Side-effect-free existence check used by
agents logs read subscribe’s wait loop. Returnstrueiffobjectiveai.messages_queuehas at least one unread row past the watermark for any child ofparent_agent_instance_hierarchywhosem."table"falls inkinds. WhenkindsisNoneor empty, the kind filter is dropped (existence check across all kinds — equivalent to “is there anything pending at all?”). - function_
execution_ chunk_ rows - Entry: walk every task in a function chunk and forward to the matching tier walker. Reasoning summary’s inner agent completion also flows through. Recursive: function tasks chain back into this function.
- insert_
request_ blob - INSERT the request blob. Called once per stream, on first chunk
arrival. Request blobs don’t carry
agent_instance_hierarchy— they’re shared across every agent that participates in the stream. The per-agent “the request was made for me” linkage lives inobjectiveai.messagesand is written separately byinsert_request_messages_rowthe first time each agent appears in the chunk’s row iterator. - insert_
request_ messages_ row - INSERT a
objectiveai.messagesrow that registers this stream’s request blob in the agent’s history. Called once per (stream, agent) pair — the writer tracks which agents it has already seen and only emits this row the first time it encounters a new one in the row iterator. By postgres’s BIGSERIAL"index"assignment, this row is guaranteed to land earlier in the agent’s history than any subsequent streaming-content row that the same writer call sequences after it. - insert_
response_ blob - INSERT the response tier blob (first tick only). Response blobs
don’t emit messages — they’re the latest snapshot, not events.
Tier-symmetric: every tier’s response table now has the same
(response_id, body, created_at, inserted_at)shape. - lookup_
session - Resolve the session for
agent_instance_hierarchy.Ok(None)means there’s no logged request for that hierarchy’s embeddedresponse_id(no prior session). - read_
all_ for_ hierarchy - Materialize every
objectiveai.messagesrow foragent_instance_hierarchy(filtered byafter_id/limit), coalesced intoResponseItemblocks. - read_
by_ id - Resolve one
objectiveai.messages."index"to the matching SDKResponsevariant. ReturnsOk(None)when no row exists at that index. - read_
pending_ for_ parent - Materialize every unread
objectiveai.messagesrow for the children spawned byparent_agent_instance_hierarchy(perobjectiveai.messages_queuewatermarks), coalesced intoResponseItemblocks. Bumps each affected child’sread_indextoGREATEST(current, max_returned)atomically in the same SQL statement. - update_
response_ blob - UPDATE the response tier blob (subsequent ticks).
- vector_
completion_ chunk_ rows - Entry: walk every embedded per-agent completion in a vector chunk
and forward to
agent_completion_chunk_rows. - wait_
for_ logs_ message_ at - Block until the next
objectiveai.messagesINSERT whoseagent_instance_hierarchypayload equalstarget_aih. Mismatching notifications are silently consumed. - write_
agent_ completion - write_
function_ execution - write_
value - Dispatch SQL for
valueperop.Skipis a no-op. - write_
vector_ completion
Type Aliases§
- Rows
Iter - Boxed-iterator alias used at the recursive boundaries (function execution → vector completion → agent completion). One Box per recursive descent, never per leaf row.