Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
c2f646c
fix: wrap content in raw tags to prevent Liquid syntax error in audio…
KirillTrubitsyn Feb 27, 2026
64db59c
fix: add _config.yml to disable Liquid processing globally and fix al…
KirillTrubitsyn Feb 27, 2026
9295355
fix: add liquid error_mode: lax to suppress JSX syntax errors in Jeky…
KirillTrubitsyn Feb 27, 2026
3d32a07
fix: wrap charts.md content in raw tags to prevent Liquid syntax errors
KirillTrubitsyn Feb 27, 2026
cc462df
fix: wrap charts.md content in raw tags to prevent Liquid syntax errors
KirillTrubitsyn Feb 27, 2026
8bb5511
fix: wrap calculate-metadata.md content in raw tags to prevent Liquid…
KirillTrubitsyn Feb 27, 2026
4821bd8
docs: add Eggent proposal for Railway deployment and multi-user system
claude Feb 27, 2026
25789c6
Merge pull request #2 from KirillTrubitsyn/claude/explore-project-set…
KirillTrubitsyn Feb 27, 2026
9445744
Phase 1: Remove passwordless sudo from Dockerfile
claude Feb 27, 2026
0e025ba
Phase 2: Add users-store with CRUD, roles, permissions and quotas
claude Feb 27, 2026
0bfc171
Merge pull request #3 from KirillTrubitsyn/claude/setup-eggent-projec…
KirillTrubitsyn Feb 27, 2026
a6f8461
Phase 3: Per-user data isolation for chats and projects
claude Feb 27, 2026
d72abe3
Phase 4: Telegram per-user integration
claude Feb 27, 2026
03438ee
Phase 5: Usage statistics with quota enforcement
claude Feb 27, 2026
1444b40
Merge pull request #4 from KirillTrubitsyn/claude/setup-eggent-projec…
KirillTrubitsyn Feb 27, 2026
d10b952
fix: upgrade next.js to 15.5.9 to resolve critical security vulnerabi…
claude Feb 27, 2026
cbb280c
Merge pull request #5 from KirillTrubitsyn/claude/setup-eggent-projec…
KirillTrubitsyn Feb 27, 2026
22af25f
fix: update package-lock.json for next@15.5.9
claude Feb 27, 2026
5dce3cb
Merge pull request #6 from KirillTrubitsyn/claude/setup-eggent-projec…
KirillTrubitsyn Feb 27, 2026
ba4ed84
feat: route all models through OpenRouter with single API key
claude Feb 27, 2026
764997b
feat: switch default embedding model to qwen3-embedding-8b
claude Feb 27, 2026
44f3eda
feat: update multimedia model to gemini-3.1-pro-preview
claude Feb 27, 2026
a3eca28
feat: swap chat/utility models — Sonnet as main, Opus for heavy tasks
claude Feb 27, 2026
ae00e6a
feat: wire multi-model routing — Opus for subordinate agents, Gemini …
claude Feb 27, 2026
79429f1
Merge pull request #7 from KirillTrubitsyn/claude/setup-eggent-projec…
KirillTrubitsyn Feb 27, 2026
7ba2507
fix: send error messages to Telegram user for all failure types
claude Feb 28, 2026
fa03ecd
fix: auto-register Telegram webhook on startup and auto-allow first user
claude Feb 28, 2026
43930ae
fix: eliminate duplicate chat responses and unnecessary code execution
claude Feb 28, 2026
47847c8
fix: auto-add https:// to APP_BASE_URL when protocol is missing
claude Feb 28, 2026
b4fe257
Merge pull request #8 from KirillTrubitsyn/claude/setup-eggent-projec…
KirillTrubitsyn Feb 28, 2026
d7539ae
Merge pull request #9 from KirillTrubitsyn/claude/fix-telegram-bot-uX4J0
KirillTrubitsyn Feb 28, 2026
91c3a8f
fix: gracefully fallback when TELEGRAM_DEFAULT_PROJECT_ID points to m…
claude Feb 28, 2026
f14590c
Merge pull request #10 from KirillTrubitsyn/claude/fix-telegram-bot-u…
KirillTrubitsyn Feb 28, 2026
0db3909
fix: add entrypoint to fix Railway volume permissions
claude Feb 28, 2026
a8aeb6c
fix: prevent agent from making excessive API requests on simple quest…
claude Feb 28, 2026
91b5ff6
Merge pull request #11 from KirillTrubitsyn/claude/fix-chat-response-…
KirillTrubitsyn Feb 28, 2026
66b84db
merge: resolve conflict in system.md, combine both efficiency improve…
claude Feb 28, 2026
eda9f69
Merge pull request #12 from KirillTrubitsyn/claude/fix-agent-requests…
KirillTrubitsyn Feb 28, 2026
6e7f293
fix: resolve Railway deploy crash — bind to 0.0.0.0, fix entrypoint
claude Feb 28, 2026
48d5c9b
Merge pull request #13 from KirillTrubitsyn/claude/fix-railway-deploy…
KirillTrubitsyn Feb 28, 2026
6933126
perf: optimize Dockerfile — eliminate massive chown layer
claude Feb 28, 2026
3ef7fa2
Merge pull request #14 from KirillTrubitsyn/claude/fix-railway-deploy…
KirillTrubitsyn Feb 28, 2026
0e47d06
fix: separate gosu apt-get from python packages to avoid dep conflict
claude Feb 28, 2026
a81754f
Merge pull request #15 from KirillTrubitsyn/claude/fix-railway-deploy…
KirillTrubitsyn Feb 28, 2026
b5d5df6
fix: install requests via pip instead of apt to avoid dep conflicts
claude Feb 28, 2026
f8290d0
Merge pull request #16 from KirillTrubitsyn/claude/fix-railway-deploy…
KirillTrubitsyn Feb 28, 2026
760f635
fix: create TMPDIR before apt-get to unblock ca-certificates
claude Feb 28, 2026
ac2b976
Merge pull request #17 from KirillTrubitsyn/claude/fix-railway-deploy…
KirillTrubitsyn Feb 28, 2026
7f60cf3
fix: reduce system prompt from ~20KB to ~2KB per request
claude Feb 28, 2026
69159f7
fix: trim tool descriptions to reduce API token usage by ~60%
claude Feb 28, 2026
82f87e4
Merge pull request #18 from KirillTrubitsyn/claude/fix-chat-response-…
KirillTrubitsyn Feb 28, 2026
96946b6
fix: reduce unnecessary tool calls for simple questions
claude Feb 28, 2026
baf0f3e
Merge pull request #19 from KirillTrubitsyn/claude/fix-chat-response-…
KirillTrubitsyn Feb 28, 2026
4e2cd28
feat: route nano-banana-pro skill through OpenRouter instead of direc…
claude Feb 28, 2026
d6de137
fix: use google/gemini-3.1-flash-image-preview model for image genera…
claude Feb 28, 2026
9fbdb83
fix: install uv, httpx, and pillow in Docker image
claude Feb 28, 2026
04b2386
fix: correct OpenRouter image generation API format
claude Feb 28, 2026
316a37a
feat: display generated images inline in chat
claude Feb 28, 2026
76817b4
feat: add file click-to-preview in file tree sidebar
claude Feb 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
# === Eggent Configuration ===

# OpenAI (required for default model)
OPENAI_API_KEY=sk-...

# Anthropic (optional)
ANTHROPIC_API_KEY=sk-ant-...

# Google (optional)
GOOGLE_API_KEY=...

# OpenRouter (optional)
# OpenRouter (required — all models route through OpenRouter by default)
OPENROUTER_API_KEY=sk-or-...

# Direct provider keys (optional — only needed if you bypass OpenRouter)
# OPENAI_API_KEY=sk-...
# ANTHROPIC_API_KEY=sk-ant-...
# GOOGLE_API_KEY=...

# Tavily Search (optional - for web search)
TAVILY_API_KEY=tvly-...

Expand Down
32 changes: 20 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ FROM node:22-bookworm-slim AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV HOSTNAME=0.0.0.0
ENV PYTHON_VENV=/opt/eggent-python
ENV PATH="${PYTHON_VENV}/bin:${PATH}"
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
Expand All @@ -24,38 +25,45 @@ ENV PLAYWRIGHT_BROWSERS_PATH=/app/data/ms-playwright
ENV npm_config_cache=/app/data/npm-cache
ENV XDG_CACHE_HOME=/app/data/.cache

RUN mkdir -p "${TMPDIR}" "${PLAYWRIGHT_BROWSERS_PATH}" "${npm_config_cache}" "${XDG_CACHE_HOME}"

RUN apt-get update \
RUN mkdir -p /app/data/tmp \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
bash \
ca-certificates \
curl \
git \
gosu \
jq \
python3 \
python3-requests \
python3-pip \
python3-venv \
sudo \
ripgrep \
&& python3 -m venv --system-site-packages "${PYTHON_VENV}" \
&& "${PYTHON_VENV}/bin/python3" -m pip --version \
&& python3 -m venv "${PYTHON_VENV}" \
&& "${PYTHON_VENV}/bin/pip" install requests httpx pillow \
&& curl -LsSf https://astral.sh/uv/install.sh | env INSTALLER_NO_MODIFY_PATH=1 sh \
&& mv /root/.local/bin/uv /usr/local/bin/uv \
&& mv /root/.local/bin/uvx /usr/local/bin/uvx \
&& rm -rf /var/lib/apt/lists/*

RUN echo "node ALL=(root) NOPASSWD: ALL" > /etc/sudoers.d/eggent-node \
&& chmod 440 /etc/sudoers.d/eggent-node

COPY package.json package-lock.json ./
RUN npm install --omit=dev --no-package-lock

COPY --from=builder /app/.next ./.next
COPY --from=builder /app/next.config.mjs ./next.config.mjs
COPY --from=builder /app/bundled-skills ./bundled-skills
COPY --from=builder /app/src/prompts ./src/prompts

# Only chown /app/data — the sole writable directory at runtime.
# Everything else (node_modules, .next, etc.) is read-only and stays root-owned.
RUN mkdir -p /app/data/tmp /app/data/settings /app/data/projects /app/data/chats \
&& chown -R node:node /app/data

RUN mkdir -p /app/data/tmp /app/data/ms-playwright /app/data/npm-cache /app/data/.cache \
&& chown -R node:node /app "${PYTHON_VENV}"
COPY entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh

USER node
# Start as root so the entrypoint can fix volume permissions, then drop to node
EXPOSE 3000

ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["npm", "run", "start"]
370 changes: 370 additions & 0 deletions EGGENT_PROPOSAL.md

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions _config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Jekyll configuration
# Use lax error mode to prevent Liquid syntax errors from breaking the build
# This is needed because markdown files contain JSX code with {{ }} syntax
liquid:
error_mode: lax

defaults:
- scope:
path: ""
values:
render_with_liquid: false
25 changes: 16 additions & 9 deletions bundled-skills/nano-banana-pro/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
name: nano-banana-pro
description: Generate or edit images via Gemini 3 Pro Image (Nano Banana Pro).
homepage: https://ai.google.dev/
description: Generate or edit images via Gemini 3.1 Flash Image through OpenRouter (Nano Banana Pro).
homepage: https://openrouter.ai/
metadata:
{
"eggent":
{
"emoji": "🍌",
"requires": { "bins": ["uv"], "env": ["GEMINI_API_KEY"] },
"primaryEnv": "GEMINI_API_KEY",
"requires": { "bins": ["uv"], "env": ["OPENROUTER_API_KEY"] },
"primaryEnv": "OPENROUTER_API_KEY",
"install":
[
{
Expand All @@ -23,9 +23,9 @@ metadata:
}
---

# Nano Banana Pro (Gemini 3 Pro Image)
# Nano Banana Pro (Gemini 3.1 Flash Image via OpenRouter)

Use the bundled script to generate or edit images.
Use the bundled script to generate or edit images. Requests are routed through the shared OpenRouter API key instead of a direct Google Gemini key.

Generate

Expand All @@ -45,14 +45,21 @@ Multi-image composition (up to 14 images)
uv run {baseDir}/scripts/generate_image.py --prompt "combine these into one scene" --filename "output.png" -i img1.png -i img2.png -i img3.png
```

Override model (optional)

```bash
uv run {baseDir}/scripts/generate_image.py --prompt "description" --filename "output.png" --model "google/gemini-3.1-flash-image-preview"
```

API key

- `GEMINI_API_KEY` env var
- Or set `skills."nano-banana-pro".apiKey` / `skills."nano-banana-pro".env.GEMINI_API_KEY` in `~/.eggent/eggent.json`
- `OPENROUTER_API_KEY` env var (shared key for all OpenRouter models)
- Or set `skills."nano-banana-pro".apiKey` / `skills."nano-banana-pro".env.OPENROUTER_API_KEY` in `~/.eggent/eggent.json`

Notes

- Resolutions: `1K` (default), `2K`, `4K`.
- Resolutions: `0.5K`, `1K` (default), `2K`, `4K`. (`0.5K` is exclusive to this model.)
- Use timestamps in filenames: `yyyy-mm-dd-hh-mm-ss-name.png`.
- The script prints a `MEDIA:` line for eggent to auto-attach on supported chat providers.
- Do not read the image back; report the saved path only.
- Default model: `google/gemini-3.1-flash-image-preview` (can be overridden with `--model`).
Loading