web

package
v0.13.1 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2026 License: MIT Imports: 59 Imported by: 0

Documentation

Overview

Package web is the `uam web` service: a detached per-user process that owns web-surface managed sessions, drives providers through agentapi, and serves the browser interface described in docs/adr/0004-web-interface.md.

Provider conversations and turns belong to the Manager, never to an HTTP request or an event-stream connection. Browsers only observe and submit.

Index

Constants

View Source
const (
	RunRunning   = "running"
	RunFinished  = "finished"
	RunFailed    = "failed"
	RunCancelled = "cancelled"
	RunTimeLimit = "time_limit"
	RunSkipped   = "skipped"
)

Run outcomes. A run is running from its firing until its Task's turn ends.

View Source
const (
	TriggerSchedule = "schedule"
	TriggerMissed   = "missed"
	TriggerManual   = "manual"
)

Run triggers: the schedule, the schedule's firing missed while the service was down (run once on start), or Run now.

View Source
const (
	StateIdle               = "idle"
	StateStarting           = "starting"
	StateWorking            = "working"
	StateAwaitingPermission = "awaiting_permission"
	StateAwaitingAnswer     = "awaiting_answer"
	StateCompleted          = "completed"
	StateCancelled          = "cancelled"
	StateFailed             = "failed"
	StateInterrupted        = "interrupted"
	StateClosed             = "closed"
)

Session states reported to browsers.

View Source
const (
	SubmissionAccepted  = "accepted"
	SubmissionRejected  = "rejected"
	SubmissionUncertain = "uncertain"
	SubmissionQueued    = "queued"
	SubmissionCancelled = "cancelled"
)

Submission outcomes. A queued prompt is "queued" until it is sent, then takes the send's outcome; one removed from the queue unsent is "cancelled".

View Source
const (
	StageActive   = ""
	StageSettled  = "settled"
	StageArchived = "archived"
)

Task stages. A Task is active until the user settles or archives it; archived is final.

View Source
const (
	HistoryLoaded      = "loaded"
	HistoryLoading     = "loading"
	HistoryUnavailable = "unavailable"
)

Transcript states of SessionDetail.History. A Task whose conversation is not open has its recorded transcript read without opening it: loading until a "history" event carries it, unavailable when it could not be read.

View Source
const (
	ModeSend  = "send"
	ModeQueue = "queue"
	ModeSteer = "steer"
)

Prompt modes. While a turn runs, send is refused, queue holds the prompt until the turn completes, and steer adds it to the running turn. While the Task is idle, all three send it.

View Source
const (
	ScopeSession   = "session"
	ScopeWorkspace = "workspace"
	// ScopeTask is the files this Task's agent edited, and ScopeTurn those
	// it edited in its latest turn, each compared with HEAD.
	ScopeTask = "task"
	ScopeTurn = "turn"
)

Change scopes.

View Source
const (
	// DefaultListen is the loopback address `uam web` binds by default.
	DefaultListen = "127.0.0.1:8260"
)

Variables

This section is empty.

Functions

func BeyondLoopback

func BeyondLoopback(listen string) bool

BeyondLoopback reports whether listen (host:port) binds a non-loopback IP, which other machines may reach.

func LoadOrCreateToken

func LoadOrCreateToken(path string) (string, error)

LoadOrCreateToken returns the access token stored at path, creating an owner-only file with a new random token when none exists.

func NormalizePublicOrigin

func NormalizePublicOrigin(origin string) (string, error)

NormalizePublicOrigin validates a --public-origin value and returns it as scheme://host[:port].

func RunDaemon

func RunDaemon(cfg DaemonConfig) error

RunDaemon is `uam __web`: it serves until SIGTERM or SIGINT, then shuts down gracefully. Startup errors are reported on the readiness pipe.

func SetToken

func SetToken(path, token string) error

SetToken validates token and atomically replaces the access token file at path with it: a private temp file, renamed over any existing file. A running service keeps its old token until it restarts; the new one then invalidates every session cookie, since cookies are derived from it.

func Spawn

func Spawn(ctx context.Context, exe string, args []string) error

Spawn starts `uam __web` detached, exactly like a session host: its own session, stdio on /dev/null, readiness reported on fd 3, and its own systemd scope where userScope finds one fitting. It returns once the service is serving or with the error the service reported.

func Stop

func Stop(ctx context.Context, dir string) (bool, error)

Stop asks the verified running service to shut down gracefully and waits for it. It reports false when nothing was running.

func TokenPath

func TokenPath() string

TokenPath is the access token file, next to sessions.json.

func ValidateListen

func ValidateListen(addr string) (string, error)

ValidateListen accepts an IP literal (loopback, unspecified or an interface address) or localhost, and returns host:port with an IP literal. Other host names are refused.

func ValidateToken

func ValidateToken(token string) error

ValidateToken accepts 24 to 256 printable ASCII characters without whitespace. The generated token (64 hex characters) always qualifies. The error never contains the token.

Types

type AcceptResult added in v0.12.0

type AcceptResult struct {
	Cmd     string    `json:"cmd"`
	CmdHash string    `json:"cmd_hash"`
	Head    string    `json:"head"`
	Dirty   bool      `json:"dirty"`
	Exit    int       `json:"exit"`
	Tail    string    `json:"tail"`
	RanAt   time.Time `json:"ran_at"`
	Stale   bool      `json:"stale"`
}

AcceptResult is one acceptance run. Head and Dirty are the tree it ran against; Exit is -1 when the shell did not start. Stale is stored false and set as the API sends a done request, once CmdHash is not the hash of the command its card resolves to (requestViews).

type AccountUsage

type AccountUsage struct {
	Quotas    []Quota   `json:"quotas"`
	Stale     bool      `json:"stale"`
	UpdatedAt time.Time `json:"updated_at,omitzero"`
}

AccountUsage is the GET /api/usage response: the account quotas of every provider with the usage capability, from the last read that succeeded. Stale is set while the latest read failed; UpdatedAt is when the oldest of the shown quotas was read, omitted before any read succeeded.

type AddPromptRequest added in v0.13.1

type AddPromptRequest struct {
	Name      string `json:"name"`
	Text      string `json:"text"`
	ProjectID string `json:"project_id"`
}

PromptRequest bodies: AddPromptRequest adds a prompt, RenamePromptRequest renames one.

type Ask added in v0.13.1

type Ask struct {
	Kind agentapi.InteractionKind `json:"kind"`
	// Title is a permission's title, or the first line of a question's text
	// (its header, else the interaction title, when the text is empty).
	Title string `json:"title"`
}

Ask is the request a Task waits on, as the Task list's status line and the notices name it: its kind and one line. The Task's detail carries every interaction whole.

type BackgroundTaskCancellation

type BackgroundTaskCancellation struct {
	Accepted        bool                     `json:"accepted"`
	BackgroundTasks agentapi.BackgroundTasks `json:"background_tasks"`
}

type Badge

type Badge struct {
	Text  string `json:"text"`
	Color string `json:"color"`
}

Badge is a Project's badge: Text is two uppercase ASCII letters or digits, unique among Projects; Color is one of badgeColors.

type BoardCard added in v0.12.0

type BoardCard struct {
	ID              string         `json:"id"`
	Seq             int64          `json:"seq"`
	ProjectID       string         `json:"project_id"`
	Kind            board.Kind     `json:"kind"`
	ParentID        *string        `json:"parent_id"`
	Rank            int            `json:"rank"`
	Title           string         `json:"title"`
	Desc            string         `json:"desc"`
	WinCondition    string         `json:"win_condition"`
	Status          board.Status   `json:"status"`
	Progress        *BoardProgress `json:"progress,omitempty"`
	Prio            int            `json:"prio"`
	Due             string         `json:"due,omitempty"`
	Effort          string         `json:"effort"`
	Labels          []string       `json:"labels"`
	Checklist       []board.Check  `json:"checklist"`
	Blocked         bool           `json:"blocked"`
	BlockedBy       []string       `json:"blocked_by"`
	Blocks          []string       `json:"blocks"`
	Confirmed       bool           `json:"confirmed"`
	ExpiresAt       *time.Time     `json:"expires_at,omitempty"`
	HeldBy          string         `json:"held_by,omitempty"`
	PinnedSHA       string         `json:"pinned_sha"`
	AcceptCmd       *string        `json:"accept_cmd"`
	Paths           []string       `json:"paths"`
	Stale           *Stale         `json:"stale,omitempty"`
	PendingRequests int            `json:"pending_requests"`
	Revision        int64          `json:"revision"`
	CreatedAt       time.Time      `json:"created_at"`
	UpdatedAt       time.Time      `json:"updated_at"`
	MovedAt         time.Time      `json:"moved_at"`
}

BoardCard is a card as the API sends it (ADR 0005 §14). Status and Progress are derived for containers; Progress is sent for them only, and ExpiresAt only while the card is unconfirmed. AcceptCmd is null to inherit the Project default and "" for none. Stale is sent only where it was computed, on GET /api/board for the subtasks ADR 0005 §9 names, and only when the subtask is stale: behind its pin or diverged from it.

type BoardCardDetail added in v0.12.0

type BoardCardDetail struct {
	Card     BoardCard      `json:"card"`
	Comments []BoardComment `json:"comments"`
	Requests []BoardRequest `json:"requests"`
	Holds    []BoardHold    `json:"holds"`
}

BoardCardDetail is one card with its comments, requests and attempts.

type BoardComment added in v0.12.0

type BoardComment struct {
	ID        string    `json:"id"`
	Author    string    `json:"author"`
	Body      string    `json:"body"`
	Automatic bool      `json:"automatic"`
	CreatedAt time.Time `json:"created_at"`
}

BoardComment is one comment on a card; its author is owner, task:<id> or uam.

type BoardHold added in v0.12.0

type BoardHold struct {
	ID            string     `json:"id"`
	TaskID        string     `json:"task_id"`
	Attempt       int        `json:"attempt"`
	StartedAt     time.Time  `json:"started_at"`
	BaselineHead  string     `json:"baseline_head"`
	BaselineDirty []string   `json:"baseline_dirty"`
	EndedAt       *time.Time `json:"ended_at,omitempty"`
	EndReason     string     `json:"end_reason,omitempty"`
}

BoardHold is one attempt at a subtask.

type BoardProgress added in v0.12.0

type BoardProgress struct {
	Done     int `json:"done"`
	Total    int `json:"total"`
	Proposed int `json:"proposed"`
}

BoardProgress is a container's done ÷ non-cancelled confirmed subtasks, and its unconfirmed ones.

type BoardProject added in v0.12.0

type BoardProject struct {
	AcceptCmd string `json:"accept_cmd"`
	Git       string `json:"git"`
}

BoardProject is a Project's planner settings: its default acceptance command ("" for none), and Git, the Project's no_git reason or "".

type BoardRequest added in v0.12.0

type BoardRequest struct {
	ID              string              `json:"id"`
	CardID          string              `json:"card_id"`
	TaskID          string              `json:"task_id"`
	AgentID         string              `json:"agent_id"`
	Kind            board.RequestKind   `json:"kind"`
	Comment         string              `json:"comment"`
	Payload         jsonObject          `json:"payload"`
	Evidence        jsonObject          `json:"evidence"`
	Flags           []string            `json:"flags"`
	BaseRevision    int64               `json:"base_revision"`
	Status          board.RequestStatus `json:"status"`
	CreatedAt       time.Time           `json:"created_at"`
	DecidedAt       *time.Time          `json:"decided_at,omitempty"`
	DecisionComment string              `json:"decision_comment,omitempty"`
	// DecidedBy is owner, or uam for a done request accepted automatically.
	DecidedBy board.DecidedBy `json:"decided_by,omitempty"`
}

BoardRequest is an inbox row as the API sends it. Payload and Evidence are objects, empty when the request has none.

type BoardSnapshot added in v0.12.0

type BoardSnapshot struct {
	Cards    []BoardCard    `json:"cards"`
	Requests []BoardRequest `json:"requests"`
	Revision int64          `json:"revision"`
}

BoardSnapshot is one Project's Board: every card, the pending requests, and the revision later board frames count from.

type ChangedFile

type ChangedFile struct {
	Path      string `json:"path"`
	Status    string `json:"status"`
	Additions int    `json:"additions"`
	Deletions int    `json:"deletions"`
	// Digest changes whenever the file's working-tree content may have
	// changed; it is empty where the scope cannot tell.
	Digest string `json:"digest,omitempty"`
}

ChangedFile is one entry of a Changes listing.

type Changes

type Changes struct {
	Scope     string        `json:"scope"`
	Label     string        `json:"label"`
	Supported bool          `json:"supported"`
	Reason    string        `json:"reason"`
	Files     []ChangedFile `json:"files"`
	// Counts is set on the task, turn and workspace scopes.
	Counts *ScopeCounts `json:"counts,omitempty"`
}

Changes lists changed files for one scope. Label states plainly what the scope includes.

type Chart added in v0.13.1

type Chart struct {
	ChartSpec
	ChartData
	PinnedID string `json:"pinned_id,omitempty"`
}

Chart is a chart a Task drew. PinnedID is the Project's pinned chart made from it, if any.

type ChartData added in v0.13.1

type ChartData struct {
	Labels []string      `json:"labels"`
	Series []ChartSeries `json:"series"`
	At     time.Time     `json:"at"`
}

ChartData is a chart's rows, column-wise, and when they were read.

type ChartSeries added in v0.13.1

type ChartSeries struct {
	Name   string    `json:"name"`
	Values []float64 `json:"values"`
}

ChartSeries is one y field's values, one per label.

type ChartSpec added in v0.13.1

type ChartSpec struct {
	Title   string   `json:"title"`
	Kind    string   `json:"kind"`
	XLabel  string   `json:"x_label,omitempty"`
	YLabel  string   `json:"y_label,omitempty"`
	Command string   `json:"command,omitempty"`
	Format  string   `json:"format,omitempty"`
	X       string   `json:"x"`
	Y       []string `json:"y"`
}

ChartSpec is what a chart shows and where its rows come from: Command, when set, printed them in Format; X and Y name the fields read.

type CommandRequest

type CommandRequest struct {
	RequestID   string   `json:"request_id"`
	Name        string   `json:"name"`
	Arguments   string   `json:"arguments"`
	Files       []string `json:"files"`
	Attachments []string `json:"attachments"`
}

CommandRequest is the POST /api/sessions/{id}/command body. Name is a command from GET /api/sessions/{id}/commands, without the slash.

type CommitDraft added in v0.13.1

type CommitDraft struct {
	Message      string `json:"message"`
	Conventional bool   `json:"conventional"`
	Model        string `json:"model"`
}

CommitDraft is a commit message the Utility model drafted. Conventional is whether the repository's recent subjects follow Conventional Commits.

type CreateRequest

type CreateRequest struct {
	ProjectID   string `json:"project_id"`
	Provider    string `json:"provider"`
	Model       string `json:"model"`
	Effort      string `json:"effort"`
	ContextSize string `json:"context_size"`
	Name        string `json:"name"`
	Prompt      string `json:"prompt"`
	RequestID   string `json:"request_id"`
	// Mode is safe (also when empty) or yolo.
	Mode string `json:"mode"`
	// contains filtered or unexported fields
}

CreateRequest is the POST /api/sessions body. Name may be empty; the provider's title is shown until the user names the Task.

type CustomModel added in v0.9.0

type CustomModel struct {
	Name        string `json:"name"`
	DisplayName string `json:"display_name,omitempty"`
	BaseURL     string `json:"base_url"`
	ModelID     string `json:"model_id"`
	WireAPI     string `json:"wire_api,omitempty"`
	APIKeyEnv   string `json:"api_key_env"`
	KeyPresent  bool   `json:"key_present"`
}

CustomModel is one custom model in Settings. APIKeyEnv only names the service environment variable holding the key; KeyPresent says whether it is set and non-empty there. No key value is ever sent.

type DaemonConfig

type DaemonConfig struct {
	Listen        string
	PublicOrigins []string
	Providers     []agentapi.Provider
	Version       string
	// LogHeaders logs every request's headers (see ServerConfig).
	LogHeaders bool
}

DaemonConfig configures `uam __web`.

type DaemonState

type DaemonState struct {
	PID           int      `json:"pid"`
	StartTime     int64    `json:"start_time"`
	Listen        string   `json:"listen"`
	PublicOrigins []string `json:"public_origins,omitempty"`
	// LegacyNoAuth detects unsupported insecure daemons written by older
	// versions. New daemons never set this field.
	LegacyNoAuth bool      `json:"no_auth,omitempty"`
	LogHeaders   bool      `json:"log_headers,omitempty"`
	Version      string    `json:"version"`
	StartedAt    time.Time `json:"started_at"`
}

DaemonState is web.json: how to find and verify the running service. It never contains the access token.

func ReadRunning

func ReadRunning(dir string) (DaemonState, bool)

ReadRunning returns the running service's state after verifying that its PID still names the same process. A stale file reports not running.

func (DaemonState) LocalAddr

func (st DaemonState) LocalAddr() string

LocalAddr is the host:port clients on this host connect to: the listen address, with an unspecified host replaced by loopback on the same port (0.0.0.0 by 127.0.0.1, :: by ::1).

func (DaemonState) URL

func (st DaemonState) URL() string

URL is the address browsers on this host use (see LocalAddr).

type DiffStat added in v0.13.1

type DiffStat struct {
	Files     int `json:"files"`
	Additions int `json:"additions"`
	Deletions int `json:"deletions"`
}

DiffStat totals a list of changed files.

type DirEntry

type DirEntry struct {
	Name string `json:"name"`
	Path string `json:"path"`
	// Git means the folder holds .git, a directory or, in a linked worktree,
	// a file.
	Git    bool `json:"git"`
	Hidden bool `json:"hidden"`
	// Link means the entry is a symbolic link to a directory.
	Link bool `json:"link"`
}

DirEntry is one folder in a listing. Name is the last element of Path; both are displayable as they are (see displayable).

type DirList

type DirList struct {
	Path      string     `json:"path"`
	Parent    string     `json:"parent,omitempty"`
	Entries   []DirEntry `json:"entries"`
	Truncated bool       `json:"truncated"`
}

DirList answers GET /api/fs/dirs. Parent is empty at /.

type DiscoverRequest added in v0.9.0

type DiscoverRequest struct {
	BaseURL   string `json:"base_url"`
	APIKeyEnv string `json:"api_key_env"`
	WireAPI   string `json:"wire_api"`
}

DiscoverRequest names an OpenAI-compatible endpoint whose models to list.

type DiscoverResult added in v0.9.0

type DiscoverResult struct {
	Models     []string `json:"models"`
	Truncated  bool     `json:"truncated,omitempty"`
	KeyPresent bool     `json:"key_present"`
}

DiscoverResult is what the endpoint lists: sorted, distinct model IDs that could be stored, at most maxDiscoverIDs (Truncated when more were listed). KeyPresent is true: discovery refuses a missing key.

type Error

type Error struct {
	Status  int
	Message string
	// ProjectID names the existing Project when adding a directory that
	// already has one.
	ProjectID string
	// Code classifies a planner refusal (ADR 0005 §14): planner_off, no_git,
	// holds_undecided, or a board rule's code. Refs lists what a board rule
	// refused over, such as open checklist items, and Cards are the held
	// subtasks a holds_undecided refusal asks about.
	Code  string
	Refs  []string
	Cards []BoardCard
}

Error is a failure with the HTTP status the server reports for it.

func (*Error) Error

func (e *Error) Error() string

type Evidence added in v0.12.0

type Evidence struct {
	Baseline   board.Baseline      `json:"baseline"`
	Diff       EvidenceDiff        `json:"diff"`
	Commits    []EvidenceCommit    `json:"commits"`
	Accept     *AcceptResult       `json:"accept,omitempty"`
	Transcript *EvidenceTranscript `json:"transcript,omitempty"`
	Checklist  EvidenceChecklist   `json:"checklist"`
	// contains filtered or unexported fields
}

Evidence is a done request's evidence (ADR 0005 §14).

type EvidenceCheck added in v0.13.1

type EvidenceCheck struct {
	ItemID string `json:"item_id"`
	// Kinds are the checks it runs: test, build, lint, vet, typecheck.
	Kinds   []string `json:"kinds"`
	Command string   `json:"command"`
	// Outcome is pass, fail, unclear or running: the worst of its checks.
	Outcome string `json:"outcome"`
	Exit    *int   `json:"exit,omitempty"`
	// Counts is what its output counted ("2 packages ok").
	Counts string `json:"counts,omitempty"`
	TookMS *int64 `json:"took_ms,omitempty"`
	// Note says why the outcome is unclear, or how it passed.
	Note      string `json:"note,omitempty"`
	HasOutput bool   `json:"has_output"`
	// contains filtered or unexported fields
}

EvidenceCheck is one command of a turn that runs checks.

type EvidenceChecklist added in v0.12.0

type EvidenceChecklist struct {
	Done  int `json:"done"`
	Total int `json:"total"`
}

EvidenceChecklist is the subtask's checklist state.

type EvidenceClaim added in v0.13.1

type EvidenceClaim struct {
	Text     string `json:"text"`
	Verified bool   `json:"verified"`
	// Detail is what backs it ("go test ./... · exit 0"), or "Not verified ·
	// why".
	Detail string `json:"detail"`
}

EvidenceClaim is one sentence of a turn's final message that claims what evidence should back.

type EvidenceCommit added in v0.12.0

type EvidenceCommit struct {
	SHA     string `json:"sha"`
	Subject string `json:"subject"`
}

EvidenceCommit is one commit since the baseline.

type EvidenceDiff added in v0.12.0

type EvidenceDiff struct {
	Added   int            `json:"added"`
	Deleted int            `json:"deleted"`
	Files   []EvidenceFile `json:"files"`
}

EvidenceDiff is the working tree compared with the baseline HEAD, plus the untracked files. A path already dirty at the baseline appears only when its content changed since. The totals count every file; Files lists at most maxChangedFiles.

type EvidenceFile added in v0.12.0

type EvidenceFile struct {
	Path     string           `json:"path"`
	Added    int              `json:"added"`
	Deleted  int              `json:"deleted"`
	ByTask   bool             `json:"by_task"`
	PreDirty bool             `json:"pre_dirty"`
	Overlap  *EvidenceOverlap `json:"overlap,omitempty"`
}

EvidenceFile is one changed file. ByTask is set when the claiming Task's edit tools touched it, and Overlap names another live hold whose Task touched it. PreDirty marks a path already dirty at the baseline; its line counts include the changes it had then.

type EvidenceOverlap added in v0.12.0

type EvidenceOverlap struct {
	Card   int64  `json:"card"`
	TaskID string `json:"task_id"`
}

EvidenceOverlap is another live hold: its subtask's #seq and its Task.

type EvidenceTranscript added in v0.12.0

type EvidenceTranscript struct {
	TaskID   string `json:"task_id"`
	FromItem string `json:"from_item"`
	ToItem   string `json:"to_item"`
	Partial  bool   `json:"partial,omitempty"`
}

EvidenceTranscript is the span of the claiming Task's transcript. Partial is set when the transcript uam holds does not reach back to the hold's start, so the files marked by_task may be incomplete.

type FileEntry

type FileEntry struct {
	Path string `json:"path"`
	// Type is "file" or "directory".
	Type string `json:"type"`
	// Status is set by Tree only: a file's working-tree status as Changes names
	// it ("modified", "added", "untracked", "deleted", ...), or "changed" for a
	// folder that holds changed files. Empty when unchanged or unknown.
	Status string `json:"status,omitempty"`
}

FileEntry is one project path the composer can reference.

type FileList

type FileList struct {
	Files  []FileEntry `json:"files"`
	Reason string      `json:"reason"`
}

FileList answers GET /api/sessions/{id}/files and GET /api/projects/{id}/files. Reason says why the list is empty or cut short.

type GitFile added in v0.13.1

type GitFile struct {
	ChangedFile
	Mine      bool `json:"mine,omitempty"`
	OtherTask bool `json:"other_task,omitempty"`
}

GitFile is a changed file of the repository. Mine is set when this Task's edit tools touched it; OtherTask when another Task's did and this one's did not. Both come from the Tasks' edit records (task_changes.go).

type GitResult added in v0.13.1

type GitResult struct {
	Summary string `json:"summary"`
	Commit  string `json:"commit,omitempty"`
	Output  string `json:"output,omitempty"`
}

GitResult is a finished write action: a sentence saying what happened, the new commit when one was made, and git's output.

type GitState added in v0.13.1

type GitState struct {
	// Repo is false when the Task's directory is in no repository; Reason
	// then says why, and CanInit whether "Set up git here" may run.
	Repo    bool   `json:"repo"`
	Reason  string `json:"reason,omitempty"`
	CanInit bool   `json:"can_init,omitempty"`
	// Branch is empty when HEAD is detached. Upstream is the branch's
	// upstream, such as origin/main; Ahead and Behind count commits against
	// it as last fetched. Remote is whether Push has somewhere to go.
	Branch   string `json:"branch,omitempty"`
	Upstream string `json:"upstream,omitempty"`
	Ahead    int    `json:"ahead"`
	Behind   int    `json:"behind"`
	Remote   bool   `json:"remote"`
	// HasCommits is false before the first commit.
	HasCommits bool      `json:"has_commits"`
	Files      []GitFile `json:"files"`
	// TaskFilesKnown is false when this Task's edits from before its history
	// was read may be missing (after a restart), so Mine may be incomplete.
	TaskFilesKnown bool `json:"task_files_known"`
	// Busy says why write actions are refused now; empty when they may run.
	Busy string `json:"busy,omitempty"`
}

GitState is what the commit panel shows for a Task's repository.

type HistoryPage added in v0.11.0

type HistoryPage struct {
	Seq    uint64          `json:"seq"`
	Items  []agentapi.Item `json:"items"`
	Before string          `json:"before"`
}

HistoryPage is a backwards page of complete items, oldest first. Before is opaque and empty at the beginning of retained history. One oversized item is returned alone, rather than silently truncating it or preventing progress.

type HoldDecision added in v0.12.0

type HoldDecision struct {
	Action  string `json:"action"`
	Comment string `json:"comment"`
}

HoldDecision is what Settle does with one subtask the Task holds (ADR 0005 §5): keep it held until the Task is reopened, release it to todo, or cancel it, which needs a comment.

type LaunchRequest added in v0.12.0

type LaunchRequest struct {
	Provider    string `json:"provider"`
	Model       string `json:"model"`
	Effort      string `json:"effort"`
	ContextSize string `json:"context_size"`
	Mode        string `json:"mode"`
	Brief       string `json:"brief"`
}

LaunchRequest is the launch and plan body (ADR 0005 §14): the new Task's selection, where an empty model takes the Task defaults in Settings, and a plan's brief.

type MCPSecret added in v0.13.1

type MCPSecret struct {
	Key string `json:"key"`
	Set bool   `json:"set"`
}

MCPSecret is one env variable or header: its name and whether a value is stored. The value itself is never sent.

type MCPSecretInput added in v0.13.1

type MCPSecretInput struct {
	Key   string  `json:"key"`
	Value *string `json:"value"`
}

MCPSecretInput is one env variable or header of an add or edit. A nil Value on an edit keeps the stored one.

type MCPServerInput added in v0.13.1

type MCPServerInput struct {
	Name    string           `json:"name"`
	Type    string           `json:"type"`
	Command string           `json:"command"`
	Args    []string         `json:"args"`
	Cwd     string           `json:"cwd"`
	URL     string           `json:"url"`
	Env     []MCPSecretInput `json:"env"`
	Headers []MCPSecretInput `json:"headers"`
}

MCPServerInput is the body of an add or edit.

type MCPServerView added in v0.13.1

type MCPServerView struct {
	Name    string      `json:"name"`
	Type    string      `json:"type"`
	Command string      `json:"command,omitempty"`
	Args    []string    `json:"args,omitempty"`
	Cwd     string      `json:"cwd,omitempty"`
	URL     string      `json:"url,omitempty"`
	Env     []MCPSecret `json:"env"`
	Headers []MCPSecret `json:"headers"`
	Enabled bool        `json:"enabled"`
	Source  string      `json:"source"`
}

MCPServerView is one configured server as the browser sees it.

type MCPServers added in v0.13.1

type MCPServers struct {
	Available    bool            `json:"available"`
	StdioAllowed bool            `json:"stdio_allowed"`
	Servers      []MCPServerView `json:"servers"`
}

MCPServers is GET /api/mcp. Available is false when no provider manages MCP servers; StdioAllowed mirrors the Terminal setting.

type MCPSignIn added in v0.13.1

type MCPSignIn struct {
	URL   string `json:"url,omitempty"`
	Relay bool   `json:"relay,omitempty"`
}

MCPSignIn is the answer to starting a sign-in. URL is empty when a kept sign-in sufficed. Relay is true when the browser may paste the address it ends on, for the service to pass to the provider's loopback listener.

type Manager

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

Manager owns every web session, its provider conversation, and the event fan-out to browsers.

Two locks per session keep provider callbacks non-blocking: session.op serializes operations that call the provider (open, send, close) and may be held across those calls, while Manager.mu guards all observable state and is only ever held for short, allocation-bounded sections. Provider events take only Manager.mu, so a slow provider call or an absent browser never delays event processing.

func NewManager

func NewManager(st *store.Store, providers []agentapi.Provider) *Manager

NewManager builds a manager for providers. Start must run before use.

func (*Manager) AcceptRequest added in v0.12.0

func (m *Manager) AcceptRequest(id, comment string) (BoardRequest, error)

AcceptRequest accepts the pending request id with the owner's comment.

func (*Manager) Account added in v0.13.1

func (m *Manager) Account(ctx context.Context, name string) (agentapi.Account, error)

Account reads a provider's sign-in and brings its availability in line with it.

func (*Manager) AccountUsage

func (m *Manager) AccountUsage() AccountUsage

AccountUsage returns the cached account quotas.

func (*Manager) AddProject

func (m *Manager) AddProject(dir, name string) (Project, error)

AddProject adds the directory dir as a Project and gives it a badge. A directory has at most one Project; adding it again reports the existing one with 409.

func (*Manager) AddPrompt added in v0.13.1

func (m *Manager) AddPrompt(req AddPromptRequest) (SavedPrompt, error)

AddPrompt saves a new prompt and returns it.

func (*Manager) AllRoutines added in v0.13.1

func (m *Manager) AllRoutines() []Routine

AllRoutines lists every Project's routines, oldest first.

func (*Manager) Answer

func (m *Manager) Answer(id, interactionID string, answer agentapi.Answer) (agentapi.Interaction, error)

Answer forwards the user's answer to a pending interaction. The first answer wins. The service answers on the user's behalf only for permission requests of a yolo Task, and never for questions.

func (*Manager) Archive

func (m *Manager) Archive(id string) (SessionSummary, error)

Archive moves an active or settled Task to its final stage; nothing moves it back. An active Task must meet the same conditions as for Settle. Archiving ends the Task's planner calls in progress, then releases its planner holds.

func (*Manager) Attachment

func (m *Manager) Attachment(id, attachmentID string) (agentapi.Attachment, []byte, time.Time, error)

Attachment returns one stored upload of a Task and its bytes.

func (*Manager) Board added in v0.12.0

func (m *Manager) Board(projectID string) (BoardSnapshot, error)

Board returns projectID's Board, or the Unassigned list for "unassigned". Each subtask staleness is computed for (ADR 0005 §9) carries it when HEAD has moved past its pin; when git cannot tell, the cards go without.

func (*Manager) BoardProject added in v0.12.0

func (m *Manager) BoardProject(id string) (BoardProject, error)

BoardProject returns the Project id's planner settings.

func (*Manager) Cancel

func (m *Manager) Cancel(id string) (SessionSummary, error)

Cancel aborts the running turn. It is distinct from a viewer leaving and from Close: the conversation stays open.

func (*Manager) CancelBackgroundTask

func (m *Manager) CancelBackgroundTask(id, taskID string) (BackgroundTaskCancellation, error)

func (*Manager) CancelQueued

func (m *Manager) CancelQueued(id, reqID string) error

CancelQueued removes one prompt from the queue before it is sent. It never contacts the provider. Cancelling it again succeeds; a prompt already sent is refused with 409.

func (*Manager) CancelSubagent

func (m *Manager) CancelSubagent(id, agentID string) (agentapi.Subagent, error)

CancelSubagent stops only the selected agent. Successful repeats never resend, and final status is supplied by the provider's subagent event.

func (*Manager) CardDetail added in v0.12.0

func (m *Manager) CardDetail(ref string) (BoardCardDetail, error)

CardDetail returns the card ref with its comments, requests and attempts. A card on a Project with no repository is refused, as its Board is.

func (*Manager) Changes

func (m *Manager) Changes(ctx context.Context, id, scope string) (Changes, error)

Changes lists changed files for a session in the requested scope. It also re-reads the branch of the session's Project.

func (*Manager) CheckCard added in v0.12.0

func (m *Manager) CheckCard(ref string) (string, error)

CheckCard starts "Check at HEAD" (ADR 0005 §9) on the subtask ref: a job that runs its resolved acceptance command in its Project's working tree through the Project's runner, as a done claim would. What can be told at once is checked before the job starts: a subtask, of a Project with git, with a command. The run can outlast what a proxy lets a request take, so its outcome comes in board_job frames: done with the run, red or green (exit -1 when the shell did not start), or failed with why, such as a runner still busy past the timeout. The run is recorded nowhere: green rows go stale only in done requests' evidence, which carries the command's hash. It returns the job ID.

func (*Manager) ClearQueue

func (m *Manager) ClearQueue(id string) error

ClearQueue removes every queued prompt, as CancelQueued does one.

func (*Manager) Close

func (m *Manager) Close(id string) (SessionSummary, error)

Close disconnects the conversation and keeps the record.

func (*Manager) Command

func (m *Manager) Command(id string, req CommandRequest) (Submission, error)

Command runs one of the provider's listed commands. It follows the rules of a send: a repeated request ID returns the recorded outcome, a running turn refuses it, and there is no queue or steer.

func (*Manager) Commands

func (m *Manager) Commands(ctx context.Context, id string) ([]agentapi.Command, error)

Commands lists the live catalogue, reopening only the exact conversation of an active Task. Discovery never submits a prompt.

func (*Manager) CommentCard added in v0.12.0

func (m *Manager) CommentCard(ref, body string) (BoardComment, error)

CommentCard adds the owner's comment to the card ref.

func (*Manager) CompactDetail added in v0.11.0

func (m *Manager) CompactDetail(id string) (compactSessionDetail, error)

func (*Manager) CompactHistoryPage added in v0.11.0

func (m *Manager) CompactHistoryPage(id, agent, before, after string) (compactHistoryPage, error)

CompactHistoryPage returns the page before (or after) the item a cursor names. Past the retained items it reads the provider's record without Manager.mu; a page never needs more than two reads.

func (*Manager) CompactOlderHistory added in v0.11.0

func (m *Manager) CompactOlderHistory(id, agent, before string) (compactHistoryPage, error)

func (*Manager) CompactSubagent added in v0.11.0

func (m *Manager) CompactSubagent(id, agent string) (compactSubagentDetail, error)

CompactSubagent returns a subagent with its newest page, read from the record when its transcript is not retained, and its record when it is not held.

func (*Manager) Create

func (m *Manager) Create(req CreateRequest) (SessionSummary, error)

Create opens a new provider conversation in a Project's directory, records the session (a Task), and, when a prompt is given, submits it through the same path as Submit.

func (*Manager) CreateCard added in v0.12.0

func (m *Manager) CreateCard(in board.NewCard) (BoardCard, error)

CreateCard is the owner's create; the card is confirmed. A card under a parent goes to the parent's Project.

func (*Manager) CreateRoutine added in v0.13.1

func (m *Manager) CreateRoutine(projectID string, in RoutineInput) (Routine, error)

CreateRoutine adds a routine to a Project. Without a model it takes the one New task starts with; it is enabled, in safe mode, with the default limits unless the input says otherwise.

func (*Manager) Delete

func (m *Manager) Delete(id string) error

Delete deletes an archived Task's record and its stored attachments. It is refused for any other stage. The conversation is never deleted at the provider.

func (*Manager) DeletePrompt added in v0.13.1

func (m *Manager) DeletePrompt(id string) error

DeletePrompt deletes prompt id.

func (*Manager) DeleteRoutine added in v0.13.1

func (m *Manager) DeleteRoutine(id string) error

DeleteRoutine removes a routine and its run history. Tasks its runs started stay, a running one included.

func (*Manager) Detail

func (m *Manager) Detail(id string) (SessionDetail, error)

Detail returns one session with its retained transcript. Asking for it starts a read-only load of the recorded transcript when the conversation is not open and the transcript is not in memory.

func (*Manager) DiscoverModels added in v0.9.0

func (m *Manager) DiscoverModels(ctx context.Context, req DiscoverRequest) (DiscoverResult, error)

DiscoverModels lists the models an OpenAI-compatible endpoint serves with one GET of base_url + "/models", authenticated with the key read from the named UAM_BYOM_ variable. Only the IDs come back; an upstream failure is reported by status line or kind, never by its body.

func (*Manager) DraftCommitMessage added in v0.13.1

func (m *Manager) DraftCommitMessage(ctx context.Context, id string, paths []string) (CommitDraft, error)

DraftCommitMessage asks the Utility model for a commit message for the chosen changed files, in the style of the repository's recent subjects. It never commits.

func (*Manager) DropSubscribers

func (m *Manager) DropSubscribers()

DropSubscribers disconnects every event stream, for server shutdown.

func (*Manager) EditCard added in v0.12.0

func (m *Manager) EditCard(ref string, p board.Patch) (BoardCard, error)

EditCard is the owner's edit of any field; it confirms the card. Moving an Unassigned card into a Project pins it to that Project's HEAD.

func (*Manager) ExportMarkdown added in v0.13.1

func (m *Manager) ExportMarkdown(ctx context.Context, id string) ([]byte, string, error)

ExportMarkdown returns Task id's conversation as Markdown and a file name for it.

func (*Manager) FileChange

func (m *Manager) FileChange(ctx context.Context, id, scope, path string) (agentapi.FileDiff, error)

FileChange returns one file's diff in the requested scope. The path must be one the scope's listing reports.

func (*Manager) Files

func (m *Manager) Files(ctx context.Context, id, q string, limit int) (FileList, error)

Files lists up to limit paths in the Task's directory whose path matches q, for the @ picker. Git lists them, so .gitignore applies; parent directories are added, symbolic links are left out.

func (*Manager) FinishMCPSignIn added in v0.13.1

func (m *Manager) FinishMCPSignIn(id, name, pasted string) error

FinishMCPSignIn passes the pasted callback address to the provider's loopback listener. Only the pending sign-in's exact listener (port and path) and state are accepted; the pending entry is used once.

func (*Manager) GitCommit added in v0.13.1

func (m *Manager) GitCommit(ctx context.Context, id string, paths []string, message string) (GitResult, error)

GitCommit stages exactly paths, deletions included, and commits them with message as given. Paths must be changed files git reports; anything else already staged stays staged and out of the commit.

func (*Manager) GitInit added in v0.13.1

func (m *Manager) GitInit(ctx context.Context, id string) (GitState, error)

GitInit sets up a repository in the Task's Project directory, only when git says that directory is in none, and re-reads the Project's git state.

func (*Manager) GitPull added in v0.13.1

func (m *Manager) GitPull(ctx context.Context, id string) (GitResult, error)

GitPull fast-forwards the current branch to its upstream, and nothing else: it never merges or rebases.

func (*Manager) GitPush added in v0.13.1

func (m *Manager) GitPush(ctx context.Context, id string) (GitResult, error)

GitPush pushes the current branch, never forced: to its upstream when it has one, else to origin under its own name, setting that as upstream.

func (*Manager) GitState added in v0.13.1

func (m *Manager) GitState(ctx context.Context, id string) (GitState, error)

GitState reads the Task's repository: its branch, its changed files with whose they are, and whether write actions may run now.

func (*Manager) Import

func (m *Manager) Import(ctx context.Context, projectID, convID string) (SessionSummary, error)

Import creates an active Task linked to a previous conversation of a Project's directory. Nothing is sent. The Task starts closed with the transcript read without opening the conversation; its next prompt opens it. It keeps the conversation's model when the provider offers it, otherwise takes the Task defaults of Settings, and it takes their mode. A conversation another client holds open, or a Task is linked to, is refused with 409.

func (*Manager) ImportBoard added in v0.12.0

func (m *Manager) ImportBoard(ctx context.Context, dir string) (board.ImportReport, error)

ImportBoard imports the external board database kept in dir, an absolute directory path, into the planner store (board.Store.Import); it is refused while the planner is off. A source project goes to the git Project with exactly its name, compared case-sensitively. A name that no git Project has, or that several share, leaves its cards in Unassigned.

func (*Manager) ItemBody added in v0.11.0

func (m *Manager) ItemBody(id, agent, item string) (itemBody, error)

ItemBody returns one item whole: read from the provider's record when it is not retained, or retained clipped, and the record can be paged.

func (*Manager) Launch added in v0.12.0

func (m *Manager) Launch(ref string, req LaunchRequest) (BoardCard, SessionSummary, error)

Launch starts a Task on the card ref (ADR 0005 §5). On a subtask it holds that subtask; on a container it is "Do whole story" and holds the first pending one. It returns the held subtask and the Task.

func (*Manager) LinkCards added in v0.12.0

func (m *Manager) LinkCards(blocker, blocked string, link bool) error

LinkCards records that blocker blocks blocked, or with link false removes the link between them.

func (*Manager) List

func (m *Manager) List() []SessionSummary

List returns every web session, newest first.

func (*Manager) MCPServers added in v0.13.1

func (m *Manager) MCPServers() (MCPServers, error)

MCPServers lists the configured servers without their secret values.

func (*Manager) OlderHistory added in v0.11.0

func (m *Manager) OlderHistory(id, before string) (HistoryPage, error)

OlderHistory uses an item boundary, so concurrent appends cannot move the page. Eviction or replacement of the boundary requires a fresh snapshot.

func (*Manager) OlderSubagents added in v0.11.0

func (m *Manager) OlderSubagents(id, before string) (compactSubagentPage, error)

OlderSubagents returns the page of subagents recorded before the one an archive cursor names, from the record.

func (*Manager) PinChart added in v0.13.1

func (m *Manager) PinChart(taskID, callID string) (PinnedChart, error)

PinChart pins the chart the Task taskID drew with the call callID to the Task's Project, with its rows; a chart pinned already is returned as it is.

func (*Manager) PinnedCharts added in v0.13.1

func (m *Manager) PinnedCharts(id string) ([]PinnedChart, error)

PinnedCharts returns the charts pinned to the Project id with their rows.

func (*Manager) Plan added in v0.12.0

func (m *Manager) Plan(ref string, req LaunchRequest) (SessionSummary, error)

Plan starts a planning Task scoped to the container ref (ADR 0005 §4): it creates and edits under the container and holds nothing.

func (*Manager) Previous

func (m *Manager) Previous(projectID string) ([]PreviousConversation, error)

Previous lists, newest first and at most maxPrevious, the conversations that providers able to import recorded for a Project's directory and that no Task is linked to, each marked while another client holds it open.

func (*Manager) PreviousCounts

func (m *Manager) PreviousCounts(ctx context.Context) (map[string]int, error)

PreviousCounts lists each provider once without holder checks. Counts use the same cap and linked-conversation exclusions as the Project list.

func (*Manager) ProjectFiles added in v0.10.4

func (m *Manager) ProjectFiles(ctx context.Context, projectID, q string, limit int) (FileList, error)

ProjectFiles is Files for a Project's directory, for the @ picker of a new Task that has no conversation yet.

func (*Manager) Projects

func (m *Manager) Projects() []Project

Projects returns every Project, oldest first.

func (*Manager) PromptSubagent

func (m *Manager) PromptSubagent(id, agentID, text, requestID string) (Submission, error)

PromptSubagent sends text to one idle subagent of an active Task whose conversation is open and runs no turn. The follow-up is not a Task turn: the Task's state, queue and last submission stay as they are, and the subagent's status arrives through its events. A repeated request ID returns the recorded outcome without contacting the provider.

func (*Manager) Providers

func (m *Manager) Providers() []ProviderInfo

Providers lists every provider with its availability.

func (*Manager) PurgeBoard added in v0.12.0

func (m *Manager) PurgeBoard(projectID string) (int, error)

PurgeBoard hard-deletes projectID's cancelled cards whose whole subtree is cancelled, and returns how many went.

func (*Manager) RawImage added in v0.10.1

func (m *Manager) RawImage(id, p string) (*ServedFile, error)

RawImage opens the image at p, absolute or relative to the Task's directory, for the raw file route. Symbolic links are resolved first and the real file must lie inside the Task's real directory; anything else, missing files included, is a 404 that says nothing more. Only a regular file whose extension and bytes agree on png, jpeg, gif or webp, at most maxServedImageBytes, is served.

func (*Manager) RecentWorkdirs

func (m *Manager) RecentWorkdirs() []string

RecentWorkdirs returns distinct workdirs of stored records of any surface, most recently seen first.

func (*Manager) ReconnectTaskMCP added in v0.13.1

func (m *Manager) ReconnectTaskMCP(id string) error

ReconnectTaskMCP closes a quiet Task's conversation so the next read reopens it with the servers configured now: a conversation keeps the configuration it opened with.

func (*Manager) RefreshChart added in v0.13.1

func (m *Manager) RefreshChart(ctx context.Context, projectID, id string, auto bool) (PinnedChart, error)

RefreshChart runs the command of the chart id pinned to the Project projectID again in the Project directory and keeps the rows it reads, or the reason it failed beside the last good rows. No model takes part.

On demand (auto false) a chart refreshes at most once a minute: sooner, or while it refreshes, the call is refused. auto is the refresh when the owner opens the Project's charts: at most once an hour, and otherwise it returns the chart as it is, as it does for a snapshot.

func (*Manager) RefreshModels

func (m *Manager) RefreshModels()

RefreshModels reloads the catalog of every available provider whose copy is older than modelsMaxAge. A failed load keeps the previous catalog and is retried after modelsMaxAge.

func (*Manager) RejectRequest added in v0.12.0

func (m *Manager) RejectRequest(id, reason string) (Rejection, error)

RejectRequest rejects the pending request id with reason (ADR 0005 §14). While the requesting Task is Active its hold stays, and the reason goes to the Task through its send path, as a steer while a turn runs. Otherwise the store releases the hold with the reason as a comment.

func (*Manager) RemoveMCPServer added in v0.13.1

func (m *Manager) RemoveMCPServer(name string) error

RemoveMCPServer and SetMCPServerEnabled change a user-configured server. Neither starts a new command, so neither needs Terminal.

func (*Manager) RemoveProject

func (m *Manager) RemoveProject(id string) error

RemoveProject deletes a Project and its Task records. It is refused unless every Task in it is archived. Conversations are never deleted at the provider, and the directory is not touched. The Project's planner cards move to Unassigned.

func (*Manager) Rename

func (m *Manager) Rename(id, name string) (SessionSummary, error)

Rename sets the Task's typed name. An empty name shows the Task's title again; the provider's conversation is not renamed. A title job running meanwhile leaves the Task alone.

func (*Manager) RenamePrompt added in v0.13.1

func (m *Manager) RenamePrompt(id, name string) (SavedPrompt, error)

RenamePrompt renames prompt id.

func (*Manager) Reopen

func (m *Manager) Reopen(id string) (SessionSummary, error)

Reopen makes a settled Task active again. Its next prompt reopens the same conversation.

func (*Manager) Rerun added in v0.13.1

func (m *Manager) Rerun(id string, req RerunRequest) (SessionSummary, error)

Rerun creates a Task in Task id's Project with its settings, the model req names when it names one, and its last message as the first message. The new Task records id as rerun_of. A message's attachments are not sent again. The effort and context size go back to their defaults with another model.

func (*Manager) ResumeQueue

func (m *Manager) ResumeQueue(id string) error

ResumeQueue lets a paused queue drain again: at once when no turn is running, otherwise after the running turn completes.

func (*Manager) Routines added in v0.13.1

func (m *Manager) Routines(projectID string) ([]Routine, error)

Routines lists a Project's routines, oldest first.

func (*Manager) RunRoutine added in v0.13.1

func (m *Manager) RunRoutine(id string) (Routine, error)

RunRoutine fires a routine now, paused or not, under the same rules as its schedule: it is skipped while the previous run is still running or once the day's runs reached the limit. Its next scheduled run does not move.

func (*Manager) SaveMCPServer added in v0.13.1

func (m *Manager) SaveMCPServer(name string, in MCPServerInput, existing bool) error

SaveMCPServer adds a server (existing false) or replaces the one named name. A server that runs a command needs Terminal on, checked under settingsMu so the setting cannot turn off while the change is written.

func (*Manager) SetBoardProject added in v0.12.0

func (m *Manager) SetBoardProject(id, acceptCmd string) (BoardProject, error)

SetBoardProject sets the Project id's default acceptance command, and returns it as stored (trimmed).

func (*Manager) SetMCPServerEnabled added in v0.13.1

func (m *Manager) SetMCPServerEnabled(name string, enabled bool) error

func (*Manager) SetMode

func (m *Manager) SetMode(id, mode string) (SessionSummary, error)

SetMode sets the Task's permission mode at any time, even while a turn runs. It applies to permission requests raised afterwards; switching to yolo also answers the ones already pending.

func (*Manager) SetModel

func (m *Manager) SetModel(id string, model, effort, contextSize *string) (SessionSummary, error)

SetModel changes the supplied settings together for the Task's next turns. An omitted effort or context size survives a model change when supported. With the conversation open, settings are stored only after provider success; otherwise the next open applies them. Changes during a turn are refused.

func (*Manager) SetViewing added in v0.13.1

func (m *Manager) SetViewing(page, task string)

SetViewing records the Task page shows while it is visible, "" when it shows none or is hidden. It holds for the page's open streams; a stream that ends takes it along.

func (*Manager) Settings

func (m *Manager) Settings() Settings

Settings returns the web interface's settings.

func (*Manager) Settle

func (m *Manager) Settle(id string) (SessionSummary, error)

Settle marks an active Task complete and closes its conversation. It is refused while the Task is busy, has queued prompts, waits for an answer, or still runs subagents or background tasks. A Task holding planner subtasks settles through SettleHolds.

func (*Manager) SettleHolds added in v0.12.0

func (m *Manager) SettleHolds(id string, decisions map[string]HoldDecision) (SessionSummary, error)

SettleHolds settles the Task id like Settle, deciding each subtask it holds. Without a decision for every one, it is refused with 409 holds_undecided and the held subtasks. A Task that holds nothing needs no decisions, and neither does any Task while the planner is off.

func (*Manager) Shutdown

func (m *Manager) Shutdown(ctx context.Context) error

Shutdown ends every conversation this service drives: running turns are recorded as interrupted, conversations are closed, and every provider is asked to stop the runtimes it started.

func (*Manager) SignIn added in v0.13.1

func (m *Manager) SignIn(ctx context.Context, name, token string) (agentapi.Account, error)

SignIn hands token to the provider's runtime, which validates and stores it. The token is not logged or kept here.

func (*Manager) SignOut added in v0.13.1

func (m *Manager) SignOut(ctx context.Context, name string) (agentapi.Account, error)

SignOut removes the provider runtime's stored sign-in.

func (*Manager) Start

func (m *Manager) Start(ctx context.Context) error

Start checks providers, loads their model catalogs and the web records, assigns records from before Projects existed to a Project, and gives each Project without a valid badge one. A provider whose check fails is listed as unavailable; it is not fatal.

func (*Manager) StartMCPSignIn added in v0.13.1

func (m *Manager) StartMCPSignIn(id, name string, again bool) (MCPSignIn, error)

StartMCPSignIn asks the Task's provider for a sign-in address. When its redirect is a loopback address of this host, the browser, which may be on another machine, can paste the address it ends on to FinishMCPSignIn.

func (*Manager) Subagent

func (m *Manager) Subagent(id, agentID string) (SubagentDetail, error)

Subagent returns one subagent of a session with its retained transcript.

func (*Manager) Submit

func (m *Manager) Submit(id string, req PromptRequest) (Submission, error)

Submit sends one prompt in mode: ModeSend ("" too), ModeQueue or ModeSteer. A prompt needs text, a file or an attachment. A repeated request ID returns the recorded outcome, or "queued" while the prompt waits in the queue, without contacting the provider.

func (*Manager) Subscribe

func (m *Manager) Subscribe(sessionID string) (*Subscriber, []byte, error)

Subscribe registers a subscriber and returns it with its snapshot frame. Registration and snapshot happen under one lock, so the subscriber sees every later event exactly once and nothing between the two. Subscribing to a session views it, as Detail does.

func (*Manager) Suggest added in v0.12.0

func (m *Manager) Suggest(ref string, req SuggestRequest) (string, error)

Suggest starts a suggestion job on the container ref (ADR 0005 §4, §18): a store-less Utility conversation whose only tools are board_create, board_edit, board_get and board_list, scoped to the container, acting as an agent whose Task is the job and who may write proposals only. So the per-Task caps apply to the job, and it files no change request. A document makes it split the document into cards. One job runs per card at a time; the job reports through board_job frames. It returns the job ID.

func (*Manager) SuggestReplies added in v0.13.1

func (m *Manager) SuggestReplies(ctx context.Context, id string) (Suggestions, error)

SuggestReplies returns up to maxSuggestedReplies replies for Task id's last completed turn. They are generated by one Utility call the first time they are asked for and kept by the item the transcript ends with, so the same state is never asked for twice, a failure included. A concurrent request for the same state waits for that call. Without a Utility model, or when replies are not offered, the answer is empty.

func (*Manager) Summary

func (m *Manager) Summary(id string) (SessionSummary, error)

Summary returns one session's summary.

func (*Manager) TaskChart added in v0.13.1

func (m *Manager) TaskChart(id, callID string) (Chart, error)

TaskChart returns the chart the Task id drew with the call callID, with the Project's pin of it, if any.

func (*Manager) TaskMCP added in v0.13.1

func (m *Manager) TaskMCP(id string) ([]agentapi.MCPStatus, error)

TaskMCP lists a Task's servers with their state and tools.

func (*Manager) TaskMCPAction added in v0.13.1

func (m *Manager) TaskMCPAction(id, name, action string) error

TaskMCPAction runs enable, disable or restart on a Task's conversation. They last until the conversation closes.

func (*Manager) Tree added in v0.11.0

func (m *Manager) Tree(ctx context.Context, id, dir string) (FileList, error)

Tree lists the entries directly inside dir, relative to the Task's directory ("" is the top), for the Files panel: folders first, then files, each by path. Git lists them, so .gitignore applies; symbolic links and special files are left out, and a dir that passes through a link is a 404.

func (*Manager) TriageCard added in v0.12.0

func (m *Manager) TriageCard(ctx context.Context, ref string) (Triage, error)

TriageCard triages the stale subtask ref on the Utility model (ADR 0005 §9). It writes nothing to the Board, and its answer is kept per subtask and HEAD, so asking again at the same HEAD makes no model call. A subtask staleness is not computed for, or one at its pin, is refused.

func (*Manager) TurnEvidence added in v0.13.1

func (m *Manager) TurnEvidence(ctx context.Context, id string, since, until time.Time) (TurnEvidence, error)

TurnEvidence is the evidence of Task id's latest turn and, when since is set, what changed in it between since and until (zero: now).

func (*Manager) UnpinChart added in v0.13.1

func (m *Manager) UnpinChart(projectID, id string) error

UnpinChart removes the chart id from the Project projectID, rows and all.

func (*Manager) Unsubscribe

func (m *Manager) Unsubscribe(sub *Subscriber)

Unsubscribe removes a subscriber (its viewer left). It has no effect on the provider side.

func (*Manager) UpdateProject

func (m *Manager) UpdateProject(id, name string) (Project, error)

UpdateProject renames a Project. An empty name resets it to the directory's base name.

func (*Manager) UpdateRoutine added in v0.13.1

func (m *Manager) UpdateRoutine(id string, in RoutineInput) (Routine, error)

UpdateRoutine edits a routine. Pausing clears its next run; resuming it, or changing its schedule while enabled, sets the next one from now. A run in progress is not affected.

func (*Manager) UpdateSettings

func (m *Manager) UpdateSettings(p SettingsPatch) (Settings, error)

UpdateSettings applies p. An invalid value is refused with 400 and changes nothing. A change is stored and sent as a settings frame; no change writes nothing. Hidden models are a display preference: nothing else checks them. A Utility model must be one the provider lists now, and the provider must have the titles capability; neither is needed to unset it or opt out.

func (*Manager) Upload

func (m *Manager) Upload(id, name string, data []byte) (agentapi.Attachment, error)

Upload stores one file for the Task and returns its record. The type is sniffed from the bytes, and images and PDFs must pass the Task's model gate.

func (*Manager) UtilityLog added in v0.13.1

func (m *Manager) UtilityLog(before int64, limit int) UtilityLog

UtilityLog returns today's use, the totals of every day kept and up to limit calls before the call with ID before (0: the newest), newest first.

func (*Manager) View

func (m *Manager) View(ctx context.Context, id string) error

View opens a session's conversation lazily for a viewer and waits a bounded time for it. The open runs on the service, not on ctx: a viewer leaving early does not abort it.

func (*Manager) ViewFile added in v0.10.1

func (m *Manager) ViewFile(id, rel string) (*ServedFile, error)

ViewFile opens the file at rel, relative to the Task's directory, for the view route, with the confinement of RawImage. Its type comes from the extension (viewTypes), else text/plain or application/octet-stream.

type Meta

type Meta struct {
	Version         string         `json:"version"`
	Providers       []ProviderInfo `json:"providers"`
	RecentWorkdirs  []string       `json:"recent_workdirs"`
	TempRoot        string         `json:"temp_root,omitempty"`
	TempRootAliases []string       `json:"temp_root_aliases,omitempty"`
}

Meta is the /api/meta response.

type PinnedChart added in v0.13.1

type PinnedChart struct {
	ID        string    `json:"id"`
	ProjectID string    `json:"project_id"`
	PinnedAt  time.Time `json:"pinned_at"`
	ChartSpec
	ChartData
	Error   string    `json:"error,omitempty"`
	ErrorAt time.Time `json:"error_at,omitzero"`
}

PinnedChart is a chart pinned to a Project with its latest rows. Error says why the latest refresh failed; the rows are then the last good ones.

type PreviousConversation

type PreviousConversation struct {
	Provider       string    `json:"provider"`
	ConversationID string    `json:"conversation_id"`
	Title          string    `json:"title"`
	CreatedAt      time.Time `json:"created_at"`
	UpdatedAt      time.Time `json:"updated_at"`
	InUse          bool      `json:"in_use"`
}

PreviousConversation is a provider conversation recorded for a Project's directory that no Task is linked to. InUse is set while another client holds it open.

type Project

type Project struct {
	ID        string    `json:"id"`
	Name      string    `json:"name"`
	Dir       string    `json:"dir"`
	CreatedAt time.Time `json:"created_at"`
	Badge     Badge     `json:"badge"`
	// Branch is the branch checked out in Dir's git work tree, read from git
	// and never stored. It is empty when Dir is not in a work tree, HEAD is
	// detached, or git cannot tell.
	Branch string `json:"branch,omitempty"`
	// NoGit says why Dir has no changes or git-listed files to show:
	// "not_installed" (no git in a standard location) or "not_repository"
	// (git reports Dir is in no work tree). It is empty in a work tree and
	// when git cannot tell. Read with Branch and never stored.
	NoGit string `json:"no_git,omitempty"`
	// Charts counts the charts pinned to the Project (chart_pins.go).
	Charts int `json:"charts,omitempty"`
}

Project is a directory the user added; its Tasks are web sessions whose project_id is ID.

type PromptRequest

type PromptRequest struct {
	Text      string `json:"text"`
	RequestID string `json:"request_id"`
	Mode      string `json:"mode"`
	// Files are project paths relative to the Task's directory, sent as
	// structured references.
	Files []string `json:"files"`
	// Attachments are IDs from POST /api/sessions/{id}/attachments.
	Attachments []string `json:"attachments"`
	// Omitted settings snapshot the Task's current selection. A running steer
	// may only use that same selection; new settings require a queued turn.
	Settings *PromptSettings `json:"settings,omitempty"`
}

PromptRequest is the POST /api/sessions/{id}/prompt body.

type PromptSettings added in v0.11.0

type PromptSettings struct {
	Model       string `json:"model"`
	Effort      string `json:"effort"`
	ContextSize string `json:"context_size"`
}

PromptSettings is the complete selection for one prompt's next turn.

type ProviderInfo

type ProviderInfo struct {
	Name        string `json:"name"`
	DisplayName string `json:"display_name"`
	Available   bool   `json:"available"`
	Reason      string `json:"reason"`
	// SignedOut is set when the provider is unavailable because its runtime
	// has no account sign-in; Reason then says to sign in in Settings.
	SignedOut    bool                  `json:"signed_out,omitempty"`
	Capabilities agentapi.Capabilities `json:"capabilities"`
	// Models are the selectable models; empty means the provider default only.
	Models []agentapi.Model `json:"models"`
	// CheapestModel is the cheapest priced model not hidden in Settings: the
	// Utility model when Settings name none. Omitted when none is priced.
	CheapestModel string `json:"cheapest_model,omitempty"`
}

ProviderInfo describes one provider for the create form.

type QueuedPrompt

type QueuedPrompt struct {
	RequestID string    `json:"request_id"`
	Text      string    `json:"text"`
	QueuedAt  time.Time `json:"queued_at"`
	// Files are the project paths the prompt references; they are checked
	// again when it is sent.
	Files []string `json:"files,omitempty"`
	// Attachments are the uploads the prompt carries.
	Attachments []agentapi.Attachment `json:"attachments,omitempty"`
	Settings    PromptSettings        `json:"settings"`
}

QueuedPrompt is one prompt in a Task's queue.

type Quota

type Quota struct {
	Provider         string    `json:"provider"`
	Type             string    `json:"type"`
	Used             int64     `json:"used"`
	Entitlement      int64     `json:"entitlement"`
	Unlimited        bool      `json:"unlimited"`
	RemainingPercent float64   `json:"remaining_percent"`
	Overage          float64   `json:"overage"`
	ResetAt          time.Time `json:"reset_at,omitzero"`
}

Quota is one account quota. Entitlement is 0 when Unlimited; ResetAt is omitted unless the provider reported a time still in the future.

type Rejection added in v0.12.0

type Rejection struct {
	BoardRequest
	Steered bool `json:"steered"`
}

Rejection is a rejected request and whether its reason reached the requesting Task. Steered is false when the Task was not Active, so the store released its hold, and when sending the reason failed, so the hold stays with a Task that did not hear why; the owner may then Release it.

type RenamePromptRequest added in v0.13.1

type RenamePromptRequest struct {
	Name string `json:"name"`
}

type RerunRequest added in v0.13.1

type RerunRequest struct {
	Model     string `json:"model"`
	RequestID string `json:"request_id"`
}

RerunRequest is the POST /api/sessions/{id}/rerun body. Model, when set, replaces the Task's model (Try with another model); RequestID makes a repeated request return the Task the first one created.

type Routine added in v0.13.1

type Routine struct {
	ID            string                `json:"id"`
	ProjectID     string                `json:"project_id"`
	Name          string                `json:"name"`
	Prompt        string                `json:"prompt"`
	Provider      string                `json:"provider"`
	Model         string                `json:"model"`
	Schedule      store.RoutineSchedule `json:"schedule"`
	Enabled       bool                  `json:"enabled"`
	Mode          string                `json:"mode"`
	MaxRunsPerDay int                   `json:"max_runs_per_day"`
	MaxMinutes    int                   `json:"max_minutes"`
	CreatedAt     time.Time             `json:"created_at"`
	NextRun       time.Time             `json:"next_run,omitzero"`
	Runs          []store.WebRoutineRun `json:"runs"`
}

Routine is a routine as the browser sees it; Runs is newest first.

type RoutineInput added in v0.13.1

type RoutineInput struct {
	Name          *string                `json:"name"`
	Prompt        *string                `json:"prompt"`
	Model         *string                `json:"model"`
	Schedule      *store.RoutineSchedule `json:"schedule"`
	Enabled       *bool                  `json:"enabled"`
	Mode          *string                `json:"mode"`
	MaxRunsPerDay *int                   `json:"max_runs_per_day"`
	MaxMinutes    *int                   `json:"max_minutes"`
}

RoutineInput is the body of a routine's create (every field but Model, Enabled, Mode and the limits required) or edit (only the fields given change).

type SavedPrompt added in v0.13.1

type SavedPrompt = store.WebSavedPrompt

SavedPrompt is one saved prompt; ProjectID is empty for every Project.

type ScopeCounts added in v0.13.1

type ScopeCounts struct {
	Task      int `json:"task"`
	Turn      int `json:"turn"`
	Workspace int `json:"workspace"`
}

ScopeCounts are the changed-file counts of the git-based scopes.

type ServedFile added in v0.10.1

type ServedFile struct {
	File *os.File
	Info fs.FileInfo
	MIME string
}

ServedFile is a file of a Task's directory, open for reading, with the type it is served as.

type Server

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

Server is the HTTP handler for the web interface.

func NewServer

func NewServer(cfg ServerConfig) (*Server, error)

NewServer validates cfg and builds the handler.

func (*Server) Close added in v0.11.0

func (s *Server) Close()

Close cancels grants before HTTP shutdown waits for readers to drain. It is safe to call more than once; a Server must not be reused after Close.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP applies the security checks every request passes before routing.

type ServerConfig

type ServerConfig struct {
	Manager *Manager
	// Token is the required access token browsers present at /api/login.
	Token string
	// PublicOrigins are validated origins (scheme://host[:port]) of same-host
	// reverse proxies. Authentication is bound to the request Host.
	PublicOrigins []string
	Version       string
	// Assets overrides the embedded frontend (tests).
	Assets fs.FS
	// LogHeaders logs one record per request with its headers (credentials
	// redacted) and the outcome of the checks in ServeHTTP.
	LogHeaders bool
}

ServerConfig configures the HTTP interface.

type SessionDetail

type SessionDetail struct {
	TurnTimings []TurnTiming `json:"turn_timings"`
	SessionSummary
	// Seq orders this snapshot against events on the same service.
	Seq              uint64                    `json:"seq"`
	Items            []agentapi.Item           `json:"items"`
	Interactions     []agentapi.Interaction    `json:"interactions"`
	Subagents        []agentapi.Subagent       `json:"subagents"`
	HistoryTruncated bool                      `json:"history_truncated"`
	LastSubmission   *Submission               `json:"last_submission"`
	BackgroundTasks  *agentapi.BackgroundTasks `json:"background_tasks,omitempty"`
	// Queue holds the prompts waiting for the running turn, oldest first.
	Queue []QueuedPrompt `json:"queue"`
	// QueuePaused is set while the queue waits for the user to resume or
	// clear it; it is never set with an empty queue.
	QueuePaused bool `json:"queue_paused"`
	// History says whether Items and Subagents hold the conversation's
	// recorded transcript (HistoryLoaded, HistoryLoading or
	// HistoryUnavailable); HistoryReason says why it is unavailable.
	History       string `json:"history"`
	HistoryReason string `json:"history_reason,omitempty"`
	// Present for paged clients, empty when all retained items are included.
	HistoryBefore *string `json:"history_before,omitempty"`
}

type SessionSummary

type SessionSummary struct {
	ID             string    `json:"id"`
	Provider       string    `json:"provider"`
	Name           string    `json:"name"`
	Workdir        string    `json:"workdir"`
	ConversationID string    `json:"conversation_id"`
	State          string    `json:"state"`
	StateDetail    string    `json:"state_detail"`
	Open           bool      `json:"open"`
	Pending        int       `json:"pending"`
	CreatedAt      time.Time `json:"created_at"`
	UpdatedAt      time.Time `json:"updated_at"`
	// Capabilities come from the provider so the browser can hide controls
	// the provider does not really support.
	Capabilities agentapi.Capabilities `json:"capabilities"`
	ProjectID    string                `json:"project_id"`
	// Model is the selected model; empty means the provider default.
	Model       string            `json:"model"`
	Effort      string            `json:"effort"`
	ContextSize string            `json:"context_size"`
	Context     *agentapi.Context `json:"context,omitempty"`
	// Usage is the AI units the Task's conversation used, main agent and
	// subagents together, once the provider reports them; it is not
	// persisted and after a restart comes back only from provider history.
	Usage *agentapi.Usage `json:"usage,omitempty"`
	// Title is the provider-generated title. Name may be empty; browsers
	// display name || title || "New task".
	Title string `json:"title"`
	// LastModel is the model the provider reported for the latest turn that
	// reported one. It is not persisted.
	LastModel string `json:"last_model"`
	// SubagentsRunning counts subagents that have not ended.
	SubagentsRunning int `json:"subagents_running"`
	// BackgroundTasksRunning counts the open conversation's background shell
	// tasks that have not finished.
	BackgroundTasksRunning int `json:"background_tasks_running"`
	// Queued counts prompts waiting in the Task's queue.
	Queued int `json:"queued"`
	// Mode is safe or yolo. A yolo Task's permission requests are allowed
	// once without asking; questions still wait for the user.
	Mode      string                   `json:"mode"`
	Execution *agentapi.ExecutionState `json:"execution"`
	// Stage is omitted for an active Task, otherwise StageSettled or
	// StageArchived; SettledAt and ArchivedAt say when.
	Stage      string    `json:"stage,omitempty"`
	SettledAt  time.Time `json:"settled_at,omitzero"`
	ArchivedAt time.Time `json:"archived_at,omitzero"`
	// SpawnedBy is the ID of the Task whose uam_create_task call created
	// this one; omitted otherwise.
	SpawnedBy string `json:"spawned_by,omitempty"`
	// Ask is the request the Task waits on, for the Task list to answer in
	// place; omitted when nothing waits for the user.
	Ask *Ask `json:"ask,omitempty"`
	// EventAt is when the provider last reported anything for the open
	// conversation, to the minute, so a quiet Task can say how long it has
	// been quiet. It is not persisted.
	EventAt time.Time `json:"event_at,omitzero"`
	// RoutineID is the ID of the routine whose run created this Task;
	// omitted otherwise.
	RoutineID string `json:"routine_id,omitempty"`
	// Diff totals the Task's own changes (the task scope of Changes); omitted
	// while it has none or they are not known yet.
	Diff *DiffStat `json:"diff,omitempty"`
	// RerunOf is the ID of the Task whose last message this one runs again
	// (Run again, Try with another model); omitted otherwise.
	RerunOf string `json:"rerun_of,omitempty"`
	// Outcome is a one-line summary of the last completed turn: a short
	// phrase from the Utility model, when one ran, then what the turn's tool
	// calls show (files changed, tests, failed commands). Omitted while a
	// turn runs, after one that did not complete, and when there is nothing
	// to say.
	Outcome string `json:"outcome,omitempty"`
	// Compacting is set while the open conversation is being compacted
	// (the /compact command or the provider's automatic compaction).
	Compacting bool `json:"compacting,omitempty"`
	// CompactThreshold is the share of the context, in percent, at which
	// the open conversation starts compacting: Settings' value when it
	// opened, which a later change reaches only when it reopens. Omitted
	// while no conversation is open.
	CompactThreshold int `json:"compact_threshold,omitempty"`
}

SessionSummary is one web session (a Task) as listed.

type Settings

type Settings struct {
	// SendDefault is what Enter does while a turn runs: steer or queue.
	SendDefault string `json:"send_default"`
	// Terminal lets anyone signed in open a shell, as the service user, at a
	// Project's directory (terminal.go). Off by default.
	Terminal bool `json:"terminal"`
	// Planner turns on the planner (ADR 0005, board.go). Off by default, and
	// always sent, so a browser tells off from a service without it.
	Planner bool `json:"planner"`
	// HiddenModels lists, by provider, the model IDs the browser does not
	// offer, sorted; omitted when none is hidden. IDs the provider no longer
	// lists are kept. The service never refuses a hidden model.
	HiddenModels map[string][]string `json:"hidden_models,omitempty"`
	// TitleModel maps a provider to its Utility model, the model UAM uses for
	// its own small AI jobs such as titling new Tasks: a model ID, or
	// store.WebTitleModelNone when the provider keeps its own title. A
	// provider without an entry uses ProviderInfo.CheapestModel. Omitted when
	// no provider has an entry.
	TitleModel map[string]string `json:"title_model,omitempty"`
	// CustomModels are the OpenAI-compatible models the owner brought;
	// omitted when there are none. Their model IDs are name/model_id.
	CustomModels []CustomModel `json:"custom_models,omitempty"`
	// TaskDefaults are the settings a new Task starts with; omitted when
	// unset, and the browser then starts from the provider's own defaults.
	TaskDefaults TaskDefaults `json:"task_defaults,omitzero"`
	// UtilityDailyLimit is how many Utility model calls UAM makes a day, 0
	// for none; omitted for store.DefaultUtilityDailyLimit (utility.go).
	UtilityDailyLimit *int `json:"utility_daily_limit,omitempty"`
	// SuggestReplies is false when replies to send next are not offered
	// after a turn (assist.go); omitted while they are, the default.
	SuggestReplies *bool `json:"suggest_replies,omitempty"`
	// CompactionThreshold is the share of the context, in percent, at which
	// a Task's conversation starts compacting; omitted for the provider
	// default, store.DefaultCompactionThreshold.
	CompactionThreshold *int `json:"compact_threshold,omitempty"`
	// SavedPrompts are the prompts the owner saved (prompts.go), oldest
	// first; omitted when there are none.
	SavedPrompts []SavedPrompt `json:"saved_prompts,omitempty"`
}

Settings are the web interface's settings, shared by every browser.

type SettingsPatch

type SettingsPatch struct {
	SendDefault  *string
	Terminal     *bool
	Planner      *bool
	HiddenModels map[string][]string
	TitleModel   map[string]string
	CustomModels *[]store.WebCustomModel
	TaskDefaults *TaskDefaults
	UtilityLimit **int
	// SuggestReplies turns suggested replies on or off.
	SuggestReplies      *bool
	CompactionThreshold **int
}

SettingsPatch is a settings change; a nil field changes nothing. HiddenModels replaces the hidden model IDs of each provider it names, and only those; an empty list hides none of that provider's models. TitleModel sets the Utility model of each provider it names: a model ID, or store.WebTitleModelNone to opt out; an empty ID unsets it, so the provider uses its cheapest priced model again.

CustomModels, when not nil, replaces every custom model; an empty list removes them all. TaskDefaults replaces the settings a new Task starts with; they are checked as a Task's selection is. Turning Terminal off closes every open terminal. Turning Planner on opens the planner database, and turning it off closes it; it cannot turn on without Git. UtilityLimit sets the daily limit of Utility calls, 0 to store.MaxUtilityDailyLimit; pointing at nil puts the default back. CompactionThreshold works the same way, store.MinCompactionThreshold to store.MaxCompactionThreshold; the default itself is stored as nil.

type SinceSummary added in v0.13.1

type SinceSummary struct {
	// Text is "the agent finished, ran the tests, and changed 3 files".
	Text string `json:"text"`
	// IDs are the main agent's items after the mark, oldest first.
	IDs []string `json:"ids"`
}

SinceSummary says what changed in a Task between two looks.

type Stale added in v0.12.0

type Stale struct {
	Behind   int      `json:"behind"`
	Diverged bool     `json:"diverged"`
	Files    []string `json:"files"`
}

Stale is a subtask's staleness: Behind counts the commits on HEAD that are not on the pin, Diverged is set once the pin is not an ancestor of HEAD (or no longer exists), and Files lists the changed files that match the subtask's paths, at most maxStaleFiles.

type SubagentDetail

type SubagentDetail struct {
	// Seq is the SSE sequence captured with the transcript and metadata.
	Seq      uint64            `json:"seq"`
	Subagent agentapi.Subagent `json:"subagent"`
	Items    []agentapi.Item   `json:"items"`
}

SubagentDetail is one subagent and its retained transcript.

type Submission

type Submission struct {
	RequestID     string                  `json:"request_id"`
	Status        string                  `json:"status"`
	Error         string                  `json:"error"`
	Time          time.Time               `json:"time"`
	CommandResult *agentapi.CommandResult `json:"command_result,omitempty"`
}

Submission is the recorded outcome of one prompt request.

type Subscriber

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

Subscriber is one event-stream connection. It only observes: dropping it never affects providers.

func (*Subscriber) Frames

func (s *Subscriber) Frames() <-chan []byte

Frames returns the queue of encoded events for this subscriber.

func (*Subscriber) Gone

func (s *Subscriber) Gone() <-chan struct{}

Gone is closed when the subscriber was dropped (queue overflow or service shutdown).

func (*Subscriber) Sent

func (s *Subscriber) Sent(frame []byte)

Sent records that one queued frame was written.

type SuggestRequest added in v0.12.0

type SuggestRequest struct {
	Brief    string `json:"brief"`
	Document string `json:"document"`
	Max      int    `json:"max"`
}

SuggestRequest is a suggestion job's body (ADR 0005 §14): what to plan, a document to split into cards, and at most how many cards to propose, defaultSuggestMax when 0.

type Suggestions added in v0.13.1

type Suggestions struct {
	ItemID  string   `json:"item_id"`
	Replies []string `json:"replies"`
}

Suggestions is the POST /api/sessions/{id}/suggestions response: replies the owner would likely send next, for the main transcript ending with the item ItemID. Both are empty when none are offered.

type TaskDefaults

type TaskDefaults struct {
	Provider    string `json:"provider"`
	Model       string `json:"model"`
	Effort      string `json:"effort"`
	ContextSize string `json:"context_size"`
	Mode        string `json:"mode"`
}

TaskDefaults are the settings a new Task starts with (Settings). The browser resolves them against the live models when it creates a Task. ContextSize is "default" unless a tier is chosen; Mode is safe or yolo.

type Triage added in v0.12.0

type Triage struct {
	Verdict  string `json:"verdict"`
	Sentence string `json:"sentence"`
	Head     string `json:"head"`
}

Triage is a stale subtask's triage: valid, moot or conflicts, one sentence saying why, and the HEAD it was judged at.

type TurnEvidence added in v0.13.1

type TurnEvidence struct {
	Checks []EvidenceCheck `json:"checks"`
	Claims []EvidenceClaim `json:"claims"`
	Files  []TurnFile      `json:"files"`
	Since  *SinceSummary   `json:"since,omitempty"`
}

TurnEvidence is GET /api/sessions/{id}/evidence: the evidence of the Task's latest turn and, when asked, what changed since a look.

type TurnFile added in v0.13.1

type TurnFile struct {
	Path      string `json:"path"`
	Additions *int   `json:"additions,omitempty"`
	Deletions *int   `json:"deletions,omitempty"`
}

TurnFile is one file the turn's edit tools changed, relative to the repository as Changes lists it, with its line counts when Changes lists it.

type TurnTiming

type TurnTiming = store.TurnTiming

SessionDetail is a summary plus the retained main-agent transcript, interactions and subagents.

type UtilityCall added in v0.13.1

type UtilityCall struct {
	ID           int64     `json:"id"`
	At           time.Time `json:"at"`
	Day          string    `json:"day,omitempty"`
	Purpose      string    `json:"purpose"`
	Provider     string    `json:"provider,omitempty"`
	Model        string    `json:"model,omitempty"`
	TaskID       string    `json:"task_id,omitempty"`
	ProjectID    string    `json:"project_id,omitempty"`
	PromptChars  int       `json:"prompt_chars"`
	ReplyChars   int       `json:"reply_chars"`
	InputTokens  int64     `json:"input_tokens"`
	OutputTokens int64     `json:"output_tokens"`
	Estimated    bool      `json:"estimated,omitempty"`
	Credits      float64   `json:"credits,omitempty"`
	DurationMS   int64     `json:"duration_ms"`
	Outcome      string    `json:"outcome"`
	Reason       string    `json:"reason,omitempty"`
}

UtilityCall is one Utility model call in the log. At is when it started; Day is its server-local date, set when the log is read. Tokens are the provider's figures unless Estimated, when they are worked out from the characters. PromptChars counts what the service sent the provider: a Utility request's system message and prompt, or the text a title or a subagent summary is made from. Reason is why a call was skipped (daily_limit or off) or failed.

type UtilityDay added in v0.13.1

type UtilityDay struct {
	Day          string  `json:"day"`
	Calls        int     `json:"calls"`
	Errors       int     `json:"errors"`
	Skipped      int     `json:"skipped"`
	PromptChars  int64   `json:"prompt_chars"`
	ReplyChars   int64   `json:"reply_chars"`
	InputTokens  int64   `json:"input_tokens"`
	OutputTokens int64   `json:"output_tokens"`
	Estimated    bool    `json:"estimated,omitempty"`
	Credits      float64 `json:"credits,omitempty"`
}

UtilityDay totals one day of the log. Estimated is set when some of its tokens are estimates.

type UtilityLog added in v0.13.1

type UtilityLog struct {
	Today UtilityToday  `json:"today"`
	Days  []UtilityDay  `json:"days"`
	Calls []UtilityCall `json:"calls"`
	Next  int64         `json:"next,omitempty"`
}

UtilityLog is the GET /api/utility response: today, every day kept with its totals, and a page of calls, newest first. Next, when set, is the before value of the next page.

type UtilityModel added in v0.12.0

type UtilityModel struct {
	Provider string
	Model    string
}

UtilityModel is the provider and model the planner's Utility jobs run on (ADR 0005 §18).

type UtilityToday added in v0.13.1

type UtilityToday struct {
	Day      string    `json:"day"`
	Calls    int       `json:"calls"`
	Limit    int       `json:"limit"`
	Paused   bool      `json:"paused"`
	ResetsAt time.Time `json:"resets_at"`
}

UtilityToday is today's use against the limit. Paused is set once no more calls run today; ResetsAt is the server's next local midnight.

Jump to

Keyboard shortcuts

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