@bolloon/bolloon-agent 0.5.5 → 0.6.1

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 (158) hide show
  1. package/dist/agents/execution-entry.js +10 -0
  2. package/dist/agents/goal-flywheel/wiring/seams.js +5 -1
  3. package/dist/agents/parse-tool-call.js +6 -1
  4. package/dist/agents/pi-sdk-session-factory.js +36 -3
  5. package/dist/agents/pi-sdk-tools.js +18 -8
  6. package/dist/agents/pi-sdk.js +749 -1390
  7. package/dist/agents/run-context.js +20 -0
  8. package/dist/agents/runner-resolver.js +3 -1
  9. package/dist/agents/tool-capability/index.js +51 -0
  10. package/dist/agents/workflow-pivot-loop.js +31 -10
  11. package/dist/agents/write-verify.js +60 -0
  12. package/dist/bollharness-integration/integration.js +8 -0
  13. package/dist/bollharness-integration/skill-adapter.js +32 -3
  14. package/dist/electron-build/agents/goal-flywheel/wiring/seams.js +5 -1
  15. package/dist/electron-build/agents/goal-flywheel/wiring/seams.js.map +1 -1
  16. package/dist/electron-build/agents/parse-tool-call.js +6 -1
  17. package/dist/electron-build/agents/parse-tool-call.js.map +1 -1
  18. package/dist/electron-build/agents/pi-sdk-session-factory.js +36 -3
  19. package/dist/electron-build/agents/pi-sdk-session-factory.js.map +1 -1
  20. package/dist/electron-build/agents/pi-sdk-tools.js +21 -11
  21. package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
  22. package/dist/electron-build/agents/pi-sdk-types.js.map +1 -1
  23. package/dist/electron-build/agents/pi-sdk.js +750 -1389
  24. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  25. package/dist/electron-build/agents/run-context.js +24 -0
  26. package/dist/electron-build/agents/run-context.js.map +1 -0
  27. package/dist/electron-build/agents/runner-resolver.js +3 -1
  28. package/dist/electron-build/agents/runner-resolver.js.map +1 -1
  29. package/dist/electron-build/agents/tool-capability/index.js +90 -0
  30. package/dist/electron-build/agents/tool-capability/index.js.map +1 -0
  31. package/dist/electron-build/agents/workflow-pivot-loop.js +31 -10
  32. package/dist/electron-build/agents/workflow-pivot-loop.js.map +1 -1
  33. package/dist/electron-build/agents/write-verify.js +99 -0
  34. package/dist/electron-build/agents/write-verify.js.map +1 -0
  35. package/dist/electron-build/bollharness-integration/integration.js +8 -0
  36. package/dist/electron-build/bollharness-integration/integration.js.map +1 -1
  37. package/dist/electron-build/bollharness-integration/skill-adapter.js +32 -3
  38. package/dist/electron-build/bollharness-integration/skill-adapter.js.map +1 -1
  39. package/dist/electron-build/kernel/channel-actor.js +339 -0
  40. package/dist/electron-build/kernel/channel-actor.js.map +1 -0
  41. package/dist/electron-build/kernel/control.js +102 -0
  42. package/dist/electron-build/kernel/control.js.map +1 -0
  43. package/dist/electron-build/kernel/model-runtime.js +508 -0
  44. package/dist/electron-build/kernel/model-runtime.js.map +1 -0
  45. package/dist/electron-build/kernel/run-lifecycle.js +146 -0
  46. package/dist/electron-build/kernel/run-lifecycle.js.map +1 -0
  47. package/dist/electron-build/kernel/transport.js +119 -0
  48. package/dist/electron-build/kernel/transport.js.map +1 -0
  49. package/dist/electron-build/llm/native-adapter.js +122 -0
  50. package/dist/electron-build/llm/native-adapter.js.map +1 -0
  51. package/dist/index.js +43 -19
  52. package/dist/ios/bolloon-web.json +3 -3
  53. package/dist/ios/client.js +13 -7
  54. package/dist/ios/mobile-core.js +7762 -6289
  55. package/dist/ios/mobile.js +64 -0
  56. package/dist/ios/routes-mobile-tasks.js +2 -1
  57. package/dist/ios/routes-tasks.js +16 -1
  58. package/dist/ios/routes-x402-info.js +28 -1
  59. package/dist/ios/server-storage.js +26 -5
  60. package/dist/ios/server.js +840 -862
  61. package/dist/ios/sw.js +1 -1
  62. package/dist/ios/ui/message-renderer.js +473 -29
  63. package/dist/ios/ui/step-timeline.js +13 -12
  64. package/dist/kernel/channel-actor.js +321 -0
  65. package/dist/kernel/control.js +95 -0
  66. package/dist/kernel/gate-scan.js +1350 -0
  67. package/dist/kernel/model-runtime.js +494 -0
  68. package/dist/kernel/plan-channel-actor.js +305 -0
  69. package/dist/kernel/plan-communication.js +163 -0
  70. package/dist/kernel/plan-constraint.js +152 -0
  71. package/dist/kernel/plan-deletion.js +32 -0
  72. package/dist/kernel/plan-harness.js +78 -0
  73. package/dist/kernel/plan-modelruntime.js +60 -0
  74. package/dist/kernel/plan-runcontext.js +163 -0
  75. package/dist/kernel/plan.js +149 -0
  76. package/dist/kernel/roster.js +244 -0
  77. package/dist/kernel/run-lifecycle.js +138 -0
  78. package/dist/kernel/transport.js +111 -0
  79. package/dist/llm/native-adapter.js +117 -0
  80. package/dist/web/bolloon-web.json +3 -3
  81. package/dist/web/client.js +12 -7
  82. package/dist/web/routes-tasks.js +16 -1
  83. package/dist/web/server.js +838 -862
  84. package/dist/web/sw.js +1 -1
  85. package/dist/web/ui/message-renderer.js +473 -29
  86. package/dist/web/ui/step-timeline.js +13 -12
  87. package/package.json +1 -1
  88. package/scripts/build-web.ts +74 -1
  89. package/dist/constraint-runtime/_archive_helper.d.ts +0 -1
  90. package/dist/constraint-runtime/_archive_helper.js +0 -9
  91. package/dist/constraint-runtime/assistant/index.d.ts +0 -11
  92. package/dist/constraint-runtime/assistant/index.js +0 -12
  93. package/dist/constraint-runtime/bootstrap/index.d.ts +0 -11
  94. package/dist/constraint-runtime/bootstrap/index.js +0 -12
  95. package/dist/constraint-runtime/bridge/index.d.ts +0 -11
  96. package/dist/constraint-runtime/bridge/index.js +0 -12
  97. package/dist/constraint-runtime/buddy/index.d.ts +0 -11
  98. package/dist/constraint-runtime/buddy/index.js +0 -12
  99. package/dist/constraint-runtime/cli/index.d.ts +0 -11
  100. package/dist/constraint-runtime/cli/index.js +0 -12
  101. package/dist/constraint-runtime/components/index.d.ts +0 -11
  102. package/dist/constraint-runtime/components/index.js +0 -12
  103. package/dist/constraint-runtime/constants/index.d.ts +0 -11
  104. package/dist/constraint-runtime/constants/index.js +0 -12
  105. package/dist/constraint-runtime/coordinator/index.d.ts +0 -11
  106. package/dist/constraint-runtime/coordinator/index.js +0 -12
  107. package/dist/constraint-runtime/cost_hook.d.ts +0 -2
  108. package/dist/constraint-runtime/cost_hook.js +0 -4
  109. package/dist/constraint-runtime/entrypoints/index.d.ts +0 -11
  110. package/dist/constraint-runtime/entrypoints/index.js +0 -12
  111. package/dist/constraint-runtime/execution_registry.d.ts +0 -20
  112. package/dist/constraint-runtime/execution_registry.js +0 -44
  113. package/dist/constraint-runtime/hooks/index.d.ts +0 -11
  114. package/dist/constraint-runtime/hooks/index.js +0 -12
  115. package/dist/constraint-runtime/ink.d.ts +0 -1
  116. package/dist/constraint-runtime/ink.js +0 -4
  117. package/dist/constraint-runtime/keybindings/index.d.ts +0 -11
  118. package/dist/constraint-runtime/keybindings/index.js +0 -12
  119. package/dist/constraint-runtime/memdir/index.d.ts +0 -11
  120. package/dist/constraint-runtime/memdir/index.js +0 -12
  121. package/dist/constraint-runtime/migrations/index.d.ts +0 -11
  122. package/dist/constraint-runtime/migrations/index.js +0 -12
  123. package/dist/constraint-runtime/moreright/index.d.ts +0 -11
  124. package/dist/constraint-runtime/moreright/index.js +0 -12
  125. package/dist/constraint-runtime/native_ts/index.d.ts +0 -11
  126. package/dist/constraint-runtime/native_ts/index.js +0 -12
  127. package/dist/constraint-runtime/output_styles/index.d.ts +0 -11
  128. package/dist/constraint-runtime/output_styles/index.js +0 -12
  129. package/dist/constraint-runtime/plugins/index.d.ts +0 -11
  130. package/dist/constraint-runtime/plugins/index.js +0 -12
  131. package/dist/constraint-runtime/port_manifest.d.ts +0 -7
  132. package/dist/constraint-runtime/port_manifest.js +0 -11
  133. package/dist/constraint-runtime/query.d.ts +0 -6
  134. package/dist/constraint-runtime/query.js +0 -1
  135. package/dist/constraint-runtime/remote/index.d.ts +0 -11
  136. package/dist/constraint-runtime/remote/index.js +0 -12
  137. package/dist/constraint-runtime/schemas/index.d.ts +0 -11
  138. package/dist/constraint-runtime/schemas/index.js +0 -12
  139. package/dist/constraint-runtime/screens/index.d.ts +0 -11
  140. package/dist/constraint-runtime/screens/index.js +0 -12
  141. package/dist/constraint-runtime/server/index.d.ts +0 -11
  142. package/dist/constraint-runtime/server/index.js +0 -12
  143. package/dist/constraint-runtime/services/index.d.ts +0 -11
  144. package/dist/constraint-runtime/services/index.js +0 -12
  145. package/dist/constraint-runtime/state/index.d.ts +0 -11
  146. package/dist/constraint-runtime/state/index.js +0 -12
  147. package/dist/constraint-runtime/system_init.d.ts +0 -1
  148. package/dist/constraint-runtime/system_init.js +0 -20
  149. package/dist/constraint-runtime/types/index.d.ts +0 -11
  150. package/dist/constraint-runtime/types/index.js +0 -12
  151. package/dist/constraint-runtime/upstream_proxy/index.d.ts +0 -11
  152. package/dist/constraint-runtime/upstream_proxy/index.js +0 -12
  153. package/dist/constraint-runtime/utils/index.d.ts +0 -11
  154. package/dist/constraint-runtime/utils/index.js +0 -12
  155. package/dist/constraint-runtime/vim/index.d.ts +0 -11
  156. package/dist/constraint-runtime/vim/index.js +0 -12
  157. package/dist/constraint-runtime/voice/index.d.ts +0 -11
  158. package/dist/constraint-runtime/voice/index.js +0 -12
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ /**
3
+ * run-lifecycle.ts — K10 ①: **运行生命周期写口** (与 `control.ts` 分开: 语义不同)
4
+ *
5
+ * `control.ts` = **命令式控制面**: 「谁命令我停 / 继续 / 恢复」—— web · cli · supervisor 发起, 带 origin 审计。
6
+ * 本文件 = **回合事实写口**: 「我这一轮发生了什么」—— start-run · record-step · finish-run · save-checkpoint。
7
+ *
8
+ * 为什么必须分开 (K10 ① 的下一刀定形时复核过):
9
+ * 混进同一个 `kind` 空间之后, K10 ②③④ 那些批次就无法区分「这条写入是外部命令还是回合事实」,
10
+ * 两者的**失败语义也不同** —— 控制面被拒要给 409 (调用方改主意), 而事实写不进是**响亮失败**
11
+ * (run-store 是 strict 的: 写不进 = 这次运行在事实层面不存在, 不许静默继续)。
12
+ *
13
+ * 形状照抄 `control.ts` (同一个仓库里只该有一种端口写法):
14
+ * 端口注入 · **未注入即拒** (不静默降级) · 一律**返回结果对象不抛** · 端口用 `{ok:false}` 表达拒绝要被归一化 · 审计流水可读。
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.RUN_LIFECYCLE_NEEDS_RUN_ID = exports.RUN_LIFECYCLE_OPS = void 0;
18
+ exports.runLifecycleAudit = runLifecycleAudit;
19
+ exports.resetRunLifecycleAudit = resetRunLifecycleAudit;
20
+ exports.submitRunLifecycle = submitRunLifecycle;
21
+ exports.assertLifecycleOk = assertLifecycleOk;
22
+ exports.RUN_LIFECYCLE_OPS = [
23
+ 'start-run',
24
+ 'record-step',
25
+ 'finish-run',
26
+ 'save-checkpoint',
27
+ ];
28
+ /** 哪些操作必须有 runId (start-run 例外: 它的 runId 是**结果**, 不是入参) */
29
+ exports.RUN_LIFECYCLE_NEEDS_RUN_ID = {
30
+ 'start-run': false,
31
+ 'record-step': true,
32
+ 'finish-run': true,
33
+ 'save-checkpoint': true,
34
+ };
35
+ /**
36
+ * 端口**不抛异常但明确拒绝** (`{ ok: false, reason }`) 的归一化 —— 与 `control.ts` 同口径。
37
+ * 为什么必须有: store 类原语用返回值表达拒绝 (例如状态迁移不合法), 只看"有没有抛"会把**被拒当成成功**。
38
+ */
39
+ function portRefusal(res) {
40
+ if (res && typeof res === 'object' && 'ok' in res) {
41
+ const r = res;
42
+ if (r.ok === false)
43
+ return `端口拒绝: ${String(r.reason ?? '(未给原因)')}`;
44
+ }
45
+ return null;
46
+ }
47
+ const audit = [];
48
+ const AUDIT_MAX = 200;
49
+ /** 审计流水 (最近 N 条; 测试与运维可读) */
50
+ function runLifecycleAudit() {
51
+ return audit;
52
+ }
53
+ function resetRunLifecycleAudit() {
54
+ audit.length = 0;
55
+ }
56
+ /**
57
+ * 提交一条生命周期写入。**唯一入口** —— 校验 (op 合法 / origin 非空 / 需要的定位字段齐) → 派发到 port → 记审计。
58
+ * 一律**返回结果对象**, 不抛 (调用方不该用 try/catch 表达"没落盘"); 要不要把 `ok=false` 变成异常由
59
+ * `assertLifecycleOk` 决定 —— 生命周期写入**一律**要 (见该函数注释)。
60
+ */
61
+ async function submitRunLifecycle(req, ports) {
62
+ const op = req?.op;
63
+ const finish = (ok, detail, port, result) => {
64
+ audit.push({
65
+ at: Date.now(),
66
+ op,
67
+ origin: req?.origin ?? '(anonymous)',
68
+ target: String(req?.runId ?? '(new)'),
69
+ ok,
70
+ detail,
71
+ });
72
+ if (audit.length > AUDIT_MAX)
73
+ audit.splice(0, audit.length - AUDIT_MAX);
74
+ return { ok, op, via: 'kernel-run-lifecycle', detail, port, result };
75
+ };
76
+ if (!exports.RUN_LIFECYCLE_OPS.includes(op))
77
+ return finish(false, `未知写入类型: ${String(req?.op)}`);
78
+ if (!req.origin)
79
+ return finish(false, '缺少 origin (审计要求: 不许匿名写入)');
80
+ if (exports.RUN_LIFECYCLE_NEEDS_RUN_ID[op] && !req.runId)
81
+ return finish(false, `${op} 缺少 runId`);
82
+ const payload = req.payload ?? {};
83
+ if (op === 'start-run') {
84
+ if (typeof ports.startRun !== 'function')
85
+ return finish(false, 'port 未注入: startRun');
86
+ try {
87
+ const res = await ports.startRun(payload);
88
+ const refusal = portRefusal(res);
89
+ return refusal ? finish(false, refusal, 'startRun', res) : finish(true, undefined, 'startRun', res);
90
+ }
91
+ catch (err) {
92
+ return finish(false, `startRun 失败: ${String(err?.message ?? err).slice(0, 160)}`);
93
+ }
94
+ }
95
+ if (op === 'record-step') {
96
+ if (typeof ports.recordStep !== 'function')
97
+ return finish(false, 'port 未注入: recordStep');
98
+ try {
99
+ const res = await ports.recordStep(req.runId, payload);
100
+ const refusal = portRefusal(res);
101
+ return refusal ? finish(false, refusal, 'recordStep', res) : finish(true, undefined, 'recordStep', res);
102
+ }
103
+ catch (err) {
104
+ return finish(false, `recordStep 失败: ${String(err?.message ?? err).slice(0, 160)}`);
105
+ }
106
+ }
107
+ if (op === 'finish-run') {
108
+ if (typeof ports.finishRun !== 'function')
109
+ return finish(false, 'port 未注入: finishRun');
110
+ try {
111
+ const res = await ports.finishRun(req.runId, payload);
112
+ const refusal = portRefusal(res);
113
+ return refusal ? finish(false, refusal, 'finishRun', res) : finish(true, undefined, 'finishRun', res);
114
+ }
115
+ catch (err) {
116
+ return finish(false, `finishRun 失败: ${String(err?.message ?? err).slice(0, 160)}`);
117
+ }
118
+ }
119
+ if (op === 'save-checkpoint') {
120
+ if (typeof ports.saveCheckpoint !== 'function')
121
+ return finish(false, 'port 未注入: saveCheckpoint');
122
+ try {
123
+ const res = await ports.saveCheckpoint(req.runId, payload);
124
+ const refusal = portRefusal(res);
125
+ return refusal ? finish(false, refusal, 'saveCheckpoint', res) : finish(true, undefined, 'saveCheckpoint', res);
126
+ }
127
+ catch (err) {
128
+ return finish(false, `saveCheckpoint 失败: ${String(err?.message ?? err).slice(0, 160)}`);
129
+ }
130
+ }
131
+ return finish(false, `未处理的写入类型: ${String(op)}`);
132
+ }
133
+ /**
134
+ * 生命周期写入**必须**落盘 —— 拿不到 `ok` 就抛。
135
+ *
136
+ * 依据: `run-store` 的持久化是 **strict** (写不进 = 这次运行在事实层面不存在),
137
+ * 所以「写失败但继续跑」= 制造"agent 跑了但没记录"的老毛病。要降级只有一种合法姿势:
138
+ * 由调用方显式换持久化等级 (环境开关), 不许在这里静默吞。
139
+ */
140
+ function assertLifecycleOk(out) {
141
+ if (!out.ok) {
142
+ throw new Error(`[kernel-run-lifecycle] ${out.op} 未落盘: ${out.detail ?? '未知原因'}`
143
+ + ' (run-store 是 strict: 写不进 = 这次运行在事实层面不存在, 不许静默继续)');
144
+ }
145
+ }
146
+ //# sourceMappingURL=run-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-lifecycle.js","sourceRoot":"","sources":["../../../src/kernel/run-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ /**
3
+ * transport.ts — K10 ④: **通信入口端口** (与 `control.ts` / `run-lifecycle.ts` 同一套端口写法)
4
+ *
5
+ * 目标形态 (设计页): `transport → router → channel mailbox` —— 也就是说:
6
+ * **上层只对"通信端口"说话, 不直接对某条传输 (hyperswarm / iroh / p2pNetwork) 说话**。
7
+ * Pi 现在自己持有 3 个薄包装 (`getPeers` / `sendMessage` / `broadcast` → `p2pNetwork`),
8
+ * 那正是"Pi 内部通信发送逻辑"还没迁完的形状 (K10 ④)。
9
+ *
10
+ * 为什么用端口而不是直接调传输:
11
+ * - 传输是可替换的 (hyperswarm / iroh / 以后的东西) ⇒ 上层不该 import 具体实现;
12
+ * - 发送是**有副作用**的动作 ⇒ 要能审计 (谁发的 / 发给谁 / 成没成), 且**未注入即拒** (不静默丢弃消息);
13
+ * - 与 `control.ts` / `run-lifecycle.ts` 保持同一种形状, 免得仓里出现第三种端口写法。
14
+ *
15
+ * 注: 本模块只做"入口收口", **不搬传输实现** (传输仍在 `src/network/**`); 判据见 `src/test/k10-transport-port.test.ts`。
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.TRANSPORT_NEEDS_TARGET = exports.TRANSPORT_OPS = void 0;
19
+ exports.transportPeersSync = transportPeersSync;
20
+ exports.transportAudit = transportAudit;
21
+ exports.resetTransportAudit = resetTransportAudit;
22
+ exports.submitTransport = submitTransport;
23
+ exports.TRANSPORT_OPS = ['send', 'broadcast', 'peers'];
24
+ /** 哪些操作必须有目标 (send 要 peerId; broadcast / peers 不需要) */
25
+ exports.TRANSPORT_NEEDS_TARGET = {
26
+ send: true,
27
+ broadcast: false,
28
+ peers: false,
29
+ };
30
+ /**
31
+ * 同步读对端 (K10 ④ 后半) —— 与 `submitTransport` 分开是因为**签名**而不是因为语义:
32
+ * 传输层是异步的, 但上层有同步调用点 (sync 签名不能凭空变 async)。
33
+ * 返回 `null` = 端口未注入 (调用方必须自己决定降级, 不许假装"没有对端" —— 那是两回事)。
34
+ */
35
+ function transportPeersSync(ports) {
36
+ if (typeof ports?.peersSync !== 'function')
37
+ return null;
38
+ return ports.peersSync();
39
+ }
40
+ /** 端口用 `{ok:false}` 表达拒绝的归一化 (与另外两个端口同口径) */
41
+ function portRefusal(res) {
42
+ if (res && typeof res === 'object' && 'ok' in res) {
43
+ const r = res;
44
+ if (r.ok === false)
45
+ return `端口拒绝: ${String(r.reason ?? '(未给原因)')}`;
46
+ }
47
+ return null;
48
+ }
49
+ const audit = [];
50
+ const AUDIT_MAX = 200;
51
+ /** 审计流水 (最近 N 条; 测试与运维可读) */
52
+ function transportAudit() {
53
+ return audit;
54
+ }
55
+ function resetTransportAudit() {
56
+ audit.length = 0;
57
+ }
58
+ /** 提交一次通信动作。**唯一入口** —— 校验 → 派发到 port → 记审计; 一律返回结果对象, 不抛。 */
59
+ async function submitTransport(req, ports) {
60
+ const op = req?.op;
61
+ const finish = (ok, detail, port, result) => {
62
+ audit.push({
63
+ at: Date.now(),
64
+ op,
65
+ origin: req?.origin ?? '(anonymous)',
66
+ target: String(req?.peerId ?? '(all)'),
67
+ ok,
68
+ detail,
69
+ });
70
+ if (audit.length > AUDIT_MAX)
71
+ audit.splice(0, audit.length - AUDIT_MAX);
72
+ return { ok, op, via: 'kernel-transport', detail, port, result };
73
+ };
74
+ if (!exports.TRANSPORT_OPS.includes(op))
75
+ return finish(false, `未知通信动作: ${String(req?.op)}`);
76
+ if (!req.origin)
77
+ return finish(false, '缺少 origin (审计要求: 不许匿名发送)');
78
+ if (exports.TRANSPORT_NEEDS_TARGET[op] && !req.peerId)
79
+ return finish(false, `${op} 缺少 peerId`);
80
+ const kind = req.kind ?? 'message';
81
+ const payload = req.payload ?? '';
82
+ if (op === 'send') {
83
+ if (typeof ports.send !== 'function')
84
+ return finish(false, 'port 未注入: send');
85
+ try {
86
+ const res = await ports.send(req.peerId, kind, payload);
87
+ const refusal = portRefusal(res);
88
+ return refusal ? finish(false, refusal, 'send', res) : finish(true, undefined, 'send', res);
89
+ }
90
+ catch (err) {
91
+ return finish(false, `send 失败: ${String(err?.message ?? err).slice(0, 160)}`);
92
+ }
93
+ }
94
+ if (op === 'broadcast') {
95
+ if (typeof ports.broadcast !== 'function')
96
+ return finish(false, 'port 未注入: broadcast');
97
+ try {
98
+ const res = await ports.broadcast(kind, payload);
99
+ const refusal = portRefusal(res);
100
+ return refusal ? finish(false, refusal, 'broadcast', res) : finish(true, undefined, 'broadcast', res);
101
+ }
102
+ catch (err) {
103
+ return finish(false, `broadcast 失败: ${String(err?.message ?? err).slice(0, 160)}`);
104
+ }
105
+ }
106
+ if (op === 'peers') {
107
+ if (typeof ports.peers !== 'function')
108
+ return finish(false, 'port 未注入: peers');
109
+ try {
110
+ const res = await ports.peers();
111
+ return finish(true, undefined, 'peers', res);
112
+ }
113
+ catch (err) {
114
+ return finish(false, `peers 失败: ${String(err?.message ?? err).slice(0, 160)}`);
115
+ }
116
+ }
117
+ return finish(false, `未处理的通信动作: ${String(op)}`);
118
+ }
119
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/kernel/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNativeAdapter = createNativeAdapter;
4
+ exports.nativeAdapterFromEnv = nativeAdapterFromEnv;
5
+ const tool_name_js_1 = require("./tool-name.js");
6
+ /** 可被 abort 打断的 sleep (退避用) */
7
+ function sleep(ms, signal) {
8
+ return new Promise((resolve, reject) => {
9
+ const t = setTimeout(() => { signal?.removeEventListener?.('abort', onAbort); resolve(); }, ms);
10
+ const onAbort = () => { clearTimeout(t); reject(new Error('aborted during backoff')); };
11
+ if (signal?.aborted)
12
+ onAbort();
13
+ else
14
+ signal?.addEventListener?.('abort', onAbort, { once: true });
15
+ });
16
+ }
17
+ function createNativeAdapter(cfg) {
18
+ const timeoutMs = cfg.timeoutMs ?? 120_000;
19
+ const maxRetries = cfg.maxRetries ?? 3;
20
+ const url = `${String(cfg.baseUrl || '').replace(/\/+$/, '')}/chat/completions`;
21
+ let calls = 0; // 观测: 真发出去几次 (重试也算)
22
+ let retries = 0;
23
+ const adapter = {
24
+ providerId: cfg.providerId ?? 'native',
25
+ stats: () => ({ calls, retries }),
26
+ async chat(context, systemPrompt, signal, tools, purpose) {
27
+ const messages = [
28
+ { role: 'system', content: String(systemPrompt ?? '') },
29
+ { role: 'user', content: String(context ?? '') },
30
+ ];
31
+ let attempt = 0;
32
+ let lastErr;
33
+ while (attempt <= maxRetries) {
34
+ const ac = new AbortController();
35
+ const onAbort = () => ac.abort();
36
+ if (signal?.aborted)
37
+ ac.abort();
38
+ else
39
+ signal?.addEventListener?.('abort', onAbort, { once: true });
40
+ const timer = setTimeout(() => ac.abort(), timeoutMs);
41
+ try {
42
+ calls += 1;
43
+ // ⚠️ 出程必须**净化工具名** —— 端点只接受 `^[a-zA-Z0-9_-]{1,64}$` (实测: 原样转发 183 个工具
44
+ // 里第 124 个不合规 ⇒ HTTP 400, 整轮空回复)。净化会把映射登记进**全局路由表**,
45
+ // 回程由 pivot 的 `resolveApiToolName` 还原 ⇒ 上下层协议不变 (这正是"适配器边界"的一部分)。
46
+ const wireTools = Array.isArray(tools) && tools.length > 0 ? (0, tool_name_js_1.sanitizeToolsForApi)(tools) : undefined;
47
+ const res = await fetch(url, {
48
+ method: 'POST',
49
+ headers: { 'content-type': 'application/json', authorization: `Bearer ${cfg.apiKey}` },
50
+ body: JSON.stringify({
51
+ model: cfg.model,
52
+ messages,
53
+ ...(wireTools ? { tools: wireTools } : {}),
54
+ stream: false,
55
+ }),
56
+ signal: ac.signal,
57
+ });
58
+ if (!res.ok) {
59
+ const text = await res.text().catch(() => '');
60
+ const retryable = res.status === 429 || res.status >= 500;
61
+ if (retryable && attempt < maxRetries) {
62
+ lastErr = new Error(`native-adapter HTTP ${res.status}: ${text.slice(0, 160)}`);
63
+ attempt += 1;
64
+ retries += 1;
65
+ await sleep(1000 * 2 ** (attempt - 1), signal);
66
+ continue;
67
+ }
68
+ // 非 429 的 4xx ⇒ **不重试** (重试无意义)。这里必须打标记: 否则下面的 catch
69
+ // 会把它当"网络错"再退避重试 —— 踩过 (用例⑤: 一个 400 被发了 4 次)。
70
+ const fatal = new Error(`native-adapter HTTP ${res.status}: ${text.slice(0, 200)}`);
71
+ fatal.noRetry = true;
72
+ throw fatal;
73
+ }
74
+ const data = await res.json();
75
+ const msg = data?.choices?.[0]?.message ?? {};
76
+ const toolCalls = Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 ? msg.tool_calls : undefined;
77
+ return {
78
+ reply: String(msg.content ?? ''),
79
+ tokens: data?.usage?.total_tokens,
80
+ toolCalls,
81
+ messages: messages.concat([{ role: 'assistant', content: String(msg.content ?? '') }]),
82
+ };
83
+ }
84
+ catch (e) {
85
+ // 调用方主动 abort ⇒ 原样抛出 (别当网络错去重试)
86
+ if (signal?.aborted)
87
+ throw e;
88
+ if (e?.noRetry)
89
+ throw e; // 非 429 的 4xx 等: 不重试
90
+ lastErr = e;
91
+ if (attempt >= maxRetries)
92
+ throw e;
93
+ attempt += 1;
94
+ retries += 1;
95
+ await sleep(1000 * 2 ** (attempt - 1), signal);
96
+ }
97
+ finally {
98
+ clearTimeout(timer);
99
+ signal?.removeEventListener?.('abort', onAbort);
100
+ }
101
+ }
102
+ throw lastErr ?? new Error('native-adapter: 不可达');
103
+ },
104
+ };
105
+ return adapter;
106
+ }
107
+ /**
108
+ * 从环境装配一个 native 适配器 (供 `BOLLOON_NATIVE_ADAPTER=1` 开关使用)。
109
+ * 缺 key ⇒ 返回 null (调用方回落到原适配器, 不假装可用)。
110
+ */
111
+ function nativeAdapterFromEnv(env = process.env) {
112
+ const apiKey = env.BOLLOON_NATIVE_API_KEY || env.DEEPSEEK_API_KEY || '';
113
+ if (!apiKey)
114
+ return null;
115
+ return createNativeAdapter({
116
+ baseUrl: env.BOLLOON_NATIVE_BASE_URL || 'https://api.deepseek.com/v1',
117
+ apiKey,
118
+ model: env.BOLLOON_NATIVE_MODEL || 'deepseek-chat',
119
+ providerId: 'native-openai-compatible',
120
+ });
121
+ }
122
+ //# sourceMappingURL=native-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-adapter.js","sourceRoot":"","sources":["../../../src/llm/native-adapter.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { deliverThroughActor } from './kernel/channel-actor.js';
1
2
  import { createHyperswarmCommunicator, createTopic, KeyManager, AgentAuthManager, createVerificationManager, } from '@diap/sdk';
2
3
  import { irohTransport } from './network/iroh-transport.js';
3
4
  import { getLastAiTiming, getLastAiUsage } from './llm/pi-ai.js';
@@ -781,7 +782,8 @@ async function handleSummarize(task) {
781
782
  if (!task.documentPath)
782
783
  return `ERR|${JSON.stringify({ code: 'no_path' })}`;
783
784
  const a = await getAgent();
784
- const { summary, qualityScore } = await a.summarizeDocument(task.documentPath);
785
+ const docPath = task.documentPath; // 闭包里 TS 不保留收窄 ⇒ 先收成局部 const
786
+ const { summary, qualityScore } = await deliverThroughActor(a, () => a.summarizeDocument(docPath));
785
787
  writeOut(` ✅ 质量=${(qualityScore * 10).toFixed(1)}/10`);
786
788
  return `OK|${JSON.stringify({ id: task.id, type: 'summarize', qualityScore, summary })}`;
787
789
  }
@@ -790,11 +792,14 @@ async function handleImprove(task) {
790
792
  return `ERR|${JSON.stringify({ code: 'no_path_or_req' })}`;
791
793
  }
792
794
  const a = await getAgent();
793
- const res = await a.improveDocument({
794
- originalPath: task.documentPath,
795
- requirements: task.requirements,
795
+ // 闭包里 TS 不保留收窄 ⇒ 先把两个字段收成局部 const
796
+ const docPath = task.documentPath;
797
+ const reqs = task.requirements;
798
+ const res = await deliverThroughActor(a, () => a.improveDocument({
799
+ originalPath: docPath,
800
+ requirements: reqs,
796
801
  context: `来自节点: ${task.from}`,
797
- });
802
+ }));
798
803
  const ok = res.improved ?? false;
799
804
  writeOut(` ✅ 改进${ok ? '成功' : '失败'} 质量=${(res.qualityScore * 10).toFixed(1)}/10 自动发送=${res.shouldAutoSend}`);
800
805
  return `OK|${JSON.stringify({
@@ -1421,7 +1426,7 @@ async function startCLI(commReady) {
1421
1426
  new Promise((res) => setTimeout(() => res(null), 8000)),
1422
1427
  ]);
1423
1428
  if (a && typeof a.promptStream === 'function') {
1424
- llm = (p) => a.promptStream(p, () => { }, undefined, cliActiveChannelId || undefined);
1429
+ llm = (p) => deliverThroughActor(a, () => a.promptStream(p, () => { }, undefined, cliActiveChannelId || undefined));
1425
1430
  }
1426
1431
  }
1427
1432
  catch { /* 无 agent → 仅扫描 */ }
@@ -2001,7 +2006,7 @@ async function processInputInner(input, comm) {
2001
2006
  return;
2002
2007
  }
2003
2008
  const agent = await getAgent();
2004
- const active = String(agent?.currentChannelId || '');
2009
+ const active = String(agent?.actor?.state?.channelId || ''); // K5 步骤⑧: 本体在 actor (删访问器后这里曾静默变空 ⇒ 安全检查失效)
2005
2010
  if (rec.channelId && active && rec.channelId !== active) {
2006
2011
  appendLine(`${C_ERROR}该运行属于 channel ${rec.channelId} (当前 ${active}) — 先 /channel 切过去再 /resume${RESET}`);
2007
2012
  return;
@@ -2310,7 +2315,7 @@ async function processInputInner(input, comm) {
2310
2315
  }
2311
2316
  agent.setGoalId?.(req.goal.goalId);
2312
2317
  agent.setContinuationGuards?.(req.guards || []);
2313
- await agent.prompt(req.instruction);
2318
+ await deliverThroughActor(agent, () => agent.prompt(req.instruction));
2314
2319
  return { runId: agent.getLastRunId?.() || agent.getRunId?.(), status: 'done' };
2315
2320
  }
2316
2321
  : undefined;
@@ -2869,7 +2874,7 @@ async function processInputInner(input, comm) {
2869
2874
  const a = await getAgent();
2870
2875
  const h = a.messageHistory ?? [];
2871
2876
  appendLine(`${C_ACCENT}当前会话:${RESET} ${C_DIM}${cliSessionKey || '—'}${RESET}`);
2872
- appendLine(` ${C_DIM}channel:${RESET} ${a.currentChannelId || cliActiveChannelId || '—'} ${C_DIM}agent:${RESET} ${a.currentAgentId || cliAgentId || '—'}`);
2877
+ appendLine(` ${C_DIM}channel:${RESET} ${a.actor?.state?.channelId || cliActiveChannelId || '—'} ${C_DIM}agent:${RESET} ${a.currentAgentId || cliAgentId || '—'}`);
2873
2878
  appendLine(` ${C_DIM}消息:${RESET} ${h.length} 条 ${h.length > 15 ? `${C_DIM}(${h.length - 15} 条已压缩)${RESET}` : ''}`);
2874
2879
  }
2875
2880
  catch (e) {
@@ -3398,7 +3403,7 @@ async function processInputInner(input, comm) {
3398
3403
  const a = await getAgent();
3399
3404
  appendLine(`${C_ACCENT}智能体:${RESET}`);
3400
3405
  appendLine(` ${C_DIM}名称:${RESET} ${cliAgentName}`);
3401
- appendLine(` ${C_DIM}agentId:${RESET} ${a.currentAgentId || '—'}`);
3406
+ appendLine(` ${C_DIM}agentId:${RESET} ${a.actor?.state?.agentId || '—'}`); // K5 步骤⑧: 本体在 actor
3402
3407
  appendLine(` ${C_DIM}channel:${RESET} ${cliActiveChannelId || '—'}`);
3403
3408
  }
3404
3409
  catch { /* 静默 */ }
@@ -4111,7 +4116,7 @@ async function processInputInner(input, comm) {
4111
4116
  cliTurnStartedAt = Date.now();
4112
4117
  cliTurnReplyBytes = 0;
4113
4118
  cliTurnToolCount = 0;
4114
- const response = await a.prompt(trimmed, {
4119
+ const response = await deliverThroughActor(a, () => a.prompt(trimmed, {
4115
4120
  onStream: (e) => {
4116
4121
  // 2026-08-07: 中间思考/状态显示 — 之前只显示工具步骤, LLM 的思考过程
4117
4122
  // (thinking / status / phase / Reflection) 全被丢弃 → 用户只能看到输入和最终输出
@@ -4219,7 +4224,7 @@ async function processInputInner(input, comm) {
4219
4224
  }
4220
4225
  }
4221
4226
  }
4222
- });
4227
+ }));
4223
4228
  // 智能体回复框
4224
4229
  appendLine(renderAgentMessage(response));
4225
4230
  try {
@@ -4489,7 +4494,7 @@ goalFlag) {
4489
4494
  error = response;
4490
4495
  break;
4491
4496
  }
4492
- const result = await a.summarizeDocument(filePath, ctx.join(' '));
4497
+ const result = await deliverThroughActor(a, () => a.summarizeDocument(filePath, ctx.join(' ')));
4493
4498
  response = `📝 摘要:\n${result.summary}\n\n质量评分: ${(result.qualityScore * 10).toFixed(1)}/10`;
4494
4499
  metadata.qualityScore = result.qualityScore;
4495
4500
  break;
@@ -4501,10 +4506,10 @@ goalFlag) {
4501
4506
  error = response;
4502
4507
  break;
4503
4508
  }
4504
- const result = await a.improveDocument({
4509
+ const result = await deliverThroughActor(a, () => a.improveDocument({
4505
4510
  originalPath: filePath,
4506
4511
  requirements: req.join(' ')
4507
- });
4512
+ }));
4508
4513
  response = result.newContent || '';
4509
4514
  if (!result.improved) {
4510
4515
  response = '错误: 改进失败';
@@ -4685,7 +4690,7 @@ goalFlag) {
4685
4690
  error = response;
4686
4691
  break;
4687
4692
  }
4688
- response = await a.prompt(text);
4693
+ response = await deliverThroughActor(a, () => a.prompt(text));
4689
4694
  break;
4690
4695
  }
4691
4696
  case 'tools': {
@@ -4740,6 +4745,25 @@ goalFlag) {
4740
4745
  case 'harness-skill': {
4741
4746
  if (!harness) {
4742
4747
  harness = createBollharnessIntegration();
4748
+ // 2026-10-02 (K7): **生产活路径必须过门** —— 这条路径原先直调 registry (skill 旁路)。
4749
+ // 门 = PiAgentSession 的 Harness 判定 (`createSkillGuard()`, 只给判定; 执行仍在 adapter 的唯一执行点)。
4750
+ // **fail-closed**: 门建不起来 ⇒ 注入 deny-all (拒绝执行), 绝不留"没门"状态 ——
4751
+ // "门坏了静默等于没门"比没门更危险 (与 pivot loop / adapter 同一条纪律)。
4752
+ try {
4753
+ const gateSession = await createAgentSession({ cwd: process.cwd(), peerId: 'harness-skill' });
4754
+ if (typeof gateSession.createSkillGuard !== 'function') {
4755
+ throw new Error('该 session 实现未提供 createSkillGuard');
4756
+ }
4757
+ harness.setSkillGuard(gateSession.createSkillGuard());
4758
+ }
4759
+ catch (guardErr) {
4760
+ console.warn(`[K7] skill 门未能建立 ⇒ fail-closed (拒绝执行): ${String(guardErr?.message || guardErr)}`);
4761
+ harness.setSkillGuard(async () => ({
4762
+ allow: false,
4763
+ rejectedBy: 'harness-unavailable',
4764
+ reason: `skill 门未能建立: ${String(guardErr?.message || guardErr).slice(0, 120)}`,
4765
+ }));
4766
+ }
4743
4767
  }
4744
4768
  const [skillName, action] = args;
4745
4769
  if (!skillName) {
@@ -5340,7 +5364,7 @@ async function runNonInteractive(args, comm) {
5340
5364
  }
5341
5365
  else if (prompt) {
5342
5366
  const a = await getAgent();
5343
- writeOut(await a.prompt(prompt));
5367
+ writeOut(await deliverThroughActor(a, () => a.prompt(prompt)));
5344
5368
  }
5345
5369
  console.log = originalLog;
5346
5370
  await fs.writeFile(output, outputBuffer.trim(), 'utf-8');
@@ -5353,7 +5377,7 @@ async function runNonInteractive(args, comm) {
5353
5377
  const startTime = Date.now();
5354
5378
  const a = await getAgent();
5355
5379
  try {
5356
- const response = await a.prompt(prompt);
5380
+ const response = await deliverThroughActor(a, () => a.prompt(prompt));
5357
5381
  const elapsed = Date.now() - startTime;
5358
5382
  if (json) {
5359
5383
  writeOut(JSON.stringify({ success: true, response, elapsedMs: elapsed }, null, 2));
@@ -5383,7 +5407,7 @@ async function runNonInteractive(args, comm) {
5383
5407
  const a = await getAgent();
5384
5408
  let response;
5385
5409
  try {
5386
- response = await a.prompt(prompt);
5410
+ response = await deliverThroughActor(a, () => a.prompt(prompt));
5387
5411
  }
5388
5412
  catch (e) {
5389
5413
  response = `错误: ${e.message}`;
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "schema": "bolloon-mobile-web/1",
3
- "version": "0.5.1",
3
+ "version": "0.6.1",
4
4
  "channel": "stable",
5
5
  "build": "stable",
6
- "commit": "40006e67bf87e892569dd0b02cf2456fddcbbfaf",
7
- "builtAt": "2026-09-27T05:37:37.788Z",
6
+ "commit": "6e2afcdd8723004df91715d48cf7bf7d291ab7af",
7
+ "builtAt": "2026-10-04T08:00:57.589Z",
8
8
  "layer": "web",
9
9
  "note": "web 资源层构建戳 (手机端 OTA 的身份第 ③ 级回退; 装机后以 OTA state.json 为准)"
10
10
  }