chore: add docs
This commit is contained in:
150
docs/Architecture.md
Normal file
150
docs/Architecture.md
Normal file
@@ -0,0 +1,150 @@
|
||||
# Architecture
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Layer | Technology |
|
||||
|-------|------------|
|
||||
| Runtime | Bun (v1.0+) |
|
||||
| Language | TypeScript (strict mode) |
|
||||
| LLM Abstraction | Vercel AI SDK v6 |
|
||||
| Validation | Zod v4 |
|
||||
| CLI | Commander |
|
||||
| Colors | picocolors |
|
||||
| Formatting | oxfmt (single quotes) |
|
||||
| Linting | oxlint |
|
||||
|
||||
## Folder Structure
|
||||
|
||||
```
|
||||
nanobot-ts/
|
||||
├── index.ts # Entry point
|
||||
├── src/
|
||||
│ ├── agent/
|
||||
│ │ ├── loop.ts # AgentLoop: LLM ↔ tool execution loop
|
||||
│ │ ├── context.ts # ContextBuilder: system prompt assembly
|
||||
│ │ ├── memory.ts # MemoryConsolidator: token management
|
||||
│ │ ├── skills.ts # Skill loader from workspace
|
||||
│ │ ├── subagent.ts # SubagentManager: background tasks
|
||||
│ │ └── tools/
|
||||
│ │ ├── base.ts # Tool interface + ToolRegistry
|
||||
│ │ ├── filesystem.ts # read_file, write_file, edit_file, list_dir
|
||||
│ │ ├── shell.ts # exec
|
||||
│ │ ├── web.ts # web_search, web_fetch
|
||||
│ │ ├── message.ts # message
|
||||
│ │ ├── spawn.ts # spawn
|
||||
│ │ └── cron.ts # cron
|
||||
│ ├── channels/
|
||||
│ │ ├── base.ts # BaseChannel abstract class
|
||||
│ │ ├── mattermost.ts # Mattermost WebSocket + REST
|
||||
│ │ └── manager.ts # ChannelManager lifecycle
|
||||
│ ├── bus/
|
||||
│ │ ├── types.ts # InboundMessage, OutboundMessage schemas
|
||||
│ │ └── queue.ts # AsyncQueue, MessageBus
|
||||
│ ├── provider/
|
||||
│ │ ├── types.ts # LLMResponse, ToolCall, ChatOptions
|
||||
│ │ └── index.ts # LLMProvider (AI SDK wrapper)
|
||||
│ ├── session/
|
||||
│ │ ├── types.ts # SessionMessage, SessionMeta schemas
|
||||
│ │ └── manager.ts # Session persistence (JSONL)
|
||||
│ ├── cron/
|
||||
│ │ ├── types.ts # CronJob, CronSchedule schemas
|
||||
│ │ └── service.ts # CronService
|
||||
│ ├── heartbeat/
|
||||
│ │ └── service.ts # HeartbeatService
|
||||
│ ├── config/
|
||||
│ │ ├── types.ts # Zod config schemas
|
||||
│ │ └── loader.ts # loadConfig, env overrides
|
||||
│ └── cli/
|
||||
│ └── commands.ts # gateway + agent commands
|
||||
├── templates/ # Default workspace files
|
||||
│ ├── SOUL.md # Agent personality
|
||||
│ ├── USER.md # User preferences
|
||||
│ ├── TOOLS.md # Tool documentation
|
||||
│ ├── AGENTS.md # Agent behavior rules
|
||||
│ ├── HEARTBEAT.md # Periodic tasks
|
||||
│ └── memory/MEMORY.md # Long-term memory
|
||||
└── skills/ # Bundled skills
|
||||
```
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Gateway Mode │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Mattermost ──► BaseChannel ──► MessageBus ──► AgentLoop │
|
||||
│ ▲ │ │ │
|
||||
│ │ ▼ ▼ │
|
||||
│ │ OutboundQueue LLMProvider │
|
||||
│ │ │ │ │
|
||||
│ └───────────────────────────────┘ ▼ │
|
||||
│ ToolRegistry │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ Tool.execute() │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Agent Mode │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ CLI stdin ──► processDirect() ──► AgentLoop ──► Response │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### AgentLoop
|
||||
The core orchestrator. Consumes inbound messages, runs the LLM tool-calling loop, and publishes responses.
|
||||
|
||||
1. Receives `InboundMessage` from bus
|
||||
2. Loads/creates session by key
|
||||
3. Builds context (system prompt + history)
|
||||
4. Calls LLM with tools
|
||||
5. Executes tool calls, appends results
|
||||
6. Repeats until no tool calls or max iterations
|
||||
7. Saves session, publishes response
|
||||
|
||||
### MessageBus
|
||||
An async queue system for decoupling channels from the agent loop.
|
||||
|
||||
- `publishInbound()` / `consumeInbound()`: messages from channels to agent
|
||||
- `publishOutbound()` / `consumeOutbound()`: responses from agent to channels
|
||||
|
||||
### LLMProvider
|
||||
Wraps Vercel AI SDK `generateText()` with:
|
||||
|
||||
- Model string resolution (e.g., `openrouter/anthropic/claude-sonnet-4-5`)
|
||||
- Retry logic (3 attempts, exponential backoff)
|
||||
- Malformed JSON repair
|
||||
- Normalized `LLMResponse` type
|
||||
|
||||
### SessionManager
|
||||
Persists conversation history to JSONL files in `~/.nanobot/sessions/`.
|
||||
|
||||
- Key format: `{channel}:{chatId}` (e.g., `mattermost:abc123`)
|
||||
- Supports history truncation for context window limits
|
||||
|
||||
### ToolRegistry
|
||||
Stores tools by name, provides OpenAI-compatible function definitions to the LLM.
|
||||
|
||||
### MemoryConsolidator
|
||||
When session history exceeds token limits, summarizes old messages and archives to `memory/MEMORY.md`.
|
||||
|
||||
## Configuration
|
||||
|
||||
- File: `~/.nanobot/config.json`
|
||||
- Validation: Zod schemas in `src/config/types.ts`
|
||||
- Env overrides: `NANOBOT_MODEL`, `NANOBOT_WORKSPACE`, `NANOBOT_CONFIG`
|
||||
|
||||
## Session Key Convention
|
||||
|
||||
| Channel | Key Format | Example |
|
||||
|---------|-----------|----------|
|
||||
| Mattermost | `mattermost:{channelId}` | `mattermost:abc123` |
|
||||
| Mattermost (thread) | `mattermost:{channelId}:{rootId}` | `mattermost:abc:def456` |
|
||||
| CLI | `cli:{chatId}` | `cli:interactive` |
|
||||
| System | `system:{source}` | `system:heartbeat` |
|
||||
Reference in New Issue
Block a user