Skip to main content

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 the hollanov Docker 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 just recipes. Run just --list for 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

EnvironmentNetworkSecretsVPS AccessSetup
Mac (local)Unrestricted1Password desktop + varlockSSH via 1Password agentjust setup
Claude Code webEgress proxy (needs allowlist config)Project env varsSSH via env var key or generated keyjust setup-web
CI runnerTypically unrestrictedGitHub secrets / env varsSSH via env var keyjust 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_stop with 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)

CategoryTools
VPSvps-list, vps-add, vps-new, vps-provision, vps-destroy
Docsdocs-build, docs-deploy
Gitpr-create, pr-merge
Qualitylint-sh, lint-md, lint
Agentagent-test, agent-typecheck, agent-doctor, agent-verify
Memorymemory-store, memory-recall
Webweb-search
Skillsskill-coderabbit, skill-deploy, skill-new-doc, skill-status, skill-vps

Channels

Two AI assistants run on openclaw-vps-1:

NameContainerChannelWhat It Is
HollanovhollanovTelegram @illyarozenovbotOur custom runtime — 34 tools, permissions, memory, sessions
Ilyaopenclaw-gatewayWhatsApp +15089811893Hostinger OpenClaw gateway — default personality

Voice responses: When ELEVENLABS_API_KEY and ELEVENLABS_VOICE_ID are 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.service starts 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

CommandWhat It Does
just agent-runStart the interactive agent REPL
just agent-testRun all 373 tests
just agent-verifyVerify 5 safety invariants
just agent-doctorSystem health check
just agent-typecheckTypeScript type checking
just agent-buildCompile TypeScript to dist/
just bot-runRun Telegram bot locally
just bot-run-opRun Telegram bot locally with 1Password secrets
just bot-deployDeploy bot to VPS (git pull + rebuild)