Skip to content

fix(chat): clear Responding state + multi-camera grab_frame#98

Merged
edgarriba merged 3 commits into
mainfrom
fix/chat-streaming-fixes
May 18, 2026
Merged

fix(chat): clear Responding state + multi-camera grab_frame#98
edgarriba merged 3 commits into
mainfrom
fix/chat-streaming-fixes

Conversation

@edgarriba

Copy link
Copy Markdown
Member

Summary

  • Fix Chat tab stuck permanently in "Responding" mode after a grab_frame response: React StrictMode double-invokes effects, permanently zeroing mountedRef.current — removed the guard (React 18 makes setState on unmounted components a safe no-op)
  • Fix Stop button doing nothing: added ctrl.abort() on done/error SSE events to unblock the pending reader.read() inside parseSseStream; added AbortSignal support to parseSseStream so reader.read() races against the signal
  • Fix agent always grabbing from one camera: removed specific camera name examples from grab_frame tool description (they biased the model); updated prompt.rs to explicitly mandate calling grab_frame for ALL camera nodes when the user asks generically
  • Simplify sse.ts comments for clarity

Test plan

  • Chat tab: type a message, agent responds → "Responding" chip clears after streaming ends
  • Chat tab: click Stop during streaming → streaming stops immediately
  • Chat tab: "what do the cameras see?" → agent calls grab_frame for every camera in inventory, not just one
  • cargo check passes

🤖 Generated with Claude Code

edgarriba and others added 2 commits May 18, 2026 14:37
- Fix React StrictMode bug: mountedRef.current was permanently false
  after StrictMode's double-invoke cleanup, so setStreaming(false) in
  the finally block was silently skipped. Reset mountedRef.current=true
  in effect setup; drop the guard entirely (React 18 safe no-op).

- Fix SSE generator hang: parseSseStream now accepts AbortSignal and
  races every reader.read() against it. Calling ctrl.abort() on done/
  error immediately unblocks any pending read so generator.return()
  can complete and the outer finally runs.

- Fix labeled-break no-op: break inside switch only exits the switch,
  not the for-await. Changed to sseLoop: label + break sseLoop.

- Fix Stop button: ctrl.abort() now reliably interrupts the in-flight
  reader.read() via the abort promise race.

- grab_frame: remove specific camera name examples from tool schema
  (biased LLM toward tapo-terrace). System prompt now instructs agent
  to call grab_frame for ALL camera nodes when no specific camera is
  named by the user.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

… in Dashboard.tsx

SortableTimeseriesCard.tsx and TimeseriesView.tsx were never committed;
CI failed with TS2307 (module not found) and TS7006 (implicit any on
onTopicChange callback parameter).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@edgarriba edgarriba merged commit 85dff9c into main May 18, 2026
1 check passed
@edgarriba edgarriba deleted the fix/chat-streaming-fixes branch May 18, 2026 12:48
edgarriba added a commit that referenced this pull request May 19, 2026
Ships 10 commits worth of features and fixes since v0.0.13:

Features
- agent: grab_frame tool + Gemini Vision provider + image-in-chat (#96)
- dashboard: Chat tab with HTTP+SSE agent gateway (#91)
- agent: client-side turn cancellation via Zenoh cancel topic (#94, #95)
- chat: multi-provider login status, 404 on unknown agent, Claude OAuth
  risk warning (#93)
- mcp: 'bubbaloop mcp --token' prints bearer token for .mcp.json (#90)

Fixes
- agent: grab_frame reads binary JPEG payload + JSON metadata
  attachment from camera nodes (#99)
- chat: clear Responding state after multi-camera grab_frame (#98)
- mcp: eliminate token race between gateway and agent runtime (#89)

Chores
- dashboard: remove LibraryView component (#92, replaced by Chat tab)

Docs
- Comprehensive sync across README, CHANGELOG (backfilled v0.0.8 to
  v0.0.13), CLAUDE.md, ARCHITECTURE.md, ROADMAP.md, concept/reference/
  dashboard docs to match the new feature surface (#100)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant