client

package
v0.0.11 Latest Latest
Warning

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

Go to latest
Published: Oct 10, 2026 License: MIT Imports: 11 Imported by: 1

Documentation

Overview

Package client is what a terminal client reads an agent through and what it says to it. The view takes two things in: an event Source, the agent's live stream (what is not committed yet), and a Record, its session (what is). It sends one thing out: [Intent]s, plain values a Controller acts on. The view holds nothing it can act on; whoever gives it a Controller decides what an intent does, and what follows reaches the view as events and record entries, never as a return value.

The rule behind the split is that the record is the truth for everything committed and live events carry only what is not. Package github.com/ChristopherDavenport/agentconsole/view turns the two streams into what a client renders, and package github.com/ChristopherDavenport/agentconsole/console runs the terminal client over them.

agentturn's types are the vocabulary: its events, its answers. An agentturn.Control is a Source, and Direct maps intents onto one, the only call of a Control in agentconsole's library packages.

Index

Constants

This section is empty.

Variables

View Source
var ErrNoHeadMove = errors.New("client: moving the head is not offered by this agent's control")

ErrNoHeadMove refuses a ContinueFrom to a control that cannot move the agent's head.

Functions

func CallID

func CallID(item openresponses.Item) string

CallID is the call ID of a function call or its output, "" for any other item.

func CloneItem

func CloneItem(item openresponses.Item) openresponses.Item

CloneItem returns a deep copy of item, which shares nothing with it.

func Copy added in v0.0.11

func Copy(ev agentturn.Event) (agentturn.Event, bool)

Copy returns what a view keeps of ev, sharing nothing the agent goes on changing, and false for an event a view does not read: an item the model never sees (Hidden), a response end without its response, and the events of the loop's own bookkeeping (turn_end, queued, model_blocked). An event's item is the agent's accumulator, so a subscriber copies it before its callback returns, as Live does.

What the view does not read and could be large is left out of the copy: a run end's transcript, a request's input (only its model is kept), an update's raw stream event, a response's output items (its ID, model, status and usage are kept), and a pending call's tool.

func ItemID

func ItemID(item openresponses.Item) string

ItemID is the item's own ID, "" for an item that has none.

func Live added in v0.0.11

Live subscribes to src when it is called, not when the result is first ranged over, so a client that calls it and then starts a run misses nothing, and yields what the view reads of each event, copied (Copy) inside the subscriber. Past events are not replayed, except the questions still waiting, which a Source sends a new subscriber first; a run already going is read from src's State.

Events queue without bound until the caller takes them: an in-process agent's delivery is a barrier, and a slow client must not stall the run or the recorder. The subscription ends when ctx is done or the caller stops ranging.

Types

type Abort added in v0.0.11

type Abort struct{}

Abort asks for the run that goes to stop.

type Answer added in v0.0.11

type Answer struct{ Answers []agentturn.Answer }

Answer answers the calls a run left waiting and asks for the run to go on: the permission panel's answers, one per call it asked about.

type ContinueFrom added in v0.0.11

type ContinueFrom struct{ EntryID string }

ContinueFrom asks to move the agent's head to EntryID: the next prompt continues the conversation from there, on a branch of the session.

type Controller added in v0.0.11

type Controller func(ctx context.Context, in Intent) error

Controller acts on an intent. It returns promptly: nil says the intent was taken, and an error is a refusal, which the client shows. What happens after (a run starting, going, ending, a question closing, the head moving) reaches the client as events and record entries, never as a return value. A product writes its own: one that answers some questions by rule, records an answer as a person's, or forwards to an agent elsewhere.

func Direct added in v0.0.11

func Direct(c agentturn.Control) Controller

Direct is the Controller that maps each intent onto c:

  • Prompt and Answer start c.Prompt and c.Resume on a goroutine of their own, under ctx, and return once the run has started (its run_start, seen through a subscription to c) or the call has failed before it started, with that error (agentturn.ErrRunning, say). An error after the start reaches the client in the run's agentturn.RunEnd.
  • Queue, Abort and Reply are c's own, which return at once.
  • ContinueFrom goes to c when c has a ContinueFrom(ctx, entryID) method (agentkit's Control has), and is refused with ErrNoHeadMove otherwise.

The run is under ctx: ending ctx ends the run, as it does an in-process Prompt's.

type Cost

type Cost func(model string, usage openresponses.Usage) (float64, bool)

Cost prices one model call in US dollars. It reports false for a model it has no price for.

type Intent added in v0.0.11

type Intent interface {
	// contains filtered or unexported methods
}

Intent is what the user asked of the agent, as a plain value: the view sends it to its Controller, which decides what it does.

type Prompt added in v0.0.11

type Prompt struct{ Items []openresponses.Item }

Prompt asks for a run with Items.

type Queue added in v0.0.11

type Queue struct {
	Mode  agentturn.QueueMode
	Items []openresponses.Item
}

Queue queues Items into the run that goes, or the next one, as Mode says: a steer, taken before the run's next model call, or a follow-up, taken when the run would stop.

type Record

type Record interface {
	// Follow yields a Snapshot first, or with a cursor the changes after
	// it, and then each change as the store accepts it, as
	// agentsession's Follower does.
	Follow(ctx context.Context, from agentsession.Cursor) iter.Seq2[agentsession.Change, error]
	// Verified reports whether the record is the agent's own, hashed and
	// checkable, or one synthesized from what a foreign agent said.
	Verified() bool
	// Read reads a session whole, as the caller's own: the followed one
	// for the empty ID, or another the store holds (the origin of a
	// fork, a subsession, a successor). It is what the tree and the
	// detail panes are computed from, on demand and off the follow: the
	// session it returns is a snapshot no later append reaches.
	Read(ctx context.Context, sessionID string) (*agentsession.Session, error)
	// Refs lists the refs that point at the session (the empty ID is the
	// followed one), by name. A store that keeps no refs answers with
	// agentsession.ErrNoRefs.
	Refs(ctx context.Context, sessionID string) ([]agentsession.Ref, error)
}

Record is the agent's session as a client follows it.

func RecordOf added in v0.0.11

func RecordOf(rec *session.Recorder) (Record, error)

RecordOf is the session rec writes, followed on rec's store: the record of an agent in this process. The store must be a agentsession.Follower to follow and a agentsession.Reader to read a session whole beside the recorder writing it; it may be a agentsession.RefStore for Refs. The record is verified: it is the agent's own, written by its recorder with request hashes a reader can check.

The followed session is rec's at the call: a head move rebases the recorder within its session, which a follower sees as a head change.

type Reply

type Reply struct {
	ID     string
	Answer agenttool.Answer
}

Reply answers the question ID a running call asked (agentturn.Question); the user's words are the answer's Note.

type Source added in v0.0.11

type Source interface {
	// Subscribe calls fn with each event, in order, until unsubscribe,
	// as [agentturn.Control.Subscribe] does: a question still waiting is
	// sent a new subscriber first, and no other past event.
	Subscribe(fn func(context.Context, agentturn.Event) error) (unsubscribe func())
	// State is the agent's state now: whether a run goes, the calls
	// that wait.
	State() agentturn.State
}

Source is where the view's live events come from: agentturn's events and the agent's state. An agentturn.Control is one (in process, agentkit's Kit.Control; over a wire, agentturn's front/control Dial); the view needs nothing else of it.

Jump to

Keyboard shortcuts

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