Documentation
¶
Overview ¶
Package transcript renders a session's event log as text a model reads. Two renderers live here over the same log: Render, the outcome grader's role-labelled plain text (plan 21 slice 3), and RenderDream, the streamed, redacted, capped markdown a dream's stages read (plan 41 §3.2). It sits outside internal/brain because both the brain and the controlplane's dream runner import it, and it depends on internal/domain and internal/events alone — nothing here may reach for a provider, a store or an HTTP layer.
Index ¶
Constants ¶
const ( // GraderTranscriptBudget caps the rendered transcript handed to the // grader; the head is kept and a truncation note marks the cut (ours). GraderTranscriptBudget = 200_000 // GraderItemBudget caps any single transcript item (a tool result can be // 100 KiB on its own; the grader needs the shape, not every byte). GraderItemBudget = 4_000 )
const ( // DreamPageSize is the keyset page the renderer pulls. Large enough that a // long session is not a thousand round trips, small enough that one page // of tool results is not itself the memory bound the cap exists to hold. DreamPageSize = 200 )
Variables ¶
var DreamTranscriptCap = 24 << 10
DreamTranscriptCap bounds one rendered transcript, so a hundred of them are at most 2.4 MiB — the per-dream bound (§3.2). The head kept and the rolling tail are each half of it, which is what makes it a memory bound and not just an output length: a test that lowers the cap sees both buffers shrink with it. A var, not a const, for that test (memoryPruneInterval's idiom); nothing in production writes it.
Functions ¶
func ContentText ¶
ContentText flattens an event body's content — a string or a block array — into plain text for the transcript.
func FlattenBlocks ¶
func FlattenBlocks(raw json.RawMessage) (string, bool)
FlattenBlocks renders a content-block array as plain text. Most blocks carry their text at the top level; a search_result block carries its evidence as title + source + nested text blocks, so those flatten too — web_search answers would otherwise vanish from the transcript.
func IndexLine ¶
IndexLine is one INDEX.md row (§3.1): seq · session_id · created_at · turns · rendered_bytes · the first user message. What the cap elided is named in the bytes column rather than appended, so the one free-text field stays last and a "·" inside a user's message cannot look like another column.
func Redact ¶
Redact replaces the four secret shapes with "[REDACTED_SECRET]": an sk- key, an AKIA access key id, a Bearer token, and an api_key/token/secret/password assignment with either separator. Fixed in code, not configurable — a knob here is a way to leak a credential into a memory store (§3.2).
It is best-effort by construction: a shape pattern cannot know a private key, a cookie, a connection string or an opaque token from prose, which is why internal/provider/redact.go redacts by known value instead — that redactor holds the credential it is removing, and a dream's renderer holds none. What backs this is the clone by default and the completion scan, not the pattern list.
func Render ¶
Render renders the session's conversation-bearing events as the role-labeled plain text the grader reads (shape ours, INFERRED). Long items truncate at GraderItemBudget; the whole transcript at GraderTranscriptBudget.
The agent-to-agent message pair (plan 35) is deliberately not rendered. The grader reads the whole session rather than one thread, so a child's report is already here as that child's own submit_result call, and rendering the coordinator's copy of it would put the same text in twice. RenderDream keeps the received half, because it reads the session view alone (§3.2).
Types ¶
type Dream ¶
type Dream struct {
SessionID string
Text []byte // the rendered markdown: redacted, per-event truncated, capped
Turns int // user.message events kept (the INDEX.md "turns" column)
ElidedBytes int // bytes the per-transcript cap removed; 0 when the cap was not hit
FirstUser string // the first user message's text, redacted, one line, ≤ 200 runes
}
Dream is one input session rendered for a dream.
func RenderDream ¶
RenderDream streams the session's log in pages of DreamPageSize through log.List with Scope events.ScopeSession and the AfterSeq keyset, renders and redacts each event as it arrives, and keeps only a head and a rolling tail of half DreamTranscriptCap each — peak memory is the cap whatever the log's length.
The scope is the coordinator's view: its primary thread's rows plus the ones a child cross-posted. Per-thread logs are not expanded, so a delegated task reads as the report that came back (§3.2).