Documentation
¶
Overview ¶
Package tui is the terminal client: a Bubble Tea model over the view reconciler. It renders what view.Model says, committed rows plainly and in-flight rows marked as such, and turns keys into [client.Intent]s it sends its client.Controller. It holds nothing it can act on and keeps no runs of its own: whether a run goes is the view's, from the events, with a mark between sending a prompt or an answer and seeing its run start.
Concurrency ¶
The controller returns promptly; each intent is sent in a tea.Cmd and reported with an [intentDoneMsg] when it is refused. The view is fed by Attach on goroutines of its own and reaches the model only as ModelMsg values, which share nothing with the view. The model itself is touched by the program's goroutine alone.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Attach ¶
func Attach(ctx context.Context, rec client.Record, src client.Source, send func(tea.Msg)) (wait func())
Attach follows the record rec and the live stream of src (client.Live) into a view.View and delivers each resulting view.Model through send, as a ModelMsg; with a program, send is its Send method.
The view is not safe for concurrent use, and the two streams arrive on goroutines of their own, so every step is applied under one lock, and the model is taken and sent inside it: the program sees the models in the order the steps were applied. It cannot be applied from the program's goroutine instead. A record change's session is valid only until the follow takes its next step, so the change has to be applied before the iterator is resumed, and the program runs behind it.
The live stream subscribes before Attach returns, so a run started right after misses no event. The returned function waits for both goroutines, which stop when ctx is done.
Types ¶
type FeedErrMsg ¶
FeedErrMsg reports that the record or the live stream failed. The feed of that stream has stopped.
type InterruptMsg ¶
type InterruptMsg struct{}
InterruptMsg is an interrupt from outside the terminal, SIGINT or SIGTERM: it does what Ctrl-C does with nothing selected — a signal always interrupts, never copies. The host turns the program's own signal handling off (tea.WithoutSignalHandler) and sends this instead, since bubbletea's ends the program with an error and no abort.
type Line ¶ added in v0.0.10
type Line struct {
// Text is what was typed, without the space around it.
Text string
// Running is whether a run was going when the line was taken up.
Running bool
}
Line is a line the user submitted in the input.
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model is the Bubble Tea model.
func New ¶
func New(ctx context.Context, rec client.Record, src client.Source, act client.Controller, options ...Option) *Model
New returns the model of the agent whose session rec follows and whose events src gives, which sends what the user asks to act. The caller starts Attach with the program's Send; ctx is the context of every intent.
func (*Model) Drain ¶
Drain waits until the controller has answered every intent the model sent and the source reports no run going, or timeout, and reports whether both happened. A host calls it after the program ends and the run was aborted, before it closes the store the run is writing its end to. Call it only once the program has stopped sending messages to the model.
func (*Model) Init ¶
Init implements tea.Model. The textarea's styles and the markdown's (glamour's dark or light) depend on whether the terminal's background is dark, which the terminal is asked for.
type ModelMsg ¶
ModelMsg carries what the view renders after one more step of the record or the live stream. The feed sends one per step, in the order the steps were applied.
type Option ¶
type Option func(*Model)
Option configures New.
func WithCopier ¶
WithCopier sets where a copied selection goes. Without one a selection is still drawn, but nothing is copied.
func WithCost ¶
WithCost sets the function that prices one model call, in US dollars; it feeds the session pane's total. Without it the pane shows tokens but no cost.
func WithSubmit ¶ added in v0.0.10
WithSubmit hands each line the user submits to fn, which decides what it is. fn runs off the program's goroutine, one line at a time in the order they were submitted; its error is shown and the line is given back to the input. Without it, a line is a prompt when idle and a steer while a run goes.
func WithToolRenderers ¶ added in v0.0.8
WithToolRenderers sets the renderers of the tools' calls, by tool name; a call to any other tool shows its arguments as key=value pairs.
type Submission ¶ added in v0.0.10
type Submission struct {
Prompt []openresponses.Item
Steer []openresponses.Item
FollowUp []openresponses.Item
Reply string
}
Submission is what the model does with a line, as the submit function decided: a prompt starts a run, a steer queues into the one going, a follow-up queues for when the run would stop, and a reply is shown over the input. A reply may come with any one of them; an empty submission does nothing.