@bolloon/bolloon-agent 0.3.44 → 0.3.46
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.
- package/README.md +135 -135
- package/bin/bolloon-cli.cjs +183 -183
- package/bin/bolloon-daemon.sh +207 -0
- package/bin/bolloon.cjs +0 -0
- package/dist/agents/agent-identity.js +17 -0
- package/dist/agents/constraint-layer.js +19 -19
- package/dist/agents/judgment-protocol.js +14 -14
- package/dist/agents/loop-review.js +21 -5
- package/dist/agents/pi-sdk-types.js +12 -12
- package/dist/agents/pi-sdk.js +197 -102
- package/dist/agents/skill-writer.js +19 -0
- package/dist/agents/workflow-pivot-loop.js +3 -3
- package/dist/bollharness/src/scripts/deploy-guard.js +8 -8
- package/dist/bollharness-integration/context-router-judgment.js +4 -4
- package/dist/bollharness-integration/context-router.js +292 -292
- package/dist/bollharness-integration/gate-state-machine.js +13 -13
- package/dist/bollharness-integration/llm-judgment-engine.js +134 -134
- package/dist/bollharness-integration/skill-adapter.js +21 -21
- package/dist/bootstrap/chat-archiver.js +14 -14
- package/dist/bootstrap/context-os.js +21 -21
- package/dist/bootstrap/memory-compressor.js +29 -13
- package/dist/cli-entry.js +47 -37
- package/dist/constraint-runtime/reference_data/archive_surface_snapshot.json +63 -0
- package/dist/constraint-runtime/reference_data/commands_snapshot.json +1037 -0
- package/dist/constraint-runtime/reference_data/subsystems/assistant.json +8 -0
- package/dist/constraint-runtime/reference_data/subsystems/bootstrap.json +8 -0
- package/dist/constraint-runtime/reference_data/subsystems/bridge.json +32 -0
- package/dist/constraint-runtime/reference_data/subsystems/buddy.json +13 -0
- package/dist/constraint-runtime/reference_data/subsystems/cli.json +26 -0
- package/dist/constraint-runtime/reference_data/subsystems/components.json +32 -0
- package/dist/constraint-runtime/reference_data/subsystems/constants.json +28 -0
- package/dist/constraint-runtime/reference_data/subsystems/coordinator.json +8 -0
- package/dist/constraint-runtime/reference_data/subsystems/entrypoints.json +15 -0
- package/dist/constraint-runtime/reference_data/subsystems/hooks.json +32 -0
- package/dist/constraint-runtime/reference_data/subsystems/keybindings.json +21 -0
- package/dist/constraint-runtime/reference_data/subsystems/memdir.json +15 -0
- package/dist/constraint-runtime/reference_data/subsystems/migrations.json +18 -0
- package/dist/constraint-runtime/reference_data/subsystems/moreright.json +8 -0
- package/dist/constraint-runtime/reference_data/subsystems/native_ts.json +11 -0
- package/dist/constraint-runtime/reference_data/subsystems/outputStyles.json +8 -0
- package/dist/constraint-runtime/reference_data/subsystems/plugins.json +9 -0
- package/dist/constraint-runtime/reference_data/subsystems/remote.json +11 -0
- package/dist/constraint-runtime/reference_data/subsystems/schemas.json +8 -0
- package/dist/constraint-runtime/reference_data/subsystems/screens.json +10 -0
- package/dist/constraint-runtime/reference_data/subsystems/server.json +10 -0
- package/dist/constraint-runtime/reference_data/subsystems/services.json +32 -0
- package/dist/constraint-runtime/reference_data/subsystems/skills.json +27 -0
- package/dist/constraint-runtime/reference_data/subsystems/state.json +13 -0
- package/dist/constraint-runtime/reference_data/subsystems/types.json +18 -0
- package/dist/constraint-runtime/reference_data/subsystems/upstreamproxy.json +9 -0
- package/dist/constraint-runtime/reference_data/subsystems/utils.json +32 -0
- package/dist/constraint-runtime/reference_data/subsystems/vim.json +12 -0
- package/dist/constraint-runtime/reference_data/subsystems/voice.json +8 -0
- package/dist/constraint-runtime/reference_data/tools_snapshot.json +922 -0
- package/dist/constraint-runtime/setup.js +1 -1
- package/dist/constraint-runtime/tools/PolymarketSDK/cancelOrder.d.ts +13 -3
- package/dist/constraint-runtime/tools/PolymarketSDK/cancelOrder.js +16 -4
- package/dist/constraint-runtime/tools/PolymarketSDK/clobShared.d.ts +50 -0
- package/dist/constraint-runtime/tools/PolymarketSDK/clobShared.js +78 -0
- package/dist/constraint-runtime/tools/PolymarketSDK/createOrder.d.ts +24 -3
- package/dist/constraint-runtime/tools/PolymarketSDK/createOrder.js +31 -4
- package/dist/constraint-runtime/tools/PolymarketSDK/getMarket.d.ts +1 -0
- package/dist/constraint-runtime/tools/PolymarketSDK/getMarket.js +14 -3
- package/dist/constraint-runtime/tools/PolymarketSDK/getOrders.d.ts +11 -2
- package/dist/constraint-runtime/tools/PolymarketSDK/getOrders.js +23 -4
- package/dist/constraint-runtime/tools/PolymarketSDK/listMarkets.d.ts +4 -0
- package/dist/constraint-runtime/tools/PolymarketSDK/listMarkets.js +22 -2
- package/dist/context-compaction/auto-compact.js +7 -7
- package/dist/electron/config.js.map +1 -0
- package/dist/electron/dialogs.js.map +1 -0
- package/dist/electron/first-run.js +54 -54
- package/dist/electron/first-run.js.map +1 -0
- package/dist/electron/ipc.js.map +1 -0
- package/dist/electron/logger.js.map +1 -0
- package/dist/electron/main.js.map +1 -0
- package/dist/electron/menu.js.map +1 -0
- package/dist/electron/paths.js.map +1 -0
- package/dist/electron/server.js.map +1 -0
- package/dist/electron/tray.js.map +1 -0
- package/dist/electron/window.js.map +1 -0
- package/dist/electron-build/electron/first-run.js +54 -54
- package/dist/electron-preload.js.map +1 -1
- package/dist/electron.js.map +1 -1
- package/dist/index.js +113 -113
- package/dist/llm/llm-judgment-client.js +102 -102
- package/dist/llm/pi-ai.js +48 -48
- package/dist/llm/system-prompt/layers/channel/human-async.md +41 -41
- package/dist/llm/system-prompt/layers/channel/local.md +14 -14
- package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -18
- package/dist/llm/system-prompt/layers/channel/p2p-peer-sync.md +51 -51
- package/dist/llm/system-prompt/layers/channel/p2p-proactive.md +43 -43
- package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -19
- package/dist/llm/system-prompt/layers/channel/session-handoff.md +61 -61
- package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -89
- package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -21
- package/dist/llm/system-prompt/layers/core/external-engagement.md +73 -73
- package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -15
- package/dist/llm/system-prompt/layers/core/identity.md +48 -48
- package/dist/llm/system-prompt/layers/core/knowledge.md +17 -17
- package/dist/llm/system-prompt/layers/core/memory_system.md +12 -12
- package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -28
- package/dist/llm/system-prompt/layers/core/refusal.md +37 -37
- package/dist/llm/system-prompt/layers/core/tone.md +31 -31
- package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -13
- package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -41
- package/dist/llm/system-prompt/layers/role/architect.md +20 -20
- package/dist/llm/system-prompt/layers/role/expert.md +19 -19
- package/dist/llm/system-prompt/layers/role/implementer.md +15 -15
- package/dist/llm/system-prompt/layers/role/security.md +15 -15
- package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -72
- package/dist/llm/system-prompt/layers/tool/bash.md +25 -25
- package/dist/llm/system-prompt/layers/tool/goal_handoff.md +77 -77
- package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -171
- package/dist/llm/system-prompt/layers/tool/image_search.md +70 -70
- package/dist/llm/system-prompt/layers/tool/manifest.md +89 -89
- package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -53
- package/dist/llm/system-prompt/layers/tool/p2p_request.md +61 -61
- package/dist/llm/system-prompt/layers/tool/web_search.md +83 -83
- package/dist/llm/tool-manifest/ask_user_input.js +1 -1
- package/dist/llm/tool-manifest/bash.js +3 -3
- package/dist/llm/tool-manifest/create_file.js +4 -4
- package/dist/llm/tool-manifest/fetch_sports_data.js +3 -3
- package/dist/llm/tool-manifest/image_search.js +2 -2
- package/dist/llm/tool-manifest/index.js +59 -0
- package/dist/llm/tool-manifest/mcp.js +2 -2
- package/dist/llm/tool-manifest/message_compose.js +3 -3
- package/dist/llm/tool-manifest/places.js +2 -2
- package/dist/llm/tool-manifest/present_files.js +1 -1
- package/dist/llm/tool-manifest/recipe.js +2 -2
- package/dist/llm/tool-manifest/str_replace.js +5 -5
- package/dist/llm/tool-manifest/view.js +3 -3
- package/dist/llm/tool-manifest/weather.js +4 -4
- package/dist/llm/tool-manifest/web.js +4 -4
- package/dist/orbitdb/cid-database.js +41 -0
- package/dist/orbitdb/did-catalog-replication.js +199 -0
- package/dist/orbitdb/trajectory-store.js +150 -0
- package/dist/pi-ecosystem-judgment/causal-judge.js +51 -51
- package/dist/pi-ecosystem-judgment/distill-prompt.js +42 -42
- package/dist/pi-ecosystem-judgment/distillation.js +14 -14
- package/dist/pi-ecosystem-judgment/monitor-gate.js +28 -28
- package/dist/pi-ecosystem-judgment/value-injection.js +102 -102
- package/dist/security/context-router-tool.js +15 -15
- package/dist/storage/did-catalog-bridge.js +271 -0
- package/dist/utils/auto-update.js.map +1 -0
- package/dist/web/api-config.html +779 -779
- package/dist/web/client-hearth.js +10 -10
- package/dist/web/client.js +141 -0
- package/dist/web/client.js.map +7 -0
- package/dist/web/components/wallet-viem.mjs +118 -118
- package/dist/web/index.html +472 -424
- package/dist/web/manifest.json +20 -20
- package/dist/web/server.js +290 -13
- package/dist/web/style.css +4946 -4914
- package/package.json +193 -193
- package/scripts/build-cli.js +215 -215
- package/scripts/build-web.ts +130 -130
- package/scripts/postinstall.js +152 -152
- package/bin/bolloon.js +0 -157
- package/dist/pi-ecosystem-colony/index.js +0 -365
- package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
- package/dist/social/ant-colony/PheromoneEngine.js +0 -227
- package/dist/social/ant-colony/index.js +0 -6
- package/dist/social/ant-colony/types.js +0 -24
- package/dist/test/ai-judgment-test.js +0 -80
- package/dist/test/bollharness-integration.test.js +0 -318
- package/dist/test/channel-agent-multi-dialogue.js +0 -205
- package/dist/test/channel-heartbeat-agent-test.js +0 -201
- package/dist/test/constraint-layer.test.js +0 -164
- package/dist/test/diap-identity-test.js +0 -172
- package/dist/test/diap-quick-test.js +0 -62
- package/dist/test/global-shared-context.test.js +0 -315
- package/dist/test/harness-judgment-injection.test.js +0 -246
- package/dist/test/harness-workflow-integrator-test.js +0 -228
- package/dist/test/human-value-store.test.js +0 -243
- package/dist/test/hybrid-integration-test.js +0 -118
- package/dist/test/hybrid-messenger-verify.js +0 -55
- package/dist/test/iroh-bistream-debug.js +0 -38
- package/dist/test/iroh-communication.test.js +0 -66
- package/dist/test/iroh-debug-test.js +0 -57
- package/dist/test/iroh-diap-test.js +0 -71
- package/dist/test/iroh-direct-connect.js +0 -55
- package/dist/test/iroh-e2e-fixed.js +0 -89
- package/dist/test/iroh-e2e-same-process.js +0 -63
- package/dist/test/iroh-e2e.js +0 -66
- package/dist/test/iroh-final-e2e.js +0 -72
- package/dist/test/iroh-relay-test.js +0 -37
- package/dist/test/iroh-simple-test.js +0 -41
- package/dist/test/iroh-transport-verify.js +0 -54
- package/dist/test/iroh-transport.test.js +0 -37
- package/dist/test/iroh-two-nodes.js +0 -70
- package/dist/test/iroh-verify.js +0 -44
- package/dist/test/judgment-decision.test.js +0 -219
- package/dist/test/llm-judgment-integration.test.js +0 -220
- package/dist/test/p2p-agent-complex-dialogue.js +0 -385
- package/dist/test/p2p-agent-dialogue.js +0 -341
- package/dist/test/p2p-agent-full-bidirectional.js +0 -510
- package/dist/test/p2p-agent-harness-flow.js +0 -437
- package/dist/test/p2p-agent-harness-single.js +0 -143
- package/dist/test/p2p-ai-dialogue-test.js +0 -318
- package/dist/test/p2p-cid-connect-test.js +0 -195
- package/dist/test/p2p-connect-receiver.js +0 -69
- package/dist/test/p2p-doc-transfer.js +0 -110
- package/dist/test/p2p-identity-page-test.js +0 -77
- package/dist/test/p2p-iroh-test.js +0 -171
- package/dist/test/p2p-minimal-test.js +0 -241
- package/dist/test/p2p-node-1.js +0 -148
- package/dist/test/p2p-node-2.js +0 -148
- package/dist/test/p2p-server.js +0 -281
- package/dist/test/p2p-two-nodes-test.js +0 -438
- package/dist/test/pi-sdk.test.js +0 -44
- package/dist/test/set-persona.js +0 -40
- package/dist/test/simple.test.js +0 -9
- package/dist/test/storage-integration.test.js +0 -150
- package/dist/test/subagent-manager.test.js +0 -276
- package/dist/test/test-gate-flow.test.js +0 -81
- package/dist/test/workflow-engine.test.js +0 -87
- package/dist/test/workflow-pivot-loop.test.js +0 -246
package/dist/web/manifest.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Bolloon Agent",
|
|
3
|
-
"short_name": "Bolloon",
|
|
4
|
-
"description": "AI Agent with Claude API integration",
|
|
5
|
-
"start_url": "/",
|
|
6
|
-
"display": "standalone",
|
|
7
|
-
"background_color": "#1a1a2e",
|
|
8
|
-
"theme_color": "#1a1a2e",
|
|
9
|
-
"icons": [
|
|
10
|
-
{
|
|
11
|
-
"src": "/icons/favicon-192x192.png",
|
|
12
|
-
"sizes": "192x192",
|
|
13
|
-
"type": "image/png"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"src": "/icons/favicon-512x512.png",
|
|
17
|
-
"sizes": "512x512",
|
|
18
|
-
"type": "image/png"
|
|
19
|
-
}
|
|
20
|
-
]
|
|
1
|
+
{
|
|
2
|
+
"name": "Bolloon Agent",
|
|
3
|
+
"short_name": "Bolloon",
|
|
4
|
+
"description": "AI Agent with Claude API integration",
|
|
5
|
+
"start_url": "/",
|
|
6
|
+
"display": "standalone",
|
|
7
|
+
"background_color": "#1a1a2e",
|
|
8
|
+
"theme_color": "#1a1a2e",
|
|
9
|
+
"icons": [
|
|
10
|
+
{
|
|
11
|
+
"src": "/icons/favicon-192x192.png",
|
|
12
|
+
"sizes": "192x192",
|
|
13
|
+
"type": "image/png"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"src": "/icons/favicon-512x512.png",
|
|
17
|
+
"sizes": "512x512",
|
|
18
|
+
"type": "image/png"
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
21
|
}
|
package/dist/web/server.js
CHANGED
|
@@ -1669,6 +1669,40 @@ export async function createWebServer(port = 3000, options = {}) {
|
|
|
1669
1669
|
console.warn('[mcp] 初始化失败 (非致命):', e?.message?.slice(0, 120));
|
|
1670
1670
|
}
|
|
1671
1671
|
})();
|
|
1672
|
+
// 2026-08-08: DID 目录启动接入 — 回填既有磁盘数据 + 启动 OrbitDB 自动复制.
|
|
1673
|
+
// fire-and-forget: 不阻塞启动; 失败静默 (catalog 是增强层, 原磁盘路径永远可用).
|
|
1674
|
+
(async () => {
|
|
1675
|
+
try {
|
|
1676
|
+
const { openUserCatalog, backfillDidCatalog } = await import('../storage/did-catalog-bridge.js');
|
|
1677
|
+
const cat = await openUserCatalog();
|
|
1678
|
+
if (!cat) {
|
|
1679
|
+
console.log('[did-catalog] 未生成用户 DID, 跳过回填 (首次启动会由 /api/user/identity 生成)');
|
|
1680
|
+
return;
|
|
1681
|
+
}
|
|
1682
|
+
const r = await backfillDidCatalog(cat);
|
|
1683
|
+
const total = r.reduce((a, x) => a + x.added, 0);
|
|
1684
|
+
console.log(`[did-catalog] 启动回填完成: ${total} 行新写入 (${r.map(x => `${x.table}=${x.added}+${x.skipped}跳过`).join(', ')})`);
|
|
1685
|
+
}
|
|
1686
|
+
catch (e) {
|
|
1687
|
+
console.warn('[did-catalog] 启动回填失败 (非致命):', e?.message?.slice(0, 120));
|
|
1688
|
+
}
|
|
1689
|
+
})();
|
|
1690
|
+
// 2026-08-08: DID 目录 → OrbitDB 自动复制 (WAL 事件流驱动跨设备合并).
|
|
1691
|
+
// 懒启动: 等 identity 就绪后再开; 失败静默 (离线时 catalog 照常工作).
|
|
1692
|
+
(async () => {
|
|
1693
|
+
try {
|
|
1694
|
+
const identity = await loadOrCreateUserIdentity();
|
|
1695
|
+
if (!identity.did)
|
|
1696
|
+
return;
|
|
1697
|
+
const { startDidCatalogReplication } = await import('../orbitdb/did-catalog-replication.js');
|
|
1698
|
+
const rep = await startDidCatalogReplication(identity.did, { intervalMs: 30_000 });
|
|
1699
|
+
console.log(`[did-catalog] OrbitDB 自动复制已启动: store=${rep.storeName} address=${String(rep.storeAddress).slice(0, 48)}...`);
|
|
1700
|
+
globalThis.__didCatalogReplication = rep;
|
|
1701
|
+
}
|
|
1702
|
+
catch (e) {
|
|
1703
|
+
console.warn('[did-catalog] OrbitDB 复制启动失败 (非致命, 稍后可用 API 重试):', e?.message?.slice(0, 120));
|
|
1704
|
+
}
|
|
1705
|
+
})();
|
|
1672
1706
|
// 重置旧的 agent session,确保使用新的 LLM 配置
|
|
1673
1707
|
const { resetAgentSession } = await import('../agents/pi-sdk.js');
|
|
1674
1708
|
resetAgentSession();
|
|
@@ -1839,6 +1873,13 @@ export async function createWebServer(port = 3000, options = {}) {
|
|
|
1839
1873
|
// 尝试发布 DID 到 IPFS
|
|
1840
1874
|
try {
|
|
1841
1875
|
const auth = await AgentAuthManager.newWithRemoteIpfs('http://127.0.0.1:5001', 'http://127.0.0.1:8080');
|
|
1876
|
+
// 2026-08-09: 归属用户 DID — 智能体身份归属用户唯一身份 (DID 文档带 controller+alsoKnownAs)
|
|
1877
|
+
try {
|
|
1878
|
+
const owner = await loadOrCreateUserIdentity();
|
|
1879
|
+
if (owner?.did)
|
|
1880
|
+
auth.setOwnerDid(owner.did);
|
|
1881
|
+
}
|
|
1882
|
+
catch { /* 归属设置失败不阻塞 */ }
|
|
1842
1883
|
await auth.registerAgent({ name, services: [] }, kp, '');
|
|
1843
1884
|
console.log('P2P DID 已发布到 IPFS');
|
|
1844
1885
|
}
|
|
@@ -2313,19 +2354,19 @@ export async function createWebServer(port = 3000, options = {}) {
|
|
|
2313
2354
|
.map((p) => `- ${p.name || p.publicKey.slice(0, 8)} (pk=${p.publicKey.slice(0, 12)}…): 渠道[${p.channels.map((c) => c.name).join(', ') || '无'}]`)
|
|
2314
2355
|
.join('\n');
|
|
2315
2356
|
const goalDesc = ctx.goal ? `当前目标: ${ctx.goal.description} (已发起 ${ctx.goal.initiationsUsed}/${ctx.goal.maxInitiations}, 有效回复 ${ctx.goal.effectfulReplies}/${ctx.goal.effectThreshold})` : '当前无明确目标';
|
|
2316
|
-
const prompt = `你是智能体「${ctx.self.name || '本地智能体'}」。你通过 P2P 网络认识以下其他智能体:
|
|
2317
|
-
${peerLines}
|
|
2318
|
-
|
|
2319
|
-
${goalDesc}
|
|
2320
|
-
|
|
2321
|
-
规则:
|
|
2322
|
-
1. 社交是为了达成上述目标, 不是闲聊。只在你有真正有价值的信息要分享/询问、且能推进目标时才主动发起。
|
|
2323
|
-
2. 不要重复最近已经聊过的话题, 不要每条心跳都发消息, 保持克制。
|
|
2324
|
-
3. 如果目标已经通过已有交流达成 (或你认为无需再聊), 输出 {"initiate": false, "goalAchieved": true}。
|
|
2325
|
-
4. 如果决定发起, 选一个最合适的目标渠道 (用对方渠道的真实 id)。
|
|
2326
|
-
|
|
2327
|
-
现在是否要主动联系其中某个智能体? 只输出一个 JSON 对象, 不要任何其他文字:
|
|
2328
|
-
{"initiate": true 或 false, "goalAchieved": true 或 false, "targetPeerPublicKey": "对方 pk", "targetChannelId": "对方渠道 id", "message": "你要说的话"}
|
|
2357
|
+
const prompt = `你是智能体「${ctx.self.name || '本地智能体'}」。你通过 P2P 网络认识以下其他智能体:
|
|
2358
|
+
${peerLines}
|
|
2359
|
+
|
|
2360
|
+
${goalDesc}
|
|
2361
|
+
|
|
2362
|
+
规则:
|
|
2363
|
+
1. 社交是为了达成上述目标, 不是闲聊。只在你有真正有价值的信息要分享/询问、且能推进目标时才主动发起。
|
|
2364
|
+
2. 不要重复最近已经聊过的话题, 不要每条心跳都发消息, 保持克制。
|
|
2365
|
+
3. 如果目标已经通过已有交流达成 (或你认为无需再聊), 输出 {"initiate": false, "goalAchieved": true}。
|
|
2366
|
+
4. 如果决定发起, 选一个最合适的目标渠道 (用对方渠道的真实 id)。
|
|
2367
|
+
|
|
2368
|
+
现在是否要主动联系其中某个智能体? 只输出一个 JSON 对象, 不要任何其他文字:
|
|
2369
|
+
{"initiate": true 或 false, "goalAchieved": true 或 false, "targetPeerPublicKey": "对方 pk", "targetChannelId": "对方渠道 id", "message": "你要说的话"}
|
|
2329
2370
|
若不想发起, 输出 {"initiate": false}。`;
|
|
2330
2371
|
const raw = await agent.promptStream(prompt, () => { }, undefined, local.id);
|
|
2331
2372
|
const m = raw.match(/\{[\s\S]*\}/);
|
|
@@ -2759,6 +2800,117 @@ ${goalDesc}
|
|
|
2759
2800
|
res.status(500).json({ error: err.message });
|
|
2760
2801
|
}
|
|
2761
2802
|
});
|
|
2803
|
+
// ========== 登录框架 (2026-08-09) — GitHub/Google/邮箱/手机号, 仅骨架 ==========
|
|
2804
|
+
// 所有登录方式最终都归属到用户 DID (右下角唯一身份).
|
|
2805
|
+
// 真实 OAuth / 验证码后续接入, 这里先做: 记录账号 + 绑定用户 DID + 提供状态查询.
|
|
2806
|
+
const ACCOUNTS_FILE = `${process.env.HOME || '/tmp'}/.bolloon/accounts.json`;
|
|
2807
|
+
async function loadAccounts() {
|
|
2808
|
+
try {
|
|
2809
|
+
const { readFile } = await import('fs/promises');
|
|
2810
|
+
const parsed = JSON.parse(await readFile(ACCOUNTS_FILE, 'utf-8'));
|
|
2811
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
2812
|
+
}
|
|
2813
|
+
catch {
|
|
2814
|
+
return [];
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
async function saveAccounts(accs) {
|
|
2818
|
+
const { mkdir, writeFile } = await import('fs/promises');
|
|
2819
|
+
await mkdir(`${process.env.HOME || '/tmp'}/.bolloon`, { recursive: true });
|
|
2820
|
+
await writeFile(ACCOUNTS_FILE, JSON.stringify(accs, null, 2), { mode: 0o600 });
|
|
2821
|
+
}
|
|
2822
|
+
// GET /api/auth/status — 当前用户 DID + 已绑定账号列表
|
|
2823
|
+
app.get('/api/auth/status', async (_req, res) => {
|
|
2824
|
+
try {
|
|
2825
|
+
const identity = await loadOrCreateUserIdentity();
|
|
2826
|
+
const accs = await loadAccounts();
|
|
2827
|
+
res.json({
|
|
2828
|
+
did: identity.did,
|
|
2829
|
+
didShort: identity.didShort,
|
|
2830
|
+
name: identity.name,
|
|
2831
|
+
// 只返回脱敏视图 (不含 token)
|
|
2832
|
+
accounts: accs.map((a) => ({
|
|
2833
|
+
provider: a.provider,
|
|
2834
|
+
identifier: a.identifier || a.email || a.username || '',
|
|
2835
|
+
loggedAt: a.loggedAt,
|
|
2836
|
+
skeleton: !!a.skeleton,
|
|
2837
|
+
})),
|
|
2838
|
+
});
|
|
2839
|
+
}
|
|
2840
|
+
catch (err) {
|
|
2841
|
+
res.status(500).json({ error: err.message });
|
|
2842
|
+
}
|
|
2843
|
+
});
|
|
2844
|
+
// POST /api/auth/login — 登录骨架 (记录账号 + 绑定用户 DID)
|
|
2845
|
+
// body: { provider: 'github'|'google'|'email'|'phone', identifier?: string }
|
|
2846
|
+
app.post('/api/auth/login', async (req, res) => {
|
|
2847
|
+
try {
|
|
2848
|
+
const { provider, identifier } = req.body || {};
|
|
2849
|
+
const prov = String(provider || '').trim().toLowerCase();
|
|
2850
|
+
const VALID = ['github', 'google', 'email', 'phone'];
|
|
2851
|
+
if (!VALID.includes(prov)) {
|
|
2852
|
+
return res.status(400).json({ error: `provider 必须是 ${VALID.join('/')}` });
|
|
2853
|
+
}
|
|
2854
|
+
// 邮箱/手机号必填 identifier
|
|
2855
|
+
if ((prov === 'email' || prov === 'phone') && !String(identifier || '').trim()) {
|
|
2856
|
+
return res.status(400).json({ error: `${prov === 'email' ? '邮箱' : '手机号'}必填` });
|
|
2857
|
+
}
|
|
2858
|
+
const identity = await loadOrCreateUserIdentity();
|
|
2859
|
+
const accs = await loadAccounts();
|
|
2860
|
+
const idStr = String(identifier || '').trim();
|
|
2861
|
+
const existing = accs.find((a) => a.provider === prov && (!idStr || a.identifier === idStr || a.email === idStr));
|
|
2862
|
+
const now = new Date().toISOString();
|
|
2863
|
+
if (existing) {
|
|
2864
|
+
// 已绑定 → 更新归属 DID + 时间
|
|
2865
|
+
existing.ownerDid = identity.did;
|
|
2866
|
+
existing.loggedAt = now;
|
|
2867
|
+
existing.skeleton = true;
|
|
2868
|
+
}
|
|
2869
|
+
else {
|
|
2870
|
+
accs.push({
|
|
2871
|
+
provider: prov,
|
|
2872
|
+
identifier: idStr || '',
|
|
2873
|
+
email: prov === 'email' ? idStr : '',
|
|
2874
|
+
phone: prov === 'phone' ? idStr : '',
|
|
2875
|
+
username: idStr || '',
|
|
2876
|
+
token: '', // 真实 OAuth 后填
|
|
2877
|
+
ownerDid: identity.did, // 归属用户唯一 DID
|
|
2878
|
+
loggedAt: now,
|
|
2879
|
+
skeleton: true, // 骨架标记: 未做真实 OAuth/验证码
|
|
2880
|
+
});
|
|
2881
|
+
}
|
|
2882
|
+
await saveAccounts(accs);
|
|
2883
|
+
console.log(`[auth] 登录骨架: ${prov}${idStr ? ' ' + idStr : ''} → 归属 DID ${identity.did.substring(0, 20)}...`);
|
|
2884
|
+
res.json({
|
|
2885
|
+
ok: true,
|
|
2886
|
+
provider: prov,
|
|
2887
|
+
identifier: idStr,
|
|
2888
|
+
ownerDid: identity.did,
|
|
2889
|
+
skeleton: true,
|
|
2890
|
+
message: `${prov} 登录骨架已记录 (归属用户 DID), 真实 OAuth/验证码后续接入`,
|
|
2891
|
+
});
|
|
2892
|
+
}
|
|
2893
|
+
catch (err) {
|
|
2894
|
+
res.status(500).json({ error: err.message });
|
|
2895
|
+
}
|
|
2896
|
+
});
|
|
2897
|
+
// POST /api/auth/logout — 解除某个 provider 的绑定 (骨架)
|
|
2898
|
+
app.post('/api/auth/logout', async (req, res) => {
|
|
2899
|
+
try {
|
|
2900
|
+
const { provider } = req.body || {};
|
|
2901
|
+
const prov = String(provider || '').trim().toLowerCase();
|
|
2902
|
+
const accs = await loadAccounts();
|
|
2903
|
+
const before = accs.length;
|
|
2904
|
+
const remaining = accs.filter((a) => a.provider !== prov);
|
|
2905
|
+
if (remaining.length === before)
|
|
2906
|
+
return res.status(404).json({ error: `未绑定 ${prov} 账号` });
|
|
2907
|
+
await saveAccounts(remaining);
|
|
2908
|
+
res.json({ ok: true, provider: prov });
|
|
2909
|
+
}
|
|
2910
|
+
catch (err) {
|
|
2911
|
+
res.status(500).json({ error: err.message });
|
|
2912
|
+
}
|
|
2913
|
+
});
|
|
2762
2914
|
// 2026-08-08: DID 目录 (Postgres 式) — 以用户 DID 为主键, 绑定 memory/persona/skills/on_policy/context_os 等表
|
|
2763
2915
|
app.get('/api/did-catalog/:table', async (req, res) => {
|
|
2764
2916
|
try {
|
|
@@ -2818,6 +2970,104 @@ ${goalDesc}
|
|
|
2818
2970
|
res.status(500).json({ error: err.message });
|
|
2819
2971
|
}
|
|
2820
2972
|
});
|
|
2973
|
+
// 手动触发启动回填 (既有磁盘数据 → DID 目录表, 幂等)
|
|
2974
|
+
app.post('/api/did-catalog/backfill', async (_req, res) => {
|
|
2975
|
+
try {
|
|
2976
|
+
const identity = await loadOrCreateUserIdentity();
|
|
2977
|
+
if (!identity.did)
|
|
2978
|
+
return res.status(404).json({ error: '未生成用户 DID' });
|
|
2979
|
+
const { openUserCatalog, backfillDidCatalog } = await import('../storage/did-catalog-bridge.js');
|
|
2980
|
+
const cat = await openUserCatalog();
|
|
2981
|
+
if (!cat)
|
|
2982
|
+
return res.status(404).json({ error: '目录未打开' });
|
|
2983
|
+
const r = await backfillDidCatalog(cat);
|
|
2984
|
+
res.json({ ok: true, did: identity.did, tables: r });
|
|
2985
|
+
}
|
|
2986
|
+
catch (err) {
|
|
2987
|
+
res.status(500).json({ error: err.message });
|
|
2988
|
+
}
|
|
2989
|
+
});
|
|
2990
|
+
// OrbitDB 复制状态 / 启动 (自动复制失败后的手动入口)
|
|
2991
|
+
app.get('/api/did-catalog/replication', async (_req, res) => {
|
|
2992
|
+
try {
|
|
2993
|
+
const identity = await loadOrCreateUserIdentity();
|
|
2994
|
+
if (!identity.did)
|
|
2995
|
+
return res.status(404).json({ error: '未生成用户 DID' });
|
|
2996
|
+
const rep = globalThis.__didCatalogReplication;
|
|
2997
|
+
if (!rep)
|
|
2998
|
+
return res.json({ ok: false, did: identity.did, running: false });
|
|
2999
|
+
const { publishPending, syncNow } = rep;
|
|
3000
|
+
const published = await publishPending();
|
|
3001
|
+
const synced = await syncNow();
|
|
3002
|
+
res.json({
|
|
3003
|
+
ok: true, did: identity.did, running: true,
|
|
3004
|
+
storeName: rep.storeName, storeAddress: rep.storeAddress,
|
|
3005
|
+
stats: rep.stats, publishedNow: published, syncedNow: synced,
|
|
3006
|
+
});
|
|
3007
|
+
}
|
|
3008
|
+
catch (err) {
|
|
3009
|
+
res.status(500).json({ error: err.message });
|
|
3010
|
+
}
|
|
3011
|
+
});
|
|
3012
|
+
app.post('/api/did-catalog/replication/start', async (_req, res) => {
|
|
3013
|
+
try {
|
|
3014
|
+
const identity = await loadOrCreateUserIdentity();
|
|
3015
|
+
if (!identity.did)
|
|
3016
|
+
return res.status(404).json({ error: '未生成用户 DID' });
|
|
3017
|
+
if (globalThis.__didCatalogReplication) {
|
|
3018
|
+
return res.json({ ok: true, did: identity.did, running: true, storeAddress: globalThis.__didCatalogReplication.storeAddress });
|
|
3019
|
+
}
|
|
3020
|
+
const { startDidCatalogReplication } = await import('../orbitdb/did-catalog-replication.js');
|
|
3021
|
+
const rep = await startDidCatalogReplication(identity.did, { intervalMs: 30_000 });
|
|
3022
|
+
globalThis.__didCatalogReplication = rep;
|
|
3023
|
+
res.json({ ok: true, did: identity.did, running: true, storeName: rep.storeName, storeAddress: rep.storeAddress });
|
|
3024
|
+
}
|
|
3025
|
+
catch (err) {
|
|
3026
|
+
res.status(500).json({ error: err.message });
|
|
3027
|
+
}
|
|
3028
|
+
});
|
|
3029
|
+
// 智能体运行轨迹 (trajectory): 列表 + 单条 (落盘 ~/.bolloon/trajectories/)
|
|
3030
|
+
app.get('/api/trajectories', async (_req, res) => {
|
|
3031
|
+
try {
|
|
3032
|
+
const { listTrajectories } = await import('../orbitdb/trajectory-store.js');
|
|
3033
|
+
const list = await listTrajectories();
|
|
3034
|
+
const summary = [];
|
|
3035
|
+
for (const { runId, file } of list) {
|
|
3036
|
+
try {
|
|
3037
|
+
const { loadTrajectory } = await import('../orbitdb/trajectory-store.js');
|
|
3038
|
+
const run = await loadTrajectory(runId);
|
|
3039
|
+
summary.push({
|
|
3040
|
+
runId, file,
|
|
3041
|
+
agentId: run?.agentId, channelId: run?.channelId,
|
|
3042
|
+
startedAt: run?.startedAt, endedAt: run?.endedAt,
|
|
3043
|
+
durationMs: run?.durationMs, status: run?.status,
|
|
3044
|
+
input: run?.input?.slice(0, 120), reply: run?.reply?.slice(0, 120),
|
|
3045
|
+
steps: run?.steps?.length ?? 0,
|
|
3046
|
+
});
|
|
3047
|
+
}
|
|
3048
|
+
catch { /* 单条失败跳过 */ }
|
|
3049
|
+
}
|
|
3050
|
+
res.json({ ok: true, count: list.length, runs: summary });
|
|
3051
|
+
}
|
|
3052
|
+
catch (err) {
|
|
3053
|
+
res.status(500).json({ error: err.message });
|
|
3054
|
+
}
|
|
3055
|
+
});
|
|
3056
|
+
app.get('/api/trajectories/:runId', async (req, res) => {
|
|
3057
|
+
try {
|
|
3058
|
+
const { loadTrajectory } = await import('../orbitdb/trajectory-store.js');
|
|
3059
|
+
const runId = String(req.params.runId || '');
|
|
3060
|
+
if (!runId)
|
|
3061
|
+
return res.status(400).json({ error: 'runId 必填' });
|
|
3062
|
+
const run = await loadTrajectory(runId);
|
|
3063
|
+
if (!run)
|
|
3064
|
+
return res.status(404).json({ error: `轨迹不存在: ${runId}` });
|
|
3065
|
+
res.json({ ok: true, run });
|
|
3066
|
+
}
|
|
3067
|
+
catch (err) {
|
|
3068
|
+
res.status(500).json({ error: err.message });
|
|
3069
|
+
}
|
|
3070
|
+
});
|
|
2821
3071
|
// 2026-07-01 (v0.2.6): 前后端分离核心 — 后端切 LLM 输出为结构化 segments
|
|
2822
3072
|
// - POST /api/segment-reply { reply, knownTools }
|
|
2823
3073
|
// - 返回 ChatSegment[] (think / text / env_details / tool_call / final)
|
|
@@ -3419,6 +3669,26 @@ ${goalDesc}
|
|
|
3419
3669
|
const memBlock = summariesToRead.map(s => s.trim().slice(-1500)).join('\n\n---\n\n');
|
|
3420
3670
|
contextHint += `[系统上下文] 动态状态层 · chat-worksite (上次做到哪 — 本 channel 历史记忆, 来自 memory-compressor 摘要, 引用而非复述):\n${memBlock.slice(-2500)}\n\n`;
|
|
3421
3671
|
}
|
|
3672
|
+
else {
|
|
3673
|
+
// 2026-08-08 (DID 目录读侧): 磁盘无摘要时, 回退读 DID 目录 memory 表 (跨设备同步来的记忆)
|
|
3674
|
+
try {
|
|
3675
|
+
const { openUserCatalog, catalogMemoryRows } = await import('../storage/did-catalog-bridge.js');
|
|
3676
|
+
const cat = await openUserCatalog();
|
|
3677
|
+
if (cat) {
|
|
3678
|
+
const rows = catalogMemoryRows(cat, agentId);
|
|
3679
|
+
if (rows.length > 0) {
|
|
3680
|
+
const memBlock = rows.slice(0, 2)
|
|
3681
|
+
.map(({ row }) => String(row.data.summary || '').slice(-1500))
|
|
3682
|
+
.filter(Boolean)
|
|
3683
|
+
.join('\n\n---\n\n');
|
|
3684
|
+
if (memBlock) {
|
|
3685
|
+
contextHint += `[系统上下文] 动态状态层 · chat-worksite (DID 目录同步记忆, 引用而非复述):\n${memBlock.slice(-2500)}\n\n`;
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3688
|
+
}
|
|
3689
|
+
}
|
|
3690
|
+
catch { /* 目录读失败静默 */ }
|
|
3691
|
+
}
|
|
3422
3692
|
}
|
|
3423
3693
|
}
|
|
3424
3694
|
catch (memErr) {
|
|
@@ -4024,6 +4294,13 @@ ${goalDesc}
|
|
|
4024
4294
|
const pkBytes = Buffer.from(channel.publicKey, 'hex');
|
|
4025
4295
|
const kp = { privateKey: new Uint8Array(32), publicKey: pkBytes, did: channel.did };
|
|
4026
4296
|
const auth = await AgentAuthManager.newWithRemoteIpfs('http://127.0.0.1:5001', 'http://127.0.0.1:8080');
|
|
4297
|
+
// 2026-08-09: 归属用户 DID — 子智能体身份归属用户唯一身份
|
|
4298
|
+
try {
|
|
4299
|
+
const owner = await loadOrCreateUserIdentity();
|
|
4300
|
+
if (owner?.did)
|
|
4301
|
+
auth.setOwnerDid(owner.did);
|
|
4302
|
+
}
|
|
4303
|
+
catch { /* 归属设置失败不阻塞 */ }
|
|
4027
4304
|
const result = await auth.registerAgent({ name: channel.name, services: [] }, kp, '');
|
|
4028
4305
|
channel.cid = result.cid || channel.cid;
|
|
4029
4306
|
// 关键: 不再保存整份 didDocument, 只留 cid/ipnsName 两个引用字段
|