Skip to content

v0.3.1 — Auto-pause, per-worker concurrency, dashboard panel

Choose a tag to compare

@a-radwan-20 a-radwan-20 released this 02 Jun 09:13
· 40 commits to main since this release

Highlights

Three substantive capabilities round out the v0.3.x line:

  1. 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 to waiting_user and emits a
    mission.confirmation_required event the dashboard can render.
    Resume via mission.interrupt action=resume once the user grants
    the capability.
  2. Per-worker concurrent handlingWorker.MaxConcurrent lets 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.
  3. 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
    for waiting_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.x mission.confirmation_required and
    mission.replanned events.
  • 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 AND RequiresConfirmation.
    Carries the capability resource ID and engine reason; sentinel
    detection via errors.Is or structured recovery via errors.As.
    Previously the RequiresConfirmation flag 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. runStep branches on
    NeedsConfirmation BEFORE the success/failure split. It marks the
    step State=waiting_user, stamps the reason in Step.Error, leaves
    CompletedAt unset, emits supervisor.step_paused, and returns a
    sentinel error. runSequential catches it, emits a
    mission.confirmation_required event with {step_id, reason},
    calls Manager.Pause to transition the mission to waiting_user,
    and exits with ErrMissionPaused. Replanning is bypassed entirely
    on the auto-pause path.
  • Runtime auto-resume. Runtime.scan now lists missions in
    StateRunning (not just StatePlanned) on every poll tick. After
    mission.interrupt action=resume transitions the mission back to
    running, the runtime spawns a fresh supervisor + worker pair. The
    supervisor's cursor treats step state=waiting_user as non-terminal
    and re-dispatches cleanly.

Added — Per-worker concurrent handling

  • Worker.MaxConcurrent field. 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.Run now waits for every in-flight
    handler to complete before returning on context cancellation.
  • missionruntime.Options.WorkerMaxConcurrent. Runtime-level
    configuration plumbed through to every spawned Worker.

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=3 complete 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