@sema-agent/server 7.75.3 → 7.76.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/USAGE.md +29 -13
- package/dist/boot/reapers.d.ts +5 -1
- package/dist/boot/reapers.js +6 -1
- package/dist/boot/shutdown.js +5 -1
- package/dist/config-catalog.js +1 -1
- package/dist/config-types.d.ts +9 -7
- package/dist/http/routes/approvals-assistant.js +37 -1
- package/dist/http/server.d.ts +5 -1
- package/dist/main.js +3 -1
- package/dist/parent-watch.d.ts +55 -23
- package/dist/parent-watch.js +38 -23
- package/dist/plugins/approval-nonce-store.d.ts +94 -0
- package/dist/plugins/approval-nonce-store.js +126 -0
- package/dist/plugins/permission-rule-store-sql.d.ts +1 -30
- package/dist/plugins/permission-rule-store-sql.js +2 -10
- package/dist/plugins/pg-pool.js +8 -0
- package/dist/plugins/pg-session-storage.js +1 -0
- package/dist/plugins/sql-driver.d.ts +27 -0
- package/dist/plugins/sql-driver.js +12 -0
- package/dist/plugins/store-backend.d.ts +6 -0
- package/dist/plugins/store-backend.js +7 -0
- package/dist/plugins/tidb-pool.js +26 -1
- package/dist/principal-jwt.d.ts +49 -9
- package/dist/principal-jwt.js +16 -8
- package/dist/tool-approval.d.ts +2 -1
- package/dist/tool-approval.js +8 -1
- package/dist/trace/redact.d.ts +7 -4
- package/dist/trace/redact.js +64 -33
- package/package.json +2 -2
package/dist/trace/redact.js
CHANGED
|
@@ -206,23 +206,28 @@ function forgetEscapedSeparatorTails() {
|
|
|
206
206
|
escapedTailsValue = undefined;
|
|
207
207
|
}
|
|
208
208
|
const VALUE_ARM_STICKY = new Map();
|
|
209
|
+
const VALUE_ARMS = new Set();
|
|
209
210
|
const VALUE_ARM_BODIES = [];
|
|
210
211
|
const valueArm = (prefixSrc, valueClass, min, evidence) => {
|
|
211
212
|
const body = `${prefixSrc}${twoStrongAhead(valueClass)}${atLeast(valueClass, min)}`;
|
|
212
213
|
VALUE_ARM_BODIES.push(body);
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
214
|
+
const g = (() => {
|
|
215
|
+
switch (evidence) {
|
|
216
|
+
case "self-evident":
|
|
217
|
+
return new RegExp(body, "g");
|
|
218
|
+
case "needs-left-boundary": {
|
|
219
|
+
const re = new RegExp(`(?<!${WORD_INTERIOR_CLASS})${body}`, "g");
|
|
220
|
+
VALUE_ARM_STICKY.set(re, new RegExp(body, "y"));
|
|
221
|
+
return re;
|
|
222
|
+
}
|
|
223
|
+
default: {
|
|
224
|
+
const unhandled = evidence;
|
|
225
|
+
throw new Error(`redact: unhandled value-arm evidence ${String(unhandled)}`);
|
|
226
|
+
}
|
|
224
227
|
}
|
|
225
|
-
}
|
|
228
|
+
})();
|
|
229
|
+
VALUE_ARMS.add(g);
|
|
230
|
+
return g;
|
|
226
231
|
};
|
|
227
232
|
let anyValueArm;
|
|
228
233
|
function anyValueArmRe() {
|
|
@@ -312,10 +317,19 @@ function collectValueArmSpans(g, y, repl, order, text, out) {
|
|
|
312
317
|
pos = end;
|
|
313
318
|
}
|
|
314
319
|
}
|
|
315
|
-
function
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
320
|
+
function collectStickySpans(y, repl, order, text, at, out) {
|
|
321
|
+
let pos = 0;
|
|
322
|
+
for (const p of at) {
|
|
323
|
+
if (p < pos)
|
|
324
|
+
continue;
|
|
325
|
+
y.lastIndex = p;
|
|
326
|
+
const m = y.exec(text);
|
|
327
|
+
if (m === null)
|
|
328
|
+
continue;
|
|
329
|
+
const end = p + m[0].length;
|
|
330
|
+
out.push({ start: p, end, repl, order });
|
|
331
|
+
pos = end;
|
|
332
|
+
}
|
|
319
333
|
}
|
|
320
334
|
const WORD_SEGMENT_CLASS = "[A-Za-z0-9._~+/-]";
|
|
321
335
|
const keywordArm = (keywordSrc, valueClass, min, tailSrc = "") => new RegExp(`(?:${keywordSrc}\\s+${atLeast(valueClass, min)}${tailSrc}` +
|
|
@@ -747,9 +761,10 @@ function redactionTokenEndAt(s, p, limit) {
|
|
|
747
761
|
return 0;
|
|
748
762
|
}
|
|
749
763
|
const labelOfToken = (token) => token.replace(/[«»]/g, "").replace(/^redacted:/, "");
|
|
764
|
+
const armOfToken = (repl) => (repl.match(/«[^»]*»/g) ?? [repl]).some((t) => t.endsWith(":partial»")) ? "fragment" : "full";
|
|
750
765
|
const NO_HITS = [];
|
|
751
766
|
const singleHit = (label, arm, r) => r.count > 0 ? { out: r.out, hits: [{ label, count: r.count, arm }] } : { out: r.out, hits: NO_HITS };
|
|
752
|
-
const regexRule = ([re, repl]
|
|
767
|
+
const regexRule = ([re, repl]) => {
|
|
753
768
|
const groupCount = (new RegExp(`${re.source}|`).exec("")?.length ?? 1) - 1;
|
|
754
769
|
const refs = [...repl.matchAll(/\$(.)/g)].map(([, d]) => d ?? "");
|
|
755
770
|
for (const d of refs) {
|
|
@@ -757,13 +772,11 @@ const regexRule = ([re, repl], arm) => {
|
|
|
757
772
|
throw new Error(`redact: replacement ${JSON.stringify(repl)} uses unsupported ref $${d}`);
|
|
758
773
|
}
|
|
759
774
|
const expand = refs.length === 0 ? undefined : (args) => repl.replace(/\$([1-9])/g, (_, d) => args[Number(d)] ?? "");
|
|
760
|
-
const
|
|
761
|
-
if (
|
|
762
|
-
throw new Error(`redact:
|
|
775
|
+
const arm = armOfToken(repl);
|
|
776
|
+
if (VALUE_ARMS.has(re) || arm === "fragment")
|
|
777
|
+
throw new Error(`redact: rule ${JSON.stringify(repl)} belongs in the arm pool, not a per-arm section`);
|
|
763
778
|
const label = labelOfToken(repl);
|
|
764
779
|
const applyOnce = (text, wantCount) => {
|
|
765
|
-
if (sticky !== undefined)
|
|
766
|
-
return runValueArm(re, sticky, repl, text);
|
|
767
780
|
if (!wantCount)
|
|
768
781
|
return { out: text.replace(re, repl), count: 0 };
|
|
769
782
|
let n = 0;
|
|
@@ -970,12 +983,13 @@ function redactPpkContainers(text, record) {
|
|
|
970
983
|
}
|
|
971
984
|
const URL_USERINFO_LABEL = labelOfToken(URL_USERINFO_PATTERN[1]);
|
|
972
985
|
const urlUserinfoRule = { run: (text, _wantCount, json) => singleHit(URL_USERINFO_LABEL, "full", redactUrlUserinfo(text, json)) };
|
|
973
|
-
const
|
|
974
|
-
const arms = SHAPE_SECRET_PATTERNS.map(([re, repl], order) => {
|
|
986
|
+
const armPoolRule = (() => {
|
|
987
|
+
const arms = [...SHAPE_SECRET_PATTERNS, ...FRAGMENT_SECRET_PATTERNS].map(([re, repl], order) => {
|
|
975
988
|
if (/\$./.test(repl))
|
|
976
|
-
throw new Error(`redact:
|
|
989
|
+
throw new Error(`redact: arm-pool replacement ${JSON.stringify(repl)} must not use $N refs`);
|
|
977
990
|
return { g: re, y: VALUE_ARM_STICKY.get(re), repl, order };
|
|
978
991
|
});
|
|
992
|
+
const boundaryArms = arms.flatMap((a) => (a.y === undefined ? [] : [{ y: a.y, repl: a.repl, order: a.order }]));
|
|
979
993
|
return {
|
|
980
994
|
run: (text, wantCount) => {
|
|
981
995
|
const spans = [];
|
|
@@ -985,6 +999,24 @@ const shapeSectionRule = (() => {
|
|
|
985
999
|
else
|
|
986
1000
|
collectValueArmSpans(a.g, a.y, a.repl, a.order, text, spans);
|
|
987
1001
|
}
|
|
1002
|
+
const tried = new Set();
|
|
1003
|
+
const freshEnds = (from) => {
|
|
1004
|
+
const at = [];
|
|
1005
|
+
for (let k = from; k < spans.length; k++) {
|
|
1006
|
+
const e = spans[k].end;
|
|
1007
|
+
if (tried.has(e))
|
|
1008
|
+
continue;
|
|
1009
|
+
tried.add(e);
|
|
1010
|
+
at.push(e);
|
|
1011
|
+
}
|
|
1012
|
+
return at.sort((x, y) => x - y);
|
|
1013
|
+
};
|
|
1014
|
+
for (let at = freshEnds(0); at.length > 0;) {
|
|
1015
|
+
const before = spans.length;
|
|
1016
|
+
for (const a of boundaryArms)
|
|
1017
|
+
collectStickySpans(a.y, a.repl, a.order, text, at, spans);
|
|
1018
|
+
at = freshEnds(before);
|
|
1019
|
+
}
|
|
988
1020
|
const kept = resolveSpanOverlaps(spans);
|
|
989
1021
|
const out = applySpans(text, kept).out;
|
|
990
1022
|
if (!wantCount || kept.length === 0)
|
|
@@ -992,18 +1024,17 @@ const shapeSectionRule = (() => {
|
|
|
992
1024
|
const byToken = new Map();
|
|
993
1025
|
for (const sp of kept)
|
|
994
1026
|
byToken.set(sp.repl, (byToken.get(sp.repl) ?? 0) + 1);
|
|
995
|
-
return { out, hits: [...byToken].map(([token, count]) => ({ label: labelOfToken(token), count, arm:
|
|
1027
|
+
return { out, hits: [...byToken].map(([token, count]) => ({ label: labelOfToken(token), count, arm: armOfToken(token) })) };
|
|
996
1028
|
},
|
|
997
1029
|
};
|
|
998
1030
|
})();
|
|
999
1031
|
const SECRET_RULES = [
|
|
1000
|
-
...STRUCTURAL_SECRET_PATTERNS.map((p) => (p === URL_USERINFO_PATTERN ? urlUserinfoRule : regexRule(p
|
|
1001
|
-
{ run: (text, _wantCount, _json, observe) => singleHit(labelOfToken(PPK_CONTAINER_TOKEN),
|
|
1002
|
-
{ run: (text, _wantCount, json) => singleHit(labelOfToken(PEM_FRAGMENT_TOKEN),
|
|
1003
|
-
{ run: (text) => singleHit(labelOfToken(HEADLESS_PPK_TOKEN),
|
|
1004
|
-
...KEYWORD_SECRET_PATTERNS.map((p) => regexRule(p
|
|
1005
|
-
|
|
1006
|
-
...FRAGMENT_SECRET_PATTERNS.map((p) => regexRule(p, "fragment")),
|
|
1032
|
+
...STRUCTURAL_SECRET_PATTERNS.map((p) => (p === URL_USERINFO_PATTERN ? urlUserinfoRule : regexRule(p))),
|
|
1033
|
+
{ run: (text, _wantCount, _json, observe) => singleHit(labelOfToken(PPK_CONTAINER_TOKEN), armOfToken(PPK_CONTAINER_TOKEN), redactPpkContainers(text, observe)) },
|
|
1034
|
+
{ run: (text, _wantCount, json) => singleHit(labelOfToken(PEM_FRAGMENT_TOKEN), armOfToken(PEM_FRAGMENT_TOKEN), redactPemFragments(text, json)) },
|
|
1035
|
+
{ run: (text) => singleHit(labelOfToken(HEADLESS_PPK_TOKEN), armOfToken(HEADLESS_PPK_TOKEN), redactHeadlessPpkBodies(text)) },
|
|
1036
|
+
...KEYWORD_SECRET_PATTERNS.map((p) => regexRule(p)),
|
|
1037
|
+
armPoolRule,
|
|
1007
1038
|
{ run: (text, _wantCount, json) => ({ out: redactUrlUserinfo(text, json).out, hits: NO_HITS }) },
|
|
1008
1039
|
];
|
|
1009
1040
|
let onRedaction;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/server",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.76.0",
|
|
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,7 +54,7 @@
|
|
|
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.17.
|
|
57
|
+
"@sema-agent/core": "7.17.6",
|
|
58
58
|
"@sema-agent/settings-schema": "1.10.0",
|
|
59
59
|
"e2b": "^2.28.0",
|
|
60
60
|
"libsodium-wrappers": "^0.8.4",
|