Documentation
¶
Overview ¶
Package ui is Fort's interface module (backlog Phase 3): the event/command contract (AO-031), the live board (AO-032), the SSE live-feed transport (AO-033), the chat surface (AO-034), the gate inbox (AO-035), and the OpenClaw inbound channel (AO-036). It imports core; core never imports ui.
Contract summary (published for clients, incl. the iOS shell, AO-037):
GET /api/board -> Board (runs + waiting gates + checkpoints)
GET /api/summary -> Summary (counts + pending gates)
GET /api/runs/{id} -> RunDetail (run + nodes + events; replayable)
GET /api/gates -> []GateItem
POST /api/gate <- GateDecision -> ActionResult (reject may carry a note)
POST /api/chat <- ChatRequest -> ChatResult
GET /api/backlog -> []BacklogItem
POST /api/backlog <- BacklogRequest -> BacklogItem
PATCH /api/backlog/{id} <- BacklogPatch -> BacklogItem (reassign, spec 033)
POST /api/backlog/{id}/dispatch -> ChatResult
DELETE /api/backlog/{id}
POST /api/breakdown <- BreakdownRequest -> BreakdownResult
GET /api/metrics[?days=N&lane=L] -> MetricsResponse (spec 033)
GET /api/playbooks -> []Playbook (latest immutable revisions)
PUT /api/playbooks <- Playbook -> Playbook (new revision)
POST /api/playbooks/{id}/duplicate -> Playbook
POST /api/route <- RouteRequest -> RoutePreview (pure; spec 036)
POST /api/openclaw <- OpenClawMessage-> ChatResult
GET /api/events[?since=N] -> text/event-stream of Event frames
Index ¶
- type ActionResult
- type AgentMetrics
- type BacklogItem
- type BacklogPatch
- type BacklogRequest
- type Board
- type BreakdownRequest
- type BreakdownResult
- type ChatRequest
- type ChatResult
- type CheckpointSummary
- type Deps
- type Dispatcher
- type Event
- type FlowNode
- type FlowRunner
- type GateDecision
- type GateItem
- type MachineLister
- type MachineStatus
- type MetricsResponse
- type NodeSummary
- type OpenClawMessage
- type Planner
- type Playbook
- type PlaybookAssignment
- type PlaybookCatalog
- type PlaybookRunResult
- type PlaybookRunner
- type PlaybookStage
- type PlaybookTrigger
- type ResolvedPlaybookStage
- type RoutePreview
- type RouteRequest
- type RunDetail
- type RunRef
- type RunResult
- type RunSummary
- type Server
- type Summary
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ActionResult ¶
type ActionResult struct {
State string `json:"state"`
PausedNode string `json:"paused_node,omitempty"`
}
ActionResult is a generic command result (gate decisions).
type AgentMetrics ¶ added in v0.11.0
type AgentMetrics struct {
Agent string `json:"agent"`
Assignments int `json:"assignments"` // routed runs + flow task-node executions
Decided int `json:"decided"` // sign-offs that reached a decision
FirstPass int `json:"first_pass"` // approved first try, no note
FirstPassPct float64 `json:"first_pass_pct"` // 0 when Decided==0
Accepted int `json:"accepted"` // finally-approved sign-offs
Redirects int `json:"redirects"` // rejects + approves-with-edits
RedirectsPer float64 `json:"redirects_per_assignment"` // 0 when Assignments==0
CostUSD float64 `json:"cost_usd"` // parsed engine cost; 0 = unknown
CostPerAccept float64 `json:"cost_per_accepted"` // 0 = unknown
CostKnown bool `json:"cost_known"`
Trend string `json:"trend"` // improving | steady | slipping
TrendDelta float64 `json:"trend_delta"` // pct-point change between window halves
Spark []float64 `json:"spark"` // 7 first-pass-% buckets, carried forward
Best []string `json:"best"` // strongest routing lanes (≥3 terminal runs)
Weak []string `json:"weak"`
}
AgentMetrics is one agent's scorecard over the metrics window (spec 033). Everything is derived from the append-only event log + run rows — sign-off counts are human decisions, never agent estimates. Sample sizes (Assignments, Decided) ship alongside every ratio because 30-day windows are small.
type BacklogItem ¶ added in v0.7.0
type BacklogItem struct {
ID string `json:"id"`
Title string `json:"title"`
Body string `json:"body,omitempty"`
Agent string `json:"agent,omitempty"`
Machine string `json:"machine,omitempty"`
Labels []string `json:"labels,omitempty"`
Source string `json:"source"` // "user" | "agent"
}
BacklogItem is a pending task queued on the board (spec 025).
type BacklogPatch ¶ added in v0.11.0
type BacklogPatch struct {
Agent string `json:"agent"`
}
BacklogPatch is the command body for PATCH /api/backlog/{id} (spec 033): reassign an Up-next item to another agent ("" clears the pin).
type BacklogRequest ¶ added in v0.7.0
type BacklogRequest struct {
Title string `json:"title"`
Body string `json:"body,omitempty"`
Agent string `json:"agent,omitempty"`
Machine string `json:"machine,omitempty"`
Labels []string `json:"labels,omitempty"`
Source string `json:"source,omitempty"` // defaults to "user"
}
BacklogRequest is the command body for POST /api/backlog.
type Board ¶
type Board struct {
Runs []RunSummary `json:"runs"`
Gates []GateItem `json:"gates"`
}
Board is the live board payload.
type BreakdownRequest ¶ added in v0.8.0
type BreakdownRequest struct {
Text string `json:"text"`
Agent string `json:"agent,omitempty"`
Machine string `json:"machine,omitempty"`
}
BreakdownRequest is the command body for POST /api/breakdown.
type BreakdownResult ¶ added in v0.8.0
type BreakdownResult struct {
RunID string `json:"run_id"`
}
BreakdownResult is the response for POST /api/breakdown: the visible planner run's id. Sub-tasks appear in the backlog when that run completes.
type ChatRequest ¶
type ChatRequest struct {
Text string `json:"text"`
Agent string `json:"agent,omitempty"` // force a specific agent
Machine string `json:"machine,omitempty"` // pin a target host (spec 022)
PlaybookID string `json:"playbook_id,omitempty"` // exact route override (spec 036)
PlaybookRevision int `json:"playbook_revision,omitempty"` // immutable preview revision
TaskType string `json:"task_type,omitempty"` // explicit deterministic signal
PlanGate *bool `json:"plan_gate,omitempty"` // per-handoff plan-gate override
}
ChatRequest is the command body for POST /api/chat.
type ChatResult ¶
type ChatResult struct {
Kind string `json:"kind"` // task | flow | answer
RunID string `json:"run_id"`
Route string `json:"route,omitempty"` // agent, for task kind (execution plane)
Machine string `json:"machine,omitempty"` // resolved host (spec 022)
Queued bool `json:"queued,omitempty"` // true when only boarded (control-only)
FlowID string `json:"flow_id,omitempty"` // for flow/playbook kind
Paused string `json:"paused,omitempty"` // gate id if the flow paused
Answer string `json:"answer,omitempty"` // inline Quick answer delivery
PlaybookID string `json:"playbook_id,omitempty"` // executed immutable route
PlaybookRevision int `json:"playbook_revision,omitempty"`
}
ChatResult is the response for chat/openclaw.
type CheckpointSummary ¶ added in v0.11.0
type CheckpointSummary struct {
Total int `json:"total"` // gate nodes in the plan (executed-only when no plan is known)
Accepted int `json:"accepted"` // approved gates
Waiting int `json:"waiting"` // gates awaiting sign-off
Rejected int `json:"rejected"` // rejected gates
Done int `json:"done"` // non-gate nodes finished (for in-progress inference)
}
CheckpointSummary is a run's human-checkpoint progress: checkpoints are the flow's gate nodes — progress is what the human accepted, never an agent estimate (spec 033).
type Deps ¶
type Deps struct {
Dispatcher Dispatcher // required
Runner FlowRunner // nil in control-only mode
Store *store.Store // required
FlowIDs []string // available flow ids (for chat templates); empty in control-only
Machines MachineLister // nil in single-machine mode (spec 022)
Planner Planner // nil in control-only mode (spec 026)
Playbooks PlaybookCatalog // deterministic catalog + preview (spec 036)
PlaybookRunner PlaybookRunner // nil in control-only mode
}
Deps are the control-plane collaborators — ports only. With no Runner and a queue Dispatcher this serves a full control plane (board, chat, scheduler, gate inbox) that needs none of the deterministic execution components.
type Dispatcher ¶
Dispatcher accepts a task. With an execution plane it routes + dispatches; in control-only mode it simply boards the task (Queued=true).
type Event ¶
type Event struct {
ID int64 `json:"id"`
RunID string `json:"run_id"`
NodeID string `json:"node_id,omitempty"`
Type string `json:"type"`
Data string `json:"data,omitempty"`
Code int `json:"code,omitempty"`
Time string `json:"time"`
}
Event is the wire form of one append-only event-log row (the live-feed unit).
type FlowNode ¶ added in v0.11.0
type FlowNode struct {
ID string `json:"id"`
Type string `json:"type"` // task | gate | check | transform | fanout
}
FlowNode is one node of a flow plan as exposed to the control plane (spec 033): just enough to know a run's checkpoint total.
type FlowRunner ¶
type FlowRunner interface {
StartFlow(ctx context.Context, flowID, runID, payload string) (RunResult, error)
Approve(runID, nodeID, edit string) error
Reject(runID, nodeID, note string) error
ResumeFlow(ctx context.Context, flowID, runID string) (RunResult, error)
// Plan returns the flow's node list (nil for an unknown id).
Plan(flowID string) []FlowNode
}
FlowRunner runs flows by id. It is nil in control-only mode (no DAG engine); chat "ship X" then degrades to a boarded task and gate actions return 409.
type GateDecision ¶
type GateDecision struct {
RunID string `json:"run_id"`
NodeID string `json:"node_id"`
Decision string `json:"decision"` // approve | reject
Edit string `json:"edit,omitempty"`
Note string `json:"note,omitempty"` // redirect note on reject (spec 033)
}
GateDecision is the command body for POST /api/gate.
type GateItem ¶
type GateItem struct {
RunID string `json:"run_id"`
NodeID string `json:"node_id"`
Input string `json:"input,omitempty"`
Since string `json:"since,omitempty"` // RFC3339 — when the gate began waiting (spec 033)
}
GateItem is a gate awaiting a human decision (the gate inbox).
type MachineLister ¶
type MachineLister interface {
Machines() []MachineStatus
}
MachineLister reports the machine roster + reachability for the control plane (GET /api/machines, spec 022). It is nil in single-machine mode, in which case the endpoint returns an empty roster. Implemented by package control.
type MachineStatus ¶
type MachineStatus struct {
Name string `json:"name"`
URL string `json:"url,omitempty"`
Agents []string `json:"agents"`
Local bool `json:"local"`
Reachable bool `json:"reachable"`
}
MachineStatus is one host in the roster (GET /api/machines, spec 022).
type MetricsResponse ¶ added in v0.11.0
type MetricsResponse struct {
WindowDays int `json:"window_days"`
Assignments int `json:"assignments"`
Agents []AgentMetrics `json:"agents"`
Lanes []string `json:"lanes"` // distinct matched_rule values seen in the window
}
MetricsResponse is the payload of GET /api/metrics (spec 033).
type NodeSummary ¶
type NodeSummary struct {
NodeID string `json:"node_id"`
Type string `json:"type"`
Status string `json:"status"`
Attempts int `json:"attempts,omitempty"`
}
NodeSummary is a node's state within a run.
type OpenClawMessage ¶
OpenClawMessage is an inbound OpenClaw message (AO-036).
type Planner ¶ added in v0.8.0
type Planner interface {
Breakdown(ctx context.Context, goal, agent, machine string) (runID string, err error)
}
Planner decomposes a goal into backlog sub-tasks by running a planner agent (spec 026). It is nil in control-only mode (planning needs an execution plane); the /api/breakdown endpoint 409s when it is nil. Breakdown returns the planner run's id immediately; the sub-tasks land in the backlog asynchronously when that run completes.
type Playbook ¶ added in v0.12.0
type Playbook struct {
ID string `json:"id"`
Name string `json:"name"`
Revision int `json:"revision"`
IsDefault bool `json:"is_default,omitempty"`
PlanGate bool `json:"plan_gate,omitempty"`
Delivery string `json:"delivery"` // assignment | answer
Trigger PlaybookTrigger `json:"trigger"`
Stages []PlaybookStage `json:"stages"`
}
Playbook is the latest (or an explicitly requested immutable) revision of a reusable agent/model pipeline.
type PlaybookAssignment ¶ added in v0.12.0
type PlaybookAssignment struct {
TaskType string `json:"task_type,omitempty"`
Agent string `json:"agent"`
Model string `json:"model,omitempty"`
}
PlaybookAssignment chooses the agent + model for a task-type branch. An empty TaskType is the required default branch for that stage.
type PlaybookCatalog ¶ added in v0.12.0
type PlaybookCatalog interface {
List(ctx context.Context) ([]Playbook, error)
Save(ctx context.Context, p Playbook) (Playbook, error)
Duplicate(ctx context.Context, id string) (Playbook, error)
Route(ctx context.Context, req RouteRequest) (RoutePreview, error)
}
PlaybookCatalog owns immutable playbook revisions and deterministic route resolution. It is available in both full and control-only modes; Route must never invoke a model or dispatch runtime work.
type PlaybookRunResult ¶ added in v0.12.0
type PlaybookRunResult struct {
State string `json:"state"`
PausedNode string `json:"paused_node,omitempty"`
FlowID string `json:"flow_id"`
Answer string `json:"answer,omitempty"`
}
PlaybookRunResult is the synchronous Start result. Answer is populated only by a delivery=answer playbook; its event history remains inspectable.
type PlaybookRunner ¶ added in v0.12.0
type PlaybookRunner interface {
StartPlaybook(ctx context.Context, route RoutePreview, runID, direction string) (PlaybookRunResult, error)
}
PlaybookRunner compiles and executes an already-resolved immutable route. It is nil in control-only mode.
type PlaybookStage ¶ added in v0.12.0
type PlaybookStage struct {
Order int `json:"order"`
Name string `json:"name"`
Prompt string `json:"prompt,omitempty"`
Description string `json:"description,omitempty"`
Assignments []PlaybookAssignment `json:"assignments"`
Memory bool `json:"memory,omitempty"`
}
PlaybookStage is one reusable pipeline stage.
type PlaybookTrigger ¶ added in v0.12.0
type PlaybookTrigger struct {
Kind string `json:"kind"` // question | bug | research | feature | manual
Enabled bool `json:"enabled"`
}
PlaybookTrigger is a deterministic task-type binding. Enabled is exposed so the Turn-4 shortcut toggles can be persisted without changing the route grammar.
type ResolvedPlaybookStage ¶ added in v0.12.0
type ResolvedPlaybookStage struct {
Order int `json:"order"`
Name string `json:"name"`
Prompt string `json:"prompt,omitempty"`
Agent string `json:"agent"`
Model string `json:"model,omitempty"`
Memory bool `json:"memory,omitempty"`
}
ResolvedPlaybookStage is the one selected branch for a stage.
type RoutePreview ¶ added in v0.12.0
type RoutePreview struct {
PlaybookID string `json:"playbook_id"`
PlaybookRevision int `json:"playbook_revision"`
PlaybookName string `json:"playbook_name"`
TaskType string `json:"task_type"`
Source string `json:"source"` // manual | trigger | default
PlanGate bool `json:"plan_gate"`
Delivery string `json:"delivery"` // assignment | answer
Stages []ResolvedPlaybookStage `json:"stages"`
}
RoutePreview is the immutable route card shown before handoff.
type RouteRequest ¶ added in v0.12.0
type RouteRequest struct {
Text string `json:"text"`
PlaybookID string `json:"playbook_id,omitempty"`
PlaybookRevision int `json:"playbook_revision,omitempty"`
TaskType string `json:"task_type,omitempty"`
PlanGate *bool `json:"plan_gate,omitempty"`
}
RouteRequest asks Fort to resolve a route without dispatching. The result is a pure function of this request and the immutable catalog revision.
type RunDetail ¶
type RunDetail struct {
Run RunSummary `json:"run"`
Nodes []NodeSummary `json:"nodes"`
Events []Event `json:"events"`
}
RunDetail makes a run replayable from the event log.
type RunRef ¶
type RunRef struct {
RunID string `json:"run_id"`
Route string `json:"route,omitempty"` // agent, when an execution plane routed it
Machine string `json:"machine,omitempty"` // host it was placed on (spec 022)
Queued bool `json:"queued,omitempty"` // true when only boarded (no execution plane)
}
RunRef identifies the run a submitted task produced.
type RunResult ¶
type RunResult struct {
State string `json:"state"`
PausedNode string `json:"paused_node,omitempty"`
}
RunResult is a flow run's state after a Start/Resume.
type RunSummary ¶
type RunSummary struct {
ID string `json:"id"`
Title string `json:"title"`
Body string `json:"body,omitempty"`
Agent string `json:"agent"`
Status string `json:"status"`
Machine string `json:"machine,omitempty"` // host the run is placed on (spec 022)
FlowID string `json:"flow_id,omitempty"`
CreatedAt string `json:"created_at,omitempty"` // RFC3339 (spec 033)
UpdatedAt string `json:"updated_at,omitempty"` // RFC3339 (spec 033)
Checkpoints *CheckpointSummary `json:"checkpoints,omitempty"`
}
RunSummary is a board card.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server holds the ui handlers.
func (*Server) HasExecution ¶
HasExecution reports whether an execution plane is wired (for diagnostics).
type Summary ¶
type Summary struct {
Total int `json:"total"`
Running int `json:"running"`
Queued int `json:"queued"`
Blocked int `json:"blocked"` // paused at a gate
Succeeded int `json:"succeeded"`
Failed int `json:"failed"`
Execution bool `json:"execution"` // whether an execution plane is attached
Gates []GateItem `json:"gates"`
}
Summary is the glanceable control-plane snapshot for constrained surfaces (watch complication, CarPlay). Served at GET /api/summary.