Documentation
¶
Index ¶
- func AllLoopsEventFilter() event.EventFilter
- func RenderStatusLine(s Status) string
- type Agent
- type AgentBanner
- type AgentHolder
- type DisplayProjection
- type EffortID
- type EffortOption
- type EventStream
- type HandoffFinalizer
- type LoopRuntimeOptions
- type ModeID
- type ModeOption
- type ModelID
- type ModelOption
- type OpenAgent
- type Option
- type RestoreBacklogError
- type RuntimeCatalog
- type RuntimeController
- type Screen
- type SessionBrowser
- type SessionID
- type SessionPresentation
- type SessionPresenter
- type SessionSummary
- type Status
- type TerminalErrorHolder
- type ToolCallView
- type ToolStatus
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AllLoopsEventFilter ¶
func AllLoopsEventFilter() event.EventFilter
AllLoopsEventFilter is the TUI's declared interest for a session subscription: BOTH classes deliver from EVERY loop — Ephemeral is All and Enduring is All. It takes no loop id because neither scope discriminates by loop, and session-scoped events (SessionStarted/Active/Idle/Stopped, ActiveLoopChanged) bypass the loop filter and always deliver.
The TUI renders every loop's WHOLE live stream (a user can focus any subagent loop and watch its live tokens stream), so it must actually RECEIVE every loop's live Ephemeral firehose. The widened scope also delivers each loop's tool-lifecycle events, which fold into that loop's live projection. An active-only Ephemeral scope would starve projections of a subagent's live output, freezing a focused subagent view at Enduring StepDone granularity. The whole-session hub buffer is bounded and has no replay, so the TUI opens ONE all-loops subscription at startup and never re-subscribes; focus is then a pure view filter over already-received, already-projected state.
func RenderStatusLine ¶
RenderStatusLine returns the one-line status indicator for the given status. It derives the label from the session status alone (no live interaction signals), so a Running turn reads "thinking…" until the surface — which knows the live segment — refines it via renderStatusLine. The empty label renders to "", every other label as a (here static, phase-0) lime↔blue gradient. Retained for callers holding only the status.
Types ¶
type Agent ¶
type Agent interface {
// SessionID returns the durable, non-zero identity of the current session.
// The startup banner reads it directly so a restored or /clear-replaced agent
// always displays its own session rather than stale composition metadata.
SessionID() uuid.UUID
// Submit sends input fire-and-forget as a queueable UserInput; the returned
// InputID correlates the Reply events (Cause.CommandID) that report the outcome.
// It targets the session's ACTIVE loop — the currently selected default input
// target the single-loop convenience Screen and the modern viewport both use.
Submit(ctx context.Context, blocks []content.Block) (uuid.UUID, error)
// SubmitToLoop sends input fire-and-forget to a SPECIFIC loop — the modern
// viewport's FOCUSED loop — rather than the active loop, so a submit while focused on a
// subagent runs a new turn on THAT loop. It is the loop-targeted counterpart of
// Submit (same fire-and-forget InputID/Cause.CommandID contract, human agency); a
// loopID equal to the ACTIVE loop id behaves exactly like Submit.
SubmitToLoop(ctx context.Context, loopID uuid.UUID, blocks []content.Block) (uuid.UUID, error)
// CompactToLoop requests manual conversation compaction for one exact loop.
// The modern viewport supplies its focused loop so this action never redirects
// through the session's active-loop convenience target.
CompactToLoop(ctx context.Context, loopID uuid.UUID) (uuid.UUID, error)
// ActiveLoopID returns the current default input target.
ActiveLoopID() uuid.UUID
Interrupt(ctx context.Context) (bool, error)
Close(ctx context.Context) error
// AcceptsImages reports the current model capability for loopID — whether the model
// bound to that loop accepts image blocks — so buildBlocks can reject image @path
// tokens at the boundary instead of failing mid-turn. It is keyed on the loop because
// a multi-loop session runs heterogeneous models: the focused subagent's model, not
// the session's, governs a submission to that loop. Query it per submission (the loop's
// model can change) and fail closed for an unknown loop.
AcceptsImages(loopID uuid.UUID) bool
// Subscribe attaches a whole-session event consumer to the agent's session
// fan-in with the given filter and returns its EventStream. It is the seam the
// TUI uses to observe events across the entire session (every loop): a session
// subscription spans turns and loops. The caller must Close the returned stream
// when done. Use AllLoopsEventFilter for the whole-session all-loop delivery.
Subscribe(filter event.EventFilter) (EventStream, error)
// ReplayBacklog returns the RESTORED session's historical Enduring events for a
// cold-restore repaint, in session order. It is the backlog seam the TUI folds
// off the update loop (restoreBacklogCmd) to rebuild the committed transcript +
// pending gates BEFORE attaching the live Subscribe stream. The slice is
// materialized (the data layer is sub-second for realistic sizes) so the consumer
// drains it without owning a cursor's lifetime. A NEW (non-restored) session
// returns nil/empty — the TUI then skips the repaint and behaves exactly as a
// fresh session. A read failure returns a typed error the fold surfaces as a
// non-fatal restore-error notice (history could not repaint; the live stream is
// unaffected). The events are the session's all-loop Enduring history — never
// the live 256-cap hub buffer. ctx bounds the read.
ReplayBacklog(ctx context.Context) ([]event.Event, error)
// Approve resolves a pending tool-call permission gate with one of the two
// approve actions — gate.ApprovalApprove (once, persists nothing) or
// gate.ApprovalApproveAlwaysWorkspace (atomically persists the displayed reusable
// rule candidates before execution). loopID is the loop that opened the gate (the
// PermissionRequested event's Header.LoopID) so the reply is dispatched to the
// right loop in a multi-loop session; callID identifies the gate. The agent
// wrapper delegates to its session; the action string is exactly one the gate's
// controls advertised, which the session validates.
Approve(ctx context.Context, loopID, callID uuid.UUID, action gate.ApprovalAction) error
// Deny resolves a pending tool-call permission gate by failing it closed
// (fail-secure); nothing is persisted. loopID names the gate-opening loop so the
// reply reaches the right loop. The wrapper delegates to its session.
Deny(ctx context.Context, loopID, callID uuid.UUID) error
// ProvideAnswer supplies the user's reply to a pending AskUser request
// identified by callID. loopID names the gate-opening loop so the answer reaches
// the right loop. It is the TUI-facing name for the session's ProvideUserInput;
// the wrapper delegates to it.
ProvideAnswer(ctx context.Context, loopID, callID uuid.UUID, answer string) error
// RespondGate answers a HOST-RAISED gate identified by gateID — a form gate
// (gate.KindForm) or an open-url gate (gate.KindOpenURL). Unlike the three
// above it names the GATE directly: such a gate is observed through GateOpened,
// which carries the gate id, so there is nothing to look up. It is one method
// for both kinds because the act is identical — an advertised action sent to a
// gate id — and only an open-url gate's empty values distinguish them.
// action is one of the gate.FormAction* values; values carries a form accept's
// answers keyed by schema field name, already encoded as the JSON types the
// schema calls for, and is nil for any other action (and always nil for an
// open-url gate, which has no fields). The session validates
// them against the gate's authoritative schema and rejects an action the gate
// never offered, so this is a request, not a command.
RespondGate(ctx context.Context, gateID gate.ID, action string, values map[string]json.RawMessage) error
}
Agent is the narrow surface the TUI drives. *coding.Coding satisfies it structurally; the TUI never imports any agent package.
type AgentBanner ¶
AgentBanner is the static agent metadata shown as the startup info notice. Name and Description are threaded in at construction from the application composition root; the session identity comes from the current Agent when the notice is committed. The zero value renders a name-less banner; bannerText degrades gracefully when either static field is empty.
It lives in its own file (not the shell) because it is shared state on the embedded sessionCore that BOTH the composition root and the presentation shell read — see sessioncore.go's banner field and Screen's use of bannerText.
type AgentHolder ¶
type AgentHolder interface {
Agent() Agent
}
AgentHolder is the narrow, read-only view of a presentation shell that the CLI composition root (runtime/run.go — a DIFFERENT package) type-asserts against at teardown: it exposes ONLY the live Agent, so Run can bound a best-effort Close of whichever agent a /clear may have swapped in, without depending on either concrete shell type. It returns nil after a failed /clear handoff because the prior agent was already closed and no replacement exists. Both Screen and Screen satisfy it through the Agent() method promoted from the embedded sessionCore (a value receiver), so Run asserts the final tea.Model against this one interface and teardown works whichever shell runtime.Run wires. It is exported because the cross-package assertion in runtime/run.go needs the name, and deliberately tiny — one method — so the composition root depends on nothing it does not use (interface segregation).
type DisplayProjection ¶
type DisplayProjection struct {
// contains filtered or unexported fields
}
DisplayProjection is the committed TUI projection of a fold over all delivered Enduring events — the "displayed" transcript the event-persistence design's headline property compares (displayed == stored == restored). It bundles the pure reducer states (transcript, pending-gate interaction, and compaction activity) so the restore-repaint path and the persistence property tests build the displayed view through one named seam. It is value-typed and immutable; FoldDisplay is its only constructor.
func FoldDisplay ¶
func FoldDisplay(events []event.Event) DisplayProjection
FoldDisplay folds events through the SAME pure reducers the live path and the cold-restore repaint use, starting from the zero reducer state scoped to loopID, and returns the resulting displayed projection. It is the single fold the TUI uses to turn a slice of Enduring events into a repaintable transcript: restoreBacklogCmd folds the restored backlog through it, and the persistence property tests fold both a restored ReplayBacklog and the original live Enduring sequence through it to assert the two displayed views are identical. The fold is order-sensitive and side-effect-free — folding the same events twice yields an EqualTranscript pair.
func (DisplayProjection) CommittedLen ¶
func (p DisplayProjection) CommittedLen() int
CommittedLen is the number of finalized transcript entries across the global stream and every loop projection.
func (DisplayProjection) EqualTranscript ¶
func (p DisplayProjection) EqualTranscript(other DisplayProjection) bool
EqualTranscript reports whether p and other have the byte-for-byte identical committed transcript (the displayed scrollback), via reflect.DeepEqual over the transcript reducer state — IGNORING the live-only thinking DURATION. It is the headline-property comparator: a restored session's repainted transcript EqualTranscript the original session's live transcript iff the repaint reproduced the displayed view exactly. The interaction surface (its input editor carries cursor state and completion-panel closures that are not value- comparable) is intentionally NOT part of this equality — assert PendingPrompts for the pending-gate dimension instead.
The thinking duration (entry.thinkDur and the live segment's streaming timestamps) is EXCLUDED from the comparison: it is measured from streaming TokenDelta timestamps, which are Ephemeral and NEVER journaled, so a cold-restore fold replays only the persisted StepDone events and legitimately produces dur == 0 (the restored row correctly shows "│ thought" with no number) while the same row folded live shows "│ thought for 10sec". That divergence is the ACCEPTED display behavior, not a repaint bug, so it is normalized out (normalizeThinkTiming) before DeepEqual; every OTHER field (the committed rows, ordering, blocks, tool cards, gate state) is compared exactly.
This is a TEST / RESTORE-VERIFICATION comparator, NOT a cheap runtime equality check: normalizeThinkTiming allocates fresh copies of both models (committed slices + projection map/pointers) on every call, and reflect.DeepEqual walks the whole reducer state. Do NOT wire it into a render loop or a per-event hot path expecting it to be free.
func (DisplayProjection) EventCount ¶
func (p DisplayProjection) EventCount() int
EventCount reports how many backlog events were folded. Unlike CommittedLen it remains non-zero for lifecycle-only history that rebuilds loop metadata without transcript rows.
func (DisplayProjection) PendingPrompts ¶
func (p DisplayProjection) PendingPrompts() int
PendingPrompts is the number of pending prompts (permission gates + AskUser requests) the projection's interaction surface holds — the gate dimension a transcript deep- equal does not cover.
type EffortOption ¶
type EventStream ¶
type EventStream = event.Subscription
EventStream is the narrow consumer-facing handle the TUI reads whole-session events from. It is event.Subscription — the read+teardown contract the session hub's *EventSubscription satisfies structurally — so the TUI depends on the interface, not the concrete hub type. Events yields the filtered fan-in stream; it closes on Close or on a hub-forced loss, after which Err reports the typed cause (nil for an intentional Close).
type HandoffFinalizer ¶
type HandoffFinalizer interface {
FinalizeHandoff() error
}
HandoffFinalizer is the final-model lifecycle barrier runtime.Run crosses before returning to a composition root that may close stores used by an asynchronous /clear open or deferred replacement close.
type LoopRuntimeOptions ¶
type LoopRuntimeOptions struct {
Modes []ModeOption
Models []ModelOption
Efforts []EffortOption
}
LoopRuntimeOptions contains available choices. Each option's Current marker maps the catalog's opaque choice identity to the live loop value so a picker can identify its active row even when, for example, a model ID is a product routing alias. Durable current state and status display remain authoritative event projections.
Access is deliberately absent: the access profile is FIXED for the session and supplied synchronously as SessionPresentation, never a mutable runtime control.
type ModeOption ¶
type ModelOption ¶
type OpenAgent ¶
OpenAgent constructs a fresh Agent. The composition root binds it to its session factory. On /clear the TUI closes the current Agent before invoking OpenAgent, allowing exclusive resources to transfer to the replacement. A failed open is terminal because the closed current Agent cannot be resumed. Implementations MUST honor context cancellation: runtime shutdown waits a bounded interval for an in-flight handoff, after which it returns fatal and the coordinator closes any replacement that arrives late.
type Option ¶
type Option func(*screenOptions)
func WithSessionBrowser ¶
func WithSessionBrowser(browser SessionBrowser) Option
func WithSessionPresentation ¶
func WithSessionPresentation(p SessionPresentation) Option
WithSessionPresentation supplies the synchronous session metadata (workspace, fixed profile, permission diagnostics) the Screen captures at construction. It is consumer-filled and minimal; an omitted option falls back to the constructed Agent's own SessionPresenter capability, if it implements one (see New), and otherwise yields the zero presentation (no profile, no workspace, no diagnostics). A SUPPLIED option always wins over the agent's capability: it is the explicit, consumer-authoritative override.
type RestoreBacklogError ¶
type RestoreBacklogError struct {
Cause error
}
RestoreBacklogError reports a failure to read a restored session's historical Enduring backlog for repaint (the Agent.ReplayBacklog call failed). It is a NON-FATAL restore error: the live subscription is unaffected, so the Screen surfaces it as a faint error notice and continues with an empty transcript rather than a dead surface. It wraps the underlying replay cause so a caller can errors.As both this and the journal's typed read error.
func (*RestoreBacklogError) Error ¶
func (e *RestoreBacklogError) Error() string
func (*RestoreBacklogError) Unwrap ¶
func (e *RestoreBacklogError) Unwrap() error
type RuntimeCatalog ¶
type RuntimeCatalog interface {
LoopRuntimeOptions(context.Context, uuid.UUID) (LoopRuntimeOptions, error)
}
RuntimeCatalog is the optional read-only runtime-choice capability of an Agent.
type RuntimeController ¶
type RuntimeController interface {
SetMode(context.Context, uuid.UUID, ModeID) error
SetModel(context.Context, uuid.UUID, ModelID) error
SetEffort(context.Context, uuid.UUID, EffortID) error
}
RuntimeController is the optional typed runtime-mutation capability of an Agent. It mutates only per-loop inference controls; the access profile is fixed and has no setter.
type Screen ¶
type Screen struct {
// contains filtered or unexported fields
}
Screen is the MODERN VIEWPORT presentation shell over the shared sessionCore transport (embedded). Where the scrollback-first Screen lets the terminal own history, Screen owns an alt-screen VIEWPORT the user can scroll and select/copy from while content streams: it renders the FOCUSED loop's projection into a hand-rolled viewportModel (scroll + drag-select + copy), applies a RETROACTIVE collapse fold (ctrl+t + header-click), draws a bottom active-loops bar and the reused composer, and subscribes to EVERY loop's live stream (AllLoopsEventFilter) so any focused subagent's tokens render live rather than freezing at Enduring StepDone granularity.
The core owns event routing exactly as it does for Screen; Screen adds ONLY the viewport presentation. Update delegates transport to the core then re-renders the focused projection into the viewport (keeping the auto-follow tail pinned); View composes, top to bottom, the viewport content, one status line, a blank gap, an optional completion tray, the bottom box, a blank gap, and the active-loops bar, and returns a per-frame View with AltScreen + cell-motion mouse (the v2 fields the copy-while-scrolling design turns on). Agent() is promoted from the embedded sessionCore, so Screen satisfies the composition root's agentHolder through that single definition.
Focus switching (Task 8): ctrl+n / ctrl+p cycle focus over the bar's loops and a bar-region click focuses the clicked loop, both repointing focusedLoopID and re-rendering that loop's projection (focusLoop). Focus is VIEW-ONLY — it never submits/interrupts a loop.
Prompts + feature parity (Task 9): prompt keys route to the reused interaction model (handleKey precedence (2)) and the bottom box renders the head gate via the shared surface; a pending gate marks its loop with "!" in the bar WITHOUT stealing focus (bar() reads pendingGateLoops). A composer submit targets the FOCUSED loop (routeToInteraction — Stage 2: submitting while focused on any loop runs a new turn on that loop and stays focused there). A cold-restore session repaints its history: Init batches restoreBacklogCmd and handleRestored folds the backlog into the transcript + projections + loop table and re-renders. The remaining parity items (/clear reopen, esc/ctrl+c interrupt, queued input, image @path rejection) all flow through the shared sessionCore, so they are shared with Screen rather than re-implemented.
func New ¶
func New(ctx context.Context, agent Agent, open OpenAgent, banner AgentBanner, supplied ...Option) Screen
New constructs an idle Screen driving agent, with open as the /clear thunk and banner the agent name/description shown as the opening info notice. The session subscription delivers EVERY loop's live Ephemeral stream (see AllLoopsEventFilter) — the modern mode renders any focused loop's whole live output. The viewport starts pinned to the tail (atTail) so streaming content auto-follows, the collapse state starts folded (dense; ctrl+t expands), and focus starts on the agent's ACTIVE loop (Agent.ActiveLoopID — the session's current default target); a later selection event never moves it.
func (Screen) Agent ¶
func (c Screen) Agent() Agent
Agent returns the live agent. Product commands use this for a bounded backstop Close of whichever agent /clear may have swapped in. It is a value receiver so it promotes into every embedding shell's method set — both Screen and Screen satisfy the composition root's agentHolder through this one definition.
func (Screen) FinalizeHandoff ¶
FinalizeHandoff extends the core ownership finalizer with any stale replacement cleanup still in flight. agentCloseHandoff is sync.Once-backed, so a concurrent command completion and finalization close each rejected replacement exactly once.
func (Screen) Init ¶
Init focuses the composer (starting the cursor blink), schedules the opening banner (systemReadyMsg), schedules the cold-restore repaint, and attaches the session-lifetime ALL-LOOPS subscription (m.subscribe uses AllLoopsEventFilter). restoreBacklogCmd folds a restored session's historical Enduring backlog off the update loop. Live events may arrive first; the restore barrier buffers and continuously re-arms them, then applies them in arrival order after restoredMsg installs history. An empty backlog simply releases the barrier.
func (Screen) TerminalError ¶
func (c Screen) TerminalError() error
TerminalError reports a fatal transport ownership failure that caused the TUI to quit. Ordinary user-visible command errors remain in the transcript and return nil here.
func (Screen) Update ¶
Update advances the model. It is a value receiver so Screen satisfies tea.Model; the mutating handlers take a pointer to the addressable receiver and Update returns the updated value. Note the two-statement pattern for the pointer-receiver handlers (cmd := …; return m, cmd): a `return m, m.handle(...)` would evaluate the first result (the OLD m) before the handler mutates it, stranding the mutation.
func (Screen) View ¶
View composes the frame top to bottom — the viewport content (the focused projection with collapse), one status line, a blank gap, an optional completion tray, the bottom box, an optional transient key panel, a blank gap, and the active-loops bar — and returns a per-frame View with the modern configuration: AltScreen on and all-motion mouse (the v2 per-frame mode required for pointer-only hover as well as copy-while-scrolling), plus the composer's Kitty keyboard request (see Screen.View for why). It returns an empty view until the first sized frame (avoids a 0×0 first frame).
type SessionBrowser ¶
type SessionBrowser interface {
ListSessions(context.Context) ([]SessionSummary, error)
ResumeSession(context.Context, SessionID) (Agent, error)
}
SessionBrowser is a process-scoped optional capability, deliberately separate from Agent.
type SessionPresentation ¶
type SessionPresentation struct {
WorkspaceRoot string
ProfileName string
PermissionDiagnostics []string
}
SessionPresentation is the synchronous, consumer-supplied session metadata the TUI displays. The TUI never queries it asynchronously and never infers it from events: the product composition root fills it at screen construction (WithSessionPresentation) and, on a reopen, the TUI refreshes it from the replacement Agent via SessionPresenter, because the workspace, the fixed access profile, and the permission diagnostics are known before the session runs a single turn. A cross-session browser resume therefore displays the RESUMED session's context, not the prior one (see SessionPresenter and handleReopenResult).
- WorkspaceRoot is the session's workspace path, shown in the footer metadata.
- ProfileName is the FIXED access profile's display name. It is shown as session metadata (the footer), NOT as a mutable control — there is no way to change the profile from the TUI, so it must not look changeable.
- PermissionDiagnostics are display-ready notices for manual, out-of-catalog allow families the consumer detected. They MUST be visible before the first permission gate, so the Screen commits them in the startup metadata area (before any event, and therefore before any gate, can arrive).
type SessionPresenter ¶
type SessionPresenter interface {
SessionPresentation() SessionPresentation
}
SessionPresenter is the OPTIONAL capability a reopened or resumed Agent implements to supply its OWN SessionPresentation, so the reopen path can refresh the footer + pre-gate permission diagnostics to the REPLACEMENT session's security context instead of retaining the prior session's. It mirrors the RuntimeCatalog/RuntimeController optional-interface pattern: the Screen detects it on the swapped Agent by type assertion.
CONTRACT (the product composition root fills this): the composition root's agent implements SessionPresentation() returning the session's fixed access profile name, workspace root, and any manual out-of-catalog permission diagnostics — the same values it would pass to WithSessionPresentation at construction, but read from the RESUMED session. A cross-session browser resume may land on a session with a DIFFERENT workspace root and DIFFERENT fixed profile, so this is the authority for the resumed session's displayed security context.
An Agent that does NOT implement it degrades safely: a cross-session browser resume CLEARS the presentation (empty ⇒ show nothing, never a different session's context), while a /clear reopen (same session family, same workspace + fixed profile) retains the construction-time value, which is still correct. Showing nothing is acceptable; showing a different session's security context is not.
type SessionSummary ¶
type SessionSummary struct {
ID SessionID
Title string
// Description is optional, secret-free context shown by the session owner only through
// search. The compact picker keeps its two visible rows focused on recency and identity.
Description string
State string
CreatedAt time.Time
LastActiveAt time.Time
}
SessionSummary is secret-free presentation metadata for one resumable session.
type TerminalErrorHolder ¶
type TerminalErrorHolder interface {
TerminalError() error
}
TerminalErrorHolder is the minimal final-model surface runtime.Run uses to distinguish a clean Bubble Tea quit from a fatal /clear handoff. Bubble Tea itself returns nil when the model intentionally emits tea.Quit, so the model must retain the cause.
type ToolCallView ¶
type ToolCallView struct {
ToolExecutionID uuid.UUID
ToolName string // ToolCallStarted.ToolName
Summary string // ToolCallStarted.Summary (already redacted, one line)
Permission string // PermissionRequest.Description for gated calls, if available
Status ToolStatus // lifecycle state
Result []string // capped preview lines from ToolCallCompleted; nil while running
Decision gateDecision // the user's permission decision, if this call prompted (else gateNone)
// Children are the SUBAGENT's nested tool cards, reconstructed from the child's
// StepDone groups via the PURE storedStepToolCard builder (design §3a). Empty for
// an ordinary card and for a Subagent whose child loop never ran (spawn failure).
Children []ToolCallView
// Steps is the count of the child's StepDone events (its "N steps"). Zero for an
// ordinary card.
Steps int
// Agent is the subagent's agent name (the child LoopStarted.AgentName). Non-empty
// ONLY on a reconciled Subagent card; it is the field other code keys on to tell a
// Subagent card apart from an ordinary one.
Agent string
// Task is the subagent's task message (its first TurnStarted.Message, truncated to
// one line). Empty for an ordinary card.
Task string
// SubStatus is the child loop's terminal state (running/done/failed/interrupted),
// read from the child terminal event — not from a tool result's IsError. subRunning
// (the zero value) for an ordinary card.
SubStatus subStatus
// Nested is the depth-2 collapsed counter ("+N nested subagent steps", design §6):
// the count of deeper StepDones attributed to this depth-1 card. Wired in Task 7;
// zero here. Zero for an ordinary card.
Nested int
// contains filtered or unexported fields
}
ToolCallView is one tool call rendered as a child of its assistant segment. It is reconstructed from the turn event stream (ToolCallStarted / ToolCallCompleted), correlated by ToolExecutionID.
A Subagent card carries the nested-subagent fields (Children/Steps/Agent/Task/ SubStatus/Nested), populated at the orchestrator's StepDone from a detached accumulator built off the child's ENDURING events (design §1/§3). Every one of those fields is zero/empty for an ordinary (non-Subagent) card.
type ToolStatus ¶
type ToolStatus uint8
ToolStatus is the lifecycle state of a tool call rendered in the transcript.
const ( ToolRunning ToolStatus = iota // started, no completion seen yet ToolOK // completed without error ToolError // completed with an error ToolCancelled // turn interrupted while the call was still running )
Source Files
¶
- action.go
- agent.go
- agentholder.go
- anim.go
- banner.go
- clipboard.go
- commands.go
- diffview.go
- entryrender.go
- footer.go
- gradient.go
- handoff.go
- integrationstatus.go
- interaction.go
- keypanel.go
- loopbar.go
- mdcache.go
- message.go
- messages.go
- model_aliases.go
- modernrender.go
- prompt.go
- render.go
- rendered.go
- restore.go
- runtimecontrol.go
- runtimeprojection.go
- screen.go
- sessionbrowser.go
- sessioncore.go
- sessionpresentation.go
- status.go
- statusline.go
- summary.go
- surface.go
- toolsummary.go
- transcript.go
- view_helpers.go
- viewport.go