@bolloon/bolloon-agent 0.4.13 → 0.4.15

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 (221) hide show
  1. package/README.md +127 -127
  2. package/bin/bolloon-cli.cjs +183 -183
  3. package/bin/bolloon-daemon.sh +207 -0
  4. package/bin/bolloon.cjs +0 -0
  5. package/dist/agents/agent-gateway.js +130 -0
  6. package/dist/agents/constraint-layer.js +19 -19
  7. package/dist/agents/gateway-group.js +261 -0
  8. package/dist/agents/gateway-network.js +278 -0
  9. package/dist/agents/judgment-protocol.js +14 -14
  10. package/dist/agents/pi-sdk-tools.js +117 -0
  11. package/dist/agents/pi-sdk-types.js +12 -12
  12. package/dist/agents/pi-sdk.js +101 -101
  13. package/dist/agents/skill-organizer.js +19 -19
  14. package/dist/agents/workflow-pivot-loop.js +2 -2
  15. package/dist/agents/x402/x402Pay.js +4 -0
  16. package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
  17. package/dist/bollharness-integration/context-router-judgment.js +4 -4
  18. package/dist/bollharness-integration/context-router.js +292 -292
  19. package/dist/bollharness-integration/gate-state-machine.js +13 -13
  20. package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
  21. package/dist/bollharness-integration/skill-adapter.js +21 -21
  22. package/dist/bootstrap/chat-archiver.js +14 -14
  23. package/dist/bootstrap/context-os.js +24 -24
  24. package/dist/bootstrap/memory-compressor.js +13 -13
  25. package/dist/cli-entry.js +36 -36
  26. package/dist/constraint-runtime/reference_data/archive_surface_snapshot.json +63 -0
  27. package/dist/constraint-runtime/reference_data/commands_snapshot.json +1037 -0
  28. package/dist/constraint-runtime/reference_data/subsystems/assistant.json +8 -0
  29. package/dist/constraint-runtime/reference_data/subsystems/bootstrap.json +8 -0
  30. package/dist/constraint-runtime/reference_data/subsystems/bridge.json +32 -0
  31. package/dist/constraint-runtime/reference_data/subsystems/buddy.json +13 -0
  32. package/dist/constraint-runtime/reference_data/subsystems/cli.json +26 -0
  33. package/dist/constraint-runtime/reference_data/subsystems/components.json +32 -0
  34. package/dist/constraint-runtime/reference_data/subsystems/constants.json +28 -0
  35. package/dist/constraint-runtime/reference_data/subsystems/coordinator.json +8 -0
  36. package/dist/constraint-runtime/reference_data/subsystems/entrypoints.json +15 -0
  37. package/dist/constraint-runtime/reference_data/subsystems/hooks.json +32 -0
  38. package/dist/constraint-runtime/reference_data/subsystems/keybindings.json +21 -0
  39. package/dist/constraint-runtime/reference_data/subsystems/memdir.json +15 -0
  40. package/dist/constraint-runtime/reference_data/subsystems/migrations.json +18 -0
  41. package/dist/constraint-runtime/reference_data/subsystems/moreright.json +8 -0
  42. package/dist/constraint-runtime/reference_data/subsystems/native_ts.json +11 -0
  43. package/dist/constraint-runtime/reference_data/subsystems/outputStyles.json +8 -0
  44. package/dist/constraint-runtime/reference_data/subsystems/plugins.json +9 -0
  45. package/dist/constraint-runtime/reference_data/subsystems/remote.json +11 -0
  46. package/dist/constraint-runtime/reference_data/subsystems/schemas.json +8 -0
  47. package/dist/constraint-runtime/reference_data/subsystems/screens.json +10 -0
  48. package/dist/constraint-runtime/reference_data/subsystems/server.json +10 -0
  49. package/dist/constraint-runtime/reference_data/subsystems/services.json +32 -0
  50. package/dist/constraint-runtime/reference_data/subsystems/skills.json +27 -0
  51. package/dist/constraint-runtime/reference_data/subsystems/state.json +13 -0
  52. package/dist/constraint-runtime/reference_data/subsystems/types.json +18 -0
  53. package/dist/constraint-runtime/reference_data/subsystems/upstreamproxy.json +9 -0
  54. package/dist/constraint-runtime/reference_data/subsystems/utils.json +32 -0
  55. package/dist/constraint-runtime/reference_data/subsystems/vim.json +12 -0
  56. package/dist/constraint-runtime/reference_data/subsystems/voice.json +8 -0
  57. package/dist/constraint-runtime/reference_data/tools_snapshot.json +922 -0
  58. package/dist/constraint-runtime/tools/PolymarketSDK/econ-integration.d.ts +55 -0
  59. package/dist/constraint-runtime/tools/PolymarketSDK/econ-integration.js +59 -0
  60. package/dist/context-compaction/auto-compact.js +7 -7
  61. package/dist/electron/config.js.map +1 -0
  62. package/dist/electron/dialogs.js.map +1 -0
  63. package/dist/electron/first-run.js +54 -54
  64. package/dist/electron/first-run.js.map +1 -0
  65. package/dist/electron/ipc.js.map +1 -0
  66. package/dist/electron/logger.js.map +1 -0
  67. package/dist/electron/main.js.map +1 -0
  68. package/dist/electron/menu.js.map +1 -0
  69. package/dist/electron/paths.js.map +1 -0
  70. package/dist/electron/server.js.map +1 -0
  71. package/dist/electron/tray.js.map +1 -0
  72. package/dist/electron/window.js.map +1 -0
  73. package/dist/electron-build/electron/first-run.js +54 -54
  74. package/dist/electron-preload.js.map +1 -1
  75. package/dist/electron.js.map +1 -1
  76. package/dist/index.js +112 -112
  77. package/dist/llm/llm-judgment-client.js +102 -102
  78. package/dist/llm/pi-ai.js +48 -48
  79. package/dist/llm/system-prompt/layers/channel/human-async.md +41 -41
  80. package/dist/llm/system-prompt/layers/channel/local.md +14 -14
  81. package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
  82. package/dist/llm/system-prompt/layers/channel/p2p-peer-sync.md +51 -51
  83. package/dist/llm/system-prompt/layers/channel/p2p-proactive.md +43 -43
  84. package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
  85. package/dist/llm/system-prompt/layers/channel/session-handoff.md +61 -61
  86. package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
  87. package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
  88. package/dist/llm/system-prompt/layers/core/external-engagement.md +73 -73
  89. package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
  90. package/dist/llm/system-prompt/layers/core/identity.md +48 -48
  91. package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
  92. package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
  93. package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
  94. package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
  95. package/dist/llm/system-prompt/layers/core/tone.md +31 -31
  96. package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
  97. package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
  98. package/dist/llm/system-prompt/layers/role/architect.md +20 -20
  99. package/dist/llm/system-prompt/layers/role/expert.md +19 -19
  100. package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
  101. package/dist/llm/system-prompt/layers/role/security.md +15 -15
  102. package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
  103. package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
  104. package/dist/llm/system-prompt/layers/tool/goal_handoff.md +77 -77
  105. package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
  106. package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
  107. package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
  108. package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
  109. package/dist/llm/system-prompt/layers/tool/p2p_request.md +61 -61
  110. package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
  111. package/dist/llm/tool-manifest/ask_user_input.js +1 -1
  112. package/dist/llm/tool-manifest/bash.js +3 -3
  113. package/dist/llm/tool-manifest/create_file.js +4 -4
  114. package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
  115. package/dist/llm/tool-manifest/image_search.js +2 -2
  116. package/dist/llm/tool-manifest/index.js +59 -0
  117. package/dist/llm/tool-manifest/mcp.js +2 -2
  118. package/dist/llm/tool-manifest/message_compose.js +3 -3
  119. package/dist/llm/tool-manifest/places.js +2 -2
  120. package/dist/llm/tool-manifest/present_files.js +1 -1
  121. package/dist/llm/tool-manifest/recipe.js +2 -2
  122. package/dist/llm/tool-manifest/str_replace.js +5 -5
  123. package/dist/llm/tool-manifest/view.js +3 -3
  124. package/dist/llm/tool-manifest/weather.js +4 -4
  125. package/dist/llm/tool-manifest/web.js +4 -4
  126. package/dist/network/p2p.js +78 -4
  127. package/dist/orbitdb/cid-database.js +39 -10
  128. package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
  129. package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
  130. package/dist/pi-ecosystem-judgment/distillation.js +14 -14
  131. package/dist/pi-ecosystem-judgment/index.js +1 -1
  132. package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
  133. package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
  134. package/dist/security/context-router-tool.js +15 -15
  135. package/dist/utils/auto-update.js.map +1 -0
  136. package/dist/web/a2ui-client.js +1594 -223
  137. package/dist/web/api-config.html +779 -779
  138. package/dist/web/client-hearth.js +10 -10
  139. package/dist/web/client.js +273 -0
  140. package/dist/web/client.js.map +7 -0
  141. package/dist/web/components/wallet-viem.mjs +118 -118
  142. package/dist/web/index.html +502 -485
  143. package/dist/web/manifest.json +20 -20
  144. package/dist/web/mobile-agent.js +397 -0
  145. package/dist/web/mobile-core.js +86235 -0
  146. package/dist/web/mobile-data.js +346 -0
  147. package/dist/web/mobile-http-api.js +71 -0
  148. package/dist/web/mobile-p2p.js +250 -0
  149. package/dist/web/mobile-payments.js +80 -0
  150. package/dist/web/mobile-wallet.js +226 -0
  151. package/dist/web/mobile.css +483 -6
  152. package/dist/web/mobile.html +99 -50
  153. package/dist/web/mobile.js +1040 -187
  154. package/dist/web/server.js +196 -13
  155. package/dist/web/style.css +5062 -4946
  156. package/package.json +201 -198
  157. package/scripts/build-cli.js +215 -215
  158. package/scripts/build-web.ts +162 -149
  159. package/scripts/postinstall.js +152 -152
  160. package/bin/bolloon.js +0 -157
  161. package/dist/agents/python-exec.js +0 -115
  162. package/dist/pi-ecosystem-colony/index.js +0 -365
  163. package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
  164. package/dist/social/ant-colony/PheromoneEngine.js +0 -227
  165. package/dist/social/ant-colony/index.js +0 -6
  166. package/dist/social/ant-colony/types.js +0 -24
  167. package/dist/storage/trajectory.js +0 -101
  168. package/dist/test/ai-judgment-test.js +0 -80
  169. package/dist/test/bollharness-integration.test.js +0 -318
  170. package/dist/test/channel-agent-multi-dialogue.js +0 -205
  171. package/dist/test/channel-heartbeat-agent-test.js +0 -201
  172. package/dist/test/constraint-layer.test.js +0 -164
  173. package/dist/test/diap-identity-test.js +0 -172
  174. package/dist/test/diap-quick-test.js +0 -62
  175. package/dist/test/global-shared-context.test.js +0 -315
  176. package/dist/test/harness-judgment-injection.test.js +0 -246
  177. package/dist/test/harness-workflow-integrator-test.js +0 -228
  178. package/dist/test/human-value-store.test.js +0 -243
  179. package/dist/test/hybrid-integration-test.js +0 -118
  180. package/dist/test/hybrid-messenger-verify.js +0 -55
  181. package/dist/test/iroh-bistream-debug.js +0 -38
  182. package/dist/test/iroh-communication.test.js +0 -66
  183. package/dist/test/iroh-debug-test.js +0 -57
  184. package/dist/test/iroh-diap-test.js +0 -71
  185. package/dist/test/iroh-direct-connect.js +0 -55
  186. package/dist/test/iroh-e2e-fixed.js +0 -89
  187. package/dist/test/iroh-e2e-same-process.js +0 -63
  188. package/dist/test/iroh-e2e.js +0 -66
  189. package/dist/test/iroh-final-e2e.js +0 -72
  190. package/dist/test/iroh-relay-test.js +0 -37
  191. package/dist/test/iroh-simple-test.js +0 -41
  192. package/dist/test/iroh-transport-verify.js +0 -54
  193. package/dist/test/iroh-transport.test.js +0 -37
  194. package/dist/test/iroh-two-nodes.js +0 -70
  195. package/dist/test/iroh-verify.js +0 -44
  196. package/dist/test/judgment-decision.test.js +0 -219
  197. package/dist/test/llm-judgment-integration.test.js +0 -220
  198. package/dist/test/p2p-agent-complex-dialogue.js +0 -385
  199. package/dist/test/p2p-agent-dialogue.js +0 -341
  200. package/dist/test/p2p-agent-full-bidirectional.js +0 -510
  201. package/dist/test/p2p-agent-harness-flow.js +0 -437
  202. package/dist/test/p2p-agent-harness-single.js +0 -143
  203. package/dist/test/p2p-ai-dialogue-test.js +0 -318
  204. package/dist/test/p2p-cid-connect-test.js +0 -195
  205. package/dist/test/p2p-connect-receiver.js +0 -69
  206. package/dist/test/p2p-doc-transfer.js +0 -110
  207. package/dist/test/p2p-identity-page-test.js +0 -77
  208. package/dist/test/p2p-iroh-test.js +0 -171
  209. package/dist/test/p2p-minimal-test.js +0 -241
  210. package/dist/test/p2p-node-1.js +0 -148
  211. package/dist/test/p2p-node-2.js +0 -148
  212. package/dist/test/p2p-server.js +0 -281
  213. package/dist/test/p2p-two-nodes-test.js +0 -438
  214. package/dist/test/pi-sdk.test.js +0 -44
  215. package/dist/test/set-persona.js +0 -40
  216. package/dist/test/simple.test.js +0 -9
  217. package/dist/test/storage-integration.test.js +0 -150
  218. package/dist/test/subagent-manager.test.js +0 -276
  219. package/dist/test/test-gate-flow.test.js +0 -81
  220. package/dist/test/workflow-engine.test.js +0 -87
  221. package/dist/test/workflow-pivot-loop.test.js +0 -246
@@ -735,6 +735,16 @@ async function handleV3P2PMessage(parsed, conn, comm) {
735
735
  }
736
736
  // 2026-07-29: 语义分析 — 分析远端聊天内容, 隐式滑动 trustScore
737
737
  recordInteraction(senderKey, text).catch(() => { });
738
+ // 2026-08-14: 远端消息带 gateway 链接 → 自动加入 (幂等, fire-and-forget 不阻塞聊天)
739
+ import('../agents/gateway-network.js').then(({ maybeAutoJoinGateway }) => maybeAutoJoinGateway(String(text || '')).then((note) => {
740
+ if (note) {
741
+ console.log(`[agent-gateway] ${note}`);
742
+ try {
743
+ broadcast({ type: 'gateway', content: note, channelId }, channelId);
744
+ }
745
+ catch { /* 广播失败忽略 */ }
746
+ }
747
+ }).catch(() => { })).catch(() => { });
738
748
  console.log(`[v3] 收到 ${senderKey.substring(0, 12)}... (${tierLabel(tierState.tier)}) 对 channel ${channelId} 的 chat: "${text.substring(0, 40)}..."`);
739
749
  try {
740
750
  // 1. 找到 channel
@@ -2409,19 +2419,19 @@ export async function createWebServer(port = 3000, options = {}) {
2409
2419
  .map((p) => `- ${p.name || p.publicKey.slice(0, 8)} (pk=${p.publicKey.slice(0, 12)}…): 渠道[${p.channels.map((c) => c.name).join(', ') || '无'}]`)
2410
2420
  .join('\n');
2411
2421
  const goalDesc = ctx.goal ? `当前目标: ${ctx.goal.description} (已发起 ${ctx.goal.initiationsUsed}/${ctx.goal.maxInitiations}, 有效回复 ${ctx.goal.effectfulReplies}/${ctx.goal.effectThreshold})` : '当前无明确目标';
2412
- const prompt = `你是智能体「${ctx.self.name || '本地智能体'}」。你通过 P2P 网络认识以下其他智能体:
2413
- ${peerLines}
2414
-
2415
- ${goalDesc}
2416
-
2417
- 规则:
2418
- 1. 社交是为了达成上述目标, 不是闲聊。只在你有真正有价值的信息要分享/询问、且能推进目标时才主动发起。
2419
- 2. 不要重复最近已经聊过的话题, 不要每条心跳都发消息, 保持克制。
2420
- 3. 如果目标已经通过已有交流达成 (或你认为无需再聊), 输出 {"initiate": false, "goalAchieved": true}。
2421
- 4. 如果决定发起, 选一个最合适的目标渠道 (用对方渠道的真实 id)。
2422
-
2423
- 现在是否要主动联系其中某个智能体? 只输出一个 JSON 对象, 不要任何其他文字:
2424
- {"initiate": true 或 false, "goalAchieved": true 或 false, "targetPeerPublicKey": "对方 pk", "targetChannelId": "对方渠道 id", "message": "你要说的话"}
2422
+ const prompt = `你是智能体「${ctx.self.name || '本地智能体'}」。你通过 P2P 网络认识以下其他智能体:
2423
+ ${peerLines}
2424
+
2425
+ ${goalDesc}
2426
+
2427
+ 规则:
2428
+ 1. 社交是为了达成上述目标, 不是闲聊。只在你有真正有价值的信息要分享/询问、且能推进目标时才主动发起。
2429
+ 2. 不要重复最近已经聊过的话题, 不要每条心跳都发消息, 保持克制。
2430
+ 3. 如果目标已经通过已有交流达成 (或你认为无需再聊), 输出 {"initiate": false, "goalAchieved": true}。
2431
+ 4. 如果决定发起, 选一个最合适的目标渠道 (用对方渠道的真实 id)。
2432
+
2433
+ 现在是否要主动联系其中某个智能体? 只输出一个 JSON 对象, 不要任何其他文字:
2434
+ {"initiate": true 或 false, "goalAchieved": true 或 false, "targetPeerPublicKey": "对方 pk", "targetChannelId": "对方渠道 id", "message": "你要说的话"}
2425
2435
  若不想发起, 输出 {"initiate": false}。`;
2426
2436
  const raw = await agent.promptStream(prompt, () => { }, undefined, local.id);
2427
2437
  const m = raw.match(/\{[\s\S]*\}/);
@@ -2811,6 +2821,141 @@ ${goalDesc}
2811
2821
  res.status(500).json({ error: e?.message });
2812
2822
  }
2813
2823
  });
2824
+ // 2026-08-14: Agent Gateway — 网络加入 / 分享链接 / 成员 / 状态 (入口要小: 一条链接)
2825
+ app.post('/api/gateway/join', async (req, res) => {
2826
+ try {
2827
+ const { joinNetwork } = await import('../agents/gateway-network.js');
2828
+ const link = String(req.body?.link || '').trim();
2829
+ if (!link)
2830
+ return res.status(400).json({ error: 'link 必填 (orbitdb:// / ipns:// / https://.../registry)' });
2831
+ const r = await joinNetwork(link);
2832
+ res.json(r);
2833
+ }
2834
+ catch (e) {
2835
+ res.status(500).json({ error: e?.message });
2836
+ }
2837
+ });
2838
+ app.get('/api/gateway/link', async (req, res) => {
2839
+ try {
2840
+ const { shareNetworkLink } = await import('../agents/gateway-network.js');
2841
+ const name = String(req.query?.name || '').trim() || undefined;
2842
+ const r = await shareNetworkLink(name ? { name } : undefined);
2843
+ if (!r.ok)
2844
+ return res.status(400).json({ error: r.error });
2845
+ res.json({ ok: true, link: r.link });
2846
+ }
2847
+ catch (e) {
2848
+ res.status(500).json({ error: e?.message });
2849
+ }
2850
+ });
2851
+ app.get('/api/gateway/networks', async (_req, res) => {
2852
+ try {
2853
+ const { listJoinedNetworks } = await import('../agents/gateway-network.js');
2854
+ res.json({ networks: await listJoinedNetworks() });
2855
+ }
2856
+ catch (e) {
2857
+ res.status(500).json({ error: e?.message });
2858
+ }
2859
+ });
2860
+ app.get('/api/gateway/status', async (_req, res) => {
2861
+ try {
2862
+ const { gatewayStatus } = await import('../agents/agent-gateway.js');
2863
+ const { getAgentRegistry } = await import('../agents/agent-registry.js');
2864
+ const { listJoinedNetworks } = await import('../agents/gateway-network.js');
2865
+ const registry = getAgentRegistry();
2866
+ const services = await registry.list();
2867
+ res.json({
2868
+ ready: registry.ready,
2869
+ count: services.length,
2870
+ services,
2871
+ networks: await listJoinedNetworks(),
2872
+ summary: await gatewayStatus(),
2873
+ });
2874
+ }
2875
+ catch (e) {
2876
+ res.status(500).json({ error: e?.message });
2877
+ }
2878
+ });
2879
+ // ============ 2026-08-14: P2P 群组 (微信式群聊, OrbitDB events store) ============
2880
+ app.post('/api/gateway/groups', async (req, res) => {
2881
+ try {
2882
+ const { createGroup } = await import('../agents/gateway-group.js');
2883
+ const r = await createGroup(String(req.body?.name || '').trim(), {
2884
+ from: String(req.body?.from || '').trim() || undefined,
2885
+ hello: req.body?.hello ? String(req.body.hello) : undefined,
2886
+ });
2887
+ if (!r.ok)
2888
+ return res.status(400).json({ error: r.error });
2889
+ registerGroupSse(r.group.id, r.group.name);
2890
+ res.json({ ok: true, group: r.group });
2891
+ }
2892
+ catch (e) {
2893
+ res.status(500).json({ error: e?.message });
2894
+ }
2895
+ });
2896
+ app.post('/api/gateway/groups/join', async (req, res) => {
2897
+ try {
2898
+ const { joinGroup } = await import('../agents/gateway-group.js');
2899
+ const link = String(req.body?.link || '').trim();
2900
+ if (!link)
2901
+ return res.status(400).json({ error: 'link 必填 (orbitdb://...?type=group&name=...)' });
2902
+ const r = await joinGroup(link);
2903
+ if (!r.ok)
2904
+ return res.status(400).json({ error: r.error });
2905
+ if (r.group)
2906
+ registerGroupSse(r.group.id, r.group.name);
2907
+ res.json(r);
2908
+ }
2909
+ catch (e) {
2910
+ res.status(500).json({ error: e?.message });
2911
+ }
2912
+ });
2913
+ app.get('/api/gateway/groups', async (_req, res) => {
2914
+ try {
2915
+ const { listGroups, groupInfo } = await import('../agents/gateway-group.js');
2916
+ const groups = await listGroups();
2917
+ const detailed = await Promise.all(groups.map((g) => groupInfo(g.id).catch(() => g)));
2918
+ res.json({ groups: detailed });
2919
+ }
2920
+ catch (e) {
2921
+ res.status(500).json({ error: e?.message });
2922
+ }
2923
+ });
2924
+ app.get('/api/gateway/groups/:id/messages', async (req, res) => {
2925
+ try {
2926
+ const { groupMessages } = await import('../agents/gateway-group.js');
2927
+ const limit = Math.min(Number(req.query?.limit || 50), 200);
2928
+ const msgs = await groupMessages(String(req.params.id), limit);
2929
+ res.json({ messages: msgs });
2930
+ }
2931
+ catch (e) {
2932
+ res.status(500).json({ error: e?.message });
2933
+ }
2934
+ });
2935
+ app.post('/api/gateway/groups/:id/message', async (req, res) => {
2936
+ try {
2937
+ const { groupSend } = await import('../agents/gateway-group.js');
2938
+ const r = await groupSend(String(req.params.id), String(req.body?.text || ''), String(req.body?.from || 'web-user'));
2939
+ if (!r.ok)
2940
+ return res.status(400).json({ error: r.error });
2941
+ res.json({ ok: true });
2942
+ }
2943
+ catch (e) {
2944
+ res.status(500).json({ error: e?.message });
2945
+ }
2946
+ });
2947
+ app.get('/api/gateway/groups/:id/link', async (req, res) => {
2948
+ try {
2949
+ const { groupLink } = await import('../agents/gateway-group.js');
2950
+ const link = await groupLink(String(req.params.id));
2951
+ if (!link)
2952
+ return res.status(404).json({ error: '群组不存在' });
2953
+ res.json({ ok: true, link });
2954
+ }
2955
+ catch (e) {
2956
+ res.status(500).json({ error: e?.message });
2957
+ }
2958
+ });
2814
2959
  // 2026-08-13: 人工支付审批 API — YAML 验证门 confirm 的支付请求
2815
2960
  app.get('/api/payments/pending', async (_req, res) => {
2816
2961
  try {
@@ -2910,11 +3055,38 @@ ${goalDesc}
2910
3055
  const { warmAgentRegistry } = await import('../agents/agent-registry.js');
2911
3056
  const ok = await warmAgentRegistry();
2912
3057
  console.log(`[agent-registry] OrbitDB 服务注册表 ${ok ? '已启用' : '未启用 (回退本地)'}`);
3058
+ // 2026-08-14: 恢复已加入的 Agent 网络 (重启后仍是家庭成员, 失败静默保留记录)
3059
+ const { restoreJoinedNetworks } = await import('../agents/gateway-network.js');
3060
+ restoreJoinedNetworks().then((r) => {
3061
+ if (r.total > 0)
3062
+ console.log(`[agent-gateway] 恢复 ${r.restored}/${r.total} 个已加入网络 (失败 ${r.failed}, 记录保留)`);
3063
+ }).catch(() => { });
3064
+ // 2026-08-14: 恢复已加入的群组 (重开 store + 注册 SSE 广播)
3065
+ const { restoreGroups, listGroups } = await import('../agents/gateway-group.js');
3066
+ restoreGroups().then((r) => {
3067
+ if (r.total > 0)
3068
+ console.log(`[agent-gateway] 恢复 ${r.restored}/${r.total} 个群组 (失败 ${r.failed})`);
3069
+ listGroups().then((gs) => { for (const g of gs)
3070
+ registerGroupSse(g.id, g.name); }).catch(() => { });
3071
+ }).catch(() => { });
2913
3072
  }
2914
3073
  catch (e) {
2915
3074
  console.warn('[agent-registry] 预热失败 (非致命):', e?.message?.slice(0, 120));
2916
3075
  }
2917
3076
  })();
3077
+ // 2026-08-14: 群组消息 → SSE 广播 (手机端/Web 实时收到群聊)
3078
+ const groupSseRegistered = new Set();
3079
+ function registerGroupSse(groupId, groupName) {
3080
+ if (groupSseRegistered.has(groupId))
3081
+ return;
3082
+ groupSseRegistered.add(groupId);
3083
+ import('../agents/gateway-group.js').then(({ onGroupMessage }) => onGroupMessage(groupId, (msg) => {
3084
+ try {
3085
+ broadcast({ type: 'group-message', groupId, groupName, message: msg }, 'p2p-global');
3086
+ }
3087
+ catch { /* 忽略 */ }
3088
+ })).catch(() => { });
3089
+ }
2918
3090
  app.get('/api/health', (_req, res) => {
2919
3091
  res.json(healthCheck(getPackageVersion()));
2920
3092
  });
@@ -3655,6 +3827,17 @@ ${goalDesc}
3655
3827
  catch { /* 预激活失败不阻塞 */ }
3656
3828
  // 将真实 DID 作为上下文前缀,让 AI 使用真实的 DID 而不是自己编造的
3657
3829
  let contextHint = '';
3830
+ // 2026-08-14: 本地消息带 gateway 链接 → 自动加入, 结果注入 agent 上下文 (5s 上限, 不阻塞 LLM)
3831
+ try {
3832
+ const { maybeAutoJoinGateway } = await import('../agents/gateway-network.js');
3833
+ const gwNote = await Promise.race([
3834
+ maybeAutoJoinGateway(text),
3835
+ new Promise((resolve) => setTimeout(() => resolve(null), 5000)),
3836
+ ]);
3837
+ if (gwNote)
3838
+ contextHint += `[系统上下文] ${gwNote}\n`;
3839
+ }
3840
+ catch { /* 自动加入失败不阻塞 */ }
3658
3841
  // 2026-08-02: slash 命令提示 (在 /message 开头解析, 这里注入)
3659
3842
  if (slashCommandHint)
3660
3843
  contextHint += slashCommandHint;