Documentation
¶
Overview ¶
Package scrollback owns Mecatui's logical conversation document.
It records the ordered cards shown in the main conversation, their stable document-local identities, and the revisions that invalidate rendered-card cache entries. It deliberately has no dependency on client events, terminal geometry, styling, rendering, frame provenance, viewport state, or Bubble Tea. The ui package translates client events into the typed operations here, then adapts immutable snapshots into renderer-owned presentation inputs.
Start with Conversation. Use its component facades to create and update cards:
- Messages appends user, assistant, notice, error, hook, delivery, and turn-stat cards and applies assistant streaming updates.
- Tools creates and resolves ordinary tool cards.
- Subagents and Teams specialize a matching pending tool card and apply the corresponding delegation lifecycle updates.
- RecordFileChange and AppendixSnapshot manage the document-local changed-files appendix.
Conversation owns card state. Facade inputs are detached before storage, and SnapshotAt and SnapshotForCall return detached snapshots, so a caller cannot mutate model-owned state. MetadataAt provides only ID, revision, and kind for renderer cache checks; renderers should request a full snapshot only after a cache miss.
PayloadSnapshot is a closed family. Consumers may inspect its Kind and use a type switch over the package-defined snapshot types, but cannot define another card family or mutate a stored payload. A render-visible state change advances the enclosing card revision exactly once. Identical lifecycle replays retain their revision; conflicting or invalid lifecycle transitions report failure without changing the document.
Index ¶
- Constants
- func Float64(v float64) *float64
- type AppendixSnapshot
- type Artifact
- type AssistantCardSnapshot
- type AssistantInput
- type BlockID
- type BlockMetadata
- type BlockSnapshot
- type Conversation
- func (c *Conversation) AppendixSnapshot() (AppendixSnapshot, bool)
- func (c *Conversation) Len() int
- func (c *Conversation) Messages() MessageCards
- func (c *Conversation) MetadataAt(i int) BlockMetadata
- func (c *Conversation) Notices() PlainCards
- func (c *Conversation) RecordFileChange(path string) BlockID
- func (c *Conversation) SnapshotAt(i int) BlockSnapshot
- func (c *Conversation) SnapshotForCall(callID string) (BlockSnapshot, bool)
- func (c *Conversation) Subagents() SubagentCards
- func (c *Conversation) Teams() TeamCards
- func (c *Conversation) ToolCallMetadataAt(i int) (ToolCallMetadata, bool)
- func (c *Conversation) Tools() ToolCards
- type DeliveryCardSnapshot
- type ErrorCardSnapshot
- type Finding
- type HookCardSnapshot
- type Kind
- type MessageCards
- func (m MessageCards) AddAssistant(in AssistantInput) BlockID
- func (m MessageCards) AddUser(in UserInput) BlockID
- func (m MessageCards) AppendAssistant(text string) bool
- func (m MessageCards) AppendReasoning(text string) bool
- func (m MessageCards) EndReasoningStream() bool
- func (m MessageCards) RemoveUser(id BlockID) bool
- func (m MessageCards) ReviseAssistant(text string) bool
- type NoticeCardSnapshot
- type PayloadSnapshot
- type PlainCards
- func (p PlainCards) AddDelivery(fireID, text string) BlockID
- func (p PlainCards) AddDeliveryWithSchedule(scheduleName, fireID, text string) BlockID
- func (p PlainCards) AddError(text string, permanent bool) BlockID
- func (p PlainCards) AddGuardrailNotice(text string, benign bool) BlockID
- func (p PlainCards) AddHook(phase, tool, decision string) BlockID
- func (p PlainCards) AddHookText(text, phase, tool, decision string) BlockID
- func (p PlainCards) AddNotice(text string) BlockID
- func (p PlainCards) AddRecoveryNotice(text string) BlockID
- func (p PlainCards) AddTurnStat(text string) BlockID
- func (p PlainCards) RemoveNotice(id BlockID) bool
- func (p PlainCards) RetractLatestNotice(text string) bool
- func (p PlainCards) UpdateGuardrailNotice(id BlockID, text string, benign bool) bool
- func (p PlainCards) UpdateNotice(id BlockID, text string) bool
- type RoutingDecision
- type SubagentCardSnapshot
- type SubagentCards
- type SubagentStart
- type SubagentUpdate
- type Task
- type TeamCardSnapshot
- type TeamCards
- type TeamLane
- type TeamStart
- type TeamUpdate
- type ToolCall
- type ToolCallMetadata
- type ToolCardSnapshot
- type ToolCards
- func (t ToolCards) Add(call ToolCall) BlockID
- func (t ToolCards) Finish(callID string, failed bool) bool
- func (t ToolCards) ReconcileUnresolved(call ToolCall) bool
- func (t ToolCards) Resolve(callID string, result ToolResult) bool
- func (t ToolCards) ResolveAvailable(callID string, result ToolResult) bool
- type ToolResult
- type TraceEntry
- type TurnStatCardSnapshot
- type Usage
- type UserCardSnapshot
- type UserInput
Constants ¶
const MaxTraceEntries = 128 + 12
MaxTraceEntries bounds tool calls plus independently retained message previews.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AppendixSnapshot ¶
AppendixSnapshot is a detached description of the changed-files appendix. ID is allocated once when the first non-empty path is recorded; PrecedingBlockID identifies the final ordinary card at snapshot time, or zero when there is none.
type Artifact ¶
type Artifact struct {
Kind, MIMEType string
Data []byte
URL, Text string
Name, Title string
Description string
}
Artifact is presentation-neutral content produced by a tool. Data is binary content; the remaining fields describe its logical media or resource form.
type AssistantCardSnapshot ¶
AssistantCardSnapshot is the detached payload for an assistant message card.
func (AssistantCardSnapshot) Kind ¶
func (AssistantCardSnapshot) Kind() Kind
Kind returns KindAssistant.
type AssistantInput ¶
AssistantInput supplies the initial text and reasoning state for a new assistant card. ReasoningStreaming marks reasoning that is still arriving.
type BlockID ¶
type BlockID uint64
BlockID is a non-zero identifier allocated by a Conversation for a card or its changed-files appendix. IDs are unique within one Conversation and are never reused; zero denotes no block.
type BlockMetadata ¶
BlockMetadata identifies a card for renderer cache lookup without cloning its payload. It deliberately exposes only logical identity, revision, and kind.
type BlockSnapshot ¶
type BlockSnapshot struct {
ID BlockID
Revision uint64
Payload PayloadSnapshot
}
BlockSnapshot is a detached view of one conversation card. ID remains stable for the card's lifetime. Revision starts at zero and advances when the card's payload changes, including confirmation of a provisional tool result.
type Conversation ¶
type Conversation struct {
// contains filtered or unexported fields
}
Conversation is an ordered, mutable logical conversation document. It owns its cards, tool-call index, and changed-files appendix; use its component facades to append or transition cards, and snapshots to observe them.
func (*Conversation) AppendixSnapshot ¶
func (c *Conversation) AppendixSnapshot() (AppendixSnapshot, bool)
AppendixSnapshot returns the current changed-files appendix and true, or false if no non-empty file path has been recorded. Its Files slice is detached from the Conversation.
func (*Conversation) Len ¶
func (c *Conversation) Len() int
Len returns the number of ordinary cards in the conversation. It excludes the separately rendered changed-files appendix.
func (*Conversation) Messages ¶
func (c *Conversation) Messages() MessageCards
Messages returns the facade for adding and updating message cards.
func (*Conversation) MetadataAt ¶
func (c *Conversation) MetadataAt(i int) BlockMetadata
MetadataAt returns the cache identity for a card without allocating or detaching its payload. A renderer can reuse a cached rendering while ID and Revision match; it should call SnapshotAt only after a cache miss.
func (*Conversation) Notices ¶
func (c *Conversation) Notices() PlainCards
Notices returns the facade for appending non-streaming informational cards.
func (*Conversation) RecordFileChange ¶
func (c *Conversation) RecordFileChange(path string) BlockID
RecordFileChange records path in the conversation's changed-files appendix and returns that appendix's stable ID. Empty paths return zero. Repeated paths do not add another entry and return the existing appendix ID when it exists.
func (*Conversation) SnapshotAt ¶
func (c *Conversation) SnapshotAt(i int) BlockSnapshot
SnapshotAt returns a detached snapshot of the card at index i. It panics when i is outside [0, Len()). Mutating the returned payload or data reachable from it cannot mutate the Conversation.
func (*Conversation) SnapshotForCall ¶
func (c *Conversation) SnapshotForCall(callID string) (BlockSnapshot, bool)
SnapshotForCall returns the current detached snapshot for the tool card indexed by callID. It returns false when no non-empty call ID was recorded for a tool card. Call IDs are indexed when their tool card is appended.
func (*Conversation) Subagents ¶
func (c *Conversation) Subagents() SubagentCards
Subagents returns the facade for subagent lifecycle transitions.
func (*Conversation) Teams ¶
func (c *Conversation) Teams() TeamCards
Teams returns the facade for team lifecycle transitions.
func (*Conversation) ToolCallMetadataAt ¶ added in v0.0.45
func (c *Conversation) ToolCallMetadataAt(i int) (ToolCallMetadata, bool)
ToolCallMetadataAt returns the compact top-level tool projection at index i without detaching its payload. It returns false for non-tool cards.
func (*Conversation) Tools ¶
func (c *Conversation) Tools() ToolCards
Tools returns the facade for adding and resolving tool cards.
type DeliveryCardSnapshot ¶
type DeliveryCardSnapshot struct{ ScheduleName, FireID, Text string }
DeliveryCardSnapshot is the detached payload for a scheduled delivery.
func (DeliveryCardSnapshot) Kind ¶
func (DeliveryCardSnapshot) Kind() Kind
Kind returns KindDelivery.
type ErrorCardSnapshot ¶
ErrorCardSnapshot is the detached payload for an error; Permanent identifies an error that will not be retried.
type Finding ¶
type Finding struct{ Member, Body string }
Finding is a result reported by a named team member.
type HookCardSnapshot ¶
type HookCardSnapshot struct{ Text, Phase, Tool, Decision string }
HookCardSnapshot is the detached payload recording a hook phase, tool, and decision, with optional display text.
type Kind ¶
type Kind uint8
Kind identifies the payload family stored in a card snapshot.
const ( // KindUser identifies a UserCardSnapshot. KindUser Kind = iota // KindAssistant identifies an AssistantCardSnapshot. KindAssistant // KindTool identifies a ToolCardSnapshot. KindTool // KindSubagent identifies a SubagentCardSnapshot. KindSubagent // KindTeam identifies a TeamCardSnapshot. KindTeam // KindNotice identifies a NoticeCardSnapshot. KindNotice // KindTurnStat identifies a TurnStatCardSnapshot. KindTurnStat // KindError identifies an ErrorCardSnapshot. KindError // KindHook identifies a HookCardSnapshot. KindHook // KindDelivery identifies a DeliveryCardSnapshot. KindDelivery )
type MessageCards ¶
type MessageCards struct {
// contains filtered or unexported fields
}
MessageCards mutates user and assistant cards in its Conversation. The facade does not own a copy of the Conversation and is valid while that Conversation remains in use.
func (MessageCards) AddAssistant ¶
func (m MessageCards) AddAssistant(in AssistantInput) BlockID
AddAssistant appends an assistant card and returns its new, stable block ID.
func (MessageCards) AddUser ¶
func (m MessageCards) AddUser(in UserInput) BlockID
AddUser appends a user card and returns its new, stable block ID.
func (MessageCards) AppendAssistant ¶
func (m MessageCards) AppendAssistant(text string) bool
AppendAssistant appends text to the final assistant card. If the final card is not an assistant card, it appends a new one. It returns true after that mutation and clears ReasoningStreaming on an existing assistant card.
func (MessageCards) AppendReasoning ¶
func (m MessageCards) AppendReasoning(text string) bool
AppendReasoning appends reasoning to the final assistant card, appending an empty assistant card first when needed. It marks reasoning as streaming while that card has no visible assistant text.
func (MessageCards) EndReasoningStream ¶
func (m MessageCards) EndReasoningStream() bool
EndReasoningStream clears ReasoningStreaming on the final assistant card. It returns false if the conversation is empty or its final card is not an assistant card.
func (MessageCards) RemoveUser ¶
func (m MessageCards) RemoveUser(id BlockID) bool
RemoveUser removes the user card with id without affecting other cards. It returns false when id does not identify a user card in this conversation.
func (MessageCards) ReviseAssistant ¶
func (m MessageCards) ReviseAssistant(text string) bool
ReviseAssistant replaces the text of the final assistant card. If the final card is not an assistant card, it appends a new one. It returns true after the resulting mutation and clears ReasoningStreaming on an existing assistant card.
type NoticeCardSnapshot ¶
NoticeCardSnapshot is the detached payload for a notice; Recover marks a notice emitted while recovering a session. BenignGuardrail marks a retained known-benign guardrail review that presentation may hide while details are collapsed.
type PayloadSnapshot ¶
type PayloadSnapshot interface {
Kind() Kind
// contains filtered or unexported methods
}
PayloadSnapshot is the immutable-from-the-conversation perspective payload of a BlockSnapshot. The unexported method seals the payload-family boundary: consumers can inspect the package-defined concrete types but cannot introduce another card family. Payload values returned by Conversation snapshots are detached and may be changed without changing the Conversation.
type PlainCards ¶
type PlainCards struct {
// contains filtered or unexported fields
}
PlainCards appends non-streaming informational cards to its Conversation.
func (PlainCards) AddDelivery ¶
func (p PlainCards) AddDelivery(fireID, text string) BlockID
AddDelivery appends an unscheduled delivery and returns its new, stable block ID.
func (PlainCards) AddDeliveryWithSchedule ¶
func (p PlainCards) AddDeliveryWithSchedule(scheduleName, fireID, text string) BlockID
AddDeliveryWithSchedule appends a scheduled delivery and returns its new, stable block ID.
func (PlainCards) AddError ¶
func (p PlainCards) AddError(text string, permanent bool) BlockID
AddError appends an error card and returns its new, stable block ID.
func (PlainCards) AddGuardrailNotice ¶ added in v0.0.45
func (p PlainCards) AddGuardrailNotice(text string, benign bool) BlockID
AddGuardrailNotice appends a guardrail review notice with its client-only benign presentation classification.
func (PlainCards) AddHook ¶
func (p PlainCards) AddHook(phase, tool, decision string) BlockID
AddHook appends a hook card without display text and returns its new, stable block ID.
func (PlainCards) AddHookText ¶
func (p PlainCards) AddHookText(text, phase, tool, decision string) BlockID
AddHookText appends a hook card and returns its new, stable block ID.
func (PlainCards) AddNotice ¶
func (p PlainCards) AddNotice(text string) BlockID
AddNotice appends a normal notice and returns its new, stable block ID.
func (PlainCards) AddRecoveryNotice ¶
func (p PlainCards) AddRecoveryNotice(text string) BlockID
AddRecoveryNotice appends a recovery notice and returns its new, stable block ID.
func (PlainCards) AddTurnStat ¶
func (p PlainCards) AddTurnStat(text string) BlockID
AddTurnStat appends turn statistics text and returns its new, stable block ID.
func (PlainCards) RemoveNotice ¶ added in v0.0.43
func (p PlainCards) RemoveNotice(id BlockID) bool
RemoveNotice removes only the notice with the given identity.
func (PlainCards) RetractLatestNotice ¶
func (p PlainCards) RetractLatestNotice(text string) bool
RetractLatestNotice removes the most-recent matching notice. It is used when a provisional approval notice is refused before it reaches the server.
func (PlainCards) UpdateGuardrailNotice ¶ added in v0.0.45
func (p PlainCards) UpdateGuardrailNotice(id BlockID, text string, benign bool) bool
UpdateGuardrailNotice replaces a guardrail review notice's text and benign classification without changing its identity or position.
func (PlainCards) UpdateNotice ¶ added in v0.0.43
func (p PlainCards) UpdateNotice(id BlockID, text string) bool
UpdateNotice replaces a notice without changing its identity or position.
type RoutingDecision ¶
type RoutingDecision struct {
Backend, ClassifierModel, CandidateCategory, CandidateModel string
Confidence, MinimumConfidence *float64
Outcome string
ConsecutiveMisses, MissLimit int
BreakerOpen bool
}
RoutingDecision retains scalar routing evidence. Nil confidence values preserve absence in the source event and are detached when stored or snapshotted.
type SubagentCardSnapshot ¶
type SubagentCardSnapshot struct {
Call ToolCall
Resolved bool
Result ToolResult
Start SubagentStart
Update SubagentUpdate
// contains filtered or unexported fields
}
SubagentCardSnapshot is the detached payload of a specialized Subagent tool card, including its call lifecycle and child state.
func (SubagentCardSnapshot) Kind ¶
func (SubagentCardSnapshot) Kind() Kind
Kind returns KindSubagent.
type SubagentCards ¶
type SubagentCards struct {
// contains filtered or unexported fields
}
SubagentCards transitions tool cards for delegated children.
func (SubagentCards) Start ¶
func (s SubagentCards) Start(callID string, start SubagentStart) bool
Start specializes the indexed pending Subagent tool card with start. It returns false for a missing, wrong-kind, or non-Subagent call; an identical replay succeeds without changing its revision.
func (SubagentCards) Update ¶
func (s SubagentCards) Update(callID string, update SubagentUpdate) bool
Update records a subagent update. It returns false for a missing or wrong-kind card and for a conflicting update after Done; identical updates succeed as no-ops.
func (SubagentCards) UpdateStart ¶
func (s SubagentCards) UpdateStart(callID string, start SubagentStart) bool
UpdateStart replaces the start data for an existing subagent card. It returns false when callID does not identify such a card; identical input is a successful no-op.
type SubagentStart ¶
type SubagentStart struct {
ChildID, Goal, Model, Provider, ExplicitRouterCategory, RoutedCategory, RoutedModel, RoutingReason string
Background bool
Routing RoutingDecision
}
SubagentStart describes a started delegated child.
type SubagentUpdate ¶
type SubagentUpdate struct {
Current, Stop, Cause string
Trace []TraceEntry
ToolCount int
Usage Usage
DurationMS int64
Done bool
Artifacts []Artifact
}
SubagentUpdate is the current or terminal state of a delegated child. Done seals the update: only an identical replay is accepted afterwards.
type TeamCardSnapshot ¶
type TeamCardSnapshot struct {
Call ToolCall
Resolved bool
Result ToolResult
Update TeamUpdate
// contains filtered or unexported fields
}
TeamCardSnapshot is the detached payload of a specialized Team tool card.
type TeamCards ¶
type TeamCards struct {
// contains filtered or unexported fields
}
TeamCards transitions tool cards for teams.
type TeamLane ¶
type TeamLane struct {
Name, SessionID, Role string
Mutating, Lead bool
RoutedCategory, RoutedModel, RoutingReason, Model string
Provider, ExplicitRouterCategory string
Routing RoutingDecision
Current string
ToolCount int
Usage Usage
Trace []TraceEntry
Idle, Stopped bool
StopReason, Cause string
ErrorRounds int
ContextUsed, ContextWindow int64
}
TeamLane is a bounded projection of one Team member, in roster order.
type TeamUpdate ¶
type TeamUpdate struct {
TeamID string
Lanes []TeamLane
Tasks []Task
Findings []Finding
Rounds int
Stop string
Usage Usage
Done bool
}
TeamUpdate is the current or terminal state of a team. Done seals the update: only an identical replay is accepted afterwards.
type ToolCall ¶
ToolCall describes the request represented by a tool card. Add copies its Artifacts and indexes a non-empty ID for later lifecycle transitions.
type ToolCallMetadata ¶ added in v0.0.45
type ToolCallMetadata struct {
ID BlockID
Revision uint64
CallID, Name, Arguments string
// ResultReceived reports payload.Resolved; Provisional reports an available
// result awaiting canonical confirmation. Terminal is lifecycle completion
// without implying a canonical result.
ResultReceived, Provisional, Terminal bool
ResultError, LifecycleFailed bool
Stop string
}
ToolCallMetadata is the compact tool-card projection used by inventories. It intentionally excludes results and artifacts, whose byte payloads remain owned by the conversation until a selected detail requests a detached snapshot.
func ToolCallMetadataOf ¶ added in v0.0.45
func ToolCallMetadataOf(s BlockSnapshot) (ToolCallMetadata, bool)
ToolCallMetadataOf returns the same compact projection as ToolCallMetadataAt for an already detached snapshot, so a renderer that loaded a snapshot after a cache miss does not reinterpret tool lifecycle fields itself.
type ToolCardSnapshot ¶
type ToolCardSnapshot struct {
Call ToolCall
Resolved, Finished bool
Failed bool
Result ToolResult
// contains filtered or unexported fields
}
ToolCardSnapshot is the detached payload for a tool call. Resolved distinguishes a call with its terminal Result; Finished records an earlier terminal lifecycle projection when the result has not arrived yet. Failed classifies that projection.
type ToolCards ¶
type ToolCards struct {
// contains filtered or unexported fields
}
ToolCards adds tool cards and records their one-way results.
func (ToolCards) Add ¶
Add appends a pending tool card, copies its mutable artifacts, and returns its new stable block ID. A non-empty call.ID is available to Resolve and specialized subagent or team transitions.
func (ToolCards) Finish ¶
Finish records a terminal lifecycle projection before the tool result arrives. It returns false for an unknown, resolved, specialized, or conflicting card.
func (ToolCards) ReconcileUnresolved ¶
ReconcileUnresolved updates the pending card indexed by call.ID. It returns false for an unknown, resolved, finished, or non-tool card.
func (ToolCards) Resolve ¶
func (t ToolCards) Resolve(callID string, result ToolResult) bool
Resolve records the authoritative result for the call indexed by callID. It confirms identical availability or replaces a different available result. A conflicting canonical replay fails.
func (ToolCards) ResolveAvailable ¶ added in v0.0.44
func (t ToolCards) ResolveAvailable(callID string, result ToolResult) bool
ResolveAvailable settles a pending card with a transient display result.
type ToolResult ¶
ToolResult describes a resolved tool call. IsError records an error result; Artifacts are detached when stored or returned in a snapshot.
type TraceEntry ¶
type TraceEntry struct {
Lane string // child session ID when multiple children share a Subagent card
ID string // child tool-call ID, scoped to its lane
Kind, Text, ToolName, Detail, Intent string
Error, Resolved, Provisional, Blocked bool
Serial uint64
}
TraceEntry is one retained delegation preview. A Subagent update holds at most 128 tool calls and 12 message previews per child lane, interleaved in event order.
type TurnStatCardSnapshot ¶
type TurnStatCardSnapshot struct{ Text string }
TurnStatCardSnapshot is the detached payload for turn statistics text.
func (TurnStatCardSnapshot) Kind ¶
func (TurnStatCardSnapshot) Kind() Kind
Kind returns KindTurnStat.
type Usage ¶
type Usage struct {
InputTokens, OutputTokens, CacheReadTokens, CacheWriteTokens, ReasoningTokens int64
}
Usage records token accounting associated with a delegation or team member.
type UserCardSnapshot ¶
UserCardSnapshot is the detached payload for a user message card.