# 🧬 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 `to` to the corresponding process’s stdin. Messages with `to: "core"` are handled by the Orchestrator (e.g. Telegram `task.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 uses `correlationId: 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 from `CONFIG_PATH` or default), merges with env, exports `getConfig()`. Used by all services/adapters for Lemonade URL, Telegram token/allow-list, DB paths (task memory, RAG, cron, logger), RAG embed model and `rag.dbPath`, tool sandbox, model router names. - **protocol.ts**: Envelope and response/error/event schemas; `parseEnvelope`, `parseResponse`, etc. - **base-process.ts**: `BaseProcess` extends EventEmitter; readline on stdin, `handleEnvelope(line)` β†’ emit `"message"`; `send(envelope)` writes JSONL to stdout. Subclasses override `handleEnvelope` and call `send` for responses. - **graph-utils.ts**: `CapabilityGraph`, `CapabilityNode`, `validateGraph`, `getDependencyMap`, `getReadyNodes` for DAG execution order. ### Agent layer - **Planner**: Listens for `plan.create`; uses Lemonade + Model Router to produce a DAG; validates with `validateGraph`; 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.execute` with `type: "generate_text"` or `type: "summarize"`; for `summarize`, uses summarizer system prompt and `input.chatHistory`; builds prompt from context (goal, deps, optional critic feedback); calls Lemonade; responds with `{ text, ... }`. - **Task Memory**: SQLite store; `conversation_id` on tasks; handles `task.create`, `task.update`, `task.get`, `task.getByConversationId`, `task.appendReflection`, `task.complete`, `task.fail`. - **Logger**: Subscribes to `event.*`; writes structured log (pino) to `logDir/logFile` from 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.execute` for `semantic_search` returns snippets for downstream nodes. - **Tool Host**: Registry of tools (shell, http_get, http_search); sandbox dir from config; `tool.execute` and `node.execute` for type `tool`; shell tool executes commands with sandbox restrictions; browsing supports persistent context (cookies) via `userDataDir`. - **Cron Manager**: SQLite schedule table; node-cron; `cron.schedule.add/list/remove`; emits `event.cron.started/completed/failed` to 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.create` to core (with `conversationId` from session map); sends `chat.new` on `/new`; handles `telegram.send`, `telegram.progress`, and response payloads with `chatId`/`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 by `correlationId`; implements task pipeline for `task.create` from Telegram. ### Data flow (high level) 1. User sends message in Telegram. 2. Telegram Adapter β†’ Core: `task.create` (goal, chatId, userId). 3. Core β†’ Planner: `plan.create` (goal); Planner β†’ Core: plan (DAG). 4. Core β†’ Task Memory: `task.create` (taskId, goal, nodes, edges). 5. Core β†’ Executor: `plan.execute` (taskId, plan, goal). 6. Executor runs DAG: executes specialized **Agents** with instructions; Agents use tools and dynamically call `load_skill`; Task Memory updates; optional Critic revision loop. 7. Executor β†’ Core: response with aggregated result. 8. Core β†’ Telegram Adapter: `telegram.send` (chatId, text). 9. 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**.