feat: background tasks panel (Phase 7)
This commit is contained in:
1 parent
5c35fa9c65
commit
af296da6b8
7 files changed
+339
-5
No files matched your search
@@ -26,7 +26,7 @@ Goal: full-parity native iOS app per UPDATE_PATH.md, verified in simulator via X
|
||||
- [x] Phase 4: voice/model pickers with sync-on-join (commit ca2d26f)
|
||||
- [x] Phase 5: media player — commit 0af944e (webm playback blocked by iOS AVPlayer; see status below)
|
||||
- [x] Phase 6: media search, choices, library panel (commit cbf1830)
|
||||
- [ ] Phase 7: background tasks panel (task_event fold-in)
|
||||
- [x] Phase 7: background tasks panel (commit 63f2634)
|
||||
- [ ] Phase 8: polish/hardening/parity pass
|
||||
- [ ] Phase 9: docs & handoff
|
||||
|
||||
@@ -130,6 +130,27 @@ Verified in simulator (log + UI + server evidence):
|
||||
- Add Stream: entered name + URL, tapped Add → POST /media/api/streams 400 (server rejected test URL) → error message "Could not add stream: Media API request failed with HTTP 400. url must be http(s)" displayed in red.
|
||||
- Polling without session: confirmed via AVPlayer webm decode error in logs (state was fetched and reconciled even though no voice session was active).
|
||||
|
||||
## Phase 7 status (2026-08-30 ~12:50)
|
||||
Done:
|
||||
- `TaskStore` (Sources/LiveKit/TaskStore.swift): @MainActor ObservableObject. Folds task_event payloads into TaskItem entries keyed by taskId — created (from nested `task` object or description), step (appends {role, content}, pending→running), completed (result + completedAt), failed (error). `sortedTasks` by createdAt desc; `activeCount` = pending+running (badge); `clear()`.
|
||||
- `ControlChannel.handleTaskEvent` fixed to match the real wire format: agent publishes `{type:"task_event", task_id, event: created|step|completed|failed, ...}` — discriminator is `event`, not `type` (old code never matched). Parses nested `task.description`/`task.created_at`. Added `JSONValue.doubleValue`.
|
||||
- `VoiceSession`: owns `taskStore`; `.taskEvent` in handleControlEvent → `taskStore.apply`.
|
||||
- `TaskPanelView` (Sources/Features/Tasks/TaskPanelView.swift): cards sorted desc, status dot (gray/blue/green/red), description header, steps list with role labels + web-mirrored colors (thinking=blue, tool_call=indigo, tool_result=muted, text=primary), green result block, red error block. Empty state "Nothing running / Ask Hope to research or compare something."
|
||||
- Toolbar: `tray.full` button in ConversationView with red count badge when activeCount > 0; pushes TaskPanelView (NavigationLink, matching the media panel pattern).
|
||||
- DEBUG-only "Sample" toolbar button in the panel injects two synthetic tasks (one completed, one failed) for UI verification.
|
||||
|
||||
Verified in simulator — REAL events (primary):
|
||||
- Start → ready (text mode) → composer: "Research the history of jazz music in a background task…" → send.
|
||||
- Agent published 8 real task_events on topic `tasks` (created + 6 steps incl. thinking/tool_call/tool_result/text + completed). Logs: `[dev.shane.voice:tasks] task created id=738e422c steps=0 … task completed id=738e422c steps=6`.
|
||||
- Panel opened from toolbar shows the real card: description, all 6 role-styled steps (web_search tool_call visible), green result block with full jazz-history summary. Badge showed "1" while running (activeCount).
|
||||
|
||||
Verified — SYNTHETIC events (secondary, via DEBUG Sample button):
|
||||
- Injected sample-a (created→2 steps→completed) and sample-b (created→step→failed); both cards rendered with correct status dots, error block ("Search backend timed out after 30s"), and badge count.
|
||||
|
||||
Notes:
|
||||
- Screenshot captured at /tmp/taskpanel.png (model can't view images; verified via UI snapshot text + logs instead).
|
||||
- No server/agent changes needed — the task dispatch pipeline already worked; only the iOS client was missing.
|
||||
|
||||
## Subagent notes
|
||||
- Small context model: keep prompts self-contained, point at this file + UPDATE_PATH.md
|
||||
- Watch for loops (repeated identical commands) — kill and redirect if seen
|
||||
|
||||
Reference in new issue
Block a user