{"_id":"0xagent","_rev":"2-b6f590fc64ff85289895a056669fa329","name":"0xagent","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"0xagent","version":"0.1.0","keywords":["ai","agent","llm","multi-agent","plugin","mcp","coordination"],"author":{"name":"Roki Ran","email":"ranxiaojing7096@gmail.com"},"license":"MIT","_id":"0xagent@0.1.0","maintainers":[{"name":"jackmao","email":"ranxiaojing7096@gmail.com"}],"homepage":"https://github.com/RokiRan/0xAgent#readme","bugs":{"url":"https://github.com/RokiRan/0xAgent/issues"},"bin":{"bus-agent":"dist/bus-agent.js","agent-harness":"dist/cli.js","agent-harness-v2":"dist/cli-v2.js","agent-harness-server":"dist/server.js","agent-harness-registry":"dist/registry-server.js"},"dist":{"shasum":"7b25bc2517ecd66f28af65a650515740b721b958","tarball":"https://registry.npmjs.org/0xagent/-/0xagent-0.1.0.tgz","fileCount":120,"integrity":"sha512-9kQpjt8XaElYr96s64aw+z5d3gceCXQs8nmOng20WbTX6tdmKkXRvQa4etRGrIwBOSLsFqBDC1xlAJi+uvdjTw==","signatures":[{"sig":"MEUCIQDZpx0QadMv1RwqYo0FaV5vvVR/1b1p3gNmlH4E66rSjwIgHe/EO6RWiPsp/8y+zLtE4FwvdIC8Ndm+27oGexCzusU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":537315},"main":"dist/harness.js","type":"module","types":"dist/harness.d.ts","engines":{"node":">=22.0.0"},"gitHead":"caaf2112015ffca208c9d696d8f188f2c1c966ff","scripts":{"dev":"tsx src/cli.ts","test":"sh scripts/test.sh","build":"tsc","start":"node dist/cli.js","dev:v2":"tsx src/cli-v2.ts","server":"tsx src/server.ts","registry":"tsx src/registry-server.ts","start:v2":"node dist/cli-v2.js","demo:http":"node dist/test-http-transport.js","typecheck":"tsc && tsc -p test/tsconfig.json","test:legacy":"node dist/test-pro.js","demo:multi-agent":"node dist/demo-multi-agent.js"},"_npmUser":{"name":"jackmao","email":"ranxiaojing7096@gmail.com"},"repository":{"url":"git+https://github.com/RokiRan/0xAgent.git","type":"git"},"_npmVersion":"11.16.0","description":"Lightweight, plugin-based AI Agent framework for Node.js. Everything is a plugin.","directories":{},"_nodeVersion":"20.19.5","dependencies":{"ws":"^8.21.3","yaml":"^2.4.0","better-sqlite3":"^13.0.3"},"_hasShrinkwrap":false,"prepublishOnly":"npm run build && npm test","devDependencies":{"tsx":"^4.0.0","jsdom":"^30.0.1","canvas":"^3.2.3","marked":"^18.0.10","@types/ws":"^8.18.1","dompurify":"^3.4.14","playwright":"^1.62.1","typescript":"^5.4.0","@types/node":"^20.0.0","@types/better-sqlite3":"^9.6.0"},"_npmOperationalInternal":{"tmp":"tmp/0xagent_0.1.0_1787583811285_0.23289525660621546","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"0xagent","version":"0.1.1","description":"Lightweight, plugin-based AI Agent framework for Node.js. Everything is a plugin.","type":"module","main":"dist/harness.js","types":"dist/harness.d.ts","scripts":{"build":"tsc","dev":"tsx src/cli.ts","dev:v2":"tsx src/cli-v2.ts","server":"tsx src/server.ts","registry":"tsx src/registry-server.ts","start":"node dist/cli.js","start:v2":"node dist/cli-v2.js","test":"sh scripts/test.sh","demo:multi-agent":"node dist/demo-multi-agent.js","demo:http":"node dist/test-http-transport.js","test:legacy":"node dist/test-pro.js","typecheck":"tsc && tsc -p test/tsconfig.json"},"keywords":["ai","agent","llm","multi-agent","plugin","mcp","coordination"],"author":{"name":"Roki Ran","email":"ranxiaojing7096@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/RokiRan/0xAgent.git"},"engines":{"node":">=22.0.0"},"dependencies":{"better-sqlite3":"^13.0.3","ws":"^8.21.3","yaml":"^2.4.0"},"devDependencies":{"@types/better-sqlite3":"^9.6.0","@types/node":"^20.0.0","@types/ws":"^8.18.1","canvas":"^3.2.3","dompurify":"^3.4.14","jsdom":"^30.0.1","marked":"^18.0.10","playwright":"^1.62.1","tsx":"^4.0.0","typescript":"^5.4.0"},"bin":{"agent-harness":"dist/cli.js","agent-harness-v2":"dist/cli-v2.js","agent-harness-server":"dist/server.js","agent-harness-registry":"dist/registry-server.js","bus-agent":"dist/bus-agent.js"},"prepublishOnly":"npm run build && npm test","gitHead":"be96761e2b192eb6148d8938d6e54748c4a26aa3","_id":"0xagent@0.1.1","bugs":{"url":"https://github.com/RokiRan/0xAgent/issues"},"homepage":"https://github.com/RokiRan/0xAgent#readme","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-tK/D6e5pmu/dSmwrVo8S4gOkSXGBqSb08gZp5PZQk0/Zb/tG0jOi9QOuhd0eMvKEGkqvwIeiuKnqknxbCpgRxg==","shasum":"598b8ff38333431d0aeb7e418c68636c92dd2d15","tarball":"https://registry.npmjs.org/0xagent/-/0xagent-0.1.1.tgz","fileCount":118,"unpackedSize":534929,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/0xagent@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC5vSqPCOsDQ33luR/69p9OxVtmM2rb7Xw0XIe41OVOHwIhAKnqZsw4nn58sbinXwdAIUx79S0Gq/S3rJNnZwPymYuf"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:becfe8fe-618e-4df2-aa25-df00a9e2357a"}},"directories":{},"maintainers":[{"name":"jackmao","email":"ranxiaojing7096@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/0xagent_0.1.1_1787584353545_0.5893081341297179"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-24T15:03:31.225Z","modified":"2026-08-24T15:12:34.090Z","0.1.0":"2026-08-24T15:03:31.427Z","0.1.1":"2026-08-24T15:12:33.684Z"},"bugs":{"url":"https://github.com/RokiRan/0xAgent/issues"},"author":{"name":"Roki Ran","email":"ranxiaojing7096@gmail.com"},"license":"MIT","homepage":"https://github.com/RokiRan/0xAgent#readme","keywords":["ai","agent","llm","multi-agent","plugin","mcp","coordination"],"repository":{"type":"git","url":"git+https://github.com/RokiRan/0xAgent.git"},"description":"Lightweight, plugin-based AI Agent framework for Node.js. Everything is a plugin.","maintainers":[{"name":"jackmao","email":"ranxiaojing7096@gmail.com"}],"readme":"# Agent Harness\n\n> 生产级 AI Agent 框架。插件化架构、多模型支持、安全沙箱、持久化会话、向量记忆、并行调度、MCP 协议兼容、跨网络多 Agent 协作（渠道中继 + 协调闸门 + 任务/决策/承诺硬对象）。\n\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue)](https://www.typescriptlang.org/)\n[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n\n## 简介\n\nAgent Harness 是一个受 [DeepSeek Harness](https://github.com/deepseek-ai/awesome-deepseek-integration) 和 [OpenAI Codex CLI](https://github.com/openai/codex) 启发的 AI Agent 框架。从零开始构建，目标是提供一个**类型安全、可扩展、生产就绪**的 Agent 运行时。\n\n**核心理念：**\n- **插件优先**：所有能力都是插件，不侵入核心\n- **零依赖默认**：核心框架不依赖外部服务，可选能力按需加载\n- **安全第一**：代码执行沙箱化，操作需审批\n- **持久化**：SQLite ACID 持久化，重启后状态不丢失\n- **多模态**：支持 OpenAI、MiniMax 等多种模型，一键切换\n\n---\n\n## 功能特性\n\n### 已实现的完整功能栈\n\n| 模块 | 特性 | 状态 | 说明 |\n|------|------|------|------|\n| **核心架构** | 插件系统 | ✅ | Kernel + ServiceRegistry + EventBus |\n| | TypeScript 严格模式 | ✅ | 完整类型推导 |\n| **模型层** | OpenAI 兼容 | ✅ | GPT-4 / GPT-3.5 / 自定义兼容端点 |\n| | MiniMax 国区 | ✅ | MiniMax-M3，国内直连 |\n| | 多模型热切换 | ✅ | 改配置即可切换 |\n| **工具层** | 文件系统 | ✅ | 读写文件、目录操作 |\n| | Shell 执行 | ✅ | 带超时和目录限制 |\n| | 代码执行 | ✅ | JavaScript / Python / Bash |\n| | 自定义工具 | ✅ | 简单函数即可注册 |\n| **安全** | 进程沙箱 | ✅ | 临时目录 + 超时 + 输出限制 |\n| | Docker 沙箱 | ✅ | 容器隔离 + 内存/CPU 限制 |\n| | 审批策略 | ✅ | auto / confirm / reject 三级 |\n| | 危险命令拦截 | ✅ | rm -rf /、fork bomb 等 |\n| **会话管理** | Item/Turn/Thread 原语 | ✅ | Codex-inspired |\n| | 内存存储 | ✅ | 开发调试 |\n| | SQLite 持久化 | ✅ | ACID + 搜索 + Fork |\n| | 向量记忆 | ✅ | RAG 检索历史上下文（按 thread 隔离，跨会话检索走显式 API） |\n| | 上下文压缩 | ✅ | 阈值触发 + 摘要 |\n| **通信协议** | Agent Bus (内存) | ✅ | 同进程通信 |\n| | Agent Bus (HTTP) | ✅ | P2P / Registry 中继 / 渠道隔离 |\n| | 协调闸门 | ✅ | lapping / verbatim-dup / 速率地板 / seen-cursor / hold-token |\n| | 多 agent 聊天室 | ✅ | @ 点名、自主插嘴判断、上下文互评 |\n| | 任务板 | ✅ | Task/Lease/评分重派/验收/ADR |\n| | 决策板 | ✅ | quorum/timebox/anti-reopen/结构化升级 |\n| | 承诺与依赖 | ✅ | promise 确认入图、阻塞驱动催办 |\n| | Focus window | ✅ | in_progress 租约=深度工作期，只放行直聊/关键路径催办，其余批量摘要补发 |\n| | MCP Server | ✅ | 对外暴露工具 |\n| | MCP Client | ✅ | 调用外部 MCP 工具 |\n| | WebSocket | ✅ | 实时双向通信 |\n| **Web UI** | 聊天界面 | ✅ | 现代化 React-less 前端 |\n| | Thread 管理 | ✅ | 创建 / 切换 / Fork / 归档 |\n| | 实时流式 | ✅ | WebSocket 推送 |\n| | 审批弹窗 | ✅ | 人工确认操作 |\n| **调度** | 子 Agent 并行 | ✅ | Map-Reduce 模式 |\n| | 任务路由 | ✅ | 关键字自动分配 |\n| | 结果聚合 | ✅ | LLM 合成多 Agent 输出 |\n| **可观测性** | 执行追踪 | ✅ | 全链路事件 |\n\n---\n\n## 架构设计\n\n```\n┌─────────────────────────────────────────────────────┐\n│                    Client Layer                      │\n│   CLI (stdio) / Web UI (WebSocket) / MCP Client     │\n├─────────────────────────────────────────────────────┤\n│                  App Server                          │\n│   JSON-RPC  │  Thread Manager  │  Turn Executor      │\n├─────────────────────────────────────────────────────┤\n│                    Agent Core                        │\n│   Prompt Builder │ Approver │ Compactor │ Memory     │\n├─────────────────────────────────────────────────────┤\n│                  Execution Layer                     │\n│   Model Provider │ Tool Registry │ Parallel Scheduler│\n├─────────────────────────────────────────────────────┤\n│                   Sandbox Layer                      │\n│   Process Sandbox │ Docker Sandbox │ Danger Filter   │\n├─────────────────────────────────────────────────────┤\n│                  Persistence Layer                   │\n│   SQLite (Thread/Turn/Item) │ Vector Memory (RAG)   │\n└─────────────────────────────────────────────────────┘\n```\n\n---\n\n## 快速开始\n\n### 安装\n\n```bash\ngit clone <repo-url>\ncd agent-harness\nnpm install\n```\n\n### 环境配置\n\n```bash\n# 方案一：OpenAI\nexport OPENAI_API_KEY=sk-...\n\n# 方案二：MiniMax 国区\nexport MINIMAX_API_KEY=sk-...\nexport MINIMAX_BASE_URL=https://api.minimaxi.com/v1\nexport MINIMAX_MODEL=MiniMax-M3\n# 可选：双脑分流——judge/vote/promise/verify 走小脑（不设则全部走主模型）\nexport MINIMAX_MODEL_SMALL=MiniMax-M2.5\n\n# 可选：持久化路径\nexport AGENT_DB_PATH=./data/threads.db\n```\n\n### 启动方式\n\n```bash\n# 1. CLI 模式（stdio）\nnpm run dev\n\n# 2. Web UI 模式（WebSocket + HTTP，无头服务，含多 agent 聊天室）\nAGENT_MODEL_PROVIDER=minimax MINIMAX_API_KEY=sk-... \\\nBUS_REGISTRY_URL=http://localhost:9876 npm run server\n# 打开 http://localhost:3456\n\n# 3. Registry 中继（多 agent 跨网络协作时，放公网节点）\nnpm run registry   # 默认 :9876，REGISTRY_PORT 可改\n\n# 4. MCP Server 模式：由 mcp 插件按配置激活（config.server.enabled + transport:'stdio'），\n#    见 src/mcp/plugin.ts；无独立 npm script\n```\n\n### 最小代码示例\n\n```typescript\nimport { HarnessV2 } from './harness-v2.js';\n\nconst agent = new HarnessV2({\n  modelProvider: 'minimax',\n  model: {\n    apiKey: process.env.MINIMAX_API_KEY!,\n    baseUrl: 'https://api.minimaxi.com/v1',\n    model: 'MiniMax-M3',\n  },\n  filesystem: { rootPath: './workspace' },\n  agent: {\n    maxIterations: 10,\n    systemInstruction: 'You are a helpful coding assistant.',\n  },\n  persistence: { dbPath: './data/threads.db' },\n  enableMemory: true,\n  transports: ['stdio', 'websocket'],\n  webUI: { enabled: true, port: 3456 },\n});\n\nawait agent.start();\n```\n\n---\n\n## 核心概念\n\n### 1. Thread / Turn / Item 三原语\n\n受 OpenAI Codex CLI 启发，会话管理采用三级结构：\n\n- **Thread**：会话线程，独立上下文边界\n- **Turn**：单次用户输入到 Agent 响应的完整回合\n- **Item**：Turn 内的原子消息单元（用户输入、Assistant 回复、工具调用、工具结果）\n\n```typescript\n// 创建线程\nconst thread = threadManager.create();\n\n// Fork 线程（保留历史，独立发展）\nconst forked = threadManager.fork(thread.id);\n\n// 归档线程\nthreadManager.archive(thread.id);\n```\n\n### 2. 审批策略\n\n三级策略控制工具执行：\n\n```typescript\nconst approval = {\n  autoApprove: ['filesystem:read'],  // 自动放行\n  confirm: ['filesystem:write', 'shell'],  // 需确认\n  reject: ['rm', 'mkfs'],  // 直接拒绝\n};\n```\n\n### 3. 上下文压缩\n\n当 Token 数超过阈值时，自动压缩历史：\n\n```typescript\nconst compactor = new ContextCompactor({\n  tokenThreshold: 12000,  // 触发阈值\n  summaryModel: modelProvider,  // 用于摘要的模型\n});\n\n// 自动保留最近 N 轮，老消息摘要化\n```\n\n### 4. 向量记忆\n\n无需外部向量数据库，轻量 RAG：\n\n```typescript\nconst memory = new ThreadMemory();\n\n// 自动索引\nmemory.indexThread(thread);\n\n// 检索相关上下文（可选 threadId 限定会话范围；\n// agent 对话轮内自动按当前 thread 隔离，防跨会话泄漏）\nconst context = memory.getRelevantContext(\"帮我优化那个函数\");\n// 返回: \"Relevant previous context: [assistant]: ...\"\n```\n\n---\n\n## 插件系统\n\n### 内置插件\n\n| 插件 | 功能 |\n|------|------|\n| `model:openai` | OpenAI API 兼容模型 |\n| `model:minimax` | MiniMax 国区 API |\n| `tool:filesystem` | 文件读写、目录操作 |\n| `tool:shell` | Shell 命令执行 |\n| `sandbox:process` | 进程级代码沙箱 |\n| `sandbox:docker` | Docker 容器沙箱 |\n| `session:memory` | 内存会话存储 |\n| `session:persistence` | JSON 文件持久化 |\n| `agent-loop:react` | ReAct 决策循环 |\n| `agent:bus` | 多 Agent 通信 |\n| `mcp` | MCP 协议适配 |\n\n### 自定义插件\n\n```typescript\nimport { Plugin } from './core/plugin.js';\nimport { Tool } from './plugins/tools/interface.js';\n\nconst myTool: Tool = {\n  name: 'weather',\n  description: '获取城市天气',\n  parameters: {\n    type: 'object',\n    properties: { city: { type: 'string' } },\n    required: ['city'],\n  },\n  async execute(args) {\n    return { temp: 24, condition: 'sunny' };\n  },\n};\n\nexport const myPlugin: Plugin = {\n  name: 'tool:weather',\n  dependencies: ['tool:registry'],\n  async activate(ctx) {\n    const registry = ctx.services.get('tool:registry') as any;\n    registry.register(myTool);\n  },\n};\n```\n\n---\n\n## 多 Agent 并行调度\n\n### 基础用法\n\n```typescript\nimport { ParallelScheduler } from './core/scheduler.js';\n\nconst scheduler = new ParallelScheduler(\n  {\n    agents: [\n      { id: 'coder', systemPrompt: 'You are a code expert.', tools: ['shell', 'code'] },\n      { id: 'writer', systemPrompt: 'You are a writer.', tools: ['filesystem'] },\n    ],\n    maxConcurrency: 3,\n  },\n  modelProvider,\n  toolRegistry\n);\n\n// 并行执行\nconst results = await scheduler.runParallel([\n  { id: 'task-1', description: 'Write a fibonacci function', agentId: 'coder' },\n  { id: 'task-2', description: 'Write documentation', agentId: 'writer' },\n]);\n\n// 聚合结果\nconst summary = await scheduler.aggregate('Create a math library', results);\n```\n\n### Map-Reduce 模式\n\n```typescript\nconst documents = ['doc1.txt', 'doc2.txt', 'doc3.txt'];\n\nconst summary = await scheduler.mapReduce(\n  documents,\n  (doc) => ({\n    id: doc,\n    description: `Summarize ${doc}`,\n  }),\n  async (results) => {\n    // 自定义聚合逻辑\n    return results.map(r => r.output).join('\\n');\n  }\n);\n```\n\n---\n\n## 多 Agent 协作（Agent Bus）\n\n跨网络多 agent 协作系统：Registry 中继（公网节点）+ Bus Agent（各地执行体）+ Web Gateway（聊天室桥）。协调机制移植自 cumora 的工程实践：**并发与一致性用代码硬闸，判断与表达用模型**。\n\n### 架构\n\n```\n┌────────────┐   broadcast/relay   ┌──────────────────┐\n│ bus-agent  │ ◄────poll(2s)─────  │  Registry (公网)  │\n│ (树莓派)   │                     │  channels/queues  │\n└────────────┘                     │  协调闸门 + 指标  │\n┌────────────┐                     └──────────────────┘\n│ bus-agent  │ ◄──────────────────────────▲\n│ (Mac/任意) │                            │ register/heartbeat(30s)\n└────────────┘                            │\n┌────────────┐   WS   ┌─────────────────┐ │\n│  Web UI    │ ◄────► │ Harness Server  │─┘\n│ (聊天室)   │        │ (web-gateway)   │\n└────────────┘        └─────────────────┘\n```\n\n### 渠道（Channel）\n\n消息按渠道隔离。`default` 渠道自动加入；`/register` 心跳每 30s 自愈渠道成员资格（registry 重启无需重启 agent）；3 分钟无心跳的成员被清扫。\n\n**安全与持久化**：\n- `BUS_TOKEN`：设置后所有端点（含 `/poll`）要求 `x-bus-token` 头，agent/gateway 端同名 env 注入；不设则开放（仅建议内网）。\n- `REGISTRY_STATE_FILE`：registry 快照落盘（agents/channels/queues，1s 防抖，原子替换）——**在途消息重启不丢**（邮箱模型：落盘是唯一事实源，唤醒可丢）。\n- 保留策略（gateway 侧，启动 + 每日）：`room_messages` 每房间保留最近 500 条；`done/cancelled` 任务与 `decided` 决策保留 90 天；principles 不删。\n\n| 端点 | 说明 |\n|------|------|\n| `POST /channels/create` | 创建（幂等），创建者加入 |\n| `POST /channels/join` `/leave` | 加入/退出 |\n| `POST /channels/delete` | 删除（`default` 受保护） |\n| `GET /channels` `/channels/members?channel=X` | 列表/成员 |\n| `GET /metrics` | 闸门计数（held 按原因、broadcasts、evicted） |\n\n### 协调闸门（Registry 硬机制）\n\n| 闸门 | 行为 | 语义 |\n|------|------|------|\n| **lapping** | 无人类时，agent 消息数 > 不同发言者数 → 429 HELD | 死循环判据自扩展 |\n| **两档地板** | 人类 10 分钟内在场：cap=6（自适应 `max(6, μ+2σ)`）；人类离开：严格 lapping | 人在场的讨论有界放开 |\n| **verbatim-dup** | 同 `(channel, from)` 逐字重复 → 409 HELD | 不可被 override 绕过 |\n| **速率地板** | 30 条/分钟/agent，**人类流量永不节流** | 内容盲成本地板 |\n| **seen-cursor 新鲜度** | 发言前有未读消息 → 409 HELD 并**内联未读**，agent 重算后重试 | 游标独立于读取路径 |\n| **hold-token** | override 令牌绑定已展示 seq、120s TTL、单次消费、过期拒收 | 覆盖=对已展示状态的确认 |\n\n人类消息重置全部循环计数（人类是复位器）。stale agent 3 分钟清扫。\n\n### 聊天室（Web UI）\n\n- 房间 = 渠道；侧边栏创建/切换，成员徽章实时显示\n- **@ 点名**：request/response 强制应答；**不 @**：逐成员 relay + 各 agent 自主判断（judge，fail-closed），反附和规则防互吹\n- agent 上下文按 token 预算装配（`BUS_CONTEXT_TOKENS`，默认 3000，字符/2 估算），超预算省略显式报数、单条超长带截断标记——agent 知道记录不完整\n- **Focus window**：agent 持有 `in_progress` 租约时房间消息进个人摘要队列（cap 50），窗口结束（任务流转/租约回收/30s 巡检）一次性补发；@ 直聊与关键路径催办永不拦截\n- agent 回复带思考链折叠块 + 耗时，Markdown 渲染（DOMPurify 消毒）\n\n### 任务板（Task/Contract + Lease）\n\n```mermaid\nstateDiagram-v2\n  ready --> in_progress: 指派/认领(起租30min)\n  in_progress --> review: agent 提交 evidence\n  in_progress --> in_progress: 评分重派(租约逾期)\n  in_progress --> escalated: 二次逾期(升级给人)\n  review --> done: approver 确认(自动落 ADR)\n  review --> in_progress: 退回(带 note 返工)\n  done --> in_progress: 仅新证据 diff 返工\n  escalated --> cancelled: 人类终止(强制 ADR)\n```\n\n不变量：acceptance 非空才能开工；approver ≠ owner；重派评分 = 在场 − 负载×10 + 历史成功率×10（纯 DB 事实）。高风险任务（`risk: 'high'`）停在 `pending_approval`，人工确认才派发。\n\n### 决策板（Decision）\n\n`decision/open` 发起表决 → 全体在场 agent 收票（LLM 选项+理由）→ quorum 达成即 `decided`；timebox 到点未决 → `escalated`（四行结构化封套：要决定什么/选项与票数/默认项/时限后果）；人类再超时 → 采用默认项（`auto_default`）。`decided` 只有新证据 diff 可 reopen。\n\n### 承诺与依赖（Commitment）\n\n`promise/create` 产生承诺候选，**agent 确认后才入依赖图**；`dep/add` 登记依赖边（防环）。阻塞驱动催办：只点名关键路径上逾期的阻塞者，同一依赖边 45 分钟冷却。\n\n### LLM 台账与双脑（cumora §7 适配）\n\n- **台账**：每次出站 LLM 调用记账（agent/purpose/model/token/延迟/状态）。server 侧经 `RecordingProvider` 装饰器在 provider 层收口（漏点为零）落 SQLite `llm_calls`；agent 侧上报 registry `POST /llm-calls`（追加 JSONL）——系统记账走系统通道，不污染对话通道不计入 rounds。fire-and-forget：记账失败绝不阻塞调用；provider 未报用量时 `measured=false` 记 0，**绝不猜测**\n- **双脑**：reply/task 走主模型（`MINIMAX_MODEL`），judge/vote/promise/verify 走小脑（`MINIMAX_MODEL_SMALL`，未设回落主模型——策略收口在位，行为不变）\n- 查询：`llm/stats` 合并 server（SQLite）与 agents（registry JSONL）两侧聚合视图\n\n### 验收门（Verify，cumora §10.1.1 适配）\n\nagent 提交任务 evidence 后、进 `review` 前，小脑对账 acceptance × evidence（「确认 ≠ 交付」）。`complete=false` → 自动退回返工并附 `next_step`；连续 2 次不过仍进 `review` 但标红留人裁；验收器自身故障按 `complete:false` 处理——宁可多烧跳数不放过假完成。\n\n### 定时提醒（future-you，cumora §9.2.1 适配）\n\n`reminder/create`（或 agent 经 bus request `kind:'reminder'` 直连 gateway）把\"我以后再做\"变成服务器担保的唤醒：60s tick 到点 → 系统消息落房 + 直连唤醒 assignee。派发幂等（`UPDATE ... WHERE status='pending'` 认领），投递失败不回滚——房间记录兜底，agent 下次活跃自然补见。\n\n### 事故著录\n\n多 agent 协调的反模式与事故记录（含常量校准依据）见 [docs/COORDINATION.md](docs/COORDINATION.md)。改协调闸门数值前必读。\n\n### 编码引擎（Coding Engine，BYOA 最小版）\n\nagent 的编码任务可委派给真实编码 CLI 执行——产出是真实文件副作用而非空谈：\n\n```bash\n# bus-agent 环境变量\nCODING_ENGINE=omp        # 或 claude；不设 = LLM-only 旧行为\nCODING_WORKDIR=/tmp/0xagent-work   # 默认 $TMPDIR/0xagent-work（刻意不落仓库根：引擎持写权限，边界必须显式）\nCODING_TIMEOUT_MS=240000           # 默认 240s（< task-board 5min 派发超时）\nCODING_BIN=/path/to/binary         # 可选，覆盖二进制路径\n```\n\n- **omp**：`omp -p --auto-approve --no-session`，本机已装即可用，无 per-call 成本\n- **claude**：`claude -p --output-format json --permission-mode bypassPermissions`，JSON 输出自带 `total_cost_usd` 回传\n- 引擎调用按 `purpose='task'`、`model='engine:<id>'` 入台账；token 不可得时 `measured=false` 记 0 不猜\n- 新增引擎 = 实现 `CodingEngine` 接口（`src/plugins/engine/index.ts`），bus-agent 主流程无感\n\n### 部署\n\n```bash\n# Registry（公网节点，单文件零依赖）\nnpx esbuild src/registry-server.ts --bundle --platform=node --format=esm --outfile=registry.mjs\nREGISTRY_PORT=9876 REGISTRY_STATE_FILE=./registry-state.json \\\nREGISTRY_LEDGER_FILE=./llm-calls.jsonl \\\nBUS_TOKEN=shared-secret node registry.mjs\n\n# Bus Agent（任意机器）\nnpx esbuild src/bus-agent.ts --bundle --platform=node --format=esm --outfile=bus-agent.mjs\nAGENT_ID=pi-agent REGISTRY_URL=http://registry:9876 BUS_CHANNEL=team \\\nBUS_TOKEN=shared-secret \\\nAGENT_PERSONA=\"树莓派/嵌入式/Linux运维专家\" \\\nMINIMAX_API_KEY=sk-... node bus-agent.mjs\n\n# Web 服务端（含聊天室 gateway）\nAGENT_MODEL_PROVIDER=minimax MINIMAX_API_KEY=sk-... \\\nBUS_REGISTRY_URL=http://registry:9876 BUS_CHANNELS=team \\\nBUS_TOKEN=shared-secret npm run server\n```\n\n无 LLM key 的 bus-agent 自动降级为静默模式（不判断、不插嘴、不轻诺）。\n\n---\n\n## MCP 协议兼容\n\n### 作为 MCP Server\n\n暴露所有工具给外部 MCP 客户端（如 Claude Desktop）：\n\n```typescript\n// claude_desktop_config.json\n{\n  \"mcpServers\": {\n    \"agent-harness\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/agent-harness/dist/mcp/stdio-server.js\"]\n    }\n  }\n}\n```\n\n### 作为 MCP Client\n\n调用外部 MCP Server 的工具：\n\n```typescript\nconst harness = new HarnessV2({\n  mcp: {\n    clients: [\n      {\n        name: 'filesystem',\n        command: 'npx',\n        args: ['-y', '@modelcontextprotocol/server-filesystem', '/path/to/allowed'],\n      },\n    ],\n  },\n});\n\n// 外部工具自动注册为 harness:toolName\n```\n\n---\n\n## Web UI 控制台\n\n### 启动\n\n```bash\nnpm run server\n# 自动启动:\n# - HTTP 静态服务器: http://localhost:3456\n# - WebSocket JSON-RPC: ws://localhost:3456/jsonrpc（同端口共享）\n# - 设了 BUS_REGISTRY_URL 时: 多 agent 聊天室 gateway\n#\n# （cli-v2 的 npm run dev:v2 是带终端 REPL 的形态，后台/服务部署请用 npm run server）\n```\n\n### 功能\n\n- **Thread 管理**：侧边栏列出所有线程（首条消息派生标题），点击切换\n- **多 Agent 聊天室**：渠道房间、@ 点名补全、成员徽章、任务面板\n- **思考链展示**：`<think>` 推理折叠块 + 耗时统计\n- **Markdown 渲染**：marked + DOMPurify 消毒（表格/代码块/列表）\n- **实时通信**：WebSocket 双向推送，断线 3s 自动重连\n- **审批交互**：危险操作弹窗确认\n- **输入体验**：多行自增高、@ 补全、无选中时禁用引导\n- **响应式**：侧边栏可折叠，窄屏自动收起\n\n### 截图\n\n```\n┌─────────────┬─────────────────────────────────────────┐\n│ Agent Harness│ 🤖 Agent                                │\n│ [Status: 🟢] │ ───────────────────────────────────────│\n│             │                                         │\n│ + New Thread│ User: 写一个快速排序                    │\n│             │                                         │\n│ 💬 thread-1 │ 🤖 我来实现一个快速排序算法...          │\n│ 💬 thread-2 │ [代码块]                                │\n│ 💬 thread-3 │                                         │\n│             │ 🔧 shell: node test.js                  │\n│             │ 输出: [1, 2, 3, 4, 5]                   │\n│             │                                         │\n│             ├─────────────────────────────────────────┤\n│             │ [输入框...                    ] [Send]  │\n└─────────────┴─────────────────────────────────────────┘\n```\n\n---\n\n## API 参考\n\n### JSON-RPC 方法\n\n**Thread 生命周期**\n\n| 方法 | 参数 | 说明 |\n|------|------|------|\n| `thread/create` | `{ id?: string }` | 创建线程 |\n| `thread/get` | `{ id: string }` | 获取线程状态 |\n| `thread/list` | - | 列出所有线程 |\n| `thread/fork` | `{ sourceId, newId? }` | 分叉线程 |\n| `thread/archive` | `{ id }` | 归档线程 |\n| `thread/delete` | `{ id }` | 删除线程 |\n\n**执行**\n\n| 方法 | 参数 | 说明 |\n|------|------|------|\n| `turn/submit` | `{ threadId, input }` | 提交用户输入 |\n| `turn/cancel` | `{ turnId }` | 取消执行 |\n\n**审批**\n\n| 方法 | 参数 | 说明 |\n|------|------|------|\n| `approval/list` | - | 列出待审批 |\n| `approval/resolve` | `{ id, approved }` | 审批操作 |\n\n**记忆**\n\n| 方法 | 参数 | 说明 |\n|------|------|------|\n| `memory/search` | `{ query, topK? }` | 搜索历史 |\n| `memory/context` | `{ query, maxTokens? }` | 获取相关上下文 |\n\n**聊天室（需 `BUS_REGISTRY_URL`）**\n\n| 方法 | 参数 | 说明 |\n|------|------|------|\n| `room/list` | - | 房间列表（含成员） |\n| `room/create` | `{ name }` | 创建房间 |\n| `room/history` | `{ room }` | 房间消息历史（SQLite 持久化） |\n| `room/send` | `{ room, text }` | 发言；`@agent` 点名强制应答，否则广播+自主判断 |\n\n**任务板**\n\n| 方法 | 参数 | 说明 |\n|------|------|------|\n| `task/create` | `{ room, title, acceptance[], owner?, risk? }` | 创建；acceptance 必填；`risk:'high'` 需 `task/confirm` |\n| `task/list` | `{ room }` | 任务列表 |\n| `task/approve` / `task/return` | `{ taskId }` / `{ taskId, note }` | 验收（落 ADR）/ 退回返工 |\n| `task/cancel` | `{ taskId, adr }` | 终止（ADR 必填） |\n| `task/reopen` | `{ taskId, evidence }` | done 返工（需新证据 diff） |\n| `task/reassign` / `task/confirm` | `{ taskId, owner }` / `{ taskId }` | 人工重派 / 高风险确认 |\n| `promise/create` | `{ room, taskId, promiser, dueInMin? }` | 承诺候选（agent 确认才入图） |\n| `dep/add` | `{ blockedTaskId, blockingTaskId }` | 依赖边（防环） |\n\n**决策板**\n\n| 方法 | 参数 | 说明 |\n|------|------|------|\n| `decision/open` | `{ room, question, options[], criterion?, quorum?, defaultOption?, timeboxMin? }` | 发起表决 |\n| `decision/list` | `{ room }` | 决策列表 |\n| `decision/resolve` | `{ decisionId, option }` | 人类裁定 |\n| `decision/reopen` | `{ decisionId, evidence }` | 新证据重开 |\n\n**原则与指标**\n\n| 方法 | 参数 | 说明 |\n|------|------|------|\n| `principle/propose` | `{ room, text, taskId? }` | 登记 episode 经验 |\n| `principle/promote` / `principle/pin` | `{ principleId }` | 晋升（需 ≥2 来源）/ 人类 pin |\n| `principle/list` | `{ room }` | 原则列表 |\n| `reminder/create` | `{ room, agent, prompt, at }` | 定时提醒（at = epoch ms 或 ISO 字符串） |\n| `reminder/list` / `reminder/cancel` | `{ room }` / `{ reminderId }` | 提醒列表 / 取消 |\n| `llm/stats` | `{ hours? }` | LLM 台账聚合（server + agents 两侧） |\n| `metrics/get` | - | 任务/决策/gateway/registry 计数汇总 |\n\n### 通知 (Server → Client)\n\n| 通知 | 说明 |\n|------|------|\n| `turn/started` | Turn 开始执行 |\n| `turn/completed` | Turn 完成 |\n| `item/delta` | 流式输出增量 |\n| `item/completed` | Item 完成 |\n| `tool_call/started` | 工具调用开始 |\n| `tool_call/completed` | 工具调用完成 |\n| `approval/required` | 需要人工审批 |\n| `room/message` | 聊天室新消息（user/agent/system） |\n| `system/connected` | 客户端连接成功 |\n\n---\n\n## 配置详解\n\n### 完整配置示例\n\n```typescript\nimport { HarnessV2 } from './harness-v2.js';\n\nconst harness = new HarnessV2({\n  // 模型配置\n  modelProvider: 'minimax',\n  model: {\n    apiKey: process.env.MINIMAX_API_KEY!,\n    baseUrl: 'https://api.minimaxi.com/v1',\n    model: 'MiniMax-M3',\n    temperature: 0.7,\n  },\n\n  // 文件系统\n  filesystem: {\n    rootPath: './workspace',\n    allowedPaths: ['./workspace', './temp'],\n  },\n\n  // Agent 行为\n  agent: {\n    maxIterations: 10,\n    systemInstruction: 'You are a helpful assistant.',\n    enableCompaction: true,\n    compactionThreshold: 12000,\n  },\n\n  // 审批策略\n  approval: {\n    readonly: false,\n    network: false,\n    autoApprove: ['filesystem:read', 'filesystem:list'],\n    confirm: ['filesystem:write', 'shell', 'code'],\n    reject: ['rm', 'mkfs', 'dd'],\n  },\n\n  // 持久化\n  persistence: {\n    dbPath: './data/threads.db',\n  },\n\n  // 向量记忆\n  enableMemory: true,\n\n  // 传输层\n  transports: ['stdio', 'websocket'],\n\n  // Web UI\n  webUI: {\n    enabled: true,\n    port: 3456,\n    host: '0.0.0.0',\n  },\n});\n```\n\n---\n\n## 项目结构\n\n```\nagent-harness/\n├── src/\n│   ├── core/                      # 核心框架\n│   │   ├── kernel.ts              # 插件内核\n│   │   ├── plugin.ts              # 插件接口\n│   │   ├── event-bus.ts           # 事件总线\n│   │   ├── service-registry.ts    # 服务注册表\n│   │   ├── thread.ts              # Thread/Turn/Item 原语\n│   │   ├── sqlite-thread.ts       # SQLite 持久化\n│   │   ├── prompt-builder.ts      # Cache-aware prompt 构建\n│   │   ├── approver.ts            # 三级审批策略\n│   │   ├── compactor.ts           # 上下文压缩\n│   │   ├── vector-memory.ts       # 轻量 RAG\n│   │   └── scheduler.ts           # 并行调度器\n│   ├── appserver/                 # App Server\n│   │   ├── protocol.ts            # JSON-RPC 协议\n│   │   ├── server.ts              # App Server 核心\n│   │   ├── server-v2.ts           # 集成版 (SQLite + Memory)\n│   │   ├── bus-gateway.ts         # 聊天室桥（房间/扇出/@/context 注入）\n│   │   ├── task-board.ts          # 任务板（Task/Lease/重派/催办/承诺/原则）\n│   │   ├── decision-board.ts      # 决策板（quorum/timebox/anti-reopen）\n│   │   ├── stdio-transport.ts     # stdio 传输\n│   │   ├── websocket-transport.ts # WebSocket 传输（可共享静态服务端口）\n│   │   └── static-server.ts       # 静态文件服务\n│   ├── mcp/                       # MCP 协议适配\n│   │   ├── protocol.ts            # MCP 协议实现\n│   │   └── plugin.ts              # MCP 插件\n│   ├── plugins/\n│   │   ├── model/                 # 模型提供者\n│   │   │   ├── interface.ts       # 模型接口\n│   │   │   ├── openai.ts          # OpenAI 实现\n│   │   │   └── minimax.ts         # MiniMax 实现\n│   │   ├── tools/                 # 工具\n│   │   │   ├── interface.ts       # 工具接口\n│   │   │   ├── filesystem.ts      # 文件系统\n│   │   │   └── shell.ts           # Shell 执行\n│   │   ├── sandbox/               # 沙箱\n│   │   │   ├── process-sandbox.ts # 进程沙箱\n│   │   │   └── docker-sandbox.ts  # Docker 沙箱\n│   │   ├── agent-loop/            # Agent 循环\n│   │   │   └── react-loop.ts      # ReAct 实现\n│   │   ├── session/               # 会话\n│   │   │   ├── memory.ts          # 内存存储\n│   │   │   └── persistence.ts     # JSON 持久化\n│   │   ├── agent-bus/             # 多 Agent 通信\n│   │   │   ├── bus.ts             # 总线实现（内存/Redis transport）\n│   │   │   └── http-transport.ts  # HTTP 传输 + Registry（渠道/闸门/指标）\n│   │   └── observability/         # 可观测性\n│   │       └── tracer.ts          # 执行追踪\n│   ├── harness.ts                 # 基础组装\n│   ├── harness-pro.ts             # 产品级组装\n│   ├── harness-v2.ts              # V2 组装器\n│   ├── cli.ts                     # CLI 入口\n│   ├── cli-v2.ts                  # V2 CLI 入口（含终端 REPL）\n│   ├── server.ts                  # 无头服务入口（Web UI + 聊天室 gateway）\n│   ├── registry-server.ts         # Registry 独立入口（公网中继）\n│   ├── bus-agent.ts               # 独立 bus agent（LLM 判断/任务/投票/承诺）\n│   └── demo-*.ts                  # 示例脚本\n├── public/                        # Web UI 前端\n│   ├── index.html                 # 单页应用\n│   └── vendor/                    # marked / DOMPurify（本地 UMD，免 CDN）\n├── dist/                          # 编译输出\n├── package.json\n├── tsconfig.json\n└── README.md\n```\n\n---\n\n## 开发指南\n\n### 编译\n\n```bash\nnpm run build        # TypeScript 编译\nnpm run build:watch  # 监视模式\n```\n\n### 测试\n\n```bash\nnpm test             # 运行测试\n```\n\n### 添加新模型\n\n实现 `ModelProvider` 接口：\n\n```typescript\nimport { ModelProvider, Message, ToolSchema, ModelResponse } from './plugins/model/interface.js';\n\nexport class MyProvider implements ModelProvider {\n  async generate(messages: Message[], tools?: ToolSchema[]): Promise<ModelResponse> {\n    // 调用你的 API\n    return { content: 'Hello', toolCalls: [] };\n  }\n}\n```\n\n### 添加新工具\n\n实现 `Tool` 接口并注册：\n\n```typescript\nconst myTool: Tool = {\n  name: 'myTool',\n  description: 'Does something',\n  parameters: { type: 'object', properties: {} },\n  async execute(args) {\n    return { result: 'done' };\n  },\n};\n```\n\n---\n\n## 路线图\n\n### 已完成 ✅\n\n- [x] 插件化架构\n- [x] 多模型支持（OpenAI、MiniMax）\n- [x] 工具调用（文件系统、Shell、代码执行）\n- [x] 安全沙箱（进程 + Docker）\n- [x] 会话持久化（SQLite）\n- [x] 向量记忆（RAG，按 thread 隔离）\n- [x] 任务规划\n- [x] 多 Agent 通信（内存 / P2P / 跨网络渠道中继）\n- [x] 可观测性（执行追踪）\n- [x] Codex-inspired 架构（V2）\n- [x] Web UI 控制台（Markdown / 思考链折叠 / 任务面板）\n- [x] MCP 协议适配\n- [x] 子 Agent 并行调度\n- [x] 协调闸门（lapping / verbatim-dup / 速率地板 / seen-cursor / hold-token / 人类复位）\n- [x] 多 agent 聊天室（@ 点名、自主插嘴、token 预算上下文）\n- [x] 任务板（Task/Lease/评分重派/验收/ADR/风险门）\n- [x] 决策板（quorum/timebox/anti-reopen/结构化升级）\n- [x] 承诺账本与依赖图（确认入图、阻塞驱动催办）\n- [x] 记忆分层（episode→semantic 晋升门）与原则回流 agent 上下文\n- [x] Focus window（深度工作期打断经济学）\n- [x] Registry 状态落盘（在途消息重启不丢）\n- [x] Retention GC（消息/终态对象限期清理）\n\n### 计划中 📋\n\n近期（正确性补洞）：\n\n- [ ] 协调层测试套件（闸门/状态机/anti-reopen/focus window 回归网）\n- [ ] shouldInterject 成本短路（规则前置：刚发言/纯寒暄本地判 NO，减少每消息 LLM 调用）\n\n中期（能力扩展）：\n\n- [ ] 更多模型（Claude、Gemini、本地模型）\n- [ ] gateway 历史权威 failover（数据已在 SQLite，缺第二实例接管协议）\n- [ ] 更多沙箱语言（Rust、Go、Java）\n\n### 不做 ✋\n\n- 插件市场 / 可视化工作流编辑器 / 分布式集群调度——当前没有真实需求拉动\n- REST API 服务——bus registry 本身就是 HTTP 轮询 API，重复建设\n\n---\n\n## 实际案例\n\n### 案例 1：多 Agent 协作写文档\n\n```typescript\nconst scheduler = new ParallelScheduler({\n  agents: [\n    { id: 'coder', systemPrompt: 'Write code examples' },\n    { id: 'writer', systemPrompt: 'Write explanations' },\n    { id: 'reviewer', systemPrompt: 'Review for accuracy' },\n  ],\n}, model, tools);\n\nconst results = await scheduler.runParallel([\n  { id: 'code', description: 'Write quicksort implementation' },\n  { id: 'explain', description: 'Explain quicksort algorithm' },\n  { id: 'review', description: 'Review for correctness' },\n]);\n\nconst doc = await scheduler.aggregate('Create a quicksort guide', results);\n```\n\n---\n\n## 贡献指南\n\n欢迎 Issue 和 PR。设计原则：\n\n1. **插件优先**：新功能优先以插件形式实现\n2. **零依赖默认**：核心不依赖外部服务\n3. **类型安全**：TypeScript 严格模式\n4. **安全第一**：默认安全，显式授权\n\n---\n\n## 许可证\n\nMIT License\n\n---\n\n> 我不负责让场面热闹。我负责让事情变清楚。\n","readmeFilename":"README.md"}