@sema-agent/client-core 0.6.0 → 0.8.0
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 +31 -11
- package/dist/adapt.d.ts +4 -2
- package/dist/adapt.js +225 -25
- package/dist/compensations.d.ts +63 -0
- package/dist/compensations.js +138 -0
- package/dist/detachWire.d.ts +141 -0
- package/dist/detachWire.js +182 -0
- package/dist/diff/patch.d.ts +29 -0
- package/dist/diff/patch.js +45 -0
- package/dist/engineSessionParam.d.ts +11 -0
- package/dist/engineSessionParam.js +41 -0
- package/dist/engineWireTarget.d.ts +14 -0
- package/dist/engineWireTarget.js +53 -0
- package/dist/finalVerifyWire.d.ts +74 -0
- package/dist/finalVerifyWire.js +63 -0
- package/dist/fleet/fleetLedger.d.ts +132 -0
- package/dist/fleet/fleetLedger.js +393 -0
- package/dist/fleet/fleetProjection.d.ts +181 -0
- package/dist/fleet/fleetProjection.js +258 -0
- package/dist/headlessPermissionModeWire.d.ts +55 -0
- package/dist/headlessPermissionModeWire.js +111 -0
- package/dist/headlessReconnectWire.d.ts +96 -0
- package/dist/headlessReconnectWire.js +141 -0
- package/dist/hooksWireCaps.d.ts +91 -0
- package/dist/hooksWireCaps.js +359 -0
- package/dist/host.d.ts +34 -2
- package/dist/host.js +6 -0
- package/dist/index.d.ts +74 -1
- package/dist/index.js +104 -1
- package/dist/interactiveToolsWire.d.ts +48 -0
- package/dist/interactiveToolsWire.js +86 -0
- package/dist/limitsWire.d.ts +89 -0
- package/dist/limitsWire.js +225 -0
- package/dist/liveInitToolFace.d.ts +53 -0
- package/dist/liveInitToolFace.js +251 -0
- package/dist/model/modelFamilies.json +63 -0
- package/dist/model/providerPresets.d.ts +46 -0
- package/dist/model/providerPresets.js +160 -0
- package/dist/model/providerPresets.json +1179 -0
- package/dist/notifications.d.ts +7 -0
- package/dist/notifications.js +32 -0
- package/dist/sandboxWire.d.ts +75 -0
- package/dist/sandboxWire.js +138 -0
- package/dist/scenarioWire.d.ts +62 -0
- package/dist/scenarioWire.js +115 -0
- package/dist/seam.d.ts +52 -5
- package/dist/seam.js +15 -2
- package/dist/subagent/engineCompactWire.d.ts +12 -0
- package/dist/subagent/engineCompactWire.js +176 -0
- package/dist/subagent/engineDelegatedPrompt.d.ts +44 -0
- package/dist/subagent/engineDelegatedPrompt.js +205 -0
- package/dist/subagent/engineRowStopGate.d.ts +18 -0
- package/dist/subagent/engineRowStopGate.js +54 -0
- package/dist/subagent/engineSubagentOutput.d.ts +15 -0
- package/dist/subagent/engineSubagentOutput.js +98 -0
- package/dist/subagent/engineSubagentSteer.d.ts +10 -0
- package/dist/subagent/engineSubagentSteer.js +68 -0
- package/dist/subagent/engineSubagentTail.d.ts +40 -0
- package/dist/subagent/engineSubagentTail.js +241 -0
- package/dist/subagent/engineTaskHandleWire.d.ts +90 -0
- package/dist/subagent/engineTaskHandleWire.js +212 -0
- package/dist/toolResult.d.ts +118 -0
- package/dist/toolResult.js +774 -0
- package/dist/workflowClient.d.ts +42 -0
- package/dist/workflowClient.js +467 -0
- package/dist/workflowMonitor.d.ts +94 -0
- package/dist/workflowMonitor.js +43 -0
- package/package.json +5 -3
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ⇄ B6 批搬迁(2026-07-27,设计稿 §3 B6):子代 wire 族里**逐字重复**的 `wireConfig()`
|
|
3
|
+
* (SEMA_LIVE_BASEURL / SEMA_LIVE_TOKEN / SEMA_LIVE_PRINCIPAL 三读 + 'anon:shell-live' 缺省)
|
|
4
|
+
* 收成一份。
|
|
5
|
+
*
|
|
6
|
+
* 🔴 收编前的事实(壳 HEAD 2aa1d3e 实测,`grep -rln 'function wireConfig' src/sema/`):
|
|
7
|
+
* **七**份而不是六份 —— `engineSubagentOutput.ts:30` · `engineSubagentSteer.ts:26` ·
|
|
8
|
+
* `engineTaskHandleWire.ts:40` · `engineCompactWire.ts:77` · `engineSubagentTail.ts:40` ·
|
|
9
|
+
* `engineDelegatedPrompt.ts:80` · **`planReviewWire.ts:36`**。
|
|
10
|
+
* ⚠️ 本批搬入的是前六份(子代/fleet 族);**第七份 `planReviewWire` 不在 B6 范围**,仍留壳内
|
|
11
|
+
* —— 它是下一批的收编候选,别以为已经收干净了(这条更正即为「按名字数数会数漏」的实例)。
|
|
12
|
+
* 七份漂移不是假想:`engineCompactWire` 那份已经多了一行 principal 注释,`engineSubagentSteer`
|
|
13
|
+
* 那份 token 读法与其它几份的 `...(cfg.token ? …)` spread 姿势不同步。
|
|
14
|
+
*
|
|
15
|
+
* 🔴 env 读取走 `hostEnv()`(本包零 `process` —— portability 门盯着)。Node 下 `hostEnv()` 返回的
|
|
16
|
+
* 就是 `process.env` 那个同一对象 ⇒ 壳侧行为一字节不变;浏览器宿主返回 `{}` ⇒ `baseUrl`
|
|
17
|
+
* 缺席 ⇒ 每个 verb 走自己既有的「无 wire」回落路径(不是报错)。
|
|
18
|
+
* ⚠️ web/桌面宿主要用这条 wire,**不能靠 env** —— 用 `installEngineWireTarget()` 显式装。
|
|
19
|
+
*/
|
|
20
|
+
import { hostEnv } from './hostEnv.js';
|
|
21
|
+
/** 显式装配(非 Node 宿主唯一的入口;装了就**优先于** env,便于桌面/web 一页多引擎)。 */
|
|
22
|
+
let installed = null;
|
|
23
|
+
/** 装/卸引擎 wire 目标。传 null 卸回 env 派生。返回还原函数。 */
|
|
24
|
+
export function installEngineWireTarget(t) {
|
|
25
|
+
const prev = installed;
|
|
26
|
+
installed = t;
|
|
27
|
+
return () => {
|
|
28
|
+
installed = prev;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 当前引擎 wire 目标。null = 无 wire(离线/mock/浏览器未装)—— 调用方走各自的回落路径,
|
|
33
|
+
* **不是**错误态。
|
|
34
|
+
*/
|
|
35
|
+
export function engineWireTarget() {
|
|
36
|
+
if (installed !== null)
|
|
37
|
+
return installed;
|
|
38
|
+
const env = hostEnv();
|
|
39
|
+
const baseUrl = env.SEMA_LIVE_BASEURL;
|
|
40
|
+
if (!baseUrl)
|
|
41
|
+
return null;
|
|
42
|
+
return {
|
|
43
|
+
baseUrl,
|
|
44
|
+
// principal must match the run's owner (stamped by the live stream) — the owner-gated routes answer
|
|
45
|
+
// 404 for non-owners (no existence oracle), so a missing header reads as "run not found".
|
|
46
|
+
...(env.SEMA_LIVE_TOKEN ? { token: env.SEMA_LIVE_TOKEN } : {}),
|
|
47
|
+
principal: env.SEMA_LIVE_PRINCIPAL ?? 'anon:shell-live',
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** 诊断开关(壳侧 `process.env.SEMA_DEBUG` 的等价读;本包零 process)。 */
|
|
51
|
+
export function engineWireDebugEnabled() {
|
|
52
|
+
return Boolean(hostEnv().SEMA_DEBUG);
|
|
53
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/sema/finalVerifyWire.ts — headless `-p` finalVerification wire (TB2.0 反馈批 A · P1-1, 2026-07-15):
|
|
3
|
+
* stamp the ENGINE-EXISTING `TaskRequest.finalVerification` field on the headless `-p` path, DEFAULT ON.
|
|
4
|
+
*
|
|
5
|
+
* WHY: TB2.0 无人值守回归里 14/19 题 agent 自认完成判 0(写完不验/即兴自测即收尾)。引擎的
|
|
6
|
+
* finalVerification stop-gate(core runtask.js:1429-1493 —— 最多追加 2 条 '[final verification]'
|
|
7
|
+
* system-reminder,wroteThisRun && 非 structured-output && 未贴 maxTurns 才触发)+ server wire
|
|
8
|
+
* (http/server.js:3711 校验 / main.js:1383 转发)早已在线,壳侧从未 stamp——本模块补上这最后一段 wire。
|
|
9
|
+
*
|
|
10
|
+
* PRECEDENCE(off 优先,任何一条命中即不 stamp;否则默认 true):
|
|
11
|
+
* a) `--no-final-verify` flag → off(一键回上游 2.1.207 严格对齐态:上游
|
|
12
|
+
* `-p` 全文 0 处 final verification,默认开属超集;上游对应扩展点是 Stop hook)。
|
|
13
|
+
* b) `SEMA_HEADLESS_FINAL_VERIFY` env('false'/'0') → off。settings.json `env` 块 → 1a-envseed →
|
|
14
|
+
* process.env,其它 wire 配置(SEMA_HEADLESS_SCENARIO 等)同一车道。
|
|
15
|
+
* c) 用户配置了 Stop hook(settings hooks.Stop,经 hooksForWire 投影)→ off【对抗轮硬性 amendment】:
|
|
16
|
+
* 引擎 finalVerification 分支在 Stop hook 查询之前 return(runtask.js:1430-1443),默认开会把
|
|
17
|
+
* 用户 Stop hook 延迟至多 2 turn——对上游迁移来的 hook 用户是真行为变化,故有 Stop hook 即让位。
|
|
18
|
+
* d) 都没有 → true(TB 默认态吃满终验闸杠杆)。
|
|
19
|
+
*
|
|
20
|
+
* LIVE-GATE:与 scenarioWire 同款——调用点(seamQueryEngine.ask)以 SEMA_LIVE_BASEURL 为门,
|
|
21
|
+
* mock/pty fixture 车道永不 stamp 该字段(离线投影字节等价)。
|
|
22
|
+
*
|
|
23
|
+
* 语义澄清(分诊报告):finalVerification 是同会话 stop-gate 追加,不是独立上下文 verifier;
|
|
24
|
+
* 纯读任务(wroteThisRun gate)与 structured-output 任务被 core 自身豁免,回归面天然收窄。
|
|
25
|
+
*/
|
|
26
|
+
import type { SemaSettings } from '@sema-agent/sdk';
|
|
27
|
+
import { type EnvLike } from './hostEnv.js';
|
|
28
|
+
/**
|
|
29
|
+
* B5:`hooksWireCaps` 的宿主耦合半场(settings 三层合并 + trust 门)还没搬,但这个**纯类型**
|
|
30
|
+
* 先落本包 —— 它就是 SDK 的 `settings.hooks`,与 hooksWireCaps 无耦合。
|
|
31
|
+
* 🔴 hooksWireCaps 后续进包时 **import 本条**,别再定义第二份(两份类型 = 漂移温床)。
|
|
32
|
+
*/
|
|
33
|
+
export type WireHooksConfig = NonNullable<SemaSettings['hooks']>;
|
|
34
|
+
/** Settings-lane env knob(settings.json `env` 块 → 1a-envseed → process.env)。'false'/'0' = off。 */
|
|
35
|
+
export declare const HEADLESS_FINAL_VERIFY_ENV = "SEMA_HEADLESS_FINAL_VERIFY";
|
|
36
|
+
/**
|
|
37
|
+
* Parse `--no-final-verify` out of an argv slice(everything before a bare `--` — positionals are
|
|
38
|
+
* never flags,scenarioWire 同款纪律)。Boolean flag,无值形态,重复无害。
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseNoFinalVerifyArgv(argv: string[]): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* The settings-lane off-switch:`SEMA_HEADLESS_FINAL_VERIFY` = 'false' or '0'(case-insensitive)
|
|
43
|
+
* disables the stamp。其它任何值(含空串/'true'/typo)= 默认态 on——fail-soft:一个 settings typo
|
|
44
|
+
* 只会落回默认开,绝不 brick 任何 run(scenarioWire 的 settings-lane 纪律)。
|
|
45
|
+
*/
|
|
46
|
+
export declare function headlessFinalVerifyDisabledByEnv(env?: EnvLike): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* 用户 Stop hook 在场判定:hooksForWire() 投影(policy→user→project→local 合并、trust/managed 门后)
|
|
49
|
+
* 里 `Stop` 事件带 ≥1 个 matcher 组即认定。判定输入用 wire 投影而非裸 settings——被 trust/
|
|
50
|
+
* disableAllHooks 门掉的 Stop hook 引擎侧同样不会 fire,不构成让位理由。
|
|
51
|
+
*/
|
|
52
|
+
export declare function hasUserStopHook(wireHooks: WireHooksConfig | undefined): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Resolve the finalVerification stamp for a headless `-p` submit:默认 true;
|
|
55
|
+
* `--no-final-verify` flag / SEMA_HEADLESS_FINAL_VERIFY=false|0 / 用户 Stop hook 在场 → false。
|
|
56
|
+
* 调用点必须 live-gate(SEMA_LIVE_BASEURL)——mock/offline 形状不变。
|
|
57
|
+
*/
|
|
58
|
+
export declare function resolveHeadlessFinalVerify(argv: string[], env?: EnvLike, wireHooks?: WireHooksConfig): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* #106 裁 B(clay 2026-07-26):让位维持 + 诚实告知。detail 形暴露 off 原因供调用点分诊 ——
|
|
61
|
+
* flag/env 关闭是用户显式意愿(不聒噪);`stop-hook` 让位是用户**没显式要求**的关闭
|
|
62
|
+
* (Stop hook 可能来自 /goal 自注册或 settings hook),必须告知(修前静默,用户不知道自己
|
|
63
|
+
* 失去了终验)。方向注记:finalVerification 后续默认关(CC Stop hook 机制同,不叠超集)——
|
|
64
|
+
* 见记忆 final-verification-direction;届时本函数的默认臂翻转,detail 形不动。
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveHeadlessFinalVerifyDetail(argv: string[], env?: EnvLike, wireHooks?: WireHooksConfig): {
|
|
67
|
+
on: boolean;
|
|
68
|
+
offReason?: 'flag' | 'env' | 'stop-hook';
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* stop-hook 让位的告知文案(单一措辞源;stderr 一行)。措辞纪律与 hook_notice 同族:
|
|
72
|
+
* 「让位/接管」向,绝不写「守卫失效」向 —— 后者会让用户以为链路坏了。
|
|
73
|
+
*/
|
|
74
|
+
export declare const FINAL_VERIFY_YIELD_NOTICE = "final verification is off for this run \u2014 a Stop hook is active and takes over end-of-turn gating (it would otherwise be delayed by up to 2 turns)";
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { hostEnv } from './hostEnv.js';
|
|
2
|
+
/** Settings-lane env knob(settings.json `env` 块 → 1a-envseed → process.env)。'false'/'0' = off。 */
|
|
3
|
+
export const HEADLESS_FINAL_VERIFY_ENV = 'SEMA_HEADLESS_FINAL_VERIFY';
|
|
4
|
+
/**
|
|
5
|
+
* Parse `--no-final-verify` out of an argv slice(everything before a bare `--` — positionals are
|
|
6
|
+
* never flags,scenarioWire 同款纪律)。Boolean flag,无值形态,重复无害。
|
|
7
|
+
*/
|
|
8
|
+
export function parseNoFinalVerifyArgv(argv) {
|
|
9
|
+
for (const a of argv) {
|
|
10
|
+
if (a === '--')
|
|
11
|
+
break; // positionals — never flags
|
|
12
|
+
if (a === '--no-final-verify')
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The settings-lane off-switch:`SEMA_HEADLESS_FINAL_VERIFY` = 'false' or '0'(case-insensitive)
|
|
19
|
+
* disables the stamp。其它任何值(含空串/'true'/typo)= 默认态 on——fail-soft:一个 settings typo
|
|
20
|
+
* 只会落回默认开,绝不 brick 任何 run(scenarioWire 的 settings-lane 纪律)。
|
|
21
|
+
*/
|
|
22
|
+
export function headlessFinalVerifyDisabledByEnv(env = hostEnv()) {
|
|
23
|
+
const v = env[HEADLESS_FINAL_VERIFY_ENV]?.trim().toLowerCase();
|
|
24
|
+
return v === 'false' || v === '0';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 用户 Stop hook 在场判定:hooksForWire() 投影(policy→user→project→local 合并、trust/managed 门后)
|
|
28
|
+
* 里 `Stop` 事件带 ≥1 个 matcher 组即认定。判定输入用 wire 投影而非裸 settings——被 trust/
|
|
29
|
+
* disableAllHooks 门掉的 Stop hook 引擎侧同样不会 fire,不构成让位理由。
|
|
30
|
+
*/
|
|
31
|
+
export function hasUserStopHook(wireHooks) {
|
|
32
|
+
const groups = wireHooks?.['Stop'];
|
|
33
|
+
return Array.isArray(groups) && groups.length > 0;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the finalVerification stamp for a headless `-p` submit:默认 true;
|
|
37
|
+
* `--no-final-verify` flag / SEMA_HEADLESS_FINAL_VERIFY=false|0 / 用户 Stop hook 在场 → false。
|
|
38
|
+
* 调用点必须 live-gate(SEMA_LIVE_BASEURL)——mock/offline 形状不变。
|
|
39
|
+
*/
|
|
40
|
+
export function resolveHeadlessFinalVerify(argv, env = hostEnv(), wireHooks) {
|
|
41
|
+
return resolveHeadlessFinalVerifyDetail(argv, env, wireHooks).on;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* #106 裁 B(clay 2026-07-26):让位维持 + 诚实告知。detail 形暴露 off 原因供调用点分诊 ——
|
|
45
|
+
* flag/env 关闭是用户显式意愿(不聒噪);`stop-hook` 让位是用户**没显式要求**的关闭
|
|
46
|
+
* (Stop hook 可能来自 /goal 自注册或 settings hook),必须告知(修前静默,用户不知道自己
|
|
47
|
+
* 失去了终验)。方向注记:finalVerification 后续默认关(CC Stop hook 机制同,不叠超集)——
|
|
48
|
+
* 见记忆 final-verification-direction;届时本函数的默认臂翻转,detail 形不动。
|
|
49
|
+
*/
|
|
50
|
+
export function resolveHeadlessFinalVerifyDetail(argv, env = hostEnv(), wireHooks) {
|
|
51
|
+
if (parseNoFinalVerifyArgv(argv))
|
|
52
|
+
return { on: false, offReason: 'flag' };
|
|
53
|
+
if (headlessFinalVerifyDisabledByEnv(env))
|
|
54
|
+
return { on: false, offReason: 'env' };
|
|
55
|
+
if (hasUserStopHook(wireHooks))
|
|
56
|
+
return { on: false, offReason: 'stop-hook' };
|
|
57
|
+
return { on: true };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* stop-hook 让位的告知文案(单一措辞源;stderr 一行)。措辞纪律与 hook_notice 同族:
|
|
61
|
+
* 「让位/接管」向,绝不写「守卫失效」向 —— 后者会让用户以为链路坏了。
|
|
62
|
+
*/
|
|
63
|
+
export const FINAL_VERIFY_YIELD_NOTICE = 'final verification is off for this run — a Stop hook is active and takes over end-of-turn gating (it would otherwise be delayed by up to 2 turns)';
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ⇄ B6 批搬迁(2026-07-27,设计稿 §3 B6 + §2.5 拆缝表):cli `src/sema/fleetClient.ts` 的
|
|
3
|
+
* **帧消费半场** —— `applyFrame` 的帧体 upsert + own/foreign 判别 + `recordOwnEngineRun` /
|
|
4
|
+
* `recordBgParentRun` / `recordBgTerminalFacts` 台账三写 + `retained` 终态留存池 + 帧间时钟
|
|
5
|
+
* 补偿 + 模块级 bg 读面(`readEngineActiveBgTasks` / `isFleetSessionScoped`)。
|
|
6
|
+
*
|
|
7
|
+
* 留在 TUI(设计稿 §2.4.2-B):`AgentClient` 构造与 consume/重连循环 · `main` 合成行 ·
|
|
8
|
+
* `selection` 游标 · `viewed` 的所有者(AppState)· `SEMA_DEBUG_FILE` 行字段落盘探针 ·
|
|
9
|
+
* hook_notice 的**写 store** 半场(判定在 notifications.ts,本文件只做分发)。
|
|
10
|
+
*
|
|
11
|
+
* ── B6 三处删债(每条都有直证,不是「看起来能删」)──────────────────────────────────────────
|
|
12
|
+
*
|
|
13
|
+
* 🔴 **P1-4 / `makeSessionScopingFetch` 退役**:壳里为了给 fleet 流塞 `?session=` 注了一个自定义
|
|
14
|
+
* `fetch`(fleetClient.ts:201-227,注入点 :604)—— 归属过滤是最不该留在端上的东西。SDK 0.0.117
|
|
15
|
+
* `fleet.stream({ session })` / `fleet.snapshot({ session })` 已是一等参数(`resources/fleet.d.ts`
|
|
16
|
+
* 实读),本包出 `fleetStreamOptions()` 直接给出那个参数,**壳侧删掉整个 fetch 包装器**。
|
|
17
|
+
*
|
|
18
|
+
* 🔴 **G12 / `rowSessionTag` 整条删(比任务书说的更彻底,附直证)**:任务书写「ownerSessionId /
|
|
19
|
+
* rootSessionId 防御读删」。实测 server **1.291.0** `dist/http/server.js` 的 `streamFleet`:
|
|
20
|
+
* ```js
|
|
21
|
+
* const stripT = (r) => { const { scope: _s, sessionId: _sid, ...rest } = r; … }
|
|
22
|
+
* const stripW = (r) => { const { scope: _s, sessionId: _sid, ...rest } = r; … }
|
|
23
|
+
* ```
|
|
24
|
+
* ⇒ task/workflow **行**上 `scope` 与 `sessionId` **双双被剥**,而 `rootSessionId`/`ownerSessionId`
|
|
25
|
+
* 在 `FleetTaskRow`/`FleetWorkflowRow` 里**从来就不存在**(server 自己的 `fleet-bus.d.ts` 实读)。
|
|
26
|
+
* ⇒ `rowSessionTag(row)` 三个键**全部恒 undefined**,整条腿是死的 —— 不是「删两个键留一个」。
|
|
27
|
+
* 后果方向核过:这条腿在 `ownTaskRow` 里是**放行**位(命中即判 own),死 ⇒ 从不放行 ⇒ 删掉
|
|
28
|
+
* **零可观测差异**(其余两腿:祖链 own-run 台账 / `sessionScoped` 让位,原样保留)。
|
|
29
|
+
* ⚠️ 对照:`bg_notification` 帧上 server 只剥 `ownerScope`/`ownerSessionId`,**`rootSessionId`
|
|
30
|
+
* 与 `sessionId` 照发** ⇒ 通知臂的 `ownByRoot` 那条腿**是活的,保留**。同一个名字两条腿、
|
|
31
|
+
* 一死一活 —— 这正是「判据锚在决定结果的量上」要求逐条核而不是按名字一刀切的地方。
|
|
32
|
+
*
|
|
33
|
+
* 🔴 **G19 / 一次性快照**:`fleet.snapshot({session})` 已是 SDK 一等 verb(开流→取 snapshot 帧→
|
|
34
|
+
* 关流封装),壳的 `engineBgProbe.ts:8-9` 自述「引擎 fleet 面只有 SSE,没有一次性口」已过期。
|
|
35
|
+
* 本包出 `fleetSnapshotOptions()`;`engineBgProbe` 的手抄开流即断由壳侧换 verb(见交接报告)。
|
|
36
|
+
*
|
|
37
|
+
* ── 单实例纪律 ────────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
* `liveBgViews` 是 module 级 Set:写者 = 每个 `createFleetLedger()`,读者 = 引擎温切门
|
|
39
|
+
* (`readEngineActiveBgTasks`)与代际让位读面(`isFleetSessionScoped`)。两份实例 = 温切门恒读空
|
|
40
|
+
* ⇒ respawn 会静默杀掉在飞 bg 子代。
|
|
41
|
+
*/
|
|
42
|
+
import type { FleetFrame, FleetTaskRow } from '@sema-agent/sdk';
|
|
43
|
+
import { type FleetTaskView, type FleetWorkflowView, type ProjectTasksOptions } from './fleetProjection.js';
|
|
44
|
+
/** 终态行留存宽限窗(187 的 agents 页把完成会话留在列表;窗过即净,防长会话堆行)。 */
|
|
45
|
+
export declare const TERMINAL_RETAIN_MS = 60000;
|
|
46
|
+
export interface EngineActiveBgTask {
|
|
47
|
+
id: string;
|
|
48
|
+
name?: string;
|
|
49
|
+
status: string;
|
|
50
|
+
/** fleet 行的 parentId(spawn 该子代的 run 行 id;顶层 run 行缺席)—— killed 残局合成通知的
|
|
51
|
+
* own/foreign 判别用。 */
|
|
52
|
+
parentId?: string;
|
|
53
|
+
}
|
|
54
|
+
export interface EngineActiveBgReading {
|
|
55
|
+
tasks: EngineActiveBgTask[];
|
|
56
|
+
/** true = 至少一条 fleet 流当前连着(读数新鲜);false = 断线期 last-known(可能 stale)或无 live 源。 */
|
|
57
|
+
fresh: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* server 代际证据读面:任一 live fleet 源的 meta 报过 `sessionScoped=true`。
|
|
61
|
+
* true ⇒ 到达本连接的**行帧**已经过 server 会话过滤,端侧行级 own 判别可以让位。
|
|
62
|
+
* 🔴 只覆盖【行帧】:通知帧的 own-run 台账判别不看本标,恒开(1.244 对缺 ownerSessionId 的通知
|
|
63
|
+
* 仍广播,fail-closed 是 1.245+)。
|
|
64
|
+
*/
|
|
65
|
+
export declare function isFleetSessionScoped(): boolean;
|
|
66
|
+
/** 引擎侧在飞 bg 子代读数(union 所有未 dispose 的源,按 row.id 去重)。无 live 源 ⇒ `{[], false}`。 */
|
|
67
|
+
export declare function readEngineActiveBgTasks(): EngineActiveBgReading;
|
|
68
|
+
/**
|
|
69
|
+
* 清空所有 live 源的终态留存池 —— 会话切换(/clear、REPL 内 resume、fork)信号一到就调。
|
|
70
|
+
* R7:留存池是渲染层宽限窗,快照臂刻意不清它(重连不该抽走行);但换了会话继续渲上一会话的
|
|
71
|
+
* 终态行(名字 = objective 派生)就是跨会话残影。
|
|
72
|
+
*/
|
|
73
|
+
export declare function clearAllRetainedFleetRows(): void;
|
|
74
|
+
/** 测试钩:摘掉所有登记的视图(同进程多组断言之间互不污染)。 */
|
|
75
|
+
export declare function __resetFleetLedgerRegistryForTests(): void;
|
|
76
|
+
/**
|
|
77
|
+
* `client.fleet.stream(...)` 的会话过滤参数。缺席(端未装 SessionPort / 还没有会话 id)⇒ `{}`
|
|
78
|
+
* = principal 级视图,**与 1.37 之前逐字同行为**(不是错误态)。
|
|
79
|
+
*/
|
|
80
|
+
export declare function fleetStreamOptions(): {
|
|
81
|
+
session?: string;
|
|
82
|
+
};
|
|
83
|
+
/** G19:`client.fleet.snapshot(...)` 的参数(同上;首屏/温切探针用)。 */
|
|
84
|
+
export declare function fleetSnapshotOptions(opts?: {
|
|
85
|
+
timeoutMs?: number;
|
|
86
|
+
}): {
|
|
87
|
+
session?: string;
|
|
88
|
+
timeoutMs?: number;
|
|
89
|
+
};
|
|
90
|
+
export interface FleetLedgerHooks {
|
|
91
|
+
/**
|
|
92
|
+
* hook_notice 帧的**写 store** 半场(判定在 `classifyHookNoticeFrame`,本台账只做分发)。
|
|
93
|
+
* 返回值忽略;不给 = 该帧被静默丢弃(端没有承载面时的正确行为)。
|
|
94
|
+
*/
|
|
95
|
+
onHookNotice?(frame: unknown, sessionScoped: boolean): void;
|
|
96
|
+
}
|
|
97
|
+
export interface FleetLedgerStatus {
|
|
98
|
+
connected: boolean;
|
|
99
|
+
version: number | null;
|
|
100
|
+
scoped: boolean | null;
|
|
101
|
+
sessionScoped: boolean | undefined;
|
|
102
|
+
bgNotifyFailClosed: boolean;
|
|
103
|
+
taskCount: number;
|
|
104
|
+
workflowCount: number;
|
|
105
|
+
}
|
|
106
|
+
export interface FleetLedger {
|
|
107
|
+
/** 消费一帧(consumer-side active-set update-in-place / remove)。 */
|
|
108
|
+
applyFrame(frame: FleetFrame): void;
|
|
109
|
+
/** 连接态由宿主的 consume 循环告知(台账自己不开流)。 */
|
|
110
|
+
setConnected(v: boolean): void;
|
|
111
|
+
/**
|
|
112
|
+
* 把当前 Map 投影成渲染行。`nowMs` 驱动帧间时钟补偿与留存池过期。
|
|
113
|
+
* `rowFilter` 必填(端专属决策,见 fleetProjection 头注)。
|
|
114
|
+
*/
|
|
115
|
+
project(nowMs: number, opts: ProjectTasksOptions & {
|
|
116
|
+
/** 正在被查看的行不过期(用户读报告中途被抽走=清障变添堵)。 */
|
|
117
|
+
viewingTaskId?: string | undefined;
|
|
118
|
+
}): {
|
|
119
|
+
tasks: FleetTaskView[];
|
|
120
|
+
workflows: FleetWorkflowView[];
|
|
121
|
+
};
|
|
122
|
+
status(): FleetLedgerStatus;
|
|
123
|
+
/** 摘掉模块级读面登记(宿主 dispose 时必调,否则温切门读到僵尸源)。 */
|
|
124
|
+
dispose(): void;
|
|
125
|
+
/** 测试直取:当前 task 行原样(顺序 = 插入序)。 */
|
|
126
|
+
__rowsForTest(): FleetTaskRow[];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 建一个 fleet 帧台账。**不开流、不构造 client** —— 宿主的 consume 循环把解码后的帧喂进来。
|
|
130
|
+
* (这条切缝就是设计稿 §2.5 给 fleetClient 划的那一刀:帧体归库、连接归端。)
|
|
131
|
+
*/
|
|
132
|
+
export declare function createFleetLedger(hooks?: FleetLedgerHooks): FleetLedger;
|