3.6 KiB
3.6 KiB
PicoBot
Maintenance
- Update this file on any architectural change — module boundaries, data flow, key constraints, or build/test commands must be reflected here
Build & Run
cargo build— build the binarycargo run -- gateway— start gateway server (binds127.0.0.1:19876by default)cargo run -- chat— connect to gateway as CLI client (defaultws://127.0.0.1:19876/ws)
Config
- Config file:
~/.picobot/config.jsonor./config.json(fallback order) .envis loaded and env var placeholders<VAR_NAME>are substituted into config- Config example:
config.example.json
Tests
cargo test --lib— run unit tests (FAILS:src/session/session.rs:657missingworkspace_dirfield in test helper)cargo test --test test_integration -- --ignored— run integration tests (requirestests/test.envwith API keys)
Reference
reference/— third-party reference implementations (nanobot, Mini-Agent, zeroclaw); not part of this project; use for similar functionality patterns
Architecture
Modes
- Gateway mode (
cargo run -- gateway): HTTP/WebSocket server; ownsGatewayStatewhich holds all services - Client mode (
cargo run -- chat): TUI chat client; connects to gateway via WebSocket, purely for user interaction
Core Data Flow
Channel → MessageBus → SessionManager → AgentLoop → (tools) → SessionManager → MessageBus → OutboundDispatcher → Channel
↑
ControlChannel ──→ SessionManager (dialog ops: create/switch/archive/delete)
Modules
| Module | Responsibility | Key Types |
|---|---|---|
gateway |
Server lifecycle, HTTP/WS endpoints, owns GatewayState |
GatewayState, run() |
client |
TUI rendering, WebSocket client for CLI chat | App, run() |
channels |
External integrations (Feishu, CLI chat) | ChannelManager, Channel trait |
bus |
Async message queue (inbound/outbound/control channels) | MessageBus, InboundMessage, OutboundMessage, ControlMessage |
session |
Conversation session lifecycle, dialog operations | SessionManager, Session |
agent |
LLM call loop, tool execution, context compression | AgentLoop |
providers |
LLM API clients (OpenAI-compatible, Anthropic) | LLMProvider trait, factory create_provider() |
tools |
Agent tools (bash, file operations, http, web, get_skill) | ToolRegistry, Tool trait |
skills |
Skills loading, management, and prompt building | SkillsLoader, Skill |
Functional Boundaries
- Channels only send/receive messages via
MessageBus; they know nothing about sessions or LLM - MessageBus is a pure async queue; it routes nothing, just passes messages
- SessionManager owns session state and dialog operations; it does NOT call LLM directly
- SessionManager is responsible for injecting skills prompt into conversation history
- AgentLoop receives dialog events from
SessionManager, calls LLM viaproviders, executes tools, returns text responses- AgentLoop is stateless; all state is managed by Session/SessionManager
- Providers are pure HTTP clients; no bus/session/channel awareness
- Tools are executed by
AgentLoop; they receive raw arguments and return string results
Key Constraints
- Gateway changes working directory to workspace on startup (
src/gateway/mod.rs:31) ChannelManagerowns theMessageBusand all channel instancesOutboundDispatcherroutes outbound messages to the correct channel viaChannelManager
Known Issues
- (No known issues at this time)