Files

1 line
33 KiB
JSON

{"repo": "baby-llm/baby-agent", "files": {"CLAUDE.md": {"55712911ad0c3d1554c94198370b08d9076fac1c": {"t": 1785746474.5773177, "n": 11811, "h": "12be25c12e2e84f8", "c": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nBabyAgent is a Go-based AI Agent development tutorial that builds a Claude Code-like assistant from scratch. Each chapter (ch01-ch12) is a standalone module that progressively adds capabilities:\n\n- **ch01-03**: Basic LLM interaction, tool calling, TUI visualization\n- **ch04-06**: MCP protocol integration, context engineering, memory system\n- **ch07**: Agentic RAG with vector search (pgvector)\n- **ch08**: Sandbox/security with Docker isolation and tool confirmation\n- **ch09**: Skills system for task-specific guidance\n- **ch10+**: Web services, evaluation, observability (planned)\n\nChapters ch01-ch09 are complete. The current implementation combines all features into a full-featured agent.\n\n## Common Commands\n\n### Running Chapters\n```bash\n# Run individual chapters (each has a TUI interface)\ngo run ./ch03/main # Chapter 3: TUI visualization\ngo run ./ch04/main # Chapter 4: MCP integration\ngo run ./ch05/main # Chapter 5: Context management\ngo run ./ch06/main # Chapter 6: Memory system\ngo run ./ch08/main # Chapter 8: Full agent with guardrails\ngo run ./ch09/main # Chapter 9: Full agent with skills system (latest)\n```\n\n### Testing\n```bash\n# Run all tests\ngo test ./...\n\n# Run tests for specific chapter\ngo test ./ch08/context/...\ngo test ./ch08/... -v\ngo test ./ch09/skill/... -v\n\n# Run a single test\ngo test -v ./ch08/context/... -run TestTruncatePolicyApply\n```\n\n### Building\n```bash\n# Build a chapter's main executable\ngo build -o bin/ch09 ./ch09/main\n```\n\n## Configuration Requirements\n\nBefore running any chapter, set up the environment:\n\n1. **Copy example configs:**\n ```bash\n cp .env.example .env\n cp config.example.json config.json\n ```\n\n2. **Configure LLM providers** in `config.json`:\n - `front_model`: Main chat model (e.g., gpt-4o, deepseek-chat)\n - `back_model`: Cheaper model for summarization/memory updates\n - Both require: `base_url`, `api_key`, `model`, `context_window`\n\n3. **Optional: Configure MCP servers** in `mcp-server.json` for extending agent capabilities\n\n## Architecture Overview\n\n### Core Components (ch08)\n\n```\nch08/ or ch09/\n├── agent.go # Main Agent: orchestrates LLM calls, tool execution, streaming\n├── context/\n│ ├── engine.go # ContextEngine: manages conversation history, applies policies\n│ ├── policy.go # Policy interface: truncate, offload, summarize strategies\n│ ├── policy_*.go # Policy implementations\n│ └── share.go # Token counting with tiktoken-go\n├── memory/\n│ ├── memory.go # Memory interface: global + workspace memory\n│ └── update.go # LLM-driven memory extraction/update\n├── storage/\n│ ├── storage.go # Storage interface for persistence\n│ └── filesystem.go # File system storage implementation\n├── tool/\n│ ├── tool.go # Tool interface\n│ ├── bash.go # Shell command execution\n│ ├── docker_bash.go # Docker-isolated shell execution (ch08+)\n│ ├── load_storage.go # Load offloaded content\n│ └── load_skill.go # Load skill content (ch09)\n├── mcp.go # MCP client integration (Model Context Protocol)\n├── skill/ # Skills system (ch09 only)\n│ ├── skill.go # Skill manager\n│ └── markdown.go # Skill file parser\n├── main/ # Main entry point\n│ └── main.go # TUI application entry\n├── tui/ # Bubble Tea terminal UI\n│ ├── tui.go # TUI model and update logic\n│ └── entry.go # Log entry types and rendering\n├── vo.go # View objects for streaming messages to TUI\n└── prompt.go # System prompt template with {runtime}, {workspace_path}, {memory}, {skills}\n```\n\n### Agent Loop Flow\n\n1. **User Input** → `Agent.RunStreaming(query, viewCh, confirmCh)`\n2. **Context Build** → ContextEngine builds messages with system prompt (includes memory + skills for ch09)\n3. **LLM Call** → Streaming response via openai-go SDK\n4. **Tool Calls** → Check if confirmation needed → Show confirm UI or execute directly\n5. **Confirmation** → User selects Allow/Reject/Always Allow (via `confirmCh`)\n6. **Execute Tools** → Run native tools (bash, read, write, load_skill) or MCP tools\n7. **ESC Handling** → User can cancel anytime; messages preserved, policies/memory skipped\n8. **Normal End** → Apply truncate/offload/summarize policies\n9. **Memory Update** → LLM extracts new facts from conversation\n10. **TUI Display** → Show reasoning, content, tool calls, confirm dialog via MessageVO channel\n\n### Skill Loading Flow (ch09)\n\n1. **Agent Startup** → Skill manager scans `.babyagent/skills/` directory\n2. **Metadata Extraction** → Parse YAML front matter (name, description) from each `SKILL.md`\n3. **System Prompt** → Inject skill list into `{skills}` placeholder\n4. **User Request** → LLM analyzes task and identifies relevant skill\n5. **load_skill Call** → LLM calls `load_skill(name=\"<skill-id>\")`\n6. **Skill Content** → Tool reads full Markdown content and returns to LLM\n7. **Task Execution** → LLM follows skill guidance to complete task\n\n### Key Architectural Patterns\n\n**Context Management (ch05)**:\n- Messages wrapped with token counts (`messageWrap`)\n- Policies applied when context usage exceeds thresholds\n- Draft/commit pattern: `StartTurn()` → modify → `CommitTurn()` or `AbortTurn()`\n- Policy event hooks notify TUI during execution\n\n**Memory System (ch06)**:\n- Two-level: Global (home dir) + Workspace (project dir)\n- LLM-driven extraction: runs a cheaper model to extract facts\n- Memory injected into system prompt via `{memory}` placeholder\n\n**Tool System**:\n- Native tools: `bash`, `read`, `write`, `edit`, `load_storage`, `load_skill`\n- `bash`: Shell command execution with optional Docker isolation (ch08+)\n- `docker_bash`: Docker-isolated shell execution (auto-detects Docker, falls back to bash)\n- `load_storage`: Load offloaded message content from storage\n- `load_skill`: Load full skill content for LLM guidance (ch09)\n- MCP tools: Namespaced as `babyagent_mcp__<server>__<tool>`\n- Tool results become `openai.ToolMessage` in conversation\n\n**MCP Integration (ch04)**:\n- Connects via stdio (subprocess) or HTTP (SSE)\n- Tool discovery via `ListTools()`, execution via `CallTool()`\n- Workspace variable `${workspaceFolder}` auto-replaced with current dir\n\n**Tool Confirmation (ch08)**:\n- `ToolConfirmConfig.RequireConfirmTools` maps tool names to confirmation requirement\n- Before execution, check if tool requires confirmation AND not in `alwaysAllowTools`\n- If needed, send `MessageTypeToolConfirm` to TUI and wait for `ConfirmationAction`\n- Three actions: `ConfirmAllow`, `ConfirmReject` (terminates loop), `ConfirmAlwaysAllow`\n- `alwaysAllowTools` tracks user's \"always allow\" choices for current session\n\n**ESC Cancellation (ch08)**:\n- TUI creates `context.WithCancel()` and passes to `Agent.RunStreaming()`\n- User presses ESC → TUI calls `cancel()` → Agent detects `ctx.Done()`\n- On cancel: `CommitTurn(..., skipPoliciesAndMemory=true)` preserves messages without running policies/memory\n- Draft messages are saved to context, allowing user to continue from that point\n\n**Skills System (ch09)**:\n- Skills are descriptive prompts, not code - they guide LLM on how to use tools\n- Progressive loading saves tokens: metadata (~50 tokens) at startup, full content (~500 tokens) on-demand\n- Skill metadata (name + description) injected into `{skills}` placeholder in system prompt\n- LLM calls `load_skill(name=\"<skill-id>\")` when it needs full guidance\n- Skill files in `.babyagent/skills/<skill-id>/SKILL.md` with YAML front matter\n- Skill manager (`skill.Manager`) auto-discovers and loads skills at startup\n- Skills can be shared across projects (workspace-level) or globally (home dir)\n\n## Testing Patterns\n\nTests use lightweight fakes to avoid LLM API calls:\n\n- **fakeSummarizer**: Returns pre-defined summaries for testing policy logic\n- **fakeStorage**: In-memory key-value store for testing offload policy\n- **buildEngine()**: Helper to create test engines with pre-populated messages\n\nExample from `ch08/context/policy_test.go`:\n```go\nfunc TestOffloadPolicyApply_OffloadsLongToolMessagesOnly(t *testing.T) {\n st := &fakeStorage{store: map[string]string{}}\n p := NewOffloadPolicy(st, 0.8, 1, 10)\n engine := buildEngine([]shared.OpenAIMessage{...})\n result, err := p.Apply(context.Background(), engine)\n // assertions...\n}\n```\n\n## Shared Utilities\n\nThe `shared/` package contains common code used across chapters:\n\n- `client.go`: `NewLLMClient()` creates openai-go client with custom headers\n- `config.go`: ModelConfig, AppConfig, environment variable loading\n- `env.go`: `GetHomeDir()`, `GetWorkspaceDir()`, `GetProjectName()`\n- `mcp.go`: MCP server configuration loading and placeholder replacement\n- `type.go`: Common type aliases (e.g., `OpenAIMessage`)\n\n## Chapter-Specific Notes\n\n**Chapter 7 (RAG)**:\n- Requires PostgreSQL with pgvector extension\n- Uses GORM for database operations\n- Implements semantic search via `SemanticSearchTool`\n- Supports line-based and paragraph-based chunking\n\n**Chapter 8 (Guardrails)**:\n- Tool confirmation UI: Allow/Reject/Always Allow options with ↑↓ navigation\n- ESC cancellation: Preserves conversation context, skips summary/memory\n- `CommitTurn(skipPoliciesAndMemory bool)`: Controls whether to run policies/memory on commit\n- `findTool(toolName)`: Unified tool lookup across native and MCP tools\n\n**Chapter 9 (Skills System)**:\n- Skills are descriptive prompts that guide models on how to use tools in specific scenarios\n- Progressive loading: Only skill metadata (name + description) injected into system prompt at startup\n- Full skill content loaded on-demand via `load_skill` tool\n- Skill files in `.babyagent/skills/<skill-id>/SKILL.md` with YAML front matter\n- Skill manager automatically discovers and loads skills from workspace\n\n**System Prompt Placeholders** (ch08/prompt.go, ch09/prompt.go):\n- `{runtime}`: OS (darwin/linux/windows)\n- `{workspace_path}`: Current working directory\n- `{memory}`: Injected global + workspace memory\n- `{skills}`: List of available skills (name + description) - ch09 only\n\n## Development Workflow\n\nWhen modifying agent behavior:\n1. Changes to `Agent.RunStreaming()` affect the core loop\n2. Changes to policies affect how context is managed after each turn\n3. Changes to system prompt affect how the agent behaves\n4. TUI changes go in `ch08/tui/` or `ch09/tui/`, MessageVO types in `vo.go`\n5. Skills are managed in `.babyagent/skills/` directory (ch09)\n\nWhen adding new tools:\n1. Implement `Tool` interface: `ToolName()`, `Info()`, `Execute()`\n2. Register in `ch08/main/main.go` or `ch09/main/main.go` tool list\n3. Tool will automatically be included in LLM requests\n\nWhen adding skills (ch09):\n1. Create skill directory: `.babyagent/skills/<skill-id>/`\n2. Create `SKILL.md` with YAML front matter (name, description)\n3. Skill will be auto-discovered and metadata injected into system prompt\n4. LLM can call `load_skill(name=\"<skill-id>\")` to load full content\n\nWhen configuring tool confirmation:\n1. Create `ToolConfirmConfig` with `RequireConfirmTools` map in `ch08/main/main.go` or `ch09/main/main.go`\n2. Map tool names (e.g., `tool.AgentToolBash`) to `true` for tools requiring confirmation\n3. For MCP tools, use full tool name (e.g., `babyagent_mcp__filesystem__write_file`)\n4. `alwaysAllowTools` is managed automatically by Agent during session\n\nWhen debugging issues:\n- Set `log.SetOutput(os.Stdout)` in main/main.go to see logs\n- Check policy execution via TUI events\n- Verify token counts with `CountTokens()` from context/share.go\n- For confirmation flow: check `MessageTypeToolConfirm` in TUI event handling\n- For skills (ch09): Check `.babyagent/skills/` directory and verify skill metadata is loaded"}, "964c333ff21664612011ec506c0e07462301bccc": {"t": 1785764695.2550287, "n": 11811, "h": "12be25c12e2e84f8", "c": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nBabyAgent is a Go-based AI Agent development tutorial that builds a Claude Code-like assistant from scratch. Each chapter (ch01-ch12) is a standalone module that progressively adds capabilities:\n\n- **ch01-03**: Basic LLM interaction, tool calling, TUI visualization\n- **ch04-06**: MCP protocol integration, context engineering, memory system\n- **ch07**: Agentic RAG with vector search (pgvector)\n- **ch08**: Sandbox/security with Docker isolation and tool confirmation\n- **ch09**: Skills system for task-specific guidance\n- **ch10+**: Web services, evaluation, observability (planned)\n\nChapters ch01-ch09 are complete. The current implementation combines all features into a full-featured agent.\n\n## Common Commands\n\n### Running Chapters\n```bash\n# Run individual chapters (each has a TUI interface)\ngo run ./ch03/main # Chapter 3: TUI visualization\ngo run ./ch04/main # Chapter 4: MCP integration\ngo run ./ch05/main # Chapter 5: Context management\ngo run ./ch06/main # Chapter 6: Memory system\ngo run ./ch08/main # Chapter 8: Full agent with guardrails\ngo run ./ch09/main # Chapter 9: Full agent with skills system (latest)\n```\n\n### Testing\n```bash\n# Run all tests\ngo test ./...\n\n# Run tests for specific chapter\ngo test ./ch08/context/...\ngo test ./ch08/... -v\ngo test ./ch09/skill/... -v\n\n# Run a single test\ngo test -v ./ch08/context/... -run TestTruncatePolicyApply\n```\n\n### Building\n```bash\n# Build a chapter's main executable\ngo build -o bin/ch09 ./ch09/main\n```\n\n## Configuration Requirements\n\nBefore running any chapter, set up the environment:\n\n1. **Copy example configs:**\n ```bash\n cp .env.example .env\n cp config.example.json config.json\n ```\n\n2. **Configure LLM providers** in `config.json`:\n - `front_model`: Main chat model (e.g., gpt-4o, deepseek-chat)\n - `back_model`: Cheaper model for summarization/memory updates\n - Both require: `base_url`, `api_key`, `model`, `context_window`\n\n3. **Optional: Configure MCP servers** in `mcp-server.json` for extending agent capabilities\n\n## Architecture Overview\n\n### Core Components (ch08)\n\n```\nch08/ or ch09/\n├── agent.go # Main Agent: orchestrates LLM calls, tool execution, streaming\n├── context/\n│ ├── engine.go # ContextEngine: manages conversation history, applies policies\n│ ├── policy.go # Policy interface: truncate, offload, summarize strategies\n│ ├── policy_*.go # Policy implementations\n│ └── share.go # Token counting with tiktoken-go\n├── memory/\n│ ├── memory.go # Memory interface: global + workspace memory\n│ └── update.go # LLM-driven memory extraction/update\n├── storage/\n│ ├── storage.go # Storage interface for persistence\n│ └── filesystem.go # File system storage implementation\n├── tool/\n│ ├── tool.go # Tool interface\n│ ├── bash.go # Shell command execution\n│ ├── docker_bash.go # Docker-isolated shell execution (ch08+)\n│ ├── load_storage.go # Load offloaded content\n│ └── load_skill.go # Load skill content (ch09)\n├── mcp.go # MCP client integration (Model Context Protocol)\n├── skill/ # Skills system (ch09 only)\n│ ├── skill.go # Skill manager\n│ └── markdown.go # Skill file parser\n├── main/ # Main entry point\n│ └── main.go # TUI application entry\n├── tui/ # Bubble Tea terminal UI\n│ ├── tui.go # TUI model and update logic\n│ └── entry.go # Log entry types and rendering\n├── vo.go # View objects for streaming messages to TUI\n└── prompt.go # System prompt template with {runtime}, {workspace_path}, {memory}, {skills}\n```\n\n### Agent Loop Flow\n\n1. **User Input** → `Agent.RunStreaming(query, viewCh, confirmCh)`\n2. **Context Build** → ContextEngine builds messages with system prompt (includes memory + skills for ch09)\n3. **LLM Call** → Streaming response via openai-go SDK\n4. **Tool Calls** → Check if confirmation needed → Show confirm UI or execute directly\n5. **Confirmation** → User selects Allow/Reject/Always Allow (via `confirmCh`)\n6. **Execute Tools** → Run native tools (bash, read, write, load_skill) or MCP tools\n7. **ESC Handling** → User can cancel anytime; messages preserved, policies/memory skipped\n8. **Normal End** → Apply truncate/offload/summarize policies\n9. **Memory Update** → LLM extracts new facts from conversation\n10. **TUI Display** → Show reasoning, content, tool calls, confirm dialog via MessageVO channel\n\n### Skill Loading Flow (ch09)\n\n1. **Agent Startup** → Skill manager scans `.babyagent/skills/` directory\n2. **Metadata Extraction** → Parse YAML front matter (name, description) from each `SKILL.md`\n3. **System Prompt** → Inject skill list into `{skills}` placeholder\n4. **User Request** → LLM analyzes task and identifies relevant skill\n5. **load_skill Call** → LLM calls `load_skill(name=\"<skill-id>\")`\n6. **Skill Content** → Tool reads full Markdown content and returns to LLM\n7. **Task Execution** → LLM follows skill guidance to complete task\n\n### Key Architectural Patterns\n\n**Context Management (ch05)**:\n- Messages wrapped with token counts (`messageWrap`)\n- Policies applied when context usage exceeds thresholds\n- Draft/commit pattern: `StartTurn()` → modify → `CommitTurn()` or `AbortTurn()`\n- Policy event hooks notify TUI during execution\n\n**Memory System (ch06)**:\n- Two-level: Global (home dir) + Workspace (project dir)\n- LLM-driven extraction: runs a cheaper model to extract facts\n- Memory injected into system prompt via `{memory}` placeholder\n\n**Tool System**:\n- Native tools: `bash`, `read`, `write`, `edit`, `load_storage`, `load_skill`\n- `bash`: Shell command execution with optional Docker isolation (ch08+)\n- `docker_bash`: Docker-isolated shell execution (auto-detects Docker, falls back to bash)\n- `load_storage`: Load offloaded message content from storage\n- `load_skill`: Load full skill content for LLM guidance (ch09)\n- MCP tools: Namespaced as `babyagent_mcp__<server>__<tool>`\n- Tool results become `openai.ToolMessage` in conversation\n\n**MCP Integration (ch04)**:\n- Connects via stdio (subprocess) or HTTP (SSE)\n- Tool discovery via `ListTools()`, execution via `CallTool()`\n- Workspace variable `${workspaceFolder}` auto-replaced with current dir\n\n**Tool Confirmation (ch08)**:\n- `ToolConfirmConfig.RequireConfirmTools` maps tool names to confirmation requirement\n- Before execution, check if tool requires confirmation AND not in `alwaysAllowTools`\n- If needed, send `MessageTypeToolConfirm` to TUI and wait for `ConfirmationAction`\n- Three actions: `ConfirmAllow`, `ConfirmReject` (terminates loop), `ConfirmAlwaysAllow`\n- `alwaysAllowTools` tracks user's \"always allow\" choices for current session\n\n**ESC Cancellation (ch08)**:\n- TUI creates `context.WithCancel()` and passes to `Agent.RunStreaming()`\n- User presses ESC → TUI calls `cancel()` → Agent detects `ctx.Done()`\n- On cancel: `CommitTurn(..., skipPoliciesAndMemory=true)` preserves messages without running policies/memory\n- Draft messages are saved to context, allowing user to continue from that point\n\n**Skills System (ch09)**:\n- Skills are descriptive prompts, not code - they guide LLM on how to use tools\n- Progressive loading saves tokens: metadata (~50 tokens) at startup, full content (~500 tokens) on-demand\n- Skill metadata (name + description) injected into `{skills}` placeholder in system prompt\n- LLM calls `load_skill(name=\"<skill-id>\")` when it needs full guidance\n- Skill files in `.babyagent/skills/<skill-id>/SKILL.md` with YAML front matter\n- Skill manager (`skill.Manager`) auto-discovers and loads skills at startup\n- Skills can be shared across projects (workspace-level) or globally (home dir)\n\n## Testing Patterns\n\nTests use lightweight fakes to avoid LLM API calls:\n\n- **fakeSummarizer**: Returns pre-defined summaries for testing policy logic\n- **fakeStorage**: In-memory key-value store for testing offload policy\n- **buildEngine()**: Helper to create test engines with pre-populated messages\n\nExample from `ch08/context/policy_test.go`:\n```go\nfunc TestOffloadPolicyApply_OffloadsLongToolMessagesOnly(t *testing.T) {\n st := &fakeStorage{store: map[string]string{}}\n p := NewOffloadPolicy(st, 0.8, 1, 10)\n engine := buildEngine([]shared.OpenAIMessage{...})\n result, err := p.Apply(context.Background(), engine)\n // assertions...\n}\n```\n\n## Shared Utilities\n\nThe `shared/` package contains common code used across chapters:\n\n- `client.go`: `NewLLMClient()` creates openai-go client with custom headers\n- `config.go`: ModelConfig, AppConfig, environment variable loading\n- `env.go`: `GetHomeDir()`, `GetWorkspaceDir()`, `GetProjectName()`\n- `mcp.go`: MCP server configuration loading and placeholder replacement\n- `type.go`: Common type aliases (e.g., `OpenAIMessage`)\n\n## Chapter-Specific Notes\n\n**Chapter 7 (RAG)**:\n- Requires PostgreSQL with pgvector extension\n- Uses GORM for database operations\n- Implements semantic search via `SemanticSearchTool`\n- Supports line-based and paragraph-based chunking\n\n**Chapter 8 (Guardrails)**:\n- Tool confirmation UI: Allow/Reject/Always Allow options with ↑↓ navigation\n- ESC cancellation: Preserves conversation context, skips summary/memory\n- `CommitTurn(skipPoliciesAndMemory bool)`: Controls whether to run policies/memory on commit\n- `findTool(toolName)`: Unified tool lookup across native and MCP tools\n\n**Chapter 9 (Skills System)**:\n- Skills are descriptive prompts that guide models on how to use tools in specific scenarios\n- Progressive loading: Only skill metadata (name + description) injected into system prompt at startup\n- Full skill content loaded on-demand via `load_skill` tool\n- Skill files in `.babyagent/skills/<skill-id>/SKILL.md` with YAML front matter\n- Skill manager automatically discovers and loads skills from workspace\n\n**System Prompt Placeholders** (ch08/prompt.go, ch09/prompt.go):\n- `{runtime}`: OS (darwin/linux/windows)\n- `{workspace_path}`: Current working directory\n- `{memory}`: Injected global + workspace memory\n- `{skills}`: List of available skills (name + description) - ch09 only\n\n## Development Workflow\n\nWhen modifying agent behavior:\n1. Changes to `Agent.RunStreaming()` affect the core loop\n2. Changes to policies affect how context is managed after each turn\n3. Changes to system prompt affect how the agent behaves\n4. TUI changes go in `ch08/tui/` or `ch09/tui/`, MessageVO types in `vo.go`\n5. Skills are managed in `.babyagent/skills/` directory (ch09)\n\nWhen adding new tools:\n1. Implement `Tool` interface: `ToolName()`, `Info()`, `Execute()`\n2. Register in `ch08/main/main.go` or `ch09/main/main.go` tool list\n3. Tool will automatically be included in LLM requests\n\nWhen adding skills (ch09):\n1. Create skill directory: `.babyagent/skills/<skill-id>/`\n2. Create `SKILL.md` with YAML front matter (name, description)\n3. Skill will be auto-discovered and metadata injected into system prompt\n4. LLM can call `load_skill(name=\"<skill-id>\")` to load full content\n\nWhen configuring tool confirmation:\n1. Create `ToolConfirmConfig` with `RequireConfirmTools` map in `ch08/main/main.go` or `ch09/main/main.go`\n2. Map tool names (e.g., `tool.AgentToolBash`) to `true` for tools requiring confirmation\n3. For MCP tools, use full tool name (e.g., `babyagent_mcp__filesystem__write_file`)\n4. `alwaysAllowTools` is managed automatically by Agent during session\n\nWhen debugging issues:\n- Set `log.SetOutput(os.Stdout)` in main/main.go to see logs\n- Check policy execution via TUI events\n- Verify token counts with `CountTokens()` from context/share.go\n- For confirmation flow: check `MessageTypeToolConfirm` in TUI event handling\n- For skills (ch09): Check `.babyagent/skills/` directory and verify skill metadata is loaded"}, "3dfe3563b48d21e19fb5d7fc67f81686250a410d": {"t": 1785764696.6660404, "n": 8581, "h": "5ff5543f20fa3d37", "c": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nBabyAgent is a Go-based AI Agent development tutorial that builds a Claude Code-like assistant from scratch. Each chapter (ch01-ch12) is a standalone module that progressively adds capabilities:\n\n- **ch01-03**: Basic LLM interaction, tool calling, TUI visualization\n- **ch04-06**: MCP protocol integration, context engineering, memory system\n- **ch07**: Agentic RAG with vector search (pgvector)\n- **ch08+**: Sandbox/security, web services, evaluation, observability\n\nThe current active development chapter is ch08, which combines all previous features into a complete agent.\n\n## Common Commands\n\n### Running Chapters\n```bash\n# Run individual chapters (each has a TUI interface)\ngo run ./ch03/tui # Chapter 3: TUI visualization\ngo run ./ch04/tui # Chapter 4: MCP integration\ngo run ./ch05/tui # Chapter 5: Context management\ngo run ./ch06/tui # Chapter 6: Memory system\ngo run ./ch08/tui # Chapter 8: Full agent (latest)\n```\n\n### Testing\n```bash\n# Run all tests\ngo test ./...\n\n# Run tests for specific chapter\ngo test ./ch08/context/...\ngo test ./ch08/... -v\n\n# Run a single test\ngo test -v ./ch08/context/... -run TestTruncatePolicyApply\n```\n\n### Building\n```bash\n# Build a chapter's main executable\ngo build -o bin/ch08-tui ./ch08/tui\n```\n\n## Configuration Requirements\n\nBefore running any chapter, set up the environment:\n\n1. **Copy example configs:**\n ```bash\n cp .env.example .env\n cp config.example.json config.json\n ```\n\n2. **Configure LLM providers** in `config.json`:\n - `front_model`: Main chat model (e.g., gpt-4o, deepseek-chat)\n - `back_model`: Cheaper model for summarization/memory updates\n - Both require: `base_url`, `api_key`, `model`, `context_window`\n\n3. **Optional: Configure MCP servers** in `mcp-server.json` for extending agent capabilities\n\n## Architecture Overview\n\n### Core Components (ch08)\n\n```\nch08/\n├── agent.go # Main Agent: orchestrates LLM calls, tool execution, streaming\n├── context/\n│ ├── engine.go # ContextEngine: manages conversation history, applies policies\n│ ├── policy.go # Policy interface: truncate, offload, summarize strategies\n│ ├── policy_*.go # Policy implementations\n│ └── share.go # Token counting with tiktoken-go\n├── memory/\n│ ├── memory.go # Memory interface: global + workspace memory\n│ └── update.go # LLM-driven memory extraction/update\n├── storage/\n│ ├── storage.go # Storage interface for persistence\n│ └── filesystem.go # File system storage implementation\n├── tool/\n│ ├── tool.go # Tool interface\n│ ├── bash.go # Shell command execution\n│ └── load_storage.go# Load offloaded content\n├── mcp.go # MCP client integration (Model Context Protocol)\n├── tui/ # Bubble Tea terminal UI\n├── vo.go # View objects for streaming messages to TUI\n└── prompt.go # System prompt template with {runtime}, {workspace_path}, {memory}\n```\n\n### Agent Loop Flow\n\n1. **User Input** → `Agent.RunStreaming(query, viewCh, confirmCh)`\n2. **Context Build** → ContextEngine builds messages with system prompt (includes memory)\n3. **LLM Call** → Streaming response via openai-go SDK\n4. **Tool Calls** → Check if confirmation needed → Show confirm UI or execute directly\n5. **Confirmation** → User selects Allow/Reject/Always Allow (via `confirmCh`)\n6. **Execute Tools** → Run native tools (bash, read, write) or MCP tools\n7. **ESC Handling** → User can cancel anytime; messages preserved, policies/memory skipped\n8. **Normal End** → Apply truncate/offload/summarize policies\n9. **Memory Update** → LLM extracts new facts from conversation\n10. **TUI Display** → Show reasoning, content, tool calls, confirm dialog via MessageVO channel\n\n### Key Architectural Patterns\n\n**Context Management (ch05)**:\n- Messages wrapped with token counts (`messageWrap`)\n- Policies applied when context usage exceeds thresholds\n- Draft/commit pattern: `StartTurn()` → modify → `CommitTurn()` or `AbortTurn()`\n- Policy event hooks notify TUI during execution\n\n**Memory System (ch06)**:\n- Two-level: Global (home dir) + Workspace (project dir)\n- LLM-driven extraction: runs a cheaper model to extract facts\n- Memory injected into system prompt via `{memory}` placeholder\n\n**Tool System**:\n- Native tools: `bash`, `read`, `write`, `edit`, `load_storage`\n- MCP tools: Namespaced as `babyagent_mcp__<server>__<tool>`\n- Tool results become `openai.ToolMessage` in conversation\n\n**MCP Integration (ch04)**:\n- Connects via stdio (subprocess) or HTTP (SSE)\n- Tool discovery via `ListTools()`, execution via `CallTool()`\n- Workspace variable `${workspaceFolder}` auto-replaced with current dir\n\n**Tool Confirmation (ch08)**:\n- `ToolConfirmConfig.RequireConfirmTools` maps tool names to confirmation requirement\n- Before execution, check if tool requires confirmation AND not in `alwaysAllowTools`\n- If needed, send `MessageTypeToolConfirm` to TUI and wait for `ConfirmationAction`\n- Three actions: `ConfirmAllow`, `ConfirmReject` (terminates loop), `ConfirmAlwaysAllow`\n- `alwaysAllowTools` tracks user's \"always allow\" choices for current session\n\n**ESC Cancellation (ch08)**:\n- TUI creates `context.WithCancel()` and passes to `Agent.RunStreaming()`\n- User presses ESC → TUI calls `cancel()` → Agent detects `ctx.Done()`\n- On cancel: `CommitTurn(..., skipPoliciesAndMemory=true)` preserves messages without running policies/memory\n- Draft messages are saved to context, allowing user to continue from that point\n\n## Testing Patterns\n\nTests use lightweight fakes to avoid LLM API calls:\n\n- **fakeSummarizer**: Returns pre-defined summaries for testing policy logic\n- **fakeStorage**: In-memory key-value store for testing offload policy\n- **buildEngine()**: Helper to create test engines with pre-populated messages\n\nExample from `ch08/context/policy_test.go`:\n```go\nfunc TestOffloadPolicyApply_OffloadsLongToolMessagesOnly(t *testing.T) {\n st := &fakeStorage{store: map[string]string{}}\n p := NewOffloadPolicy(st, 0.8, 1, 10)\n engine := buildEngine([]shared.OpenAIMessage{...})\n result, err := p.Apply(context.Background(), engine)\n // assertions...\n}\n```\n\n## Shared Utilities\n\nThe `shared/` package contains common code used across chapters:\n\n- `client.go`: `NewLLMClient()` creates openai-go client with custom headers\n- `config.go`: ModelConfig, AppConfig, environment variable loading\n- `env.go`: `GetHomeDir()`, `GetWorkspaceDir()`, `GetProjectName()`\n- `mcp.go`: MCP server configuration loading and placeholder replacement\n- `type.go`: Common type aliases (e.g., `OpenAIMessage`)\n\n## Chapter-Specific Notes\n\n**Chapter 7 (RAG)**:\n- Requires PostgreSQL with pgvector extension\n- Uses GORM for database operations\n- Implements semantic search via `SemanticSearchTool`\n- Supports line-based and paragraph-based chunking\n\n**Chapter 8 (Guardrails)**:\n- Tool confirmation UI: Allow/Reject/Always Allow options with ↑↓ navigation\n- ESC cancellation: Preserves conversation context, skips summary/memory\n- `CommitTurn(skipPoliciesAndMemory bool)`: Controls whether to run policies/memory on commit\n- `findTool(toolName)`: Unified tool lookup across native and MCP tools\n\n**System Prompt Placeholders** (ch08/prompt.go):\n- `{runtime}`: OS (darwin/linux/windows)\n- `{workspace_path}`: Current working directory\n- `{memory}`: Injected global + workspace memory\n\n## Development Workflow\n\nWhen modifying agent behavior:\n1. Changes to `Agent.RunStreaming()` affect the core loop\n2. Changes to policies affect how context is managed after each turn\n3. Changes to system prompt affect how the agent behaves\n4. TUI changes go in `ch08/tui/`, MessageVO types in `vo.go`\n\nWhen adding new tools:\n1. Implement `Tool` interface: `ToolName()`, `Info()`, `Execute()`\n2. Register in `ch08/tui/main.go` tool list\n3. Tool will automatically be included in LLM requests\n\nWhen configuring tool confirmation:\n1. Create `ToolConfirmConfig` with `RequireConfirmTools` map in `ch08/tui/main.go`\n2. Map tool names (e.g., `tool.AgentToolBash`) to `true` for tools requiring confirmation\n3. For MCP tools, use full tool name (e.g., `babyagent_mcp__filesystem__write_file`)\n4. `alwaysAllowTools` is managed automatically by Agent during session\n\nWhen debugging issues:\n- Set `log.SetOutput(os.Stdout)` in tui/main.go to see logs\n- Check policy execution via TUI events\n- Verify token counts with `CountTokens()` from context/share.go\n- For confirmation flow: check `MessageTypeToolConfirm` in TUI event handling"}}}}