@sema-agent/server 7.77.0 → 7.78.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/approval-card.d.ts +24 -1
- package/dist/approval-card.js +13 -0
- package/dist/boot/resolve-spec.js +3 -0
- package/dist/boot/runner-deps.js +3 -1
- package/dist/config-catalog.js +1 -0
- package/dist/config-center/read-warnings.d.ts +10 -1
- package/dist/config-center/read-warnings.js +5 -1
- package/dist/config-provider.js +2 -2
- package/dist/config-types.d.ts +13 -1
- package/dist/config.js +2 -1
- package/dist/http/routes/approvals-assistant.d.ts +22 -0
- package/dist/http/routes/approvals-assistant.js +4 -1
- package/dist/http/routes/tasks.js +14 -9
- package/dist/http/routes/workflows.js +7 -1
- package/dist/http/server.d.ts +28 -4
- package/dist/http/server.js +47 -13
- package/dist/observability/fail-open.d.ts +4 -0
- package/dist/observability/fail-open.js +4 -0
- package/dist/observability/run-terminal-log.js +1 -0
- package/dist/orchestration/workflow-agent-session-index.d.ts +7 -3
- package/dist/parked-decide.d.ts +27 -12
- package/dist/parked-decide.js +1 -1
- package/dist/plugins/workflow-run-store-sql.d.ts +7 -3
- package/dist/request-key-closure.d.ts +30 -0
- package/dist/request-key-closure.js +56 -0
- package/dist/runs.js +3 -1
- package/dist/runtime-governance.d.ts +18 -4
- package/dist/runtime-governance.js +2 -2
- package/dist/spec-fields.d.ts +3 -1
- package/dist/spec-fields.js +4 -5
- package/dist/task-settings.d.ts +18 -16
- package/dist/task-settings.js +17 -29
- package/dist/tool-approval.d.ts +35 -3
- package/dist/tool-approval.js +41 -19
- package/dist/trace/core-keyset-guard.d.ts +8 -8
- package/dist/trace/ledger-events.d.ts +7 -1
- package/dist/trace/ledger-sink.js +19 -6
- package/dist/trace/model-segment.d.ts +32 -2
- package/dist/trace/model-segment.js +16 -6
- package/dist/trace/project.d.ts +95 -3
- package/dist/trace/project.js +128 -12
- package/dist/trace/redact.js +159 -13
- package/package.json +4 -4
package/dist/trace/project.js
CHANGED
|
@@ -78,10 +78,13 @@ export function aggregateModelUsage(events) {
|
|
|
78
78
|
}
|
|
79
79
|
function identityFields(src) {
|
|
80
80
|
return {
|
|
81
|
-
...(src.eventId ? { eventId:
|
|
82
|
-
...(src.parentToolCallId ? { parentToolCallId:
|
|
81
|
+
...(identityKey(src.eventId) !== undefined ? { eventId: identityKey(src.eventId) } : {}),
|
|
82
|
+
...(identityKey(src.parentToolCallId) !== undefined ? { parentToolCallId: identityKey(src.parentToolCallId) } : {}),
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
|
+
function identityKey(v) {
|
|
86
|
+
return typeof v === "string" && v !== "" ? v : undefined;
|
|
87
|
+
}
|
|
85
88
|
export function modelTextEventData(ev) {
|
|
86
89
|
return { text: ev.text, ...(ev.eventId ? { eventId: ev.eventId } : {}) };
|
|
87
90
|
}
|
|
@@ -110,8 +113,12 @@ function screenedGateOrThrow(v) {
|
|
|
110
113
|
recordFailOpen("server.trace.gate-outcome-defective", "disposition is not one of the two arms");
|
|
111
114
|
return undefined;
|
|
112
115
|
}
|
|
116
|
+
const classifierFallbackRaw = d.classifier !== null && typeof d.classifier === "object" ? d.classifier.fallback : undefined;
|
|
113
117
|
const shapeDefect = (d.kind === "denied" && typeof d.deniedBy !== "string" && "disposition.deniedBy is not a string") ||
|
|
114
118
|
(d.kind === "denied" && d.cause !== undefined && typeof d.cause !== "string" && "disposition.cause is not a string") ||
|
|
119
|
+
(d.classifier !== undefined && (d.classifier === null || typeof d.classifier !== "object") && "disposition.classifier is not an object") ||
|
|
120
|
+
(classifierFallbackRaw !== undefined && (classifierFallbackRaw === null || typeof classifierFallbackRaw !== "object") && "disposition.classifier.fallback is not an object") ||
|
|
121
|
+
(classifierFallbackRaw !== undefined && classifierFallbackRaw !== null && typeof classifierFallbackRaw === "object" && typeof classifierFallbackRaw.cause !== "string" && "disposition.classifier.fallback.cause is not a string") ||
|
|
115
122
|
(g.settlement !== undefined && (g.settlement === null || typeof g.settlement !== "object") && "settlement is not an object") ||
|
|
116
123
|
(g.settlement !== undefined && g.settlement !== null && typeof g.settlement.kind !== "string" && "settlement.kind is not a string") ||
|
|
117
124
|
(g.origin !== undefined && typeof g.origin !== "string" && "origin is not a string") ||
|
|
@@ -125,6 +132,16 @@ function screenedGateOrThrow(v) {
|
|
|
125
132
|
recordFailOpen("server.trace.gate-outcome-defective", defects.join("; "));
|
|
126
133
|
return undefined;
|
|
127
134
|
}
|
|
135
|
+
const attribution = d.classifier;
|
|
136
|
+
const classifier = attribution === undefined
|
|
137
|
+
? undefined
|
|
138
|
+
: {
|
|
139
|
+
modelRequested: attribution.modelRequested,
|
|
140
|
+
modelUsed: attribution.modelUsed,
|
|
141
|
+
...(attribution.fallback === undefined
|
|
142
|
+
? {}
|
|
143
|
+
: { fallback: { from: attribution.fallback.from, to: attribution.fallback.to, cause: attribution.fallback.cause } }),
|
|
144
|
+
};
|
|
128
145
|
const settlement = g.settlement === undefined ? undefined : projectSettlement(g.settlement);
|
|
129
146
|
if (g.settlement !== undefined && settlement === undefined) {
|
|
130
147
|
recordFailOpen("server.trace.gate-outcome-defective", "settlement.who is not an object with a party in the closed set");
|
|
@@ -132,8 +149,8 @@ function screenedGateOrThrow(v) {
|
|
|
132
149
|
}
|
|
133
150
|
return {
|
|
134
151
|
disposition: d.kind === "denied"
|
|
135
|
-
? { kind: "denied", deniedBy: d.deniedBy, ...(d.cause === undefined ? {} : { cause: d.cause }) }
|
|
136
|
-
: { kind: "allowed" },
|
|
152
|
+
? { kind: "denied", deniedBy: d.deniedBy, ...(d.cause === undefined ? {} : { cause: d.cause }), ...(classifier === undefined ? {} : { classifier }) }
|
|
153
|
+
: { kind: "allowed", ...(classifier === undefined ? {} : { classifier }) },
|
|
137
154
|
...(settlement === undefined ? {} : { settlement }),
|
|
138
155
|
...(g.origin === undefined ? {} : { origin: g.origin }),
|
|
139
156
|
};
|
|
@@ -178,15 +195,17 @@ export function textEndEventData(ev) {
|
|
|
178
195
|
return null;
|
|
179
196
|
return segmentEndFields(ev.content, ev);
|
|
180
197
|
}
|
|
181
|
-
function
|
|
198
|
+
export function liveIdentityFields(ev) {
|
|
182
199
|
return {
|
|
183
|
-
|
|
184
|
-
...(ev.
|
|
185
|
-
...(ev.
|
|
186
|
-
...(ev.
|
|
187
|
-
...(ev.bgAgentId !== undefined ? { bgAgentId: ev.bgAgentId } : {}),
|
|
200
|
+
...(identityKey(ev.eventId) !== undefined ? { eventId: identityKey(ev.eventId) } : {}),
|
|
201
|
+
...(identityKey(ev.parentToolCallId) !== undefined ? { parentToolCallId: identityKey(ev.parentToolCallId) } : {}),
|
|
202
|
+
...(identityKey(ev.sourceTaskId) !== undefined ? { sourceTaskId: identityKey(ev.sourceTaskId) } : {}),
|
|
203
|
+
...(identityKey(ev.bgAgentId) !== undefined ? { bgAgentId: identityKey(ev.bgAgentId) } : {}),
|
|
188
204
|
};
|
|
189
205
|
}
|
|
206
|
+
function segmentEndFields(content, ev) {
|
|
207
|
+
return { content: redactModelText(content), ...liveIdentityFields(ev) };
|
|
208
|
+
}
|
|
190
209
|
export function reasoningEndEventData(ev) {
|
|
191
210
|
if (typeof ev.content !== "string" || ev.content.trim().length === 0)
|
|
192
211
|
return null;
|
|
@@ -210,6 +229,43 @@ export function toolEndEventData(ev) {
|
|
|
210
229
|
...identityFields(ev),
|
|
211
230
|
};
|
|
212
231
|
}
|
|
232
|
+
const dropProjectedFace = (what) => {
|
|
233
|
+
recordFailOpen("server.trace.projection-input-malformed", what);
|
|
234
|
+
return undefined;
|
|
235
|
+
};
|
|
236
|
+
export function toolProgressEventData(ev) {
|
|
237
|
+
const id = typeof ev.toolCallId === "string" && ev.toolCallId !== "" ? ev.toolCallId : undefined;
|
|
238
|
+
const name = typeof ev.toolName === "string" && ev.toolName !== "" ? ev.toolName : undefined;
|
|
239
|
+
if (id === undefined || name === undefined)
|
|
240
|
+
return dropProjectedFace("tool_progress is missing toolCallId/toolName");
|
|
241
|
+
const n = (v) => (typeof v === "number" && Number.isFinite(v) ? v : undefined);
|
|
242
|
+
const hasOutput = typeof ev.output === "string";
|
|
243
|
+
return {
|
|
244
|
+
toolCallId: id,
|
|
245
|
+
toolName: name,
|
|
246
|
+
...(n(ev.elapsedTimeSeconds) !== undefined ? { elapsedTimeSeconds: n(ev.elapsedTimeSeconds) } : {}),
|
|
247
|
+
...(hasOutput ? { output: redactDeep(ev.output) } : {}),
|
|
248
|
+
...(hasOutput && n(ev.totalLines) !== undefined ? { totalLines: n(ev.totalLines) } : {}),
|
|
249
|
+
...(hasOutput && n(ev.totalBytes) !== undefined ? { totalBytes: n(ev.totalBytes) } : {}),
|
|
250
|
+
...identityFields(ev),
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
export function toolDisclosureEventData(ev) {
|
|
254
|
+
const policy = typeof ev.policy === "string" && ev.policy !== "" ? ev.policy : undefined;
|
|
255
|
+
const names = (v) => (Array.isArray(v) ? v.filter((x) => typeof x === "string" && x !== "") : undefined);
|
|
256
|
+
const deferred = names(ev.deferred);
|
|
257
|
+
const activated = names(ev.activated);
|
|
258
|
+
if (policy === undefined || deferred === undefined || activated === undefined)
|
|
259
|
+
return dropProjectedFace("tool_disclosure is missing policy/deferred/activated");
|
|
260
|
+
const threshold = typeof ev.thresholdPercent === "number" && Number.isFinite(ev.thresholdPercent) ? ev.thresholdPercent : undefined;
|
|
261
|
+
return {
|
|
262
|
+
policy,
|
|
263
|
+
...(threshold !== undefined ? { thresholdPercent: threshold } : {}),
|
|
264
|
+
deferred,
|
|
265
|
+
activated,
|
|
266
|
+
...identityFields(ev),
|
|
267
|
+
};
|
|
268
|
+
}
|
|
213
269
|
export function taskProgressEventData(ev) {
|
|
214
270
|
return {
|
|
215
271
|
taskId: ev.taskId,
|
|
@@ -390,6 +446,41 @@ export function wiringManifestEventData(ev) {
|
|
|
390
446
|
})();
|
|
391
447
|
const toolsIn = m.tools;
|
|
392
448
|
const tools = toolsIn === undefined ? undefined : Value.Check(ToolRoster, toolsIn) ? toolsIn : (recordFailOpen("server.trace.tool-roster-malformed", "wiring_manifest.tools did not fit core ToolRoster"), undefined);
|
|
449
|
+
const hooksIn = m.hooks;
|
|
450
|
+
const hooks = (() => {
|
|
451
|
+
if (hooksIn === undefined)
|
|
452
|
+
return undefined;
|
|
453
|
+
if (!Array.isArray(hooksIn))
|
|
454
|
+
return dropProjectedFace("wiring_manifest.hooks is not an array");
|
|
455
|
+
const rows = [];
|
|
456
|
+
for (const raw of hooksIn) {
|
|
457
|
+
const e = sec(raw);
|
|
458
|
+
if (e === undefined) {
|
|
459
|
+
dropProjectedFace("wiring_manifest.hooks[] row is not an object");
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
const family = str(e.family);
|
|
463
|
+
const owner = str(e.owner);
|
|
464
|
+
if (family === undefined || owner === undefined) {
|
|
465
|
+
dropProjectedFace("wiring_manifest.hooks[] row is missing family/owner");
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
rows.push({ family, owner, ...(e.observational === true ? { observational: true } : {}) });
|
|
469
|
+
}
|
|
470
|
+
return rows.length > 0 ? rows : undefined;
|
|
471
|
+
})();
|
|
472
|
+
const lspIn = sec(m.lsp);
|
|
473
|
+
const lsp = (() => {
|
|
474
|
+
if (m.lsp === undefined)
|
|
475
|
+
return undefined;
|
|
476
|
+
if (lspIn === undefined)
|
|
477
|
+
return dropProjectedFace("wiring_manifest.lsp is not an object");
|
|
478
|
+
const mounted = bool(lspIn.mounted);
|
|
479
|
+
if (mounted === undefined)
|
|
480
|
+
return dropProjectedFace("wiring_manifest.lsp.mounted is not a boolean");
|
|
481
|
+
const lane = str(lspIn.lane);
|
|
482
|
+
return { mounted, ...(lane === undefined ? {} : { lane }) };
|
|
483
|
+
})();
|
|
393
484
|
const mcpIn = m.mcp;
|
|
394
485
|
const mcp = (() => {
|
|
395
486
|
if (!Array.isArray(mcpIn))
|
|
@@ -430,6 +521,8 @@ export function wiringManifestEventData(ev) {
|
|
|
430
521
|
...(autoMode !== undefined ? { autoMode } : {}),
|
|
431
522
|
...(tools !== undefined ? { tools } : {}),
|
|
432
523
|
...(mcp !== undefined ? { mcp } : {}),
|
|
524
|
+
...(hooks !== undefined ? { hooks } : {}),
|
|
525
|
+
...(lsp !== undefined ? { lsp } : {}),
|
|
433
526
|
...identityFields(ev),
|
|
434
527
|
};
|
|
435
528
|
}
|
|
@@ -505,8 +598,7 @@ export function compactedEventData(ev) {
|
|
|
505
598
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
506
599
|
})();
|
|
507
600
|
return {
|
|
508
|
-
...(ev
|
|
509
|
-
...(ev.parentToolCallId !== undefined ? { parentToolCallId: ev.parentToolCallId } : {}),
|
|
601
|
+
...identityFields(ev),
|
|
510
602
|
...(typeof ev.trigger === "string" ? { trigger: ev.trigger } : {}),
|
|
511
603
|
...(num(ev.tokensBefore) !== undefined ? { tokensBefore: num(ev.tokensBefore) } : {}),
|
|
512
604
|
...(ev.preserved_segment?.firstKeptEntryId ? { preserved_segment: { firstKeptEntryId: ev.preserved_segment.firstKeptEntryId } } : {}),
|
|
@@ -535,9 +627,32 @@ export function contextUsageEventData(ev) {
|
|
|
535
627
|
...(n(ev.usedTokens) !== undefined ? { usedTokens: n(ev.usedTokens) } : {}),
|
|
536
628
|
...(n(ev.windowTokens) !== undefined ? { windowTokens: n(ev.windowTokens) } : {}),
|
|
537
629
|
...(n(ev.compactAtTokens) !== undefined ? { compactAtTokens: n(ev.compactAtTokens) } : {}),
|
|
630
|
+
...contextUsageSectionsField(ev.sections),
|
|
538
631
|
...identityFields(ev),
|
|
539
632
|
};
|
|
540
633
|
}
|
|
634
|
+
function contextUsageSectionsField(sections) {
|
|
635
|
+
if (sections === undefined)
|
|
636
|
+
return {};
|
|
637
|
+
if (!Array.isArray(sections)) {
|
|
638
|
+
dropProjectedFace("context_usage.sections is not an array");
|
|
639
|
+
return {};
|
|
640
|
+
}
|
|
641
|
+
const out = [];
|
|
642
|
+
for (const raw of sections) {
|
|
643
|
+
if (typeof raw !== "object" || raw === null) {
|
|
644
|
+
dropProjectedFace("context_usage.sections[] element is not an object");
|
|
645
|
+
continue;
|
|
646
|
+
}
|
|
647
|
+
const { id, tokens, kind } = raw;
|
|
648
|
+
if (typeof id !== "string" || id === "" || typeof tokens !== "number" || !Number.isFinite(tokens)) {
|
|
649
|
+
dropProjectedFace("context_usage.sections[] element is missing id/tokens");
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
out.push({ id, tokens, ...(typeof kind === "string" && kind !== "" ? { kind } : {}) });
|
|
653
|
+
}
|
|
654
|
+
return out.length > 0 ? { sections: out } : {};
|
|
655
|
+
}
|
|
541
656
|
export function turnEndEventData(ev) {
|
|
542
657
|
return {
|
|
543
658
|
...(ev.usage ? { usage: ev.usage } : {}),
|
|
@@ -711,6 +826,7 @@ function mapTraceEventInner(type, seq, data) {
|
|
|
711
826
|
case "wiring_manifest":
|
|
712
827
|
case "human_input":
|
|
713
828
|
case "tool_roster_delta":
|
|
829
|
+
case "tool_disclosure":
|
|
714
830
|
return null;
|
|
715
831
|
default:
|
|
716
832
|
return null;
|
package/dist/trace/redact.js
CHANGED
|
@@ -233,12 +233,150 @@ let anyValueArm;
|
|
|
233
233
|
function anyValueArmRe() {
|
|
234
234
|
return (anyValueArm ??= new RegExp(`(?:${VALUE_ARM_BODIES.join("|")})`, "y"));
|
|
235
235
|
}
|
|
236
|
-
|
|
236
|
+
const HEAD_CLASS_ESCAPES = new Set(["d", "D", "w", "W", "s", "S"]);
|
|
237
|
+
const HEAD_LITERAL_ESCAPES = new Set(["\\", "/", "-", ".", "+", "*", "?", "(", ")", "[", "]", "{", "}", "|", "^", "$"]);
|
|
238
|
+
function headOfAtoms(atoms, src) {
|
|
239
|
+
const tail = atoms[atoms.length - 1];
|
|
240
|
+
if (tail === undefined || !tail.unbounded || tail.cls === undefined) {
|
|
241
|
+
throw new Error(`redact: arm-pool pattern /${src}/ must end in a greedy unbounded single-class value run`);
|
|
242
|
+
}
|
|
243
|
+
let pos = 0;
|
|
244
|
+
let head = 0;
|
|
245
|
+
for (let k = 0; k < atoms.length - 1; k++) {
|
|
246
|
+
const a = atoms[k];
|
|
247
|
+
if (a.cls !== tail.cls)
|
|
248
|
+
head = pos + a.len;
|
|
249
|
+
pos += a.len;
|
|
250
|
+
}
|
|
251
|
+
return head;
|
|
252
|
+
}
|
|
253
|
+
const HEAD_GROUP_OPEN = /^\((\?:|\?=|\?!|\?<=|\?<!)/;
|
|
254
|
+
function parseHeadAlternative(src, from) {
|
|
255
|
+
let seqs = [[]];
|
|
256
|
+
let i = from;
|
|
257
|
+
let closed = false;
|
|
258
|
+
while (i < src.length) {
|
|
259
|
+
const c = src[i];
|
|
260
|
+
if (c === "|" || c === ")")
|
|
261
|
+
break;
|
|
262
|
+
if (closed)
|
|
263
|
+
throw new Error(`redact: arm-pool pattern /${src}/ has trailing syntax after its value run`);
|
|
264
|
+
let base;
|
|
265
|
+
if (c === "(") {
|
|
266
|
+
const open = HEAD_GROUP_OPEN.exec(src.slice(i));
|
|
267
|
+
if (open === null)
|
|
268
|
+
throw new Error(`redact: head derivation cannot bound group at ${i} in /${src}/`);
|
|
269
|
+
const mark = open[1];
|
|
270
|
+
const inner = parseHeadAlternatives(src, i + 1 + mark.length);
|
|
271
|
+
if (src[inner.next] !== ")")
|
|
272
|
+
throw new Error(`redact: unbalanced group at ${i} in /${src}/`);
|
|
273
|
+
i = inner.next + 1;
|
|
274
|
+
if (mark !== "?:")
|
|
275
|
+
continue;
|
|
276
|
+
if (inner.alts.some((alt) => alt.some((a) => a.unbounded))) {
|
|
277
|
+
seqs = inner.alts.flatMap((alt) => seqs.map((s) => [...s, ...alt]));
|
|
278
|
+
closed = true;
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
base = { len: Math.max(...inner.alts.map((alt) => alt.reduce((n, a) => n + a.len, 0))), cls: undefined };
|
|
282
|
+
}
|
|
283
|
+
else if (c === "[") {
|
|
284
|
+
let k = i + 1;
|
|
285
|
+
while (k < src.length && src[k] !== "]")
|
|
286
|
+
k += src[k] === "\\" ? 2 : 1;
|
|
287
|
+
if (k >= src.length)
|
|
288
|
+
throw new Error(`redact: unterminated character class at ${i} in /${src}/`);
|
|
289
|
+
base = { len: 1, cls: src.slice(i, k + 1) };
|
|
290
|
+
i = k + 1;
|
|
291
|
+
}
|
|
292
|
+
else if (c === "\\") {
|
|
293
|
+
const e = src[i + 1];
|
|
294
|
+
if (e === undefined)
|
|
295
|
+
throw new Error(`redact: dangling escape at ${i} in /${src}/`);
|
|
296
|
+
if (HEAD_CLASS_ESCAPES.has(e))
|
|
297
|
+
base = { len: 1, cls: `\\${e}` };
|
|
298
|
+
else if (HEAD_LITERAL_ESCAPES.has(e))
|
|
299
|
+
base = { len: 1, cls: undefined };
|
|
300
|
+
else
|
|
301
|
+
throw new Error(`redact: head derivation cannot bound escape \\${e} at ${i} in /${src}/`);
|
|
302
|
+
i += 2;
|
|
303
|
+
}
|
|
304
|
+
else if (c === "." || c === "^" || c === "$" || c === "*" || c === "+" || c === "?" || c === "{") {
|
|
305
|
+
throw new Error(`redact: head derivation cannot bound ${JSON.stringify(c)} at ${i} in /${src}/`);
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
base = { len: 1, cls: undefined };
|
|
309
|
+
i += 1;
|
|
310
|
+
}
|
|
311
|
+
let atom = { ...base, unbounded: false };
|
|
312
|
+
const q = src[i];
|
|
313
|
+
if (q === "*" || q === "+") {
|
|
314
|
+
atom = { ...base, unbounded: true };
|
|
315
|
+
i += 1;
|
|
316
|
+
}
|
|
317
|
+
else if (q === "?") {
|
|
318
|
+
i += 1;
|
|
319
|
+
}
|
|
320
|
+
else if (q === "{") {
|
|
321
|
+
const m = /^\{(\d+)(,(\d*))?\}/.exec(src.slice(i));
|
|
322
|
+
if (m === null)
|
|
323
|
+
throw new Error(`redact: head derivation cannot bound quantifier at ${i} in /${src}/`);
|
|
324
|
+
const lo = Number(m[1]);
|
|
325
|
+
const hi = m[2] === undefined ? lo : m[3] === "" ? -1 : Number(m[3]);
|
|
326
|
+
atom = hi < 0 ? { ...base, unbounded: true } : { len: base.len * hi, cls: base.cls, unbounded: false };
|
|
327
|
+
i += m[0].length;
|
|
328
|
+
}
|
|
329
|
+
if (src[i] === "?")
|
|
330
|
+
throw new Error(`redact: head derivation cannot bound a lazy quantifier at ${i} in /${src}/`);
|
|
331
|
+
if (atom.unbounded)
|
|
332
|
+
closed = true;
|
|
333
|
+
for (const s of seqs)
|
|
334
|
+
s.push(atom);
|
|
335
|
+
}
|
|
336
|
+
return { seqs, next: i };
|
|
337
|
+
}
|
|
338
|
+
function parseHeadAlternatives(src, from) {
|
|
339
|
+
const alts = [];
|
|
340
|
+
let i = from;
|
|
341
|
+
for (;;) {
|
|
342
|
+
const one = parseHeadAlternative(src, i);
|
|
343
|
+
alts.push(...one.seqs);
|
|
344
|
+
i = one.next;
|
|
345
|
+
if (src[i] !== "|")
|
|
346
|
+
break;
|
|
347
|
+
i += 1;
|
|
348
|
+
}
|
|
349
|
+
return { alts, next: i };
|
|
350
|
+
}
|
|
351
|
+
function literalHeadLength(re) {
|
|
352
|
+
if (/[uv]/.test(re.flags))
|
|
353
|
+
throw new Error(`redact: head derivation does not support the u/v flags on /${re.source}/`);
|
|
354
|
+
const src = re.source;
|
|
355
|
+
const parsed = parseHeadAlternatives(src, 0);
|
|
356
|
+
if (parsed.next !== src.length)
|
|
357
|
+
throw new Error(`redact: head derivation stopped at ${parsed.next} in /${src}/`);
|
|
358
|
+
return Math.max(...parsed.alts.map((alt) => headOfAtoms(alt, src)));
|
|
359
|
+
}
|
|
360
|
+
function scanResumeAfterHit(start, end, head) {
|
|
361
|
+
return Math.max(start + 1, end - Math.max(head - 1, 0));
|
|
362
|
+
}
|
|
363
|
+
function headWindowCandidates(at, maxHead) {
|
|
364
|
+
const out = [];
|
|
365
|
+
let last = -1;
|
|
366
|
+
for (const e of at) {
|
|
367
|
+
for (let p = Math.max(e - Math.max(maxHead - 1, 0), last + 1, 0); p <= e; p++) {
|
|
368
|
+
out.push({ p, back: e - p });
|
|
369
|
+
last = p;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return out;
|
|
373
|
+
}
|
|
374
|
+
function collectRegexSpans(g, head, repl, order, text, out) {
|
|
237
375
|
g.lastIndex = 0;
|
|
238
376
|
for (let m = g.exec(text); m !== null; m = g.exec(text)) {
|
|
239
377
|
const end = m.index + m[0].length;
|
|
240
378
|
out.push({ start: m.index, end, repl, order });
|
|
241
|
-
g.lastIndex =
|
|
379
|
+
g.lastIndex = scanResumeAfterHit(m.index, end, head);
|
|
242
380
|
}
|
|
243
381
|
}
|
|
244
382
|
function resolveSpanOverlaps(spans) {
|
|
@@ -265,10 +403,10 @@ function applySpans(text, spans) {
|
|
|
265
403
|
parts.push(text.slice(copied));
|
|
266
404
|
return { out: parts.join(""), count: spans.length };
|
|
267
405
|
}
|
|
268
|
-
function collectValueArmSpans(g, y, repl, order, text, out) {
|
|
406
|
+
function collectValueArmSpans(g, y, head, repl, order, text, out) {
|
|
269
407
|
const tails = escapedSeparatorTails(text);
|
|
270
408
|
if (tails === undefined) {
|
|
271
|
-
collectRegexSpans(g, repl, order, text, out);
|
|
409
|
+
collectRegexSpans(g, head, repl, order, text, out);
|
|
272
410
|
return;
|
|
273
411
|
}
|
|
274
412
|
let pos = 0;
|
|
@@ -314,12 +452,14 @@ function collectValueArmSpans(g, y, repl, order, text, out) {
|
|
|
314
452
|
else
|
|
315
453
|
break;
|
|
316
454
|
out.push({ start: idx, end, repl, order });
|
|
317
|
-
pos = end;
|
|
455
|
+
pos = scanResumeAfterHit(idx, end, head);
|
|
318
456
|
}
|
|
319
457
|
}
|
|
320
|
-
function collectStickySpans(y, repl, order, text, at, out) {
|
|
458
|
+
function collectStickySpans(y, head, repl, order, text, at, out) {
|
|
321
459
|
let pos = 0;
|
|
322
|
-
for (const p of at) {
|
|
460
|
+
for (const { p, back } of at) {
|
|
461
|
+
if (back >= head)
|
|
462
|
+
continue;
|
|
323
463
|
if (p < pos)
|
|
324
464
|
continue;
|
|
325
465
|
y.lastIndex = p;
|
|
@@ -328,7 +468,7 @@ function collectStickySpans(y, repl, order, text, at, out) {
|
|
|
328
468
|
continue;
|
|
329
469
|
const end = p + m[0].length;
|
|
330
470
|
out.push({ start: p, end, repl, order });
|
|
331
|
-
pos = end;
|
|
471
|
+
pos = scanResumeAfterHit(p, end, head);
|
|
332
472
|
}
|
|
333
473
|
}
|
|
334
474
|
const WORD_SEGMENT_CLASS = "[A-Za-z0-9._~+/-]";
|
|
@@ -1000,17 +1140,22 @@ const armPoolRule = (() => {
|
|
|
1000
1140
|
const arms = [...SHAPE_SECRET_PATTERNS, ...FRAGMENT_SECRET_PATTERNS].map(([re, repl], order) => {
|
|
1001
1141
|
if (/\$./.test(repl))
|
|
1002
1142
|
throw new Error(`redact: arm-pool replacement ${JSON.stringify(repl)} must not use $N refs`);
|
|
1003
|
-
|
|
1143
|
+
const y = VALUE_ARM_STICKY.get(re);
|
|
1144
|
+
const head = literalHeadLength(re);
|
|
1145
|
+
if (y !== undefined && head === 0)
|
|
1146
|
+
throw new Error(`redact: boundary arm /${re.source}/ has a zero-length structural head — the head-window screen would skip every candidate position`);
|
|
1147
|
+
return { g: re, y, head, repl, order };
|
|
1004
1148
|
});
|
|
1005
|
-
const boundaryArms = arms.flatMap((a) => (a.y === undefined ? [] : [{ y: a.y, repl: a.repl, order: a.order }]));
|
|
1149
|
+
const boundaryArms = arms.flatMap((a) => (a.y === undefined ? [] : [{ y: a.y, head: a.head, repl: a.repl, order: a.order }]));
|
|
1150
|
+
const maxBoundaryHead = Math.max(1, ...boundaryArms.map((a) => a.head));
|
|
1006
1151
|
return {
|
|
1007
1152
|
run: (text, wantCount) => {
|
|
1008
1153
|
const spans = [];
|
|
1009
1154
|
for (const a of arms) {
|
|
1010
1155
|
if (a.y === undefined)
|
|
1011
|
-
collectRegexSpans(a.g, a.repl, a.order, text, spans);
|
|
1156
|
+
collectRegexSpans(a.g, a.head, a.repl, a.order, text, spans);
|
|
1012
1157
|
else
|
|
1013
|
-
collectValueArmSpans(a.g, a.y, a.repl, a.order, text, spans);
|
|
1158
|
+
collectValueArmSpans(a.g, a.y, a.head, a.repl, a.order, text, spans);
|
|
1014
1159
|
}
|
|
1015
1160
|
const tried = new Set();
|
|
1016
1161
|
const freshEnds = (from) => {
|
|
@@ -1026,8 +1171,9 @@ const armPoolRule = (() => {
|
|
|
1026
1171
|
};
|
|
1027
1172
|
for (let at = freshEnds(0); at.length > 0;) {
|
|
1028
1173
|
const before = spans.length;
|
|
1174
|
+
const cand = headWindowCandidates(at, maxBoundaryHead);
|
|
1029
1175
|
for (const a of boundaryArms)
|
|
1030
|
-
collectStickySpans(a.y, a.repl, a.order, text,
|
|
1176
|
+
collectStickySpans(a.y, a.head, a.repl, a.order, text, cand, spans);
|
|
1031
1177
|
at = freshEnds(before);
|
|
1032
1178
|
}
|
|
1033
1179
|
const kept = resolveSpanOverlaps(spans);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/server",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.78.1",
|
|
4
4
|
"description": "Sema Server — the server/API implementation layer for Sema, wiring core, registry, model providers, and cloud agent execution. Built on @sema-agent/core.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BUSL-1.1",
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
"build:binary:run-local:darwin-arm64": "bun build --compile --target=bun-darwin-arm64 src/run-local.ts --outfile dist/run-local-darwin-arm64"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@sema-agent/core": "7.
|
|
58
|
-
"@sema-agent/settings-schema": "1.
|
|
57
|
+
"@sema-agent/core": "7.19.0",
|
|
58
|
+
"@sema-agent/settings-schema": "2.1.0",
|
|
59
59
|
"e2b": "^2.28.0",
|
|
60
60
|
"libsodium-wrappers": "^0.8.4",
|
|
61
61
|
"mysql2": "^3.22.4",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"sharp": "^0.35.3"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@sema-agent/sdk": "9.
|
|
72
|
+
"@sema-agent/sdk": "9.5.0",
|
|
73
73
|
"@types/libsodium-wrappers": "^0.7.14",
|
|
74
74
|
"@types/node": "22.10.2",
|
|
75
75
|
"@types/pg": "^8.20.0",
|