Help us shape the future of Go! Take the 2026 Go Developer Survey

transcript

package
v0.51.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 21, 2026 License: Apache-2.0, MIT Imports: 6 Imported by: 0

Documentation

Overview

Package transcript renders a session's span projection as one readable conversation: the user's words and the assistant's replies, in the order they happened, with the harness's own traffic left out.

The projection already carries everything a transcript needs. An llm span's Input holds only the content blocks NEW to that call (never the re-sent history) and its Output is the model's reply, so walking the conversation-spine llm calls in presentation order yields each message exactly once. Tool results are not on the llm span that consumed them; they live on the tool span the deriver opened for each tool_use, which the deriver emits right after the call that requested it. A Walker folds a run of those tool spans into one user row, the same place the results sit on the wire.

What is left out is what the deriver classified as not conversation: offshoot calls (permission checks, title generation, suggestions), injected context (event spans), and — unless asked for — subagent threads. Harness tags (<system-reminder> and friends) are stripped from user text with the same projection the trace header's prompt uses.

Index

Constants

View Source
const (
	RoleUser      = "user"
	RoleAssistant = "assistant"
)

Row roles.

Variables

This section is empty.

Functions

func AssistantText

func AssistantText(blocks []llm.ContentBlock) string

AssistantText joins a reply's text blocks verbatim; assistant output carries no harness scaffolding.

func Contributes

func Contributes(sp storage.SpanRecord, opts Options) bool

Contributes reports whether sp is part of the transcript under opts: a conversation llm call (call_kind main, or empty on rows derived before the taxonomy) or a tool span, on the root thread unless subagents are included.

func Matches

func Matches(row Row, role, q string) bool

Matches reports whether row passes the role and substring filters: role is "user", "assistant", or "" / "all"; a user filter keeps only rows with genuine user text. q is matched case-insensitively against the row text.

func UserText

func UserText(blocks []llm.ContentBlock) string

UserText renders the genuine user text of a call's fresh input: each text block projected for humans (harness tags stripped, the human words inside content-bearing wrappers such as <command-args> kept), blocks that project to nothing dropped, the rest joined by newlines.

Types

type Emitted

type Emitted struct {
	Row  Row
	Next Position
}

Emitted is a row together with the position just past it, which is what a pager mints its cursor from.

type Options

type Options struct {
	// Subagents includes subagent threads; false keeps the root thread
	// (the spans whose thread_id is empty).
	Subagents bool
}

Options selects which spans contribute.

type Position

type Position struct {
	After      storage.SpanCursor
	SkipUserOf string
}

Position is where a walk resumes within one trace: after the span key After (zero: from the trace's first span), and, when SkipUserOf names a span, without re-serving that span's user row — the row a page ended on when the same span's assistant row did not fit.

type Row

type Row struct {
	// Seq is the presentation ordinal, within its trace, of the span the
	// row was read from. A tool-results row takes the seq of its first
	// tool span.
	Seq     int64  `json:"seq"`
	TraceID string `json:"trace_id"`
	SpanID  string `json:"span_id"`
	// ThreadID names the subagent thread the message belongs to; absent
	// for the root conversation.
	ThreadID  string    `json:"thread_id,omitempty"`
	StartedAt time.Time `json:"started_at"`
	// Role is "user" or "assistant".
	Role string `json:"role"`
	// Text is the message's prose. For a user row it is the genuine user
	// text with harness tags stripped; a row that only carries tool
	// results has empty text. For an assistant row it is the reply's text
	// blocks (thinking is not included).
	Text string `json:"text"`
	// ToolCalls are the tools the assistant asked for, on assistant rows.
	ToolCalls []ToolCall `json:"tool_calls,omitempty"`
	// ToolResults are the results handed back to the model, on user rows.
	// An assistant row carries the inline results of server-side tools
	// (web_search_tool_result and the like), which arrive in the reply
	// itself rather than in a later request.
	ToolResults []ToolResult `json:"tool_results,omitempty"`
}

Row is one message of the transcript.

type ToolCall

type ToolCall struct {
	ID    string         `json:"id"`
	Name  string         `json:"name"`
	Input map[string]any `json:"input"`
}

ToolCall is one tool_use block of an assistant reply.

type ToolResult

type ToolResult struct {
	ToolUseID string `json:"tool_use_id"`
	Text      string `json:"text"`
	IsError   bool   `json:"is_error"`
}

ToolResult is one tool_result handed back to the model.

type Walker

type Walker struct {
	// contains filtered or unexported fields
}

Walker turns one trace's spans, fed in presentation order, into rows. It holds at most one pending tool-results row, so its memory is bounded by the run of tool spans one call opened, not by the trace.

func NewWalker

func NewWalker(opts Options, pos Position) *Walker

NewWalker starts a walk of one trace from pos. Feed it the spans the store yields after pos.After.

func (*Walker) Feed

func (w *Walker) Feed(sp storage.SpanRecord) []Emitted

Feed consumes the next span and returns the rows it completes, each with the position just past it.

func (*Walker) Flush

func (w *Walker) Flush() []Emitted

Flush returns the row still pending at the end of the trace.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL