Agent Overview
Mental Model: Message to Response
When a user sends a Telegram message, here is exactly what happens:
YOU (Telegram app)
|
| "What tools do you have?"
v
TELEGRAM SERVERS (cloud)
|
| Long-polling (grammy library pulls updates)
v
DOCKER CONTAINER: hollanov
on openclaw-vps-1 (Hostinger VPS, Boston, 76.13.100.227)
|
| src/channels/telegram.ts receives the Update object
| Checks TELEGRAM_ALLOWED_USERS — rejects if not on allowlist
v
AGENT LOOP (src/agent/loop.ts)
|
| 1. Budget check
| BudgetTracker.check() — "do I have tokens/turns left?"
| If no -> stop with "budget exceeded"
|
| 2. Context assembly
| ContextAssembler builds the full prompt:
| - System prompt (personality, tool descriptions, session state)
| - Memory fragments (persistent memories scored by relevance)
| - Conversation history (compacted if getting long)
| - The user's new message
|
| 3. Claude API call
| Anthropic SDK -> api.anthropic.com (HTTPS)
| Sends: system prompt + messages + tool definitions
| Model: claude-sonnet-4-20250514 (configurable via HOLLANOV_MODEL)
v
CLAUDE (Anthropic's servers)
|
| Returns: text response + optional tool_use blocks
v
AGENT LOOP (back on VPS)
|
| 4. Tool execution (if Claude requested tool use)
| a. Permission pipeline — 6 stages:
| deny list -> pre-approved -> read-only auto-approve
| -> destructive detection -> SSH safety -> trust tier
| -> fallback deny
| b. If granted: ToolRegistry.execute()
| shell.ts runs the actual command
| (e.g. `just agent-test`, or `ssh openclaw-vps-1 docker ps`)
| c. Tool result sent back to Claude -> goto step 3 (multi-round)
|
| 5. Final response (no more tool calls)
| a. BudgetTracker.record() — log actual token usage
| b. CostTracker.record() — log dollar cost to ~/.openclaw/cost/
| c. SessionManager.persist() — save to ~/.openclaw/sessions/
| d. SystemLogger.log() — write JSONL to ~/.openclaw/logs/
v
TELEGRAM CHANNEL (src/channels/telegram.ts)
|
| Sends reply via grammy -> Telegram Bot API
v
TELEGRAM SERVERS -> YOUR PHONE
|
"Here are my 32 registered tools: ..."
Key concepts
- OpenClaw is the project/repo name. It is not a running service.
- Hollanov is the custom agent runtime (the TypeScript app in
src/agent/). This is what actually runs inside thehollanovDocker container. - Ilya is a separate container (
openclaw-gateway) running the Hostinger-provided OpenClaw gateway with its own AI. It handles WhatsApp and does not use the Hollanov runtime. - The harness is the agent loop + all supporting modules (permissions, budget, memory, sessions, streaming, logging). grammy handles the Telegram protocol; the harness handles everything else.
- All operations (testing, deployment, VPS management, docs) are initiated through
justrecipes. Runjust --listfor the full catalog.
Where it runs
Everything from "DOCKER CONTAINER" down in the diagram runs on openclaw-vps-1 — a Hostinger KVM 2 VPS in Boston. The Docker container starts via systemd on boot. Secrets are injected by 1Password's op run at startup and never touch disk.
Development environments
| Environment | Network | Secrets | VPS Access | Setup |
|---|---|---|---|---|
| Mac (local) | Unrestricted | 1Password desktop + varlock | SSH via 1Password agent | just setup |
| Claude Code web | Egress proxy (needs allowlist config) | Project env vars | SSH via env var key or generated key | just setup-web |
| CI runner | Typically unrestricted | GitHub secrets / env vars | SSH via env var key | just vps-setup-web |
For Claude Code web setup details, see Developer Setup — Claude Code Web Environment.
What We Built
Agent Runtime (src/agent/ — 19 modules + 4 tool modules)
A complete AI agent engine in TypeScript. Every piece is tested and wired together.
Core pipeline:
- Tool Registry — 34 tools registered with metadata (name, permissions, risk profile, tags). Query without executing.
- Permission System — 6-stage pipeline: deny list, pre-approved, read-only auto-approve, destructive detection, SSH safety, trust tiers, fallback deny. Every decision logged.
- Agent Loop — User message in, budget pre-check, Claude API call, tool execution (with permission gate), stream response, persist session. Handles multi-round tool use automatically.
- Session Persistence — Full state saved to
~/.openclaw/sessions/after every turn. Resume where you left off.
Budget and observability:
- Token Budget — Pre-turn checks halt before spending. Default 500K tokens / 50 turns per session.
- Event Stream — Typed events:
tool_selected,permission_check,message_delta,message_stopwith stop reason. - System Logger — JSONL at
~/.openclaw/logs/. Categories: init, registry, permission, execution, session, error. - Audit Trail — Every permission decision queryable by tool, time, outcome.
Advanced:
- Workflow Manager — Multi-step operations with checkpoints, idempotency keys, crash recovery.
- Agent Types — 5 constrained roles (explore, plan, verification, general-purpose, deploy) with allowed/denied tool patterns.
- Memory System — Persistent + session memory with provenance tracking, relevance scoring (age decay, access frequency, validation recency).
- Skills — Load from
.claude/skills/*/SKILL.md, register as tools. - Hooks — Before/after pipeline on tool execution, turns, sessions, permissions.
- Context Assembly — Provenance-aware fragments with trust levels and token budgets.
- Compaction — Summarize old messages to manage context size.
- Doctor — Health checks (Node, gh, op, just, shellcheck).
- Verification — 5 safety invariants that must always hold.
Tools (src/tools/ — 24 registered)
| Category | Tools |
|---|---|
| VPS | vps-list, vps-add, vps-new, vps-provision, vps-destroy |
| Docs | docs-build, docs-deploy |
| Git | pr-create, pr-merge |
| Quality | lint-sh, lint-md, lint |
| Agent | agent-test, agent-typecheck, agent-doctor, agent-verify |
| Memory | memory-store, memory-recall |
| Web | web-search |
| Skills | skill-coderabbit, skill-deploy, skill-new-doc, skill-status, skill-vps |
Channels
Two AI assistants run on openclaw-vps-1:
| Name | Container | Channel | What It Is |
|---|---|---|---|
| Hollanov | hollanov | Telegram @illyarozenovbot | Our custom runtime — 34 tools, permissions, memory, sessions |
| Ilya | openclaw-gateway | WhatsApp +15089811893 | Hostinger OpenClaw gateway — default personality |
Voice responses: When
ELEVENLABS_API_KEYandELEVENLABS_VOICE_IDare set, Hollanov sends short conversational replies (20-2000 chars, no code blocks/tables) as Telegram voice messages alongside text, using the Ilya Rozenov voice. TTS failures fall back to text-only.
Deployment
- Hollanov:
just bot-deploy(git pull + rebuild container). Auto-deploys via webhook on push. - Ilya:
just gateway-start/just gateway-stop - Systemd:
openclaw-secrets.servicestarts Hollanov on boot
Tests
373 tests across 27 files, all passing. Covers every module.
How to Test
1. Telegram (live, deployed)
Message @illyarozenovbot on Telegram. Try:
- "What tools do you have?" — lists all 34 tools
- "Run the agent tests" — executes
just agent-test, reports results - "List my VPS instances" — runs
vps-list - /tools — see all tools with risk indicators
- /budget — check token usage
- /reset — start fresh session
2. Local CLI (interactive REPL)
ANTHROPIC_API_KEY=$(op item get "Anthropic API Key" \
--vault="Shared-Infrastructure" --fields credential --reveal) just agent-run
Then type messages. Commands: /tools, /session, /budget, /quit.
3. Local bot (runs Telegram bot from your Mac)
just bot-run-op
4. Run tests
just agent-test # 373 tests
just agent-verify # 5 safety invariants
just agent-doctor # system health check
just agent-typecheck # TypeScript types
5. Check deployed bot
just bot-logs # recent logs
just vps-exec "docker ps" # container status
Project Structure
src/
agent/
registry.ts permissions.ts session.ts
workflow.ts budget.ts stream.ts
logger.ts audit.ts compaction.ts
context.ts agents.ts memory.ts
skills.ts hooks.ts loop.ts
doctor.ts verify.ts boot.ts
utils.ts
tools/
definitions.ts register.ts shell.ts
channels/
telegram.ts
cli/
agent.ts telegram.ts doctor.ts verify.ts
types/
index.ts
index.ts
deploy/
.env.gateway.tpl start.sh start-gateway.sh
.env.schema Dockerfile docker-compose.yml
All Commands
| Command | What It Does |
|---|---|
just agent-run | Start the interactive agent REPL |
just agent-test | Run all 373 tests |
just agent-verify | Verify 5 safety invariants |
just agent-doctor | System health check |
just agent-typecheck | TypeScript type checking |
just agent-build | Compile TypeScript to dist/ |
just bot-run | Run Telegram bot locally |
just bot-run-op | Run Telegram bot locally with 1Password secrets |
just bot-deploy | Deploy bot to VPS (git pull + rebuild) |