diff --git a/samples/dartantic_cli/lib/src/runner.dart b/samples/dartantic_cli/lib/src/runner.dart index ac409756..1ec35477 100644 --- a/samples/dartantic_cli/lib/src/runner.dart +++ b/samples/dartantic_cli/lib/src/runner.dart @@ -8,6 +8,7 @@ import 'commands/chat_command.dart'; import 'commands/embed_command.dart'; import 'commands/generate_command.dart'; import 'commands/models_command.dart'; +import 'commands/repl_command.dart'; import 'exit_codes.dart'; import 'settings/settings.dart'; import 'settings/settings_loader.dart'; @@ -72,6 +73,7 @@ class DartanticCommandRunner extends CommandRunner { addCommand(GenerateCommand(_settingsLoader)); addCommand(EmbedCommand(_settingsLoader)); addCommand(ModelsCommand(_settingsLoader)); + addCommand(ReplCommand(_settingsLoader)); } final SettingsLoader _settingsLoader; @@ -286,6 +288,7 @@ class DartanticCommandRunner extends CommandRunner { ..writeln('Examples:') ..writeln(' dartantic -p "What is 2+2?"') ..writeln(' dartantic chat -a anthropic -p "Hello"') + ..writeln(' dartantic repl -a coder') ..writeln(' dartantic -a openai models') ..writeln(' dartantic embed create doc.txt > embeddings.json'); diff --git a/samples/dartantic_cli/pubspec.yaml b/samples/dartantic_cli/pubspec.yaml index f0b5a365..d6a1ace2 100644 --- a/samples/dartantic_cli/pubspec.yaml +++ b/samples/dartantic_cli/pubspec.yaml @@ -8,6 +8,7 @@ environment: dependencies: args: ^2.4.0 + cli_repl: ^0.2.3 cross_file: ^0.3.4+2 dartantic_ai: ^2.0.0 dotprompt_dart: ^0.5.0 diff --git a/wiki/CLI-Spec.md b/wiki/CLI-Spec.md index 06d3528f..65bf66fb 100644 --- a/wiki/CLI-Spec.md +++ b/wiki/CLI-Spec.md @@ -33,13 +33,9 @@ This document specifies the design for the `dartantic` command-line interface ### Non-Goals (v1) -1. **Interactive REPL mode** - Multi-turn conversations deferred to future - version -2. **Custom Dart tools** - CLI cannot execute arbitrary Dart code; MCP servers +1. **Custom Dart tools** - CLI cannot execute arbitrary Dart code; MCP servers provide extensibility -3. **Container/session persistence** - Code interpreter container reuse requires - REPL -4. **GUI or TUI** - This is a command-line tool only +2. **GUI or TUI** - This is a command-line tool only --- @@ -77,6 +73,7 @@ COMMANDS: generate Generate media content embed Embedding operations (create, search) models List available models for a provider + repl Start an interactive chat session GLOBAL OPTIONS: -a, --agent Agent name or model string (default: google) @@ -123,6 +120,28 @@ MODELS COMMAND: Lists available models for a provider. +REPL COMMAND: + dartantic repl [options] + + Start an interactive chat session with multi-turn conversation support. + + Slash commands available in REPL: + /exit, /quit Exit the REPL + /help Show available commands + /model [name] View or switch the current agent + /models [filter] List available models + /tools Show available MCP tools + /messages Display conversation history + /clear Clear conversation history + /system [text] View or set system prompt + /verbose Toggle verbose output (token usage) + /thinking Toggle thinking output display + + File attachments: Use @filename in your message to attach files. + + MCP Tools: Only tools from MCP servers configured for the selected agent + are available. No built-in tools are provided. + ENVIRONMENT VARIABLES: DARTANTIC_AGENT Default agent (overrides built-in default) DARTANTIC_LOG_LEVEL Logging level (FINE, INFO, WARNING, SEVERE, OFF) @@ -828,6 +847,48 @@ agents: EOF dartantic -s /tmp/env-settings.yaml -a test -p "Hello" +echo "=== REPL COMMAND SCENARIOS ===" + +# SR-001: Start REPL with default agent +echo "SR-001: Start REPL with default agent" +# Interactive - requires manual testing +# dartantic repl + +# SR-002: Start REPL with specific agent +echo "SR-002: Start REPL with specific agent" +# Interactive - requires manual testing +# dartantic repl -a coder + +# SR-003: REPL with MCP tools agent +echo "SR-003: REPL with MCP tools" +# Interactive - requires manual testing +# dartantic repl -a research + +# SR-004: REPL with verbose mode +echo "SR-004: REPL with verbose" +# Interactive - requires manual testing +# dartantic repl -v + +# SR-005: REPL with thinking disabled +echo "SR-005: REPL with no thinking" +# Interactive - requires manual testing +# dartantic repl --no-thinking + +# SR-006: REPL with working directory +echo "SR-006: REPL with working directory" +# Interactive - requires manual testing +# dartantic repl -d /tmp/dartantic-test + +# SR-007: REPL with custom settings +echo "SR-007: REPL with custom settings" +# Interactive - requires manual testing +# dartantic repl -s /tmp/custom-settings.yaml + +# SR-008: REPL with no-color +echo "SR-008: REPL with no color" +# Interactive - requires manual testing +# dartantic repl --no-color + echo "=== ALL SCENARIOS COMPLETE ===" ``` @@ -838,9 +899,9 @@ The following table maps Dartantic examples to CLI commands: | Example | CLI Command | Status | |---------|-------------|--------| | single_turn_chat.dart | `dartantic -p "What is the capital of England?"` | ✅ Covered | -| multi_turn_chat.dart | N/A | ⏳ Deferred (REPL) | +| multi_turn_chat.dart | `dartantic repl -a google` | ✅ Covered | | system_message.dart | `dartantic -a pirate -p "What is 7 * 8?"` | ✅ Covered | -| chat.dart | N/A | ⏳ Deferred (REPL) | +| chat.dart | `dartantic repl` | ✅ Covered | | typed_output.dart | `dartantic -p "..." --output-schema '{...}'` | ✅ Covered | | single_tool_call.dart | Via MCP servers in settings | ✅ Covered | | multi_tool_call.dart | Via MCP servers in settings | ✅ Covered | @@ -853,7 +914,7 @@ The following table maps Dartantic examples to CLI commands: | media_gen_openai.dart | `dartantic generate -a openai-responses --mime image/png -p "..."` | ✅ Covered | | media_gen_google.dart | `dartantic generate -a google --mime image/png -p "..."` | ✅ Covered | | server_side_web_search.dart | Server tools enabled by default | ✅ Covered | -| server_side_code_execution.dart | Single turn works; container reuse needs REPL | ⚠️ Partial | +| server_side_code_execution.dart | `dartantic repl` with container reuse | ✅ Covered | | logging.dart | `DARTANTIC_LOG_LEVEL=FINE dartantic -p "..."` | ✅ Covered | | usage_tracking.dart | `dartantic -v -p "..."` | ✅ Covered | | custom_provider.dart | Via settings: `base_url`, `api_key_name`, `headers` | ✅ Covered | diff --git a/wiki/Tic-CLI-Design.md b/wiki/Tic-CLI-Design.md new file mode 100644 index 00000000..2e580492 --- /dev/null +++ b/wiki/Tic-CLI-Design.md @@ -0,0 +1,619 @@ +# Tic CLI Design + +Interactive CLI for the Dartantic AI framework with multi-mode REPL, vector database management, and code generation. + +**Name**: `tic` (Dartantic → Agentic → nervous tic) + +## Overview + +Tic unifies batch and interactive workflows across three modes: +- **Chat**: LLM conversation with optional vector DB context +- **Generate**: LLM media generation (images, PDFs, etc.) +- **Embed**: Vector database (vault) management and raw search + +## CLI Entry Points + +Commands without required args enter REPL mode; with args they execute batch operations. + +``` +tic # REPL in chat mode (default) +tic chat # REPL in chat mode +tic chat -p "hello" # batch: single chat + +tic embed # REPL in embed mode +tic embed -db codebase # REPL in embed mode with vault +tic embed sync -db codebase # batch: sync vault + +tic generate # REPL in generate mode +tic generate -p "..." --mime image/png # batch: generate media +``` + +## Modes + +### Chat Mode (default) +- Prompts sent to LLM for conversation +- Conversation history maintained +- Vector DB available as local tool (if configured) +- MCP tools available (from agent settings) + +``` +[chat] You: Hello, how are you? +[chat] You: What files mention authentication? # LLM uses search tool +``` + +### Generate Mode +- Prompts sent to LLM for media generation +- Output saved to files in output directory +- Vector DB available as context tool +- Need to specify/set MIME type + +``` +[generate] You: A sunset over mountains +[generate] You: /mime application/pdf +[generate] You: Create a report about our codebase +``` + +### Embed Mode +- Vault management (no LLM interaction) +- Prompts are raw vector similarity searches +- Manage, sync, and explore indexed content + +``` +[embed] You: authentication # raw vector search +[embed] You: /status # vault info +[embed] You: /sync # refresh embeddings +[embed] You: /files # list indexed files +``` + +## Mode Switching + +**Mode switch** (no args): Changes current mode +``` +[chat] You: /embed # switch to embed mode +[embed] You: /generate # switch to generate mode +[generate] You: /chat # switch to chat mode +``` + +**One-shot** (with args): Execute in that mode, stay in current mode +``` +[chat] You: /embed @doc.txt # one-shot: embed file, stay in chat +[chat] You: /embed machine learning # one-shot: raw search, stay in chat +[chat] You: /generate A sunset # one-shot: generate, stay in chat +``` + +## Slash Commands + +### Universal Commands +| Command | Description | +|---------|-------------| +| `/help` | Show available commands | +| `/exit`, `/quit` | Exit REPL | +| `/chat [prompt]` | Switch to chat mode, or one-shot chat | +| `/embed [query]` | Switch to embed mode, or one-shot search | +| `/generate [prompt]` | Switch to generate mode, or one-shot generate | + +### Agent & Model Commands +| Command | Description | +|---------|-------------| +| `/agent` | Show current agent | +| `/agent ` | Switch agent | +| `/model` | Show current model (for current mode) | +| `/model ` | Switch model (for current mode) | +| `/models [filter]` | List models (for current mode) | + +### Vault Commands (embed mode or universal) +| Command | Description | +|---------|-------------| +| `/vault` | Show current vault | +| `/vault ` | Switch vault | +| `/vaults` | List available vaults | +| `/sync` | Sync vault with filesystem | +| `/status` | Show vault status (files, stale, etc.) | +| `/files` | List indexed files/chunks | + +### Generate Mode Commands +| Command | Description | +|---------|-------------| +| `/mime` | Show current MIME type | +| `/mime ` | Set MIME type for generation | + +### History Commands +| Command | Description | +|---------|-------------| +| `/history` | Show session summary | +| `/history save ` | Save session | +| `/history load ` | Load session | +| `/history list` | List saved sessions | +| `/history clear` | Clear current session | +| `/history delete ` | Delete saved session | + +### Code Export +| Command | Description | +|---------|-------------| +| `/code` | Print Dart code for session to stdout | +| `/code ` | Save Dart code to file | + +### Other +| Command | Description | +|---------|-------------| +| `/system` | Show system prompt | +| `/system ` | Set system prompt | +| `/verbose` | Toggle verbose output | +| `/thinking` | Toggle thinking display | +| `/tools` | Show available tools (MCP + search) | +| `/messages` | Show conversation history | +| `/clear` | Clear conversation (alias for `/history clear`) | + +## Vector Database (Vault) System + +### Concept +A **vault** is a named collection of: +- Source files/folders to index +- Output location for cached embeddings +- Embedding model configuration + +Vaults sync automatically on file changes, minimizing re-embedding costs. + +### Settings Configuration +```yaml +# ~/.tic/settings.yaml + +vaults: + codebase: + sources: + - ./src + - ./lib + output: ./.tic/vaults/codebase + model: openai:text-embedding-3-small + chunk_size: 512 + chunk_overlap: 100 + + docs: + sources: + - ./wiki + - ./README.md + output: ./.tic/vaults/docs + +agents: + coder: + model: anthropic:claude-sonnet-4-20250514 + vaults: [codebase, docs] # vaults available to this agent + mcp_servers: + - name: filesystem + command: npx + args: ["-y", "@anthropic/mcp-server-filesystem", "."] +``` + +### LLM Integration +When a vault is active in chat/generate mode: +- A local `search_vault` tool is automatically available +- LLM can search the vault for relevant context +- Works alongside MCP tools + +``` +[chat] You: What authentication methods does this codebase support? +# LLM calls search_vault("authentication") internally +# Gets relevant chunks as context +# Responds with grounded answer +``` + +## History & Sessions + +Sessions are transient by default. Use `/history save` to persist. + +**Storage**: `~/.tic/sessions/.json` + +**Session contains**: +- Mode transitions +- Conversation history (all modes) +- Active vault/agent at each point +- Model switches + +## Code Export + +The `/code` command generates Dart code that recreates the session: + +```dart +import 'package:dartantic_ai/dartantic_ai.dart'; + +void main() async { + // Agent setup + final agent = Agent('anthropic:claude-sonnet-4-20250514'); + + // Conversation + var response = await agent.send('Hello, how are you?'); + print(response.text); + + response = await agent.send( + 'Tell me about Dart', + history: response.messages, + ); + print(response.text); + + // Model switch + final agent2 = Agent('openai:gpt-4o'); + response = await agent2.send( + 'Summarize our conversation', + history: response.messages, + ); + + // Embeddings + final embeddings = await agent.embedDocuments(['text to embed']); + + // Media generation + final media = await agent.generate( + 'A sunset over mountains', + mimeTypes: ['image/png'], + ); + // ... save media to file +} +``` + +## File Attachments + +Use `@filename` syntax in prompts to attach files: + +``` +[chat] You: Summarize this: @document.pdf +[chat] You: Compare @file1.txt and @file2.txt +[embed] You: @newdoc.txt # would add to vault? or just embed? +``` + +## Configuration + +### Settings File Location +`~/.tic/settings.yaml` + +### Full Settings Schema +```yaml +# Default agent when not specified +default_agent: coder + +# Default vault when not specified +default_vault: codebase + +# Global defaults +thinking: true +verbose: false + +# Vault definitions +vaults: + : + sources: [] + output: + model: + chunk_size: 512 + chunk_overlap: 100 + +# Agent definitions +agents: + : + model: + system: + thinking: true|false + vaults: [] + mcp_servers: + - name: + url: + headers: {...} + - name: + command: + args: [...] + environment: {...} +``` + +### Sessions Location +`~/.tic/sessions/` + +### Vault Cache Location +Configurable per-vault via `output` field, or defaults to `~/.tic/vaults//` + +## CLI Arguments + +### Global Options +``` +-a, --agent Agent name or model string +-s, --settings Settings file path +-d, --cwd Working directory +-o, --output-dir Output directory for generated files +-v, --verbose Show token usage +--no-thinking Disable thinking display +--no-color Disable colored output +--db, --vault Active vault +--version Show version +-h, --help Show help +``` + +### Chat Options +``` +-p, --prompt Prompt (batch mode) +--output-schema Structured output schema +-t, --temperature Model temperature +``` + +### Generate Options +``` +-p, --prompt Prompt (batch mode) +--mime MIME type(s) to generate +``` + +### Embed Options +``` +--db, --vault Vault to operate on +``` + +## Example Workflows + +### Interactive Code Exploration +``` +$ tic -a coder --db codebase +[chat] You: How does authentication work in this codebase? +[chat] You: Show me the login flow +[chat] You: /embed # switch to embed mode +[embed] You: authentication handler # raw search +[embed] You: /chat # back to chat +[chat] You: Refactor the auth to use JWT +[chat] You: /code auth_refactor.dart # export session as code +``` + +### Batch Embedding Pipeline +``` +$ tic embed sync --db codebase # sync vault +$ tic embed sync --db docs # sync another vault +$ tic -a coder --db codebase -p "Summarize the architecture" +``` + +### Media Generation Session +``` +$ tic generate +[generate] You: /mime image/png +[generate] You: A logo for an AI company +[generate] You: Make it more minimalist +[generate] You: /mime application/pdf +[generate] You: Create a brand guidelines document +``` + +## Open Questions + +### 1. `/embed` One-Shot Ambiguity + +`/embed @doc.txt` (add to vault) vs `/embed query` (search) are different operations with same syntax. + +**Options**: +- **A**: Separate commands: `/search ` for search, `/index @file` for adding to vault. Keep `/embed` for mode switching only. +- **B**: Detect `@` prefix to distinguish operations. +- **C**: `/embed` always searches; use `/vault add @file` to index. + +--- + +### 2. Generate Mode Feature Parity + +Generate mode lacks features that chat has: +- Temperature +- System prompt (for style guidance) +- File attachments (reference images) +- Thinking display +- Multi-turn iteration + +**Questions**: +- Should generate support temperature? (`-t` batch, `/temperature` REPL) +- Should generate have system prompts? (e.g., "Always use minimalist style") +- Should generate support `@file` attachments? (e.g., `@sketch.png` as reference) +- Does multi-turn generation make sense? ("Make it more blue") + +--- + +### 3. Missing REPL Commands for Batch Options + +Batch has options that can't be changed in REPL: +- Temperature (`-t`) +- Output schema (`--output-schema`) +- Output directory (`-o`) + +**Proposed commands**: +``` +/temperature [n] # show or set (chat/generate) +/schema [json|@file] # show or set output schema (chat) +/output [dir] # show or set output directory (generate) +``` + +--- + +### 4. `/model` vs `/agent` Relationship + +Agents have models, but `/model` exists separately. Confusion about what `/model` overrides. + +**Options**: +- **A**: Remove `/model`. Only `/agent` exists. To use a raw model, use `-a model:string` syntax which creates an anonymous agent. +- **B**: `/model` temporarily overrides the current agent's model for the current mode. +- **C**: Keep both but clarify: `/agent` switches config bundle, `/model` switches just the LLM. + +--- + +### 5. Batch Embed Operations + +Only `sync` shown for batch embed. Missing operations: + +**Proposed batch commands**: +``` +tic embed sync --db # sync vault +tic embed search --db # search vault +tic embed status --db # show vault status +tic embed create --db --sources [--output ] +tic embed delete --db # delete vault +tic embed files --db # list indexed files +``` + +--- + +### 6. Vault Search in Generate Mode + +Doc claims vault available as tool in generate, but generation typically doesn't do tool calls. + +**Options**: +- **A**: Pre-flight injection via `/context ` command that searches vault and injects into next prompt. +- **B**: Remove the claim if model doesn't support tools during generation. +- **C**: For models that support it, allow tool use during generation. + +--- + +### 7. `/clear` Meaning Per Mode + +`/clear` in embed mode is meaningless (no conversation) or dangerous (clear vault?). + +**Options**: +- **A**: Mode-specific behavior: chat=conversation, generate=generation history, embed=search history +- **B**: Disable `/clear` in embed mode +- **C**: `/clear` always means conversation/prompt history, never vault data + +--- + +### 8. File Attachment in Embed Mode + +What does `@file` mean in embed mode? + +**Options**: +- **A**: `@file` in embed mode = add file to vault and index it +- **B**: `@file` in embed mode = error ("use /index @file instead") +- **C**: `@file` in embed mode = search contents of file (not index it) + +--- + +### 9. Multi-Vault Handling + +Agents can have multiple vaults but interaction unclear. + +**Questions**: +- Does `search_vault` tool search all agent vaults or just active one? +- Should tool accept vault name parameter? +- What does `/vault` show/switch when agent has multiple? + +**Proposed settings**: +```yaml +agents: + coder: + vaults: [codebase, docs] # all available + default_vault: codebase # active by default +``` + +--- + +### 10. Missing `/config` Command + +No unified view of current state. + +**Proposed output**: +``` +[chat] You: /config +Agent: coder (anthropic:claude-sonnet-4-20250514) +Mode: chat +Vault: codebase (3,247 chunks, synced 2 min ago) +MCP: filesystem (3 tools) +Verbose: off +Thinking: on +Temperature: 0.7 +``` + +--- + +### 11. Embed Search Output Format + +What format for raw search results? + +**Options**: +- **A**: Human-readable table by default, `/format json` to switch +- **B**: JSON by default (machine-friendly) +- **C**: Human-readable always in REPL, JSON in batch + +**Proposed REPL output**: +``` +[embed] You: authentication +Score File Preview +0.89 src/auth/handler.dart "The authentication handler validates..." +0.84 src/auth/middleware.dart "JWT tokens are verified in..." +``` + +--- + +### 12. Batch Mode Default Vault + +If no `--db` specified in batch mode, what happens? + +**Options**: +- **A**: Use `default_vault` from settings, error if none +- **B**: No vault (tool not available), proceed without +- **C**: Error always if vault-dependent operation + +--- + +### 13. Generate MIME Default + +Must specify MIME every time? + +**Options**: +- **A**: Default to `image/png` (most common) +- **B**: No default, require explicit +- **C**: Remember last MIME type in session + +--- + +### 14. Command Aliases + +Should common commands have short aliases? + +**Proposed**: +``` +/q → /quit +/h → /help +/v → /vault (or /verbose?) +/s → /search +/? → /help +``` + +**Conflict**: `/v` could be `/vault` or `/verbose`. Worth having aliases? + +--- + +### 15. Feature Completeness Matrix + +Current state showing gaps: + +| Feature | Chat Batch | Chat REPL | Gen Batch | Gen REPL | Embed Batch | Embed REPL | +|---------|:----------:|:---------:|:---------:|:--------:|:-----------:|:----------:| +| Prompt | `-p` | direct | `-p` | direct | N/A | direct | +| Agent | `-a` | `/agent` | `-a` | `/agent` | `-a` | `/agent` | +| Vault | `--db` | `/vault` | `--db` | `/vault` | `--db` | `/vault` | +| Temperature | `-t` | ❓ | ❓ | ❓ | N/A | N/A | +| Output Schema | `--output-schema` | ❓ | N/A | N/A | N/A | N/A | +| MIME | N/A | N/A | `--mime` | `/mime` | N/A | N/A | +| System | config | `/system` | ❓ | ❓ | N/A | N/A | +| Thinking | `--no-thinking` | `/thinking` | ❓ | ❓ | N/A | N/A | +| Verbose | `-v` | `/verbose` | `-v` | `/verbose` | `-v` | `/verbose` | +| Output Dir | `-o` | ❓ | `-o` | ❓ | N/A | N/A | +| File Attach | `@file` | `@file` | ❓ | ❓ | ❓ | ❓ | +| Sync | N/A | N/A | N/A | N/A | `sync` | `/sync` | +| Search | tool | tool | ❓ | ❓ | ❓ | direct | +| Status | N/A | N/A | N/A | N/A | ❓ | `/status` | + +--- + +## Implementation Notes + +### Dependencies +- `cli_repl` for interactive loop +- `ragamuffin` patterns for vault management +- SQLite for embedding cache (via ragamuffin approach) + +### Key Components +- `TicCommandRunner` - CLI entry point and routing +- `ReplSession` - Interactive loop management +- `ModeHandler` - Mode-specific prompt handling +- `VaultManager` - Embedding cache and sync +- `SessionManager` - History save/load +- `CodeExporter` - Dart code generation + +### Migration from dartantic_cli +- Rename package to `tic` +- Move settings to `~/.tic/` +- Integrate ragamuffin vault system +- Add REPL infrastructure