fix(web): use session flavor label in voice context formatters (closes #680)#815
Merged
Merged
Conversation
…tiann#680) Replaces hardcoded \"Claude Code\" strings in voice context injections with the active session's flavor label (Cursor, Codex, Gemini, etc.) via getFlavorLabel() from @hapi/protocol. Falls back to \"coding agent\" for unknown or missing flavors. Threads an agentLabel string param through: - formatMessage - formatNewSingleMessage - formatNewMessages - formatHistory - formatSessionFull - formatPermissionRequest - buildSessionVoiceContextPlan (passes to its internal formatMessage call) voiceHooks adds a single getAgentLabel(session) helper that reads session.metadata.flavor and resolves the display label once per call. Tests updated to cover the new parameter shape and to assert that \"Claude Code\" is never substituted regardless of agent flavor. formatReadyEvent already used a generic \"coding agent\" phrasing and needs no signature change. Closes tiann#680 Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Findings
No issues found in the added or modified lines.
Questions
None.
Summary
Review mode: initial
Reviewed the full diff for the voice context formatter label threading. The formatter signatures, voice hook call sites, and bootstrap context plan all consistently pass the resolved agent label, and the touched tests cover the main non-Claude regression path. Residual risk: I could not run the test suite in this runner because bun is not installed.
Testing
Not run locally: bun unavailable in this environment (bun: command not found).
HAPI Bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #680
Problem
web/src/realtime/hooks/contextFormatters.tshardcodes the literal string"Claude Code"in four places that get fed into the voice agent's context window:formatPlainText— assistant message prefix (Claude Code: <text>...)formatPermissionRequest— permission prompt narration (Claude Code is requesting permission to use ...)formatMessagetool-call narration — two places (Claude Code is using ${name}andClaude Code is using ${name} with arguments: ...)Result: voice readouts always announce "Claude Code" regardless of which agent flavor (Cursor, Codex, Gemini, Kimi, OpenCode) is actually running the session. The voice context lies about which agent the user is talking about, which is confusing in a fleet view and just plain wrong on a single-flavor non-Claude session.
Fix
Thread
agentLabel: stringthrough the affected formatter signatures and resolve the label once per call invoiceHooksfromsession.metadata.flavorviagetFlavorLabel()from@hapi/protocol:Falls back to the generic
"coding agent"for unknown or missing flavors (still better than substituting "Claude Code" everywhere).Files
web/src/realtime/hooks/contextFormatters.ts(+27/-18) — signature changes + literal swapsweb/src/realtime/hooks/contextFormatters.test.ts(+33/-9) — passagentLabel, add regression test for bug(voice): context formatters hardcode "Claude Code" for all agent flavors #680 that asserts"Claude Code"never appears for non-Claude flavorsweb/src/realtime/hooks/voiceContextPlan.ts(+6/-2) — threadagentLabelintobuildSessionVoiceContextPlanand pass to its innerformatMessagecallweb/src/realtime/hooks/voiceContextPlan.test.ts(+3/-2) — passagentLabelarg, assert no"Claude Code"substitutionweb/src/realtime/hooks/voiceHooks.ts(+19/-7) —getAgentLabelhelper + thread through all 5 call sites (reportSession,onPermissionRequested,onMessages,prepareVoiceSession)Net: 5 files, +88 / -38 lines.
Compatibility
formatReadyEventalready used a generic"coding agent"phrasing; no signature change.getFlavorLabel/isKnownFlavoralready exist inshared/src/flavors.ts(added in the voice/flavor work that landed earlier); only the threading is net-new here.SessionMetadataSummaryalready hasflavor?: string | null."coding agent"— strictly better than the current hardcoded"Claude Code".Verification
bun x vitest run web/src/realtime/hooks/contextFormatters.test.ts— 15/15 passing, including new regression assertions that"Claude Code"is absent regardless ofagentLabel.bun x tsc --noEmitfromweb/: zero new errors introduced (pre-existing workspace-link errors unrelated to this change).Made with Cursor