feat(connector): add /focus and /ask commands for @-free routing#391
feat(connector): add /focus and /ask commands for @-free routing#391QiliangLi wants to merge 2 commits intozts212653:mainfrom
Conversation
Ports the /focus and /ask slash commands from clowder-ai to enable cat routing without @mentions, addressing the Feishu @mention UX conflict. - /focus <猫名>: Sets a preferred cat for the current thread. Subsequent messages without @mentions will route to this cat. - /ask <猫名> <消息>: Single-shot message to a specific cat without changing the default routing. Features: - normalizeCatId handles aliases: 宪宪/布偶猫→opus, 砚砚/缅因猫→codex, 烁烁/暹罗猫→gemini - preferredCats stored at thread level - ConnectorRouter checks preferredCats before last-active cat fallback Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d2307d90d1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| { cmd: '/focus <猫名>', desc: '设置当前 thread 的首选猫' }, | ||
| { cmd: '/ask <猫名> <消息>', desc: '单次定向:让指定猫回复这条消息' }, |
There was a problem hiding this comment.
Register new connector commands in the shared registry
Adding /focus and /ask only to FALLBACK_COMMANDS does not make them visible in normal runtime, because buildCommandsList() prefers registry.listBySurface('connector') whenever a CommandRegistry is wired (the default gateway path). As a result, users can execute the new commands but /commands will still omit them in production, which breaks command discoverability.
Useful? React with 👍 / 👎.
| if (this.deps.threadStore.updatePreferredCats) { | ||
| await this.deps.threadStore.updatePreferredCats(binding.threadId, [catId]); | ||
| } |
There was a problem hiding this comment.
Fail /focus when preferred-cat persistence is unavailable
This branch silently skips persistence if threadStore.updatePreferredCats is missing, but the handler still returns a success message (已设置首选猫). In any deployment or test wiring that uses a thread store without that optional method, /focus appears to succeed while routing behavior never changes, creating a hard-to-debug false-positive state.
Useful? React with 👍 / 👎.
| if (preferredCats && preferredCats.length > 0) { | ||
| // Use first preferred cat | ||
| targetCatId = preferredCats[0]; | ||
| preferredCatsApplied = true; |
There was a problem hiding this comment.
Validate preferredCats before forcing routing target
The connector router now takes preferredCats[0] as the target without checking whether that cat is currently routable. If a thread stores a stale/disabled cat ID (for example after catalog or provider changes), every non-mention message in that thread is forced to an invalid target instead of falling back, causing invocation failures rather than a reply.
Useful? React with 👍 / 👎.
- P1: Validate preferredCats exists in catRegistry before routing - Prevents routing to stale/disabled cat IDs - Falls back to last-active cat if preferred cat invalid - P2: Register /focus and /ask in CORE_COMMANDS - Commands now appear in /commands listing in production - Previously only in FALLBACK_COMMANDS (not visible with registry) - P2: Fail /focus when persistence unavailable - Returns error instead of silent success when updatePreferredCats missing - Prevents false-positive state where command appears to work but doesn't Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Ports the
/focusand/askslash commands from clowder-ai feat branch to enable cat routing without @mentions, addressing the Feishu @mention UX conflict.Changes
/focus <猫名>: Sets a preferred cat for the current thread. Subsequent messages without @mentions will route to this cat./ask <猫名> <消息>: Single-shot message to a specific cat without changing the default routing.Features
normalizeCatIdhandles aliases:preferredCatsstored at thread level viaupdatePreferredCatspreferredCatsbefore last-active cat fallback/commandslistingFiles Modified
packages/api/src/infrastructure/connectors/ConnectorCommandLayer.ts- Added handleFocus, handleAsk, normalizeCatId methodspackages/api/src/infrastructure/connectors/ConnectorRouter.ts- Added /ask forwarding and preferredCats priority logicpackages/api/src/infrastructure/connectors/connector-command-helpers.ts- Added /focus and /ask to FALLBACK_COMMANDSTest Plan
🤖 Generated with Claude Code