@sema-agent/core 1.445.0 → 1.447.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/dist/core/arg-summary.js
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
const ACTIVITY_ARG_MAX = 80;
|
|
2
2
|
const SENSITIVE_KEY = /token|secret|key|password|passwd|credential|auth/i;
|
|
3
3
|
const SECRET_PATTERNS = [
|
|
4
|
-
/(?<![A-Za-z0-9])(?:sk|pk|rk|gh[opsur])[-_][A-Za-z0-9_-]{8,}/g,
|
|
5
|
-
/(?<![A-Za-z0-9])AIza[A-Za-z0-9_-]{20,}/g,
|
|
6
|
-
/(?<![A-Za-z0-9])xox[baprs]-[A-Za-z0-9-]{10,}/g,
|
|
7
|
-
/(?<![A-Za-z0-9])AKIA[0-9A-Z]{12,}/g,
|
|
8
|
-
/(?<![A-Za-z0-9])
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
/(?<![A-Za-z0-9])
|
|
4
|
+
{ re: /(?<![A-Za-z0-9])(?:sk|pk|rk|gh[opsur])[-_][A-Za-z0-9_-]{8,}/g, replace: "[redacted]" },
|
|
5
|
+
{ re: /(?<![A-Za-z0-9])AIza[A-Za-z0-9_-]{20,}/g, replace: "[redacted]" },
|
|
6
|
+
{ re: /(?<![A-Za-z0-9])xox[baprs]-[A-Za-z0-9-]{10,}/g, replace: "[redacted]" },
|
|
7
|
+
{ re: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{12,}/g, replace: "[redacted]" },
|
|
8
|
+
{ re: /(?<![A-Za-z0-9])hf_[A-Za-z0-9]{20,}/g, replace: "[redacted]" },
|
|
9
|
+
{ re: /(?<![A-Za-z0-9])eyJ[A-Za-z0-9._-]{20,}/g, replace: "[redacted]" },
|
|
10
|
+
{ re: /-----BEGIN[ A-Z]*PRIVATE KEY-----[\s\S]*?(?:-----END[ A-Z]*PRIVATE KEY-----|$)/g, replace: "[redacted]" },
|
|
11
|
+
{ re: /(?<![A-Za-z0-9])Bearer\s+[A-Za-z0-9._~+/-]{8,}=*/gi, replace: "[redacted]" },
|
|
12
|
+
{
|
|
13
|
+
re: /(?<![A-Za-z0-9])((?:token|secret|key|password|passwd|credential|authorization)["']?\s*[=:]\s*["']?)[^\s"';|&]{4,}/gi,
|
|
14
|
+
replace: "$1[redacted]",
|
|
15
|
+
},
|
|
12
16
|
];
|
|
13
17
|
export function scrubSecrets(s) {
|
|
14
18
|
let out = s;
|
|
15
|
-
for (const
|
|
16
|
-
out = out.replace(
|
|
19
|
+
for (const { re, replace } of SECRET_PATTERNS)
|
|
20
|
+
out = out.replace(re, replace);
|
|
17
21
|
return out;
|
|
18
22
|
}
|
|
19
23
|
function truncCodePoints(s) {
|
package/dist/core/secret-env.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
const SECRET_ENV_RE = /(^|_)(KEY|TOKEN|SECRET|SECRETS|PASSWORD|PASSWD|CREDENTIAL|CREDENTIALS|PRIVATEKEY|APIKEY|ACCESS_KEY|SESSION_TOKEN)
|
|
1
|
+
const SECRET_ENV_RE = /(^|_)(KEY|TOKEN|SECRET|SECRETS|PASSWORD|PASSWD|CREDENTIAL|CREDENTIALS|PRIVATEKEY|APIKEY|ACCESS_KEY|SESSION_TOKEN)(?:_(?:\d+|ID))?$/i;
|
|
2
|
+
const SECRET_ENV_EXACT_NAMES = new Set(["DATABASE_URL", "CONNECTION_STRING", "DSN", "NPM_AUTH"]);
|
|
2
3
|
export function isSecretEnvKey(key) {
|
|
3
|
-
return SECRET_ENV_RE.test(key);
|
|
4
|
+
return SECRET_ENV_RE.test(key) || SECRET_ENV_EXACT_NAMES.has(key.toUpperCase());
|
|
4
5
|
}
|
|
5
6
|
export function scrubSecretEnv(env) {
|
|
6
7
|
const out = {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type SessionRepo } from "../internal/harness.js";
|
|
2
|
-
import { type AcquiredSession, type SessionStore, type
|
|
2
|
+
import { type AcquiredSession, type SessionStore, type SessionStoreSummary } from "./session.js";
|
|
3
3
|
export declare const SESSION_DEFAULT_TTL_DAYS = 7;
|
|
4
4
|
export type EvictPolicy = "delete" | "forget";
|
|
5
5
|
export interface TtlSessionStoreOptions {
|
|
@@ -24,7 +24,7 @@ export declare class TtlSessionStore implements SessionStore {
|
|
|
24
24
|
private createAndStore;
|
|
25
25
|
touch(sessionId: string): void;
|
|
26
26
|
noteTaskRun(sessionId: string, taskId: string): void;
|
|
27
|
-
list(): Promise<
|
|
27
|
+
list(): Promise<SessionStoreSummary[]>;
|
|
28
28
|
fork(sourceId: string, owner?: string | null): Promise<string | null>;
|
|
29
29
|
release(sessionId: string): Promise<void>;
|
|
30
30
|
forget(sessionId: string): void;
|
package/dist/core/session.d.ts
CHANGED
|
@@ -12,13 +12,14 @@ export interface AcquiredSession {
|
|
|
12
12
|
session: Session;
|
|
13
13
|
sessionId: string;
|
|
14
14
|
}
|
|
15
|
-
export interface
|
|
15
|
+
export interface SessionStoreSummary {
|
|
16
16
|
sessionId: string;
|
|
17
17
|
createdAt?: string;
|
|
18
18
|
lastActiveAt: number;
|
|
19
19
|
lastTaskId?: string;
|
|
20
20
|
forkedFrom?: string;
|
|
21
21
|
}
|
|
22
|
+
export type SessionSummary = SessionStoreSummary;
|
|
22
23
|
export interface SessionStore {
|
|
23
24
|
acquire(sessionId?: string, opts?: {
|
|
24
25
|
requireExisting?: boolean;
|
|
@@ -29,7 +30,7 @@ export interface SessionStore {
|
|
|
29
30
|
pin?(sessionId: string): void | Promise<void>;
|
|
30
31
|
unpin?(sessionId: string): void | Promise<void>;
|
|
31
32
|
noteTaskRun?(sessionId: string, taskId: string): void | Promise<void>;
|
|
32
|
-
list?(): Promise<
|
|
33
|
+
list?(): Promise<SessionStoreSummary[]>;
|
|
33
34
|
fork?(sourceId: string, owner?: string | null): Promise<string | null>;
|
|
34
35
|
readonly size: number;
|
|
35
36
|
dispose(): void | Promise<void>;
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { delimitUntrusted } from "./untrusted-text.js";
|
|
2
2
|
import { scrubSecrets } from "./arg-summary.js";
|
|
3
3
|
const URI_SCHEME = String.raw `[A-Za-z][A-Za-z0-9+.\-_]{0,63}`;
|
|
4
|
-
const CREDENTIALS_IN_AUTHORITY = new RegExp(String.raw `(${URI_SCHEME}:\/\/)(?:[^/\s"'@]*@)
|
|
4
|
+
const CREDENTIALS_IN_AUTHORITY = new RegExp(String.raw `(${URI_SCHEME}:\/\/)((?:[^/\s"'@]*@)+)`, "gi");
|
|
5
5
|
const URL_OF_ANY_PROTOCOL = new RegExp(String.raw `${URI_SCHEME}:\/\/[^\s"'\`]+`, "gi");
|
|
6
|
+
const BARE_USERNAME_MAX_LEN = 20;
|
|
7
|
+
function redactUserinfo(scheme, userinfoWithAt) {
|
|
8
|
+
const userinfo = userinfoWithAt.slice(0, -1);
|
|
9
|
+
if (userinfo.includes("@"))
|
|
10
|
+
return `${scheme}[redacted-credentials]@`;
|
|
11
|
+
const colonIdx = userinfo.indexOf(":");
|
|
12
|
+
if (colonIdx === -1) {
|
|
13
|
+
return userinfo.length >= BARE_USERNAME_MAX_LEN ? `${scheme}[redacted-credentials]@` : `${scheme}${userinfo}@`;
|
|
14
|
+
}
|
|
15
|
+
return `${scheme}${userinfo.slice(0, colonIdx)}:[redacted-credentials]@`;
|
|
16
|
+
}
|
|
6
17
|
export function redactSecrets(s) {
|
|
7
18
|
return scrubSecrets(s)
|
|
8
|
-
.replace(CREDENTIALS_IN_AUTHORITY,
|
|
19
|
+
.replace(CREDENTIALS_IN_AUTHORITY, (_m, scheme, userinfo) => redactUserinfo(scheme, userinfo))
|
|
9
20
|
.replace(/([?&#](?:sig|signature|sas|code)=)[^&\s"'#]+/gi, "$1[redacted]");
|
|
10
21
|
}
|
|
11
22
|
export function redactHostLeaks(s) {
|
|
@@ -13,6 +24,22 @@ export function redactHostLeaks(s) {
|
|
|
13
24
|
.replace(URL_OF_ANY_PROTOCOL, "[redacted-url]")
|
|
14
25
|
.replace(/(?:\/[A-Za-z0-9_.-]+){2,}/g, "[redacted-path]");
|
|
15
26
|
}
|
|
27
|
+
const REDACTION_MARKER_RE = /\[redacted(?:-[a-z]+)?\]/g;
|
|
28
|
+
function countRedactionMarkers(s) {
|
|
29
|
+
return (s.match(REDACTION_MARKER_RE) ?? []).length;
|
|
30
|
+
}
|
|
31
|
+
function safeEllipsisTruncate(s, max) {
|
|
32
|
+
if (max < 1)
|
|
33
|
+
return "";
|
|
34
|
+
const budget = max - 1;
|
|
35
|
+
let out = "";
|
|
36
|
+
for (const codePoint of s) {
|
|
37
|
+
if (out.length + codePoint.length > budget)
|
|
38
|
+
break;
|
|
39
|
+
out += codePoint;
|
|
40
|
+
}
|
|
41
|
+
return out + "…";
|
|
42
|
+
}
|
|
16
43
|
function boundedString(value, max, redact) {
|
|
17
44
|
let s;
|
|
18
45
|
try {
|
|
@@ -24,18 +51,32 @@ function boundedString(value, max, redact) {
|
|
|
24
51
|
s = redact(s);
|
|
25
52
|
if (s.length <= max)
|
|
26
53
|
return s;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
54
|
+
const totalMarkers = countRedactionMarkers(s);
|
|
55
|
+
const plainSuffix = (keepN) => `…[+${s.length - keepN} chars]`;
|
|
56
|
+
const enrichedSuffix = (keepN) => {
|
|
57
|
+
const lost = totalMarkers - countRedactionMarkers(s.slice(0, keepN));
|
|
58
|
+
return lost > 0 ? `…[+${s.length - keepN} chars, ${lost} redaction marker(s) among them]` : plainSuffix(keepN);
|
|
59
|
+
};
|
|
60
|
+
const converge = (suffixFor) => {
|
|
61
|
+
let keep = max;
|
|
62
|
+
let out = "";
|
|
63
|
+
for (let i = 0; i < 4; i++) {
|
|
64
|
+
out = `${s.slice(0, keep)}${suffixFor(keep)}`;
|
|
65
|
+
if (out.length <= max)
|
|
66
|
+
return out;
|
|
67
|
+
if (keep === 0)
|
|
68
|
+
return undefined;
|
|
69
|
+
keep = Math.max(0, keep - (out.length - max));
|
|
35
70
|
}
|
|
36
|
-
|
|
71
|
+
return out.length <= max ? out : undefined;
|
|
72
|
+
};
|
|
73
|
+
const out = (totalMarkers > 0 ? converge(enrichedSuffix) : undefined) ?? converge(plainSuffix);
|
|
74
|
+
if (out === undefined) {
|
|
75
|
+
return safeEllipsisTruncate(s, max);
|
|
37
76
|
}
|
|
38
|
-
|
|
77
|
+
if (out.length >= s.length)
|
|
78
|
+
return s;
|
|
79
|
+
return out;
|
|
39
80
|
}
|
|
40
81
|
export function boundedRedactedSummary(value, max) {
|
|
41
82
|
return boundedString(value, max, redactSecrets);
|
package/dist/index.d.ts
CHANGED
|
@@ -44,7 +44,7 @@ export { SAFETY_AXIS_VOCABULARY } from "./core/safety-axis-vocab.js";
|
|
|
44
44
|
export { createSessionRulePolicy } from "./core/runner/session-rule-policy.js";
|
|
45
45
|
export { TtlSessionStore, type TtlSessionStoreOptions, type EvictPolicy } from "./core/session-store.js";
|
|
46
46
|
export { reconcileInterruptedSession, findOrphanToolCalls, type OrphanToolCall, type ReconcileReport, } from "./core/session-reconcile.js";
|
|
47
|
-
export { StoredSession, InMemorySessionRepo, InMemorySessionStorage, BaseSessionStorage, leafIdAfterEntry, validateEntriesForImport, StreamingImportValidator, boundedTail, SessionError, isSessionConflict, hasSessionFork, uuidv7, type Session, type SessionStore, type AcquiredSession, type SessionSummary, type SessionStorage, type SessionRepo, type SessionMetadata, type SessionTreeEntry, type SessionWriteOptions, } from "./core/session.js";
|
|
47
|
+
export { StoredSession, InMemorySessionRepo, InMemorySessionStorage, BaseSessionStorage, leafIdAfterEntry, validateEntriesForImport, StreamingImportValidator, boundedTail, SessionError, isSessionConflict, hasSessionFork, uuidv7, type Session, type SessionStore, type AcquiredSession, type SessionStoreSummary, type SessionSummary, type SessionStorage, type SessionRepo, type SessionMetadata, type SessionTreeEntry, type SessionWriteOptions, } from "./core/session.js";
|
|
48
48
|
export { warmResume } from "./core/warm-resume.js";
|
|
49
49
|
export { StubExecutionEnv } from "./core/stub-env.js";
|
|
50
50
|
export { NodeExecutionEnv, FileError, ExecutionError } from "./internal/harness.js";
|