agents

package
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2026 License: MIT Imports: 71 Imported by: 0

Documentation

Overview

Package agents backs /tools/agents — the Agents UI Manager. It lets users manage AI agent sessions, workspaces, and presets from the browser and streams real-time agent output via Server-Sent Events.

Index

Constants

This section is empty.

Variables

View Source
var SPAFS fs.FS = spaEmbedded

SPAFS is the filesystem callers should read SPA files from. Defaults to the compile-time embed (production); swapped to an os.DirFS at init when WICK_DEV_REPO_ROOT is set so the dev loop can rebuild the bundle (`vite build --watch`) without a Go recompile.

View Source
var StaticFS embed.FS

Functions

func AskUsers

func AskUsers() *askuser.Manager

AskUsers returns the wired Manager so the boot path can hand it to the MCP handler. Reading this is racy if SetAskUsers is called concurrently with reads, but in practice it's set once during boot before serving begins.

func AutoInstallMCP added in v0.13.4

func AutoInstallMCP()

AutoInstallMCP installs wick into every detected MCP client that doesn't have it yet, skipping blocklisted (manually-uninstalled) clients. Called once at server startup; the mcp_auto_installed flag prevents re-runs so page renders never trigger spurious re-installs.

func DataTables added in v0.13.1

func DataTables() datatable.Service

DataTables returns the wired service (read side).

func Register

func Register(r tool.Router)

Register mounts all Agents routes under /tools/agents.

func SetApprovals

func SetApprovals(m *gate.ApprovalManager)

SetApprovals wires in the gate ApprovalManager. nil = gate disabled (handler endpoints fall back to 503).

func SetAskUsers

func SetAskUsers(m *askuser.Manager)

SetAskUsers wires in the ask_user Manager. nil = ask_user MCP tool returns errors and the answer endpoint 503s.

func SetAuth added in v0.14.21

func SetAuth(a *login.Service)

SetAuth wires the login service so per-user preferences (pinned project) can be read/written from the agents tool.

func SetBroadcaster

func SetBroadcaster(b *Broadcaster)

SetBroadcaster wires in the SSE event broadcaster.

func SetChannelRegistry added in v0.10.0

func SetChannelRegistry(r *agentchannels.Registry)

SetChannelRegistry wires the live channel registry so picker fields can issue lookup queries against each channel's upstream (Slack API, etc.). Without this, /channels/{slug}/lookup returns 503.

func SetConfigs

func SetConfigs(c *configs.Service)

SetConfigs wires the shared configs service so the Providers page can toggle agents.gate_enabled inline. Without this, the toggle endpoint 503s.

func SetDB

func SetDB(db *gorm.DB)

SetDB wires the shared GORM DB so channel handlers can read/write agent_channels rows. Without this, channel config endpoints 503.

Workflow data is DB-primary. Folders left on disk from before the DB migration are not imported automatically — use the SPA or MCP to recreate them, then remove the old folders.

func SetDataTables added in v0.13.1

func SetDataTables(s datatable.Service)

SetDataTables registers the shared data-table service. nil is allowed during early boot; handlers fall back to 503.

func SetGateStatus

func SetGateStatus(s GateStatus)

SetGateStatus records the boot-time gate-resolution result. Read by the Providers page. Call exactly once during server boot.

func SetLayout

func SetLayout(l agentconfig.Layout)

SetLayout wires in the on-disk layout used for direct file reads.

func SetManager

func SetManager(m *registry.Manager)

SetManager wires in the agents registry manager.

func SetPool

func SetPool(p *pool.Pool)

SetPool wires in the agent subprocess pool.

func SetSpawnLogger

func SetSpawnLogger(s *provider.SpawnLogger)

SetSpawnLogger wires in the per-spawn jsonl writer/reader. The Providers page reads from it via List + Read; the pool factory already writes through it.

func SetSyncManager added in v0.11.0

func SetSyncManager(m *providersync.Manager)

SetSyncManager wires the provider storage sync manager.

func SetWorkflowEncService added in v0.16.0

func SetWorkflowEncService(s *enc.Service)

SetWorkflowEncService wires the cipher used by the env save handler.

func SetWorkflowManager added in v0.13.0

func SetWorkflowManager(m *setup.Manager)

SetWorkflowManager wires in the workflow Manager constructed by server.go. After the JSON migration, workflow body is DB-primary — no file→DB importer runs here.

func WorkflowEventHook added in v0.13.0

func WorkflowEventHook(b *Broadcaster) func(id, runID string, ev wf.RunEvent)

WorkflowEventHook builds an engine.OnEvent callback that fans workflow run events out to the SSE broadcaster.

func WorkflowSSESession added in v0.13.0

func WorkflowSSESession(id string) string

WorkflowSSESession returns the broadcaster session key used for workflow run events.

Types

type Broadcaster

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

Broadcaster fans out agent events to all subscribed SSE connections. Subscribe returns a receive channel and an unsub func. Publish is called from ClaudeFactory.OnEvent on every AgentEvent.

subs is keyed by sessionID ("" = global subscribers that receive all events). Channels are buffered at 64 so a slow client never stalls the agent reader goroutine.

func NewBroadcaster

func NewBroadcaster() *Broadcaster

NewBroadcaster returns a ready Broadcaster.

func (*Broadcaster) Publish

func (b *Broadcaster) Publish(sessionID, agentName string, ev event.AgentEvent)

Publish fires ev to all subscribers of sessionID and all global ("") subscribers. Non-blocking: a full channel's event is dropped rather than blocking.

func (*Broadcaster) PublishApprovalRequest

func (b *Broadcaster) PublishApprovalRequest(sessionID string, req gate.ApprovalRequest)

PublishApprovalRequest fires when the gate binary dials the daemon socket with an unrecognised command. Browsers render this as a modal with 4 decision buttons (approve_once / approve_session / approve_always / block); the user's pick rides back through POST /approve.

Data is the JSON-encoded ApprovalRequest so the front-end can decode it once and use every field (cmd, work_dir, match_key, ...).

func (*Broadcaster) PublishApprovalResolved

func (b *Broadcaster) PublishApprovalResolved(sessionID, requestID, decision string)

PublishApprovalResolved fires once a decision is delivered (UI click, timeout, or listener close). Browsers use this to dismiss any open modal across all tabs subscribed to the session.

func (*Broadcaster) PublishAskUser

func (b *Broadcaster) PublishAskUser(sessionID, agentName string, payload []byte)

PublishAskUser fires when the ask_user MCP tool is invoked by an agent. Front-end renders an inline card with options + freeform input; user's pick rides back through POST /answer. Data is the JSON-encoded request body so every field (question, options, allow_freeform, ...) round-trips exactly once.

func (*Broadcaster) PublishAskUserResolved

func (b *Broadcaster) PublishAskUserResolved(sessionID, requestID string)

PublishAskUserResolved fires once an ask_user request resolves (UI answer or timeout). Used by the UI to dismiss the inline card across all tabs subscribed to the session.

func (*Broadcaster) PublishGitStatusJSON added in v0.15.5

func (b *Broadcaster) PublishGitStatusJSON(sessionID, jsonPayload string)

PublishGitStatusJSON broadcasts a pre-marshalled git_status payload to a session's subscribers. The payload is the full repo+status snapshot (built by the fs watcher) so the FE updates entirely from the event — no follow-up fetch, hence no polling. The marshalling lives in the caller (scm_watch.go) to avoid an import cycle on the scm types.

func (*Broadcaster) PublishLifecycle

func (b *Broadcaster) PublishLifecycle(ctx context.Context, sessionID, agentName, lifecycle string, pid int)

PublishLifecycle pushes a lifecycle transition (Spawning, Killed) to subscribers. Idle/Working transitions are inferred from AgentEvent flow on the client side; only the bookend transitions — which never carry an AgentEvent — go through this channel. PublishLifecycle takes the spawn-time ctx so the broadcast log line carries the originating request_id (set by the HTTP middleware) when the spawn came from an HTTP path. Pass context.Background() when no spawn ctx is in scope.

func (*Broadcaster) PublishPoolStats added in v0.15.2

func (b *Broadcaster) PublishPoolStats(active, max, queueLen int, procs []LiveProcessEntry)

PublishPoolStats broadcasts a pool_stats event to all global SSE subscribers (sessionID == ""). Called after every lifecycle transition so the Providers page stays live.

func (*Broadcaster) PublishRaw added in v0.13.4

func (b *Broadcaster) PublishRaw(sessionID, agentName, evType, data string)

func (*Broadcaster) PublishSystemTurn added in v0.13.4

func (b *Broadcaster) PublishSystemTurn(sessionID, agentName, text string, steps []string)

PublishSystemTurn fires a system_turn event so the UI can append it to the conversation without a page reload. Data is JSON with text + steps so the front-end can render the pill + checklist inline.

func (*Broadcaster) Subscribe

func (b *Broadcaster) Subscribe(sessionID string) (<-chan Event, func())

Subscribe registers a listener for a specific session (or "" for all). The caller must call the returned unsub func when the SSE connection closes.

type Event

type Event struct {
	SessionID string `json:"session_id"`
	AgentName string `json:"agent_name"`
	Type      string `json:"type"`
	Data      string `json:"data"`
	// ToolName, ToolInput, ToolUseID are populated for tool_use events;
	// ToolUseID and IsError are also set for tool_result events.
	ToolName  string `json:"tool_name,omitempty"`
	ToolInput string `json:"tool_input,omitempty"`
	ToolUseID string `json:"tool_use_id,omitempty"`
	IsError   bool   `json:"is_error,omitempty"`
	PID       int    `json:"pid,omitempty"`
	Lifecycle string `json:"lifecycle,omitempty"`
	// At / EndAt carry Unix ms timestamps for tool_use/tool_result events
	// so the UI can show "started HH:MM:SS, took Ns".
	At    int64 `json:"at,omitempty"`
	EndAt int64 `json:"end_at,omitempty"`
}

Event is one SSE payload pushed to browser subscribers. Type distinguishes agent stream events ("text_delta", "tool_use", ...) from lifecycle events ("lifecycle"); the latter carry PID + lifecycle label in Data so the UI can update the status badge without re-fetching the page.

func (Event) JSON

func (e Event) JSON() string

type GateStatus

type GateStatus struct {
	Enabled bool
	Binary  string // absolute path
	Source  string // gate.Source* constant
	Reason  string // populated when Enabled=false
}

GateStatus is the boot-time snapshot of the command gate. Populated once during server.go startup and read by the Providers page so operators can tell at a glance whether the gate sidecar is wired up.

Enabled=false means ResolveGateBinary returned an error — every command will hit fail-safe block at the matcher / no-socket path, except whitelist matches. Reason carries the error message so the UI can show actionable guidance (run `wick build`).

func GetGateStatus

func GetGateStatus() GateStatus

GetGateStatus is the read side. Returns a zero value when boot hasn't reached SetGateStatus yet.

type GitStatusSnapshot added in v0.15.5

type GitStatusSnapshot struct {
	Repos        []RepoSummary               `json:"repos"`
	Statuses     map[string]scm.StatusResult `json:"statuses"`
	TotalChanged int                         `json:"total_changed"`
}

GitStatusSnapshot is the full session-wide git state pushed over SSE (git_status event) AND returned by GET /git/repos. The FE renders entirely from this — repos for the switcher, statuses[rel] for the changes list of each repo — so a change event needs no follow-up fetch (zero polling).

type LiveProcessEntry added in v0.15.2

type LiveProcessEntry struct {
	SessionID string `json:"session_id"`
	AgentName string `json:"agent_name"`
	Provider  string `json:"provider,omitempty"` // "type/name"
	PID       int    `json:"pid,omitempty"`
	Queued    int    `json:"queued,omitempty"` // messages waiting after current turn
	Alive     bool   `json:"alive"`            // false only for a genuinely dead process (zombie). Respawn-mode idle-between-turns is alive.
	Lifecycle string `json:"lifecycle"`
	Substate  string `json:"substate,omitempty"`
}

LiveProcessEntry is one row in PoolStatsPayload.

type PoolStatsPayload added in v0.15.2

type PoolStatsPayload struct {
	Active        int                `json:"active"`
	Max           int                `json:"max"`
	QueueLen      int                `json:"queue_len"`
	LiveProcesses []LiveProcessEntry `json:"live_processes"`
}

PublishRaw fires an arbitrary typed SSE event. Used to inject synthetic agent events (e.g. text_delta + done for a switch confirmation reply). PoolStatsPayload is the JSON shape of a pool_stats SSE event. Sent to global ("") subscribers on every lifecycle transition so the Providers page can update the Active Processes panel without reload.

type RepoSummary added in v0.15.5

type RepoSummary struct {
	Rel     string `json:"rel"`
	Name    string `json:"name"`
	Branch  string `json:"branch"`
	Changed int    `json:"changed"`
	Ahead   int    `json:"ahead"`
	Behind  int    `json:"behind"`
}

RepoSummary is one repo in the /git/repos listing.

type StorageFileVM added in v0.11.0

type StorageFileVM struct {
	entity.ProviderStorage
	SyncedAtFmt string
}

StorageFileVM is the view model for one file row in the storage table.

type StoragePageVM added in v0.11.0

type StoragePageVM struct {
	Base           string
	Files          []StorageFileVM
	FilterProvider string
	FilterInstance string
	ProviderTypes  []string
}

StoragePageVM is the view model for the storage manager page.

type TestCaseItem added in v0.14.20

type TestCaseItem struct {
	Name   string
	Case   wftest.Case
	Result *wftest.Result
}

TestCaseItem pairs an on-disk test case with its last-run result for the spa test panel handlers.

Directories

Path Synopsis
templ: version: v0.3.1020
templ: version: v0.3.1020
workflow
templ: version: v0.3.1020
templ: version: v0.3.1020

Jump to

Keyboard shortcuts

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