Claude/setup openrouter gemini e cg p8#10
Open
KirillTrubitsyn wants to merge 59 commits intoeggent-ai:mainfrom
Open
Claude/setup openrouter gemini e cg p8#10KirillTrubitsyn wants to merge 59 commits intoeggent-ai:mainfrom
KirillTrubitsyn wants to merge 59 commits intoeggent-ai:mainfrom
Conversation
…-visualization.md
…l JSX syntax errors
Comprehensive proposal document describing the idea of deploying Eggent on Railway with a multi-user system (roles, permissions, data isolation, Telegram per-user support, usage statistics). https://claude.ai/code/session_014UXjuRzQFgRp4Mm83PKqvt
Remove the sudoers rule that granted the node user passwordless root access. This was convenient for local development but is a security vulnerability for public deployment. https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
Create src/lib/storage/users-store.ts with: - User model: id, username, displayName, passwordHash, role (admin/user), mustChangePassword, permissions, quotas, telegramUserId - CRUD operations: getAllUsers, getUserById, getUserByUsername, getUserByTelegramId, createUser, updateUser, updateUserPassword, deleteUser - SafeUser type that strips passwordHash for API responses - Auto-migration from legacy settings.auth on first access - Input validation (username format, password length) - Protection against deleting the last admin - File storage at data/settings/users.json https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
…t-HPTmw Claude/setup eggent project hp tmw
- Add userId field to Chat/ChatListItem types for chat ownership - Add ownerId/isShared fields to Project type for project ownership - Create getCurrentUser() helper to extract user from session cookie - Update chat-store to filter by userId (legacy chats without userId visible to all) - Update project-store to filter by ownerId (shared projects visible to all) - Update chat/history API to show only user's chats (admins see all) - Update chat API to set userId on new chats - Update projects API to set ownerId on new projects - Add ownership checks on project GET/PUT/DELETE operations https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
- Resolve Telegram userId to app User via getUserByTelegramId() - Check telegram permission before processing messages - Pass userId to chats created from Telegram sessions - Add quota checks (daily messages, monthly tokens) for Telegram users - Record usage stats after successful agent responses - Deny access with Russian-language messages when permissions/quotas fail https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
- Create usage-stats-store with per-user daily/monthly tracking - Track message count and estimated token usage per user per day - Auto-prune stats older than 90 days to keep storage compact - Add daily message quota and monthly token quota checking - Add GET /api/usage-stats endpoint (admins see all, users see own) - Integrate quota checks into chat API (returns 429 when exceeded) - Record usage stats fire-and-forget after agent responses https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
…t-HPTmw Claude/setup eggent project hp tmw
…t-HPTmw fix: upgrade next.js to 15.5.9 to resolve critical security vulnerabi…
…t-HPTmw fix: update package-lock.json for next@15.5.9
- Change default provider from OpenAI to OpenRouter for all models - Add multimediaModel slot (Gemini) alongside chatModel and utilityModel - Add UtilityModelWizard and MultimediaModelWizard UI components - Refactor model-wizards.tsx to use generic GenericChatModelWizard - Update API settings route to mask/restore keys for all model types - Update AgentConfig type to include multimediaModel - Update .env.example to prioritize OPENROUTER_API_KEY Default models: - Chat: anthropic/claude-opus-4-6 - Utility: anthropic/claude-sonnet-4-6 - Multimedia: google/gemini-2.5-pro-preview-05-06 - Embeddings: openai/text-embedding-3-small https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
13x cheaper than OpenAI, #1 on MTEB multilingual, 32K context. Using 1536 dims via MRL for storage/quality balance. Also add Qwen3 and Gemini embedding models to known dimensions map. https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
Google's latest SOTA reasoning model with multimodal capabilities. 1M context, audio/image/video input support. https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
- chatModel: claude-sonnet-4-6 (everyday conversations, ~5x cheaper) - utilityModel: claude-opus-4-6 (complex reasoning, coding, 8K output) https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
…for images - Subordinate agents now use utilityModel (Opus) instead of chatModel - Image attachments auto-route to multimediaModel (Gemini) with vision - Added multimodal message building (base64 images via AI SDK ImagePart) - Chat API, external handler, and Telegram all forward attachments - Regular text messages continue using chatModel (Sonnet) as before https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
…t-HPTmw Claude/setup eggent project hp tmw
Previously, only ExternalMessageError exceptions were caught and reported back to the Telegram user. All other errors (LLM API failures, missing API keys, timeouts) were silently swallowed, causing the bot to not respond at all. Now the catch-all block sends the error description to the user in Telegram so they can diagnose the issue. https://claude.ai/code/session_01XjFNsYgKjJrENstcSbcoVT
The Telegram bot was not responding because: 1. The webhook was never registered with Telegram API (setWebhook not called) 2. Empty allowedUserIds list blocked all users without any way to self-onboard Changes: - Add instrumentation.ts that auto-registers the Telegram webhook on app startup when TELEGRAM_BOT_TOKEN, TELEGRAM_WEBHOOK_SECRET, and a base URL are available. Also auto-detects base URL from deployment platforms (Vercel, Railway, Render, Fly.io) when APP_BASE_URL is not set. - Auto-allow the first user who messages the bot in a private chat when the allowedUserIds list is completely empty (no security boundary exists when nobody is configured). https://claude.ai/code/session_01JuWqDF92mQPfXk7fVH4q3K
Two issues fixed:
1. Simple questions (weather, jokes, etc.) triggered code_execution unnecessarily
because the system prompt pushed the model to always use tools. Updated prompts
to instruct the model to respond directly with text for simple questions.
2. The model produced duplicate response bubbles because the `response` tool caused
an extra agent round-trip — the model would call response tool, get the result
back, then generate another text message. Fixed by:
- Removing the response tool entirely (model now responds with text directly)
- Merging consecutive assistant messages in both storage (onFinish) and
rendering (chatMessagesToUIMessages) to prevent duplicate bubbles
https://claude.ai/code/session_016D6aN4HLJeTQkNSYRrprsv
APP_BASE_URL on Railway was set as 'kirilleggent-production.up.railway.app' without the https:// prefix, causing webhook registration to fail because Telegram requires a full URL. Now both instrumentation.ts and the runtime config normalize the URL by adding https:// if no protocol is present. https://claude.ai/code/session_01JuWqDF92mQPfXk7fVH4q3K
…t-HPTmw fix: send error messages to Telegram user for all failure types
Claude/fix telegram bot u x4 j0
…issing project When TELEGRAM_DEFAULT_PROJECT_ID is set to a non-existent project (e.g. "default"), the bot threw 'Project "default" not found' instead of falling back to the first available project. Now both resolveTelegramProjectContext() and handleExternalMessage() silently skip invalid project IDs and use the session's active project or first available project as fallback. https://claude.ai/code/session_01JuWqDF92mQPfXk7fVH4q3K
…X4J0 fix: gracefully fallback when TELEGRAM_DEFAULT_PROJECT_ID points to m…
Railway mounts volumes as root, but the app runs as user "node". Added an entrypoint script that: - When running as root: fixes /app/data ownership then drops to node via gosu - When running as non-root: ensures required subdirectories exist This fixes EACCES errors when the app tries to create settings/projects/chats directories inside the mounted volume. https://claude.ai/code/session_016D6aN4HLJeTQkNSYRrprsv
…ions - Add "Efficiency" section to system prompt instructing the agent to respond directly via the response tool for simple questions without unnecessary intermediate tool calls (code_execution, search, etc.) - Reduce max tool loop steps: chat 15→6, background 15→6, subordinate 10→5 - Clarify that code_execution should only be used when code actually needs to run, and search results should not be "processed" with additional tool calls Fixes the issue where a simple weather question triggered multiple large chained API requests (visible in OpenRouter logs) instead of a quick search + response. https://claude.ai/code/session_01Vgzt756Yc1gpSixKgXsHYp
…logic-H8Osc Claude/fix chat response logic h8 osc
…ments Merged main branch changes (direct text response, "When to Use Tools" section) with our branch changes (Efficiency section, reduced step counts, "Respond as quickly as possible" rule). https://claude.ai/code/session_01Vgzt756Yc1gpSixKgXsHYp
…-sFjDv fix: prevent agent from making excessive API requests on simple quest…
- Add HOSTNAME=0.0.0.0 so Next.js binds to all interfaces (Railway requirement) - Copy src/prompts/ to runner stage for runtime prompt loading - Simplify entrypoint.sh: use gosu directly (su-exec was never installed), remove 2>/dev/null that was swallowing all application stderr - Create data subdirectories in both root and non-root entrypoint branches https://claude.ai/code/session_01W6YtViBYRmAHgvJvMivmwX
…-7CKQw fix: resolve Railway deploy crash — bind to 0.0.0.0, fix entrypoint
- chown -R only /app/data instead of entire /app + python venv. The old chown duplicated node_modules, .next, bundled-skills etc. into a separate layer (hundreds of MB). At runtime node user only needs write access to /app/data (the volume mount). - Merge gosu into the main apt-get step (one fewer layer + apt-get update) - Remove duplicate mkdir -p for data directories https://claude.ai/code/session_01W6YtViBYRmAHgvJvMivmwX
…-7CKQw perf: optimize Dockerfile — eliminate massive chown layer
gosu + python3-venv/python3-requests cause apt dependency conflicts when installed in the same apt-get step on bookworm-slim. Split back into two steps while keeping the chown optimization (only /app/data). https://claude.ai/code/session_01W6YtViBYRmAHgvJvMivmwX
…-7CKQw fix: separate gosu apt-get from python packages to avoid dep conflict
python3-requests from apt causes dependency resolution failures on node:22-bookworm-slim. Install requests via pip in the venv instead, which avoids the system package conflicts entirely. https://claude.ai/code/session_01W6YtViBYRmAHgvJvMivmwX
…-7CKQw fix: install requests via pip instead of apt to avoid dep conflicts
ENV TMPDIR=/app/data/tmp is set before apt-get install, but the directory doesn't exist yet. ca-certificates post-install calls mktemp which uses TMPDIR and fails, cascading to python3-pip/venv failures. https://claude.ai/code/session_01W6YtViBYRmAHgvJvMivmwX
…-7CKQw fix: create TMPDIR before apt-get to unblock ca-certificates
The system prompt was bloated with ~15.5KB of tool-*.md files that duplicate the descriptions already in tool API schemas. A simple "Hello" message cost 11k prompt tokens. Changes: - Remove all 22 tool-*.md prompt injections from system prompt (tool descriptions already exist in the API tool schema) - Replace verbose markdown file table (50 files × 3 columns) with compact path-only list (30 files max) - Condense system.md from 69 lines to 14 lines - Replace XML skills metadata with simple markdown list - Remove unused escapeXml() and formatFileSize() functions Expected savings: ~80% reduction in prompt tokens per request. https://claude.ai/code/session_016D6aN4HLJeTQkNSYRrprsv
Tool descriptions and parameter .describe() strings were excessively verbose (e.g. "List all available projects. Use this when the user asks what projects exist..." → "List all projects."). Since the model can infer tool usage from short descriptions + parameter names + types, the long prose was pure token waste — sent with EVERY API call regardless of user message. Removed 271 lines of redundant description text across 24 tools. Combined with the system prompt optimization, a simple "Hello" should now cost ~3-4k tokens instead of 11k. https://claude.ai/code/session_016D6aN4HLJeTQkNSYRrprsv
…logic-H8Osc Claude/fix chat response logic h8 osc
- Add tool priority rule: search_web > code_execution for info requests - Make skill loading less aggressive: only load skills for multi-step workflows, not when a single tool call (e.g. search_web) suffices - This should reduce weather/news questions from 2 LLM calls to 1 https://claude.ai/code/session_016D6aN4HLJeTQkNSYRrprsv
…logic-H8Osc fix: reduce unnecessary tool calls for simple questions
…t Google API Switch from google-genai SDK with GEMINI_API_KEY to httpx-based OpenRouter API calls with OPENROUTER_API_KEY. Model changed to google/gemini-3.1-pro-preview. Added --model flag for optional model override. https://claude.ai/code/session_01C22Z5nyzY8gYRCSHtsxjPp
…tion Update nano-banana-pro skill and default multimediaModel to use the correct OpenRouter model ID (google/gemini-3.1-flash-image-preview) instead of google/gemini-3.1-pro-preview. https://claude.ai/code/session_01C22Z5nyzY8gYRCSHtsxjPp
The nano-banana-pro skill requires uv to run the generate_image.py script. Also pre-install httpx and pillow in the Python venv so dependencies are available immediately without network fetching at runtime. https://claude.ai/code/session_01C22Z5nyzY8gYRCSHtsxjPp
- modalities: ["image", "text"] (image first per OpenRouter docs) - Add image_config.image_size for resolution control (instead of text hint) - Parse response images from message.images[] (OpenRouter format) - Add fallback to parse images from content[] array - Support 0.5K resolution (exclusive to gemini-3.1-flash-image-preview) - Print full response on error for easier debugging https://claude.ai/code/session_01C22Z5nyzY8gYRCSHtsxjPp
- Add /api/media/serve endpoint to serve image files from data/ directory - Parse MEDIA: tokens from tool output in tool-output.tsx - Render images inline (visible even when tool output is collapsed) - Include filename and download link below each image - Security: only serve image files within the data/ directory https://claude.ai/code/session_01C22Z5nyzY8gYRCSHtsxjPp
- File click opens in new tab (images display inline, others download) - Add ?inline=1 param to /api/files/download for inline content display - Serve images with correct MIME type when inline mode is on - Add FileImage icon for image files in the tree - Add cursor pointer to indicate files are clickable https://claude.ai/code/session_01C22Z5nyzY8gYRCSHtsxjPp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Describe the problem and the intent of this PR.
What Changed
How to Test
Checklist
npm run lint.npm run build.