v0.3.1 — Auto-pause, per-worker concurrency, dashboard panel
Highlights
Three substantive capabilities round out the v0.3.x line:
- Mid-mission auto-pause on capability confirmation — when a worker's
task triggers a tool whose capability requires explicit user approval,
the mission auto-transitions towaiting_userand emits a
mission.confirmation_requiredevent the dashboard can render.
Resume viamission.interrupt action=resumeonce the user grants
the capability. - Per-worker concurrent handling —
Worker.MaxConcurrentlets a
single worker hold N tasks in flight (bounded semaphore) instead of
processing one at a time. Useful for I/O-bound work like LLM API
calls. Default 1 keeps the historical behaviour exact. - Mission dashboard panel in webchat — new sidebar nav 🎯 Missions
surfaces the existing/api/dashboard/missions/*JSON endpoints as a
first-class UI: mission list with state badges, per-mission detail
subview, and a 2-second-polling live event tail.
Together with v0.3.0's LLM-driven replanning, the v0.3.x mission engine
can now recover from step failures, pause for user confirmation, run
multiple in-flight tasks per worker, and render its full state in the
webchat UI.
Added — Mission dashboard panel in webchat
- New "Missions" panel in the sidebar nav (🎯). Consumes the
existing/api/dashboard/missions/*endpoints (shipped in v0.1.0)
and renders them as a first-class UI surface alongside Chat, Home,
Memories, Connected Apps, and Spending. - Header stats — active / completed / failed counts and total
cost across all missions, sourced from
/api/dashboard/missions/stats. - Recent missions list — goal, state badge with a pulse animation
forwaiting_user, step count, cost, age. Toggle to include
terminal-state missions. - Per-mission detail subview — click a mission to drill in. Every
step renders with its state (colour-coded left border:
green=completed, blue=running, red=failed, orange=waiting_user,
grey=cancelled), the worker's output or error inline, and a live
event tail showing the most recent 50 events newest-first
including the v0.3.xmission.confirmation_requiredand
mission.replannedevents. - 2-second polling while the panel is open; stops automatically on
panel switch. No SSE / WebSocket — append-only event log + low poll
rate keeps the implementation simple and reconnect-free. - Theme-aware (light/dark) and mobile-responsive.
All state changes (pause / resume / cancel, mission creation, plan
authoring) still happen via the agent-facing mission.* tools — the
dashboard panel is read-only by design.
Added — Mid-mission auto-pause on capability confirmation
capability.ConfirmationRequiredError+capability.ErrConfirmationRequired.
New structured error type returned by the tool dispatcher when a
capability check resolves to allowed ANDRequiresConfirmation.
Carries the capability resource ID and engine reason; sentinel
detection viaerrors.Isor structured recovery viaerrors.As.
Previously theRequiresConfirmationflag was plumbed through the
engine but silently ignored at the tool dispatch layer.worker.Result.NeedsConfirmation+Result.ConfirmationReason.
Distinguishes "this step did not run because the underlying
capability requires explicit approval" from a real failure.- Supervisor auto-pause path.
runStepbranches on
NeedsConfirmationBEFORE the success/failure split. It marks the
stepState=waiting_user, stamps the reason inStep.Error, leaves
CompletedAtunset, emitssupervisor.step_paused, and returns a
sentinel error.runSequentialcatches it, emits a
mission.confirmation_requiredevent with{step_id, reason},
callsManager.Pauseto transition the mission towaiting_user,
and exits withErrMissionPaused. Replanning is bypassed entirely
on the auto-pause path. - Runtime auto-resume.
Runtime.scannow lists missions in
StateRunning(not justStatePlanned) on every poll tick. After
mission.interrupt action=resumetransitions the mission back to
running, the runtime spawns a fresh supervisor + worker pair. The
supervisor's cursor treats stepstate=waiting_useras non-terminal
and re-dispatches cleanly.
Added — Per-worker concurrent handling
Worker.MaxConcurrentfield. Caps how many tasks a single
worker may process at once. Default 1 (preserves the historical
one-task-at-a-time semantics — fully backwards compatible). Set
to N > 1 to fan tasks out into goroutines bounded by an internal
semaphore.- Slot-before-receive ordering. A saturated worker blocks on
sem-send BEFORE reading from the dispatch chan, so the bus's
PublishCompeting fall-through correctly routes new work to peer
workers via SendTimeout — no internal queuing inside busy workers. - Clean shutdown.
Worker.Runnow waits for every in-flight
handler to complete before returning on context cancellation. missionruntime.Options.WorkerMaxConcurrent. Runtime-level
configuration plumbed through to every spawnedWorker.
Performance
- 9× wall-clock parallelism upper bound. With 3 workers ×
MaxConcurrent=3, up to 9 LLM API calls can be in flight
simultaneously while the goroutine count and runtime overhead stay
small. Verified by test: 3 tasks × 200 ms each on one worker with
MaxConcurrent=3complete in ~205 ms wall-clock vs ~600 ms
sequential.
Notes
- Auto-pause and replanning are independent: a confirmation-required
result NEVER triggers the Replanner. Auto-pause is checked first in
the supervisor's outer loop, ahead of the replan branch. - Per-worker concurrency multiplies with cross-worker parallelism.
With M workers ×MaxConcurrent=N, the effective in-flight cap is
M×N tasks pool-wide. - Granting the confirmation between Run #1 (paused) and Run #2
(resume) is still the user's responsibility — modify the capability
rule, or use the prompter's interactive path. The mission engine
handles the pause/resume cycle but does not auto-approve.
Tests
Full repo go test -race -count=1 ./... passes across all 127
packages. New test surface this release:
- 3 auto-pause tests (supervisor + worker layers): pause-on-
confirmation, resume-after-confirmation, sentinel-to-Result
translation. - 4 per-worker concurrency tests: parallel execution, cap
enforcement, in-flight drain on shutdown, default-1 preserves
sequential. - 2 dashboard frontend tests: index.html carries panel markup,
chat.js carries loader symbols. - 4 Manager.Replan tests (already shipped in v0.3.0; relisted
here for completeness alongside the auto-pause path that builds
on the same Manager / event log machinery).
Compatibility
No breaking changes. The new fields on Worker, Result,
Supervisor, and missionruntime.Options are optional with
zero-value defaults that preserve v0.3.0 behaviour exactly. No
mission schema, plan, or wire-format change. Resume-after-pause works
on any mission persisted under v0.1.0 → v0.3.0 without migration.
Full changelog: v0.3.0...v0.3.1