conversation

package
v1.17.2 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrTokenExpired reports a signed credential whose exp is not in the future.
	ErrTokenExpired = errors.New("tui: bearer token expired")
	// ErrTokenMalformed reports a token that cannot supply identity and expiry.
	ErrTokenMalformed = errors.New("tui: malformed bearer token")
	// ErrTokenUnavailable reports no credential for the requested identity.
	ErrTokenUnavailable = errors.New("tui: bearer token unavailable")
)
View Source
var (
	ErrExportWrite = errors.New("tui export: write failed")
	ErrExportEmpty = errors.New("tui export: transcript is empty")
)

Functions

This section is empty.

Types

type ConnectionState

type ConnectionState string

ConnectionState is an honest transport posture.

const (
	StateConnecting   ConnectionState = "connecting"
	StateLive         ConnectionState = "live"
	StateDisconnected ConnectionState = "disconnected"
	StateReconnecting ConnectionState = "reconnecting"
	StateReplaying    ConnectionState = "replaying"
	StateAuthExpired  ConnectionState = "authentication expired"
	StateClosed       ConnectionState = "closed"
	StateErased       ConnectionState = "erased"
)

type Controller

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

Controller owns exactly one active identity-scoped Protocol stream.

func NewController

func NewController(baseURL string, tokens *LifetimeTokenSource, identity types.IdentityScope, onUpdate func(Update)) (*Controller, error)

NewController constructs a reusable attach controller.

func (*Controller) Attach

func (c *Controller) Attach(ctx context.Context) error

Attach negotiates and hydrates the initial session.

func (*Controller) Close

func (c *Controller) Close() error

Close cancels and joins the active stream.

func (*Controller) Control

func (c *Controller) Control(ctx context.Context, method methods.Method, runID, scope string, payload map[string]any) (types.ControlResponse, error)

Control submits one canonical steering action. The response only verifies acceptance; the caller reconciles the effect from events and snapshots.

func (*Controller) Delete

Delete erases the active canonical session and marks it terminal locally.

func (*Controller) DeleteArtifact

func (c *Controller) DeleteArtifact(ctx context.Context, id string) (types.ArtifactsDeleteResponse, error)

DeleteArtifact requests canonical audited eviction.

func (*Controller) Execute

func (c *Controller) Execute(ctx context.Context, mutation Mutation) error

Execute is the single mutation boundary used by the TUI action matrix. Authority is never inferred client-side; the authenticated server enforces it.

func (*Controller) HasCapability

func (c *Controller) HasCapability(capability types.Capability) bool

HasCapability reports the negotiated Runtime capability for command gating.

func (*Controller) Identity

func (c *Controller) Identity() types.IdentityScope

Identity returns the active full triple.

func (*Controller) Inspect

func (c *Controller) Inspect(ctx context.Context, request InspectionRequest) RuntimeData

Inspect loads every Runtime-control screen through the authenticated client. Individual unavailable surfaces are retained as explicit errors.

func (*Controller) Projection

func (c *Controller) Projection() projection.Projection

Projection returns an isolated normalized copy.

func (*Controller) Rename

Rename updates canonical session metadata.

func (*Controller) ReplaceToken

func (c *Controller) ReplaceToken(ctx context.Context, token string) error

ReplaceToken installs an in-memory credential and reattaches the active session through the same drain, hydrate, and stream-acquisition transaction.

func (*Controller) RevokeToolOAuth

func (c *Controller) RevokeToolOAuth(ctx context.Context, id string) (types.ToolRevokeOAuthResponse, error)

RevokeToolOAuth revokes canonical tool bindings.

func (*Controller) Sessions

func (c *Controller) Sessions(ctx context.Context, query, cursor string) (types.SessionsListResponse, error)

Sessions lists authorized session metadata for the picker. Query is applied by the canonical sessions surface; an empty query returns the browse page.

func (*Controller) SetToolApproval

SetToolApproval updates one canonical tool policy.

func (*Controller) Start

func (c *Controller) Start(ctx context.Context, text string, artifactIDs []string, dispositions map[string]string) (types.StartResponse, error)

Start dispatches canonical start. Closed sessions reopen through this same method; erased sessions fail and remain terminal.

func (*Controller) Switch

func (c *Controller) Switch(ctx context.Context, target types.IdentityScope) error

Switch prepares the target stream and fenced hydration join, then drains the old stream before atomically committing the target generation.

func (*Controller) TaskDetail

func (c *Controller) TaskDetail(ctx context.Context, taskID string) (types.TaskDetail, error)

TaskDetail reads an authoritative task result and trajectory projection.

func (*Controller) ToolDetail

func (c *Controller) ToolDetail(ctx context.Context, toolID string) (tuitools.Detail, error)

ToolDetail reads schema, policy, OAuth, metrics, and content posture.

func (*Controller) Upload

func (c *Controller) Upload(ctx context.Context, name, mime string, body []byte) (types.ArtifactsPutResponse, error)

Upload stores one user attachment through canonical artifacts.put.

type ExportOptions

type ExportOptions struct{ Reasoning, Tools, Metadata, RawEvents bool }

ExportOptions independently selects detail without mutating display preferences.

type FollowUp

type FollowUp struct {
	ID, Text     string
	State        string
	Err          string
	ArtifactIDs  []string
	Dispositions map[string]string
}

FollowUp is explicitly local intent until dispatch begins.

type InspectionRequest

type InspectionRequest struct {
	Identity                    types.IdentityScope
	Generation, RequestEpoch    uint64
	TaskID, ToolID, ArtifactID  string
	TaskFilter, ToolFilter      string
	ArtifactFilter, EventFilter string
	TaskPage, ToolPage          int
	ArtifactPage, EventPage     int
	TaskCursor                  types.TaskListCursor
}

InspectionRequest fences one bounded screen refresh and carries exact selections. The controller never silently substitutes index zero.

type InteractionState

type InteractionState struct {
	Identity           types.IdentityScope `json:"identity"`
	RuntimeFingerprint string              `json:"runtime_fingerprint"`
	Draft              string              `json:"draft,omitempty"`
	History            []string            `json:"history,omitempty"`
	Stash              []string            `json:"stash,omitempty"`
	ScrollBlockID      string              `json:"scroll_block_id,omitempty"`
	// ExpandedReasoning / ExpandedTools hold the block IDs the operator has
	// explicitly expanded. Reasoning and tool detail are COLLAPSED by default,
	// so these record deliberate exceptions rather than the common case.
	ExpandedReasoning []string  `json:"expanded_reasoning,omitempty"`
	ExpandedTools     []string  `json:"expanded_tools,omitempty"`
	SidebarWidth      int       `json:"sidebar_width,omitempty"`
	SidebarOpen       bool      `json:"sidebar_open,omitempty"`
	Theme             string    `json:"theme,omitempty"`
	ReducedMotion     bool      `json:"reduced_motion,omitempty"`
	ShowTimestamps    bool      `json:"show_timestamps,omitempty"`
	Compact           bool      `json:"compact,omitempty"`
	UpdatedAt         time.Time `json:"updated_at"`
}

InteractionState is bounded local-only UI state. It must never contain a Runtime entity row, event payload, credential, or transcript content.

type LifetimeTokenSource

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

LifetimeTokenSource reloads a token file for every resolution and supports identity-keyed in-memory replacement. Signed credentials are never persisted.

func NewTokenSource

func NewTokenSource(path, fallback string) *LifetimeTokenSource

NewTokenSource constructs a lifetime-scoped source. file may contain either one JWT or a JSON object keyed by tenant/user/session.

func (*LifetimeTokenSource) Clear

func (s *LifetimeTokenSource) Clear(scope types.IdentityScope)

Clear removes an in-memory override so file rotation or fallback resumes.

func (*LifetimeTokenSource) Replace

func (s *LifetimeTokenSource) Replace(scope types.IdentityScope, token string) error

Replace installs a process-memory credential for one complete target scope.

func (*LifetimeTokenSource) Replacement

func (s *LifetimeTokenSource) Replacement(scope types.IdentityScope) (string, bool)

Replacement returns an isolated in-memory override for rollback handling.

func (*LifetimeTokenSource) Token

Token resolves anew before each REST call and SSE connection. Static material resolves first; a configured minter is the last resort for scopes it cannot cover.

func (*LifetimeTokenSource) WithMinter

WithMinter installs a delegate consulted when the static material (override, file, fallback) cannot cover the requested scope — an embedding host's dynamic token source, or the dev server's per-session signer. Without a minter the source is pinned to the sessions its static credentials name, which makes switching to a fresh session impossible. Minted tokens pass the same claims-vs-scope validation as every other path.

type Mutation

type Mutation struct {
	Identity           types.IdentityScope
	Method             methods.Method
	RunID, PauseToken  string
	ToolID, ArtifactID string
	Payload            map[string]any
}

Mutation is one exact Protocol mutation request. App-level ActionIntent is converted to this value only after stale-context validation.

type Notifier

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

Notifier preserves every non-batchable update in a bounded queue and keeps only the newest batchable projection. Producers backpressure rather than dropping lifecycle, intervention, session, or reconciliation updates.

Coalescing a batchable update is loss-less: each Update carries the whole cumulative Projection, so the newest strictly supersedes any resident one. A coalesced update is therefore flagged only with Overflow (the honest "frames were merged" signal); it never fabricates ReconciliationRequired or a ReplayGap, because nothing was actually dropped.

func NewNotifier

func NewNotifier(capacity int) *Notifier

NewNotifier constructs a bounded controller-to-model notifier.

func (*Notifier) Close

func (n *Notifier) Close()

Close releases blocked producers and consumers.

func (*Notifier) Next

func (n *Notifier) Next(ctx context.Context) (Update, bool)

Next waits for the next preserved critical update or latest batchable state.

Critical updates take priority. Because projections are cumulative, returning a critical frame while an older batchable frame is still resident would let a later Next hand back that stale frame and regress observable state (e.g. a completed tool back to "running"). To keep newest-wins semantics, Next drops any resident latest whose cumulative LastSequence is not newer than the critical update it is about to return; a strictly newer resident frame is preserved.

func (*Notifier) Notify

func (n *Notifier) Notify(update Update)

Notify enqueues an update. Only explicitly batchable updates may coalesce.

When a batchable update supersedes a resident one, it is marked Overflow so the UI can honestly report that intermediate frames were merged. Coalescing is loss-less (the cumulative Projection carries everything the merged frames carried), so Notify never sets ReconciliationRequired or a ReplayGap on the coalesced update.

type Queue

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

Queue is a bounded ordered local follow-up queue.

func (Queue) Begin

func (q Queue) Begin() (Queue, FollowUp, bool)

Begin marks only the first pending entry as dispatching.

func (Queue) Complete

func (q Queue) Complete(id string) Queue

Complete removes a successfully dispatched local follow-up.

func (Queue) Discard

func (q Queue) Discard(id string) Queue

Discard removes failed or still-local intent and resumes ordered dispatch.

func (Queue) Enqueue

func (q Queue) Enqueue(text string) Queue

Enqueue adds local-only intent.

func (Queue) EnqueueTurn

func (q Queue) EnqueueTurn(text string, artifactIDs []string, dispositions map[string]string) Queue

EnqueueTurn adds local-only intent with artifact references retained until dispatch.

func (Queue) Entries

func (q Queue) Entries() []FollowUp

Entries returns immutable queue state.

func (Queue) Fail

func (q Queue) Fail(id string, err error) Queue

Fail retains unrelated intent and pauses automatic dispatch.

func (Queue) Remove

func (q Queue) Remove(id string) Queue

Remove removes an entry only before dispatch.

func (Queue) Retry

func (q Queue) Retry(id string) Queue

Retry returns a failed entry to the head of ordered dispatch and resumes the queue.

type RuntimeData

type RuntimeData struct {
	Identity      types.IdentityScope
	Generation    uint64
	RequestEpoch  uint64
	Stale         bool
	Tasks         tuitasks.State
	Tools         tuitools.State
	Artifacts     tuiartifacts.State
	Events        tuievents.State
	Posture       posture.State
	Interventions interventions.Inbox
	Errors        map[string]string
}

RuntimeData is the bounded canonical inspection state for the active session. Errors is keyed by surface so partial availability never becomes a zero value.

type Store

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

Store atomically persists bounded interaction state.

func NewStore

func NewStore(path string) Store

NewStore constructs a store at path.

func (Store) LastSession

func (s Store) LastSession(tenant, user, fingerprint string) (string, error)

LastSession returns the durable reference for a tenant/user and Runtime fingerprint.

func (Store) Load

func (s Store) Load(identity types.IdentityScope, fingerprint string) (InteractionState, bool, error)

Load reads, validates, expires, and returns state for the full identity and Runtime fingerprint.

func (Store) Save

func (s Store) Save(value InteractionState) error

Save validates and atomically replaces one interaction entry.

type TokenClaims

type TokenClaims struct {
	Identity  types.IdentityScope
	ExpiresAt time.Time
}

TokenClaims contains the unverified routing claims needed to choose the Protocol identity. Authenticity remains exclusively server-verified.

func ParseToken

func ParseToken(token string, now time.Time) (TokenClaims, error)

ParseToken parses JWT payload claims without treating them as authentication. It exists only to route the credential to the identity the server will verify.

type Transcript

type Transcript struct {
	Projection                                        projection.Projection
	Selected                                          int
	Follow                                            bool
	NewOutput                                         int
	Query                                             string
	Matches                                           []int
	Compact, ShowReasoning, ShowTools, ShowTimestamps bool
	// contains filtered or unexported fields
}

Transcript tracks viewport behavior over the canonical projection.

The viewport anchor is semantic, not positional: selectedID records the stable projection.Block.ID the reader is looking at so a mid-list mutation (a deleted pause/tool block) re-resolves Selected to the SAME block rather than silently shifting a scrolled reader by one row. Selected remains the derived render index; selectedID is the source of truth across Replace.

func NewTranscript

func NewTranscript(p projection.Projection) Transcript

NewTranscript starts at the semantic bottom.

func (Transcript) Export

func (t Transcript) Export(w io.Writer, options ExportOptions) error

Export writes the redacted projection as stable Markdown.

func (Transcript) Jump

func (t Transcript) Jump(direction int) Transcript

Jump moves to the next/previous semantic block matching visible preferences.

func (Transcript) NextMatch

func (t Transcript) NextMatch(direction int) Transcript

NextMatch moves the selection to the next (direction > 0) or previous (direction < 0) entry in Matches relative to the current Selected, clamping at the ends like Jump (no wrap). It is a no-op when there is no active search. Unlike Jump it walks the recorded match set rather than stepping semantic blocks, so search traversal visits exactly the matched blocks.

func (Transcript) Replace

Replace applies a new projection without yanking a scrolled-away reader.

A following transcript stays bottom-anchored. A scrolled reader keeps its SEMANTIC offset: Selected re-resolves to the previously-anchored block ID in the new slice regardless of whether the block count grew or shrank. When the anchored block was deleted, selection falls back to the nearest surviving neighbor (preferring the preceding block) instead of blindly keeping the old index, which would point at a different block after a mid-list removal.

func (Transcript) Scroll

func (t Transcript) Scroll(delta int) Transcript

Scroll moves semantic selection and disables follow unless at bottom.

func (Transcript) Search

func (t Transcript) Search(query string) Transcript

Search incrementally records deterministic block matches. Only conversation-surface kinds participate: lifecycle and event fallbacks never render on the chat surface, so a match there would select an invisible block the view cannot scroll to.

func (Transcript) SelectByID

func (t Transcript) SelectByID(id string) Transcript

SelectByID anchors the viewport to the block carrying id, disabling follow (unless the block is the tail) so a restored reader is not yanked to the bottom. A missing or unknown id is a no-op, preserving the current anchor.

func (Transcript) SelectedID

func (t Transcript) SelectedID() string

SelectedID returns the stable projection block ID the viewport is anchored to, or "" when the transcript is empty. The app layer persists this as the restore ScrollBlockID.

type Update

type Update struct {
	Identity   types.IdentityScope
	Generation uint64
	State      ConnectionState
	Projection projection.Projection
	Err        error
	Attempt    int
	Batchable  bool
	Overflow   bool
}

Update is an immutable controller notification.

type UpdateSource

type UpdateSource interface {
	Next(context.Context) (Update, bool)
}

UpdateSource yields controller updates to the terminal event loop.

func ChannelSource

func ChannelSource(updates <-chan Update) UpdateSource

ChannelSource adapts test-owned channels without adding drop behavior.

Jump to

Keyboard shortcuts

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