Skip to content
SIGPULSE
AI & Compute 3 min read raw .md ↗

What Does It Take to Give a Chat AI Nine Tools and Your Home Directory? A 50-Line Bot That Grew to 850

● PROOF OF EXECUTION Workstation-hosted Python bot under a systemd user unit (5 s crash restart) · GLM-5.2 via the Anthropic-protocol-compatible endpoint · line counts from the source, log count from bot.log · Tested 2026-08-27 · Configs published for replication

Key Takeaways — Executive & AI Summary

  • The chat gateway that hands an AI real tools is 850 lines of Python today and started near 50 — the 800-line delta is almost entirely security and robustness added after real failures: a jailed work directory with prefix-spoof protection, a dangerous-command blocklist (rm -rf, sudo, mkfs, dd of=), exact-match edits, and path-fallback reads (source + README, 2026-08).
  • The bot exposes nine tools to GLM-5.2 — read_file, glob, grep, edit, write_file, exec_command, web_search, web_fetch, rss_fetch — inside a 15-iteration tool loop, so a single chat message can chain a full investigate-edit-test sequence (source, 2026-08).
  • Usage scale: one whitelisted human, 168,996 log lines — and the log's tail is a live server-disconnect NetworkError, a fair sample of what 'reliable' looks like at personal scale: crash-restart hygiene matters more than uptime claims (bot.log, 2026-08).

Episode 2 of One Man One Legion, opening the cockpit arc. Episode 16 tells where this bot’s supervision lessons migrated next; the map holds the series together.

Every legion needs a doorway. This one is a Telegram bot: type a message, GLM-5.2 thinks, and nine tools execute on a real Linux home directory — read, grep, edit, write, run commands, search and fetch the web, pull RSS. The README still calls it “~50 lines of code,” and that was true once. The file on disk today is 850 lines, and the difference between those two numbers is the actual story of this episode: what it costs, in code, to let a chat model touch your filesystem without regretting it.

The premise: one protocol, one credential, one chat window

The bot speaks the Anthropic protocol to a GLM-5.2 endpoint — the same coding-plan credential a Claude Code CLI uses, so the “brain” is a cloud model billed like a coding assistant, not a bespoke integration. A chat message becomes a tool loop: the model may chain up to 15 tool iterations per turn, which is what lets “find the failing test and fix it” run as read → grep → edit → exec → read, unattended. The nine tools:

ToolGuard behavior
read_fileWrong path falls back to a filename search instead of erroring out
glob / grepBounded result sizes
editExact-match old_string required — no whole-file rewrites
write_fileJailed to the work directory
exec_commandBlocklist: rm -rf, sudo, mkfs, dd of= intercepted
web_search / web_fetch / rss_fetchRead-only externals, capped output

The 800 lines that grew after the failures

The README’s own section header for all of this is “safety and robustness — added gradually, after stepping in holes.” What got added, and why each exists:

  • The work-directory jail, with prefix-spoof protection. Every file tool refuses paths outside one directory — including /home/user-evil-style prefixes that would textually pass a naive startswith check. The check resolves real boundaries, not string prefixes.
  • The dangerous-command blocklist. The model mostly proposes reasonable commands; the one time it doesn’t, interception is cheap and a restore from a bad rm is not.
  • Exact-match edits. Early versions let the model rewrite whole files, which converted small mistakes into large ones. Forcing “point at exactly this string” keeps blast radius proportional to intent.
  • Path fallback on reads. A wrong path used to stall the loop with an error the model would then narrate instead of fixing. Now the tool searches by filename and hands back something usable.

The philosophy line in the README could have been lifted from the mini-agent docs of episode 16: tolerant tools, bounded environment — the brain is the model’s; how much of it you actually get is the harness. The two projects traded lessons in both directions — the bot’s dead-process incident (found 14 hours after exit) is what taught the daemon-first diagnostic habit that the mini-agent later inherited as step one.

Operations: what “reliable” means at personal scale

The bot runs as a systemd user unit: 5-second crash restart, lingering enabled so it survives without a login session. Its log has grown to 168,996 lines — and the honest detail worth publishing is that the log’s tail is a live NetworkError: server disconnected trace. At personal scale, “reliable” is not the absence of failures; it is crash-restart hygiene plus a log you can actually read. No uptime claims are made here — the evidence would laugh.

What we claim and what we don’t

Line counts and tool lists are from the source on disk (850 lines, 9 tools, 15-iteration cap, 5-second restart). The “~50-line origin” is the README’s own account of the starting point, not an independently reconstructable measurement. The log-line count measures chatter, not messages or tasks — no throughput is claimed. One whitelisted user, by design: this is a personal gateway, not a service.

Primary sources: bot.py (850 lines, tool definitions and guards as cited), the project README (origin narrative, design philosophy), and bot.log (168,996 lines incl. the terminal NetworkError), 2026-08.

Measured 2026-08-27 from source and logs. License: CC BY 4.0 — cite the source URL.

Next in the cockpit arc: the runtime this bot’s philosophy grew into — twelve chat groups, trigger words, and a scheduler that once ran 22 jobs. Back to the series map.

FAQ — Direct Answers

How do you let an AI agent safely run commands on your machine over Telegram?
Three layers in this bot: every file operation is jailed to one work directory (with a prefix-spoof check so /home/user-evil can't impersonate /home/user), a blocklist intercepts dangerous commands like rm -rf, sudo, mkfs and dd of=, and tool iterations cap at 15 so a confused model can't loop forever. The AI never touches the host directly — the bot executes everything on its behalf.
How many tools does a useful AI chat bot need?
Nine, in this deployment: read_file, glob, grep, edit, write_file for files; exec_command for shell; web_search, web_fetch for the web; rss_fetch for feeds. That is enough for a chat message like 'find the failing test and fix it' to chain reads, an exact edit, and a test run in one conversation.
Why did a 50-line bot grow to 850 lines?
Because the first 50 lines were the happy path and the next 800 were reality: wrong paths, forbidden commands, sloppy whole-file rewrites, models stalling on errors. Each failure mode became a tool-level guard — tolerant tools, bounded environment, in the README's own words. The brain came from the model provider; everything the brain can't be trusted with became code.
What model powers the bot, and what happens when it fails?
GLM-5.2 through the Anthropic-protocol-compatible endpoint — the same coding-plan credential a Claude Code CLI would use. On failure the bot itself is wrapped by a systemd user unit with a 5-second crash restart, so a dead process (the failure mode that once took a manual diagnosis) comes back on its own.