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,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 多会话注册表与焦点编排(07 §4.1 通道契约——2026-09-06 channels 纵切批)。
|
|
3
|
+
*
|
|
4
|
+
* 职责:会话在场集合 + 焦点位(聚焦者全渲染/非聚焦摘要行的判定源)+
|
|
5
|
+
* 焦点切换清屏重画(拉投影 → repaint 回调——投影拉取经装配注入,
|
|
6
|
+
* channels 不 import session 是 02 §4.1 边表的刻意设计)。
|
|
7
|
+
*
|
|
8
|
+
* 焦点切换不自动回退:聚焦会话注销后焦点空悬(focused=null——非聚焦态
|
|
9
|
+
* 全体),下一焦点由用户动作显式给(切焦编舞归 TUI 呈现批)。
|
|
10
|
+
*/
|
|
11
|
+
export class SessionChannels {
|
|
12
|
+
fetchProjection;
|
|
13
|
+
repaint;
|
|
14
|
+
sessions = new Set();
|
|
15
|
+
currentFocus = null;
|
|
16
|
+
constructor(fetchProjection, repaint) {
|
|
17
|
+
this.fetchProjection = fetchProjection;
|
|
18
|
+
this.repaint = repaint;
|
|
19
|
+
}
|
|
20
|
+
/** 会话入场(幂等;焦点不自动变更——显式 focus 才切) */
|
|
21
|
+
registerSession(sessionId) {
|
|
22
|
+
this.sessions.add(sessionId);
|
|
23
|
+
}
|
|
24
|
+
/** 会话退场:在场集移除;若正是聚焦者 → 焦点空悬(不自动接续) */
|
|
25
|
+
unregisterSession(sessionId) {
|
|
26
|
+
this.sessions.delete(sessionId);
|
|
27
|
+
if (this.currentFocus === sessionId)
|
|
28
|
+
this.currentFocus = null;
|
|
29
|
+
}
|
|
30
|
+
/** 当前聚焦会话(null = 焦点空悬——全体非聚焦态) */
|
|
31
|
+
get focusedId() {
|
|
32
|
+
return this.currentFocus;
|
|
33
|
+
}
|
|
34
|
+
isFocused(sessionId) {
|
|
35
|
+
return this.currentFocus === sessionId;
|
|
36
|
+
}
|
|
37
|
+
/** 在场判定(emit 路由前置——不在场会话的信封仍可分流,呈现裁剪归后端) */
|
|
38
|
+
has(sessionId) {
|
|
39
|
+
return this.sessions.has(sessionId);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 焦点切换(07 §4.1:清屏重画):置位 → 拉投影 → repaint。
|
|
43
|
+
* 投影拉取缺席 → 空投影重画(诚实缺席:装配缺真源是可观察态,不静默假装
|
|
44
|
+
* 有历史);拉取异常向上抛(fail-loud——投影真源故障不降级为「无历史」谎言)。
|
|
45
|
+
* 未注册会话 focus 视同注册(焦点即活跃声明——幂等)。
|
|
46
|
+
*/
|
|
47
|
+
async focus(sessionId) {
|
|
48
|
+
this.registerSession(sessionId);
|
|
49
|
+
this.currentFocus = sessionId;
|
|
50
|
+
const projection = await (this.fetchProjection?.(sessionId) ?? []);
|
|
51
|
+
// 焦点可能在拉投影期间被再切(快速切焦)——只为本焦点落画(迟到的旧画弃)
|
|
52
|
+
if (this.currentFocus === sessionId) {
|
|
53
|
+
this.repaint(sessionId, projection);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../../../src/channels/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,OAAO,eAAe;IAKP;IACA;IALF,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,YAAY,GAAkB,IAAI,CAAC;IAE3C,YACmB,eAAqF,EACrF,OAAwE;QADxE,oBAAe,GAAf,eAAe,CAAsE;QACrF,YAAO,GAAP,OAAO,CAAiE;IACxF,CAAC;IAEJ,oCAAoC;IACpC,eAAe,CAAC,SAAiB;QAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IAED,sCAAsC;IACtC,iBAAiB,CAAC,SAAiB;QACjC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS;YAAE,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAChE,CAAC;IAED,kCAAkC;IAClC,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,SAAS,CAAC,SAAiB;QACzB,OAAO,IAAI,CAAC,YAAY,KAAK,SAAS,CAAC;IACzC,CAAC;IAED,4CAA4C;IAC5C,GAAG,CAAC,SAAiB;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK,CAAC,SAAiB;QAC3B,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QACnE,uCAAuC;QACvC,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACpC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 幂等 admit 判定纯函数(03 篇 §10.6 线协议七原则④ + 05 篇 §3.5 第二腿——
|
|
3
|
+
* durable 承载条)。
|
|
4
|
+
*
|
|
5
|
+
* **两词一字段两面**(05 §3.5):线面 `messageId`(03 §10.6 请求面动词族条)
|
|
6
|
+
* 受理时即落账为 durable `data.dedupeKey`——单键直写、无映射表、无变换。
|
|
7
|
+
* 本函数以 messageId 为键直查既存表(键域同一),语义真源在规范、查重实现
|
|
8
|
+
* (日志扫描 / 投影侧索引)随受理实装(批 13b)定形。
|
|
9
|
+
*
|
|
10
|
+
* 语义三档:fresh(无同键——受理新跑)/ duplicate(同键同内容——幂等重收执,
|
|
11
|
+
* 回执即既存事件本身、经 after 重放可取、不重跑)/ conflict(同键异内容——
|
|
12
|
+
* `SDK_MESSAGE_CONFLICT`,误判超时重发零副作用的反面执法位)。跨重启幂等
|
|
13
|
+
* 天然成立(durable 即真相——无第二套 admit 存储表)。
|
|
14
|
+
*/
|
|
15
|
+
/** admit 判定三档(conflict 档携错误码——调用方直接落结构化错误帧) */
|
|
16
|
+
export type AdmitVerdict = {
|
|
17
|
+
status: 'fresh';
|
|
18
|
+
} | {
|
|
19
|
+
status: 'duplicate';
|
|
20
|
+
} | {
|
|
21
|
+
status: 'conflict';
|
|
22
|
+
code: 'SDK_MESSAGE_CONFLICT';
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* 判定一条 prompt 的受理档。
|
|
26
|
+
*
|
|
27
|
+
* @param known 既存 dedupeKey → 内容 映射(受理侧维护;跨重启语义由 durable
|
|
28
|
+
* 落账兑现——本函数纯逻辑不触存储)
|
|
29
|
+
* @param messageId 调用方自选幂等键(受理时即落账为 data.dedupeKey——两词一字段两面)
|
|
30
|
+
* @param content 消息内容(同键异内容的比对基准——字符串全等,无归一化)
|
|
31
|
+
*/
|
|
32
|
+
export declare function admitMessage(known: ReadonlyMap<string, string>, messageId: string, content: string): AdmitVerdict;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 幂等 admit 判定纯函数(03 篇 §10.6 线协议七原则④ + 05 篇 §3.5 第二腿——
|
|
3
|
+
* durable 承载条)。
|
|
4
|
+
*
|
|
5
|
+
* **两词一字段两面**(05 §3.5):线面 `messageId`(03 §10.6 请求面动词族条)
|
|
6
|
+
* 受理时即落账为 durable `data.dedupeKey`——单键直写、无映射表、无变换。
|
|
7
|
+
* 本函数以 messageId 为键直查既存表(键域同一),语义真源在规范、查重实现
|
|
8
|
+
* (日志扫描 / 投影侧索引)随受理实装(批 13b)定形。
|
|
9
|
+
*
|
|
10
|
+
* 语义三档:fresh(无同键——受理新跑)/ duplicate(同键同内容——幂等重收执,
|
|
11
|
+
* 回执即既存事件本身、经 after 重放可取、不重跑)/ conflict(同键异内容——
|
|
12
|
+
* `SDK_MESSAGE_CONFLICT`,误判超时重发零副作用的反面执法位)。跨重启幂等
|
|
13
|
+
* 天然成立(durable 即真相——无第二套 admit 存储表)。
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* 判定一条 prompt 的受理档。
|
|
17
|
+
*
|
|
18
|
+
* @param known 既存 dedupeKey → 内容 映射(受理侧维护;跨重启语义由 durable
|
|
19
|
+
* 落账兑现——本函数纯逻辑不触存储)
|
|
20
|
+
* @param messageId 调用方自选幂等键(受理时即落账为 data.dedupeKey——两词一字段两面)
|
|
21
|
+
* @param content 消息内容(同键异内容的比对基准——字符串全等,无归一化)
|
|
22
|
+
*/
|
|
23
|
+
export function admitMessage(known, messageId, content) {
|
|
24
|
+
const existing = known.get(messageId);
|
|
25
|
+
if (existing === undefined)
|
|
26
|
+
return { status: 'fresh' };
|
|
27
|
+
// 同键:内容全等分档——异内容即冲突(fail-loud 不静默覆盖)
|
|
28
|
+
return existing === content ? { status: 'duplicate' } : { status: 'conflict', code: 'SDK_MESSAGE_CONFLICT' };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=admit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admit.js","sourceRoot":"","sources":["../../../../../../src/channels/sdk/admit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,KAAkC,EAAE,SAAiB,EAAE,OAAe;IACjG,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACvD,qCAAqC;IACrC,OAAO,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC;AAC/G,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { UiBackend } from '../types.js';
|
|
2
|
+
import { SdkWireCore, type SdkWireDeps, type SdkWireOptions } from './wire-core.js';
|
|
3
|
+
/** createSdkBackend 产物(后端 + 线核 + 收口三位——装配面 13c/13e 消费) */
|
|
4
|
+
export interface SdkBackendHandle {
|
|
5
|
+
/** 通道核注册面(UiBackend 契约件) */
|
|
6
|
+
readonly backend: UiBackend<never>;
|
|
7
|
+
/** 线协议核(宿主行解码 → handleRequest / 定时 heartbeatTick+drain) */
|
|
8
|
+
readonly core: SdkWireCore;
|
|
9
|
+
/** 连接收口:在飞 ask 全部 unavailable 收场(通道消失语义)+ core.close()(后续全静默) */
|
|
10
|
+
dispose(): void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 造 SDK 通道后端(每连接一枚——core 即该连接的单连接状态机)。
|
|
14
|
+
*
|
|
15
|
+
* @param deps 装配桥注入面(decideApproval/onSubscribed 两面由本件自持——
|
|
16
|
+
* 幂等账与重推编舞是后端语义不是桥语义)
|
|
17
|
+
* @param options 线核构造选项(时钟/节拍/背压参——透传)
|
|
18
|
+
*/
|
|
19
|
+
export declare function createSdkBackend(deps: Omit<SdkWireDeps, 'decideApproval' | 'onSubscribed'>, options?: SdkWireOptions): SdkBackendHandle;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { SdkWireCore } from './wire-core.js';
|
|
2
|
+
/**
|
|
3
|
+
* 造 SDK 通道后端(每连接一枚——core 即该连接的单连接状态机)。
|
|
4
|
+
*
|
|
5
|
+
* @param deps 装配桥注入面(decideApproval/onSubscribed 两面由本件自持——
|
|
6
|
+
* 幂等账与重推编舞是后端语义不是桥语义)
|
|
7
|
+
* @param options 线核构造选项(时钟/节拍/背压参——透传)
|
|
8
|
+
*/
|
|
9
|
+
export function createSdkBackend(deps, options) {
|
|
10
|
+
/** 未决 ask 账(approvalId → 账项——decide 幂等判据 + 重推面) */
|
|
11
|
+
const pending = new Map();
|
|
12
|
+
/** 后端内 ask 计数(调用方未指派 approvalId 时生成 `sdk-N`——连接内唯一) */
|
|
13
|
+
let askSeq = 0;
|
|
14
|
+
const core = new SdkWireCore({
|
|
15
|
+
...deps,
|
|
16
|
+
// decide 应答:未决账项在册且未决 → 落定回执 applied;unknown/已决 →
|
|
17
|
+
// superseded(跨入口竞速败者——03 §10.6 第三腿幂等语义)
|
|
18
|
+
decideApproval: (approvalId, answer) => {
|
|
19
|
+
const entry = pending.get(approvalId);
|
|
20
|
+
if (entry === undefined || entry.settled)
|
|
21
|
+
return 'superseded';
|
|
22
|
+
entry.settled = true;
|
|
23
|
+
pending.delete(approvalId);
|
|
24
|
+
entry.resolve(answer);
|
|
25
|
+
return 'applied';
|
|
26
|
+
},
|
|
27
|
+
// 订阅受理钩:该会话未决 ask 全量重推(重连后凭 hello 重收 ask 面;
|
|
28
|
+
// 已决者早已出账——重推面天然只含未决)
|
|
29
|
+
onSubscribed: (sessionId) => {
|
|
30
|
+
for (const entry of pending.values()) {
|
|
31
|
+
if (entry.frame.sessionId === sessionId)
|
|
32
|
+
core.pushFrame(entry.frame, sessionId);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
}, options);
|
|
36
|
+
const backend = {
|
|
37
|
+
id: 'sdk',
|
|
38
|
+
// 唯 approval 一位(文件头能力面注)——其余 false 使核降级判定不路由本后端
|
|
39
|
+
capabilities: {
|
|
40
|
+
notify: false,
|
|
41
|
+
confirm: false,
|
|
42
|
+
select: false,
|
|
43
|
+
input: false,
|
|
44
|
+
approval: true,
|
|
45
|
+
setStatus: false,
|
|
46
|
+
setWidget: false,
|
|
47
|
+
},
|
|
48
|
+
// 观众探针:活跃订阅数(零订阅 = 无人接帧 = 无观众)
|
|
49
|
+
hasAudience: () => core.subscriptionCount > 0,
|
|
50
|
+
// 能力位 false——核不扇出本后端(方法在场纯为接口完备)
|
|
51
|
+
notify: () => { },
|
|
52
|
+
// 活体信封直推直播腿(focused 无 SDK 语义——订阅即全量,无聚焦降档)
|
|
53
|
+
onEnvelope: (env) => core.pushEvent(env.sessionId, env.event),
|
|
54
|
+
askApproval: (sessionId, request, opts) => new Promise((resolve) => {
|
|
55
|
+
// fail-closed:该会话无订阅者即结构性无人可答——立即 unavailable
|
|
56
|
+
//(帧不出站;04 §9 无应答者语义,非用户主动取消——与 abort 路分立)
|
|
57
|
+
if (!core.isSubscribed(sessionId)) {
|
|
58
|
+
resolve('unavailable');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const approvalId = request.approvalId ?? `sdk-${++askSeq}`;
|
|
62
|
+
const frame = {
|
|
63
|
+
kind: 'ask',
|
|
64
|
+
sessionId,
|
|
65
|
+
approvalId,
|
|
66
|
+
summary: request.summary,
|
|
67
|
+
...(request.reason !== undefined ? { reason: request.reason } : {}),
|
|
68
|
+
...(request.toolName !== undefined ? { toolName: request.toolName } : {}),
|
|
69
|
+
...(request.suggestedEntry !== undefined ? { suggestedEntry: request.suggestedEntry } : {}),
|
|
70
|
+
};
|
|
71
|
+
const entry = { frame, settled: false, resolve };
|
|
72
|
+
pending.set(approvalId, entry);
|
|
73
|
+
core.pushFrame(frame, sessionId);
|
|
74
|
+
// 败腿撤销(UiCore 竞速先答后 abort 传播位):保守值 cancel(04 §9
|
|
75
|
+
// run 信号透传——用户主动打断语义,不落 unavailable)+ 出账(迟到
|
|
76
|
+
// decide 归 superseded);已决后迟到 abort 是无害 no-op
|
|
77
|
+
opts?.signal?.addEventListener('abort', () => {
|
|
78
|
+
if (entry.settled)
|
|
79
|
+
return;
|
|
80
|
+
entry.settled = true;
|
|
81
|
+
pending.delete(approvalId);
|
|
82
|
+
resolve('cancel');
|
|
83
|
+
}, { once: true });
|
|
84
|
+
}),
|
|
85
|
+
};
|
|
86
|
+
return {
|
|
87
|
+
backend,
|
|
88
|
+
core,
|
|
89
|
+
dispose: () => {
|
|
90
|
+
// 连接收口:在飞 ask 按通道消失语义收场(unavailable——连接断了无观众
|
|
91
|
+
// 可答,ApprovalService 落 timeout 源;用户主动打断走 abort 路 cancel)
|
|
92
|
+
for (const entry of pending.values()) {
|
|
93
|
+
if (entry.settled)
|
|
94
|
+
continue;
|
|
95
|
+
entry.settled = true;
|
|
96
|
+
entry.resolve('unavailable');
|
|
97
|
+
}
|
|
98
|
+
pending.clear();
|
|
99
|
+
core.close();
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.js","sourceRoot":"","sources":["../../../../../../src/channels/sdk/backend.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAE,WAAW,EAAyC,MAAM,gBAAgB,CAAC;AAqBpF;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAA0D,EAC1D,OAAwB;IAExB,mDAAmD;IACnD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC9C,uDAAuD;IACvD,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,MAAM,IAAI,GAAG,IAAI,WAAW,CAC1B;QACE,GAAG,IAAI;QACP,kDAAkD;QAClD,wCAAwC;QACxC,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO;gBAAE,OAAO,YAAY,CAAC;YAC9D,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;YACrB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC3B,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACtB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,4CAA4C;QAC5C,sBAAsB;QACtB,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE;YAC1B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACrC,IAAI,KAAK,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS;oBAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAClF,CAAC;QACH,CAAC;KACF,EACD,OAAO,CACR,CAAC;IAEF,MAAM,OAAO,GAAqB;QAChC,EAAE,EAAE,KAAK;QACT,gDAAgD;QAChD,YAAY,EAAE;YACZ,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,KAAK;YACb,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,KAAK;YAChB,SAAS,EAAE,KAAK;SACjB;QACD,+BAA+B;QAC/B,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,iBAAiB,GAAG,CAAC;QAC7C,iCAAiC;QACjC,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;QAChB,2CAA2C;QAC3C,UAAU,EAAE,CAAC,GAAoB,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC;QAC9E,WAAW,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CACxC,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,EAAE;YACzC,8CAA8C;YAC9C,0CAA0C;YAC1C,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;gBAClC,OAAO,CAAC,aAAa,CAAC,CAAC;gBACvB,OAAO;YACT,CAAC;YACD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;YAC3D,MAAM,KAAK,GAAgB;gBACzB,IAAI,EAAE,KAAK;gBACX,SAAS;gBACT,UAAU;gBACV,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnE,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzE,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC5F,CAAC;YACF,MAAM,KAAK,GAAe,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAC/B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YACjC,gDAAgD;YAChD,4CAA4C;YAC5C,6CAA6C;YAC7C,IAAI,EAAE,MAAM,EAAE,gBAAgB,CAC5B,OAAO,EACP,GAAG,EAAE;gBACH,IAAI,KAAK,CAAC,OAAO;oBAAE,OAAO;gBAC1B,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;gBACrB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC3B,OAAO,CAAC,QAAQ,CAAC,CAAC;YACpB,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;QACJ,CAAC,CAAC;KACL,CAAC;IAEF,OAAO;QACL,OAAO;QACP,IAAI;QACJ,OAAO,EAAE,GAAG,EAAE;YACZ,6CAA6C;YAC7C,yDAAyD;YACzD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACrC,IAAI,KAAK,CAAC,OAAO;oBAAE,SAAS;gBAC5B,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;gBACrB,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YAC/B,CAAC;YACD,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* after 游标对账纯函数(03 篇 §10.6 线协议七原则③ + 05 篇 §3.5 第一腿——
|
|
3
|
+
* durable seq + after 游标 / 崩溃重连对账 / 重放-直播衔接序)。
|
|
4
|
+
*
|
|
5
|
+
* 高水位约定(与 ./protocol.ts 文件头单源同律):**highWaterSeq = 会话日志当前
|
|
6
|
+
* 长度**(= 下一将分配 seq;既存末条 seq = highWaterSeq − 1;空会话 = 0)。
|
|
7
|
+
*
|
|
8
|
+
* 两执法句在该约定下的形态:
|
|
9
|
+
* - 调用方已收末 seq ≥ 高水位 ⇒ 尾被截(撕裂尾截断后 seq 按 log.length 重编
|
|
10
|
+
* **复用**——调用方已收的尾段 seq 在恢复后日志中不存在或被同号异容复用);
|
|
11
|
+
* - `after=N` ≥ 高水位 ⇒ 游标非法(N 越过既存末条 = 声称已收不存在的事件;
|
|
12
|
+
* 含空会话 after=0 档——新会话订阅应缺席 after)。
|
|
13
|
+
* 两档同码 `SDK_CURSOR_INVALID`,调用方从头(或 getEntries)重对账——消费侧
|
|
14
|
+
* 幂等以 dedupeKey 兜底,at-least-once 边界如实。
|
|
15
|
+
*/
|
|
16
|
+
/** 游标对账判定(ok=false 携错误码与报因——调用方落 SDK_CURSOR_INVALID 错误帧) */
|
|
17
|
+
export type CursorCheck = {
|
|
18
|
+
ok: true;
|
|
19
|
+
} | {
|
|
20
|
+
ok: false;
|
|
21
|
+
code: 'SDK_CURSOR_INVALID';
|
|
22
|
+
reason: 'beyond-high-water' | 'tail-truncated';
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* 校验订阅/重放游标 after 的合法性(hello.after 与 getEntries.since 同语义)。
|
|
26
|
+
*
|
|
27
|
+
* 合法 ⇔ after < highWaterSeq(重放窗口 = (after, highWaterSeq];after 恰为
|
|
28
|
+
* 既存末条 seq = 完全追平档——窗口空、直接进直播,亦合法)。
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateAfterCursor(after: number, highWaterSeq: number): CursorCheck;
|
|
31
|
+
/**
|
|
32
|
+
* 崩溃重连尾截断侦测(05 §3.5 崩溃重连对账条——hello/ack 携高水位的消费侧)。
|
|
33
|
+
*
|
|
34
|
+
* @param lastReceivedSeq 调用方已收末条 seq(无对账面〔首连〕传 undefined——恒 ok)
|
|
35
|
+
* @param highWaterSeq 服务端 hello/ack 携带的会话当前高水位
|
|
36
|
+
* @returns 已收末 seq ≥ 高水位 ⇒ 尾被截(含 ==:声称知道下一将分配 seq 同为
|
|
37
|
+
* 幻影——撕裂截断后 seq 复用使等值也歧义,保守同码)
|
|
38
|
+
*/
|
|
39
|
+
export declare function detectTailTruncation(lastReceivedSeq: number | undefined, highWaterSeq: number): CursorCheck;
|
|
40
|
+
/**
|
|
41
|
+
* 重放-直播衔接序定位(05 §3.5 衔接序第 ③ 步——**落码回归锁位**函数化):
|
|
42
|
+
* 直播起播 = 内存日志中 seq > 重放尾(lastReplayedSeq)的首条(含未落库在飞
|
|
43
|
+
* 事件)。重放尾与直播首无缝衔接 = 衔接完整性验收位,测试在册。
|
|
44
|
+
*
|
|
45
|
+
* @param log 会话内存日志(seq 单调连续升序——05 §1.1 写入序不变式)
|
|
46
|
+
* @param lastReplayedSeq 重放段末条 seq(空重放 = after 原值或 −1)
|
|
47
|
+
* @returns 直播起播下标(log.length = 重放已覆盖全部内存日志——直播等新事件)
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveLiveStart<T extends {
|
|
50
|
+
seq: number;
|
|
51
|
+
}>(log: readonly T[], lastReplayedSeq: number): number;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* after 游标对账纯函数(03 篇 §10.6 线协议七原则③ + 05 篇 §3.5 第一腿——
|
|
3
|
+
* durable seq + after 游标 / 崩溃重连对账 / 重放-直播衔接序)。
|
|
4
|
+
*
|
|
5
|
+
* 高水位约定(与 ./protocol.ts 文件头单源同律):**highWaterSeq = 会话日志当前
|
|
6
|
+
* 长度**(= 下一将分配 seq;既存末条 seq = highWaterSeq − 1;空会话 = 0)。
|
|
7
|
+
*
|
|
8
|
+
* 两执法句在该约定下的形态:
|
|
9
|
+
* - 调用方已收末 seq ≥ 高水位 ⇒ 尾被截(撕裂尾截断后 seq 按 log.length 重编
|
|
10
|
+
* **复用**——调用方已收的尾段 seq 在恢复后日志中不存在或被同号异容复用);
|
|
11
|
+
* - `after=N` ≥ 高水位 ⇒ 游标非法(N 越过既存末条 = 声称已收不存在的事件;
|
|
12
|
+
* 含空会话 after=0 档——新会话订阅应缺席 after)。
|
|
13
|
+
* 两档同码 `SDK_CURSOR_INVALID`,调用方从头(或 getEntries)重对账——消费侧
|
|
14
|
+
* 幂等以 dedupeKey 兜底,at-least-once 边界如实。
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* 校验订阅/重放游标 after 的合法性(hello.after 与 getEntries.since 同语义)。
|
|
18
|
+
*
|
|
19
|
+
* 合法 ⇔ after < highWaterSeq(重放窗口 = (after, highWaterSeq];after 恰为
|
|
20
|
+
* 既存末条 seq = 完全追平档——窗口空、直接进直播,亦合法)。
|
|
21
|
+
*/
|
|
22
|
+
export function validateAfterCursor(after, highWaterSeq) {
|
|
23
|
+
if (after >= highWaterSeq) {
|
|
24
|
+
return { ok: false, code: 'SDK_CURSOR_INVALID', reason: 'beyond-high-water' };
|
|
25
|
+
}
|
|
26
|
+
return { ok: true };
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 崩溃重连尾截断侦测(05 §3.5 崩溃重连对账条——hello/ack 携高水位的消费侧)。
|
|
30
|
+
*
|
|
31
|
+
* @param lastReceivedSeq 调用方已收末条 seq(无对账面〔首连〕传 undefined——恒 ok)
|
|
32
|
+
* @param highWaterSeq 服务端 hello/ack 携带的会话当前高水位
|
|
33
|
+
* @returns 已收末 seq ≥ 高水位 ⇒ 尾被截(含 ==:声称知道下一将分配 seq 同为
|
|
34
|
+
* 幻影——撕裂截断后 seq 复用使等值也歧义,保守同码)
|
|
35
|
+
*/
|
|
36
|
+
export function detectTailTruncation(lastReceivedSeq, highWaterSeq) {
|
|
37
|
+
if (lastReceivedSeq === undefined)
|
|
38
|
+
return { ok: true };
|
|
39
|
+
if (lastReceivedSeq >= highWaterSeq) {
|
|
40
|
+
return { ok: false, code: 'SDK_CURSOR_INVALID', reason: 'tail-truncated' };
|
|
41
|
+
}
|
|
42
|
+
return { ok: true };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 重放-直播衔接序定位(05 §3.5 衔接序第 ③ 步——**落码回归锁位**函数化):
|
|
46
|
+
* 直播起播 = 内存日志中 seq > 重放尾(lastReplayedSeq)的首条(含未落库在飞
|
|
47
|
+
* 事件)。重放尾与直播首无缝衔接 = 衔接完整性验收位,测试在册。
|
|
48
|
+
*
|
|
49
|
+
* @param log 会话内存日志(seq 单调连续升序——05 §1.1 写入序不变式)
|
|
50
|
+
* @param lastReplayedSeq 重放段末条 seq(空重放 = after 原值或 −1)
|
|
51
|
+
* @returns 直播起播下标(log.length = 重放已覆盖全部内存日志——直播等新事件)
|
|
52
|
+
*/
|
|
53
|
+
export function resolveLiveStart(log, lastReplayedSeq) {
|
|
54
|
+
const index = log.findIndex((entry) => entry.seq > lastReplayedSeq);
|
|
55
|
+
return index === -1 ? log.length : index;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../../../../../src/channels/sdk/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa,EAAE,YAAoB;IACrE,IAAI,KAAK,IAAI,YAAY,EAAE,CAAC;QAC1B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAChF,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,eAAmC,EAAE,YAAoB;IAC5F,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACvD,IAAI,eAAe,IAAI,YAAY,EAAE,CAAC;QACpC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC7E,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAA4B,GAAiB,EAAE,eAAuB;IACpG,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,GAAG,eAAe,CAAC,CAAC;IACpE,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK 通道后端件内聚合面(channels 通道核第三后端——03 篇 §10.6 件身份条:
|
|
3
|
+
* 协议核心代码位与 channels 通道核同体,UiBackend 多后端接口位既有)。
|
|
4
|
+
*
|
|
5
|
+
* 批 13a 契约先行笔 = 协议词汇/信封 + NDJSON 编解码 + admit/游标纯逻辑;
|
|
6
|
+
* 批 13b = 线协议核心(wire-core 单连接状态机:六动词受理/活体外推/心跳
|
|
7
|
+
* 装配面/出站有界队列背压)+ 后端实装(13b-3)。stdio 传输归宿主 serve
|
|
8
|
+
* (07 §5);HTTP+SSE 与 MCP 包装归 core:sdk 件(src/sdk/ 批 13e)。
|
|
9
|
+
*
|
|
10
|
+
* SDK_ 五码注册在 contracts 错误码注册表 CORE_ERROR_CODES(规范定名码直入
|
|
11
|
+
* contracts 的仓内先例——CHANNEL_/AGENT_ 同款;注册笔系并行会话〔批 12 泳道〕
|
|
12
|
+
* 先行落、本批收编,勿在本件重复注册)。
|
|
13
|
+
*/
|
|
14
|
+
export * from './protocol.js';
|
|
15
|
+
export * from './jsonl.js';
|
|
16
|
+
export * from './admit.js';
|
|
17
|
+
export * from './cursor.js';
|
|
18
|
+
export * from './schema.js';
|
|
19
|
+
export * from './wire-core.js';
|
|
20
|
+
export * from './backend.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK 通道后端件内聚合面(channels 通道核第三后端——03 篇 §10.6 件身份条:
|
|
3
|
+
* 协议核心代码位与 channels 通道核同体,UiBackend 多后端接口位既有)。
|
|
4
|
+
*
|
|
5
|
+
* 批 13a 契约先行笔 = 协议词汇/信封 + NDJSON 编解码 + admit/游标纯逻辑;
|
|
6
|
+
* 批 13b = 线协议核心(wire-core 单连接状态机:六动词受理/活体外推/心跳
|
|
7
|
+
* 装配面/出站有界队列背压)+ 后端实装(13b-3)。stdio 传输归宿主 serve
|
|
8
|
+
* (07 §5);HTTP+SSE 与 MCP 包装归 core:sdk 件(src/sdk/ 批 13e)。
|
|
9
|
+
*
|
|
10
|
+
* SDK_ 五码注册在 contracts 错误码注册表 CORE_ERROR_CODES(规范定名码直入
|
|
11
|
+
* contracts 的仓内先例——CHANNEL_/AGENT_ 同款;注册笔系并行会话〔批 12 泳道〕
|
|
12
|
+
* 先行落、本批收编,勿在本件重复注册)。
|
|
13
|
+
*/
|
|
14
|
+
export * from './protocol.js';
|
|
15
|
+
export * from './jsonl.js';
|
|
16
|
+
export * from './admit.js';
|
|
17
|
+
export * from './cursor.js';
|
|
18
|
+
export * from './schema.js';
|
|
19
|
+
export * from './wire-core.js';
|
|
20
|
+
export * from './backend.js';
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../src/channels/sdk/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK 线协议 NDJSON 编解码(03 篇 §10.6 线协议七原则⑦ 背压与写出纪律——NDJSON
|
|
3
|
+
* 行安全条款;stdio JSONL 传输的帧法真源,HTTP/SSE 腿复用同编解码语义)。
|
|
4
|
+
*
|
|
5
|
+
* 行安全:JSON 串内裸 U+2028(LINE SEPARATOR)/ U+2029(PARAGRAPH SEPARATOR)
|
|
6
|
+
* 在 JSON 合法但按 JS 行终止符语义会被下游 NDJSON 消费方的分行逻辑撕行(Claude
|
|
7
|
+
* gh-28405 实锤)——本编码器序列化后统一转义为 \u2028/\u2029 转义形(结构字符不
|
|
8
|
+
* 可能是这两位,全串替换零误伤);解码侧 JSON.parse 原生还原,无需特判。
|
|
9
|
+
*
|
|
10
|
+
* 校验深度(契约面纪律):本层做判别字段 + 必填标量的结构性校验(fail-loud
|
|
11
|
+
* 宁拒勿吞);逐动词深校验(typebox schema 面——03 §10.6 请求面动词族条
|
|
12
|
+
* 「每动词 typebox schema 校验后消费——webui 微路由同纪律」)在 ./schema.ts
|
|
13
|
+
* 单源、decodeWireLine 尾段接入(批 13e 兑现 13a 挂账)——HTTP 体校验位
|
|
14
|
+
* (core:sdk 件)经 channels 公开面同源消费,零第二套。
|
|
15
|
+
*/
|
|
16
|
+
import type { SdkRequest, SdkWireFrame } from './protocol.js';
|
|
17
|
+
/** 解码失败(fail-loud——坏行不产半帧;线面应答形〔错误帧映射〕归宿主 serve 装配批) */
|
|
18
|
+
export declare class SdkDecodeError extends Error {
|
|
19
|
+
/** 原始行文本(审计面——截断到 200 字符防日志洪水) */
|
|
20
|
+
readonly rawLine: string;
|
|
21
|
+
constructor(message: string,
|
|
22
|
+
/** 原始行文本(审计面——截断到 200 字符防日志洪水) */
|
|
23
|
+
rawLine: string);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 编码单帧为一行(含行尾 `\n`)。出站纪律:序列化 + U+2028/U+2029 转义——
|
|
27
|
+
* 返回值保证恰一个 `\n` 且在末尾(行安全锁,测试在册)。
|
|
28
|
+
*/
|
|
29
|
+
export declare function encodeWireLine(frame: SdkWireFrame | SdkRequest): string;
|
|
30
|
+
/** 值判别:请求(verb 判别字段在闭集内)——非抛型窄卫(消费面路由用) */
|
|
31
|
+
export declare function isSdkRequest(value: unknown): value is SdkRequest;
|
|
32
|
+
/**
|
|
33
|
+
* 解码单行为请求或线帧(fail-loud:非 JSON / 判别缺席 / 必填缺失各自报因,
|
|
34
|
+
* 坏行不产半帧)。行尾 `\r` 容忍(CRLF 传输面统一 LF——与 TUI 输入解码同律)。
|
|
35
|
+
*/
|
|
36
|
+
export declare function decodeWireLine(line: string): SdkWireFrame | SdkRequest;
|
|
37
|
+
/** 分帧结果:完整行列表 + 跨 chunk 残留(无 `\n` 尾的半行,续入下次调用) */
|
|
38
|
+
export interface WireSplit {
|
|
39
|
+
lines: string[];
|
|
40
|
+
remainder: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 流式分帧(stdio 管道跨 chunk 边界的安全分帧):按 `\n` 切行、行尾 `\r` 剥离
|
|
44
|
+
* (CRLF 统一 LF)、空行跳过(心跳间隙的空拍不产帧)。入参 chunk 与上次
|
|
45
|
+
* remainder 拼接后切分;无完整行的 chunk 只进 remainder(零字节丢失、零半帧)。
|
|
46
|
+
*/
|
|
47
|
+
export declare function splitWireLines(chunk: string, remainder?: string): WireSplit;
|