feat: claude one-shot port from nanobot python codebase (v0.1.4.post4)

This commit is contained in:
Joe Fleming
2026-03-13 08:58:43 -06:00
parent 37c66a1bbf
commit a857bf95cd
53 changed files with 5002 additions and 8 deletions

View File

@@ -0,0 +1,74 @@
# System Patterns
## Type Definition Pattern
Every module that has runtime-validated data uses a dedicated `types.ts` file:
```
src/config/types.ts ← Zod schemas + `export type X = z.infer<typeof XSchema>`
src/bus/types.ts
src/session/types.ts
src/cron/types.ts
src/provider/types.ts
```
The implementation files (`loader.ts`, `manager.ts`, etc.) import types from the sibling `types.ts`.
## Tool Pattern
All tools implement the `Tool` interface from `src/agent/tools/base.ts`:
```ts
interface Tool {
name: string
description: string
parameters: Record<string, unknown> // JSON Schema object
execute(args: Record<string, unknown>): Promise<string>
}
```
`ToolRegistry` stores tools by name, exposes `getDefinitions()` (OpenAI function-calling format), and `execute(name, args)`.
## Message Bus Pattern
Inbound and outbound messages are passed through a typed `AsyncQueue<T>`. The queue uses a `Promise`-based dequeue that resolves when an item is available (mirrors Python `asyncio.Queue`).
## Provider Pattern
`LLMProvider` (`src/provider/index.ts`) wraps the Vercel AI SDK `generateText()`. It:
- Accepts a model string and resolves it to the correct AI SDK provider instance
- Implements `chatWithRetry()` with 3 attempts on transient errors (429, 5xx, timeout)
- Repairs malformed tool-call JSON with `jsonrepair`
- Returns a normalized `LLMResponse` type
## Config Pattern
- Config file: `~/.nanobot/config.json` (camelCase JSON)
- Loaded with `loadConfig()`, validated by Zod, returns inferred `Config` type
- `NANOBOT_` env vars can override fields (e.g. `NANOBOT_MODEL`)
## Mattermost Channel Pattern
- Inbound: native `WebSocket` connecting to `wss://{server}/api/v4/websocket`, auth via hello message
- Outbound: `fetch()` to `POST /api/v4/posts`
- Session key: `mattermost:{channelId}` (or `mattermost:{channelId}:{rootId}` when `replyInThread`)
## Session Key Convention
`{channel}:{chatId}` — e.g. `mattermost:abc123`, `cli:direct`
## Logging Pattern
Use `console.error` / `console.warn` / `console.info` / `console.debug` — no external logger. Color via `picocolors` in CLI output only.
## File Layout
```
src/
config/types.ts + loader.ts
bus/types.ts + queue.ts
provider/types.ts + index.ts
session/types.ts + manager.ts
cron/types.ts + service.ts
heartbeat/service.ts
agent/
memory.ts
skills.ts
context.ts
loop.ts
subagent.ts
tools/base.ts + filesystem.ts + shell.ts + web.ts + message.ts + spawn.ts + cron.ts
channels/
base.ts + mattermost.ts + manager.ts
cli/commands.ts
index.ts
templates/ (SOUL.md, AGENTS.md, USER.md, TOOLS.md, HEARTBEAT.md, memory/MEMORY.md)
skills/ (copied from Python repo)
```