Skip to content

feat(chat): @-mention picker to dispatch sub-agents#15

Open
Mingholy wants to merge 2 commits into
simpx:mainfrom
Mingholy:feat/agent-mention
Open

feat(chat): @-mention picker to dispatch sub-agents#15
Mingholy wants to merge 2 commits into
simpx:mainfrom
Mingholy:feat/agent-mention

Conversation

@Mingholy

@Mingholy Mingholy commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Surface composed .claude/agents/*.md as invocable sub-agents via @-mention dropdown
  • Parse agent frontmatter (name/description/color) for display
  • Model dispatches to Agent tool when message starts with @<name>

Motivation

Upstream already composes the agents/ directory but has no UI to invoke them. This adds the missing interaction layer.

Changes

  • server/src/compose.ts: AgentMeta type + parseAgentFrontmatter() + listLoopAgents(loopId)
  • server/src/index.ts: GET /api/loops/:id/agents endpoint
  • server/src/system-prompt.ts: Appends "@-mention sub-agents" block to system prompt
  • web/src/components/chat/AgentMention.tsx (new): Dropdown triggered by leading @, filter + keyboard nav
  • web/src/components/chat/Composer.tsx: Mount <AgentMention/> beside <SlashCommand/>
  • web/src/useLoopRuntime.tsx: availableAgents state, fetched once per loopId

Test plan

  • Create .claude/agents/researcher.md with frontmatter → appears in @ dropdown
  • Type @res → filtered to "researcher" → select → model dispatches Agent tool
  • Loop with no agents → @ shows empty-state hint

Screenshots

Before / After

@-mention dropdown in Composer

Before (main) After (feat/agent-mention)
before after
No @-mention support Typing @ shows SUB-AGENTS dropdown with empty-state instructions

lemual.flm and others added 2 commits June 7, 2026 19:33
Surfaces the agents tier (already composed into each loop's .claude/agents/
on main) as a usable entry point. Re-implemented on current main after the
original stacked CRs (#27509818 compose + #27557638 picker) were stranded by
main's resync onto upstream — the compose half is now upstream, this is just
the picker layer.

- compose.ts: AgentMeta + parseAgentFrontmatter + listLoopAgents(loopId) —
  reads the already-composed loopComposedAgentsDir, .md filter, frontmatter
  name/description/color, alpha sort; skips dotfiles / broken symlinks.
- index.ts: GET /api/loops/:id/agents (requireAuth + loopExists) → {agents}.
- system-prompt.ts: buildLoopatAppend appends a "## @-mention sub-agents"
  block instructing the model to dispatch via the Agent tool when a message
  starts with @<name>; omitted when the loop has no agents.
- useLoopRuntime: availableAgents state, fetched once per loopId from the
  endpoint (empty array on failure), exposed via LoopRuntimeExtra.
- AgentMention.tsx (new): sister to SlashCommand — opens on leading @, filters
  by name+description, inserts `@<name> ` on select, capture-phase key nav.
  Empty-state hint when the loop has no composed agents (so @ isn't silent).
- Composer.tsx: mount <AgentMention/> beside <SlashCommand/> (mutually
  exclusive by construction).

Tested: server tsc clean; web tsc clean for all touched files (only the
pre-existing CodeEditor.tsx StreamParser error remains on main, unrelated);
vite build OK.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Guard against out-of-bounds crash when filtered list shrinks between
renders by clamping selectedIdx in Enter/Arrow handlers. Also reject
agent names containing unsafe characters (e.g. backticks) that would
break markdown formatting in the system prompt.

Co-Authored-By: Claude Opus 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