Skip to content

feat(canvas-sync): derive voiceCapable + voiceId from agent_config.settings.voice#1330

Merged
itskai-dev merged 1 commit into
mainfrom
claude/voice-capable-truth-seam
May 4, 2026
Merged

feat(canvas-sync): derive voiceCapable + voiceId from agent_config.settings.voice#1330
itskai-dev merged 1 commit into
mainfrom
claude/voice-capable-truth-seam

Conversation

@itskai-dev

Copy link
Copy Markdown
Collaborator

Summary

  • voiceCapable was a phantom — defined on AgentPresence (cloud), read by the 🎤 header badge + agents-panel badge + my new Speak row in AgentDetailPanel.tsx, but never produced anywhere. Every consumer fell to ?? false and the badge was dead code.
  • Truth source already exists: agent_config.settings.voice (kokoro voice ID — see canvas-interactive.ts hashTts and assignment.ts). Same shape as identityColor/avatar injection.
  • This patch extends the SQL filter in syncCanvas to also include rows with voice in settings, then injects voiceCapable: true + voiceId on the agent shape pushed to cloud.
  • Cloud passes payload through unchanged (host-canvas-state-routes.ts spreads row.payload), so this single node-side change makes the boolean real end-to-end.

Why this is a 1-file change

Cloud is already pass-through. apps/web/src/app/presence/use-host-state.ts:340,464 already maps voiceCapable: a.voiceCapable ?? false and voiceId: a.voiceId. The whole chain was waiting on the producer.

Verified canonical baseline

Curled /api/hosts/e4e35463…/agent-configs — compass has settings.voice = "af_sarah". Once this rolls, compass will be the lit-row test case for the speak V0 lane.

Test plan

  • tsc clean (npx tsc --noEmit)
  • After merge: roll canonical to new node image
  • Curl /api/hosts/.../canvas post-roll — confirm agents.compass.voiceCapable === true + voiceId === "af_sarah"
  • Then re-prove cloud-side speak V0 row (#3230) on canonical

🤖 Generated with Claude Code

…ttings.voice

Until now `voiceCapable` was a phantom field — defined on the cloud's
AgentPresence shape, read by the 🎤 header badge + agents-panel badge,
but never produced. The cloud canvas API returned agent shapes with no
such field, so every read fell to `?? false` and the badge was dead code.

Truth source already exists: `agent_config.settings.voice` (kokoro voice
ID, see canvas-interactive.ts hashTts + assignment.ts). Same pattern as
identityColor injection in syncCanvas — extend the SQL filter to also
match rows with `voice` in settings, then surface `voiceCapable: true` +
`voiceId` on the agent shape pushed to cloud.

Cloud passes the payload through unchanged (host-canvas-state-routes.ts
spreads row.payload), so this single node-side change makes the
voiceCapable boolean real end-to-end.

Unblocks the speak V0 LocalActionRow lane (kai msg-1777913827161,
re-scoped 1777914293792 to fix upstream first).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@itskai-dev
itskai-dev merged commit 1b5cb3e into main May 4, 2026
11 checks passed
@itskai-dev
itskai-dev deleted the claude/voice-capable-truth-seam branch May 4, 2026 17:13
itskai-dev added a commit that referenced this pull request May 4, 2026
…ud (#1331)

* fix(canvas-sync): mirror voiceCapable+voiceId injection in pushCanvasStateToCloud

Two node writers POST to /api/hosts/:id/canvas:
  - src/cloud.ts:1558 syncCanvas (30s cadence) — sets voiceCapable
    via PR #1330 truth seam from agent_config.settings.voice
  - src/server.ts:13151 pushCanvasStateToCloud (5s cadence) — sent
    only {state, task, displayName, identityColor, avatar}

The cloud POST handler does `payload: agentState as object` (full
replace, not merge). The 5s writer was clobbering voiceCapable/voiceId
set by the 30s syncCanvas. Compass observed flipping voiceCapable
true→false→true on each cycle.

Patch: extend the 5s writer to mirror writer #1's voice derivation
from the same agent_config.settings.voice source. Both writers now
agree on payload shape so the later one preserves what the earlier
set.

Unblocks reflectt-cloud PR #3230 speak V0 proof.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(scope-policy): add task tag for src/server.ts sensitive-path gate

task-1777140469973-770cy4yma — speak visibility V0 truth-seam
follow-up unblocking pushCanvasStateToCloud writer #2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <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