@bolloon/bolloon-agent 0.3.37 → 0.3.39

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 (222) hide show
  1. package/README.md +135 -135
  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/constraint-layer.js +19 -19
  6. package/dist/agents/judgment-protocol.js +14 -14
  7. package/dist/agents/loop-review.js +58 -0
  8. package/dist/agents/pi-sdk-tools.js +107 -0
  9. package/dist/agents/pi-sdk-types.js +12 -12
  10. package/dist/agents/pi-sdk.js +133 -91
  11. package/dist/agents/workflow-pivot-loop.js +2 -2
  12. package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
  13. package/dist/bollharness-integration/context-router-judgment.js +4 -4
  14. package/dist/bollharness-integration/context-router.js +292 -292
  15. package/dist/bollharness-integration/gate-state-machine.js +13 -13
  16. package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
  17. package/dist/bollharness-integration/skill-adapter.js +21 -21
  18. package/dist/bootstrap/bootstrap.js +14 -1
  19. package/dist/bootstrap/chat-archiver.js +14 -14
  20. package/dist/bootstrap/context-collector.js +5 -1
  21. package/dist/bootstrap/context-os.js +21 -21
  22. package/dist/bootstrap/memory-compressor.js +13 -13
  23. package/dist/cli/ink-app.js +46 -8
  24. package/dist/cli/loading-tui.js +7 -5
  25. package/dist/cli/mention-data.js +2 -1
  26. package/dist/cli-entry.js +37 -37
  27. package/dist/constraint-runtime/setup.js +1 -1
  28. package/dist/constraint-runtime/tools/PolymarketSDK/cancelOrder.d.ts +3 -13
  29. package/dist/constraint-runtime/tools/PolymarketSDK/cancelOrder.js +4 -16
  30. package/dist/constraint-runtime/tools/PolymarketSDK/createOrder.d.ts +3 -24
  31. package/dist/constraint-runtime/tools/PolymarketSDK/createOrder.js +4 -31
  32. package/dist/constraint-runtime/tools/PolymarketSDK/getMarket.d.ts +0 -1
  33. package/dist/constraint-runtime/tools/PolymarketSDK/getMarket.js +3 -14
  34. package/dist/constraint-runtime/tools/PolymarketSDK/getOrders.d.ts +2 -11
  35. package/dist/constraint-runtime/tools/PolymarketSDK/getOrders.js +4 -23
  36. package/dist/constraint-runtime/tools/PolymarketSDK/listMarkets.d.ts +0 -4
  37. package/dist/constraint-runtime/tools/PolymarketSDK/listMarkets.js +2 -22
  38. package/dist/context-compaction/auto-compact.js +7 -7
  39. package/dist/electron/first-run.js +54 -54
  40. package/dist/electron-build/electron/first-run.js +54 -54
  41. package/dist/electron-build/utils/auto-update.js +8 -0
  42. package/dist/electron-build/utils/auto-update.js.map +1 -1
  43. package/dist/electron-preload.js.map +1 -1
  44. package/dist/electron.js.map +1 -1
  45. package/dist/index.js +246 -143
  46. package/dist/llm/config-store.js +18 -2
  47. package/dist/llm/llm-judgment-client.js +102 -102
  48. package/dist/llm/pi-ai.js +77 -59
  49. package/dist/llm/system-prompt/layers/channel/human-async.md +41 -41
  50. package/dist/llm/system-prompt/layers/channel/local.md +14 -14
  51. package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
  52. package/dist/llm/system-prompt/layers/channel/p2p-peer-sync.md +51 -51
  53. package/dist/llm/system-prompt/layers/channel/p2p-proactive.md +43 -43
  54. package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
  55. package/dist/llm/system-prompt/layers/channel/session-handoff.md +61 -61
  56. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  57. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  58. package/dist/llm/system-prompt/layers/core/external-engagement.md +73 -73
  59. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  60. package/dist/llm/system-prompt/layers/core/identity.md +48 -48
  61. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  62. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  63. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  64. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  65. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  66. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  67. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  68. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  69. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  70. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  71. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  72. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  73. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  74. package/dist/llm/system-prompt/layers/tool/goal_handoff.md +77 -77
  75. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  76. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  77. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  78. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  79. package/dist/llm/system-prompt/layers/tool/p2p_request.md +61 -61
  80. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  81. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  82. package/dist/llm/tool-manifest/bash.js +3 -3
  83. package/dist/llm/tool-manifest/create_file.js +4 -4
  84. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  85. package/dist/llm/tool-manifest/image_search.js +2 -2
  86. package/dist/llm/tool-manifest/index.js +0 -59
  87. package/dist/llm/tool-manifest/mcp.js +2 -2
  88. package/dist/llm/tool-manifest/message_compose.js +3 -3
  89. package/dist/llm/tool-manifest/places.js +2 -2
  90. package/dist/llm/tool-manifest/present_files.js +1 -1
  91. package/dist/llm/tool-manifest/recipe.js +2 -2
  92. package/dist/llm/tool-manifest/str_replace.js +5 -5
  93. package/dist/llm/tool-manifest/view.js +3 -3
  94. package/dist/llm/tool-manifest/weather.js +4 -4
  95. package/dist/llm/tool-manifest/web.js +4 -4
  96. package/dist/migration/external-agent-migrator.js +300 -0
  97. package/dist/pi-ecosystem-colony/index.js +365 -0
  98. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  99. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  100. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  101. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  102. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  103. package/dist/security/context-router-tool.js +15 -15
  104. package/dist/security/tool-gate.js +2 -0
  105. package/dist/social/ant-colony/AdaptiveHeartbeat.js +101 -0
  106. package/dist/social/ant-colony/PheromoneEngine.js +227 -0
  107. package/dist/social/ant-colony/index.js +6 -0
  108. package/dist/social/ant-colony/types.js +24 -0
  109. package/dist/test/ai-judgment-test.js +80 -0
  110. package/dist/test/bollharness-integration.test.js +318 -0
  111. package/dist/test/channel-agent-multi-dialogue.js +205 -0
  112. package/dist/test/channel-heartbeat-agent-test.js +201 -0
  113. package/dist/test/constraint-layer.test.js +164 -0
  114. package/dist/test/diap-identity-test.js +172 -0
  115. package/dist/test/diap-quick-test.js +62 -0
  116. package/dist/test/global-shared-context.test.js +315 -0
  117. package/dist/test/harness-judgment-injection.test.js +246 -0
  118. package/dist/test/harness-workflow-integrator-test.js +228 -0
  119. package/dist/test/human-value-store.test.js +243 -0
  120. package/dist/test/hybrid-integration-test.js +118 -0
  121. package/dist/test/hybrid-messenger-verify.js +55 -0
  122. package/dist/test/iroh-bistream-debug.js +38 -0
  123. package/dist/test/iroh-communication.test.js +66 -0
  124. package/dist/test/iroh-debug-test.js +57 -0
  125. package/dist/test/iroh-diap-test.js +71 -0
  126. package/dist/test/iroh-direct-connect.js +55 -0
  127. package/dist/test/iroh-e2e-fixed.js +89 -0
  128. package/dist/test/iroh-e2e-same-process.js +63 -0
  129. package/dist/test/iroh-e2e.js +66 -0
  130. package/dist/test/iroh-final-e2e.js +72 -0
  131. package/dist/test/iroh-relay-test.js +37 -0
  132. package/dist/test/iroh-simple-test.js +41 -0
  133. package/dist/test/iroh-transport-verify.js +54 -0
  134. package/dist/test/iroh-transport.test.js +37 -0
  135. package/dist/test/iroh-two-nodes.js +70 -0
  136. package/dist/test/iroh-verify.js +44 -0
  137. package/dist/test/judgment-decision.test.js +219 -0
  138. package/dist/test/llm-judgment-integration.test.js +220 -0
  139. package/dist/test/p2p-agent-complex-dialogue.js +385 -0
  140. package/dist/test/p2p-agent-dialogue.js +341 -0
  141. package/dist/test/p2p-agent-full-bidirectional.js +510 -0
  142. package/dist/test/p2p-agent-harness-flow.js +437 -0
  143. package/dist/test/p2p-agent-harness-single.js +143 -0
  144. package/dist/test/p2p-ai-dialogue-test.js +318 -0
  145. package/dist/test/p2p-cid-connect-test.js +195 -0
  146. package/dist/test/p2p-connect-receiver.js +69 -0
  147. package/dist/test/p2p-doc-transfer.js +110 -0
  148. package/dist/test/p2p-identity-page-test.js +77 -0
  149. package/dist/test/p2p-iroh-test.js +171 -0
  150. package/dist/test/p2p-minimal-test.js +241 -0
  151. package/dist/test/p2p-node-1.js +148 -0
  152. package/dist/test/p2p-node-2.js +148 -0
  153. package/dist/test/p2p-server.js +281 -0
  154. package/dist/test/p2p-two-nodes-test.js +438 -0
  155. package/dist/test/pi-sdk.test.js +44 -0
  156. package/dist/test/set-persona.js +40 -0
  157. package/dist/test/simple.test.js +9 -0
  158. package/dist/test/storage-integration.test.js +150 -0
  159. package/dist/test/subagent-manager.test.js +276 -0
  160. package/dist/test/test-gate-flow.test.js +81 -0
  161. package/dist/test/workflow-engine.test.js +87 -0
  162. package/dist/test/workflow-pivot-loop.test.js +246 -0
  163. package/dist/utils/auto-update.js +7 -0
  164. package/dist/web/api-config.html +779 -779
  165. package/dist/web/client-hearth.js +10 -10
  166. package/dist/web/components/wallet-viem.mjs +118 -118
  167. package/dist/web/index.html +424 -424
  168. package/dist/web/manifest.json +20 -20
  169. package/dist/web/server.js +13 -13
  170. package/dist/web/style.css +4914 -4914
  171. package/package.json +193 -193
  172. package/scripts/build-cli.js +215 -215
  173. package/scripts/build-web.ts +130 -130
  174. package/scripts/postinstall.js +152 -152
  175. package/bin/bolloon-daemon.sh +0 -207
  176. package/dist/constraint-runtime/reference_data/archive_surface_snapshot.json +0 -63
  177. package/dist/constraint-runtime/reference_data/commands_snapshot.json +0 -1037
  178. package/dist/constraint-runtime/reference_data/subsystems/assistant.json +0 -8
  179. package/dist/constraint-runtime/reference_data/subsystems/bootstrap.json +0 -8
  180. package/dist/constraint-runtime/reference_data/subsystems/bridge.json +0 -32
  181. package/dist/constraint-runtime/reference_data/subsystems/buddy.json +0 -13
  182. package/dist/constraint-runtime/reference_data/subsystems/cli.json +0 -26
  183. package/dist/constraint-runtime/reference_data/subsystems/components.json +0 -32
  184. package/dist/constraint-runtime/reference_data/subsystems/constants.json +0 -28
  185. package/dist/constraint-runtime/reference_data/subsystems/coordinator.json +0 -8
  186. package/dist/constraint-runtime/reference_data/subsystems/entrypoints.json +0 -15
  187. package/dist/constraint-runtime/reference_data/subsystems/hooks.json +0 -32
  188. package/dist/constraint-runtime/reference_data/subsystems/keybindings.json +0 -21
  189. package/dist/constraint-runtime/reference_data/subsystems/memdir.json +0 -15
  190. package/dist/constraint-runtime/reference_data/subsystems/migrations.json +0 -18
  191. package/dist/constraint-runtime/reference_data/subsystems/moreright.json +0 -8
  192. package/dist/constraint-runtime/reference_data/subsystems/native_ts.json +0 -11
  193. package/dist/constraint-runtime/reference_data/subsystems/outputStyles.json +0 -8
  194. package/dist/constraint-runtime/reference_data/subsystems/plugins.json +0 -9
  195. package/dist/constraint-runtime/reference_data/subsystems/remote.json +0 -11
  196. package/dist/constraint-runtime/reference_data/subsystems/schemas.json +0 -8
  197. package/dist/constraint-runtime/reference_data/subsystems/screens.json +0 -10
  198. package/dist/constraint-runtime/reference_data/subsystems/server.json +0 -10
  199. package/dist/constraint-runtime/reference_data/subsystems/services.json +0 -32
  200. package/dist/constraint-runtime/reference_data/subsystems/skills.json +0 -27
  201. package/dist/constraint-runtime/reference_data/subsystems/state.json +0 -13
  202. package/dist/constraint-runtime/reference_data/subsystems/types.json +0 -18
  203. package/dist/constraint-runtime/reference_data/subsystems/upstreamproxy.json +0 -9
  204. package/dist/constraint-runtime/reference_data/subsystems/utils.json +0 -32
  205. package/dist/constraint-runtime/reference_data/subsystems/vim.json +0 -12
  206. package/dist/constraint-runtime/reference_data/subsystems/voice.json +0 -8
  207. package/dist/constraint-runtime/reference_data/tools_snapshot.json +0 -922
  208. package/dist/constraint-runtime/tools/PolymarketSDK/clobShared.d.ts +0 -50
  209. package/dist/constraint-runtime/tools/PolymarketSDK/clobShared.js +0 -78
  210. package/dist/electron/config.js.map +0 -1
  211. package/dist/electron/dialogs.js.map +0 -1
  212. package/dist/electron/first-run.js.map +0 -1
  213. package/dist/electron/ipc.js.map +0 -1
  214. package/dist/electron/logger.js.map +0 -1
  215. package/dist/electron/main.js.map +0 -1
  216. package/dist/electron/menu.js.map +0 -1
  217. package/dist/electron/paths.js.map +0 -1
  218. package/dist/electron/server.js.map +0 -1
  219. package/dist/electron/tray.js.map +0 -1
  220. package/dist/electron/window.js.map +0 -1
  221. package/dist/utils/auto-update.js.map +0 -1
  222. package/dist/web/client.js.map +0 -7
package/bin/bolloon.js ADDED
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+ const path = require("path");
3
+ const { spawn } = require("child_process");
4
+ const fs = require("fs");
5
+
6
+ const RESET = "\x1b[0m";
7
+ const BOLD = "\x1b[1m";
8
+ const CYAN = "\x1b[36m";
9
+ const GREEN = "\x1b[32m";
10
+ const MAGENTA = "\x1b[35m";
11
+
12
+ function log(msg, color) {
13
+ console.log((color || RESET) + msg + RESET);
14
+ }
15
+
16
+ function printBanner() {
17
+ console.log("\n" + CYAN + BOLD + [
18
+ " ╔═══════════════════════════════════════════╗",
19
+ " ║ 🤖 Bolloon Agent ║",
20
+ " ║ P2P AI Document Processor ║",
21
+ " ╚═══════════════════════════════════════════╝"
22
+ ].join("\n") + RESET + "\n");
23
+ }
24
+
25
+ function getMainEntry() {
26
+ const distDir = path.dirname(require.main.filename);
27
+ const distIndex = path.join(distDir, "index.js");
28
+ if (fs.existsSync(distIndex)) {
29
+ return distIndex;
30
+ }
31
+ return path.join(process.cwd(), "src", "index.ts");
32
+ }
33
+
34
+ function parseArgs() {
35
+ const args = process.argv.slice(2);
36
+ if (args.length === 0) {
37
+ return { mode: "gui", args: [] };
38
+ }
39
+ const first = args[0];
40
+ switch (first) {
41
+ case "-v":
42
+ case "--version":
43
+ return { mode: "version", args: [] };
44
+ case "-h":
45
+ case "--help":
46
+ return { mode: "help", args: [] };
47
+ case "-g":
48
+ case "--gui":
49
+ return { mode: "gui", args: args.slice(1) };
50
+ case "-w":
51
+ case "--web":
52
+ return { mode: "web", args: args.slice(1) };
53
+ case "-c":
54
+ case "--cli":
55
+ return { mode: "cli", args: args.slice(1) };
56
+ default:
57
+ return { mode: "passthrough", args };
58
+ }
59
+ }
60
+
61
+ async function startElectron(additionalArgs) {
62
+ try {
63
+ const electron = require("electron");
64
+ const distDir = path.dirname(require.main.filename);
65
+ let mainPath = path.join(distDir, "electron.js");
66
+ if (!fs.existsSync(mainPath)) {
67
+ mainPath = path.join(process.cwd(), "src", "electron.ts");
68
+ }
69
+ log("启动 Electron...", CYAN);
70
+ const child = spawn(electron, [mainPath, ...additionalArgs], {
71
+ stdio: "inherit",
72
+ env: { ...process.env, NODE_ENV: "development" }
73
+ });
74
+ child.on("error", (err) => {
75
+ log("Electron 启动失败: " + err.message, MAGENTA);
76
+ process.exit(1);
77
+ });
78
+ child.on("exit", (code) => process.exit(code || 0));
79
+ } catch (err) {
80
+ log("Electron 不可用,切换到 Web 模式...", CYAN);
81
+ await startWebServer(additionalArgs);
82
+ }
83
+ }
84
+
85
+ async function startWebServer(additionalArgs) {
86
+ const mainPath = getMainEntry();
87
+ const webArgs = ["--web", ...additionalArgs];
88
+ log("启动 Web 服务...", CYAN);
89
+ const child = spawn(process.execPath, [mainPath, ...webArgs], { stdio: "inherit" });
90
+ child.on("error", (err) => {
91
+ log("Web 服务启动失败: " + err.message, MAGENTA);
92
+ process.exit(1);
93
+ });
94
+ child.on("exit", (code) => process.exit(code || 0));
95
+ }
96
+
97
+ async function startCLI(additionalArgs) {
98
+ const mainPath = getMainEntry();
99
+ log("启动命令行界面...", CYAN);
100
+ const child = spawn(process.execPath, [mainPath, ...additionalArgs], { stdio: "inherit" });
101
+ child.on("error", (err) => {
102
+ log("CLI 启动失败: " + err.message, MAGENTA);
103
+ process.exit(1);
104
+ });
105
+ child.on("exit", (code) => process.exit(code || 0));
106
+ }
107
+
108
+ async function main() {
109
+ const { mode, args } = parseArgs();
110
+ switch (mode) {
111
+ case "version":
112
+ console.log("Bolloon Agent v0.1.1");
113
+ break;
114
+ case "help":
115
+ printBanner();
116
+ console.log(BOLD + "用法:" + RESET + " bolloon [选项] [命令] [参数]");
117
+ console.log(BOLD + "选项:" + RESET + " --gui, -g 启动图形界面");
118
+ console.log(" --web, -w 启动 Web UI");
119
+ console.log(" --cli, -c 启动命令行界面");
120
+ console.log(" --version, -v 显示版本");
121
+ console.log(" --help, -h 显示帮助");
122
+ console.log(BOLD + "示例:" + RESET + " bolloon # 启动图形界面");
123
+ console.log(" bolloon --web # 启动 Web UI");
124
+ console.log(" bolloon --read file # 读取文档");
125
+ break;
126
+ case "gui":
127
+ printBanner();
128
+ await startElectron(args);
129
+ break;
130
+ case "web":
131
+ printBanner();
132
+ await startWebServer(args);
133
+ break;
134
+ case "cli":
135
+ await startCLI(args);
136
+ break;
137
+ case "passthrough":
138
+ const mainPath = getMainEntry();
139
+ const child = spawn(process.execPath, [mainPath, ...args], { stdio: "inherit" });
140
+ child.on("error", (err) => {
141
+ log("执行失败: " + err.message, MAGENTA);
142
+ process.exit(1);
143
+ });
144
+ child.on("exit", (code) => process.exit(code || 0));
145
+ break;
146
+ default:
147
+ log("未知模式: " + mode, MAGENTA);
148
+ printBanner();
149
+ console.log("输入 --help 查看帮助");
150
+ process.exit(1);
151
+ }
152
+ }
153
+
154
+ main().catch((err) => {
155
+ console.error("Fatal error:", err);
156
+ process.exit(1);
157
+ });
@@ -7,25 +7,25 @@ import { ToolPermissionContext, BudgetTracker } from '@bolloon/constraint-runtim
7
7
  * System prompt for constraint layer
8
8
  * Defines boundaries and autonomous permissions
9
9
  */
10
- export const SYSTEM_PROMPT = `
11
- 你是一个文档处理Agent,在以下规则下运行:
12
-
13
- 【边界规则】
14
- 1. 只处理:txt, md, pdf, docx 格式文档
15
- 2. 不修改原始文件,只输出改进版本
16
- 3. 发送前必须记录操作日志
17
-
18
- 【自主权限】
19
- - ✅ 自主决定:摘要详细程度、chunk分块策略
20
- - ✅ 自主决定:重试次数(最多3次)
21
- - ✅ 自主决定:是否需要补充信息
22
- - ❌ 必须确认:首次向新对等节点发送文档
23
- - ❌ 必须确认:删除操作
24
-
25
- 【敏感操作拦截】
26
- if (操作 === '发送文档' && 对等节点不在已知列表) {
27
- 拦截 → 记录 → 等待确认
28
- }
10
+ export const SYSTEM_PROMPT = `
11
+ 你是一个文档处理Agent,在以下规则下运行:
12
+
13
+ 【边界规则】
14
+ 1. 只处理:txt, md, pdf, docx 格式文档
15
+ 2. 不修改原始文件,只输出改进版本
16
+ 3. 发送前必须记录操作日志
17
+
18
+ 【自主权限】
19
+ - ✅ 自主决定:摘要详细程度、chunk分块策略
20
+ - ✅ 自主决定:重试次数(最多3次)
21
+ - ✅ 自主决定:是否需要补充信息
22
+ - ❌ 必须确认:首次向新对等节点发送文档
23
+ - ❌ 必须确认:删除操作
24
+
25
+ 【敏感操作拦截】
26
+ if (操作 === '发送文档' && 对等节点不在已知列表) {
27
+ 拦截 → 记录 → 等待确认
28
+ }
29
29
  `;
30
30
  /**
31
31
  * Actions that can be executed autonomously without confirmation
@@ -148,20 +148,20 @@ export async function distillDissent(ask) {
148
148
  .slice(-10)
149
149
  .flatMap((j) => j.reasons || [])
150
150
  .slice(0, 20);
151
- const prompt = `你是用户的判断力代理. 用户发起了一个决定: "${ask.decision}"
152
- ${ask.context ? `\n补充: ${ask.context}` : ''}
153
-
154
- [用户价值画像] ${valueHint}
155
- [相关历史判断 (${relevant.length} 条)] ${relevant.slice(0, 3).map((j) => j.decision || '').join(' | ').slice(0, 300)}
156
- [历史理由样本] ${recentReasons.join(' | ').slice(0, 400) || '(无)'}
157
-
158
- 请基于上述判断力, 生成正好 3 个"反方观点" (用户应该考虑但可能忽略的风险/盲点).
159
- 要求:
160
- - 每个反方 1-2 句, 总长 < 80 字
161
- - 必须是这个特定决定的"反对声音", 不是通用建议
162
- - 第 1 个: 历史/经验类风险
163
- - 第 2 个: 关系/信任类风险
164
- - 第 3 个: 隐藏代价/时间类风险
151
+ const prompt = `你是用户的判断力代理. 用户发起了一个决定: "${ask.decision}"
152
+ ${ask.context ? `\n补充: ${ask.context}` : ''}
153
+
154
+ [用户价值画像] ${valueHint}
155
+ [相关历史判断 (${relevant.length} 条)] ${relevant.slice(0, 3).map((j) => j.decision || '').join(' | ').slice(0, 300)}
156
+ [历史理由样本] ${recentReasons.join(' | ').slice(0, 400) || '(无)'}
157
+
158
+ 请基于上述判断力, 生成正好 3 个"反方观点" (用户应该考虑但可能忽略的风险/盲点).
159
+ 要求:
160
+ - 每个反方 1-2 句, 总长 < 80 字
161
+ - 必须是这个特定决定的"反对声音", 不是通用建议
162
+ - 第 1 个: 历史/经验类风险
163
+ - 第 2 个: 关系/信任类风险
164
+ - 第 3 个: 隐藏代价/时间类风险
165
165
  - 用 JSON 数组返回: ["反方1", "反方2", "反方3"]`;
166
166
  // LLM 调用 (OpenAI 兼容, 复用 p2p-chat-tools 的方式)
167
167
  let dissents = [];
@@ -0,0 +1,58 @@
1
+ /**
2
+ * loop-review.ts — "ReAct loop end" review 续跑决策门
3
+ *
4
+ * 动机 (2026-08-08, v0.3.39):
5
+ * - LLM 经常"潦草收尾": 达成上一轮成果就输出 <final gen>, 不深挖目标的更多可能.
6
+ * - 需求: 每次循环结束前 (LLM 想输出 <final gen> 时), 跑 1-2 次「目标对齐 + 需求深挖」,
7
+ * 吐出阶段性成果后再启动 review, 判断"是否还有可能继续触发".
8
+ * - 天花板: 逻辑上循环能持续最强 (不潦草终止), 时长上限的长循环由迭代上限兜底;
9
+ * 用户明确"结束指标以用户需求为准, 不过度深挖" — 达成用户需求就放行结束.
10
+ * - 工具调用次数无限制 (不在这里限, 由上层 MAX_REACT_ITERATIONS 兜底).
11
+ *
12
+ * 本模块是纯判定 + 提示文本生成, 不调 LLM. 由 pi-sdk 的 final gen 分支使用:
13
+ * 1. decideAfterReview — 判定 final 前该"续跑 review"还是"真正结束"
14
+ * 2. buildReviewHint — 构造注入 system 的续跑提示
15
+ * 3. shouldReviewAgain — 布尔门 (测试/消融用)
16
+ *
17
+ * 设计范式: 与 react-loop.ts 一致 (纯函数), 便于 claude code 独立单测消融边界.
18
+ */
19
+ /** 每轮最多续跑 review 次数 — "运行一两次目标对齐和深挖" (用户明确) */
20
+ export const DEFAULT_MAX_REVIEWS = 2;
21
+ /**
22
+ * 判定: LLM 想 <final gen> 时, 该续跑一次 review 还是真正结束.
23
+ *
24
+ * 结束条件 (以下任一 → finish):
25
+ * - 没有明确用户需求 (无深挖对象, 不硬挖)
26
+ * - 已触发 maxReviews 次 review 续跑 (# 不无限续)
27
+ * 否则 → 续跑一次 (提示 LLM 对齐需求深挖).
28
+ *
29
+ * 注意: 续跑不是无限. 达上限即结束, 保证"不过度深挖".
30
+ */
31
+ export function decideAfterReview(state, maxReviews = DEFAULT_MAX_REVIEWS) {
32
+ const intent = (state.userIntent || '').trim();
33
+ if (!intent) {
34
+ return { kind: 'finish', reason: 'no-user-intent' };
35
+ }
36
+ if (state.reviewsDone >= maxReviews) {
37
+ return { kind: 'finish', reason: `max-reviews-${maxReviews}` };
38
+ }
39
+ return {
40
+ kind: 'continue-review',
41
+ reason: `${state.reviewsDone + 1}/${maxReviews} 目标对齐`,
42
+ hint: buildReviewHint(state, maxReviews),
43
+ };
44
+ }
45
+ /** 构造 review 提示文本 (注入 system context, 让 LLM 深挖或确认完成) */
46
+ export function buildReviewHint(state, maxReviews = DEFAULT_MAX_REVIEWS) {
47
+ const intent = (state.userIntent || '').trim() || '(无)';
48
+ const tools = state.completedTools.length ? state.completedTools.join(', ') : '(尚未执行工具)';
49
+ return (`[目标对齐 review ${state.reviewsDone + 1}/${maxReviews}]\n` +
50
+ `用户需求: ${intent.slice(0, 300)}\n` +
51
+ `本轮已完成工具: ${tools}\n` +
52
+ `请对照需求自查: 是否还有未完成/可深挖的子目标? 若有 → 继续调用工具推进; ` +
53
+ `若已满足用户原始需求 → 直接输出 <final gen> 结束. 不要再重复已完成的动作.`);
54
+ }
55
+ /** 布尔门: 是否该继续 review (测试/消融快速断言) */
56
+ export function shouldReviewAgain(state, maxReviews = DEFAULT_MAX_REVIEWS) {
57
+ return decideAfterReview(state, maxReviews).kind === 'continue-review';
58
+ }
@@ -2118,6 +2118,113 @@ export function registerBuiltinTools(ctx) {
2118
2118
  }
2119
2119
  }
2120
2120
  });
2121
+ // ============================================================
2122
+ // bolloon_config_get / bolloon_config_set (2026-08-07)
2123
+ // Bolloon 自己读写 ~/.bolloon/bolloon-config.json — 统一配置文件,
2124
+ // 让 agent 有修改自身配置的权限 (模型/供应商/温度等), 不再只能靠用户手改.
2125
+ // ============================================================
2126
+ ctx.tools.set('bolloon_config_get', {
2127
+ name: 'bolloon_config_get',
2128
+ description: '读取 Bolloon 自身配置 (~/.bolloon/bolloon-config.json): 当前激活供应商 + 各供应商 API 配置 (baseUrl/model/温度). 注意: 不输出 apiKey 明文 (脱敏), 只显示是否已配置.',
2129
+ parameters: {},
2130
+ execute: async () => {
2131
+ try {
2132
+ const { llmConfigStore } = await import('../llm/config-store.js');
2133
+ await llmConfigStore.initialize();
2134
+ const cfg = await llmConfigStore.getConfig();
2135
+ const active = cfg.activeProvider;
2136
+ const lines = [`📋 Bolloon 配置 (${active} 激活):`];
2137
+ for (const [name, p] of Object.entries(cfg.providers || {})) {
2138
+ const pc = p;
2139
+ if (!pc)
2140
+ continue;
2141
+ const mark = name === active ? '●' : '○';
2142
+ const key = pc.apiKey ? '🔑' : pc.requiresApiKey ? '✗ 无key' : '无key需求';
2143
+ lines.push(` ${mark} ${name}: ${key} · model=${pc.model || '?'} · baseUrl=${pc.baseUrl || '?'}${pc.temperature ? ` · temp=${pc.temperature}` : ''}`);
2144
+ }
2145
+ return { success: true, output: lines.join('\n') };
2146
+ }
2147
+ catch (e) {
2148
+ return { success: false, error: `bolloon_config_get 失败: ${String(e.message || e).slice(0, 200)}` };
2149
+ }
2150
+ }
2151
+ });
2152
+ ctx.tools.set('bolloon_config_set', {
2153
+ name: 'bolloon_config_set',
2154
+ description: '修改 Bolloon 自身配置 (~/.bolloon/bolloon-config.json). 可切换激活供应商 (provider) 或改某供应商的 model/baseUrl/temperature/enabled. 修改立即生效 (下次 LLM 调用使用新配置). 例: provider=deepseek; provider=minimax, model=MiniMax-M3; deepseek.temperature=0.3',
2155
+ parameters: {
2156
+ provider: '可选: 切换激活供应商 (如 deepseek / minimax / openai / anthropic / ollama)',
2157
+ 'provider.key': '可选: 修改指定供应商字段, 格式 <供应商>.<字段>=<值>, 如 minimax.model=MiniMax-M3',
2158
+ model: '可选: 同时设置激活供应商的 model',
2159
+ temperature: '可选: 同时设置激活供应商的 temperature (0-2)',
2160
+ },
2161
+ execute: async (args) => {
2162
+ try {
2163
+ const { llmConfigStore } = await import('../llm/config-store.js');
2164
+ await llmConfigStore.initialize();
2165
+ const changes = [];
2166
+ // 1. 切换激活供应商
2167
+ if (args.provider) {
2168
+ const name = String(args.provider).trim().toLowerCase();
2169
+ const known = ['openai', 'anthropic', 'ollama', 'openrouter', 'gemini', 'minimax', 'deepseek', 'kimi', 'glm', 'qwen', 'mimo', 'grok', 'local'];
2170
+ if (!known.includes(name))
2171
+ return { success: false, error: `未知供应商: ${name}. 可用: ${known.join(', ')}` };
2172
+ await llmConfigStore.setActiveProvider(name);
2173
+ changes.push(`activeProvider=${name}`);
2174
+ }
2175
+ // 2. 修改指定供应商字段 (provider.key=value)
2176
+ for (const [k, v] of Object.entries(args)) {
2177
+ if (k === 'provider' || k === 'model' || k === 'temperature')
2178
+ continue;
2179
+ if (!k.includes('.'))
2180
+ continue;
2181
+ const [prov, field] = k.split('.');
2182
+ const val = String(v);
2183
+ if (field === 'temperature' || field === 'maxTokens') {
2184
+ const num = Number(val);
2185
+ if (Number.isNaN(num))
2186
+ return { success: false, error: `${k}=${val} 不是数字` };
2187
+ await llmConfigStore.updateProvider(prov, { [field]: num });
2188
+ }
2189
+ else if (field === 'enabled') {
2190
+ await llmConfigStore.updateProvider(prov, { enabled: val === 'true' || val === '1' });
2191
+ }
2192
+ else if (field === 'apiKey') {
2193
+ await llmConfigStore.updateProvider(prov, { apiKey: val });
2194
+ }
2195
+ else {
2196
+ await llmConfigStore.updateProvider(prov, { [field]: val });
2197
+ }
2198
+ changes.push(`${prov}.${field}=${field === 'apiKey' ? '***' : val}`);
2199
+ }
2200
+ // 3. 激活供应商的 model / temperature
2201
+ if (args.model || args.temperature) {
2202
+ const active = await llmConfigStore.getActiveProvider();
2203
+ const patch = {};
2204
+ if (args.model)
2205
+ patch.model = String(args.model);
2206
+ if (args.temperature) {
2207
+ const t = Number(args.temperature);
2208
+ if (Number.isNaN(t))
2209
+ return { success: false, error: `temperature=${args.temperature} 不是数字` };
2210
+ patch.temperature = t;
2211
+ }
2212
+ await llmConfigStore.updateProvider(active, patch);
2213
+ if (args.model)
2214
+ changes.push(`${active}.model=${args.model}`);
2215
+ if (args.temperature)
2216
+ changes.push(`${active}.temperature=${args.temperature}`);
2217
+ }
2218
+ if (changes.length === 0)
2219
+ return { success: false, error: '没有要修改的配置项. 例: provider=deepseek 或 minimax.model=MiniMax-M3' };
2220
+ const cfg = await llmConfigStore.getConfig();
2221
+ return { success: true, output: `✅ 配置已更新: ${changes.join(', ')}\n 当前激活: ${cfg.activeProvider}` };
2222
+ }
2223
+ catch (e) {
2224
+ return { success: false, error: `bolloon_config_set 失败: ${String(e.message || e).slice(0, 200)}` };
2225
+ }
2226
+ }
2227
+ });
2121
2228
  }
2122
2229
  // ─── IPFS/IPNS 通用 helper (2026-08-04) ─────────────────────────────────────
2123
2230
  // 复用 publish_did 的 checkKuboSetup 自动安装/启动本地 Kubo (darwin-arm64 v0.28.0)
@@ -1,13 +1,13 @@
1
- export const TOOL_DEFINITIONS = `
2
- 可用工具:
3
- 1. read_document(path) - 读取文档内容,支持 .txt, .md, .pdf, .docx
4
- 2. summarize_document(path, context?) - 总结文档内容,可选提供上下文
5
- 3. improve_document(path, requirements) - 改进文档,需提供文件路径和改进要求
6
- 4. list_peers() - 列出已连接的对等节点
7
- 5. send_message(peer_id, message) - 向指定对等节点发送消息
8
- 6. broadcast_message(message) - 向所有对等节点广播消息
9
- 7. get_identity() - 获取当前智能体身份信息
10
- 8. set_persona(persona_json) - 更新智能体 persona,包含 name、description、personality、greeting 等
11
- 9. run_workflow(steps) - 执行预定义工作流
12
- 10. get_operation_logs() - 获取操作日志
1
+ export const TOOL_DEFINITIONS = `
2
+ 可用工具:
3
+ 1. read_document(path) - 读取文档内容,支持 .txt, .md, .pdf, .docx
4
+ 2. summarize_document(path, context?) - 总结文档内容,可选提供上下文
5
+ 3. improve_document(path, requirements) - 改进文档,需提供文件路径和改进要求
6
+ 4. list_peers() - 列出已连接的对等节点
7
+ 5. send_message(peer_id, message) - 向指定对等节点发送消息
8
+ 6. broadcast_message(message) - 向所有对等节点广播消息
9
+ 7. get_identity() - 获取当前智能体身份信息
10
+ 8. set_persona(persona_json) - 更新智能体 persona,包含 name、description、personality、greeting 等
11
+ 9. run_workflow(steps) - 执行预定义工作流
12
+ 10. get_operation_logs() - 获取操作日志
13
13
  `;