summaryrefslogtreecommitdiff
path: root/Omni/Agent
AgeCommit message (Collapse)Author
4 daysadd database layer for subagent job queueBen Sima
Phase 1 of subagent architecture redesign. Adds Jobs.hs with: - subagent_jobs table for persistent job queue - subagent_events table for lifecycle event log - Job CRUD: create, claim, complete, fail, cancel - Event logging for started, progress, tool_call, error, completed - Queries: pending jobs, running jobs, active summary for context - All tests passing This enables: - Jobs survive process restarts - Workers can claim and execute jobs independently - Events flow back to Ava's context for collaborative debugging 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4 daysfix UTF-8 encoding in deployed servicesBen Sima
- Systemd.hs: add LANG and LC_ALL defaults (en_US.utf8) to all generated unit files to ensure proper UTF-8 handling - Systemd.hs: add generateUnitWithLocale that reads LOCALE_ARCHIVE from the deployer's environment and injects it into generated units - Telegram.hs: add safePutText wrapper that catches encoding errors in logging to prevent them from killing message sends The root cause was NixOS systemd services not inheriting locale settings from the system, causing emoji characters to fail encoding. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4 daysOmni/Agent/Telegram/IncomingQueue: add error handling to batcherBen Sima
Wrap processFn in try/catch so exceptions don't kill the batcher thread. Previously, if a message handler threw an exception, the batcher would die and subsequent messages would be received but not processed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4 daysOmni/Agent/Subagent/Coder: fix direnv exec path handlingBen Sima
Use `cd <path> && direnv exec .` instead of `direnv exec <path>` since the latter doesn't work correctly with nix-direnv caching. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5 daysOmni/Agent/Subagent/Coder: always run in /home/ava/omniBen Sima
- Add omniRepoDir constant for the repo path - Use direnv exec with explicit path instead of "." - Update ava manifest workingDirectory to /home/ava This separates Ava's working directory from Coder's repo directory. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5 daysOmni/Agent/Subagent: fix per-spawn guardrails for CoderBen Sima
The Coder subagent was ignoring per-spawn guardrails from subagentGuardrails and always using SubagentConfig defaults. Now uses getGuardrail helper to check SpawnGuardrails first, falling back to SubagentConfig defaults if not specified. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5 daysOmni/Agent/Subagent: add General role and per-spawn customizationBen Sima
- Add SpawnGuardrails type for per-spawn resource limits - Extend SubagentConfig with toolsOverride, systemPrompt, guardrails - Add General role with balanced tools (file ops, bash, python, search) - Update spawn_subagent schema to expose general/custom roles and new params - Add subagent delegation guidance to Ava's system prompt 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
9 daysOmni/Agent/Telegram: fix reminder leak to group chatsBen Sima
Only record user's chat_id for private chats, not group chats. Previously, interacting in a group would overwrite the user's chat_id, causing personal reminders to be sent to that group.
9 daysOmni/Ava: improve trace viewer and subagent notificationsBen Sima
- Add subagent completion callback to notify user when subagent finishes - Show tool name in 'view trace' link (e.g. 'view web_search trace') - Pretty-print JSON on trace web page using aeson-pretty Amp-Thread-ID: https://ampcode.com/threads/T-019b3a13-bc75-7368-9ec9-362d462a022c Co-authored-by: Amp <amp@ampcode.com>
10 daysOmni/Agent: make token explosion impossibleBen Sima
Tools.hs: - run_bash now uses mkSuccess (applies truncation) - read_file requires line ranges for files >500 lines - read_file rejects ranges >400 lines Engine.hs: - Added engine-level truncateToolResult (10k char cap) - Fixed test detection: bash -> run_bash
10 daysOmni/Agent/Subagent/Coder: improve token efficiencyBen Sima
- Rewrote system prompt with TOKEN EFFICIENCY section - Reduced defaults: timeout 600s, maxCost 50¢, maxTokens 100k - Added output truncation (8000 char cap) to all tools - Tightened search limits (30 results, 5 context lines)
11 daysfeat(ava): add tool trace viewer mini-appBen Sima
- Add SQLite storage for tool traces (Omni/Ava/Trace.hs) - Add web server to serve trace viewer (Omni/Ava/Web.hs) - Add HTML/CSS/JS trace viewer UI (Omni/Ava/Web/trace.html) - Integrate trace storage into Engine.hs tool execution callback - Add trace links to Telegram responses when AVA_WEB_URL is set - Configure Tailscale Funnel for public access - Fix pre-push hook variable scope bug - Add direnv, bash, nix to Ava service PATH - Add mustache dep to Ava.hs for template rendering Epic: t-272
11 daysOmni/Agent: wire prompt templating system to agentsBen Sima
- Telegram.hs: add loadTelegramSystemPrompt with fallback - Subagent.hs: add loadSystemPromptForRole with fallback - Coder.hs: add loadCoderSystemPrompt with fallback - Ava.nix: add tmpfiles rules for /home/ava/prompts/ - Prompts.hs: fix test to expect .mustache extension Templates loaded at runtime from $AVA_DATA_ROOT/prompts/. Falls back to hardcoded prompts if templates not found. Amp-Thread-ID: https://ampcode.com/threads/T-019b3878-73be-77ec-97cc-d092a28d211e Co-authored-by: Amp <amp@ampcode.com>
11 daysAdd prompt templating system with mustacheBen Sima
- Add promptsDir to Paths.hs for $AVA_DATA_ROOT/prompts/ - Create Omni.Agent.Prompts module with: - Mustache template loading and rendering - Automatic partial resolution via automaticCompile - Frontmatter/metadata parsing for list command - Create omni-agent-prompt CLI for previewing prompts: - list: show all available prompts - render: render prompt with --var and --json context - Prompts use .mustache extension for automaticCompile compatibility - Partials referenced with full extension: {{> shared/memory.mustache}}
11 daysWire up writeAvaLog to actually write audit logsBen Sima
- Add AuditLog import to Telegram.hs - Call writeAvaLog for user messages in both handleEngagement paths - Call writeAvaLog for assistant responses - Add logs directories to Ava.nix tmpfiles rules
11 daysAdd semantic search for chat historyBen Sima
- Add chat_history table with embeddings in memory.db - Add saveChatHistoryEntry for live message ingestion - Add searchChatHistorySemantic for vector similarity search - Update search_chat_history tool to use semantic search - Add backfill command: run.sh Omni/Agent/Memory.hs backfill - Add stats command: run.sh Omni/Agent/Memory.hs stats - Change default memory.db path to ~/memory.db - Wire Telegram message handling to save to chat_history async
11 daysAdd search_chat_history tool for AvaBen Sima
Allows Ava to search her conversation logs for past discussions. Searches UserMessage/AssistantMessage events with case-insensitive matching, configurable days_back (default 7) and max_results (default 20).
12 daysCoder: git pull --ff-only in init phaseBen Sima
12 daysSubagent: clarify context is required for coder roleBen Sima
12 daysSubagent: remove task_id from spawn_subagent tool schemaBen Sima
The coder role no longer requires task_id, only namespace.
12 daysTelegram formatting + push.sh Tailscale supportBen Sima
- Strengthen Telegram MarkdownV2 formatting guidance in Ava's system prompt - Add DNS record beryl.bensima.com -> 100.127.197.132 (Tailscale IP) - Modify push.sh to detect local deploys and skip SSH - Add Tailscale hostname fallback when domain is unreachable
12 daysOmni/Agent/Subagent/Coder: decouple from jr task systemBen Sima
Remove task_id requirement and all jr task CLI calls. The Coder subagent now only requires namespace and task description - no external task tracking needed. Changes: - Remove coderTaskId from CoderConfig - Remove jr task show/update/comment calls - Commit message uses namespace prefix instead of task ID - Recovery phase just reverts git, no task comment - Subagent.hs only validates namespace for Coder role
12 daysAdd Telegram button confirmation for subagent spawningBen Sima
Security improvement: subagents now require explicit user confirmation via Telegram inline buttons, preventing the agent from bypassing approval. Changes: - Add InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery types - Add parseCallbackQuery for handling button presses - Add sendMessageWithKeyboard and answerCallbackQuery API functions - Add PendingSpawn registry for tracking unconfirmed spawn requests - Add spawnSubagentToolWithApproval that sends approval buttons - Add handleCallbackQuery to process approve/reject button clicks - Add approveAndSpawnSubagent and rejectPendingSpawn functions Flow: 1. Agent calls spawn_subagent → creates pending request 2. User receives message with ✅ Approve / ❌ Reject buttons 3. Button click (outside agent loop) spawns or cancels 4. Pending requests expire after 10 minutes
12 daysMake subagents non-blocking with async spawningBen Sima
- Add global subagent registry to track running handles by ID - Modify executeSpawnSubagent to use spawnSubagentAsync and return immediately - Add check_subagent tool for querying status or getting results - Export subagentTools convenience function with both tools - Update Telegram.hs to use subagentTools instead of just spawnSubagentTool Ava can now spawn subagents in the background and continue conversations while checking on progress via check_subagent.
13 daysfeat(ava): subagent hardening with audit loggingBen Sima
Based on Anthropic's effective harnesses research. New modules: - Omni/Agent/AuditLog.hs: JSONL audit logging with SubagentId linking - Omni/Agent/Tools/AvaLogs.hs: Tool for Ava to query her own logs - Omni/Agent/Subagent/HARDENING.md: Design documentation Key features: - SubagentHandle with TVar status for async execution and polling - spawnSubagentAsync, querySubagentStatus, waitSubagent, cancelSubagent - User confirmation: spawn_subagent requires confirmed=true after approval - Audit logs stored in $AVA_DATA_ROOT/logs/{ava,subagents}/ - CLI: ava logs [--last=N] [<subagent_id>] - read_ava_logs tool for Ava self-diagnosis Tasks: t-267, t-268, t-269, t-270, t-271
13 daysava: add Python/CLI tools and local whisper fallbackBen Sima
- Wrap ava binary with Python (requests, httpx, pandas, etc.) - Add CLI tools: curl, pandoc, ffmpeg, imagemagick, csvkit - Add local whisper-cli fallback when OPENAI_API_KEY unavailable Amp-Thread-ID: https://ampcode.com/threads/T-019b2dc2-36e0-75e1-90c1-622901fc9847 Co-authored-by: Amp <amp@ampcode.com>
13 daysAdd Ava systemd deployment with dedicated user and workspaceBen Sima
- Add Omni.Agent.Paths module for configurable AVA_DATA_ROOT - Create ava Linux user in Users.nix with SSH key - Add systemd service in Beryllium/Ava.nix with graceful shutdown - Update Skills.hs and Outreach.hs to use configurable paths - Add startup logging of resolved paths in Telegram.hs - Create migration script for moving data from _/var/ava to /home/ava - Add deployment documentation in Beryllium/AVA.md In dev: AVA_DATA_ROOT unset uses _/var/ava/ In prod: AVA_DATA_ROOT=/home/ava via systemd Amp-Thread-ID: https://ampcode.com/threads/T-019b2d7e-bd88-7355-8133-275c65157aaf Co-authored-by: Amp <amp@ampcode.com>
13 daysAdd subagent system for AvaBen Sima
Enables orchestrator to spawn specialized subagents for focused tasks: - WebCrawler: web search + page reading (haiku, fast) - CodeReviewer: code analysis tools (sonnet, thorough) - DataExtractor: structured data extraction (haiku) - Researcher: combined web + codebase research (sonnet) Key features: - spawn_subagent tool with role-based tool selection - Per-subagent resource limits (timeout, cost, tokens) - Structured output with citations (claim, source_url, quote) - Separate API keys for OpenRouter vs Kagi - Efficiency-focused system prompts Defaults: 200k tokens, $1.00 cost cap, 600s timeout, 20 iterations
14 daysAdd skills system for avaBen Sima
- Create Omni/Agent/Skills.hs with skill loader and tools - Skills follow Claude Skills format (SKILL.md + scripts/references/assets) - Directory structure: _/var/ava/skills/{shared,<user>}/ - Three tools: skill, list_skills, publish_skill - Users can publish private skills to shared - Integrate skills tools into Telegram bot - Create skill-creator meta-skill at _/var/ava/skills/shared/skill-creator/
14 daysBatch web_reader tool, much fasterBen Sima
Added retry with backoff, parallel proccessing, editing pages down to main content, summarization with haiku. It's so much faster and more reliable now. Plus improved the logging system and distangled the status UI bar from the logging module.
2025-12-16refactor: Rename Bot to Ava, remove cost guardrailBen Sima
- Rename Omni/Bot.hs to Omni/Ava.hs - Delete Omni/Bot.scm (unused Guile version) - Remove cost limit (was 10 cents, now 0) - Increase max iterations from 10 to 50
2025-12-15Restrict new tools to Ben onlyBen Sima
python_exec, http_get/post, outreach_*, feedback_list, and read_file now require isBenAuthorized check, matching email/hledger pattern.
2025-12-15t-265.6: Add feedback collection endpoint for PILBen Sima
- Add feedback table with migration in Core.py - Add FeedbackForm and FeedbackPage UI components - Add /feedback GET/POST routes and /api/feedback JSON endpoint - Add admin feedback view at /admin/feedback - Create Omni/Agent/Tools/Feedback.hs with feedback_list tool - Wire feedback tool into Telegram agent
2025-12-14t-265.5: Add SMTP email sending for Ava outreachBen Sima
- Add emailSendTool to Email.hs for sending approved drafts - Add sendApprovedEmail function that checks draft status - Use Network.Mail.Mime.simpleMail' with SMTP.sendMail - Integrate with Outreach module to verify approval and mark sent - Add tests for new tool
2025-12-14t-265.4: Add read_file tool and PIL codebase context to AvaBen Sima
- Import Omni.Agent.Tools in Telegram.hs - Add readFileTool to Ava's tool list - Add podcastitlater context section to system prompt with key file paths
2025-12-14Fix message splitting to not use LLMBen Sima
The haiku-based splitting was modifying message content. Replace with deterministic paragraph-based splitting that preserves the original text exactly.
2025-12-14Add outreach approval queue for Ava (t-265.3)Ben Sima
- Create Omni/Agent/Tools/Outreach.hs with tools - Drafts stored in _/var/ava/outreach/{pending,approved,...} - Add Telegram commands: /review, /approve, /reject, /queue - Integrate outreach tools into agent's tool list Amp-Thread-ID: https://ampcode.com/threads/T-019b202c-2156-74db-aa4a-e0a2f4397fbb Co-authored-by: Amp <amp@ampcode.com>
2025-12-14Add HTTP request tools for agent API interactionsBen Sima
- Create Omni/Agent/Tools/Http.hs with http_get and http_post tools - Support headers, query params, JSON body, 30s timeout - Return structured JSON with status, headers, body - Add 9 unit tests including real HTTP calls to httpbin.org - Wire tools into Telegram agent's tool list Completes t-265.2
2025-12-14Add python_exec tool for agent Python executionBen Sima
- Create Omni/Agent/Tools/Python.hs with python_exec tool - Execute Python snippets via subprocess with 30s default timeout - Return structured JSON with stdout, stderr, exit_code - Add 8 unit tests covering print, imports, errors, timeout - Wire tool into Telegram agent's tool list Completes t-265.1
2025-12-14telegram: switch to HaskellNet for IMAP, fix message delivery bugsBen Sima
- Replace openssl s_client with HaskellNet/HaskellNet-SSL for proper IMAP client support (better protocol handling, no manual parsing) - Add HaskellNet deps to Haskell.nix with doJailbreak for version bounds - Fix lost messages: sendMessageReturningId now throws on API errors instead of returning Nothing (which was incorrectly treated as success) - Auto-retry markdown parse errors as plain text - Hardcode benChatId for reliable email check loop startup
2025-12-13Add hledger tools to Telegram botBen Sima
- New Omni/Agent/Tools/Hledger.hs with 5 tools: - hledger_balance: query account balances - hledger_register: show transaction history - hledger_add: create new transactions - hledger_income_statement: income vs expenses - hledger_balance_sheet: net worth view - All tools support currency parameter (default: USD) - Balance, register, income_statement support period parameter - Period uses hledger syntax (thismonth, 2024, from X to Y) - Shell escaping fixed for multi-word period strings - Authorization: only Ben and Kate get hledger tools - Max iterations increased from 5 to 10 - Transactions written to ~/fund/telegram-transactions.journal
2025-12-13telegram: round cost to 2 decimal places in logsBen Sima
2025-12-13telegram: per-user memory in groups, continuous typingBen Sima
Memory changes: - Add thread_id column to conversation_messages for topic support - Add saveGroupMessage/getGroupConversationContext for shared history - Add storeGroupMemory/recallGroupMemories with 'group:<chat_id>' user - Fix SQLite busy error: set busy_timeout before journal_mode Telegram changes: - Group chats now use shared conversation context (chat_id, thread_id) - Personal memories stay with user, group memories shared across group - Memory context shows [Personal] and [Group] prefixes - Add withTypingIndicator: refreshes typing every 4s while agent thinks - Fix typing UX: indicator now shows continuously until response sent
2025-12-13feat: add Telegram topic (message_thread_id) supportBen Sima
- Parse message_thread_id from incoming messages - Include thread_id in sendMessage API calls - Pass thread_id through message queue system - Replies now go to the correct topic in supergroups
2025-12-13fix: use OpenAI Whisper for voice transcriptionBen Sima
OpenRouter's chat completion API doesn't properly pass audio to models. Switched to calling OpenAI's /v1/audio/transcriptions endpoint directly with the whisper-1 model. Requires OPENAI_API_KEY environment variable.
2025-12-13Enable WAL mode and busy timeout for SQLite concurrencyBen Sima
Fixes 'database is locked' errors when multiple threads access the memory database simultaneously (incoming batcher, message dispatch, reminder loop, main handler).
2025-12-13Add incoming message queue for Telegram botBen Sima
Batches incoming messages by chat_id with a 3-second sliding window before processing. This prevents confusion when messages arrive simultaneously from different chats. - New IncomingQueue module with STM-based in-memory queue - Messages enqueued immediately, offset acked on enqueue - 200ms tick loop flushes batches past deadline - Batch formatting: numbered messages, sender attribution for groups, media stubs, reply context - Media from first message in batch still gets full processing
2025-12-13telegram: fix audio transcription model and prompt orderBen Sima
- Switch from gemini-2.0-flash-001 to gemini-2.5-flash - Put audio content before text prompt (model was ignoring audio) - Strengthen prompt to return only transcription
2025-12-13telegram: unified message queue with async/scheduled sendsBen Sima
- Add Messages.hs with scheduled_messages table and dispatcher loop - All outbound messages now go through the queue (1s polling) - Disable streaming responses, use runAgentWithProvider instead - Add send_message tool for delayed messages (up to 30 days) - Add list_pending_messages and cancel_message tools - Reminders now queue messages instead of sending directly - Exponential backoff retry (max 5 attempts) for failed sends
2025-12-13Fix Telegram streaming markdown parse errorsBen Sima
Amp-Thread-ID: https://ampcode.com/threads/T-019b1894-b431-777d-aba3-65a51e720ef2 Co-authored-by: Amp <amp@ampcode.com>