| Age | Commit message (Collapse) | Author |
|
- Add RelationType with 6 relation types
- Add MemoryLink type and memory_links table
- Add graph functions: linkMemories, getMemoryLinks, queryGraph
- Add link_memories and query_graph agent tools
- Wire up graph tools to Telegram bot
- Include memory ID in recall results for linking
- Fix streaming usage parsing for cost tracking
Closes t-255
Amp-Thread-ID: https://ampcode.com/threads/T-019b181f-d6cd-70de-8857-c445baef7508
Co-authored-by: Amp <amp@ampcode.com>
|
|
When the bot is added to a group, check if the user who added it is
in the whitelist. If not, send a message explaining and leave the group
immediately. This prevents unauthorized users from bypassing DM access
controls by adding the bot to a group.
|
|
|
|
Add parse_mode=Markdown to sendMessage and editMessage API calls
|
|
OpenAI's SSE streaming sends tool calls incrementally - the first chunk
has the id and function name, subsequent chunks contain argument fragments.
Previously each chunk was treated as a complete tool call, causing invalid
JSON arguments.
- Add ToolCallDelta type with index for partial tool call data
- Add StreamToolCallDelta chunk type
- Track tool calls by index in IntMap accumulator
- Merge argument fragments across chunks via mergeToolCallDelta
- Build final ToolCall objects from accumulator when stream ends
- Handle new StreamToolCallDelta in Engine.hs pattern match
|
|
Pre-filter now sees last 5 messages so it can detect when user
is continuing a conversation with Ava, even without explicit mention.
- Fetch recent messages before shouldEngageInGroup
- Update classifier prompt to understand Ava context
- Handle follow-up messages to bot's previous responses
|
|
- Update to Dec 2024 OpenRouter pricing
- Use blended input/output rates
- Add gemini-flash, claude-sonnet-4.5 specific rates
- Fix math: was off by ~30x for Claude models
|
|
Use Gemini Flash to classify group messages before running the
full Sonnet agent. Skips casual banter to save tokens/cost.
- shouldEngageInGroup: yes/no classifier using gemini-2.0-flash
- Only runs for group chats, private chats skip the filter
- On classifier failure, defaults to engaging (fail-open)
|
|
- Remove mention-based filtering, bot sees all group messages
- Add response rules to system prompt for group chats:
- tool invocation = always respond
- direct question = respond
- factual correction = maybe respond
- casual banter = stay silent
- Empty response in group = intentional silence (no fallback msg)
- Add chat type context to system prompt
|
|
- Only respond in groups when @mentioned or replied to
- Add ChatType to TelegramMessage (private/group/supergroup/channel)
- Add getMe API call to fetch bot username on startup
- Add shouldRespondInGroup helper function
|
|
- Fix Provider.hs to strip leading whitespace from OpenRouter responses
- Fix FunctionCall parser to handle missing 'arguments' field
- Use eitherDecode for better error messages on parse failures
- Switch to claude-sonnet-4.5 for main agent
- Use gemini-2.0-flash for conversation summarization (cheaper)
- Add read_webpage tool for fetching and summarizing URLs
- Add tagsoup to Haskell deps (unused, kept for future)
|
|
Refactor Telegram.hs into submodules to reduce file size:
- Types.hs: data types, JSON parsing
- Media.hs: file downloads, image/voice analysis
- Reminders.hs: reminder loop, user chat persistence
Multimedia improvements:
- Vision uses third-person to avoid LLM confusion
- Better message framing for embedded descriptions
- Size validation (10MB images, 20MB voice)
- MIME type validation for voice messages
New features:
- Reply support: bot sees context when users reply
- Web search: default 5->10, max 10->20 results
- Guardrails: duplicate tool limit 3->10 for research
- Timezone: todos parse/display in Eastern time (ET)
|
|
- Add TelegramPhoto and TelegramVoice types
- Parse photo and voice fields from Telegram updates
- Download photos/voice via Telegram API
- Analyze images using Claude vision via OpenRouter
- Transcribe voice messages using Gemini audio via OpenRouter
- Wire multimedia processing into handleAuthorizedMessage
Photos are analyzed with user's caption as context.
Voice messages are transcribed and treated as text input.
|
|
Adds a background reminder loop that checks every 5 minutes for overdue
todos and sends Telegram notifications.
Changes:
- Add last_reminded_at column to todos table with auto-migration
- Add listTodosDueForReminder to find overdue, unreminded todos
- Add markReminderSent to update reminder timestamp
- Add user_chats table to map user_id -> chat_id for notifications
- Add recordUserChat called on each message to track chat IDs
- Add reminderLoop forked in runTelegramBot
- 24-hour anti-spam interval between reminders per todo
|
|
When the LLM returned empty content after executing tools, the agent
would complete with an empty message. Now both agent loops (LLM-based
and Provider-based) detect this case and inject a prompt asking the
LLM to provide a response to the user.
|
|
- Omni/Agent/Tools/Todos.hs: todo_add, todo_list, todo_complete, todo_delete
- Supports optional due dates in YYYY-MM-DD or YYYY-MM-DD HH:MM format
- Lists can filter by pending, all, or overdue
- Add todos table to Memory.hs schema
- Wire into Telegram bot
|
|
- Add sender_name column to conversation_messages table
- Migrate existing messages to set sender_name='bensima'
- Show sender names in conversation context (e.g., 'bensima: hello')
- Pass userName when saving user messages in Telegram bot
|
|
|
|
|
|
|
|
|
|
|
|
- Omni/Agent/Tools/Calendar.hs: calendar_list, calendar_add, calendar_search
- Wire into Telegram bot alongside other tools
- Integrates with local CalDAV via khal
|
|
- Omni/Agent/Tools/Pdf.hs: Extract text from PDFs using pdftotext
- Omni/Agent/Tools/Notes.hs: Quick notes CRUD with topics
- Add notes table schema to Memory.hs initMemoryDb
- Wire both tools into Telegram bot with logging callbacks
|
|
- Add Omni/Agent/Tools/WebSearch.hs with Kagi Search API integration
- webSearchTool for agents to search the web
- kagiSearch function for direct API access
- Load KAGI_API_KEY from environment
- Wire web search into Telegram bot tools
- Results formatted with title, URL, and snippet
Closes t-252
|
|
- Add tgAllowedUserIds field to TelegramConfig
- Load ALLOWED_TELEGRAM_USER_IDS from environment (comma-separated)
- Check isUserAllowed before processing messages
- Reject unauthorized users with friendly message
- Empty whitelist or '*' allows all users
- Add tests for whitelist behavior
|
|
- Add sendTypingAction to show typing indicator when processing
- Add conversation_messages and conversation_summaries tables
- Implement conversation history with token counting
- Auto-summarize when context exceeds threshold (3000 tokens)
- Save user/assistant messages for multi-turn context
- Add ConversationMessage, ConversationSummary, MessageRole types
Tasks created: t-252 (web search), t-253 (calendar), t-254 (PDF),
t-255 (knowledge graph), t-256 (notes)
|
|
- Set response timeout to polling timeout + 10s for long polling
- Remove Markdown parse_mode to avoid 400 errors on special chars
|
|
|
|
- Omni/Agent/Telegram.hs: Telegram API client with getUpdates/sendMessage
- Omni/Bot.hs: Standalone CLI for running the bot
- User identification via Memory.getOrCreateUserByTelegramId
- Memory-enhanced agent with remember/recall tools
- Run with: bot --token=XXX or TELEGRAM_BOT_TOKEN env var
|
|
- User management with Telegram ID identification
- Memory storage with Ollama embeddings (nomic-embed-text)
- Semantic similarity search via cosine similarity
- remember/recall tools for agents
- runAgentWithMemory wrapper for memory-enhanced agents
- Separate memory.db database for user privacy
|
|
- Create Omni/Agent/Provider.hs with unified Provider interface
- Support OpenRouter (cloud), Ollama (local), Amp (subprocess stub)
- Add runAgentWithProvider to Engine.hs for Provider-based execution
- Add EngineType to Core.hs (EngineOpenRouter, EngineOllama, EngineAmp)
- Add --engine flag to 'jr work' command
- Worker.hs dispatches to appropriate provider based on engine type
Usage:
jr work <task-id> # OpenRouter (default)
jr work <task-id> --engine=ollama # Local Ollama
jr work <task-id> --engine=amp # Amp CLI (stub)
|
|
Defines architecture for multi-agent system with:
- Provider abstraction (OpenRouter, Ollama, Amp backends)
- Shared memory system (sqlite-vss, multi-user, cross-agent)
- Tool registry for pluggable tool sets
- Evals framework for regression testing
- Telegram bot as first concrete agent
Tasks: t-247 through t-251
|
|
Add explicit guidance on:
- Reading files with large ranges (500+ lines) instead of many small chunks
- Using read_file directly when target file is known vs search_and_read
- Cost awareness: planning refactors, avoiding redundant reads
- Tool call limits for complex tasks
|
|
The task was being added to the prompt twice, once in the base prompt and once
in the user prompt.
|
|
Worked with Gemini and Opus to improve the system prompt with learnings from the
Amp prompt. Removed reference to Omni/Task/README.md because it is deprecated in
favor of `jr task`.
|
|
jr prompt <task-id> constructs and prints the full system prompt
that would be sent to the agent, including:
- Agent configuration (model, cost budget)
- Base instructions
- AGENTS.md content
- Relevant facts from knowledge base
- Retry/progress context if applicable
Useful for debugging agent behavior and token usage.
|
|
Timeline tool display:
- Grep/search: ✓ Grep pattern in filepath
- Read file: ✓ Read filepath @start-end
- Edit file: ✓ Edit filepath
- Bash: ϟ command (lightning bolt prompt)
- Tool results only shown for meaningful output
New search_and_read tool:
- Combines search + read in one operation
- Uses ripgrep --context for surrounding lines
- More efficient than separate search then read
Worker prompt updated to prefer search_and_read over
separate search + read_file calls
|
|
- Fix Worker.hs to use EngineError instead of tuple
- Fix Types.hs imports for LazyText.encodeUtf8 and dayOfWeek
- Remove duplicate SortOrder from Components.hs (import from Types.hs)
- Add orphan instance pragmas to Pages.hs and Partials.hs
- Clean up unused imports
|
|
The HTMX-refreshed AgentEventsPartial was missing:
- Cost/token summary in header
- Live toggle button
- Autoscroll toggle button
- Comment form
Now matches the full page renderUnifiedTimeline output.
|
|
Jr was completing tasks but then going into verification loops,
re-reading files and 'tracing through logic' after tests passed.
This burned ~4 cents of extra cost on t-221.
Made instructions more emphatic:
- 'STOP IMMEDIATELY' with explicit list of what NOT to do
- 'ANY further tool calls are wasted money'
- Repeated in BUILD SYSTEM NOTES section
Task-Id: t-227
|
|
Instructs the agent to:
- Use line ranges when reading large files (>500 lines)
- Use minimal context for edit_file old_str matching
- Re-read exact lines after failed edits
- Stop after 2-3 failed edits to reconsider approach
- Flag very large files (>2000 lines) for refactoring
Task-Id: t-225
|
|
Tracks 'old_str not found' errors from edit_file tool calls. After 5
consecutive failures, stops the agent to prevent burning tokens on
impossible edits.
This catches the pattern where the agent repeatedly tries to edit a
large file with incorrect old_str matches, which was the root cause
of t-222 exceeding its cost budget.
Task-Id: t-224
|
|
Cost limits by complexity level:
- Complexity 1: 50 cents
- Complexity 2: 100 cents
- Complexity 3: 200 cents (default)
- Complexity 4: 400 cents
- Complexity 5: 600 cents
This prevents low-complexity tasks from burning budget while allowing
complex tasks more room for iteration.
Task-Id: t-223
|
|
- Add clickable LIVE toggle button that pauses/resumes timeline polling
- Green pulsing when active, grey when paused
- Uses htmx:beforeRequest event to cancel requests when paused
- Increase duplicate tool call guardrail from 20 to 30
Task-Id: t-211
|
|
- Add formatToolCallSummary to extract key argument from JSON
- Shows run_bash command, file paths for read/edit/write, patterns for search
- Display summary inline in tool call header (e.g., run_bash: `ls -la`)
- Increase token guardrail from 1M to 2M to prevent premature stops
Task-Id: t-212
|
|
The limit of 5 was too aggressive - reading 5 different files while
exploring a codebase would trigger the guardrail. 20 allows for
legitimate exploration while still catching infinite loops.
|
|
- updateTaskStatusWithActor logs status_change events to agent_events
- Worker uses Junior actor for status changes - Jr review uses
System/Human actors appropriately - CLI task update uses Human actor
- Remove task_activity table schema (migrated to agent_events) -
addComment now inserts into agent_events with event_type='comment'
Task-Id: t-213
|
|
- Add 'actor' column to agent_events table (human/junior/system)
- Add System to CommentAuthor type (reused for actor) - Add SQL
FromField/ToField instances for CommentAuthor - Update insertAgentEvent
to accept actor parameter - Update all SELECT queries to include
actor column - Update Worker.hs to pass actor for all event types -
Guardrail events logged with System actor
Migration: ALTER TABLE adds column with default 'junior' for existing
rows.
Task-Id: t-213.1
|
|
Implement runtime guardrails in Engine.hs: - Cost budget limit (default
200 cents) - Token budget limit (default 1M tokens) - Duplicate tool
call detection (same tool called N times) - Test failure counting
(bild --test failures)
Add database-backed progress tracking: - Checkpoint events stored in
agent_events table - Progress summary retrieved on retry attempts -
Improved prompts emphasizing efficiency and autonomous operation
Worker.hs improvements: - Uses guardrails configuration - Reports
guardrail violations via callbacks - Better prompt structure for
autonomous operation
Task-Id: t-203
|