Architecture
Bestie is a local-first, self-hostable agent runtime. The same core runtime should serve terminal chat, Telegram, future local web UI, MCP integrations, and later multi-agent features.
User / Channel -> Channel Adapter -> Runtime Orchestrator -> Mode Detector -> Memory Router -> Prompt Builder -> LLM Adapter -> Safety / Permission Layer -> Tool / Plugin / MCP Router -> Response -> Logs + Memory UpdateThe CLI owns user-facing commands:
onboardchatstatuslogsdoctormemorytelegramtoolsmcp
CLI commands should call runtime services instead of duplicating business logic. Installer, update, and backup commands are later milestones.
Runtime
Section titled “Runtime”The runtime coordinates a turn:
- Receive a message from terminal, Telegram, or another adapter.
- Load config, env, character files, and memory context.
- Build the prompt.
- Call the configured OpenAI-compatible LLM.
- Execute approved tool loops when needed.
- Send the response.
- Store redacted logs and approved memory updates.
The current runtime supports approved local memory recall, explicit memory writes, permission-gated read tools, a multi-step tool loop, and Doctor diagnostics. Broader external, destructive, and public-action tools remain later work.
Character system
Section titled “Character system”Bestie loads editable local character files such as:
character.jsonsystem-prompt.md- style examples
- safety boundaries
The product goal is a believable best-friend character: witty, blunt, emotionally sharp, loyal, and practical. The character can tease and push back, but must not humiliate, diagnose, pretend to be human, or encourage harm.
LLM adapter
Section titled “LLM adapter”The first adapter is OpenAI-compatible HTTP chat completions.
Required config:
baseUrlapiKeyEnvmodel
Useful optional config:
timeoutMsmaxRetriesretryDelayMs- temperature and max-token settings as the implementation expands
Provider errors are normalized for Doctor, logs, and user-facing messages.
Memory router
Section titled “Memory router”The current memory foundation uses local SQLite. It stores active memories, pending memories, persisted terminal and Telegram messages, pause state, and pending action approvals.
Future memory work may add optional Zep, memory merge logic, and richer sensitive-memory approval flows. Zep should add context; it should not define the character.
Channel adapters
Section titled “Channel adapters”Telegram is the first real channel. It uses long polling, owner-only access, slash commands, typing indicators, edited progress messages, attachment handling, memory controls, Doctor summaries, and approval prompts.
Channel adapters should stay thin. Shared behavior belongs in runtime services so terminal and Telegram do not drift.
Doctor
Section titled “Doctor”Doctor is a first-class diagnostic module. It checks environment, config, providers, memory, channels, logs, services, and character files.
bestie doctor --fix only performs safe local repairs unless an action explicitly requires confirmation.
Permissions and tools
Section titled “Permissions and tools”Every action beyond text reply should pass through a permission classifier:
- read-only
- local write
- external write
- public action
- destructive
- money/payment
- unknown
The current local foundation allows trusted read-only actions, asks or denies riskier categories by default, logs decisions with secret redaction, and exposes internal read tools for terminal and Telegram.
MCP support currently focuses on classified read-only calls through local config. Broader MCP, plugins, and multi-agent features should wait until Doctor, logging, permissions, and real-channel behavior are mature.