berry-agent-sdk 0.1.0-alpha.2
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 +78 -0
- package/dist/packages/berry-agent-sdk/src/client.d.ts +6 -0
- package/dist/packages/berry-agent-sdk/src/client.js +59 -0
- package/dist/packages/berry-agent-sdk/src/client.js.map +1 -0
- package/dist/packages/berry-agent-sdk/src/http.d.ts +24 -0
- package/dist/packages/berry-agent-sdk/src/http.js +232 -0
- package/dist/packages/berry-agent-sdk/src/http.js.map +1 -0
- package/dist/packages/berry-agent-sdk/src/index.d.ts +25 -0
- package/dist/packages/berry-agent-sdk/src/index.js +22 -0
- package/dist/packages/berry-agent-sdk/src/index.js.map +1 -0
- package/dist/packages/berry-agent-sdk/src/stdio.d.ts +23 -0
- package/dist/packages/berry-agent-sdk/src/stdio.js +238 -0
- package/dist/packages/berry-agent-sdk/src/stdio.js.map +1 -0
- package/dist/packages/berry-agent-sdk/src/types.d.ts +117 -0
- package/dist/packages/berry-agent-sdk/src/types.js +19 -0
- package/dist/packages/berry-agent-sdk/src/types.js.map +1 -0
- package/dist/src/agent/events.d.ts +11 -0
- package/dist/src/agent/events.js +2 -0
- package/dist/src/agent/events.js.map +1 -0
- package/dist/src/agent/index.d.ts +13 -0
- package/dist/src/agent/index.js +3 -0
- package/dist/src/agent/index.js.map +1 -0
- package/dist/src/agent/loop.d.ts +19 -0
- package/dist/src/agent/loop.js +140 -0
- package/dist/src/agent/loop.js.map +1 -0
- package/dist/src/agent/queue.d.ts +105 -0
- package/dist/src/agent/queue.js +120 -0
- package/dist/src/agent/queue.js.map +1 -0
- package/dist/src/agent/stream.d.ts +21 -0
- package/dist/src/agent/stream.js +80 -0
- package/dist/src/agent/stream.js.map +1 -0
- package/dist/src/agent/tools-batch.d.ts +49 -0
- package/dist/src/agent/tools-batch.js +222 -0
- package/dist/src/agent/tools-batch.js.map +1 -0
- package/dist/src/agent/types.d.ts +104 -0
- package/dist/src/agent/types.js +9 -0
- package/dist/src/agent/types.js.map +1 -0
- package/dist/src/channels/ask-queue.d.ts +44 -0
- package/dist/src/channels/ask-queue.js +83 -0
- package/dist/src/channels/ask-queue.js.map +1 -0
- package/dist/src/channels/commands.d.ts +56 -0
- package/dist/src/channels/commands.js +130 -0
- package/dist/src/channels/commands.js.map +1 -0
- package/dist/src/channels/engine/cell.d.ts +55 -0
- package/dist/src/channels/engine/cell.js +144 -0
- package/dist/src/channels/engine/cell.js.map +1 -0
- package/dist/src/channels/engine/diff.d.ts +3 -0
- package/dist/src/channels/engine/diff.js +144 -0
- package/dist/src/channels/engine/diff.js.map +1 -0
- package/dist/src/channels/engine/engine.d.ts +151 -0
- package/dist/src/channels/engine/engine.js +417 -0
- package/dist/src/channels/engine/engine.js.map +1 -0
- package/dist/src/channels/engine/index.d.ts +22 -0
- package/dist/src/channels/engine/index.js +9 -0
- package/dist/src/channels/engine/index.js.map +1 -0
- package/dist/src/channels/engine/input-keys.d.ts +39 -0
- package/dist/src/channels/engine/input-keys.js +87 -0
- package/dist/src/channels/engine/input-keys.js.map +1 -0
- package/dist/src/channels/engine/input.d.ts +174 -0
- package/dist/src/channels/engine/input.js +597 -0
- package/dist/src/channels/engine/input.js.map +1 -0
- package/dist/src/channels/engine/memory-io.d.ts +46 -0
- package/dist/src/channels/engine/memory-io.js +72 -0
- package/dist/src/channels/engine/memory-io.js.map +1 -0
- package/dist/src/channels/engine/process-io.d.ts +23 -0
- package/dist/src/channels/engine/process-io.js +39 -0
- package/dist/src/channels/engine/process-io.js.map +1 -0
- package/dist/src/channels/engine/types.d.ts +202 -0
- package/dist/src/channels/engine/types.js +18 -0
- package/dist/src/channels/engine/types.js.map +1 -0
- package/dist/src/channels/engine/width.d.ts +23 -0
- package/dist/src/channels/engine/width.js +123 -0
- package/dist/src/channels/engine/width.js.map +1 -0
- package/dist/src/channels/index.d.ts +25 -0
- package/dist/src/channels/index.js +16 -0
- package/dist/src/channels/index.js.map +1 -0
- package/dist/src/channels/registry.d.ts +33 -0
- package/dist/src/channels/registry.js +57 -0
- package/dist/src/channels/registry.js.map +1 -0
- package/dist/src/channels/sdk/admit.d.ts +32 -0
- package/dist/src/channels/sdk/admit.js +30 -0
- package/dist/src/channels/sdk/admit.js.map +1 -0
- package/dist/src/channels/sdk/backend.d.ts +19 -0
- package/dist/src/channels/sdk/backend.js +103 -0
- package/dist/src/channels/sdk/backend.js.map +1 -0
- package/dist/src/channels/sdk/cursor.d.ts +51 -0
- package/dist/src/channels/sdk/cursor.js +57 -0
- package/dist/src/channels/sdk/cursor.js.map +1 -0
- package/dist/src/channels/sdk/index.d.ts +20 -0
- package/dist/src/channels/sdk/index.js +21 -0
- package/dist/src/channels/sdk/index.js.map +1 -0
- package/dist/src/channels/sdk/jsonl.d.ts +47 -0
- package/dist/src/channels/sdk/jsonl.js +201 -0
- package/dist/src/channels/sdk/jsonl.js.map +1 -0
- package/dist/src/channels/sdk/protocol.d.ts +297 -0
- package/dist/src/channels/sdk/protocol.js +25 -0
- package/dist/src/channels/sdk/protocol.js.map +1 -0
- package/dist/src/channels/sdk/schema.d.ts +12 -0
- package/dist/src/channels/sdk/schema.js +92 -0
- package/dist/src/channels/sdk/schema.js.map +1 -0
- package/dist/src/channels/sdk/wire-core.d.ts +199 -0
- package/dist/src/channels/sdk/wire-core.js +447 -0
- package/dist/src/channels/sdk/wire-core.js.map +1 -0
- package/dist/src/channels/service.d.ts +66 -0
- package/dist/src/channels/service.js +170 -0
- package/dist/src/channels/service.js.map +1 -0
- package/dist/src/channels/tui/autocomplete/autocomplete.d.ts +32 -0
- package/dist/src/channels/tui/autocomplete/autocomplete.js +43 -0
- package/dist/src/channels/tui/autocomplete/autocomplete.js.map +1 -0
- package/dist/src/channels/tui/autocomplete/file-mentions.d.ts +18 -0
- package/dist/src/channels/tui/autocomplete/file-mentions.js +107 -0
- package/dist/src/channels/tui/autocomplete/file-mentions.js.map +1 -0
- package/dist/src/channels/tui/autocomplete/popup.d.ts +47 -0
- package/dist/src/channels/tui/autocomplete/popup.js +149 -0
- package/dist/src/channels/tui/autocomplete/popup.js.map +1 -0
- package/dist/src/channels/tui/autocomplete/provider.d.ts +38 -0
- package/dist/src/channels/tui/autocomplete/provider.js +8 -0
- package/dist/src/channels/tui/autocomplete/provider.js.map +1 -0
- package/dist/src/channels/tui/autocomplete/token.d.ts +22 -0
- package/dist/src/channels/tui/autocomplete/token.js +69 -0
- package/dist/src/channels/tui/autocomplete/token.js.map +1 -0
- package/dist/src/channels/tui/backend/ansi-rows.d.ts +86 -0
- package/dist/src/channels/tui/backend/ansi-rows.js +209 -0
- package/dist/src/channels/tui/backend/ansi-rows.js.map +1 -0
- package/dist/src/channels/tui/backend/main-screen.d.ts +90 -0
- package/dist/src/channels/tui/backend/main-screen.js +208 -0
- package/dist/src/channels/tui/backend/main-screen.js.map +1 -0
- package/dist/src/channels/tui/backend/osc.d.ts +79 -0
- package/dist/src/channels/tui/backend/osc.js +92 -0
- package/dist/src/channels/tui/backend/osc.js.map +1 -0
- package/dist/src/channels/tui/backend/transcript.d.ts +98 -0
- package/dist/src/channels/tui/backend/transcript.js +231 -0
- package/dist/src/channels/tui/backend/transcript.js.map +1 -0
- package/dist/src/channels/tui/backend/tui-backend.d.ts +324 -0
- package/dist/src/channels/tui/backend/tui-backend.js +916 -0
- package/dist/src/channels/tui/backend/tui-backend.js.map +1 -0
- package/dist/src/channels/tui/editor/editor-model.d.ts +141 -0
- package/dist/src/channels/tui/editor/editor-model.js +544 -0
- package/dist/src/channels/tui/editor/editor-model.js.map +1 -0
- package/dist/src/channels/tui/editor/editor-view.d.ts +36 -0
- package/dist/src/channels/tui/editor/editor-view.js +141 -0
- package/dist/src/channels/tui/editor/editor-view.js.map +1 -0
- package/dist/src/channels/tui/editor/editor.d.ts +50 -0
- package/dist/src/channels/tui/editor/editor.js +276 -0
- package/dist/src/channels/tui/editor/editor.js.map +1 -0
- package/dist/src/channels/tui/editor/undo-stack.d.ts +22 -0
- package/dist/src/channels/tui/editor/undo-stack.js +36 -0
- package/dist/src/channels/tui/editor/undo-stack.js.map +1 -0
- package/dist/src/channels/tui/editor/visual-lines.d.ts +39 -0
- package/dist/src/channels/tui/editor/visual-lines.js +127 -0
- package/dist/src/channels/tui/editor/visual-lines.js.map +1 -0
- package/dist/src/channels/tui/editor/word-nav.d.ts +10 -0
- package/dist/src/channels/tui/editor/word-nav.js +107 -0
- package/dist/src/channels/tui/editor/word-nav.js.map +1 -0
- package/dist/src/channels/tui/history/history-viewer.d.ts +133 -0
- package/dist/src/channels/tui/history/history-viewer.js +404 -0
- package/dist/src/channels/tui/history/history-viewer.js.map +1 -0
- package/dist/src/channels/tui/index.d.ts +16 -0
- package/dist/src/channels/tui/index.js +4 -0
- package/dist/src/channels/tui/index.js.map +1 -0
- package/dist/src/channels/tui/markdown/blocks.d.ts +42 -0
- package/dist/src/channels/tui/markdown/blocks.js +112 -0
- package/dist/src/channels/tui/markdown/blocks.js.map +1 -0
- package/dist/src/channels/tui/markdown/inline.d.ts +24 -0
- package/dist/src/channels/tui/markdown/inline.js +76 -0
- package/dist/src/channels/tui/markdown/inline.js.map +1 -0
- package/dist/src/channels/tui/markdown/markdown.d.ts +34 -0
- package/dist/src/channels/tui/markdown/markdown.js +183 -0
- package/dist/src/channels/tui/markdown/markdown.js.map +1 -0
- package/dist/src/channels/tui/memory/memory-viewer.d.ts +235 -0
- package/dist/src/channels/tui/memory/memory-viewer.js +541 -0
- package/dist/src/channels/tui/memory/memory-viewer.js.map +1 -0
- package/dist/src/channels/tui/overlay/alt-screen.d.ts +79 -0
- package/dist/src/channels/tui/overlay/alt-screen.js +106 -0
- package/dist/src/channels/tui/overlay/alt-screen.js.map +1 -0
- package/dist/src/channels/tui/overlay/overlay.d.ts +53 -0
- package/dist/src/channels/tui/overlay/overlay.js +58 -0
- package/dist/src/channels/tui/overlay/overlay.js.map +1 -0
- package/dist/src/channels/tui/overlay/select-confirm.d.ts +73 -0
- package/dist/src/channels/tui/overlay/select-confirm.js +157 -0
- package/dist/src/channels/tui/overlay/select-confirm.js.map +1 -0
- package/dist/src/channels/tui/panels/todo-panel.d.ts +24 -0
- package/dist/src/channels/tui/panels/todo-panel.js +55 -0
- package/dist/src/channels/tui/panels/todo-panel.js.map +1 -0
- package/dist/src/channels/tui/panels/tool-progress-panel.d.ts +37 -0
- package/dist/src/channels/tui/panels/tool-progress-panel.js +94 -0
- package/dist/src/channels/tui/panels/tool-progress-panel.js.map +1 -0
- package/dist/src/channels/tui/scroll/scroll-view.d.ts +96 -0
- package/dist/src/channels/tui/scroll/scroll-view.js +255 -0
- package/dist/src/channels/tui/scroll/scroll-view.js.map +1 -0
- package/dist/src/channels/tui/status/status-line.d.ts +46 -0
- package/dist/src/channels/tui/status/status-line.js +77 -0
- package/dist/src/channels/tui/status/status-line.js.map +1 -0
- package/dist/src/channels/tui/theme.d.ts +27 -0
- package/dist/src/channels/tui/theme.js +42 -0
- package/dist/src/channels/tui/theme.js.map +1 -0
- package/dist/src/channels/types.d.ts +84 -0
- package/dist/src/channels/types.js +12 -0
- package/dist/src/channels/types.js.map +1 -0
- package/dist/src/channels/ui-core.d.ts +80 -0
- package/dist/src/channels/ui-core.js +210 -0
- package/dist/src/channels/ui-core.js.map +1 -0
- package/dist/src/context/codes.d.ts +1 -0
- package/dist/src/context/codes.js +41 -0
- package/dist/src/context/codes.js.map +1 -0
- package/dist/src/context/events.d.ts +62 -0
- package/dist/src/context/events.js +161 -0
- package/dist/src/context/events.js.map +1 -0
- package/dist/src/context/index.d.ts +16 -0
- package/dist/src/context/index.js +14 -0
- package/dist/src/context/index.js.map +1 -0
- package/dist/src/context/logger.d.ts +67 -0
- package/dist/src/context/logger.js +137 -0
- package/dist/src/context/logger.js.map +1 -0
- package/dist/src/context/scope.d.ts +78 -0
- package/dist/src/context/scope.js +183 -0
- package/dist/src/context/scope.js.map +1 -0
- package/dist/src/context/workspace.d.ts +8 -0
- package/dist/src/context/workspace.js +105 -0
- package/dist/src/context/workspace.js.map +1 -0
- package/dist/src/contracts/agent-events.d.ts +73 -0
- package/dist/src/contracts/agent-events.js +17 -0
- package/dist/src/contracts/agent-events.js.map +1 -0
- package/dist/src/contracts/api.d.ts +249 -0
- package/dist/src/contracts/api.js +334 -0
- package/dist/src/contracts/api.js.map +1 -0
- package/dist/src/contracts/approval.d.ts +37 -0
- package/dist/src/contracts/approval.js +10 -0
- package/dist/src/contracts/approval.js.map +1 -0
- package/dist/src/contracts/env-ref.d.ts +41 -0
- package/dist/src/contracts/env-ref.js +33 -0
- package/dist/src/contracts/env-ref.js.map +1 -0
- package/dist/src/contracts/errors.d.ts +56 -0
- package/dist/src/contracts/errors.js +267 -0
- package/dist/src/contracts/errors.js.map +1 -0
- package/dist/src/contracts/events.d.ts +70 -0
- package/dist/src/contracts/events.js +330 -0
- package/dist/src/contracts/events.js.map +1 -0
- package/dist/src/contracts/index.d.ts +32 -0
- package/dist/src/contracts/index.js +27 -0
- package/dist/src/contracts/index.js.map +1 -0
- package/dist/src/contracts/llm.d.ts +278 -0
- package/dist/src/contracts/llm.js +13 -0
- package/dist/src/contracts/llm.js.map +1 -0
- package/dist/src/contracts/messages.d.ts +63 -0
- package/dist/src/contracts/messages.js +66 -0
- package/dist/src/contracts/messages.js.map +1 -0
- package/dist/src/contracts/redact.d.ts +46 -0
- package/dist/src/contracts/redact.js +224 -0
- package/dist/src/contracts/redact.js.map +1 -0
- package/dist/src/contracts/tools.d.ts +198 -0
- package/dist/src/contracts/tools.js +35 -0
- package/dist/src/contracts/tools.js.map +1 -0
- package/dist/src/contracts/types.d.ts +304 -0
- package/dist/src/contracts/types.js +51 -0
- package/dist/src/contracts/types.js.map +1 -0
- package/dist/src/contracts/ui.d.ts +122 -0
- package/dist/src/contracts/ui.js +16 -0
- package/dist/src/contracts/ui.js.map +1 -0
- package/dist/src/sdk/types.d.ts +144 -0
- package/dist/src/sdk/types.js +33 -0
- package/dist/src/sdk/types.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* berry-agent-sdk/stdio — spawn serve stdio 传输(批 13f-3)。
|
|
3
|
+
*
|
|
4
|
+
* spawn 子进程(缺省 process.execPath + 调用方给 args——serve 形态如
|
|
5
|
+
* `['<主包>/dist/host/main.js', 'serve']`,安装布局由调用方知悉、本件不猜)、
|
|
6
|
+
* stdin/stdout 行帧 NDJSON(编解码复用主仓 channels jsonl 件——行安全转义
|
|
7
|
+
* 与分帧单源,零第二套)。
|
|
8
|
+
*
|
|
9
|
+
* 建立即连接级握手(03 §10.6 ⑤ 定形补笔):spawn 后先发 sessionId 缺席的
|
|
10
|
+
* 连接级 hello(宿主 wire-core 连接级档——零订阅纯握手,应答 hello 帧回携
|
|
11
|
+
* protocolVersion 双方比对),先于任何请求帧(串行链头位保证);版本不符
|
|
12
|
+
* 即毒丸化 fail-loud 拒用传输(此后一切事务面携 SDK_PROTOCOL_MISMATCH 拒)。
|
|
13
|
+
*
|
|
14
|
+
* 帧归属纪律:线协议无请求 id ⇒ 事务串行链(一次一事务——前一事务应答落定
|
|
15
|
+
* 才发下一笔);在队帧〔event/heartbeat/ask/重放 entries/replay-end〕入当前
|
|
16
|
+
* 订阅监听面。订阅建立 = hello 帧(取快照高水位)→ replay-end(衔接界标即
|
|
17
|
+
* resolve 位;界标帧本身也入监听面——重放段全量承诺)两段同事务。
|
|
18
|
+
*
|
|
19
|
+
* 终局纪律(03 §10.6 传输腿错误面定形补笔①):子进程终局(exit/error/close)
|
|
20
|
+
* → 在飞事务 fail-loud 拒绝(SDK_TRANSPORT 含退出码)并清 inflight——串行链
|
|
21
|
+
* 自动续走(防前一事务不落定致整链静默挂死);终局后的新事务同律即拒。
|
|
22
|
+
*/
|
|
23
|
+
import { spawn } from 'node:child_process';
|
|
24
|
+
import { decodeWireLine, encodeWireLine, isSdkRequest, splitWireLines } from '../../../src/channels/sdk/jsonl.js';
|
|
25
|
+
import { SDK_PROTOCOL_VERSION } from '../../../src/channels/sdk/protocol.js';
|
|
26
|
+
import { SdkError } from './types.js';
|
|
27
|
+
/** 各动词的应答帧闭集(帧归属判据——事务串行 + 服务端同步受理语义下单调) */
|
|
28
|
+
const EXPECTED_KINDS = {
|
|
29
|
+
prompt: ['ack', 'error'],
|
|
30
|
+
getEntries: ['entries', 'error'],
|
|
31
|
+
sessions: ['sessions', 'error'],
|
|
32
|
+
decide: ['decide-result', 'error'],
|
|
33
|
+
};
|
|
34
|
+
/** spawn serve 子进程并建传输 */
|
|
35
|
+
export function spawnServeTransport(options) {
|
|
36
|
+
const warn = options.onWarn ?? (() => { });
|
|
37
|
+
const child = spawn(options.command ?? process.execPath, [...options.args], {
|
|
38
|
+
env: options.env ?? process.env,
|
|
39
|
+
cwd: options.cwd,
|
|
40
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
41
|
+
});
|
|
42
|
+
// —— 入站环:分帧(跨 chunk 安全)→ 解码(fail-loud 坏行跳过不崩)→ 归属 ——
|
|
43
|
+
let remainder = '';
|
|
44
|
+
let liveListener;
|
|
45
|
+
/** 在队事务(串行链保证至多一笔)——expect 帧族命中即 resolve;终局兜底走 reject(fail-loud) */
|
|
46
|
+
let inflight;
|
|
47
|
+
const deliver = (frame) => {
|
|
48
|
+
if (inflight !== undefined && inflight.expect.has(frame.kind)) {
|
|
49
|
+
const done = inflight;
|
|
50
|
+
inflight = undefined;
|
|
51
|
+
done.resolve(frame);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
liveListener?.(frame); // 直播/重放/心跳帧——订阅面
|
|
55
|
+
};
|
|
56
|
+
child.stdout.setEncoding('utf8');
|
|
57
|
+
child.stdout.on('data', (chunk) => {
|
|
58
|
+
const split = splitWireLines(chunk, remainder);
|
|
59
|
+
remainder = split.remainder;
|
|
60
|
+
for (const line of split.lines) {
|
|
61
|
+
try {
|
|
62
|
+
const decoded = decodeWireLine(line);
|
|
63
|
+
// 出站方向只有帧——请求形属协议违约(反向帧),跳过不崩
|
|
64
|
+
if (isSdkRequest(decoded)) {
|
|
65
|
+
warn(`反向帧跳过(客户端不应收请求形):${line}`);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
deliver(decoded);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
warn(`坏行跳过:${err instanceof Error ? err.message : String(err)}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
child.stderr.setEncoding('utf8');
|
|
76
|
+
child.stderr.on('data', (chunk) => options.onStderr?.(chunk));
|
|
77
|
+
// stdin 写侧防御监听:子进程先亡后的残写(EPIPE 等平台形)归因诊断面——
|
|
78
|
+
// 无 error 监听的流错误以未捕获异常打崩 SDK 消费进程(本平台静默丢弃、他平台防御)
|
|
79
|
+
child.stdin.on('error', (err) => {
|
|
80
|
+
warn(`stdin 写失败:${err instanceof Error ? err.message : String(err)}`);
|
|
81
|
+
});
|
|
82
|
+
// —— 事务串行链:一次一事务(帧归属在结构上无歧义——线协议无请求 id)——
|
|
83
|
+
let chain = Promise.resolve();
|
|
84
|
+
const serialize = (transaction) => {
|
|
85
|
+
const next = chain.then(transaction, transaction);
|
|
86
|
+
chain = next.catch(() => { }); // 链不断——前事务失败不阻塞后事务
|
|
87
|
+
return next;
|
|
88
|
+
};
|
|
89
|
+
/** 单帧应答事务:写请求、挂期望帧族、等归属命中;门检先行(毒丸/终局即 fail-loud 拒) */
|
|
90
|
+
const roundTrip = (req, expect) => serialize(() => new Promise((resolve, reject) => {
|
|
91
|
+
const gate = transactionGate();
|
|
92
|
+
if (gate !== undefined) {
|
|
93
|
+
reject(gate);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
inflight = { expect: new Set(expect), resolve, reject };
|
|
97
|
+
child.stdin.write(encodeWireLine(req));
|
|
98
|
+
}));
|
|
99
|
+
// —— 终局:exit 正常位;spawn 失败形(ENOENT 等)exit 不触发——error/close 兜底 -1 ——
|
|
100
|
+
let exited = false;
|
|
101
|
+
let exitCode; // 终局码(门检报因携带——settle 内先于 exited 置位)
|
|
102
|
+
const exitedPromise = new Promise((resolve) => {
|
|
103
|
+
const settle = (code) => {
|
|
104
|
+
if (exited)
|
|
105
|
+
return;
|
|
106
|
+
exitCode = code;
|
|
107
|
+
exited = true;
|
|
108
|
+
// 终局 → 在飞事务 fail-loud 拒(03 §10.6 定形补笔①:SDK_TRANSPORT 含退出码);
|
|
109
|
+
// 清 inflight 使串行链自动续走——防前一事务不落定致整链静默挂死
|
|
110
|
+
const pending = inflight;
|
|
111
|
+
inflight = undefined;
|
|
112
|
+
pending?.reject(new SdkError('SDK_TRANSPORT', `子进程已退出(code=${code})——在飞事务无法落定`));
|
|
113
|
+
resolve(code);
|
|
114
|
+
};
|
|
115
|
+
child.on('exit', (code) => settle(code ?? 0));
|
|
116
|
+
child.on('error', () => settle(-1));
|
|
117
|
+
child.on('close', (code) => settle(code ?? -1)); // spawn 失败形 exit 缺席 close 补位
|
|
118
|
+
});
|
|
119
|
+
// —— 建立即连接级握手(03 §10.6 ⑤ 定形补笔):串行链头位——先于任何请求帧 ——
|
|
120
|
+
let handshakeError; // 版本错配毒丸——此后一切事务面 fail-loud 拒用传输
|
|
121
|
+
/** 事务面门检(fail-loud 先于写 stdin):毒丸/终局任一在场即拒新事务 */
|
|
122
|
+
const transactionGate = () => {
|
|
123
|
+
if (handshakeError !== undefined)
|
|
124
|
+
return handshakeError;
|
|
125
|
+
if (exited)
|
|
126
|
+
return new SdkError('SDK_TRANSPORT', `子进程已退出(code=${exitCode})——传输不可再用`);
|
|
127
|
+
return undefined;
|
|
128
|
+
};
|
|
129
|
+
const handshake = serialize(() => new Promise((resolve, reject) => {
|
|
130
|
+
const gate = transactionGate(); // 构造后立即 close / 子进程瞬亡形——握手本身即拒
|
|
131
|
+
if (gate !== undefined) {
|
|
132
|
+
handshakeError = gate;
|
|
133
|
+
reject(gate);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
inflight = {
|
|
137
|
+
expect: new Set(['hello', 'error']),
|
|
138
|
+
resolve: (frame) => {
|
|
139
|
+
if (frame.kind === 'error') {
|
|
140
|
+
// 宿主版本闸(⑤ 不符即拒连)——错误帧原码投形毒丸化
|
|
141
|
+
const err = new SdkError(frame.code, frame.message);
|
|
142
|
+
handshakeError = err;
|
|
143
|
+
reject(err);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// 应答 hello 帧回携 protocolVersion——客户端侧比对(⑤「双方携版本比对」)
|
|
147
|
+
const serverVersion = frame.protocolVersion;
|
|
148
|
+
if (serverVersion !== SDK_PROTOCOL_VERSION) {
|
|
149
|
+
const err = new SdkError('SDK_PROTOCOL_MISMATCH', `线协议版本不符:服务端 ${serverVersion} / 调用方 ${SDK_PROTOCOL_VERSION}`);
|
|
150
|
+
handshakeError = err;
|
|
151
|
+
reject(err);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
resolve();
|
|
155
|
+
},
|
|
156
|
+
reject: (err) => {
|
|
157
|
+
// 握手期子进程终局(settle 兜底 reject)——同毒丸拒用
|
|
158
|
+
handshakeError = err;
|
|
159
|
+
reject(err);
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
child.stdin.write(encodeWireLine({ verb: 'hello', protocolVersion: SDK_PROTOCOL_VERSION }));
|
|
163
|
+
}));
|
|
164
|
+
// 握手失败即 best-effort 收线子进程(连接已不可用——不等优雅 EOF 退出序;已亡形 kill 为 no-op)
|
|
165
|
+
handshake.catch(() => {
|
|
166
|
+
child.kill();
|
|
167
|
+
});
|
|
168
|
+
/** 订阅收口(stdio 形:线无退订动词——记客户端口径,监听面回置空) */
|
|
169
|
+
const liveClose = async () => {
|
|
170
|
+
liveListener = undefined;
|
|
171
|
+
};
|
|
172
|
+
// —— 收口(幂等):收线 + 监听解挂;终局 = 子进程退出码 ——
|
|
173
|
+
let closed = false;
|
|
174
|
+
const transport = {
|
|
175
|
+
exited: exitedPromise,
|
|
176
|
+
request: (req) => {
|
|
177
|
+
const expect = EXPECTED_KINDS[req.verb];
|
|
178
|
+
if (expect === undefined) {
|
|
179
|
+
// hello/interrupt 非单帧事务位(hello = openLive 两段、interrupt = send 无应答)
|
|
180
|
+
return Promise.reject(new SdkError('SDK_TRANSPORT', `动词 ${req.verb} 不走请求档(hello→subscribe / interrupt→send)`));
|
|
181
|
+
}
|
|
182
|
+
return roundTrip(req, expect);
|
|
183
|
+
},
|
|
184
|
+
send: (req) => serialize(async () => {
|
|
185
|
+
// 事务面门检同律:终局/毒丸后写 stdin 是伪成功——诚实拒
|
|
186
|
+
const gate = transactionGate();
|
|
187
|
+
if (gate !== undefined)
|
|
188
|
+
throw gate;
|
|
189
|
+
child.stdin.write(encodeWireLine(req));
|
|
190
|
+
}),
|
|
191
|
+
openLive: (params, onFrame) => serialize(() => new Promise((resolve, reject) => {
|
|
192
|
+
const gate = transactionGate();
|
|
193
|
+
if (gate !== undefined) {
|
|
194
|
+
reject(gate);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
liveListener = onFrame;
|
|
198
|
+
let highWaterSeq = -1;
|
|
199
|
+
// 订阅两段同事务:hello(快照高水位)→ replay-end(衔接界标即建立点)
|
|
200
|
+
inflight = {
|
|
201
|
+
expect: new Set(['hello', 'error']),
|
|
202
|
+
resolve: (frame) => {
|
|
203
|
+
if (frame.kind === 'error') {
|
|
204
|
+
reject(new SdkError(frame.code, frame.message));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
highWaterSeq = frame.highWaterSeq;
|
|
208
|
+
inflight = {
|
|
209
|
+
expect: new Set(['replay-end']),
|
|
210
|
+
resolve: (marker) => {
|
|
211
|
+
onFrame(marker); // 界标帧入监听面(重放段全量承诺)后再立柄
|
|
212
|
+
resolve({ sessionId: params.sessionId, highWaterSeq, close: liveClose });
|
|
213
|
+
},
|
|
214
|
+
reject, // 建立期终局兜底(replay-end 前)——订阅建立 Promise 不得悬挂
|
|
215
|
+
};
|
|
216
|
+
},
|
|
217
|
+
reject,
|
|
218
|
+
};
|
|
219
|
+
child.stdin.write(encodeWireLine({
|
|
220
|
+
verb: 'hello',
|
|
221
|
+
protocolVersion: SDK_PROTOCOL_VERSION,
|
|
222
|
+
sessionId: params.sessionId,
|
|
223
|
+
...(params.after !== undefined ? { after: params.after } : {}),
|
|
224
|
+
...(params.noDelta !== undefined ? { noDelta: params.noDelta } : {}),
|
|
225
|
+
}));
|
|
226
|
+
})),
|
|
227
|
+
close: async () => {
|
|
228
|
+
if (closed)
|
|
229
|
+
return;
|
|
230
|
+
closed = true;
|
|
231
|
+
liveListener = undefined;
|
|
232
|
+
child.stdin.end(); // 收线(EOF——serve 优雅退出序)
|
|
233
|
+
await exitedPromise;
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
return transport;
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=stdio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../../../src/stdio.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* berry-agent-sdk/types — 客户端契约面(批 13f-3 契约先行)。
|
|
3
|
+
*
|
|
4
|
+
* 类型面单源(03 §10.6 批 13f 落码定形):线协议词面自 channels 协议件
|
|
5
|
+
* 相对导入 re-export、事件/审批词面自 contracts 相对导入 re-export——构建
|
|
6
|
+
* 时编译入包(同仓单源、零拷贝漂移,「生成」的实质即此)。策展式点名
|
|
7
|
+
* re-export(非整桶):发布物的公共面是稳定 API,进什么出什么逐项过目。
|
|
8
|
+
*
|
|
9
|
+
* 传输抽象(两形态同面):请求档〔单帧应答事务、串行〕/ 无应答档
|
|
10
|
+
* 〔interrupt——stdio 写后即决、HTTP 形 204〕/ 直播档〔stdio = 线内 hello、
|
|
11
|
+
* HTTP = GET /v1/events SSE——重放帧与直播帧一律入 onFrame;订阅在
|
|
12
|
+
* replay-end 落定后 resolve(衔接界标即建立点)〕。
|
|
13
|
+
*/
|
|
14
|
+
import type { ApprovalAskAnswer } from '../../../src/contracts/approval.js';
|
|
15
|
+
import type { SdkAckFrame, SdkEntriesFrame, SdkRequest, SdkSessionSummary, SdkWireFrame } from '../../../src/channels/sdk/protocol.js';
|
|
16
|
+
/** 线事件词面(04 §2 十型——live 帧载荷) */
|
|
17
|
+
export type { AgentEvent } from '../../../src/agent/events.js';
|
|
18
|
+
/** 审批应答四值闭集(decide 动词入参) */
|
|
19
|
+
export type { ApprovalAskAnswer } from '../../../src/contracts/approval.js';
|
|
20
|
+
/** 线协议请求族(六动词——手工构造进阶位;常规用法走 client 方法面) */
|
|
21
|
+
export type { SdkRequest } from '../../../src/channels/sdk/protocol.js';
|
|
22
|
+
/** 线帧全族(kind 判别联合——onFrame 消费面 pattern-match 用) */
|
|
23
|
+
export type { SdkWireFrame } from '../../../src/channels/sdk/protocol.js';
|
|
24
|
+
/** 受理回执帧(prompt 应答——sessionId/duplicate/highWaterSeq) */
|
|
25
|
+
export type { SdkAckFrame } from '../../../src/channels/sdk/protocol.js';
|
|
26
|
+
/** durable 投影页帧(getEntries 应答) */
|
|
27
|
+
export type { SdkEntriesFrame } from '../../../src/channels/sdk/protocol.js';
|
|
28
|
+
/** 会话清单行(sessions 应答元素) */
|
|
29
|
+
export type { SdkSessionSummary } from '../../../src/channels/sdk/protocol.js';
|
|
30
|
+
/** durable 平铺事件(type/seq/time/data 四字段——重放与轮询共形) */
|
|
31
|
+
export type { SdkDurableEntry } from '../../../src/channels/sdk/protocol.js';
|
|
32
|
+
/** live 事件帧(event + seq——直播段载荷) */
|
|
33
|
+
export type { SdkEventFrame } from '../../../src/channels/sdk/protocol.js';
|
|
34
|
+
/** hello 应答帧(订阅建立序首帧——highWaterSeq 快照位) */
|
|
35
|
+
export type { SdkHelloFrame } from '../../../src/channels/sdk/protocol.js';
|
|
36
|
+
/** 错误帧(code/message——线面业务错词面) */
|
|
37
|
+
export type { SdkErrorFrame } from '../../../src/channels/sdk/protocol.js';
|
|
38
|
+
/** 线协议版本(握手常量——与主包同一源) */
|
|
39
|
+
export { SDK_PROTOCOL_VERSION } from '../../../src/channels/sdk/protocol.js';
|
|
40
|
+
/** 业务错(线面错误帧的客户端投形——code 为 SDK_ 族/SESSION_* 线词面) */
|
|
41
|
+
export declare class SdkError extends Error {
|
|
42
|
+
/** 线面错误码(SDK_PROTOCOL_MISMATCH / SESSION_NOT_FOUND / …) */
|
|
43
|
+
readonly code: string;
|
|
44
|
+
/** 关联会话(错误帧在场时透传——缺席 undefined) */
|
|
45
|
+
readonly sessionId?: string | undefined;
|
|
46
|
+
constructor(
|
|
47
|
+
/** 线面错误码(SDK_PROTOCOL_MISMATCH / SESSION_NOT_FOUND / …) */
|
|
48
|
+
code: string, message: string,
|
|
49
|
+
/** 关联会话(错误帧在场时透传——缺席 undefined) */
|
|
50
|
+
sessionId?: string | undefined);
|
|
51
|
+
}
|
|
52
|
+
/** 直播帧监听面(重放段〔entries/replay-end〕与直播段〔event/heartbeat/ask〕一律入此) */
|
|
53
|
+
export type SdkFrameListener = (frame: SdkWireFrame) => void;
|
|
54
|
+
/** 订阅参数(= hello 动词载荷——after = 断线续读位、noDelta = 剥 delta) */
|
|
55
|
+
export interface SdkLiveParams {
|
|
56
|
+
readonly sessionId: string;
|
|
57
|
+
/** 重放起点(已收末条 seq——窗口 (after, 高水位];缺席 -1 从头) */
|
|
58
|
+
readonly after?: number;
|
|
59
|
+
/** 剥 message_update delta 帧(07 §5 --no-delta 客户端立场) */
|
|
60
|
+
readonly noDelta?: boolean;
|
|
61
|
+
}
|
|
62
|
+
/** 直播订阅柄(replay-end 落定后建立——close 退订〔stdio 形线内续用不受影响〕) */
|
|
63
|
+
export interface SdkLiveHandle {
|
|
64
|
+
readonly sessionId: string;
|
|
65
|
+
/** 订阅序首帧的快照高水位(衔接界标前的 durable 水位——对账起点参考) */
|
|
66
|
+
readonly highWaterSeq: number;
|
|
67
|
+
/** 退订(幂等):stdio 形仅记客户端口径〔线协议无退订动词——close 整连接即退〕、HTTP 形关 SSE 流 */
|
|
68
|
+
close(): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 传输抽象(spawn stdio / 直连 HTTP 两实装同面)。
|
|
72
|
+
*
|
|
73
|
+
* 事务串行纪律:request/openLive 一次一事务(前一事务应答落定才发下一笔)
|
|
74
|
+
* ——线协议无请求 id,串行化使帧归属在结构上无歧义(乱序并发进阶位不采)。
|
|
75
|
+
*/
|
|
76
|
+
export interface SdkTransport {
|
|
77
|
+
/** 请求档:发一动词、取应答帧(错误帧原样返回不抛——由 client 投形 SdkError) */
|
|
78
|
+
request(req: SdkRequest): Promise<SdkWireFrame>;
|
|
79
|
+
/** 无应答档(interrupt——受理经事件流可观察:错误帧走 onFrame 面) */
|
|
80
|
+
send(req: SdkRequest): Promise<void>;
|
|
81
|
+
/** 直播档建立:重放帧与直播帧入 onFrame;replay-end 后 resolve 订阅柄 */
|
|
82
|
+
openLive(params: SdkLiveParams, onFrame: SdkFrameListener): Promise<SdkLiveHandle>;
|
|
83
|
+
/** 整连接收口(幂等):stdio 形收线子进程、HTTP 形关连接池面 */
|
|
84
|
+
close(): Promise<void>;
|
|
85
|
+
}
|
|
86
|
+
/** prompt 入参(messageId 缺省 = 客户端计数器形 `sdk-N` 每次全新——幂等语义未申请即不虚构) */
|
|
87
|
+
export interface SdkPromptInput {
|
|
88
|
+
/** 续接会话句柄——缺席即新建 */
|
|
89
|
+
readonly sessionId?: string;
|
|
90
|
+
/** 幂等键(同键同内容重发收 duplicate 收执)——缺席计数器形全新 */
|
|
91
|
+
readonly messageId?: string;
|
|
92
|
+
readonly content: string;
|
|
93
|
+
}
|
|
94
|
+
/** getEntries 入参(since 缺省 -1 从头全窗;cursor = 分页续读游标——SDK 面亦透传) */
|
|
95
|
+
export interface SdkEntriesInput {
|
|
96
|
+
readonly sessionId: string;
|
|
97
|
+
readonly since?: number;
|
|
98
|
+
/** 分页续读游标(上一页 entries 帧 nextCursor 在场即携之续读——跟尽义务的回送位,分页帽落地时可跟尽) */
|
|
99
|
+
readonly cursor?: string;
|
|
100
|
+
}
|
|
101
|
+
/** 类型化客户端(传输无关面——两传输同方法面消费) */
|
|
102
|
+
export interface SdkClient {
|
|
103
|
+
/** 会话发起/续接(→ ack 应答:会话句柄 + 受理回执);错误帧 → 抛 {@link SdkError} */
|
|
104
|
+
prompt(input: SdkPromptInput): Promise<SdkAckFrame>;
|
|
105
|
+
/** 断线对账读面(→ entries 页帧);跟尽义务在调用方(nextCursor 在场即续读——cursor 位透传,分页帽落地时可跟尽) */
|
|
106
|
+
getEntries(input: SdkEntriesInput): Promise<SdkEntriesFrame>;
|
|
107
|
+
/** 会话清单 */
|
|
108
|
+
sessions(): Promise<SdkSessionSummary[]>;
|
|
109
|
+
/** 打断在飞 run(无应答档——写后即决;missing 会话错误帧走订阅帧面) */
|
|
110
|
+
interrupt(sessionId: string): Promise<void>;
|
|
111
|
+
/** 审批应答(跨入口竞速回执——applied / superseded) */
|
|
112
|
+
decide(approvalId: string, answer: ApprovalAskAnswer, note?: string): Promise<'applied' | 'superseded'>;
|
|
113
|
+
/** 直播订阅(= hello 动词承载位——重放→衔接→直播;帧全量入 onFrame) */
|
|
114
|
+
subscribe(params: SdkLiveParams, onFrame: SdkFrameListener): Promise<SdkLiveHandle>;
|
|
115
|
+
/** 整连接收口(幂等) */
|
|
116
|
+
close(): Promise<void>;
|
|
117
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** 线协议版本(握手常量——与主包同一源) */
|
|
2
|
+
export { SDK_PROTOCOL_VERSION } from '../../../src/channels/sdk/protocol.js';
|
|
3
|
+
/* ---------------- 客户端契约 ---------------- */
|
|
4
|
+
/** 业务错(线面错误帧的客户端投形——code 为 SDK_ 族/SESSION_* 线词面) */
|
|
5
|
+
export class SdkError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
sessionId;
|
|
8
|
+
constructor(
|
|
9
|
+
/** 线面错误码(SDK_PROTOCOL_MISMATCH / SESSION_NOT_FOUND / …) */
|
|
10
|
+
code, message,
|
|
11
|
+
/** 关联会话(错误帧在场时透传——缺席 undefined) */
|
|
12
|
+
sessionId) {
|
|
13
|
+
super(`[${code}] ${message}`);
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.sessionId = sessionId;
|
|
16
|
+
this.name = 'SdkError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/types.ts"],"names":[],"mappings":"AA8CA,0BAA0B;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAE7E,6CAA6C;AAE7C,oDAAoD;AACpD,MAAM,OAAO,QAAS,SAAQ,KAAK;IAGtB;IAGA;IALX;IACE,2DAA2D;IAClD,IAAY,EACrB,OAAe;IACf,mCAAmC;IAC1B,SAAkB;QAE3B,KAAK,CAAC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QALrB,SAAI,GAAJ,IAAI,CAAQ;QAGZ,cAAS,GAAT,SAAS,CAAS;QAG3B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent 件 — AgentEvent 活体事件族(04 篇 §2 机制真源)。
|
|
3
|
+
*
|
|
4
|
+
* 归位注记(2026-09-08 U3 落码批):类型族(RunStatus/DeliverChannel/
|
|
5
|
+
* AgentEvent/AgentEventSink)归位 contracts/agent-events.ts——插件侧 UI 后端
|
|
6
|
+
* 类型可达(03 §2.2 registerUiBackend 定形注记:虚拟主键 `berry-agent` 面只达
|
|
7
|
+
* contracts);本件 re-export 维持 agent 公开面与件内消费路径不变(批 11b
|
|
8
|
+
* ApprovalAsk 归位同款先例)。顺序铁律与活体流纪律的成文真源随类型走
|
|
9
|
+
* (contracts/agent-events.ts 件头)。
|
|
10
|
+
*/
|
|
11
|
+
export type { AgentEvent, AgentEventSink, DeliverChannel, RunStatus } from '../contracts/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../../src/agent/events.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent 件公开面(loop 骨架 + 三通道队列 + 活体事件;04 篇 §2/§4)。
|
|
3
|
+
*
|
|
4
|
+
* 单向 DAG:agent → contracts 唯一边(不 import llm/session/context——02 篇
|
|
5
|
+
* §4.2 关键不依赖第一条的码面执法)。驱动侧(conversation 件)经 startRun
|
|
6
|
+
* 入口消费(seeds 空数组 = 纯续入);continueRun 为恢复续入形第二入口
|
|
7
|
+
* (04 §2 入口两式)。PendingMessageQueue 是三通道暂存机制件。
|
|
8
|
+
*/
|
|
9
|
+
export type { AgentContext, AgentLoopConfig, BeforeToolCallDecision, TurnAdjustment, RunResult, EmitFn, } from './types.js';
|
|
10
|
+
export type { RunStatus, DeliverChannel, AgentEvent, AgentEventSink } from './events.js';
|
|
11
|
+
export type { QueueMode, OverflowPolicy, PendingItem, EnqueueReceipt } from './queue.js';
|
|
12
|
+
export { PendingMessageQueue, DEFAULT_QUEUE_CAPACITY } from './queue.js';
|
|
13
|
+
export { startRun, continueRun } from './loop.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/agent/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent 件 — loop 骨架(04 §2 形态铁律:双 while、≤150 行、零 try/catch、零存储感知)。
|
|
3
|
+
* 外层 turn 循环:steering 注入 → 流消费 → 终态判定 → 工具批 → followUp 续跑裁决。
|
|
4
|
+
* 内层流消费与工具批执行分别住在 stream.ts / tools-batch.ts(骨架只留控制流)。
|
|
5
|
+
* 全部策略经注入回调(AgentLoopConfig 12 项)、全部状态经活体事件回流——
|
|
6
|
+
* loop 不知道 conversation 存在;错误不就地 try/catch(StreamFn 永不抛契约),失败由 run 终态承载(04 §2/§3)。
|
|
7
|
+
*/
|
|
8
|
+
import type { AgentMessage } from '../contracts/index.js';
|
|
9
|
+
import type { AgentContext, AgentLoopConfig, RunResult } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* 种子起跑:seeds 逐条入列(用户直发——channel 缺省)后进主循环。
|
|
12
|
+
* @param context 运行上下文(messages 活数组) @param config 回调面 @param seeds 种子消息(缺省空)
|
|
13
|
+
*/
|
|
14
|
+
export declare function startRun(context: AgentContext, config: AgentLoopConfig, seeds?: AgentMessage[]): Promise<RunResult>;
|
|
15
|
+
/**
|
|
16
|
+
* 续入起跑:末角色校验(经 convertToLlm 转换后须 user/toolResult——违者
|
|
17
|
+
* AGENT_CONTINUE_INVALID fail-loud,防把 assistant 尾直接重发 provider)。
|
|
18
|
+
*/
|
|
19
|
+
export declare function continueRun(context: AgentContext, config: AgentLoopConfig): Promise<RunResult>;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent 件 — loop 骨架(04 §2 形态铁律:双 while、≤150 行、零 try/catch、零存储感知)。
|
|
3
|
+
* 外层 turn 循环:steering 注入 → 流消费 → 终态判定 → 工具批 → followUp 续跑裁决。
|
|
4
|
+
* 内层流消费与工具批执行分别住在 stream.ts / tools-batch.ts(骨架只留控制流)。
|
|
5
|
+
* 全部策略经注入回调(AgentLoopConfig 12 项)、全部状态经活体事件回流——
|
|
6
|
+
* loop 不知道 conversation 存在;错误不就地 try/catch(StreamFn 永不抛契约),失败由 run 终态承载(04 §2/§3)。
|
|
7
|
+
*/
|
|
8
|
+
import { BaseError } from '../contracts/index.js';
|
|
9
|
+
import { streamAssistantResponse } from './stream.js';
|
|
10
|
+
import { executeToolBatch } from './tools-batch.js';
|
|
11
|
+
/** 种子/续跑消息入列(steering 顶注与 followUp 续跑共用——channel 随事件披露) */
|
|
12
|
+
function pushAll(context, messages, emit, channel) {
|
|
13
|
+
for (const message of messages) {
|
|
14
|
+
context.messages.push(message);
|
|
15
|
+
emit({ type: 'message_start', role: message.role, ...(channel ? { channel } : {}) });
|
|
16
|
+
emit({ type: 'message_end', message, ...(channel ? { channel } : {}) });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** assistant 内联 toolCall 块直取(工具批与截断配对的公共提取面) */
|
|
20
|
+
function toolCallsOf(message) {
|
|
21
|
+
return message.content.filter((block) => block.type === 'toolCall');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 种子起跑:seeds 逐条入列(用户直发——channel 缺省)后进主循环。
|
|
25
|
+
* @param context 运行上下文(messages 活数组) @param config 回调面 @param seeds 种子消息(缺省空)
|
|
26
|
+
*/
|
|
27
|
+
export function startRun(context, config, seeds = []) {
|
|
28
|
+
const emit = (event) => void config.onEvent?.(event);
|
|
29
|
+
pushAll(context, seeds, emit);
|
|
30
|
+
return runLoop(context, config, emit);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 续入起跑:末角色校验(经 convertToLlm 转换后须 user/toolResult——违者
|
|
34
|
+
* AGENT_CONTINUE_INVALID fail-loud,防把 assistant 尾直接重发 provider)。
|
|
35
|
+
*/
|
|
36
|
+
export function continueRun(context, config) {
|
|
37
|
+
const last = context.messages[context.messages.length - 1];
|
|
38
|
+
const converted = last === undefined ? null : config.convertToLlm(last);
|
|
39
|
+
const role = Array.isArray(converted) ? converted[converted.length - 1]?.role : converted?.role;
|
|
40
|
+
if (role !== 'user' && role !== 'toolResult') {
|
|
41
|
+
throw new BaseError('AGENT_CONTINUE_INVALID', `continueRun 末角色校验红:转换后末角色为 ${String(role ?? '空')}(须 user/toolResult——恢复续入的上下文形状前提)`);
|
|
42
|
+
}
|
|
43
|
+
return runLoop(context, config, (event) => void config.onEvent?.(event));
|
|
44
|
+
}
|
|
45
|
+
/** 主循环(双 while 的外层本体——内层流消费在 streamAssistantResponse 内) */
|
|
46
|
+
async function runLoop(context, config, emit) {
|
|
47
|
+
emit({ type: 'agent_start' });
|
|
48
|
+
let turn = 0;
|
|
49
|
+
let stopReason;
|
|
50
|
+
let errorMessage;
|
|
51
|
+
while (true) {
|
|
52
|
+
// turn 顶:steering 注入(busy 中插入的消息进本轮上下文)——消费点在
|
|
53
|
+
// preModelRequest 之前(同步零让出):await 窗若先于消费点,busy 期
|
|
54
|
+
// submit 会漂移进 steer 通道(本应 followUp 尾声消费——通道语义时序
|
|
55
|
+
// 回归锁见 driver.test 队列通道族)
|
|
56
|
+
pushAll(context, config.getSteeringMessages?.() ?? [], emit, 'steer');
|
|
57
|
+
// 模型请求前检查(03 §2.4 agent_pre_step 窗——'stop' 刹停零 dangling turn):
|
|
58
|
+
// 位置 = steering 消费后、turn_start 前(steering 注入属上下文组装非模型
|
|
59
|
+
// 请求;刹停时 steer 件已落 durable 由下次 run 重播种承载)
|
|
60
|
+
if ((await config.preModelRequest?.(context)) === 'stop') {
|
|
61
|
+
stopReason = 'stop';
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
turn += 1;
|
|
65
|
+
emit({ type: 'turn_start', turn });
|
|
66
|
+
const assistant = await streamAssistantResponse(config, context, emit);
|
|
67
|
+
stopReason = assistant.stopReason;
|
|
68
|
+
errorMessage = assistant.errorMessage;
|
|
69
|
+
// 中止竞速败者形重归因:pi-ai 层 response promise 与 abort 信号竞速——败者形 =
|
|
70
|
+
// stopReason 'error' + errorMessage 系 AbortError 文案('This operation was aborted'
|
|
71
|
+
// 等)。signal 已 aborted 即实证善意中止在途(issue watchdog 预算帽 / TUI Esc /
|
|
72
|
+
// webui stop),重归因 aborted——消费面善意词面(『每 issue 预算帽耗尽』等)全靠
|
|
73
|
+
// aborted 分支承载。窄判据三合一(缺一不触发):error + signal.aborted + abort 文案
|
|
74
|
+
// ——真 error(网络断等)不受泛化误伤。
|
|
75
|
+
if (stopReason === 'error' &&
|
|
76
|
+
config.signal?.aborted === true &&
|
|
77
|
+
errorMessage !== undefined &&
|
|
78
|
+
/abort/i.test(errorMessage)) {
|
|
79
|
+
stopReason = 'aborted';
|
|
80
|
+
}
|
|
81
|
+
emit({ type: 'turn_end', turn, stopReason });
|
|
82
|
+
// 终态短路:error/aborted → run 收场(status 映射见函数尾)
|
|
83
|
+
if (assistant.stopReason === 'error' || assistant.stopReason === 'aborted')
|
|
84
|
+
break;
|
|
85
|
+
// 截断防御:length → 整批配对 isError 后收 failed(残缺批不进下一轮)
|
|
86
|
+
if (assistant.stopReason === 'length') {
|
|
87
|
+
errorMessage = assistant.errorMessage ?? '输出被上下文窗口截断(stopReason=length)';
|
|
88
|
+
pushAll(context, toolCallsOf(assistant).map((call) => ({
|
|
89
|
+
role: 'toolResult',
|
|
90
|
+
toolCallId: call.id,
|
|
91
|
+
toolName: call.name,
|
|
92
|
+
content: [{ type: 'text', text: '输出被上下文窗口截断——整批配对收口,不进下一轮' }],
|
|
93
|
+
isError: true,
|
|
94
|
+
timestamp: Date.now(),
|
|
95
|
+
})), emit);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
if (assistant.stopReason === 'toolUse') {
|
|
99
|
+
const outcome = await executeToolBatch(config, context, toolCallsOf(assistant), emit);
|
|
100
|
+
pushAll(context, outcome.results, emit);
|
|
101
|
+
if (outcome.terminate)
|
|
102
|
+
break; // 批内一致 terminate → 优雅停
|
|
103
|
+
}
|
|
104
|
+
// turn 终止裁决(停止词/预算尽/打断)——先于 followUp 消费:停则留在驱动侧队列不入列
|
|
105
|
+
if (await config.shouldStopAfterTurn?.(context, assistant))
|
|
106
|
+
break;
|
|
107
|
+
if (assistant.stopReason !== 'toolUse') {
|
|
108
|
+
// stop/deferred:followUp 是 idle 起跑通道——空即自然停 completed
|
|
109
|
+
const followUps = config.getFollowUpMessages?.() ?? [];
|
|
110
|
+
if (followUps.length === 0)
|
|
111
|
+
break;
|
|
112
|
+
pushAll(context, followUps, emit, 'followUp');
|
|
113
|
+
}
|
|
114
|
+
// turn 间准备窗:换 model/thinkingLevel 唯一时机(todo/goal 注入同窗)。
|
|
115
|
+
// 实况注记(2026-09-11 定形):换档只改内存 config 不落 session/thinking-level
|
|
116
|
+
// durable 事件——该词 v1 词先锚定(05 §1.1 在册、写点随会话档位切换面立题;
|
|
117
|
+
// 冷启动恢复走栈级静态 options.thinkingLevel)
|
|
118
|
+
const adjustment = await config.prepareNextTurn?.(context);
|
|
119
|
+
if (adjustment) {
|
|
120
|
+
if (adjustment.model !== undefined)
|
|
121
|
+
config.model = adjustment.model;
|
|
122
|
+
if (adjustment.thinkingLevel !== undefined)
|
|
123
|
+
config.thinkingLevel = adjustment.thinkingLevel;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// 终态映射:error/length → failed;aborted → aborted;其余(stop/toolUse/deferred)→ completed
|
|
127
|
+
const status = stopReason === 'error' || stopReason === 'length' ? 'failed' : stopReason === 'aborted' ? 'aborted' : 'completed';
|
|
128
|
+
emit({
|
|
129
|
+
type: 'agent_end',
|
|
130
|
+
status,
|
|
131
|
+
...(stopReason !== undefined ? { stopReason } : {}),
|
|
132
|
+
...(errorMessage !== undefined ? { errorMessage } : {}),
|
|
133
|
+
});
|
|
134
|
+
return {
|
|
135
|
+
status,
|
|
136
|
+
...(stopReason !== undefined ? { stopReason } : {}),
|
|
137
|
+
...(errorMessage !== undefined ? { errorMessage } : {}),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../../../../src/agent/loop.ts"],"names":[],"mappings":"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"}
|