@sema-agent/core 3.0.0 → 5.0.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/CHANGELOG.md +2382 -0
- package/dist/agents/cascade.d.ts +3 -1
- package/dist/agents/cascade.js +31 -32
- package/dist/agents/cumulative-stats.d.ts +29 -0
- package/dist/agents/cumulative-stats.js +29 -0
- package/dist/agents/observer.d.ts +4 -0
- package/dist/agents/observer.js +11 -10
- package/dist/agents/repair-loop.d.ts +2 -0
- package/dist/agents/repair-loop.js +48 -24
- package/dist/agents/retain-ledger.d.ts +2 -0
- package/dist/agents/retain-ledger.js +6 -5
- package/dist/agents/roster-store.d.ts +1 -0
- package/dist/agents/roster-store.js +3 -5
- package/dist/agents/send-message-tool.d.ts +1 -0
- package/dist/agents/send-message-tool.js +2 -0
- package/dist/agents/subagent.d.ts +3 -1
- package/dist/agents/subagent.js +79 -94
- package/dist/agents/teacher.d.ts +1 -9
- package/dist/agents/teacher.js +21 -24
- package/dist/agents/tool-filter.js +6 -7
- package/dist/agents/verify.d.ts +1 -0
- package/dist/agents/verify.js +15 -14
- package/dist/brain/anthropic.js +24 -21
- package/dist/brain/openai.js +24 -21
- package/dist/brain/stream-engine.js +5 -2
- package/dist/brain/stream-shared.d.ts +1 -0
- package/dist/brain/stream-shared.js +14 -0
- package/dist/brain/terminal-cause.d.ts +4 -0
- package/dist/brain/terminal-cause.js +12 -0
- package/dist/brain/tool-call-id.d.ts +1 -0
- package/dist/brain/tool-call-id.js +3 -0
- package/dist/brain/tool-call-repair.js +2 -1
- package/dist/core/arg-summary.d.ts +21 -1
- package/dist/core/arg-summary.js +61 -14
- package/dist/core/auto-compaction.d.ts +1 -0
- package/dist/core/auto-compaction.js +16 -25
- package/dist/core/background-agent-store.d.ts +22 -22
- package/dist/core/background-agent-store.js +19 -23
- package/dist/core/checkpoint-store.d.ts +6 -13
- package/dist/core/checkpoint-store.js +11 -5
- package/dist/core/file-snapshot-store.d.ts +8 -0
- package/dist/core/file-snapshot-store.js +4 -3
- package/dist/core/fs-write-gate-policy.js +2 -3
- package/dist/core/hooks.d.ts +4 -1
- package/dist/core/hooks.js +8 -18
- package/dist/core/lsp.js +4 -3
- package/dist/core/mailbox-store.d.ts +7 -10
- package/dist/core/mcp.d.ts +7 -10
- package/dist/core/mcp.js +7 -9
- package/dist/core/memory-engine/engine.d.ts +0 -1
- package/dist/core/memory-engine/engine.js +24 -34
- package/dist/core/memory-engine/file-backend.d.ts +1 -2
- package/dist/core/memory-engine/file-backend.js +25 -36
- package/dist/core/memory-engine/layout.d.ts +8 -0
- package/dist/core/memory-engine/layout.js +60 -4
- package/dist/core/memory-engine/scope-contract.js +9 -3
- package/dist/core/memory-engine/types.d.ts +1 -1
- package/dist/core/permission-rules.js +2 -3
- package/dist/core/runner/active-skill-scope.d.ts +0 -1
- package/dist/core/runner/active-skill-scope.js +2 -17
- package/dist/core/runner/assemble-result.d.ts +2 -7
- package/dist/core/runner/assemble-result.js +3 -4
- package/dist/core/runner/compaction-call-options.d.ts +7 -0
- package/dist/core/runner/compaction-call-options.js +30 -0
- package/dist/core/runner/prepare-task.d.ts +6 -23
- package/dist/core/runner/prepare-task.js +36 -61
- package/dist/core/runner/runtask.d.ts +1 -0
- package/dist/core/runner/runtask.js +84 -172
- package/dist/core/runner/session-rule-policy.js +7 -5
- package/dist/core/runner/teardown-bounded.d.ts +7 -0
- package/dist/core/runner/teardown-bounded.js +36 -0
- package/dist/core/runner/tool-disclosure.d.ts +2 -5
- package/dist/core/runner/turn-attachments.d.ts +5 -15
- package/dist/core/runner/turn-attachments.js +1 -1
- package/dist/core/safe-notify.d.ts +17 -0
- package/dist/core/safe-notify.js +59 -0
- package/dist/core/sensitive-path-policy.js +4 -4
- package/dist/core/session-reconcile.js +1 -2
- package/dist/core/skill-tool-specifier.js +2 -3
- package/dist/core/skills-directory.js +2 -3
- package/dist/core/store-contracts/checkpoint-store-contract.js +1 -1
- package/dist/core/stub-env.d.ts +2 -6
- package/dist/core/surrogate-safe-slice.d.ts +4 -0
- package/dist/core/surrogate-safe-slice.js +18 -0
- package/dist/core/task-registry-monitor.js +8 -13
- package/dist/core/task-registry-shared.d.ts +23 -1
- package/dist/core/task-registry-shared.js +16 -0
- package/dist/core/task-registry.d.ts +6 -1
- package/dist/core/task-registry.js +52 -87
- package/dist/core/task-tool-shape.d.ts +0 -2
- package/dist/core/task-tool-shape.js +2 -5
- package/dist/core/tool-errors.js +5 -4
- package/dist/core/tool-name-aliases.d.ts +1 -2
- package/dist/core/tool-name-aliases.js +42 -59
- package/dist/core/tool-policy.js +21 -17
- package/dist/core/tool-result-store.d.ts +1 -0
- package/dist/core/tool-result-store.js +17 -1
- package/dist/core/trace.d.ts +9 -9
- package/dist/core/types.d.ts +15 -12
- package/dist/core/untrusted-egress.d.ts +4 -2
- package/dist/core/untrusted-egress.js +28 -14
- package/dist/core/workflow-journal-store.d.ts +9 -20
- package/dist/core/workflow-run-store.d.ts +11 -10
- package/dist/core/workflow-run-store.js +22 -16
- package/dist/engine/compaction/utils.js +4 -2
- package/dist/engine/execution-env/node-execution-env.d.ts +2 -24
- package/dist/engine/execution-env/node-execution-env.js +1 -1
- package/dist/engine/harness/agent-harness.d.ts +1 -0
- package/dist/engine/harness/agent-harness.js +13 -33
- package/dist/engine/harness/types.d.ts +29 -67
- package/dist/engine/llm/types.d.ts +1 -1
- package/dist/engine/loop/agent-loop.js +12 -14
- package/dist/engine/loop/types.d.ts +11 -9
- package/dist/engine/session/memory-repo.d.ts +2 -6
- package/dist/engine/session/session.d.ts +5 -30
- package/dist/index.d.ts +6 -3
- package/dist/index.js +4 -3
- package/dist/internal/harness-types.d.ts +3 -1
- package/dist/orchestration/run-spec.js +6 -4
- package/dist/orchestration/run-workflow-tool.js +3 -36
- package/dist/orchestration/workflow-governance.js +2 -1
- package/dist/orchestration/workflow.d.ts +4 -11
- package/dist/orchestration/workflow.js +164 -204
- package/dist/prompt-assembly/packs/sema-default.js +1 -3
- package/dist/prompt-assembly/tool-catalog.d.ts +10 -9
- package/dist/prompt-assembly/turn-snapshot.d.ts +2 -5
- package/dist/prompts/default.js +1 -3
- package/dist/prompts/simple-sections.d.ts +0 -1
- package/dist/prompts/simple-sections.js +0 -1
- package/dist/stores/file/background-agent-store.d.ts +3 -12
- package/dist/stores/file/background-agent-store.js +3 -41
- package/dist/stores/file/checkpoint-store.js +6 -6
- package/dist/stores/file/mailbox-store.d.ts +2 -6
- package/dist/stores/file/session-policy-store.js +15 -1
- package/dist/stores/file/session-store.d.ts +2 -6
- package/dist/stores/file/workflow-journal-store.d.ts +3 -11
- package/dist/stores/file/workflow-run-store.d.ts +3 -7
- package/dist/stores/file/workflow-run-store.js +4 -17
- package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -0
- package/dist/tools/fs/bash-readonly-classifier.js +60 -25
- package/dist/tools/fs/fs-bash.js +330 -104
- package/dist/tools/fs/fs-pdf.d.ts +2 -12
- package/dist/tools/fs/fs-shared.js +2 -2
- package/dist/tools/fs/fs-write.js +0 -1
- package/dist/tools/fs/notebook.d.ts +2 -5
- package/dist/tools/fs/safety.d.ts +3 -0
- package/dist/tools/fs/safety.js +43 -14
- package/dist/tools/fs/search.js +5 -5
- package/dist/tools/monitor.d.ts +1 -0
- package/dist/tools/monitor.js +7 -5
- package/dist/tools/worktree.d.ts +2 -7
- package/dist/tools/worktree.js +3 -1
- package/package.json +6 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { McpDroppedTool } from "../mcp.js";
|
|
1
2
|
import { type SkillListingEntry } from "./synthetic-tools.js";
|
|
2
3
|
export declare const TODO_REMINDER_CONFIG: {
|
|
3
4
|
readonly TURNS_SINCE_WRITE: 10;
|
|
@@ -112,11 +113,7 @@ export interface AttachmentInputs {
|
|
|
112
113
|
}>;
|
|
113
114
|
removed: readonly string[];
|
|
114
115
|
};
|
|
115
|
-
mcpDroppedTools?: ReadonlyArray<
|
|
116
|
-
server: string;
|
|
117
|
-
tool: string;
|
|
118
|
-
reason: string;
|
|
119
|
-
}>;
|
|
116
|
+
mcpDroppedTools?: ReadonlyArray<McpDroppedTool>;
|
|
120
117
|
}
|
|
121
118
|
export declare function collectDueAttachments(state: AttachmentState, inp: AttachmentInputs): readonly TurnAttachment[];
|
|
122
119
|
export declare function renderToolSearchUsageReminder(undiscovered: readonly string[]): string;
|
|
@@ -178,14 +175,7 @@ export declare function renderMcpInstructionsDelta(added: ReadonlyArray<{
|
|
|
178
175
|
server: string;
|
|
179
176
|
text: string;
|
|
180
177
|
}>, removed: readonly string[]): string | undefined;
|
|
181
|
-
export declare function renderMcpDroppedTools(entries: ReadonlyArray<
|
|
182
|
-
server: string;
|
|
183
|
-
tool: string;
|
|
184
|
-
reason: string;
|
|
185
|
-
}>): string;
|
|
178
|
+
export declare function renderMcpDroppedTools(entries: ReadonlyArray<McpDroppedTool>): string;
|
|
186
179
|
export declare const MCP_DROPPED_BATCH_MAX_BYTES = 4096;
|
|
187
|
-
export declare function selectMcpDroppedBatch<T extends
|
|
188
|
-
|
|
189
|
-
tool: string;
|
|
190
|
-
reason: string;
|
|
191
|
-
}>(entries: ReadonlyArray<T>): T[];
|
|
180
|
+
export declare function selectMcpDroppedBatch<T extends McpDroppedTool>(entries: ReadonlyArray<T>): T[];
|
|
181
|
+
export declare function clipToBytes(s: string, maxBytes: number): string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface SafeNotifyFailure {
|
|
2
|
+
readonly site: string;
|
|
3
|
+
readonly error: Error;
|
|
4
|
+
readonly failures: number;
|
|
5
|
+
}
|
|
6
|
+
export interface SafeNotifierOptions {
|
|
7
|
+
readonly onError?: (failure: SafeNotifyFailure) => void;
|
|
8
|
+
}
|
|
9
|
+
export interface SafeNotifier {
|
|
10
|
+
notify(run: () => void, site: string): boolean;
|
|
11
|
+
notifyAsync(run: () => unknown, site: string): Promise<boolean>;
|
|
12
|
+
readonly failures: number;
|
|
13
|
+
failuresAt(site: string): number;
|
|
14
|
+
lastErrorAt(site: string): Error | undefined;
|
|
15
|
+
failedSites(): readonly string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function createSafeNotifier(opts?: SafeNotifierOptions): SafeNotifier;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export function createSafeNotifier(opts) {
|
|
2
|
+
const onError = opts?.onError;
|
|
3
|
+
let sites;
|
|
4
|
+
let total = 0;
|
|
5
|
+
const record = (site, thrown) => {
|
|
6
|
+
const error = thrown instanceof Error ? thrown : new Error(String(thrown));
|
|
7
|
+
total += 1;
|
|
8
|
+
if (sites === undefined)
|
|
9
|
+
sites = new Map();
|
|
10
|
+
const state = sites.get(site);
|
|
11
|
+
if (state !== undefined) {
|
|
12
|
+
state.count += 1;
|
|
13
|
+
state.last = error;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
sites.set(site, { count: 1, last: error });
|
|
17
|
+
if (onError === undefined)
|
|
18
|
+
return;
|
|
19
|
+
try {
|
|
20
|
+
onError({ site, error, failures: 1 });
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
notify(run, site) {
|
|
27
|
+
try {
|
|
28
|
+
run();
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
record(site, e);
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
async notifyAsync(run, site) {
|
|
37
|
+
try {
|
|
38
|
+
await run();
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
record(site, e);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
get failures() {
|
|
47
|
+
return total;
|
|
48
|
+
},
|
|
49
|
+
failuresAt(site) {
|
|
50
|
+
return sites?.get(site)?.count ?? 0;
|
|
51
|
+
},
|
|
52
|
+
lastErrorAt(site) {
|
|
53
|
+
return sites?.get(site)?.last;
|
|
54
|
+
},
|
|
55
|
+
failedSites() {
|
|
56
|
+
return sites === undefined ? [] : [...sites.keys()];
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { canonicalizeTarget, writeTargetPath } from "../tools/fs/safety.js";
|
|
2
|
-
import { canonicalToolName } from "./tool-name-aliases.js";
|
|
3
2
|
const DEFAULT_GUARDED_TOOLS = ["Write", "Edit", "MultiEdit", "NotebookEdit"];
|
|
4
3
|
export const RECOMMENDED_SENSITIVE_PATTERNS = [
|
|
5
4
|
".env",
|
|
@@ -28,8 +27,9 @@ export const RECOMMENDED_SENSITIVE_PATTERNS = [
|
|
|
28
27
|
];
|
|
29
28
|
function segmentGlobToRegExp(segment) {
|
|
30
29
|
const escaped = segment.replace(/[.+^${}()|[\]\\?]/g, "\\$&").replace(/\*/g, "[^/]*");
|
|
31
|
-
return new RegExp(`^${escaped}
|
|
30
|
+
return new RegExp(`^${escaped}$`, CASE_INSENSITIVE_FS ? "i" : "");
|
|
32
31
|
}
|
|
32
|
+
const CASE_INSENSITIVE_FS = process.platform === "darwin" || process.platform === "win32";
|
|
33
33
|
function compilePatterns(patterns) {
|
|
34
34
|
const out = [];
|
|
35
35
|
for (const raw of patterns) {
|
|
@@ -55,10 +55,10 @@ function matchSensitive(canonicalKey, compiled) {
|
|
|
55
55
|
}
|
|
56
56
|
export function createSensitivePathPolicy(opts) {
|
|
57
57
|
const compiled = compilePatterns(opts.patterns);
|
|
58
|
-
const guarded = new Set(
|
|
58
|
+
const guarded = new Set(opts.tools ?? DEFAULT_GUARDED_TOOLS);
|
|
59
59
|
return {
|
|
60
60
|
async check(req, signal) {
|
|
61
|
-
const canonical =
|
|
61
|
+
const canonical = req.toolName;
|
|
62
62
|
if (compiled.length === 0 || !guarded.has(canonical))
|
|
63
63
|
return { action: "allow" };
|
|
64
64
|
const path = writeTargetPath(canonical, req.args);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { canonicalToolName } from "./tool-name-aliases.js";
|
|
2
1
|
const INTERRUPTED_UNKNOWN = "[INTERRUPTED] The previous run ended before this tool call's result was recorded. Its outcome " +
|
|
3
2
|
"is UNKNOWN — the action may have completed, partially completed, or never run. Do not assume " +
|
|
4
3
|
"success or failure. Before relying on it: if it is safe to read, query the current state to " +
|
|
@@ -72,7 +71,7 @@ export async function reconcileInterruptedSession(session, toolEffects, suspende
|
|
|
72
71
|
const orphans = findOrphanToolCalls(messages, suspendedBatch).filter((o) => o.kind !== "result");
|
|
73
72
|
const recovered = [];
|
|
74
73
|
for (const orphan of orphans) {
|
|
75
|
-
const effect = toolEffects?.get(
|
|
74
|
+
const effect = toolEffects?.get(orphan.toolName) ?? "write";
|
|
76
75
|
const effectText = effect === "read" ? INTERRUPTED_SAFE : effect === "idempotent" ? INTERRUPTED_IDEMPOTENT : INTERRUPTED_UNKNOWN;
|
|
77
76
|
const neverStarted = startedToolCallIds !== undefined && !startedToolCallIds.has(orphan.toolCallId);
|
|
78
77
|
const text = neverStarted ? INTERRUPTED_NEVER_STARTED : effectText;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { parsePermissionRule, wildcardMatch } from "./permission-rules.js";
|
|
2
|
-
import { canonicalToolName } from "./tool-name-aliases.js";
|
|
3
2
|
import { COARSE_SHELL_TOOLS } from "./tool-policy.js";
|
|
4
3
|
import { parseLeadingCommandName } from "../tools/fs/bash-readonly-classifier.js";
|
|
5
|
-
const SPECIFIER_ENFORCED_TOOLS = new Set(COARSE_SHELL_TOOLS
|
|
4
|
+
const SPECIFIER_ENFORCED_TOOLS = new Set(COARSE_SHELL_TOOLS);
|
|
6
5
|
export function parseSkillToolEntry(entry) {
|
|
7
6
|
const parsed = parsePermissionRule(entry);
|
|
8
|
-
const name =
|
|
7
|
+
const name = parsed.toolName;
|
|
9
8
|
return parsed.ruleContent === undefined ? { raw: entry, name } : { raw: entry, name, specifier: parsed.ruleContent };
|
|
10
9
|
}
|
|
11
10
|
export function isSkillSpecifierEnforced(canonicalName) {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
|
|
2
2
|
import { isAbsolute, join, relative } from "node:path";
|
|
3
|
-
import { canonicalToolName } from "./tool-name-aliases.js";
|
|
4
3
|
import { isSkillSpecifierEnforced, parseSkillToolEntry } from "./skill-tool-specifier.js";
|
|
5
4
|
const SKILL_FILE = "SKILL.md";
|
|
6
5
|
const RESOURCE_DIRS = ["assets", "references", "scripts"];
|
|
@@ -340,7 +339,7 @@ function manifestFromAllowedTools(declared, disallowed, skillName, deployedTools
|
|
|
340
339
|
return undefined;
|
|
341
340
|
let allowTools = names;
|
|
342
341
|
if (deployedTools !== undefined) {
|
|
343
|
-
const mounted = new Set(deployedTools
|
|
342
|
+
const mounted = new Set(deployedTools);
|
|
344
343
|
allowTools = names.filter((n) => mounted.has(parseSkillToolEntry(n).name));
|
|
345
344
|
for (const n of names) {
|
|
346
345
|
if (!mounted.has(parseSkillToolEntry(n).name)) {
|
|
@@ -353,7 +352,7 @@ function manifestFromAllowedTools(declared, disallowed, skillName, deployedTools
|
|
|
353
352
|
}
|
|
354
353
|
}
|
|
355
354
|
if (disallowed.length > 0) {
|
|
356
|
-
const denied = new Set(disallowed
|
|
355
|
+
const denied = new Set(disallowed);
|
|
357
356
|
allowTools = allowTools.filter((n) => !denied.has(parseSkillToolEntry(n).name));
|
|
358
357
|
}
|
|
359
358
|
return { allowTools, lineageId: `skill:${skillName}` };
|
|
@@ -20,7 +20,7 @@ export function createCheckpointFixture(over = {}) {
|
|
|
20
20
|
},
|
|
21
21
|
state: {
|
|
22
22
|
activeTools: [],
|
|
23
|
-
nestedStats: { tokens: 0, turns: 0, tasks: 0, costMicroUsd: 0 },
|
|
23
|
+
nestedStats: { tokens: 0, turns: 0, tasks: 0, costMicroUsd: 0, anyUnpriced: false },
|
|
24
24
|
},
|
|
25
25
|
status: "pending",
|
|
26
26
|
createdAt: 1_700_000_000_000,
|
package/dist/core/stub-env.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ExecutionEnv, ExecutionError, FileError, type FileInfo, type Result } from "../internal/harness.js";
|
|
1
|
+
import { type ExecResult, type ExecutionEnv, ExecutionError, FileError, type FileInfo, type Result } from "../internal/harness.js";
|
|
2
2
|
export declare class StubExecutionEnv implements ExecutionEnv {
|
|
3
3
|
cwd: string;
|
|
4
4
|
constructor(cwd?: string);
|
|
@@ -18,10 +18,6 @@ export declare class StubExecutionEnv implements ExecutionEnv {
|
|
|
18
18
|
remove(path: string): Promise<Result<void, FileError>>;
|
|
19
19
|
createTempDir(): Promise<Result<string, FileError>>;
|
|
20
20
|
createTempFile(): Promise<Result<string, FileError>>;
|
|
21
|
-
exec(): Promise<Result<
|
|
22
|
-
stdout: string;
|
|
23
|
-
stderr: string;
|
|
24
|
-
exitCode: number;
|
|
25
|
-
}, ExecutionError>>;
|
|
21
|
+
exec(): Promise<Result<ExecResult, ExecutionError>>;
|
|
26
22
|
cleanup(): Promise<void>;
|
|
27
23
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const isHighSurrogate = (c) => c >= 0xd800 && c <= 0xdbff;
|
|
2
|
+
export const isLowSurrogate = (c) => c >= 0xdc00 && c <= 0xdfff;
|
|
3
|
+
export function sliceHeadSafe(s, keep) {
|
|
4
|
+
if (keep <= 0)
|
|
5
|
+
return "";
|
|
6
|
+
if (s.length <= keep)
|
|
7
|
+
return s;
|
|
8
|
+
const head = s.slice(0, keep);
|
|
9
|
+
return keep > 0 && isHighSurrogate(head.charCodeAt(keep - 1)) ? head.slice(0, -1) : head;
|
|
10
|
+
}
|
|
11
|
+
export function sliceTailSafe(s, keep) {
|
|
12
|
+
if (keep <= 0)
|
|
13
|
+
return "";
|
|
14
|
+
if (s.length <= keep)
|
|
15
|
+
return s;
|
|
16
|
+
const tail = s.slice(-keep);
|
|
17
|
+
return keep > 0 && isLowSurrogate(tail.charCodeAt(0)) ? tail.slice(1) : tail;
|
|
18
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { delimitUntrusted } from "./untrusted-text.js";
|
|
2
|
-
import { assertOwnership, defaultMonitorTimers, MONITOR_MAX_TIMEOUT_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_BATCH_WINDOW_MS, MONITOR_MAX_BATCHES_PER_MINUTE, MONITOR_STORM_BURST, MONITOR_STORM_KILL_AFTER_MS, MONITOR_LINE_BUF_CAP, MONITOR_SPILL_CAP_CHARS, TASK_OUTPUT_MAX_CHARS, mintCompletionId, clipMonitorEvent, clipMonitorLine, terminalTaskSummary, accountDroppedBytes, rollSpoolText, statusFromBackground, droppedGapNote, firstDropNote, alreadyTerminalStopNote, clipTaskOutput, sleepPollStep, } from "./task-registry-shared.js";
|
|
2
|
+
import { assertOwnership, defaultMonitorTimers, MONITOR_MAX_TIMEOUT_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_BATCH_WINDOW_MS, MONITOR_MAX_BATCHES_PER_MINUTE, MONITOR_STORM_BURST, MONITOR_STORM_KILL_AFTER_MS, MONITOR_LINE_BUF_CAP, MONITOR_SPILL_CAP_CHARS, TASK_OUTPUT_MAX_CHARS, mintCompletionId, clipMonitorEvent, clipMonitorLine, terminalTaskSummary, accountDroppedBytes, renderSpoolBody, rollSpoolText, statusFromBackground, droppedGapNote, firstDropNote, alreadyTerminalStopNote, clipTaskOutput, sleepPollStep, } from "./task-registry-shared.js";
|
|
3
3
|
import { buildToolResultRef, OFFLOAD_TOOL_NAME } from "./tool-result-store.js";
|
|
4
4
|
export function registerMonitorLane(core, input) {
|
|
5
5
|
assertOwnership(input, "registerMonitor");
|
|
@@ -318,18 +318,13 @@ export async function pollMonitorLane(handle, filter, deadline, signal) {
|
|
|
318
318
|
const shape = (text) => clipTaskOutput(rx ? text.split(/\r?\n/).filter((l) => rx.test(l)).join("\n") : text, handle.outputFile);
|
|
319
319
|
const running = handle.status === "running";
|
|
320
320
|
const retrieval = running && deadline !== undefined && Date.now() >= deadline ? "timeout" : "success";
|
|
321
|
-
const
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
: spool.
|
|
327
|
-
|
|
328
|
-
: "";
|
|
329
|
-
const drainNote = spool.drainFailed === true ? "[!] the final output drain at stop failed — the tail of the output may be missing\n" : "";
|
|
330
|
-
const stdoutHeading = droppedNote !== "" || drainNote !== "" ? "stdout (re-readable spool — INCOMPLETE, see note above)" : "stdout (full, re-readable)";
|
|
331
|
-
const body = `status: ${displayStatus}\n${rolledNote}${droppedNote}${drainNote}--- ${stdoutHeading} ---\n${shape(spool.stdout) || "(none)"}\n` +
|
|
332
|
-
`--- stderr ---\n${shape(spool.stderr) || "(none)"}`;
|
|
321
|
+
const body = renderSpoolBody(spool, {
|
|
322
|
+
running,
|
|
323
|
+
handleStatus: handle.status,
|
|
324
|
+
shape,
|
|
325
|
+
rolledExtraClause: monitorSpillNote(handle),
|
|
326
|
+
drainNote: spool.drainFailed === true ? "[!] the final output drain at stop failed — the tail of the output may be missing\n" : "",
|
|
327
|
+
});
|
|
333
328
|
return {
|
|
334
329
|
content: delimitUntrusted(`TaskOutput ${handle.id}`, body),
|
|
335
330
|
details: {
|
|
@@ -104,7 +104,7 @@ export interface BackgroundAgentTaskHandle extends SemaTaskHandle {
|
|
|
104
104
|
durable?: DurableAgentLane;
|
|
105
105
|
notify?: (notification: import("./task-notification.js").TaskNotificationPayload, opts?: {
|
|
106
106
|
priority?: import("./task-notification.js").SystemInjectionPriority;
|
|
107
|
-
}) =>
|
|
107
|
+
}) => "queued" | "parked" | "dropped_duplicate" | Promise<"queued" | "parked" | "dropped_duplicate">;
|
|
108
108
|
retainedContinuation?: boolean;
|
|
109
109
|
reviveCycle?: number;
|
|
110
110
|
cycleSeq?: number;
|
|
@@ -252,6 +252,28 @@ export declare function accountDroppedBytes(spool: {
|
|
|
252
252
|
truncated?: boolean;
|
|
253
253
|
bytesDroppedBeforeCursor?: number;
|
|
254
254
|
}): void;
|
|
255
|
+
export declare function spoolDropNote(acct: {
|
|
256
|
+
droppedBytes?: number;
|
|
257
|
+
dropUnknown?: true;
|
|
258
|
+
}): string;
|
|
259
|
+
export interface RenderableSpool {
|
|
260
|
+
stdout: string;
|
|
261
|
+
stderr: string;
|
|
262
|
+
rolledChars: number;
|
|
263
|
+
exitCode?: number;
|
|
264
|
+
timedOut?: boolean;
|
|
265
|
+
timeoutSec?: number;
|
|
266
|
+
droppedBytes?: number;
|
|
267
|
+
dropUnknown?: true;
|
|
268
|
+
}
|
|
269
|
+
export interface SpoolBodyOptions {
|
|
270
|
+
running: boolean;
|
|
271
|
+
handleStatus: SemaTaskStatus;
|
|
272
|
+
shape: (text: string) => string;
|
|
273
|
+
rolledExtraClause: string;
|
|
274
|
+
drainNote: string;
|
|
275
|
+
}
|
|
276
|
+
export declare function renderSpoolBody(spool: RenderableSpool, opts: SpoolBodyOptions): string;
|
|
255
277
|
export declare function droppedGapNote(spool: {
|
|
256
278
|
droppedBytes?: number;
|
|
257
279
|
dropUnknown?: true;
|
|
@@ -102,6 +102,22 @@ export function accountDroppedBytes(spool, poll) {
|
|
|
102
102
|
else if (poll.truncated === true)
|
|
103
103
|
spool.dropUnknown = true;
|
|
104
104
|
}
|
|
105
|
+
export function spoolDropNote(acct) {
|
|
106
|
+
if ((acct.droppedBytes ?? 0) > 0)
|
|
107
|
+
return `[!] ${acct.droppedBytes} earlier byte(s) permanently dropped before this window (8MB buffer evicted)\n`;
|
|
108
|
+
if (acct.dropUnknown === true)
|
|
109
|
+
return "[!] an unknown amount of earlier output was permanently dropped before this window (buffer evicted)\n";
|
|
110
|
+
return "";
|
|
111
|
+
}
|
|
112
|
+
export function renderSpoolBody(spool, opts) {
|
|
113
|
+
const timedOutClause = spool.timedOut === true ? ` (timed out after ${spool.timeoutSec !== undefined ? `${spool.timeoutSec}s` : "its background time budget"})` : "";
|
|
114
|
+
const displayStatus = (spool.exitCode !== undefined ? `exited(code ${spool.exitCode})` : opts.running ? "running" : opts.handleStatus) + timedOutClause;
|
|
115
|
+
const rolledNote = spool.rolledChars > 0 ? `[!] ${spool.rolledChars} earlier char(s) dropped from the spool (memory bound)${opts.rolledExtraClause}\n` : "";
|
|
116
|
+
const droppedNote = spoolDropNote(spool);
|
|
117
|
+
const stdoutHeading = droppedNote !== "" || opts.drainNote !== "" ? "stdout (re-readable spool — INCOMPLETE, see note above)" : "stdout (full, re-readable)";
|
|
118
|
+
return (`status: ${displayStatus}\n${rolledNote}${droppedNote}${opts.drainNote}--- ${stdoutHeading} ---\n${opts.shape(spool.stdout) || "(none)"}\n` +
|
|
119
|
+
`--- stderr ---\n${opts.shape(spool.stderr) || "(none)"}`);
|
|
120
|
+
}
|
|
105
121
|
export function droppedGapNote(spool) {
|
|
106
122
|
if ((spool.droppedBytes ?? 0) > 0)
|
|
107
123
|
return ` [!] ${spool.droppedBytes} earlier byte(s) of output were permanently dropped before this window (execution-environment tail buffer evicted) — the event stream and this spool are INCOMPLETE.`;
|
|
@@ -63,12 +63,17 @@ export interface AccessibleTaskRow {
|
|
|
63
63
|
parentTaskId?: string;
|
|
64
64
|
parentSessionId?: string;
|
|
65
65
|
rootSessionId?: string;
|
|
66
|
+
createdAt?: number;
|
|
66
67
|
}
|
|
67
68
|
export declare class TaskRegistry {
|
|
68
69
|
private handles;
|
|
69
70
|
private sessionReapHooks;
|
|
70
71
|
private bgQuiescenceWatchers;
|
|
71
|
-
private
|
|
72
|
+
private readonly notifier;
|
|
73
|
+
notifierFailureCounts(): ReadonlyArray<{
|
|
74
|
+
site: string;
|
|
75
|
+
count: number;
|
|
76
|
+
}>;
|
|
72
77
|
private readonly core;
|
|
73
78
|
durableAgentArmed(id: string): boolean;
|
|
74
79
|
durableAgentRowProbe(id: string): (() => Promise<boolean>) | undefined;
|