@sema-agent/server 7.144.0 → 7.145.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/MIGRATION.md +129 -0
- package/README.md +3 -0
- package/README.zh-CN.md +1 -0
- package/USAGE.md +16 -8
- package/dist/audit.d.ts +2 -21
- package/dist/audit.js +0 -9
- package/dist/boot/session-faces.d.ts +1 -1
- package/dist/boot/session-faces.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +1 -1
- package/dist/boot/stage-10-http-server.d.ts +1 -1
- package/dist/boot/stage-10-http-server.js +2 -2
- package/dist/config-d-migration.d.ts +3 -2
- package/dist/fleet/fleet-bus.d.ts +13 -3
- package/dist/fleet/fleet-bus.js +17 -3
- package/dist/http/admission.js +2 -1
- package/dist/http/checkpoint-ctx.d.ts +1 -0
- package/dist/http/checkpoint-ctx.js +1 -0
- package/dist/http/durable-run-leg.js +7 -6
- package/dist/http/resume-legs.js +5 -3
- package/dist/http/route-ctx.d.ts +15 -0
- package/dist/http/routes/approvals-assistant.d.ts +20 -1
- package/dist/http/routes/approvals-assistant.js +27 -6
- package/dist/http/routes/rules.d.ts +1 -1
- package/dist/http/routes/rules.js +5 -2
- package/dist/http/routes/session-sync.js +12 -0
- package/dist/http/routes/tasks.js +12 -9
- package/dist/http/run-meta.d.ts +14 -7
- package/dist/http/run-meta.js +5 -2
- package/dist/http/server.d.ts +13 -5
- package/dist/http/server.js +3 -0
- package/dist/http/submit-ctx.d.ts +12 -0
- package/dist/http/submit-ctx.js +23 -0
- package/dist/observability/fail-open.d.ts +15 -3
- package/dist/observability/fail-open.js +15 -3
- package/dist/plugins/approval-ask-store-file.d.ts +16 -2
- package/dist/plugins/approval-ask-store-file.js +21 -1
- package/dist/plugins/approval-ask-store-memory.d.ts +8 -2
- package/dist/plugins/approval-ask-store-memory.js +11 -8
- package/dist/plugins/caching-session-store.d.ts +3 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +29 -11
- package/dist/plugins/checkpoint-store-sql.js +38 -16
- package/dist/plugins/file-run-store.d.ts +13 -1
- package/dist/plugins/file-run-store.js +11 -1
- package/dist/plugins/local-checkpoint-store.d.ts +14 -3
- package/dist/plugins/local-checkpoint-store.js +23 -5
- package/dist/plugins/local-session-store.d.ts +52 -16
- package/dist/plugins/local-session-store.js +47 -14
- package/dist/plugins/memory-run-store.d.ts +2 -0
- package/dist/plugins/memory-run-store.js +6 -0
- package/dist/plugins/one-time-migrations.js +2 -2
- package/dist/plugins/run-store-sql.d.ts +4 -0
- package/dist/plugins/run-store-sql.js +3 -0
- package/dist/plugins/session-store.d.ts +1 -1
- package/dist/prompt-screen.d.ts +21 -0
- package/dist/prompt-screen.js +8 -0
- package/dist/rules-consent.d.ts +63 -51
- package/dist/rules-consent.js +6 -10
- package/dist/run-acceptance.d.ts +40 -10
- package/dist/run-acceptance.js +38 -5
- package/dist/runs.js +1 -1
- package/dist/security.d.ts +10 -3
- package/dist/session-agent.d.ts +39 -0
- package/dist/session-agent.js +16 -0
- package/dist/session-error-wire.d.ts +4 -4
- package/dist/trace/model-segment.d.ts +3 -2
- package/dist/trace/model-segment.js +16 -8
- package/dist/trace/redact.d.ts +66 -2
- package/dist/trace/redact.js +220 -101
- package/dist/trace/self-minted-wire.d.ts +73 -1
- package/dist/trace/self-minted-wire.js +27 -0
- package/package.json +2 -2
- package/wire-changes/server@7.145.0.json +146 -0
|
@@ -39,7 +39,7 @@ function release(s) {
|
|
|
39
39
|
return s.text.takeSettled();
|
|
40
40
|
}
|
|
41
41
|
catch (err) {
|
|
42
|
-
recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.
|
|
42
|
+
recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.length} err=${errorKindOf(err)}`);
|
|
43
43
|
return "";
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -48,20 +48,28 @@ function deliverBlock(s) {
|
|
|
48
48
|
return s.text.takeAll();
|
|
49
49
|
}
|
|
50
50
|
catch (err) {
|
|
51
|
-
recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.
|
|
51
|
+
recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.length} err=${errorKindOf(err)}`);
|
|
52
52
|
s.text.skip();
|
|
53
53
|
return OVERSIZED_REDACTION_PLACEHOLDER;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
+
function closeBlock(s) {
|
|
57
|
+
try {
|
|
58
|
+
s.text.endBlock();
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.length} err=${errorKindOf(err)}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
56
64
|
function remainderOf(family, s) {
|
|
57
65
|
try {
|
|
58
66
|
const r = s.text.flush();
|
|
59
67
|
if (r.diverged)
|
|
60
|
-
recordFailOpen("server.live-text.hold-diverged", `family=${family} len=${s.text.
|
|
68
|
+
recordFailOpen("server.live-text.hold-diverged", `family=${family} len=${s.text.length}`);
|
|
61
69
|
return r.rest;
|
|
62
70
|
}
|
|
63
71
|
catch (err) {
|
|
64
|
-
recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.
|
|
72
|
+
recordFailOpen("server.run-terminal.redact-threw", `live-hold len=${s.text.length} err=${errorKindOf(err)}`);
|
|
65
73
|
return OVERSIZED_REDACTION_PLACEHOLDER;
|
|
66
74
|
}
|
|
67
75
|
}
|
|
@@ -69,7 +77,7 @@ export function createLiveModelText() {
|
|
|
69
77
|
const open = { text: new Map(), reasoning: new Map() };
|
|
70
78
|
const deltaType = (family) => (family === "text" ? "text_delta" : "reasoning_delta");
|
|
71
79
|
const openSegment = (family, key, ident, deliver) => {
|
|
72
|
-
const s = { ident, text: createRedactionStream(), delivering: deliver
|
|
80
|
+
const s = { ident, text: createRedactionStream(), delivering: deliver };
|
|
73
81
|
open[family].set(key, s);
|
|
74
82
|
return s;
|
|
75
83
|
};
|
|
@@ -131,8 +139,8 @@ export function createLiveModelText() {
|
|
|
131
139
|
if (ev.type === "text_end") {
|
|
132
140
|
let s = open.text.get(key);
|
|
133
141
|
const out = [];
|
|
134
|
-
const before = s === undefined ? "" : s.text.
|
|
135
|
-
const arrived = s === undefined ? "" : s.text.
|
|
142
|
+
const before = s === undefined ? "" : s.text.blockContext();
|
|
143
|
+
const arrived = s === undefined ? "" : s.text.blockBytes();
|
|
136
144
|
const unfed = blockText(arrived, ev).slice(arrived.length);
|
|
137
145
|
const endOnly = unfed !== "" ? unfed : undefined;
|
|
138
146
|
if (s === undefined && endOnly !== undefined)
|
|
@@ -151,7 +159,7 @@ export function createLiveModelText() {
|
|
|
151
159
|
if (rest !== "" && endOnly === undefined)
|
|
152
160
|
out.push({ type: "text_delta", delta: rest, ...liveIdentityFields(s.ident) });
|
|
153
161
|
}
|
|
154
|
-
s
|
|
162
|
+
closeBlock(s);
|
|
155
163
|
}
|
|
156
164
|
const end = deliver ? textEndEventData(ev, before) : null;
|
|
157
165
|
if (end !== null)
|
package/dist/trace/redact.d.ts
CHANGED
|
@@ -38,6 +38,10 @@ export declare function armPoolBudgetForTest(): {
|
|
|
38
38
|
readings: number;
|
|
39
39
|
coverageVisits: number;
|
|
40
40
|
rowVisits: number;
|
|
41
|
+
scannedUnits: number;
|
|
42
|
+
windowAdvances: number;
|
|
43
|
+
windowRefusals: number;
|
|
44
|
+
windowEvaluations: number;
|
|
41
45
|
};
|
|
42
46
|
export declare function resetArmPoolBudgetForTest(): void;
|
|
43
47
|
/**
|
|
@@ -99,6 +103,23 @@ export declare function structuralScannerForTest(arm: "json-secret-field" | "pem
|
|
|
99
103
|
/** 测试可见:扫描器 indexOf 实际扫过的字节数(摊还线性 ⇒ ≤ 常数 × 输入长)。 */
|
|
100
104
|
export declare function ppkScanBytesForTest(): number;
|
|
101
105
|
export declare function resetPpkScanBytesForTest(): void;
|
|
106
|
+
/**
|
|
107
|
+
* 🔴 **一条臂向前读多远**(候选池成员身份的必填一格 {@link MemberIdentity.prior};闭集两形,读者一律穷尽 `switch`)—— 流式口扫描窗的两张字母表
|
|
108
|
+
* (地平线不数的间隔码元、被丢前缀里不许有的定界字面)由这一格现算({@link STREAM_WINDOW_ALPHABETS}),窗不另持一份。
|
|
109
|
+
* · `bounded`:判定一个位置时向前读的部分有界 —— 判定距离之内({@link MemberIdentity.reach})、同一行之内,或隔着构造两部分之间一段**任意长**的间隔 run;
|
|
110
|
+
* `gap` 答「哪些码元可以出现在这段间隔里」(按码元判,原文读法 `json = false` —— 流式口只这样读)。没有任意长间隔的臂给 {@link NO_GAP}。
|
|
111
|
+
* 正则臂由构造者现算:词法关键字臂 = 它的分隔段类({@link KeywordTail.isSeparator},造正则的同一份类源);其余正则臂的「无界原子之后还有必需的东西」在
|
|
112
|
+
* {@link regexDecisionReach} 已加载期抛 ⇒ 没有间隔。手写扫描器给它自己读间隔时调的那只谓词(同一只函数,不抄字符表)。
|
|
113
|
+
* · `anchored`:读**整段之前任意远**的前文(孤立收尾栅栏看「之前有过起始栅栏」、无头体起于前面某一枚收尾之后),但只从这几枚**字面锚**起读 —— 容器的定界字面;
|
|
114
|
+
* 前文里没有它们,这条臂就没有可读的前文。间隔不必声明:窗不越过任何一枚字面锚(这一形的构造整只在锚之后)。
|
|
115
|
+
*/
|
|
116
|
+
export type PriorReading = {
|
|
117
|
+
readonly kind: "bounded";
|
|
118
|
+
readonly gap: (unit: number) => boolean;
|
|
119
|
+
} | {
|
|
120
|
+
readonly kind: "anchored";
|
|
121
|
+
readonly anchors: readonly [string, ...string[]];
|
|
122
|
+
};
|
|
102
123
|
/** Redact unambiguous secret formats from reasoning/CoT before it is persisted to the durable trace log. */
|
|
103
124
|
/** S24 (SILENT-FALLBACK P1): optional redaction observer — rewrites previously had zero fingerprint, so
|
|
104
125
|
* over-redaction (mangling legit content) and under-redaction (a pattern that never fires) were both
|
|
@@ -165,7 +186,7 @@ export declare const WHOLE_EXTENT: RedactionExtent;
|
|
|
165
186
|
* `from`:出门区与余量**各自从自己的起点数**(窗 = 出门区〔从头数半窗〕+ 余量〔从出门区终点起再数半窗〕),不是各自从头数「第一个 ≥ units 的终点」—— 后者遇到不可见填充会按翻倍
|
|
166
187
|
* 跳到同一个终点,余量塌成 0,被窗尾切开的凭据在出门区里露出半截(修复验证 r3 high)。
|
|
167
188
|
* 取舍:不可见填充很大的文本,窗随之延伸(最坏延伸到整段 = 整段读法的代价),换来「窗里的读法单元数恒 ≥ `units`」这一个不变量 —— 窗里每一读的视图都不短于 `units`。
|
|
168
|
-
* 终点不落在转义写法中间:前缀末尾还没写完的转义写法({@link
|
|
189
|
+
* 终点不落在转义写法中间:前缀末尾还没写完的转义写法(转义写法读者的截断读数,在读法后文本上判,{@link shortestReading})不计数、窗延伸到它写完 —— 出门区终点与窗尾都因此落在转义的边上,余量从干净的边起数。
|
|
169
190
|
* 复杂度:**第一趟**若可见占比 ≥ 一半(少量换行 / 色码)按占比补足缺口,均匀的文本一两趟落在终点附近;补不足(或占比低)的趟一律至少翻倍 —— 总趟数 O(log 终点)、总功 O(终点),
|
|
170
191
|
* 不存在逐趟只前进几个码元的爬行(4095 个可见 + 4000 个控制字符曾因此平方,K=4000 约 0.2–0.3 s)。判据与读法格同源(同一批切除点收集器,零第二份「什么算不可见」)。
|
|
171
192
|
*/
|
|
@@ -254,6 +275,23 @@ export declare function pendingTailReachForTest(): ReadonlyArray<{
|
|
|
254
275
|
readonly order: number;
|
|
255
276
|
readonly reach: number;
|
|
256
277
|
}>;
|
|
278
|
+
/** 测试可见:扫描窗的两张字母表 —— 全池成员的声明再加 `extra`(造一条新臂的声明),与生产同一只派生、同一份自证(不成立照样抛)。 */
|
|
279
|
+
export declare function streamWindowAlphabetsForTest(extra?: readonly PriorReading[]): {
|
|
280
|
+
readonly isBlank: (unit: number) => boolean;
|
|
281
|
+
readonly containerDelimiters: readonly string[];
|
|
282
|
+
};
|
|
283
|
+
/** 测试可见:转义写法文法本身 —— `read(s)` = 读者对 `s`(引导 run 起头)的读数(码点 / `-1` 读不出 / `-2` 截断)与写法末尾;`isBodyUnit` = 字面锚自证读的那只本体谓词。 */
|
|
284
|
+
export declare function escapeGrammarForTest(): {
|
|
285
|
+
readonly read: (s: string) => {
|
|
286
|
+
readonly value: number;
|
|
287
|
+
readonly end: number;
|
|
288
|
+
};
|
|
289
|
+
readonly isBodyUnit: (unit: number) => boolean;
|
|
290
|
+
};
|
|
291
|
+
/** 测试可见:扫描窗的前移点候选(`-1` = 窗尾有一枚还没写完的转义写法;`0` = 没有),字母表按全池成员的声明再加 `extra` 现算({@link streamWindowAlphabetsForTest})。 */
|
|
292
|
+
export declare function windowAdvancePointForTest(text: string, units: number, extra?: readonly PriorReading[]): number;
|
|
293
|
+
/** 测试可见:扫描窗前移点的认证(生产里 `q` 恒是行首;单测拿非行首的 `q` 钉住「名字在 `q` 之前、值在 `q` 之后」「跨度横跨 `q`」两形各自被认证挡下)。 */
|
|
294
|
+
export declare function windowIndependentAtForTest(text: string, q: number): boolean;
|
|
257
295
|
/**
|
|
258
296
|
* 🔴 **流式口 —— 同一只脱敏器的三口**(live 面逐块到达的模型文本 `text_delta` / `reasoning_delta` 的唯一放行器;登记册在 `trace/model-segment.ts`)。
|
|
259
297
|
* 同一只 {@link runRedaction}、同一张表,只多一件事:知道文本还在长。
|
|
@@ -268,6 +306,20 @@ export declare function pendingTailReachForTest(): ReadonlyArray<{
|
|
|
268
306
|
* 读错的那一形在冲刷时现形(`diverged`),调用方响亮留痕。
|
|
269
307
|
* 延迟上界:一个字节在它之后又到 {@link PENDING_TAIL_UNITS} 个读法单元之后的下一次重扫时交出;盖住它的跨度判定之前(或冲刷之前)不交出。
|
|
270
308
|
* 不喂观察者(`observe:false`,与影子重扫同口):命中只在段末那一次整段脱敏里计(段末帧的铸点),逐块重扫不重复计数。扫描器抛 ⇒ 原样抛(放行位不动)。
|
|
309
|
+
*
|
|
310
|
+
* 🔴 **扫描窗**(多块长段的扫描量;与上面「押在窗里的字节」的窗不是一回事 —— 那是还没交出的未决尾,这是判定要读的前文):一段里每个块的交付点都要「前文 + 本块」一起判(锚在前一块、值在这一块),整段重扫则一段 N 块的总扫描量随 N 平方涨。流式口因此只留判定还需要的那一截前文 ——
|
|
311
|
+
* **扫描窗** = 全段的一个后缀 `[base, 全段长)`:取已判定前缀、交付点与前文({@link RedactionStream.blockContext})都只在窗上扫;只有收尾冲刷仍是整段一遍(一段一次),窗若曾判错,对不上在这里现形(`diverged`)。
|
|
312
|
+
* 扫描窗只在块界({@link RedactionStream.endBlock})前移,前移点 `q` 同时满足:① 是行首(其前一码元是换行 —— 行内向左读的臂不会读过它);② 其后至少留
|
|
313
|
+
* {@link STREAM_WINDOW_HORIZON} × 未决尾个**非空白**读法单元({@link windowAdvancePoint}:任何判定距离之内的候选与它们的证据邻居都在窗里;键与冒号已到、值的起引号还隔着一段任意长的空白在后文里的锚,
|
|
314
|
+
* 此刻不显现为任何跨度,只有「后文接在窗尾」能补全它 —— 空白不挤掉它们);③ 已交出到段尾(没有未交出的字节落在 `q` 之前);
|
|
315
|
+
* ④ 被丢的前缀里没有容器类臂的定界字面({@link STREAM_WINDOW_ALPHABETS} 的 `containerDelimiters`:孤立收尾、无头体、「前面有过起始栅栏」读的是整段之前任意远的前文);
|
|
316
|
+
* ⑤ 经 {@link windowIndependentAt} 认证(head 读法下:没有跨度横跨 `q`;从 `q` 起单独扫的跨度与整窗里同一截逐条相同)。
|
|
317
|
+
* 没有满足这五条的点(没有换行的超长单行、一枚始终没收尾的多块结构、整段里出现过密钥栅栏 / PuTTY 密钥头、整窗只有一行 …)⇒ 窗不动、读法不变,代价退回「窗长」(= 与改前同阶)。扫描窗能前移时,每块的扫描量是 O(块长 + 地平线 + 最长行),与段长无关。
|
|
318
|
+
* 🔴 **五条规则健全的三条前提,都由构造成立、不靠手抄**(臂集一变,窗随之变;没有一份要人记得同步的镜像):
|
|
319
|
+
* ① 每条臂任意长间隔里的字符,地平线都不数 —— 地平线不数的字符**就是**全池 `bounded` 声明的间隔之并({@link STREAM_WINDOW_ALPHABETS},{@link PriorReading});
|
|
320
|
+
* ② 读整段之前任意远前文的臂,都只从字面锚起读,窗不越过这些字面 —— 定界字面表**就是**全池 `anchored` 声明的字面锚之并(加载期自证每枚字面对删除单调:字面里没有一读会删的码元、首码元不是转义写法本体能读进的码元;不成立即抛);
|
|
321
|
+
* ③ 读法里「多码元、补全后消失」的写法只有转义写法,窗尾的半枚由**同一只**转义写法读者判({@link readEscapeElement} 的截断读数,{@link collectSpelledCuts} 的 `open`)—— 文法一份,新写法只改一处。
|
|
322
|
+
* 原生代理对拼成的星平面格式字符已到的那一半只占一个读法单元,撑不起地平线;原生控制字符逐码元删(不是一串整只消失)。
|
|
271
323
|
*/
|
|
272
324
|
export interface RedactionStream {
|
|
273
325
|
/** 喂入下一块原文。 */
|
|
@@ -283,10 +335,22 @@ export interface RedactionStream {
|
|
|
283
335
|
};
|
|
284
336
|
/** 跳过:已喂入的字节不再交出(没有收件人;tail 面没人在听时),之后的判定仍按整段上下文。 */
|
|
285
337
|
skip(): void;
|
|
286
|
-
/**
|
|
338
|
+
/** 块界:已喂入的字节到此为一块(引擎的 `text_end`)。扫描窗在此尝试前移;之后的 {@link RedactionStream.blockContext} / {@link RedactionStream.blockBytes} 从这里起算。认证扫描抛 ⇒ 原样抛(块界已记、窗不动)。 */
|
|
339
|
+
endBlock(): void;
|
|
340
|
+
/** 本块**之前**的前文(扫描窗内那一截;只作判定上下文,`text_end` 的正文接它判)。 */
|
|
341
|
+
blockContext(): string;
|
|
342
|
+
/** 本块已到的字节(上一个块界之后喂入的)。 */
|
|
343
|
+
blockBytes(): string;
|
|
344
|
+
/** 已喂入的整段原文(扫描窗之前丢出去的前缀也在;读时拼接)。 */
|
|
287
345
|
readonly fed: string;
|
|
346
|
+
/** 已喂入的整段长度(码元)。 */
|
|
347
|
+
readonly length: number;
|
|
288
348
|
}
|
|
289
349
|
export declare function createRedactionStream(): RedactionStream;
|
|
350
|
+
/** 测试可见:同一只流式口,扫描窗永不前移(= 改前的读法:每次扫描都读整段)—— 差分钉用它当参照,断言有窗与无窗交出的帧逐字节相同。 */
|
|
351
|
+
export declare function createRedactionStreamWithoutWindowForTest(): RedactionStream;
|
|
352
|
+
/** 测试可见:同一只流式口,前移点的认证换成调用方给的函数(造「认证扫描抛」的形:真扫描器造不出来;断言抛出后窗与块界的状态一个字节没改)。 */
|
|
353
|
+
export declare function createRedactionStreamWithCertifierForTest(certify: (text: string, q: number) => boolean): RedactionStream;
|
|
290
354
|
/** 测试可见:同一只流式口,未决尾按调用方给的数(比 {@link PENDING_TAIL_UNITS} 小 ⇒ 律被打破的那一形,冲刷时 `diverged` 现形 —— 响亮臂的触发器;生产调用方只有上面那一只)。 */
|
|
291
355
|
export declare function createRedactionStreamWithTailForTest(units: number): RedactionStream;
|
|
292
356
|
/**
|