← Holocron Logs

Jocasta: Retiring My Custom Bot for a Real Agent Framework

BD-1 logged 996 process restarts before I admitted the custom bot had hit its ceiling. Jocasta is its successor: Hermes Agent framework, local-first inference with cloud elevation, 76 loadable skills, and a hard budget cap. This is the build.

Why this matters beyond the homelab: Evaluating build-vs-adopt, running hybrid local/cloud inference under a cost ceiling, and operating an LLM agent as a managed service are the exact patterns emerging in production AI platform work.


The Case Against My Own Code

BD-1 was a custom Node.js Discord bot I wrote and was proud of: Claude-powered, SQLite-backed, PM2-managed, under a $10/month API cap. It worked. It also logged 996 process restarts under PM2.

996 restarts is not a stability number, it is a verdict. Every new capability I wanted (tool use, skill loading, structured memory, local model fallback) meant building agent infrastructure from scratch inside a codebase designed to be a chatbot. At some point the honest engineering question stops being “can I build this” and becomes “should this be my code at all.”

The answer was no. This is the story of replacing a system I built with a system I operate, which is a harder decision than it sounds when the thing being replaced is your own work.


Framework Selection

The requirements: Discord-native, local model support through Ollama, cloud model elevation for hard queries, a skill/plugin system, and enough configurability to survive my opinions.

Hermes Agent (v0.18.0 at deployment) won the evaluation over extending BD-1. The deciding factors were the skill architecture and the model routing layer, both of which I would otherwise have spent months reinventing badly. Buying into a framework means accepting its opinions, but it also means bugs get fixed by a community instead of by me at midnight.


Architecture

Discord ←→ Jocasta (Hermes Agent v0.18.0)

                ├── Ollama: qwen3:14b-hermes (default, local)
                ├── Anthropic API: Haiku/Sonnet (elevation tier)
                ├── Skills: 76 loaded (SKILL.md format)
                ├── Fleet Codex: /root/.hermes/fleet-codex (Git-synced)
                └── SOUL.md: persona definition
Host:      Coruscant (VM 205, Node-B, 192.168.20.82)
Service:   hermes-gateway.service (systemd)
Inference: RTX 4000 SFF Ada, 20GB VRAM (Tantive-III via Ollama)
Budget:    $5/day, $50/month Anthropic hard cap
Search:    Exa (semantic web extraction, free tier)

The VRAM Wall (ADR-010)

The original design specified qwen3:32b as the default local model. The RTX 4000 SFF Ada’s 20GB of VRAM disagreed. The 32b model exceeded available memory, and the options were quantize harder, offload to CPU and accept unusable latency, or drop to qwen3:14b.

I took the 14b substitution and documented it as an addendum to ADR-010 rather than pretending the original decision never existed. The hermes-tuned 14b variant handles function calling well, which matters more for agent workloads than raw parameter count. The lesson generalizes: model selection is a capacity planning problem before it is a quality problem.

The routing compensates for the smaller local model. Routine queries stay on local inference at zero marginal cost. Queries that need more capability elevate to Claude Haiku or Sonnet through the Anthropic API, inside a $5/day cap that makes a runaway loop an annoyance instead of an invoice.


Skills and the Codex

Jocasta currently loads 76 skills. A skill is a structured markdown document that teaches the agent a capability or a knowledge domain, loaded at runtime rather than baked into a prompt. The set includes operational skills for the fleet and a full study track for the Microsoft certification path: AZ-900, AZ-104, SC-300, MD-102, AZ-500, SC-200, and AZ-305. My cert prep agent runs on the same GPU that hosts it.

The knowledge layer is the Alliance Fleet Codex: BookStack documentation exported nightly to Gitea, then pulled by cron into Jocasta’s local codex directory at 4am. The agent answers infrastructure questions from version-controlled documentation that is never more than a day stale. That pipeline earned its own writeup, coming next.


Personality as Configuration

Hermes supports a SOUL.md file defining the agent’s persona. Jocasta’s blends the precision of its namesake (the Jedi Archives librarian) with a steadier, warmer advisory register. This sounds cosmetic. It is not. An agent that answers infrastructure questions needs a consistent voice for how it expresses uncertainty and how it pushes back, and defining that in a versioned file beats hoping it emerges from a system prompt. After a /reset in Discord, the persona reloads from file: personality as configuration, not as state.


Key Takeaways

← Back to Holocron Logs