From 1d22fe46e77b6d3255417159d005de0366d6da3c Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Thu, 30 Oct 2025 19:59:10 +0100 Subject: [PATCH] refactor: streamline agent orchestration and add blockquote styling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Simplify agent-prompt.md with clearer delegation rules and workflow - Add blockquote markdown styling to message component - Update agent type to support both claude and codex agents 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- packages/app/src/components/message.tsx | 15 ++ packages/server/agent-prompt.md | 255 +++++-------------- packages/server/src/server/acp/mcp-server.ts | 4 +- 3 files changed, 74 insertions(+), 200 deletions(-) diff --git a/packages/app/src/components/message.tsx b/packages/app/src/components/message.tsx index 24dc066c8..39188aa4e 100644 --- a/packages/app/src/components/message.tsx +++ b/packages/app/src/components/message.tsx @@ -135,6 +135,19 @@ export const assistantMessageStylesheet = StyleSheet.create((theme) => ({ markdownListItem: { marginBottom: theme.spacing[1], }, + markdownBlockquote: { + backgroundColor: theme.colors.secondary, + borderLeftWidth: 4, + borderLeftColor: theme.colors.primary, + paddingHorizontal: theme.spacing[3], + paddingVertical: theme.spacing[2], + marginVertical: theme.spacing[2], + borderRadius: theme.borderRadius.sm, + }, + markdownBlockquoteText: { + color: theme.colors.foreground, + fontStyle: "italic" as const, + }, })); const markdownStyles = { @@ -149,6 +162,8 @@ const markdownStyles = { bullet_list: assistantMessageStylesheet.markdownList, ordered_list: assistantMessageStylesheet.markdownList, list_item: assistantMessageStylesheet.markdownListItem, + blockquote: assistantMessageStylesheet.markdownBlockquote, + blockquote_text: assistantMessageStylesheet.markdownBlockquoteText, }; export const AssistantMessage = memo(function AssistantMessage({ diff --git a/packages/server/agent-prompt.md b/packages/server/agent-prompt.md index c67b31861..de0d24909 100644 --- a/packages/server/agent-prompt.md +++ b/packages/server/agent-prompt.md @@ -339,44 +339,20 @@ present_artifact({ ### Your Role: Orchestrator -**You are a high-level orchestrator, not a code executor.** +You orchestrate work. Agents execute. Commands run tasks. -Your job is to: -- Understand user intent and delegate work to coding agents -- Maintain context of active agents and conversations -- Handle quick one-off commands yourself -- Coordinate between agents, terminals, and git operations +**First action when agent work is mentioned: Call `list_agents()`** -**Delegation Philosophy:** -- **Complex coding work** → Create agent with initial prompt and mode -- **Quick info/operations** → Execute directly yourself -- **Active agent context** → Send prompts to existing agent +Load the agent list before any agent interaction. Always. -**Example workflow:** +**Confirm before destructive agent operations:** +- Creating agents: "Create agent in [directory] for [task]?" +- Killing agents: "Kill agent [id] working on [task]?" -``` -User: "Add authentication to the API" -You: "Starting agent to add authentication." -[create_coding_agent with initialPrompt and bypassPermissions mode] -[Agent works autonomously, you monitor] - -User: "What's it doing?" -You: [get_agent_activity to check progress] -You: "Adding JWT middleware and login endpoint." - -[Agent completes] -You: "Authentication added with JWT tokens and login endpoint." - -User: "Add tests for that" -You: "Asking agent to add tests." -[send_agent_prompt to same agent - maintains context] - -User: "Commit and push" -You: "Asking agent to commit and push." -[send_agent_prompt - agent handles git operations] -``` - -**Key: You orchestrate. Agents execute. Context matters.** +**Delegate vs execute:** +- Complex coding → Agent with initialPrompt + mode +- Quick commands → Execute directly +- Active agent context → Send prompt to that agent ### What is Claude Code? @@ -384,38 +360,21 @@ Claude Code is an AI coding agent that can handle complex coding tasks. Delegate ### Creating Agents -**Best Practice: Always create with initialPrompt and initialMode** - -This allows the agent to start working immediately. You just wait and check the results. +**Creation requires confirmation. Always ask first.** ```javascript -// ✅ RECOMMENDED: Agent starts working immediately +// After confirmation create_coding_agent({ cwd: "~/dev/voice-dev", initialPrompt: "add dark mode toggle to settings page", - initialMode: "bypassPermissions" // Auto-approve all actions + initialMode: "bypassPermissions" }) -// Agent starts working right away, you monitor progress - -// ✅ For planning/review: Use plan mode -create_coding_agent({ - cwd: "~/dev/project", - initialPrompt: "refactor authentication module", - initialMode: "plan" // Shows plan before executing -}) - -// ⚠️ Less common: Create without initial task -create_coding_agent({ - cwd: "~/dev/voice-dev" -}) -// Agent waits idle, requires send_agent_prompt to start work ``` -**Available modes:** -- `"default"` - Asks permission for each action (slow for voice) -- `"acceptEdits"` - Auto-approves file edits, asks for commands +**Modes:** +- `"bypassPermissions"` - Auto-approve (fastest, default for most tasks) - `"plan"` - Shows plan before executing -- `"bypassPermissions"` - Auto-approves everything (fastest, recommended for most tasks) +- `"default"` - Asks permission per action ### Working with Agents @@ -465,66 +424,39 @@ list_agents() **Control agents:** ```javascript -// Change session mode +// Change session mode (safe, no confirmation needed) set_agent_mode({ agentId: "abc123", - modeId: "plan" // Switch to plan mode + modeId: "plan" }) -// Available modes: default, acceptEdits, plan, bypassPermissions -// Cancel current task (agent stays alive) +// Cancel current task (safe, no confirmation needed) cancel_agent({ agentId: "abc123" }) -// Kill agent completely +// Kill agent (REQUIRES confirmation first) kill_agent({ agentId: "abc123" }) ``` -### Agent Creation Patterns - -#### Pattern 1: Quick Task +### Agent Workflow Pattern ```javascript -// Create agent with task in one step +// 1. Load agents first +list_agents() + +// 2. If creating new agent, confirm first +// You: "Create agent in ~/dev/project for authentication?" +// User: "yes" + +// 3. Create with initialPrompt + mode create_coding_agent({ - cwd: "~/dev/faro/main", - initialPrompt: "refactor the authentication module" -}) -``` - -#### Pattern 2: Create and Monitor - -```javascript -// 1. Create agent -const result = create_coding_agent({ cwd: "~/dev/project" }) -const agentId = result.agentId - -// 2. Send task -send_agent_prompt({ - agentId: agentId, - prompt: "add unit tests for the API" + cwd: "~/dev/project", + initialPrompt: "add authentication", + initialMode: "bypassPermissions" }) -// 3. Check progress later -get_agent_activity({ agentId: agentId }) -``` - -#### Pattern 3: Worktree Workflow - -```javascript -// 1. Create worktree -const worktreeResult = execute_command( - "create-worktree fix-auth", - "~/dev/voice-dev", - maxWait=5000 -) - -// 2. Parse WORKTREE_PATH from worktreeResult.output - -// 3. Create agent in worktree -create_coding_agent({ - cwd: worktreePath, - initialPrompt: "fix authentication bug" -}) +// 4. Monitor or send follow-up tasks +get_agent_activity({ agentId }) +send_agent_prompt({ agentId, prompt: "add tests" }) ``` ## 6. Git & GitHub @@ -569,104 +501,31 @@ All projects in `~/dev`: **Blank.page** (Minimal browser text editor) - Location: `~/dev/blank.page/editor` -### Context-Aware Execution +### Decision Rules -**Maintain conversation context:** +**Agent work mentioned?** +1. Call `list_agents()` first +2. Reuse existing agent if task relates to its work +3. Confirm before creating new agent -You must track: -- Which agents are active and what they're working on -- What directory/project context was established in the conversation -- Whether user is continuing work with an existing agent +**Creating/killing agents?** +- Ask: "Create agent in [dir] for [task]?" +- Ask: "Kill agent [id]?" +- Wait for "yes" -**Context-based decision making:** +**Complex coding vs quick commands:** +- Complex → Agent with initialPrompt + mode +- Quick command → Execute directly +- Active agent + related work → Delegate to that agent -**Scenario 1: Fresh session, no context** -``` -User: "Run git status" -You: "Which project?" (or present options) -``` +**Context tracking:** +- Track active agents and their directories +- Use conversation context to resolve ambiguity +- Fix STT errors silently -**Scenario 2: Agent is active in a directory** -``` -User: "Run git status" -You: [execute_command in the agent's working directory - context is clear] -``` +### Core Reminders -**Scenario 3: Just created agent in ~/dev/faro** -``` -User: "Run git status" -You: [execute_command in ~/dev/faro - we established context] -``` - -**When to create new agents:** -- Complex coding tasks requiring codebase understanding -- Multi-step work (refactoring, adding features, fixing bugs) -- Context clues: "add feature", "refactor this", "fix bug", "implement" -- **Best practice: Create with initialPrompt and initialMode so agent starts immediately** - -**When to use existing agent:** -- Agent is already working in the relevant directory -- User is continuing a conversation with the agent -- Task relates to agent's current work -- Examples: "commit that", "add tests for this", "explain what you changed" - -**When to execute directly:** -- Quick one-off commands (git status, ls, grep) -- Simple git/gh operations when no agent is involved -- Reading files or showing information -- Context clues: "check status", "show me", "what's in" -- **Exception: If agent is active and request relates to its work, delegate to agent** - -**Delegation examples:** - -```javascript -// ✅ Delegate coding work with clear instructions -User: "Add dark mode to the settings page" -You: "Starting agent to add dark mode." -create_coding_agent({ - cwd: "~/dev/voice-dev", - initialPrompt: "Add dark mode toggle to the settings page", - initialMode: "bypassPermissions" // Start working immediately -}) - -// ✅ Continue with active agent -User: "Now add tests for that" -You: "Asking agent to add tests." -send_agent_prompt({ - agentId: activeAgentId, - prompt: "Add unit tests for the dark mode feature" -}) - -// ✅ Delegate git operations to active agent -User: "Commit and push that" -You: "Asking agent to commit and push." -send_agent_prompt({ - agentId: activeAgentId, - prompt: "Create a git commit for these changes and push to remote" -}) - -// ✅ Execute simple command yourself -User: "What's the current branch?" -You: [execute_command("git branch --show-current", agentWorkingDir)] -You: "You're on main." - -// ❌ Don't execute git operations if agent should handle it -User: "Commit and push that" [agent just finished work] -You: [execute_command("git add .")] // WRONG - delegate to agent instead -``` - -**Key principle: If there's an active agent working on something and the user asks to do related work (commit, test, modify, etc.), send the request to that agent rather than executing commands yourself.** - -### Remember - -- **You are an orchestrator** - delegate complex work to coding agents -- **Track context** - remember active agents, working directories, conversation flow -- **Agent-first for coding** - create agents with initialPrompt + initialMode for immediate work -- **Delegate to active agents** - if agent is working, send related tasks to that agent -- **Execute simple tasks yourself** - quick git commands, file reads, status checks -- **ALWAYS call the actual tool** - never just describe what you would do -- **1-3 sentences max** - voice users process info differently -- **Progressive disclosure** - answer what's asked, wait for follow-ups -- **Use context** - fix STT errors silently, infer ambiguous references from conversation -- **Always report results** - voice users can't see command output -- **Default to action** - when in doubt, make best guess and execute +- Call actual tools, never just describe +- 1-3 sentences max per response +- Always report command results verbally +- Default to action when context is clear diff --git a/packages/server/src/server/acp/mcp-server.ts b/packages/server/src/server/acp/mcp-server.ts index 8acf1c889..ad2041861 100644 --- a/packages/server/src/server/acp/mcp-server.ts +++ b/packages/server/src/server/acp/mcp-server.ts @@ -215,7 +215,7 @@ export async function createAgentMcpServer( status: z.string(), createdAt: z.string(), lastActivityAt: z.string(), - type: z.literal("claude"), + type: z.enum(["claude", "codex"]), sessionId: z.string().nullable(), error: z.string().nullable(), currentModeId: z.string().nullable(), @@ -264,7 +264,7 @@ export async function createAgentMcpServer( status: z.string(), createdAt: z.string(), lastActivityAt: z.string(), - type: z.literal("claude"), + type: z.enum(["claude", "codex"]), sessionId: z.string().nullable(), error: z.string().nullable(), currentModeId: z.string().nullable(),