@bolloon/bolloon-agent 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/README.md +467 -467
  2. package/bin/bolloon-cli.cjs +183 -183
  3. package/bin/bolloon.cjs +0 -0
  4. package/bin/bolloon.js +157 -0
  5. package/dist/agents/agent-manifest-protocol.js +0 -52
  6. package/dist/agents/constraint-layer.js +19 -19
  7. package/dist/agents/pi-sdk.js +287 -1213
  8. package/dist/agents/shell-guard.js +2 -2
  9. package/dist/agents/workflow-pivot-loop.js +2 -81
  10. package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
  11. package/dist/bollharness-integration/context-router-judgment.js +4 -4
  12. package/dist/bollharness-integration/context-router.js +292 -292
  13. package/dist/bollharness-integration/gate-state-machine.js +13 -26
  14. package/dist/bollharness-integration/integration.js +0 -71
  15. package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
  16. package/dist/bollharness-integration/skill-adapter.js +127 -52
  17. package/dist/bootstrap/context-collector.js +3 -6
  18. package/dist/bootstrap/lifecycle-hooks.js +1 -15
  19. package/dist/cli-entry.js +35 -39
  20. package/dist/constraint-runtime/src/_archive_helper.js +9 -0
  21. package/dist/constraint-runtime/src/agent/coordinator.js +48 -0
  22. package/dist/constraint-runtime/src/agent/index.js +1 -0
  23. package/dist/constraint-runtime/src/assistant/index.js +12 -0
  24. package/dist/constraint-runtime/src/bootstrap/index.js +12 -0
  25. package/dist/constraint-runtime/src/bootstrap_graph.js +13 -0
  26. package/dist/constraint-runtime/src/bridge/index.js +12 -0
  27. package/dist/constraint-runtime/src/buddy/index.js +12 -0
  28. package/dist/constraint-runtime/src/cli/index.js +12 -0
  29. package/dist/constraint-runtime/src/command_graph.js +10 -0
  30. package/dist/constraint-runtime/src/commands.js +60 -0
  31. package/dist/constraint-runtime/src/components/index.js +12 -0
  32. package/dist/constraint-runtime/src/constants/index.js +12 -0
  33. package/dist/constraint-runtime/src/constraint/budget.js +22 -0
  34. package/dist/constraint-runtime/src/constraint/index.js +2 -0
  35. package/dist/constraint-runtime/src/constraint/permission.js +20 -0
  36. package/dist/constraint-runtime/src/context.js +30 -0
  37. package/dist/constraint-runtime/src/coordinator/index.js +12 -0
  38. package/dist/constraint-runtime/src/cost_hook.js +4 -0
  39. package/dist/constraint-runtime/src/cost_tracker.js +8 -0
  40. package/dist/constraint-runtime/src/deferred_init.js +10 -0
  41. package/dist/constraint-runtime/src/direct_modes.js +6 -0
  42. package/dist/constraint-runtime/src/dynamic-tool-loader.js +85 -0
  43. package/dist/constraint-runtime/src/entrypoints/index.js +12 -0
  44. package/dist/constraint-runtime/src/execution_registry.js +44 -0
  45. package/dist/constraint-runtime/src/history.js +9 -0
  46. package/dist/constraint-runtime/src/hooks/index.js +12 -0
  47. package/dist/constraint-runtime/src/index.js +26 -0
  48. package/dist/constraint-runtime/src/ink.js +4 -0
  49. package/dist/constraint-runtime/src/keybindings/index.js +12 -0
  50. package/dist/constraint-runtime/src/memdir/index.js +12 -0
  51. package/dist/constraint-runtime/src/migrations/index.js +12 -0
  52. package/dist/constraint-runtime/src/models.js +1 -0
  53. package/dist/constraint-runtime/src/moreright/index.js +12 -0
  54. package/dist/constraint-runtime/src/native_ts/index.js +12 -0
  55. package/dist/constraint-runtime/src/output_styles/index.js +12 -0
  56. package/dist/constraint-runtime/src/parity_audit.js +12 -0
  57. package/dist/constraint-runtime/src/plugins/index.js +12 -0
  58. package/dist/constraint-runtime/src/port_manifest.js +11 -0
  59. package/dist/constraint-runtime/src/prefetch.js +9 -0
  60. package/dist/constraint-runtime/src/query.js +1 -0
  61. package/dist/constraint-runtime/src/remote/index.js +12 -0
  62. package/dist/constraint-runtime/src/remote_runtime.js +9 -0
  63. package/dist/constraint-runtime/src/runtime/index.js +1 -0
  64. package/dist/constraint-runtime/src/runtime/session.js +35 -0
  65. package/dist/constraint-runtime/src/schemas/index.js +12 -0
  66. package/dist/constraint-runtime/src/screens/index.js +12 -0
  67. package/dist/constraint-runtime/src/server/index.js +12 -0
  68. package/dist/constraint-runtime/src/services/index.js +12 -0
  69. package/dist/constraint-runtime/src/session_store.js +22 -0
  70. package/dist/constraint-runtime/src/setup.js +30 -0
  71. package/dist/constraint-runtime/src/skills/index.js +1 -0
  72. package/dist/constraint-runtime/src/skills/skill-registry.js +28 -0
  73. package/dist/constraint-runtime/src/state/index.js +12 -0
  74. package/dist/constraint-runtime/src/system_init.js +20 -0
  75. package/dist/constraint-runtime/src/thinking/engine.js +42 -0
  76. package/dist/constraint-runtime/src/thinking/index.js +1 -0
  77. package/dist/constraint-runtime/src/tool_pool.js +8 -0
  78. package/dist/constraint-runtime/src/tools/OpenCLI/execAdapter.js +7 -0
  79. package/dist/constraint-runtime/src/tools/OpenCLI/listAdapters.js +7 -0
  80. package/dist/constraint-runtime/src/tools/OpenCLI/runCommand.js +7 -0
  81. package/dist/constraint-runtime/src/tools/SafeSDK/confirmTransaction.js +6 -0
  82. package/dist/constraint-runtime/src/tools/SafeSDK/createTransaction.js +8 -0
  83. package/dist/constraint-runtime/src/tools/SafeSDK/executeTransaction.js +6 -0
  84. package/dist/constraint-runtime/src/tools/SafeSDK/getBalance.js +6 -0
  85. package/dist/constraint-runtime/src/tools/SafeSDK/getPendingTransactions.js +6 -0
  86. package/dist/constraint-runtime/src/tools/SafeSDK/proposeTransaction.js +6 -0
  87. package/dist/constraint-runtime/src/tools.js +80 -0
  88. package/dist/constraint-runtime/src/transcript.js +19 -0
  89. package/dist/constraint-runtime/src/types/index.js +12 -0
  90. package/dist/constraint-runtime/src/upstream_proxy/index.js +12 -0
  91. package/dist/constraint-runtime/src/utils/index.js +12 -0
  92. package/dist/constraint-runtime/src/vim/index.js +12 -0
  93. package/dist/constraint-runtime/src/voice/index.js +12 -0
  94. package/dist/constraint-runtime/tests/agent.test.js +16 -0
  95. package/dist/constraint-runtime/tests/constraint.test.js +41 -0
  96. package/dist/constraint-runtime/tests/skill.test.js +19 -0
  97. package/dist/constraint-runtime/tests/thinking.test.js +22 -0
  98. package/dist/context-compaction/auto-compact.js +7 -7
  99. package/dist/electron-preload.js +1 -18
  100. package/dist/electron-preload.js.map +1 -1
  101. package/dist/electron.js +168 -3
  102. package/dist/electron.js.map +1 -1
  103. package/dist/index.js +116 -136
  104. package/dist/llm/config-store.js +8 -24
  105. package/dist/llm/llm-judgment-client.js +102 -102
  106. package/dist/llm/pi-ai.js +85 -126
  107. package/dist/llm/system-prompt/layers/channel/local.md +14 -14
  108. package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
  109. package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
  110. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  111. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  112. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  113. package/dist/llm/system-prompt/layers/core/identity.md +37 -37
  114. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  115. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  116. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  117. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  118. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  119. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  120. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  121. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  122. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  123. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  124. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  125. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  126. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  127. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  128. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  129. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  130. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  131. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  132. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  133. package/dist/llm/tool-manifest/bash.js +3 -3
  134. package/dist/llm/tool-manifest/create_file.js +4 -4
  135. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  136. package/dist/llm/tool-manifest/image_search.js +2 -2
  137. package/dist/llm/tool-manifest/mcp.js +2 -2
  138. package/dist/llm/tool-manifest/message_compose.js +3 -3
  139. package/dist/llm/tool-manifest/places.js +2 -2
  140. package/dist/llm/tool-manifest/present_files.js +1 -1
  141. package/dist/llm/tool-manifest/recipe.js +2 -2
  142. package/dist/llm/tool-manifest/str_replace.js +5 -5
  143. package/dist/llm/tool-manifest/view.js +3 -3
  144. package/dist/llm/tool-manifest/weather.js +4 -4
  145. package/dist/llm/tool-manifest/web.js +4 -4
  146. package/dist/pi-ecosystem-colony/index.js +365 -0
  147. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  148. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  149. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  150. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  151. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  152. package/dist/security/context-router-tool.js +15 -15
  153. package/dist/security/tool-gate.js +0 -11
  154. package/dist/social/ant-colony/AdaptiveHeartbeat.js +101 -0
  155. package/dist/social/ant-colony/PheromoneEngine.js +227 -0
  156. package/dist/social/ant-colony/index.js +6 -0
  157. package/dist/social/ant-colony/types.js +24 -0
  158. package/dist/test/ai-judgment-test.js +80 -0
  159. package/dist/test/bollharness-integration.test.js +318 -0
  160. package/dist/test/channel-agent-multi-dialogue.js +205 -0
  161. package/dist/test/channel-heartbeat-agent-test.js +201 -0
  162. package/dist/test/constraint-layer.test.js +164 -0
  163. package/dist/test/diap-identity-test.js +172 -0
  164. package/dist/test/diap-quick-test.js +62 -0
  165. package/dist/test/global-shared-context.test.js +315 -0
  166. package/dist/test/harness-judgment-injection.test.js +246 -0
  167. package/dist/test/harness-workflow-integrator-test.js +228 -0
  168. package/dist/test/human-value-store.test.js +243 -0
  169. package/dist/test/hybrid-integration-test.js +118 -0
  170. package/dist/test/hybrid-messenger-verify.js +55 -0
  171. package/dist/test/iroh-bistream-debug.js +38 -0
  172. package/dist/test/iroh-communication.test.js +66 -0
  173. package/dist/test/iroh-debug-test.js +57 -0
  174. package/dist/test/iroh-diap-test.js +71 -0
  175. package/dist/test/iroh-direct-connect.js +55 -0
  176. package/dist/test/iroh-e2e-fixed.js +89 -0
  177. package/dist/test/iroh-e2e-same-process.js +63 -0
  178. package/dist/test/iroh-e2e.js +66 -0
  179. package/dist/test/iroh-final-e2e.js +72 -0
  180. package/dist/test/iroh-relay-test.js +37 -0
  181. package/dist/test/iroh-simple-test.js +41 -0
  182. package/dist/test/iroh-transport-verify.js +54 -0
  183. package/dist/test/iroh-transport.test.js +37 -0
  184. package/dist/test/iroh-two-nodes.js +70 -0
  185. package/dist/test/iroh-verify.js +44 -0
  186. package/dist/test/judgment-decision.test.js +219 -0
  187. package/dist/test/llm-judgment-integration.test.js +220 -0
  188. package/dist/test/p2p-agent-complex-dialogue.js +385 -0
  189. package/dist/test/p2p-agent-dialogue.js +341 -0
  190. package/dist/test/p2p-agent-full-bidirectional.js +510 -0
  191. package/dist/test/p2p-agent-harness-flow.js +437 -0
  192. package/dist/test/p2p-agent-harness-single.js +143 -0
  193. package/dist/test/p2p-ai-dialogue-test.js +318 -0
  194. package/dist/test/p2p-cid-connect-test.js +195 -0
  195. package/dist/test/p2p-connect-receiver.js +69 -0
  196. package/dist/test/p2p-doc-transfer.js +110 -0
  197. package/dist/test/p2p-identity-page-test.js +77 -0
  198. package/dist/test/p2p-iroh-test.js +171 -0
  199. package/dist/test/p2p-minimal-test.js +241 -0
  200. package/dist/test/p2p-node-1.js +148 -0
  201. package/dist/test/p2p-node-2.js +148 -0
  202. package/dist/test/p2p-server.js +281 -0
  203. package/dist/test/p2p-two-nodes-test.js +438 -0
  204. package/dist/test/pi-sdk.test.js +44 -0
  205. package/dist/test/set-persona.js +40 -0
  206. package/dist/test/simple.test.js +9 -0
  207. package/dist/test/storage-integration.test.js +150 -0
  208. package/dist/test/subagent-manager.test.js +276 -0
  209. package/dist/test/test-gate-flow.test.js +81 -0
  210. package/dist/test/workflow-engine.test.js +87 -0
  211. package/dist/test/workflow-pivot-loop.test.js +246 -0
  212. package/dist/web/api-config.html +520 -520
  213. package/dist/web/client.js +2917 -3791
  214. package/dist/web/components/p2p/index.js +234 -276
  215. package/dist/web/components/wallet-viem.mjs +118 -118
  216. package/dist/web/index.html +374 -373
  217. package/dist/web/manifest.json +20 -20
  218. package/dist/web/server.js +23 -775
  219. package/dist/web/style.css +4737 -4737
  220. package/dist/web/ui/message-renderer.js +373 -451
  221. package/dist/web/ui/step-timeline.js +255 -351
  222. package/package.json +160 -157
  223. package/scripts/build-cli.js +216 -0
  224. package/scripts/build-web.ts +125 -0
  225. package/scripts/postinstall.js +153 -0
  226. package/bin/bolloon-daemon.sh +0 -207
  227. package/bin/ipfs +0 -0
  228. package/dist/agents/chat-segmenter.js +0 -298
  229. package/dist/agents/judgment-protocol.js +0 -479
  230. package/dist/agents/parse-tool-call.js +0 -304
  231. package/dist/agents/peer-manifest-loader.js +0 -210
  232. package/dist/agents/react-loop.js +0 -120
  233. package/dist/agents/session-store.js +0 -171
  234. package/dist/agents/tool-registry.js +0 -136
  235. package/dist/bootstrap/chat-archiver.js +0 -276
  236. package/dist/bootstrap/memory-compressor.js +0 -170
  237. package/dist/bootstrap/persona-loader.js +0 -94
  238. package/dist/electron/config.js +0 -16
  239. package/dist/electron/config.js.map +0 -1
  240. package/dist/electron/dialogs.js +0 -71
  241. package/dist/electron/dialogs.js.map +0 -1
  242. package/dist/electron/first-run.js +0 -129
  243. package/dist/electron/first-run.js.map +0 -1
  244. package/dist/electron/ipc.js +0 -16
  245. package/dist/electron/ipc.js.map +0 -1
  246. package/dist/electron/logger.js +0 -77
  247. package/dist/electron/logger.js.map +0 -1
  248. package/dist/electron/main.js +0 -60
  249. package/dist/electron/main.js.map +0 -1
  250. package/dist/electron/menu.js +0 -140
  251. package/dist/electron/menu.js.map +0 -1
  252. package/dist/electron/paths.js +0 -33
  253. package/dist/electron/paths.js.map +0 -1
  254. package/dist/electron/server.js +0 -74
  255. package/dist/electron/server.js.map +0 -1
  256. package/dist/electron/tray.js +0 -73
  257. package/dist/electron/tray.js.map +0 -1
  258. package/dist/electron/window.js +0 -69
  259. package/dist/electron/window.js.map +0 -1
  260. package/dist/network/local-inbox-bus.js +0 -73
  261. package/dist/network/p2p-outbox.js +0 -161
  262. package/dist/network/peer-fs.js +0 -420
  263. package/dist/network/peer-resource-bridge.js +0 -216
  264. package/dist/web/components/p2p/P2PModal.js +0 -188
  265. package/dist/web/components/p2p/p2p-modal.js +0 -664
  266. package/dist/web/components/p2p/p2p-tools.js +0 -248
  267. package/dist/web/input-validator.js +0 -103
  268. package/dist/web/util/safe-name.js +0 -32
@@ -18,9 +18,9 @@ export const fetch_sports_data = {
18
18
  { name: 'league', type: 'enum', required: true, description: 'nfl/nba/nhl/mlb/wnba/ncaafb/ncaamb/ncaawb/epl/la_liga/serie_a/bundesliga/ligue_1/mls/champions_league/tennis/golf/nascar/cricket/mma', enumValues: ['nfl', 'nba', 'nhl', 'mlb', 'wnba', 'ncaafb', 'ncaamb', 'ncaawb', 'epl', 'la_liga', 'serie_a', 'bundesliga', 'ligue_1', 'mls', 'champions_league', 'tennis', 'golf', 'nascar', 'cricket', 'mma'] },
19
19
  { name: 'team', type: 'string', required: false, description: '可选的球队名称' },
20
20
  ],
21
- callExample: `[TOOL:fetch_sports_data]
22
- [P:data_type]scores
23
- [P:league]nba
21
+ callExample: `[TOOL:fetch_sports_data]
22
+ [P:data_type]scores
23
+ [P:league]nba
24
24
  [ENDTOOL]`,
25
25
  layerId: 'tool.manifest',
26
26
  };
@@ -17,8 +17,8 @@ export const image_search = {
17
17
  { name: 'max_results', type: 'integer', required: false, description: '返回图片数 (默认 3, 最少 3, 最多 5)', minimum: 3, maximum: 5, default: 3 },
18
18
  { name: 'query', type: 'string', required: true, description: '搜索查询 (3-6 词具体)' },
19
19
  ],
20
- callExample: `[TOOL:image_search]
21
- [P:query]Eiffel Tower Paris
20
+ callExample: `[TOOL:image_search]
21
+ [P:query]Eiffel Tower Paris
22
22
  [ENDTOOL]`,
23
23
  layerId: 'tool.image_search',
24
24
  };
@@ -15,7 +15,7 @@ export const search_mcp_registry = {
15
15
  parameters: [
16
16
  { name: 'keywords', type: 'array', required: true, description: '搜索关键词', minItems: 1, items: { name: 'kw', type: 'string', required: true, description: '关键词' } }
17
17
  ],
18
- callExample: `[TOOL:search_mcp_registry]
18
+ callExample: `[TOOL:search_mcp_registry]
19
19
  [P:keywords]${'${'}JSON.stringify(["calendar","schedule"])[ENDTOOL]`,
20
20
  layerId: 'tool.mcp_apps',
21
21
  };
@@ -37,7 +37,7 @@ export const suggest_connectors = {
37
37
  parameters: [
38
38
  { name: 'uuids', type: 'array', required: true, description: '从 search_mcp_registry 结果的 directoryUuid 复制', minItems: 1, items: { name: 'u', type: 'string', required: true, description: 'uuid' } }
39
39
  ],
40
- callExample: `[TOOL:suggest_connectors]
40
+ callExample: `[TOOL:suggest_connectors]
41
41
  [P:uuids]${'${'}JSON.stringify(["uuid-from-search-result"])[ENDTOOL]`,
42
42
  layerId: 'tool.mcp_apps',
43
43
  };
@@ -23,9 +23,9 @@ export const message_compose_v1 = {
23
23
  ],
24
24
  } },
25
25
  ],
26
- callExample: `[TOOL:message_compose_v1]
27
- [P:kind]email
28
- [P:summary_title]Follow-up on Q3 review
26
+ callExample: `[TOOL:message_compose_v1]
27
+ [P:kind]email
28
+ [P:summary_title]Follow-up on Q3 review
29
29
  [P:variants]${'${'}JSON.stringify([{"label":"direct","subject":"Quick follow-up","body":"..."}])[ENDTOOL]`,
30
30
  layerId: 'tool.manifest',
31
31
  };
@@ -23,7 +23,7 @@ export const places_search = {
23
23
  { name: 'location_bias_lng', type: 'number', required: false, description: '可选经度' },
24
24
  { name: 'location_bias_radius', type: 'number', required: false, description: '米 (默认 5000)', default: 5000 }
25
25
  ],
26
- callExample: `[TOOL:places_search]
26
+ callExample: `[TOOL:places_search]
27
27
  [P:queries]${'${'}JSON.stringify([{"query":"ramen restaurants Tokyo"}])[ENDTOOL]`,
28
28
  layerId: 'tool.manifest',
29
29
  };
@@ -77,7 +77,7 @@ export const places_map_display_v0 = {
77
77
  { name: 'title', type: 'string', required: false, description: '行程标题' },
78
78
  { name: 'narrative', type: 'string', required: false, description: '行程叙述' },
79
79
  ],
80
- callExample: `[TOOL:places_map_display_v0]
80
+ callExample: `[TOOL:places_map_display_v0]
81
81
  [P:locations]${'${'}JSON.stringify([{"name":"Senso-ji","latitude":35.7148,"longitude":139.7967,"place_id":"ChIJ..."}])[ENDTOOL]`,
82
82
  layerId: 'tool.manifest',
83
83
  };
@@ -15,7 +15,7 @@ export const present_files = {
15
15
  parameters: [
16
16
  { name: 'filepaths', type: 'array', required: true, description: '至少 1 个文件路径', minItems: 1, items: { name: 'path', type: 'string', required: true, description: '容器内路径' } },
17
17
  ],
18
- callExample: `[TOOL:present_files]
18
+ callExample: `[TOOL:present_files]
19
19
  [P:filepaths]${'${'}JSON.stringify(["/home/bolloon/report.md"])[ENDTOOL]`,
20
20
  layerId: 'tool.manifest',
21
21
  };
@@ -33,8 +33,8 @@ export const recipe_display_v0 = {
33
33
  } },
34
34
  { name: 'notes', type: 'string', required: false, description: '附加说明' },
35
35
  ],
36
- callExample: `[TOOL:recipe_display_v0]
37
- [P:title]Pasta
36
+ callExample: `[TOOL:recipe_display_v0]
37
+ [P:title]Pasta
38
38
  [P:ingredients]${'${'}JSON.stringify([{"id":"a1","amount":500,"name":"pasta"}])[ENDTOOL]`,
39
39
  layerId: 'tool.manifest',
40
40
  };
@@ -17,11 +17,11 @@ export const str_replace = {
17
17
  { name: 'new_str', type: 'string', required: true, description: '新字符串 (空字符串 = 删除)', default: '' },
18
18
  { name: 'path', type: 'string', required: true, description: '文件路径' },
19
19
  ],
20
- callExample: `[TOOL:str_replace]
21
- [P:description]修复 typo
22
- [P:old_str]recieve
23
- [P:new_str]receive
24
- [P:path]/home/bolloon/main.py
20
+ callExample: `[TOOL:str_replace]
21
+ [P:description]修复 typo
22
+ [P:old_str]recieve
23
+ [P:new_str]receive
24
+ [P:path]/home/bolloon/main.py
25
25
  [ENDTOOL]`,
26
26
  layerId: 'tool.manifest',
27
27
  };
@@ -16,9 +16,9 @@ export const view = {
16
16
  { name: 'path', type: 'string', required: true, description: '绝对路径' },
17
17
  { name: 'view_range', type: 'array', required: false, description: '[start, end] 1-indexed, end=-1 表示到末尾', minItems: 2, maxItems: 2, items: { name: 'r', type: 'integer', required: true, description: '行号' } }
18
18
  ],
19
- callExample: `[TOOL:view]
20
- [P:description]读 README
21
- [P:path]/home/bolloon/README.md
19
+ callExample: `[TOOL:view]
20
+ [P:description]读 README
21
+ [P:path]/home/bolloon/README.md
22
22
  [ENDTOOL]`,
23
23
  layerId: 'tool.manifest',
24
24
  };
@@ -18,10 +18,10 @@ export const weather_fetch = {
18
18
  { name: 'latitude', type: 'number', required: true, description: '纬度' },
19
19
  { name: 'longitude', type: 'number', required: true, description: '经度' },
20
20
  ],
21
- callExample: `[TOOL:weather_fetch]
22
- [P:location_name]San Francisco, CA
23
- [P:latitude]37.78
24
- [P:longitude]-122.41
21
+ callExample: `[TOOL:weather_fetch]
22
+ [P:location_name]San Francisco, CA
23
+ [P:latitude]37.78
24
+ [P:longitude]-122.41
25
25
  [ENDTOOL]`,
26
26
  layerId: 'tool.manifest',
27
27
  };
@@ -15,8 +15,8 @@ export const web_search = {
15
15
  parameters: [
16
16
  { name: 'query', type: 'string', required: true, description: '搜索查询 (1-6 词最佳)' },
17
17
  ],
18
- callExample: `[TOOL:web_search]
19
- [P:query]S&P 500 current price
18
+ callExample: `[TOOL:web_search]
19
+ [P:query]S&P 500 current price
20
20
  [ENDTOOL]`,
21
21
  layerId: 'tool.web_search',
22
22
  };
@@ -44,8 +44,8 @@ export const web_fetch = {
44
44
  { name: 'web_fetch_rate_limit_key', type: 'string', required: false, description: '速率限制键' },
45
45
  { name: 'web_fetch_rate_limit_dark_launch', type: 'boolean', required: false, description: '速率限制暗启动模式' },
46
46
  ],
47
- callExample: `[TOOL:web_fetch]
48
- [P:url]https://example.com/article
47
+ callExample: `[TOOL:web_fetch]
48
+ [P:url]https://example.com/article
49
49
  [ENDTOOL]`,
50
50
  layerId: 'tool.manifest',
51
51
  };
@@ -0,0 +1,365 @@
1
+ /**
2
+ * Pi Ant Colony Integration for Bolloon
3
+ *
4
+ * Multi-agent collaboration system with white-box signal protocol.
5
+ * Based on oh-pi's ant colony system: COLONY_SIGNAL protocol for agent coordination.
6
+ *
7
+ * Signal Protocol:
8
+ * COLONY_SIGNAL:LAUNCHED → SCOUTING → WORKING → REVIEWING → COMPLETE
9
+ *
10
+ * Key features:
11
+ * - Fully visible signal protocol (no black boxes)
12
+ * - Per-ant turn limits, cost tracking, concurrent scheduling
13
+ * - White-box design: no "what is it doing in the background" anxiety
14
+ */
15
+ import { EventEmitter } from 'events';
16
+ import * as fs from 'fs/promises';
17
+ import * as path from 'path';
18
+ // Colony state
19
+ const ants = new Map();
20
+ const tasks = new Map();
21
+ const signalHistory = [];
22
+ const STATE_DIR = path.join(process.env.HOME || '/tmp', '.bolloon', 'colony');
23
+ // Event emitter
24
+ class ColonyEventEmitter extends EventEmitter {
25
+ }
26
+ const colonyEvents = new ColonyEventEmitter();
27
+ /**
28
+ * Generate a unique ant ID
29
+ */
30
+ function generateAntId() {
31
+ return `ant-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
32
+ }
33
+ /**
34
+ * Register a new ant in the colony
35
+ */
36
+ export function registerAnt(name, role, maxTurns = 10, tokenBudget = 50000) {
37
+ const id = generateAntId();
38
+ const ant = {
39
+ id,
40
+ name,
41
+ role,
42
+ signal: 'LAUNCHED',
43
+ turnCount: 0,
44
+ maxTurns,
45
+ tokenBudget,
46
+ tokensUsed: 0,
47
+ createdAt: new Date().toISOString(),
48
+ updatedAt: new Date().toISOString(),
49
+ };
50
+ ants.set(id, ant);
51
+ emitSignal(id, 'LAUNCHED');
52
+ console.log(`[Colony] Registered ant: ${name} (${role})`);
53
+ return ant;
54
+ }
55
+ /**
56
+ * Emit a signal transition
57
+ */
58
+ function emitSignal(antId, newSignal, details) {
59
+ const ant = ants.get(antId);
60
+ if (!ant)
61
+ return;
62
+ const event = {
63
+ antId,
64
+ antName: ant.name,
65
+ fromSignal: ant.signal,
66
+ toSignal: newSignal,
67
+ timestamp: new Date().toISOString(),
68
+ details,
69
+ };
70
+ signalHistory.push(event);
71
+ if (signalHistory.length > 100) {
72
+ signalHistory.shift();
73
+ }
74
+ ant.signal = newSignal;
75
+ ant.updatedAt = new Date().toISOString();
76
+ ants.set(antId, ant);
77
+ colonyEvents.emit('signal', event);
78
+ console.log(`[Colony] ${ant.name}: ${event.fromSignal} → ${event.toSignal}${details ? ` (${details})` : ''}`);
79
+ }
80
+ /**
81
+ * Transition ant to SCOUTING
82
+ */
83
+ export function antScouting(antId, task) {
84
+ const ant = ants.get(antId);
85
+ if (!ant)
86
+ return;
87
+ ant.task = task;
88
+ ants.set(antId, ant);
89
+ emitSignal(antId, 'SCOUTING', `Task: ${task.substring(0, 50)}...`);
90
+ }
91
+ /**
92
+ * Transition ant to WORKING
93
+ */
94
+ export function antWorking(antId) {
95
+ const ant = ants.get(antId);
96
+ if (!ant)
97
+ return;
98
+ emitSignal(antId, 'WORKING');
99
+ }
100
+ /**
101
+ * Transition ant to REVIEWING
102
+ */
103
+ export function antReviewing(antId) {
104
+ emitSignal(antId, 'REVIEWING');
105
+ }
106
+ /**
107
+ * Complete ant work
108
+ */
109
+ export function antComplete(antId, result) {
110
+ const ant = ants.get(antId);
111
+ if (!ant)
112
+ return;
113
+ ant.result = result;
114
+ ants.set(antId, ant);
115
+ emitSignal(antId, 'COMPLETE', `Result: ${result.substring(0, 50)}...`);
116
+ }
117
+ /**
118
+ * Fail ant work
119
+ */
120
+ export function antFail(antId, error) {
121
+ const ant = ants.get(antId);
122
+ if (!ant)
123
+ return;
124
+ ant.result = error;
125
+ ants.set(antId, ant);
126
+ emitSignal(antId, 'FAILED', error);
127
+ }
128
+ /**
129
+ * Abort ant work
130
+ */
131
+ export function antAbort(antId, reason) {
132
+ emitSignal(antId, 'ABORTED', reason);
133
+ }
134
+ /**
135
+ * Increment turn count
136
+ */
137
+ export function antTick(antId, tokensUsed = 0) {
138
+ const ant = ants.get(antId);
139
+ if (!ant)
140
+ return;
141
+ ant.turnCount++;
142
+ ant.tokensUsed += tokensUsed;
143
+ ant.updatedAt = new Date().toISOString();
144
+ ants.set(antId, ant);
145
+ // Check if exceeded limits
146
+ if (ant.turnCount >= ant.maxTurns) {
147
+ antAbort(antId, 'Max turns exceeded');
148
+ }
149
+ else if (ant.tokensUsed >= ant.tokenBudget) {
150
+ antAbort(antId, 'Token budget exceeded');
151
+ }
152
+ }
153
+ /**
154
+ * Create a colony task
155
+ */
156
+ export function createTask(description) {
157
+ const id = `task-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
158
+ const task = {
159
+ id,
160
+ description,
161
+ status: 'pending',
162
+ assignedAnts: [],
163
+ results: new Map(),
164
+ createdAt: new Date().toISOString(),
165
+ };
166
+ tasks.set(id, task);
167
+ console.log(`[Colony] Created task: ${id} - ${description.substring(0, 50)}...`);
168
+ return task;
169
+ }
170
+ /**
171
+ * Dispatch task to ants
172
+ */
173
+ export function dispatchTask(taskId, antIds) {
174
+ const task = tasks.get(taskId);
175
+ if (!task)
176
+ return;
177
+ task.status = 'dispatched';
178
+ task.assignedAnts = antIds;
179
+ tasks.set(taskId, task);
180
+ for (const antId of antIds) {
181
+ const ant = ants.get(antId);
182
+ if (ant) {
183
+ antScouting(antId, task.description);
184
+ }
185
+ }
186
+ console.log(`[Colony] Dispatched task ${taskId} to ${antIds.length} ants`);
187
+ }
188
+ /**
189
+ * Record ant result for a task
190
+ */
191
+ export function recordResult(taskId, antId, result) {
192
+ const task = tasks.get(taskId);
193
+ if (!task)
194
+ return;
195
+ task.results.set(antId, result);
196
+ // Check if all ants completed
197
+ if (task.results.size === task.assignedAnts.length) {
198
+ task.status = 'completed';
199
+ task.completedAt = new Date().toISOString();
200
+ for (const id of task.assignedAnts) {
201
+ antReviewing(id);
202
+ }
203
+ }
204
+ tasks.set(taskId, task);
205
+ }
206
+ /**
207
+ * Get ant by ID
208
+ */
209
+ export function getAnt(antId) {
210
+ return ants.get(antId);
211
+ }
212
+ /**
213
+ * List all ants
214
+ */
215
+ export function listAnts() {
216
+ return Array.from(ants.values());
217
+ }
218
+ /**
219
+ * List ants by role
220
+ */
221
+ export function listAntsByRole(role) {
222
+ return Array.from(ants.values()).filter((a) => a.role === role);
223
+ }
224
+ /**
225
+ * Get ants by signal state
226
+ */
227
+ export function listAntsBySignal(signal) {
228
+ return Array.from(ants.values()).filter((a) => a.signal === signal);
229
+ }
230
+ /**
231
+ * Get active ants (not complete/failed/aborted)
232
+ */
233
+ export function getActiveAnts() {
234
+ return Array.from(ants.values()).filter((a) => !['COMPLETE', 'FAILED', 'ABORTED'].includes(a.signal));
235
+ }
236
+ /**
237
+ * Get task by ID
238
+ */
239
+ export function getTask(taskId) {
240
+ return tasks.get(taskId);
241
+ }
242
+ /**
243
+ * List all tasks
244
+ */
245
+ export function listTasks() {
246
+ return Array.from(tasks.values());
247
+ }
248
+ /**
249
+ * Get signal history
250
+ */
251
+ export function getSignalHistory() {
252
+ return [...signalHistory];
253
+ }
254
+ /**
255
+ * Get colony status
256
+ */
257
+ export function getColonyStatus() {
258
+ const antList = Array.from(ants.values());
259
+ const taskList = Array.from(tasks.values());
260
+ const signalDistribution = {
261
+ LAUNCHED: 0,
262
+ SCOUTING: 0,
263
+ WORKING: 0,
264
+ REVIEWING: 0,
265
+ COMPLETE: 0,
266
+ FAILED: 0,
267
+ ABORTED: 0,
268
+ };
269
+ for (const ant of antList) {
270
+ signalDistribution[ant.signal]++;
271
+ }
272
+ return {
273
+ antCount: antList.length,
274
+ activeAnts: antList.filter((a) => !['COMPLETE', 'FAILED', 'ABORTED'].includes(a.signal)).length,
275
+ taskCount: taskList.length,
276
+ activeTasks: taskList.filter((t) => t.status === 'in_progress' || t.status === 'dispatched').length,
277
+ signalDistribution,
278
+ };
279
+ }
280
+ /**
281
+ * Subscribe to colony events
282
+ */
283
+ export function onColonyEvent(event, callback) {
284
+ colonyEvents.on(event, callback);
285
+ }
286
+ /**
287
+ * Unsubscribe from colony events
288
+ */
289
+ export function offColonyEvent(event, callback) {
290
+ colonyEvents.off(event, callback);
291
+ }
292
+ /**
293
+ * Get formatted colony dump for debugging
294
+ */
295
+ export function getColonyDump() {
296
+ const status = getColonyStatus();
297
+ const active = getActiveAnts();
298
+ let dump = '# Colony Status\n\n';
299
+ dump += `Ants: ${status.antCount} total, ${status.activeAnts} active\n`;
300
+ dump += `Tasks: ${status.taskCount} total, ${status.activeTasks} active\n\n`;
301
+ dump += '## Signal Distribution\n';
302
+ for (const [signal, count] of Object.entries(status.signalDistribution)) {
303
+ if (count > 0) {
304
+ dump += `- ${signal}: ${count}\n`;
305
+ }
306
+ }
307
+ dump += '\n## Active Ants\n';
308
+ for (const ant of active) {
309
+ dump += `- ${ant.name} (${ant.role}): ${ant.signal} [${ant.turnCount}/${ant.maxTurns} turns, ${ant.tokensUsed}/${ant.tokenBudget} tokens]\n`;
310
+ if (ant.task) {
311
+ dump += ` Task: ${ant.task.substring(0, 60)}...\n`;
312
+ }
313
+ }
314
+ dump += '\n## Recent Signals\n';
315
+ const recent = signalHistory.slice(-10);
316
+ for (const event of recent.reverse()) {
317
+ dump += `- ${event.timestamp}: ${event.antName}: ${event.fromSignal} → ${event.toSignal}\n`;
318
+ }
319
+ return dump;
320
+ }
321
+ /**
322
+ * Persist colony state
323
+ */
324
+ export async function persistColony() {
325
+ try {
326
+ await fs.mkdir(STATE_DIR, { recursive: true });
327
+ const state = {
328
+ ants: Array.from(ants.values()),
329
+ tasks: Array.from(tasks.entries()).map(([id, t]) => ({
330
+ ...t,
331
+ results: Array.from(t.results.entries()),
332
+ })),
333
+ signalHistory: signalHistory.slice(-50),
334
+ persistedAt: new Date().toISOString(),
335
+ };
336
+ await fs.writeFile(path.join(STATE_DIR, 'colony.json'), JSON.stringify(state, null, 2));
337
+ console.log('[Colony] Persisted state');
338
+ }
339
+ catch (e) {
340
+ console.warn('[Colony] Failed to persist:', e);
341
+ }
342
+ }
343
+ /**
344
+ * Load colony state
345
+ */
346
+ export async function loadColony() {
347
+ try {
348
+ const data = await fs.readFile(path.join(STATE_DIR, 'colony.json'), 'utf-8');
349
+ const state = JSON.parse(data);
350
+ ants.clear();
351
+ for (const a of state.ants) {
352
+ ants.set(a.id, a);
353
+ }
354
+ tasks.clear();
355
+ for (const t of state.tasks) {
356
+ tasks.set(t.id, { ...t, results: new Map(t.results) });
357
+ }
358
+ signalHistory.length = 0;
359
+ signalHistory.push(...state.signalHistory);
360
+ console.log(`[Colony] Loaded ${ants.size} ants, ${tasks.size} tasks`);
361
+ }
362
+ catch {
363
+ // No persisted state
364
+ }
365
+ }
@@ -81,21 +81,21 @@ function getLLM() {
81
81
  }
82
82
  return cachedModel;
83
83
  }
84
- const CORRELATION_PROMPT = `你是"判断力关联分析器"。给定两条 judgment:
85
- A: {a}
86
- B: {b}
87
-
88
- 它们经常在同一对话里被同时注入 (共现 {co} 次).
89
- 判断 A 与 B 的因果关系:
90
- - "A→B": A 引发 B (A 概念在 B 之前)
91
- - "B→A": B 引发 A
92
- - "common_cause": 共同原因 (e.g. 都是某场景触发)
93
- - "unclear": 关系不明确
94
-
95
- 输出严格 JSON:
96
- {
97
- "direction": "A→B" | "B→A" | "common_cause" | "unclear",
98
- "explanation": "≤100 字解释, 含 1 个具体例"
84
+ const CORRELATION_PROMPT = `你是"判断力关联分析器"。给定两条 judgment:
85
+ A: {a}
86
+ B: {b}
87
+
88
+ 它们经常在同一对话里被同时注入 (共现 {co} 次).
89
+ 判断 A 与 B 的因果关系:
90
+ - "A→B": A 引发 B (A 概念在 B 之前)
91
+ - "B→A": B 引发 A
92
+ - "common_cause": 共同原因 (e.g. 都是某场景触发)
93
+ - "unclear": 关系不明确
94
+
95
+ 输出严格 JSON:
96
+ {
97
+ "direction": "A→B" | "B→A" | "common_cause" | "unclear",
98
+ "explanation": "≤100 字解释, 含 1 个具体例"
99
99
  }`;
100
100
  async function explainPair(judgmentA, judgmentB, coOccurrence) {
101
101
  const fallback = { direction: 'unclear', explanation: '(LLM 不可用, 仅显示统计)' };
@@ -213,21 +213,21 @@ export async function runCorrelationAnalysis(opts = {}) {
213
213
  }
214
214
  return out;
215
215
  }
216
- const INTERVENTION_PROMPT = `你是"判断力干预分析器"。判断力库有一条 judgment, 用户想评估它的边际贡献.
217
- 给定:
218
- - judgment: {judgment}
219
- - 上次用过的场景 (user 输入 + AI 回复): {scenario}
220
- - 同时存在的相邻 judgment (供参考): {peers}
221
-
222
- 模拟反事实推理: 如果库**没有**这条 judgment, AI 在同一场景下回答会怎么变?
223
-
224
- 输出严格 JSON:
225
- {
226
- "causalEffect": 0.0-1.0, // 0 = 无影响, 1 = 行为完全变
227
- "reasoning": "2-3 步推理, 含 1 个具体例",
228
- "confidence": 0.0-1.0
229
- }
230
-
216
+ const INTERVENTION_PROMPT = `你是"判断力干预分析器"。判断力库有一条 judgment, 用户想评估它的边际贡献.
217
+ 给定:
218
+ - judgment: {judgment}
219
+ - 上次用过的场景 (user 输入 + AI 回复): {scenario}
220
+ - 同时存在的相邻 judgment (供参考): {peers}
221
+
222
+ 模拟反事实推理: 如果库**没有**这条 judgment, AI 在同一场景下回答会怎么变?
223
+
224
+ 输出严格 JSON:
225
+ {
226
+ "causalEffect": 0.0-1.0, // 0 = 无影响, 1 = 行为完全变
227
+ "reasoning": "2-3 步推理, 含 1 个具体例",
228
+ "confidence": 0.0-1.0
229
+ }
230
+
231
231
  注意: causalEffect < 0 也合法 (如"没有这条 AI 反而更好" — 库污染)`;
232
232
  export async function runIntervention(judgmentId, opts = {}) {
233
233
  const fallback = {
@@ -273,27 +273,27 @@ export async function runIntervention(judgmentId, opts = {}) {
273
273
  return fallback;
274
274
  }
275
275
  }
276
- const COUNTERFACTUAL_PROMPT = `你是"判断力反事实审计员"。某次 AI 回复违反了注入的 judgment. 判断是库设计问题还是 LLM 偶然违规.
277
-
278
- 事件:
279
- - 用户: {userInput}
280
- - AI 回复: {aiReply}
281
- - 违反原则: {principles}
282
-
283
- 构造 3 个反事实 scenario:
284
- 1. 删去最相关那条 judgment
285
- 2. 把那条 judgment 改成反向 (例如"必须"→"避免")
286
- 3. 删去整个 channel 的 judgment 库 (空库)
287
-
288
- 每个 scenario 模拟 AI 在该库下的回答, 判断还会不会违规.
289
-
290
- 输出严格 JSON:
291
- {
292
- "scenarios": [
293
- { "modification": "...", "outcomeCompliant": true/false, "explanation": "≤100 字" }
294
- ],
295
- "verdict": "库设计合理" | "建议调库" | "需更多数据",
296
- "recomendaciones": "≤200 字, ≤3 条建议"
276
+ const COUNTERFACTUAL_PROMPT = `你是"判断力反事实审计员"。某次 AI 回复违反了注入的 judgment. 判断是库设计问题还是 LLM 偶然违规.
277
+
278
+ 事件:
279
+ - 用户: {userInput}
280
+ - AI 回复: {aiReply}
281
+ - 违反原则: {principles}
282
+
283
+ 构造 3 个反事实 scenario:
284
+ 1. 删去最相关那条 judgment
285
+ 2. 把那条 judgment 改成反向 (例如"必须"→"避免")
286
+ 3. 删去整个 channel 的 judgment 库 (空库)
287
+
288
+ 每个 scenario 模拟 AI 在该库下的回答, 判断还会不会违规.
289
+
290
+ 输出严格 JSON:
291
+ {
292
+ "scenarios": [
293
+ { "modification": "...", "outcomeCompliant": true/false, "explanation": "≤100 字" }
294
+ ],
295
+ "verdict": "库设计合理" | "建议调库" | "需更多数据",
296
+ "recomendaciones": "≤200 字, ≤3 条建议"
297
297
  }`;
298
298
  export async function runCounterfactualAudit(opts) {
299
299
  const fallback = {