mirror of
https://github.com/larchanka/manbot.git
synced 2026-05-13 13:39:40 +00:00
9.7 KiB
9.7 KiB
🧬 ManBot (AI-Agent): Folder Structure and TypeScript Architecture
Folder and File Structure
AI-Agent/
├── config.json.example # Example config (copy to config.json)
├── package.json
├── tsconfig.json
├── vitest.config.ts
├── README.md
├── AI-Agent.md # This file
├── _board/
│ ├── _BOARD.md # Task board (To Do / In Progress / Done)
│ ├── INSTRUCTIONS.md # Workflow for task execution
│ └── TASKS/ # Task specs (P1-01, P2-01, …)
├── skills/ # Dynamic Skills System
│ └── [skill-name]/ # SKILL.md for each skill (first line has description)
├── _docs/
│ ├── ARCHITECTURE.md # Architectural patterns
│ ├── CAPABILITY GRAPH.md # DAG format and node types
│ ├── COMPONENTS.md # Process-oriented components
│ ├── MESSAGE PROTOCOL SPEC.md
│ ├── PROJECT.md
│ ├── TASK MEMORY SQLITE SCHEMA.md
│ └── TECH.md # Stack and dependencies
├── src/
│ ├── index.ts # Platform entry (placeholder)
│ ├── __tests__/
│ │ └── archiving.test.ts # Integration test: conversation archiving flow
│ ├── core/
│ │ └── orchestrator.ts # Core Orchestrator: spawns processes, routes messages, task pipeline
│ ├── agents/
│ │ ├── planner-agent.ts # Plan creation (goal → DAG) via Lemonade
│ │ ├── executor-agent.ts # DAG traversal, node dispatch, Task Memory, revision loop
│ │ ├── critic-agent.ts # Reflection: PASS/REVISE on draft output
│ │ └── prompts/
│ │ ├── planner.ts # Planner system prompt and builder
│ │ ├── critic.ts # Critic system prompt and builder
│ │ └── summarizer.ts # Summarizer prompt for memory extraction (archiving)
│ ├── adapters/
│ │ └── telegram-adapter.ts # Telegram bot → protocol; task.create, telegram.send/progress
│ ├── services/
│ │ ├── lemonade-adapter.ts # Lemonade API: generate, chat, embed
│ │ ├── model-router.ts # Complexity → Lemonade model name
│ │ ├── generator-service.ts # node.execute generate_text (model-router process)
│ │ ├── task-memory.ts # SQLite: tasks, nodes, edges, reflections
│ │ ├── logger-service.ts # event.* → pino file log
│ │ ├── rag-service.ts # Embeddings + SQLite; sqlite-vss KNN when available, else dot-product; memory.semantic.*, node.execute semantic_search
│ │ ├── tool-host.ts # shell, http_get (Playwright), http_search; sandbox; tool.execute / node.execute tool
│ │ ├── cron-manager.ts # node-cron + SQLite schedules; event.cron.* to Logger
│ │ ├── dashboard/ # Dashboard UI (static files: index.html, app.js, styles.css)
│ │ └── dashboard-service.ts # Serves Dashboard UI and API for system monitoring
│ └── shared/
│ ├── config.ts # Central config: config.json + env overrides
│ ├── protocol.ts # Zod schemas: Envelope, Response, Error, Event
│ ├── base-process.ts # BaseProcess: stdin JSONL → handleEnvelope; send(envelope)
│ ├── graph-utils.ts # DAG validation, getDependencyMap, getReadyNodes
│ └── __tests__/
│ └── graph-utils.test.ts
├── src/services/__tests__/
│ ├── task-memory.test.ts
│ └── rag-service.test.ts
(Test and build output dirs such as dist/, node_modules/, logs/, data/ are omitted.)
TypeScript App Architecture
Process model
- One process per agent/service. Each runs as a separate Node.js process.
- IPC: Line-delimited JSON (JSONL) on stdin/stdout. Every message is a single JSON object (envelope) with
id,from,to,type,version,payload. - Core Orchestrator spawns child processes and routes messages: reads from each child’s stdout, and forwards by
toto the corresponding process’s stdin. Messages withto: "core"are handled by the Orchestrator (e.g. Telegramtask.create→ plan → task memory → execute → reply).
Message protocol
- Envelope (Zod in
protocol.ts):id,timestamp,from,to,type,version,payload. - Request/response: Request has a unique
id; response/error usescorrelationId: request.id. - Types:
plan.create,plan.execute,task.create,task.update,task.get,task.getByConversationId,task.appendReflection,task.complete,task.fail,chat.new,node.execute,reflection.evaluate,telegram.send,telegram.progress,memory.semantic.insert,memory.semantic.search,tool.execute,cron.schedule.*,event.*.
Shared layer
- config.ts: Loads
config.json(path fromCONFIG_PATHor default), merges with env, exportsgetConfig(). Used by all services/adapters for Lemonade URL, Telegram token/allow-list, DB paths (task memory, RAG, cron, logger), RAG embed model andrag.dbPath, tool sandbox, model router names. - protocol.ts: Envelope and response/error/event schemas;
parseEnvelope,parseResponse, etc. - base-process.ts:
BaseProcessextends EventEmitter; readline on stdin,handleEnvelope(line)→ emit"message";send(envelope)writes JSONL to stdout. Subclasses overridehandleEnvelopeand callsendfor responses. - graph-utils.ts:
CapabilityGraph,CapabilityNode,validateGraph,getDependencyMap,getReadyNodesfor DAG execution order.
Agent layer
- Planner: Listens for
plan.create; uses Lemonade + Model Router to produce a DAG; validates withvalidateGraph; responds with plan. - Executor: Listens for
plan.execute; traverses the DAG and manages Autonomous Agent Loops; provides an agent system prompt and core tools; handles Dynamic Skill Loading; after DAG, optional reflection loop. - Critic: Listens for
reflection.evaluate; uses Lemonade with Critic prompt; returns structured{ decision: PASS|REVISE, feedback, score }.
Service layer
- Lemonade Adapter: HTTP to Lemonade
baseUrl(from config);generate,chat,embed; timeout and retries. - Model Router: Maps small/medium/large to Lemonade model names (from config).
- Generator Service: Handles
node.executewithtype: "generate_text"ortype: "summarize"; forsummarize, uses summarizer system prompt andinput.chatHistory; builds prompt from context (goal, deps, optional critic feedback); calls Lemonade; responds with{ text, ... }. - Task Memory: SQLite store;
conversation_idon tasks; handlestask.create,task.update,task.get,task.getByConversationId,task.appendReflection,task.complete,task.fail. - Logger: Subscribes to
event.*; writes structured log (pino) tologDir/logFilefrom config. - RAG Service: Lemonade embed; SQLite-backed document store; sqlite-vss for KNN vector search when extension loads (macOS/Linux x64), else in-DB dot-product; configurable
rag.embeddingDimensions(768);memory.semantic.insert,memory.semantic.search; search is session-scoped by default to prevent cross-chat leakage;node.executeforsemantic_searchreturns snippets for downstream nodes. - Tool Host: Registry of tools (shell, http_get, http_search); sandbox dir from config;
tool.executeandnode.executefor typetool; shell tool executes commands with sandbox restrictions; browsing supports persistent context (cookies) viauserDataDir. - Cron Manager: SQLite schedule table; node-cron;
cron.schedule.add/list/remove; emitsevent.cron.started/completed/failedto Logger. - Dashboard Service: Standalone monitoring web dashboard; provides real-time overview of tasks, processes, and IPC logs. UI is served from static files in
src/services/dashboard/.
Adapters
- Telegram Adapter: Telegram bot (token from config); allow-list from config; normalizes messages to protocol; sends
task.createto core (withconversationIdfrom session map); sendschat.newon/new; handlestelegram.send,telegram.progress, and response payloads withchatId/text; commands/start,/task,/new,/help.
Core
- Orchestrator: Spawns all processes (task-memory, logger, planner, executor, critic-agent, telegram-adapter, model-router, rag-service, tool-host, cron-manager, dashboard); multiplexes stdout → route by
to; resolves pending requests bycorrelationId; implements task pipeline fortask.createfrom Telegram.
Data flow (high level)
- User sends message in Telegram.
- Telegram Adapter → Core:
task.create(goal, chatId, userId). - Core → Planner:
plan.create(goal); Planner → Core: plan (DAG). - Core → Task Memory:
task.create(taskId, goal, nodes, edges). - Core → Executor:
plan.execute(taskId, plan, goal). - Executor runs DAG: executes specialized Agents with instructions; Agents use tools and dynamically call
load_skill; Task Memory updates; optional Critic revision loop. - Executor → Core: response with aggregated result.
- Core → Telegram Adapter:
telegram.send(chatId, text). - User sees reply in Telegram.
Archiving (on /new): Telegram sends chat.new (chatId, old conversationId). Core fetches tasks by conversationId, formats history, calls model-router summarize, inserts summary into RAG, sends "Archived" to user.
All configurable behavior (Lemonade URL, Telegram token/allow-list, DB paths, logger paths, RAG model, sandbox, cron DB, model names) is driven by config.json and environment overrides via config.ts.