- TypeScript 96.3%
- Shell 2.3%
- Makefile 1.2%
- Dockerfile 0.2%
| .github/workflows | ||
| data | ||
| docs | ||
| scripts | ||
| src | ||
| .env.example | ||
| .gitignore | ||
| buildenv.sh | ||
| bun.lock | ||
| CLAUDE.md | ||
| Dockerfile | ||
| interview.md | ||
| Makefile | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
Hero Shrimp
Hero Shrimp is a single-user AI agent you can run locally (CLI) and on chat channels (Telegram/WhatsApp), with an admin dashboard and operational recovery tools.
Who It Is For
Use Hero Shrimp if you want:
- one personal agent runtime (not multi-tenant SaaS)
- safe tool execution with
shell_runstill available - memory that survives restarts
- operational controls when things go wrong
What You Can Do
| Job | How | What You Get |
|---|---|---|
| Chat with one agent across channels | CLI, Telegram, WhatsApp | One consistent session and behavior |
| Run tools safely | Built-in policy + shell guards | Fewer dangerous commands, clearer failures |
| Keep long-term context | Memory + retrieval pipeline | Better continuity across conversations |
| Route easy vs hard requests to different models | Configurable LLM routing | Lower cost on simple work, stronger models on complex work |
| Use skills more reliably | Ranked skill routing + eligibility + usage stats | Better skill selection and easier debugging |
| Operate reliably | doctor commands + dashboard |
Recovery actions without manual DB edits |
| Observe runtime health | /api/doctor, /api/runtime, SSE |
Fast diagnosis of queue/memory/outbox state |
5-Minute Quick Start
cp .env.example .env
# set at least OPENROUTER_API_KEYS or AIBROKER_API_ENDPOINT
make install
hero_shrimp
Run from source:
make dev
One-shot CLI runs:
bun run src/index.ts --prompt "reply exactly TEST_OK"
printf 'reply exactly STDIN_OK\n' | bun run src/index.ts --prompt-stdin
bun run src/index.ts --prompt "reply exactly JSON_OK" --json
Use one-shot mode when you want logs, a single answer, and process exit without interactive readline.
Daily Operations (Copy/Paste)
Health check:
bun run doctor
Maintenance pruning:
bun run doctor:maintenance
Export/import memory snapshot:
bun run doctor:snapshot:export
bun run doctor:snapshot:import
bun run doctor:snapshot:import -- --replace
Recover outbox issues:
bun run doctor:outbox:recover
bun run doctor:outbox:replay-dead -- --limit=500
bun run doctor:outbox:drain -- --limit=200
Channels
| Channel | Enable | Notes |
|---|---|---|
| CLI | CHANNEL=cli (default) |
interactive local runtime |
| Telegram | ENABLE_TELEGRAM=true |
requires TELEGRAM_TOKEN, TELEGRAM_ALLOWED_USERS |
ENABLE_WHATSAPP=true |
QR bootstrap on first run | |
| Admin UI | ENABLE_ADMIN=true |
http://localhost:3131 |
What to Expect (Behavior Guarantees)
- Duplicate inbound messages reuse the same response (idempotent replay).
- Concurrent duplicate events are joined into one execution.
- Transient inbound failures are retried with backoff.
- Startup runs recovery checks and can recover stuck outbox work.
- Runtime maintenance prunes retention data on a schedule.
- Unhealthy channels can be restarted by watchdog logic.
Limits (Important)
- Single-user runtime by design.
- Not a multi-tenant control plane.
- WhatsApp support requires Bun runtime or Docker; compiled binary mode is limited.
Essential Configuration
LLM backend (required):
OPENROUTER_API_KEYS=sk-or-...
SHRIMP_OPENROUTER_MODELS=google/gemini-3-flash-preview,anthropic/claude-haiku-4.5,openai/gpt-4o-mini
or
AIBROKER_API_ENDPOINT=http://localhost:8080
SHRIMP_AIBROKER_MODELS=gemini-3-flash-preview,claude-haiku-4.5,gpt-4o-mini
What you can ignore:
- If you only use CLI, ignore Telegram and WhatsApp settings.
- If you do not use voice, ignore
GROQ_API_KEY,SAMBANOVA_API_KEY, andOPENAI_API_KEY. - If you do not use external news/weather/search tools, ignore
NEWS_API_KEY,WEATHER_API_KEY, andSEARCH_API_KEY. - If you are not running a broker, ignore
AIBROKER_API_ENDPOINT,SHRIMP_AIBROKER_MODELS, andMCP_BROKER_ENDPOINT. - If you are not tuning operations, leave the
SHRIMP_*maintenance/memory/watchdog knobs at their defaults.
Common runtime knobs:
AGENT_NAME=HeroShrimp
SAFETY_LEVEL=standard
ENABLE_ADMIN=true
ADMIN_PORT=3131
SESSION_NAME=default
SHRIMP_TOOL_ALLOWLIST=
SHRIMP_TOOL_DENYLIST=
SHRIMP_MEMORY_PIPELINE_ROLLOUT_MODE=on
SHRIMP_MEMORY_PIPELINE_CANARY_PERCENT=100
SHRIMP_MAINTENANCE_ENABLED=true
SHRIMP_MAINTENANCE_INTERVAL_MS=21600000
SHRIMP_DOCTOR_MAINTENANCE_STALE_HOURS=12
SHRIMP_DOCTOR_OUTBOX_MAX_DEAD=0
SHRIMP_DOCTOR_OUTBOX_MAX_PENDING_AGE_SECONDS=1800
SHRIMP_DOCTOR_OUTBOX_MAX_PROCESSING_AGE_SECONDS=600
SHRIMP_LLM_ROUTING_ENABLED=true
SHRIMP_LLM_ROUTING_SIMPLE_MODEL=
SHRIMP_LLM_ROUTING_STANDARD_MODEL=
SHRIMP_LLM_ROUTING_COMPLEX_MODEL=
SHRIMP_LLM_ROUTING_TRIAGE_MODEL=
SHRIMP_LLM_ROUTING_QUICK_MODEL=
SHRIMP_LLM_ROUTING_SUBAGENT_MODEL=
SHRIMP_LLM_ROUTING_MEMORY_MODEL=
SHRIMP_LLM_ROUTING_SKILL_MODEL=
Model routing:
triage,quick, andmemoryphases can use lighter models.agentandsubagentphases can use stronger models for harder work.- If phase-specific overrides are not set, HeroShrimp falls back to simple/standard/complex routing heuristics.
- If a routed model fails, normal fallback models are still tried afterward.
Example routing setup:
SHRIMP_LLM_ROUTING_ENABLED=true
SHRIMP_LLM_ROUTING_SIMPLE_MODEL=anthropic/claude-haiku-4.5
SHRIMP_LLM_ROUTING_STANDARD_MODEL=google/gemini-3-flash-preview
SHRIMP_LLM_ROUTING_COMPLEX_MODEL=anthropic/claude-sonnet-4-20250514
SHRIMP_LLM_ROUTING_TRIAGE_MODEL=anthropic/claude-haiku-4.5
SHRIMP_LLM_ROUTING_SUBAGENT_MODEL=anthropic/claude-sonnet-4-20250514
Current routed phases:
triage: message classificationquick: short direct tasks such as simple answers or translationagent: main multi-step agent loopsubagent: delegated focused executionmemory: auto-memory extractionskill: markdown-skill execution
Optional workspace policy:
$SHRIMP_WORKSPACE_DIR/.agent/policy.json
{
"tools": {
"allow": ["file_read", "manage_memory", "shell_run"],
"deny": ["file_delete"]
}
}
Skill directories are loaded recursively in this order (first wins on name collisions):
SHRIMP_SKILLS_DIR(or default workspace skills dir)~/.agents/skills~/.agents
SKILL.md files in nested subfolders are discovered automatically.
Environment Reference
This section documents every runtime env var currently used by Hero Shrimp.
LLM backend and model selection
| Env Var | Default | Role |
|---|---|---|
OPENROUTER_API_KEYS |
empty | Comma-separated OpenRouter API keys. Preferred direct provider configuration. |
OPENROUTER_API_KEY |
empty | Legacy single-key form. Used only if OPENROUTER_API_KEYS is empty. |
SHRIMP_OPENROUTER_MODELS |
empty | Comma-separated OpenRouter model order. First is primary, rest are fallbacks. |
LLM_MODEL |
anthropic/claude-sonnet-4-20250514 |
Compatibility fallback primary model if SHRIMP_OPENROUTER_MODELS is not set. |
LLM_FALLBACK_MODELS |
empty | Compatibility fallback model list if SHRIMP_OPENROUTER_MODELS is not set. |
LLM_BASE_URL |
https://openrouter.ai/api/v1 |
Base URL for direct LLM requests. |
LLM_MAX_TOKENS |
4096 |
Max completion tokens requested from the LLM. |
LLM_TEMPERATURE |
0.7 |
Sampling temperature for model responses. |
SHRIMP_LLM_TIMEOUT_MS |
120000 |
Per-request LLM timeout in milliseconds. |
SHRIMP_LLM_MAX_RETRIES |
3 |
Max retry attempts for failed LLM requests. |
SHRIMP_LLM_ROUTING_ENABLED |
true |
Enables phase-based primary model routing. |
SHRIMP_LLM_ROUTING_SIMPLE_MODEL |
empty | Default model for low-complexity turns when routing is enabled. |
SHRIMP_LLM_ROUTING_STANDARD_MODEL |
empty | Default model for normal-complexity turns when routing is enabled. |
SHRIMP_LLM_ROUTING_COMPLEX_MODEL |
empty | Default model for higher-complexity turns when routing is enabled. |
SHRIMP_LLM_ROUTING_TRIAGE_MODEL |
empty | Explicit override for the triage phase. |
SHRIMP_LLM_ROUTING_QUICK_MODEL |
empty | Explicit override for the quick phase. |
SHRIMP_LLM_ROUTING_SUBAGENT_MODEL |
empty | Explicit override for the subagent phase. |
SHRIMP_LLM_ROUTING_MEMORY_MODEL |
empty | Explicit override for the memory phase. |
SHRIMP_LLM_ROUTING_SKILL_MODEL |
empty | Explicit override for the skill phase. |
SHRIMP_LLM_ROUTING_SIMPLE_MAX_CHARS |
280 |
Input-size threshold used by routing heuristics for simple requests. |
SHRIMP_LLM_ROUTING_COMPLEX_MIN_CHARS |
1200 |
Input-size threshold used by routing heuristics for complex requests. |
AIBROKER_API_ENDPOINT |
empty | Optional AI Broker endpoint. If set, Hero Shrimp can route through the broker instead of direct OpenRouter only. |
SHRIMP_AIBROKER_MODELS |
empty | Ordered AI Broker model list. First is primary, rest are follow-on choices. |
Agent behavior and execution limits
| Env Var | Default | Role |
|---|---|---|
AGENT_NAME |
HeroShrimp |
Display/system name used by the runtime. |
SAFETY_LEVEL |
standard |
Maximum allowed tool safety level: strict, standard, or relaxed. |
SHRIMP_MAX_ITERATIONS |
100 |
Soft cap for main agent loop iterations. |
SHRIMP_MAX_ITERATIONS_HARD |
200 |
Hard cap for main agent loop iterations. |
SHRIMP_MAX_TOOL_OUTPUT |
16000 |
Max stored/returned tool output characters before truncation. |
SHRIMP_MAX_SUBAGENT_OUTPUT |
8000 |
Max subagent output characters before truncation. |
SHRIMP_MAX_SUBAGENT_ITERATIONS |
15 |
Max iterations for delegated subagents. |
SHRIMP_MAX_TOOL_CALLS_PER_ITERATION |
4 |
Max tool calls allowed in one agent iteration. |
SHRIMP_MAX_PARALLEL_TOOL_CALLS |
4 |
Max concurrent tool executions within allowed parallel flows. |
SHRIMP_HISTORY_LIMIT |
50 |
Number of prior conversation items kept in prompt history. |
Channels and admin
| Env Var | Default | Role |
|---|---|---|
CHANNEL |
cli |
Primary channel mode for local startup. |
ENABLE_TELEGRAM |
false |
Enables Telegram channel startup. |
TELEGRAM_TOKEN |
empty | Telegram bot token from BotFather. Required if Telegram is enabled. |
TELEGRAM_ALLOWED_USERS |
empty | Comma-separated Telegram user IDs allowed to interact with the bot. |
ENABLE_WHATSAPP |
false |
Enables WhatsApp channel startup. |
ENABLE_ADMIN |
false |
Enables the admin dashboard and admin API server. |
ADMIN_PORT |
3131 |
Admin HTTP server port. |
ADMIN_TOKEN |
empty | Optional admin API token if you want to gate dashboard/API access. |
Voice and optional external providers
| Env Var | Default | Role |
|---|---|---|
WHISPER_PROVIDER |
groq |
Voice/STT provider selection: groq, sambanova, or openai. |
GROQ_API_KEY |
empty | API key for Groq-backed voice/STT flows. |
SAMBANOVA_API_KEY |
empty | API key for SambaNova-backed voice/STT flows. |
OPENAI_API_KEY |
empty | API key for OpenAI-backed voice/STT flows. |
MCP_BROKER_ENDPOINT |
empty | MCP broker endpoint used for remote MCP tool discovery. |
MCP_BROKER_URL |
empty | Compatibility alias for MCP_BROKER_ENDPOINT. |
SEARCH_API_KEY |
empty | API key for web search tooling if configured. |
SEARCH_ENGINE |
google |
Search engine identifier used by search tooling. |
WEATHER_API_KEY |
empty | API key for weather tool support. |
NEWS_API_KEY |
empty | API key for news tool support. |
GITHUB_TOKEN |
empty | Optional token used by GitHub-related integrations/tools. |
Paths and persisted state
| Env Var | Default | Role |
|---|---|---|
SESSION_NAME |
default |
Session name used to derive the SQLite DB filename. |
SHRIMP_DATA_DIR |
~/hero/var/shrimp |
Primary data directory for DB and runtime state. |
DATA_DIR |
~/hero/var/shrimp |
Compatibility alias used if SHRIMP_DATA_DIR is unset. |
SHRIMP_WORKSPACE_DIR |
~/hero/var/shrimp/workspace |
Workspace directory for files, policies, snapshots, and local state. |
WORKSPACE_DIR |
~/hero/var/shrimp/workspace |
Compatibility alias used if SHRIMP_WORKSPACE_DIR is unset. |
SHRIMP_SKILLS_DIR |
${workspaceDir}/skills |
Primary workspace skill root. |
SKILLS_DIR |
${workspaceDir}/skills |
Compatibility alias used if SHRIMP_SKILLS_DIR is unset. |
SHRIMP_PLUGINS_DIR |
${workspaceDir}/plugins |
Workspace plugin directory. |
Queueing, inbound reliability, and request flow
| Env Var | Default | Role |
|---|---|---|
SHRIMP_MAX_CONCURRENT |
10 |
Queue concurrency limit for in-flight work. |
SHRIMP_REQUEST_TIMEOUT_MS |
300000 |
Global request timeout in milliseconds. |
SHRIMP_INBOUND_RETRY_MAX |
2 |
Max retries for transient inbound-processing failures. |
SHRIMP_INBOUND_RETRY_BASE_DELAY_MS |
1000 |
Base retry delay for inbound retry backoff. |
SHRIMP_INBOUND_MAX_CHARS |
20000 |
Max inbound message size before normalization/truncation. |
Retention, maintenance, and doctor checks
| Env Var | Default | Role |
|---|---|---|
SHRIMP_RETENTION_MESSAGES_DAYS |
30 |
Retention window for conversation messages. |
SHRIMP_RETENTION_AUDIT_DAYS |
30 |
Retention window for audit logs. |
SHRIMP_RETENTION_USAGE_DAYS |
90 |
Retention window for usage logs. |
SHRIMP_RETENTION_INBOUND_DEDUP_DAYS |
7 |
Retention window for inbound dedup cache rows. |
SHRIMP_RETENTION_TASK_STATE_DAYS |
14 |
Retention window for persisted task-state files. |
SHRIMP_RETENTION_MEMORY_OUTBOX_DAYS |
30 |
Retention window for aged outbox rows. |
SHRIMP_MAINTENANCE_ENABLED |
true |
Enables periodic runtime maintenance loop. |
SHRIMP_MAINTENANCE_INTERVAL_MS |
21600000 |
Interval between maintenance runs in milliseconds. |
SHRIMP_DOCTOR_MAINTENANCE_STALE_HOURS |
12 |
How old maintenance can be before doctor reports it stale. |
SHRIMP_STARTUP_RECOVER_OUTBOX_PROCESSING |
true |
Repairs stuck memory_outbox rows at startup. |
SHRIMP_DOCTOR_OUTBOX_MAX_DEAD |
0 |
Max tolerated dead-letter outbox rows before doctor fails. |
SHRIMP_DOCTOR_OUTBOX_MAX_PENDING_AGE_SECONDS |
1800 |
Max age for oldest pending outbox row before doctor fails. |
SHRIMP_DOCTOR_OUTBOX_MAX_PROCESSING_AGE_SECONDS |
600 |
Max age for oldest processing outbox row before doctor fails. |
Memory lifecycle and retrieval
| Env Var | Default | Role |
|---|---|---|
SHRIMP_MEMORY_DEFAULT_TTL_DAYS |
180 |
Default TTL for manually saved memory rows. |
SHRIMP_MEMORY_AUTO_TTL_DAYS |
90 |
Default TTL for auto-extracted memory rows. |
SHRIMP_MEMORY_OUTBOX_BATCH_SIZE |
20 |
Batch size for memory outbox worker processing. |
SHRIMP_MEMORY_OUTBOX_POLL_MS |
15000 |
Poll interval for memory outbox worker. |
SHRIMP_MEMORY_OUTBOX_MAX_ATTEMPTS |
5 |
Max retry attempts for memory outbox events. |
SHRIMP_MEMORY_OUTBOX_RETRY_BASE_SECONDS |
30 |
Base retry delay for outbox backoff. |
SHRIMP_MEMORY_OUTBOX_RETRY_MAX_SECONDS |
900 |
Max retry delay for outbox backoff. |
SHRIMP_MEMORY_PIPELINE_ROLLOUT_MODE |
on |
Retrieval pipeline rollout mode: off, shadow, canary, or on. |
SHRIMP_MEMORY_PIPELINE_CANARY_PERCENT |
100 |
Canary percentage when rollout mode is canary. |
SHRIMP_MEMORY_COMPACTION_ENABLED |
true |
Enables memory compaction/summarization when categories grow large. |
SHRIMP_MEMORY_COMPACTION_MAX_PER_USER_CATEGORY |
120 |
Per-user/category threshold that triggers compaction. |
SHRIMP_MEMORY_COMPACTION_KEEP_RECENT |
80 |
Number of recent rows preserved before compaction deletes older rows. |
SHRIMP_MEMORY_COMPACTION_BATCH_DELETE |
40 |
Max old memory rows deleted in one compaction pass. |
SHRIMP_MEMORY_COMPACTION_SUMMARY_MAX_CHARS |
2000 |
Max size of generated compaction summary text. |
SHRIMP_MEMORY_PIPELINE_ENABLE_QUERY_EXPANSION |
true |
Enables query expansion during memory retrieval. |
SHRIMP_MEMORY_PIPELINE_ENABLE_TEMPORAL_DECAY |
true |
Enables recency/access decay weighting during retrieval. |
SHRIMP_MEMORY_PIPELINE_ENABLE_CATEGORY_DIVERSITY |
true |
Enables category diversity capping during retrieval. |
SHRIMP_MEMORY_PIPELINE_MIN_SCORE |
0.25 |
Minimum retrieval score required for memory inclusion. |
SHRIMP_MEMORY_PIPELINE_PER_CATEGORY_CAP |
4 |
Max retrieved memories per category in diversity mode. |
Channel supervision, logging, and policy
| Env Var | Default | Role |
|---|---|---|
SHRIMP_CHANNEL_START_MAX_RETRIES |
5 |
Max startup retries for a failing channel. |
SHRIMP_CHANNEL_START_RETRY_BASE_MS |
1000 |
Base delay for channel startup retry backoff. |
SHRIMP_CHANNEL_WATCHDOG_ENABLED |
true |
Enables periodic channel watchdog checks. |
SHRIMP_CHANNEL_WATCHDOG_INTERVAL_MS |
60000 |
Interval between watchdog checks. |
LOG_LEVEL |
debug |
Runtime log verbosity: debug, info, warn, error. |
AUDIT_ENABLED |
true |
Enables audit logging for tool actions and runtime events. |
SHRIMP_TOOL_ALLOWLIST |
empty | Comma-separated explicit tool allowlist. If set, only listed tools are allowed unless policy expands access. |
SHRIMP_TOOL_DENYLIST |
empty | Comma-separated explicit tool denylist. Listed tools are blocked even if otherwise available. |
Recommended minimal setup
For a normal single-user local setup, you usually only need:
OPENROUTER_API_KEYS=...
SHRIMP_OPENROUTER_MODELS=google/gemini-3-flash-preview,anthropic/claude-haiku-4.5
ENABLE_ADMIN=true
CHANNEL=cli
Everything else can stay at defaults until you have a reason to tune it.
Admin API Quick Reference
| Endpoint | Purpose |
|---|---|
GET /api/stats |
high-level counters |
GET /api/messages |
conversation history |
GET /api/audit |
tool execution log |
GET /api/usage |
token usage |
GET /api/memories |
stored memory rows |
GET /api/jobs |
scheduled jobs |
GET /api/config |
active runtime config |
GET /api/doctor |
health/maintenance/recovery actions |
GET /api/runtime |
routing/skills/pipeline/outbox/supervisor/maintenance stats |
GET /api/events |
live SSE stream |
Examples:
curl http://localhost:3131/api/doctor?action=health
curl "http://localhost:3131/api/doctor?action=outbox_replay_dead&limit=500"
curl http://localhost:3131/api/runtime
Docker
docker build -t hero-shrimp .
docker run --env-file .env -p 3131:3131 -it hero-shrimp
Development
make install
make build
make dev
make run
make check
make test
make binary
make clean
make help
Documentation Map
- Deep internals:
docs/internals.md - Architecture overview:
docs/architecture.md - Database schema:
docs/database.md - Plugins:
docs/plugins.md - Tools:
docs/tools.md
License
MIT