@sema-agent/core 1.451.0 → 2.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/dist/agents/agent-transcript-tool.d.ts +15 -0
- package/dist/agents/agent-transcript-tool.js +122 -0
- package/dist/agents/cascade.js +5 -8
- package/dist/agents/observer.js +3 -0
- package/dist/agents/repair-loop.d.ts +1 -1
- package/dist/agents/repair-loop.js +1 -1
- package/dist/agents/retain-ledger.d.ts +60 -0
- package/dist/agents/retain-ledger.js +225 -0
- package/dist/agents/roster-store.d.ts +1 -0
- package/dist/agents/roster-store.js +9 -0
- package/dist/agents/send-message-tool.d.ts +41 -0
- package/dist/agents/send-message-tool.js +469 -0
- package/dist/agents/subagent.d.ts +33 -108
- package/dist/agents/subagent.js +40 -813
- package/dist/agents/teacher.d.ts +0 -1
- package/dist/agents/teacher.js +0 -9
- package/dist/bin/sema-tb.js +3 -3
- package/dist/brain/anthropic.js +15 -40
- package/dist/brain/openai.js +15 -40
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/stream-engine.js +2 -2
- package/dist/brain/stream-shared.d.ts +17 -0
- package/dist/brain/stream-shared.js +50 -0
- package/dist/brain/timeout.d.ts +1 -1
- package/dist/brain/timeout.js +1 -1
- package/dist/config/catalog.js +1 -3
- package/dist/config/defaults.d.ts +6 -0
- package/dist/config/defaults.js +6 -0
- package/dist/core/ask-question.d.ts +1 -1
- package/dist/core/ask-question.js +5 -5
- package/dist/core/background-agent-store.d.ts +2 -0
- package/dist/core/background-agent-store.js +5 -1
- package/dist/core/background-shell.d.ts +1 -1
- package/dist/core/checkpoint-store.d.ts +0 -1
- package/dist/core/exec-gate.d.ts +1 -1
- package/dist/core/exec-output-tail.d.ts +19 -1
- package/dist/core/exec-output-tail.js +44 -5
- package/dist/core/file-snapshot-store.d.ts +1 -1
- package/dist/core/fs-write-gate-policy.d.ts +1 -1
- package/dist/core/git-worktree-env.d.ts +1 -1
- package/dist/core/hooks.d.ts +1 -1
- package/dist/core/image-downsample.d.ts +44 -0
- package/dist/core/image-downsample.js +97 -0
- package/dist/core/lsp-session.d.ts +1 -0
- package/dist/core/lsp-session.js +24 -6
- package/dist/core/lsp.d.ts +11 -1
- package/dist/core/lsp.js +63 -6
- package/dist/core/mailbox-store.d.ts +3 -2
- package/dist/core/mailbox-store.js +19 -4
- package/dist/core/mcp.d.ts +3 -45
- package/dist/core/mcp.js +2 -97
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-recall.d.ts +0 -12
- package/dist/core/memory-recall.js +0 -222
- package/dist/core/memory.d.ts +0 -6
- package/dist/core/memory.js +0 -88
- package/dist/core/message-utils.d.ts +1 -1
- package/dist/core/oracle-isolation.d.ts +1 -1
- package/dist/core/remote-env.d.ts +1 -1
- package/dist/core/roles.d.ts +1 -1
- package/dist/core/runner/active-skill-scope.d.ts +1 -1
- package/dist/core/runner/assemble-result.d.ts +0 -2
- package/dist/core/runner/memory-consolidation.d.ts +1 -1
- package/dist/core/runner/prepare-memory.d.ts +16 -0
- package/dist/core/runner/prepare-memory.js +191 -0
- package/dist/core/runner/prepare-task.d.ts +4 -28
- package/dist/core/runner/prepare-task.js +29 -208
- package/dist/core/runner/prompt-suggestions.d.ts +1 -1
- package/dist/core/runner/runtask.d.ts +2 -3
- package/dist/core/runner/runtask.js +337 -529
- package/dist/core/runner/session-rule-policy.d.ts +1 -1
- package/dist/core/runner/synthetic-tools.d.ts +5 -5
- package/dist/core/runner/synthetic-tools.js +4 -4
- package/dist/core/runner/tool-disclosure.d.ts +3 -3
- package/dist/core/runner/tool-disclosure.js +2 -2
- package/dist/core/runner/tool-output-projection.d.ts +6 -0
- package/dist/core/runner/tool-output-projection.js +81 -0
- package/dist/core/runtime.d.ts +1 -1
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/session-reconcile.d.ts +1 -1
- package/dist/core/session-reconcile.js +5 -2
- package/dist/core/session-store.d.ts +2 -1
- package/dist/core/session-store.js +2 -1
- package/dist/core/session.d.ts +0 -1
- package/dist/core/task-notification.d.ts +1 -0
- package/dist/core/task-registry-agent.d.ts +115 -0
- package/dist/core/task-registry-agent.js +1163 -0
- package/dist/core/task-registry-monitor.d.ts +13 -0
- package/dist/core/task-registry-monitor.js +347 -0
- package/dist/core/task-registry-shared.d.ts +294 -0
- package/dist/core/task-registry-shared.js +271 -0
- package/dist/core/task-registry-workflow.d.ts +5 -0
- package/dist/core/task-registry-workflow.js +143 -0
- package/dist/core/task-registry.d.ts +54 -213
- package/dist/core/task-registry.js +190 -1766
- package/dist/core/task-tool-shape.d.ts +32 -0
- package/dist/core/task-tool-shape.js +83 -0
- package/dist/core/tool-policy.d.ts +1 -2
- package/dist/core/tool-result-budget.d.ts +1 -1
- package/dist/core/tool-result-store.d.ts +2 -2
- package/dist/core/tool-result-store.js +3 -3
- package/dist/core/tools.d.ts +7 -3
- package/dist/core/tools.js +3 -8
- package/dist/core/trace.d.ts +2 -2
- package/dist/core/types.d.ts +1 -29
- package/dist/core/workflow-journal-store.d.ts +2 -0
- package/dist/core/workflow-journal-store.js +14 -0
- package/dist/core/workflow-run-store-contract.d.ts +1 -1
- package/dist/core/workflow-run-store-contract.js +19 -19
- package/dist/engine/execution-env/node-execution-env.d.ts +14 -0
- package/dist/engine/execution-env/node-execution-env.js +184 -44
- package/dist/engine/lsp/frame-decoder.d.ts +1 -1
- package/dist/engine/lsp/frame-decoder.js +1 -1
- package/dist/engine/lsp/node-lsp-manager.d.ts +4 -2
- package/dist/engine/lsp/node-lsp-manager.js +22 -5
- package/dist/engine/lsp/stdio-lsp-transport.d.ts +1 -1
- package/dist/engine/lsp/stdio-lsp-transport.js +19 -8
- package/dist/index.d.ts +18 -16
- package/dist/index.js +15 -13
- package/dist/internal/harness-types.d.ts +7 -0
- package/dist/internal/harness-types.js +1 -0
- package/dist/internal/harness.d.ts +1 -7
- package/dist/internal/harness.js +1 -0
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +2 -1
- package/dist/orchestration/run-workflow-tool.js +29 -6
- package/dist/orchestration/workflow-types.d.ts +193 -0
- package/dist/orchestration/workflow-types.js +54 -0
- package/dist/orchestration/workflow.d.ts +3 -184
- package/dist/orchestration/workflow.js +87 -64
- package/dist/prompt-assembly/assemble.d.ts +3 -3
- package/dist/prompt-assembly/assemble.js +0 -16
- package/dist/prompt-assembly/explain.d.ts +1 -1
- package/dist/prompt-assembly/tool-catalog.d.ts +1 -1
- package/dist/prompts/default.d.ts +1 -6
- package/dist/prompts/default.js +3 -11
- package/dist/scenarios/env.d.ts +1 -1
- package/dist/scenarios/full-body.d.ts +0 -3
- package/dist/scenarios/full-body.js +0 -2
- package/dist/stores/cc/mailbox-store.js +6 -1
- package/dist/stores/file/background-agent-store.d.ts +2 -15
- package/dist/stores/file/background-agent-store.js +33 -102
- package/dist/stores/file/checkpoint-store.d.ts +1 -14
- package/dist/stores/file/checkpoint-store.js +47 -119
- package/dist/stores/file/file-snapshot-store.d.ts +1 -1
- package/dist/stores/file/mailbox-store.d.ts +1 -1
- package/dist/stores/file/mailbox-store.js +9 -7
- package/dist/stores/file/shared-ledger.d.ts +35 -0
- package/dist/stores/file/shared-ledger.js +94 -0
- package/dist/stores/file/workflow-run-store.d.ts +1 -14
- package/dist/stores/file/workflow-run-store.js +24 -93
- package/dist/tools/fs/bash-readonly-classifier.d.ts +8 -0
- package/dist/tools/fs/bash-readonly-classifier.js +166 -0
- package/dist/tools/fs/encoding.d.ts +5 -0
- package/dist/tools/fs/encoding.js +6 -0
- package/dist/tools/fs/fs-bash.d.ts +31 -0
- package/dist/tools/fs/fs-bash.js +672 -0
- package/dist/tools/fs/fs-pdf.d.ts +22 -0
- package/dist/tools/fs/fs-pdf.js +236 -0
- package/dist/tools/fs/fs-read.d.ts +8 -0
- package/dist/tools/fs/fs-read.js +286 -0
- package/dist/tools/fs/fs-search-tools.d.ts +5 -0
- package/dist/tools/fs/fs-search-tools.js +173 -0
- package/dist/tools/fs/fs-shared.d.ts +55 -0
- package/dist/tools/fs/fs-shared.js +144 -0
- package/dist/tools/fs/fs-write.d.ts +8 -0
- package/dist/tools/fs/fs-write.js +423 -0
- package/dist/tools/fs/index.d.ts +12 -65
- package/dist/tools/fs/index.js +26 -2026
- package/dist/tools/fs/notebook.d.ts +43 -0
- package/dist/tools/fs/notebook.js +141 -0
- package/dist/tools/fs/pdf.d.ts +1 -1
- package/dist/tools/fs/repo-map.d.ts +3 -3
- package/dist/tools/fs/repo-map.js +3 -3
- package/dist/tools/fs/safety.d.ts +1 -1
- package/dist/tools/fs/search.d.ts +1 -1
- package/dist/tools/fs/search.js +141 -12
- package/dist/tools/gitea-issue.js +4 -2
- package/dist/tools/monitor.d.ts +1 -1
- package/dist/tools/monitor.js +12 -8
- package/dist/tools/scheduler-tools.d.ts +1 -1
- package/dist/tools/scheduler-tools.js +16 -16
- package/dist/tools/task-list.js +34 -12
- package/dist/tools/web.d.ts +4 -2
- package/dist/tools/web.js +106 -20
- package/dist/tools/worktree.d.ts +1 -1
- package/dist/tools/worktree.js +14 -14
- package/package.json +1 -1
- package/dist/core/dynamic-recall.d.ts +0 -32
- package/dist/core/dynamic-recall.js +0 -76
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { deriveControlPlaneDir, deriveProjectControlDir, deriveProjectMemoryDir, deriveRepoMemoryDir, drainMemoryAnnouncements, enqueueMemoryAnnouncement, lookupProjectIdHint, recordProjectIdHint, resolveMemoryEngineRoot } from "../memory-engine/layout.js";
|
|
2
|
+
import { classifyScopePlanes, derivePersonalControlDir, derivePersonalMemoryDir, mergeHarvestReports, mergeInjections, needsDualRoots, parsedProjectPlane } from "../memory-engine/dual-root.js";
|
|
3
|
+
import { normalizeMemorySpec } from "../memory.js";
|
|
4
|
+
import { MemoryEngine } from "../memory-engine/engine.js";
|
|
5
|
+
import { assertScopeContractPlacement, parseScopeKey, resolveProjectId } from "../memory-engine/scope-contract.js";
|
|
6
|
+
import { FileMemoryEngineBackend } from "../memory-engine/file-backend.js";
|
|
7
|
+
export async function prepareMemory(input) {
|
|
8
|
+
const { spec, deps, sessionId, taskRootPath, memoryWriteGateRef } = input;
|
|
9
|
+
const memorySpec = normalizeMemorySpec(spec.memory);
|
|
10
|
+
const useMemoryEngine = Boolean(memorySpec && memorySpec.enabled && deps.memoryBackend);
|
|
11
|
+
let memoryEngineSession;
|
|
12
|
+
if (useMemoryEngine && memorySpec) {
|
|
13
|
+
try {
|
|
14
|
+
const backend = deps.memoryBackend;
|
|
15
|
+
const pinned = backend.directoryRoot;
|
|
16
|
+
const engineRoot = resolveMemoryEngineRoot(deps.memoryEngineDir);
|
|
17
|
+
const repoRoot = deps.rootPath ?? taskRootPath;
|
|
18
|
+
let identityKey;
|
|
19
|
+
if (memorySpec.scopeContract === "v2" && repoRoot) {
|
|
20
|
+
const consumesProjectIdentity = [...memorySpec.scopes, ...(memorySpec.writeScope !== null ? [memorySpec.writeScope] : [])]
|
|
21
|
+
.map(parseScopeKey)
|
|
22
|
+
.some((k) => k.kind === "proj" || k.kind === "userproj");
|
|
23
|
+
let marker = null;
|
|
24
|
+
try {
|
|
25
|
+
marker = resolveProjectId(repoRoot);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
if (consumesProjectIdentity)
|
|
29
|
+
throw err;
|
|
30
|
+
deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "config", sessionId });
|
|
31
|
+
}
|
|
32
|
+
if (marker) {
|
|
33
|
+
identityKey = marker.projectId;
|
|
34
|
+
const firstSwitch = lookupProjectIdHint(engineRoot, repoRoot) !== marker.projectId;
|
|
35
|
+
recordProjectIdHint(engineRoot, repoRoot, marker.projectId);
|
|
36
|
+
if (firstSwitch) {
|
|
37
|
+
try {
|
|
38
|
+
const oldCtl = deriveControlPlaneDir(engineRoot, repoRoot);
|
|
39
|
+
const newCtl = deriveProjectControlDir(engineRoot, marker.projectId);
|
|
40
|
+
const drained = drainMemoryAnnouncements(oldCtl);
|
|
41
|
+
for (const ann of drained.queue)
|
|
42
|
+
enqueueMemoryAnnouncement(newCtl, ann);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (memorySpec.writeScope !== null) {
|
|
48
|
+
const w = parseScopeKey(memorySpec.writeScope);
|
|
49
|
+
if ((w.kind === "proj" || w.kind === "userproj") && w.projectId !== marker.projectId) {
|
|
50
|
+
const e = new Error(`memory scope contract v2: writeScope ${memorySpec.writeScope} targets projectId ${w.projectId}, ` +
|
|
51
|
+
`but this checkout's marker (.sema/project) declares ${marker.projectId} — refusing a mis-addressed write.`);
|
|
52
|
+
e.code = "config.memory_project_identity";
|
|
53
|
+
throw e;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const hint = lookupProjectIdHint(engineRoot, repoRoot);
|
|
59
|
+
if (hint !== undefined) {
|
|
60
|
+
deps.onError?.(new Error(`memory project marker missing but recoverable: ${repoRoot} previously carried projectId ${hint} ` +
|
|
61
|
+
`(.sema/project deleted?). Restore the marker to keep the identity-keyed memory mount; this session ` +
|
|
62
|
+
`falls back to the path-derived key.`), { phase: "config", sessionId });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const memoryDir = typeof pinned === "string" && pinned
|
|
67
|
+
? pinned
|
|
68
|
+
: identityKey !== undefined
|
|
69
|
+
? deriveProjectMemoryDir(engineRoot, identityKey)
|
|
70
|
+
: deriveRepoMemoryDir(engineRoot, repoRoot);
|
|
71
|
+
const planes = memorySpec.scopeContract === "v2" ? classifyScopePlanes(memorySpec.scopes, memorySpec.writeScope) : undefined;
|
|
72
|
+
const dual = planes !== undefined && needsDualRoots(planes);
|
|
73
|
+
const personalOnly = planes !== undefined && !dual && planes.project.length === 0 && planes.writePlane !== "project" && (planes.personal.length > 0 || planes.writePlane === "personal");
|
|
74
|
+
if (memorySpec.scopeContract === "v2" && !personalOnly) {
|
|
75
|
+
assertScopeContractPlacement({
|
|
76
|
+
parsedScopes: dual
|
|
77
|
+
? parsedProjectPlane(planes, memorySpec.writeScope)
|
|
78
|
+
: [...memorySpec.scopes, ...(memorySpec.writeScope !== null ? [memorySpec.writeScope] : [])].map(parseScopeKey),
|
|
79
|
+
memoryDir,
|
|
80
|
+
repoRoot,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const personalMemoryDir = derivePersonalMemoryDir(engineRoot);
|
|
84
|
+
const personalControlDir = derivePersonalControlDir(engineRoot);
|
|
85
|
+
const createPersonalEngine = () => new MemoryEngine({
|
|
86
|
+
backend: typeof pinned === "string" && pinned
|
|
87
|
+
? new FileMemoryEngineBackend(personalMemoryDir, { controlDir: personalControlDir })
|
|
88
|
+
: backend,
|
|
89
|
+
memoryDir: personalMemoryDir,
|
|
90
|
+
controlDir: personalControlDir,
|
|
91
|
+
});
|
|
92
|
+
let writeEngine;
|
|
93
|
+
let writeHandle;
|
|
94
|
+
let injectFn;
|
|
95
|
+
let harvestBoth;
|
|
96
|
+
if (dual) {
|
|
97
|
+
const projectEngine = new MemoryEngine({
|
|
98
|
+
backend,
|
|
99
|
+
memoryDir,
|
|
100
|
+
controlDir: identityKey !== undefined ? deriveProjectControlDir(engineRoot, identityKey) : deriveControlPlaneDir(engineRoot, repoRoot),
|
|
101
|
+
});
|
|
102
|
+
const personalEngine = createPersonalEngine();
|
|
103
|
+
const p = planes;
|
|
104
|
+
const projectHandle = await projectEngine.materialize(p.project, p.writePlane === "project" ? memorySpec.writeScope : null);
|
|
105
|
+
const personalHandle = await personalEngine.materialize(p.personal, p.writePlane === "personal" ? memorySpec.writeScope : null);
|
|
106
|
+
const writeIsPersonal = p.writePlane === "personal";
|
|
107
|
+
writeEngine = writeIsPersonal ? personalEngine : projectEngine;
|
|
108
|
+
writeHandle = writeIsPersonal ? personalHandle : projectHandle;
|
|
109
|
+
injectFn = () => mergeInjections(projectEngine.inject(projectHandle), personalEngine.inject(personalHandle));
|
|
110
|
+
harvestBoth = async () => {
|
|
111
|
+
const writeFirst = writeIsPersonal ? [personalEngine, personalHandle] : [projectEngine, projectHandle];
|
|
112
|
+
const readOther = writeIsPersonal ? [projectEngine, projectHandle] : [personalEngine, personalHandle];
|
|
113
|
+
const writeReport = await writeFirst[0].harvest(writeFirst[1]);
|
|
114
|
+
let readReport;
|
|
115
|
+
let readFailure;
|
|
116
|
+
try {
|
|
117
|
+
readReport = await readOther[0].harvest(readOther[1]);
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
readFailure = err instanceof Error ? err.message : String(err);
|
|
121
|
+
}
|
|
122
|
+
const merged = readReport !== undefined ? mergeHarvestReports(writeReport, readReport) : writeReport;
|
|
123
|
+
if (readFailure !== undefined)
|
|
124
|
+
merged.warnings.push(`read-plane harvest failed (write-plane yield committed): ${readFailure}`);
|
|
125
|
+
return merged;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
else if (personalOnly) {
|
|
129
|
+
const personalEngine = createPersonalEngine();
|
|
130
|
+
const handle = await personalEngine.materialize(memorySpec.scopes, memorySpec.writeScope);
|
|
131
|
+
writeEngine = personalEngine;
|
|
132
|
+
writeHandle = handle;
|
|
133
|
+
injectFn = () => personalEngine.inject(handle);
|
|
134
|
+
harvestBoth = () => personalEngine.harvest(handle);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const engine = new MemoryEngine({
|
|
138
|
+
backend,
|
|
139
|
+
memoryDir,
|
|
140
|
+
controlDir: identityKey !== undefined ? deriveProjectControlDir(engineRoot, identityKey) : deriveControlPlaneDir(engineRoot, repoRoot),
|
|
141
|
+
});
|
|
142
|
+
const handle = await engine.materialize(memorySpec.scopes, memorySpec.writeScope);
|
|
143
|
+
writeEngine = engine;
|
|
144
|
+
writeHandle = handle;
|
|
145
|
+
injectFn = () => engine.inject(handle);
|
|
146
|
+
harvestBoth = () => engine.harvest(handle);
|
|
147
|
+
}
|
|
148
|
+
memoryWriteGateRef.current = (w) => writeEngine.gateWrite(writeHandle, w.key, w.content);
|
|
149
|
+
const harvestSafe = async (phase = "terminal") => {
|
|
150
|
+
try {
|
|
151
|
+
const report = await harvestBoth();
|
|
152
|
+
if (!report.ok && report.incident) {
|
|
153
|
+
deps.onError?.(new Error(`memory harvest refused (${report.incident.kind}): ${report.incident.detail}`), { phase: "memory", sessionId });
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
deps.onMemoryHarvestReport?.(report, { sessionId, phase });
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
}
|
|
160
|
+
return report;
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
try {
|
|
164
|
+
deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "memory", sessionId });
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
memoryEngineSession = { engine: writeEngine, handle: writeHandle, inject: injectFn, harvest: harvestSafe };
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
if (typeof err.code === "string" && (err.code.startsWith("config.memory_scope") || err.code.startsWith("config.memory_project"))) {
|
|
175
|
+
throw err;
|
|
176
|
+
}
|
|
177
|
+
deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "memory", sessionId });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
let memoryBlock;
|
|
181
|
+
if (memorySpec && memorySpec.enabled && !useMemoryEngine) {
|
|
182
|
+
const detail = "TaskSpec.memory is enabled but RunnerDeps.memoryBackend is not configured; memory is inactive for this task (the legacy memoryStore fallback was retired in design/138 S4 and the dep was removed in design/157 B19).";
|
|
183
|
+
deps.onError?.(new Error(detail), { phase: "config", sessionId });
|
|
184
|
+
}
|
|
185
|
+
if (memoryEngineSession) {
|
|
186
|
+
const injection = memoryEngineSession.inject();
|
|
187
|
+
if (injection.block.trim())
|
|
188
|
+
memoryBlock = injection.block;
|
|
189
|
+
}
|
|
190
|
+
return { memoryEngineSession, memoryBlock };
|
|
191
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { AgentHarness, type ThinkingLevel } from "../../internal/harness.js";
|
|
2
2
|
import type { Model } from "../../internal/llm.js";
|
|
3
3
|
import { type MaterializedMcp } from "../mcp.js";
|
|
4
|
-
import { MemoryEngine } from "../memory-engine/engine.js";
|
|
5
4
|
import type { HarvestReport, MemorySessionHandle } from "../memory-engine/types.js";
|
|
6
5
|
import { StoredSession } from "../session.js";
|
|
7
6
|
import type { SessionStore } from "../session.js";
|
|
@@ -12,28 +11,14 @@ import { type CutKillRegistry } from "./cut-kill.js";
|
|
|
12
11
|
import type { SessionPermissionRules } from "../session-policy-store.js";
|
|
13
12
|
import { CacheBreakDetector, type ToolFingerprintInput } from "../cache-break-detector.js";
|
|
14
13
|
import { type OutputRef, type BlockedRef, type SkillListingEntry } from "./synthetic-tools.js";
|
|
15
|
-
import {
|
|
14
|
+
import type { MemoryEngine } from "../memory-engine/engine.js";
|
|
16
15
|
import type { TaskNotificationPayload } from "../task-notification.js";
|
|
17
16
|
import { type CwdRef } from "../../tools/fs/index.js";
|
|
18
17
|
import type { Runner } from "./runtask.js";
|
|
19
18
|
import { type CheckpointGate, type CheckpointState, type CheckpointToken, type ResourceLedger, type ResourceLimitReason } from "../checkpoint-store.js";
|
|
20
19
|
import type { AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
|
|
21
|
-
import type {
|
|
20
|
+
import type { RunnerDeps, TaskEvent, TaskSpec, ToolActivity, ToolEffect } from "../types.js";
|
|
22
21
|
import type { RepairBundle } from "../../agents/repair-loop.js";
|
|
23
|
-
export interface PreparedConsolidation {
|
|
24
|
-
scope: string;
|
|
25
|
-
notes: ConsolidationNote[];
|
|
26
|
-
settings: {
|
|
27
|
-
role: ModelRole;
|
|
28
|
-
band: {
|
|
29
|
-
lo: number;
|
|
30
|
-
hi: number;
|
|
31
|
-
};
|
|
32
|
-
searchLimit: number;
|
|
33
|
-
maxNotes: number;
|
|
34
|
-
timeoutSec: number;
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
22
|
export declare const DEFAULT_IRREVERSIBLE_SCOPE = "irreversible";
|
|
38
23
|
export declare function checkpointScopeOf(spec: {
|
|
39
24
|
durableApproval?: {
|
|
@@ -61,7 +46,6 @@ export interface Prepared {
|
|
|
61
46
|
tokens: number;
|
|
62
47
|
turns: number;
|
|
63
48
|
tasks: number;
|
|
64
|
-
costUsd: number;
|
|
65
49
|
costMicroUsd: number;
|
|
66
50
|
};
|
|
67
51
|
cwdRef?: CwdRef;
|
|
@@ -88,7 +72,7 @@ export interface Prepared {
|
|
|
88
72
|
tools: ToolFingerprintInput[];
|
|
89
73
|
};
|
|
90
74
|
promptManifest: {
|
|
91
|
-
constitution: "core" | "replaced" | "provider-assembled"
|
|
75
|
+
constitution: "core" | "replaced" | "provider-assembled";
|
|
92
76
|
blocks: Array<{
|
|
93
77
|
id: string;
|
|
94
78
|
chars: number;
|
|
@@ -130,7 +114,6 @@ export interface Prepared {
|
|
|
130
114
|
apply: (committedArtifactDigest?: string) => void;
|
|
131
115
|
} | undefined;
|
|
132
116
|
activeTools: Set<string>;
|
|
133
|
-
consolidation?: PreparedConsolidation;
|
|
134
117
|
memoryEngineSession?: {
|
|
135
118
|
engine: MemoryEngine;
|
|
136
119
|
handle: MemorySessionHandle;
|
|
@@ -255,13 +238,6 @@ export interface Prepared {
|
|
|
255
238
|
trimPressureRef: {
|
|
256
239
|
droppedMessages: boolean;
|
|
257
240
|
};
|
|
258
|
-
dynamicRecall?: {
|
|
259
|
-
selector: import("../memory-recall.js").MemorySelector;
|
|
260
|
-
scopes: string[];
|
|
261
|
-
recentTools: string[];
|
|
262
|
-
surfacedIds: Set<string>;
|
|
263
|
-
surfacedKeys: Set<string>;
|
|
264
|
-
};
|
|
265
241
|
}
|
|
266
242
|
export interface PrepareResume {
|
|
267
243
|
leafId: string;
|
|
@@ -350,4 +326,4 @@ export declare function batchContextAt(messages: AgentMessage[], currentId: stri
|
|
|
350
326
|
completedCallIds: string[];
|
|
351
327
|
};
|
|
352
328
|
export declare function rebaseWorkspacePath(p: string, fromRaw: string, toRaw: string): string;
|
|
353
|
-
export declare function prepareTask(spec: TaskSpec, deps: RunnerDeps, sessions: SessionStore, resume?: PrepareResume,
|
|
329
|
+
export declare function prepareTask(spec: TaskSpec, deps: RunnerDeps, sessions: SessionStore, resume?: PrepareResume, internals?: RunInternals, runnerSelf?: Runner): Promise<Prepared>;
|
|
@@ -11,11 +11,6 @@ import { primaryActivityArg } from "../arg-summary.js";
|
|
|
11
11
|
import { materializeMcpTools } from "../mcp.js";
|
|
12
12
|
import { Type } from "typebox";
|
|
13
13
|
import { brainToRuntime } from "../runtime.js";
|
|
14
|
-
import { MemoryEngine } from "../memory-engine/engine.js";
|
|
15
|
-
import { deriveControlPlaneDir, deriveProjectControlDir, deriveProjectMemoryDir, deriveRepoMemoryDir, drainMemoryAnnouncements, enqueueMemoryAnnouncement, lookupProjectIdHint, recordProjectIdHint, resolveMemoryEngineRoot } from "../memory-engine/layout.js";
|
|
16
|
-
import { assertScopeContractPlacement, parseScopeKey, resolveProjectId } from "../memory-engine/scope-contract.js";
|
|
17
|
-
import { classifyScopePlanes, derivePersonalControlDir, derivePersonalMemoryDir, mergeHarvestReports, mergeInjections, needsDualRoots, parsedProjectPlane } from "../memory-engine/dual-root.js";
|
|
18
|
-
import { FileMemoryEngineBackend } from "../memory-engine/file-backend.js";
|
|
19
14
|
import { StoredSession, isSessionConflict, hasSessionFork } from "../session.js";
|
|
20
15
|
import { createAgentTranscriptTool, createSendMessageTool, createSubagentWorktreeHelper, forkGovernanceDenial, AGENT_TRANSCRIPT_TOOL_NAME, SEND_MESSAGE_TOOL_NAME, SubagentRetainLedger } from "../../agents/subagent.js";
|
|
21
16
|
import { combinePolicies, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, resolveAsk, toolPolicyNameSets } from "../tool-policy.js";
|
|
@@ -32,12 +27,12 @@ import { reservedCollisions, reservedFor } from "../../brain/request-params.js";
|
|
|
32
27
|
import { defineTool } from "../tools.js";
|
|
33
28
|
import { canonicalToolName } from "../tool-name-aliases.js";
|
|
34
29
|
import { pathToUri } from "../lsp-protocol.js";
|
|
35
|
-
import { DEFAULT_TOOL_RESULT_THRESHOLD_CHARS, firstPartyOffloadPolicy, InMemoryToolResultStore, RunnerSharedToolResultStore, ScopedToolResultStore, isVolatileOffloadStore, OFFLOAD_TOOL_NAME,
|
|
36
|
-
import { OUTPUT_TOOL_NAME, REPORT_FINDINGS_TOOL_NAME, SKILL_CONTENT_MAX_CHARS, SKILL_TOOL_NAME,
|
|
30
|
+
import { DEFAULT_TOOL_RESULT_THRESHOLD_CHARS, firstPartyOffloadPolicy, InMemoryToolResultStore, RunnerSharedToolResultStore, ScopedToolResultStore, isVolatileOffloadStore, OFFLOAD_TOOL_NAME, createReadToolResultTool, withToolResultOffload, } from "../tool-result-store.js";
|
|
31
|
+
import { OUTPUT_TOOL_NAME, REPORT_FINDINGS_TOOL_NAME, SKILL_CONTENT_MAX_CHARS, SKILL_TOOL_NAME, createOutputTool, createReportBlockedTool, createReportFindingsTool, createSkillTool, normalizeSkills } from "./synthetic-tools.js";
|
|
37
32
|
import { compileOutputSchema } from "./strict-output-schema.js";
|
|
38
|
-
import { TOOL_SEARCH_NAME, buildDeferredRegistry, classifyDeferred, extractDiscoveredToolNames,
|
|
39
|
-
import { composeMemoryBlock
|
|
40
|
-
import {} from "./memory
|
|
33
|
+
import { TOOL_SEARCH_NAME, buildDeferredRegistry, classifyDeferred, extractDiscoveredToolNames, createPlaceholderTool, createToolSearchTool, } from "./tool-disclosure.js";
|
|
34
|
+
import { composeMemoryBlock } from "../memory.js";
|
|
35
|
+
import { prepareMemory } from "./prepare-memory.js";
|
|
41
36
|
import { defaultPromptProvider, buildEnvironmentContext, buildGitSnapshot, formatLocalDate, isValidTimeZone, PROJECT_CONTEXT_FRAMING } from "../../prompts/default.js";
|
|
42
37
|
import { assemblePrompt } from "../../prompt-assembly/assemble.js";
|
|
43
38
|
import { auditToolCollisions, projectToolManifest } from "../../prompt-assembly/tool-catalog.js";
|
|
@@ -171,7 +166,7 @@ export function rebaseWorkspacePath(p, fromRaw, toRaw) {
|
|
|
171
166
|
const suffix = p.slice(fromPrefix.length).replace(/^\/+/, "");
|
|
172
167
|
return to === "/" ? `${to}${suffix}` : `${to}/${suffix}`;
|
|
173
168
|
}
|
|
174
|
-
export async function prepareTask(spec, deps, sessions, resume,
|
|
169
|
+
export async function prepareTask(spec, deps, sessions, resume, internals, runnerSelf) {
|
|
175
170
|
const toolFaceSnapshot = {
|
|
176
171
|
exclude: spec.excludeTools ? Object.freeze([...spec.excludeTools]) : undefined,
|
|
177
172
|
defer: spec.deferTools ? Object.freeze([...spec.deferTools]) : undefined,
|
|
@@ -413,19 +408,17 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
413
408
|
if (extraBodyCollisions.length > 0) {
|
|
414
409
|
deps.onError?.(new Error(`model.extraBody contains reserved key(s) [${extraBodyCollisions.join(", ")}] that core owns and sets itself — they are ignored. Remove them from extraBody.`), { phase: "config", sessionId });
|
|
415
410
|
}
|
|
416
|
-
const nestedStats = { tokens: 0, turns: 0, tasks: 0,
|
|
411
|
+
const nestedStats = { tokens: 0, turns: 0, tasks: 0, costMicroUsd: 0 };
|
|
417
412
|
if (resume) {
|
|
418
413
|
nestedStats.tokens = resume.seed.nestedStats.tokens;
|
|
419
414
|
nestedStats.turns = resume.seed.nestedStats.turns;
|
|
420
415
|
nestedStats.tasks = resume.seed.nestedStats.tasks;
|
|
421
|
-
nestedStats.costUsd = resume.seed.nestedStats.costUsd;
|
|
422
416
|
nestedStats.costMicroUsd = resume.seed.nestedStats.costMicroUsd;
|
|
423
417
|
}
|
|
424
418
|
const reportUsage = (u) => {
|
|
425
419
|
nestedStats.tokens += u.tokens;
|
|
426
420
|
nestedStats.turns += u.turns;
|
|
427
421
|
nestedStats.tasks += u.tasks;
|
|
428
|
-
nestedStats.costUsd += u.costUsd ?? 0;
|
|
429
422
|
nestedStats.costMicroUsd += u.costMicroUsd ?? 0;
|
|
430
423
|
};
|
|
431
424
|
const explicitGlobalThreshold = spec.toolResultThresholdChars ?? deps.toolResultThresholdChars;
|
|
@@ -801,10 +794,10 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
801
794
|
}), t));
|
|
802
795
|
const blockedRef = {};
|
|
803
796
|
if (spec.enableBlockedReport !== false) {
|
|
804
|
-
tools.push(
|
|
797
|
+
tools.push(createReportBlockedTool(blockedRef));
|
|
805
798
|
}
|
|
806
799
|
if (!(spec.tools ?? []).some((t) => t.name === REPORT_FINDINGS_TOOL_NAME || t.aliases?.includes(REPORT_FINDINGS_TOOL_NAME))) {
|
|
807
|
-
tools.push(
|
|
800
|
+
tools.push(createReportFindingsTool());
|
|
808
801
|
}
|
|
809
802
|
if (spec.enablePlanMode === true && spec.interactiveTools !== false) {
|
|
810
803
|
const planReviewFace = (spec.checkpointStore ?? deps.checkpointStore) !== undefined;
|
|
@@ -963,7 +956,7 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
963
956
|
catch {
|
|
964
957
|
}
|
|
965
958
|
}
|
|
966
|
-
tools.push(
|
|
959
|
+
tools.push(createOutputTool(outputRef, spec.outputSchema, compiled.strict ? compiled.modelSchema : undefined));
|
|
967
960
|
}
|
|
968
961
|
mcp = spec.mcp?.length
|
|
969
962
|
? await materializeMcpTools(spec.mcp, spec.principal, deps.onElicit, deps.mcpImageResizer)
|
|
@@ -999,9 +992,12 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
999
992
|
const results = await mcp.refresh(typeof serverArg === "string" && serverArg.length > 0 ? serverArg : undefined);
|
|
1000
993
|
const lines = [];
|
|
1001
994
|
let changed = false;
|
|
995
|
+
let anyActiveFailure = false;
|
|
1002
996
|
for (const r of results) {
|
|
1003
997
|
if (r.status !== "refreshed" || r.tools === undefined) {
|
|
1004
998
|
lines.push(`${r.server}: ${r.status}${r.error !== undefined ? ` (${r.error})` : ""}`);
|
|
999
|
+
if (r.status === "failed")
|
|
1000
|
+
anyActiveFailure = true;
|
|
1005
1001
|
continue;
|
|
1006
1002
|
}
|
|
1007
1003
|
const excludedSet = new Set(toolFaceSnapshot.exclude ?? []);
|
|
@@ -1012,6 +1008,7 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
1012
1008
|
}
|
|
1013
1009
|
catch (foldErr) {
|
|
1014
1010
|
lines.push(`${r.server}: failed (${foldErr instanceof Error ? foldErr.message : String(foldErr)})`);
|
|
1011
|
+
anyActiveFailure = true;
|
|
1015
1012
|
continue;
|
|
1016
1013
|
}
|
|
1017
1014
|
for (let i = tools.length - 1; i >= 0; i--) {
|
|
@@ -1041,7 +1038,12 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
1041
1038
|
lines.push("WARNING: refreshed tools declare irreversible/egress safety hints, but this task started with no approval gate registered (no policy/hooks and no gated tools at start) — these hints cannot arm a gate mid-task (RB-46); the refreshed tools run ungated on this deployment shape.");
|
|
1042
1039
|
}
|
|
1043
1040
|
const text = lines.length === 0 ? "No connected MCP servers to refresh." : lines.join("\n");
|
|
1044
|
-
return {
|
|
1041
|
+
return {
|
|
1042
|
+
content: [{ type: "text", text }],
|
|
1043
|
+
details: { results },
|
|
1044
|
+
terminate: false,
|
|
1045
|
+
...(anyActiveFailure && !changed ? { isError: true } : {}),
|
|
1046
|
+
};
|
|
1045
1047
|
},
|
|
1046
1048
|
});
|
|
1047
1049
|
toolEffects.set("RefreshMcpTools", "read");
|
|
@@ -1206,7 +1208,7 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
1206
1208
|
if (backgroundTaskToolsActive || workflowToolsActive) {
|
|
1207
1209
|
toolEffects.set("TaskOutput", "read");
|
|
1208
1210
|
toolEffects.set("TaskStop", "write");
|
|
1209
|
-
tools.push(firstPartyOffload(createTaskOutputTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore, ...(callCapRef ? { deadlineMs: () => toolCutDeadlineMs(callCapRef, Date.now()) } : {}) })), firstPartyOffload(createTaskStopTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore })));
|
|
1211
|
+
tools.push(firstPartyOffload(createTaskOutputTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore, notificationWired: internals?.onTaskNotification !== undefined, ...(callCapRef ? { deadlineMs: () => toolCutDeadlineMs(callCapRef, Date.now()) } : {}) })), firstPartyOffload(createTaskStopTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore })));
|
|
1210
1212
|
if (runnerSelf && !(spec.tools ?? []).some((t) => t.name === SEND_MESSAGE_TOOL_NAME)) {
|
|
1211
1213
|
const delegationForRevive = (spec.tools ?? []).find((t) => t.agentListing !== undefined);
|
|
1212
1214
|
const reviveSpawn = delegationForRevive !== undefined && deps.backgroundAgentStore !== undefined && deps.mailboxStore !== undefined
|
|
@@ -1295,7 +1297,7 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
1295
1297
|
tools.push(...createWorktreeTools(executionEnv, { repoRoot: taskRootPath, cwdRef: handsCwdRef, session: worktreeSessionRef }).map((t) => firstPartyOffload(t)));
|
|
1296
1298
|
}
|
|
1297
1299
|
if (offloadStore)
|
|
1298
|
-
tools.push(
|
|
1300
|
+
tools.push(createReadToolResultTool(offloadStore));
|
|
1299
1301
|
const onQuestion = spec.onQuestion ?? deps.onQuestion;
|
|
1300
1302
|
const durableQuestionFace = (spec.checkpointStore ?? deps.checkpointStore) !== undefined &&
|
|
1301
1303
|
(spec.durableApproval !== undefined || runtimeCaps?.forceDurableGate === true);
|
|
@@ -1360,189 +1362,8 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
1360
1362
|
.catch(() => undefined);
|
|
1361
1363
|
}
|
|
1362
1364
|
: undefined;
|
|
1363
|
-
const
|
|
1364
|
-
|
|
1365
|
-
let memoryEngineSession;
|
|
1366
|
-
if (useMemoryEngine && memorySpec) {
|
|
1367
|
-
try {
|
|
1368
|
-
const backend = deps.memoryBackend;
|
|
1369
|
-
const pinned = backend.directoryRoot;
|
|
1370
|
-
const engineRoot = resolveMemoryEngineRoot(deps.memoryEngineDir);
|
|
1371
|
-
const repoRoot = deps.rootPath ?? taskRootPath;
|
|
1372
|
-
let identityKey;
|
|
1373
|
-
if (memorySpec.scopeContract === "v2" && repoRoot) {
|
|
1374
|
-
const consumesProjectIdentity = [...memorySpec.scopes, ...(memorySpec.writeScope !== null ? [memorySpec.writeScope] : [])]
|
|
1375
|
-
.map(parseScopeKey)
|
|
1376
|
-
.some((k) => k.kind === "proj" || k.kind === "userproj");
|
|
1377
|
-
let marker = null;
|
|
1378
|
-
try {
|
|
1379
|
-
marker = resolveProjectId(repoRoot);
|
|
1380
|
-
}
|
|
1381
|
-
catch (err) {
|
|
1382
|
-
if (consumesProjectIdentity)
|
|
1383
|
-
throw err;
|
|
1384
|
-
deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "config", sessionId });
|
|
1385
|
-
}
|
|
1386
|
-
if (marker) {
|
|
1387
|
-
identityKey = marker.projectId;
|
|
1388
|
-
const firstSwitch = lookupProjectIdHint(engineRoot, repoRoot) !== marker.projectId;
|
|
1389
|
-
recordProjectIdHint(engineRoot, repoRoot, marker.projectId);
|
|
1390
|
-
if (firstSwitch) {
|
|
1391
|
-
try {
|
|
1392
|
-
const oldCtl = deriveControlPlaneDir(engineRoot, repoRoot);
|
|
1393
|
-
const newCtl = deriveProjectControlDir(engineRoot, marker.projectId);
|
|
1394
|
-
const drained = drainMemoryAnnouncements(oldCtl);
|
|
1395
|
-
for (const ann of drained.queue)
|
|
1396
|
-
enqueueMemoryAnnouncement(newCtl, ann);
|
|
1397
|
-
}
|
|
1398
|
-
catch {
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
if (memorySpec.writeScope !== null) {
|
|
1402
|
-
const w = parseScopeKey(memorySpec.writeScope);
|
|
1403
|
-
if ((w.kind === "proj" || w.kind === "userproj") && w.projectId !== marker.projectId) {
|
|
1404
|
-
const e = new Error(`memory scope contract v2: writeScope ${memorySpec.writeScope} targets projectId ${w.projectId}, ` +
|
|
1405
|
-
`but this checkout's marker (.sema/project) declares ${marker.projectId} — refusing a mis-addressed write.`);
|
|
1406
|
-
e.code = "config.memory_project_identity";
|
|
1407
|
-
throw e;
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
else {
|
|
1412
|
-
const hint = lookupProjectIdHint(engineRoot, repoRoot);
|
|
1413
|
-
if (hint !== undefined) {
|
|
1414
|
-
deps.onError?.(new Error(`memory project marker missing but recoverable: ${repoRoot} previously carried projectId ${hint} ` +
|
|
1415
|
-
`(.sema/project deleted?). Restore the marker to keep the identity-keyed memory mount; this session ` +
|
|
1416
|
-
`falls back to the path-derived key.`), { phase: "config", sessionId });
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
const memoryDir = typeof pinned === "string" && pinned
|
|
1421
|
-
? pinned
|
|
1422
|
-
: identityKey !== undefined
|
|
1423
|
-
? deriveProjectMemoryDir(engineRoot, identityKey)
|
|
1424
|
-
: deriveRepoMemoryDir(engineRoot, repoRoot);
|
|
1425
|
-
const planes = memorySpec.scopeContract === "v2" ? classifyScopePlanes(memorySpec.scopes, memorySpec.writeScope) : undefined;
|
|
1426
|
-
const dual = planes !== undefined && needsDualRoots(planes);
|
|
1427
|
-
const personalOnly = planes !== undefined && !dual && planes.project.length === 0 && planes.writePlane !== "project" && (planes.personal.length > 0 || planes.writePlane === "personal");
|
|
1428
|
-
if (memorySpec.scopeContract === "v2" && !personalOnly) {
|
|
1429
|
-
assertScopeContractPlacement({
|
|
1430
|
-
parsedScopes: dual
|
|
1431
|
-
? parsedProjectPlane(planes, memorySpec.writeScope)
|
|
1432
|
-
: [...memorySpec.scopes, ...(memorySpec.writeScope !== null ? [memorySpec.writeScope] : [])].map(parseScopeKey),
|
|
1433
|
-
memoryDir,
|
|
1434
|
-
repoRoot,
|
|
1435
|
-
});
|
|
1436
|
-
}
|
|
1437
|
-
const personalMemoryDir = derivePersonalMemoryDir(engineRoot);
|
|
1438
|
-
const personalControlDir = derivePersonalControlDir(engineRoot);
|
|
1439
|
-
const makePersonalEngine = () => new MemoryEngine({
|
|
1440
|
-
backend: typeof pinned === "string" && pinned
|
|
1441
|
-
? new FileMemoryEngineBackend(personalMemoryDir, { controlDir: personalControlDir })
|
|
1442
|
-
: backend,
|
|
1443
|
-
memoryDir: personalMemoryDir,
|
|
1444
|
-
controlDir: personalControlDir,
|
|
1445
|
-
});
|
|
1446
|
-
let writeEngine;
|
|
1447
|
-
let writeHandle;
|
|
1448
|
-
let injectFn;
|
|
1449
|
-
let harvestBoth;
|
|
1450
|
-
if (dual) {
|
|
1451
|
-
const projectEngine = new MemoryEngine({
|
|
1452
|
-
backend,
|
|
1453
|
-
memoryDir,
|
|
1454
|
-
controlDir: identityKey !== undefined ? deriveProjectControlDir(engineRoot, identityKey) : deriveControlPlaneDir(engineRoot, repoRoot),
|
|
1455
|
-
});
|
|
1456
|
-
const personalEngine = makePersonalEngine();
|
|
1457
|
-
const p = planes;
|
|
1458
|
-
const projectHandle = await projectEngine.materialize(p.project, p.writePlane === "project" ? memorySpec.writeScope : null);
|
|
1459
|
-
const personalHandle = await personalEngine.materialize(p.personal, p.writePlane === "personal" ? memorySpec.writeScope : null);
|
|
1460
|
-
const writeIsPersonal = p.writePlane === "personal";
|
|
1461
|
-
writeEngine = writeIsPersonal ? personalEngine : projectEngine;
|
|
1462
|
-
writeHandle = writeIsPersonal ? personalHandle : projectHandle;
|
|
1463
|
-
injectFn = () => mergeInjections(projectEngine.inject(projectHandle), personalEngine.inject(personalHandle));
|
|
1464
|
-
harvestBoth = async () => {
|
|
1465
|
-
const writeFirst = writeIsPersonal ? [personalEngine, personalHandle] : [projectEngine, projectHandle];
|
|
1466
|
-
const readOther = writeIsPersonal ? [projectEngine, projectHandle] : [personalEngine, personalHandle];
|
|
1467
|
-
const writeReport = await writeFirst[0].harvest(writeFirst[1]);
|
|
1468
|
-
let readReport;
|
|
1469
|
-
let readFailure;
|
|
1470
|
-
try {
|
|
1471
|
-
readReport = await readOther[0].harvest(readOther[1]);
|
|
1472
|
-
}
|
|
1473
|
-
catch (err) {
|
|
1474
|
-
readFailure = err instanceof Error ? err.message : String(err);
|
|
1475
|
-
}
|
|
1476
|
-
const merged = readReport !== undefined ? mergeHarvestReports(writeReport, readReport) : writeReport;
|
|
1477
|
-
if (readFailure !== undefined)
|
|
1478
|
-
merged.warnings.push(`read-plane harvest failed (write-plane yield committed): ${readFailure}`);
|
|
1479
|
-
return merged;
|
|
1480
|
-
};
|
|
1481
|
-
}
|
|
1482
|
-
else if (personalOnly) {
|
|
1483
|
-
const personalEngine = makePersonalEngine();
|
|
1484
|
-
const handle = await personalEngine.materialize(memorySpec.scopes, memorySpec.writeScope);
|
|
1485
|
-
writeEngine = personalEngine;
|
|
1486
|
-
writeHandle = handle;
|
|
1487
|
-
injectFn = () => personalEngine.inject(handle);
|
|
1488
|
-
harvestBoth = () => personalEngine.harvest(handle);
|
|
1489
|
-
}
|
|
1490
|
-
else {
|
|
1491
|
-
const engine = new MemoryEngine({
|
|
1492
|
-
backend,
|
|
1493
|
-
memoryDir,
|
|
1494
|
-
controlDir: identityKey !== undefined ? deriveProjectControlDir(engineRoot, identityKey) : deriveControlPlaneDir(engineRoot, repoRoot),
|
|
1495
|
-
});
|
|
1496
|
-
const handle = await engine.materialize(memorySpec.scopes, memorySpec.writeScope);
|
|
1497
|
-
writeEngine = engine;
|
|
1498
|
-
writeHandle = handle;
|
|
1499
|
-
injectFn = () => engine.inject(handle);
|
|
1500
|
-
harvestBoth = () => engine.harvest(handle);
|
|
1501
|
-
}
|
|
1502
|
-
memoryWriteGateRef.current = (w) => writeEngine.gateWrite(writeHandle, w.key, w.content);
|
|
1503
|
-
const harvestSafe = async (phase = "terminal") => {
|
|
1504
|
-
try {
|
|
1505
|
-
const report = await harvestBoth();
|
|
1506
|
-
if (!report.ok && report.incident) {
|
|
1507
|
-
deps.onError?.(new Error(`memory harvest refused (${report.incident.kind}): ${report.incident.detail}`), { phase: "memory", sessionId });
|
|
1508
|
-
}
|
|
1509
|
-
try {
|
|
1510
|
-
deps.onMemoryHarvestReport?.(report, { sessionId, phase });
|
|
1511
|
-
}
|
|
1512
|
-
catch {
|
|
1513
|
-
}
|
|
1514
|
-
return report;
|
|
1515
|
-
}
|
|
1516
|
-
catch (err) {
|
|
1517
|
-
try {
|
|
1518
|
-
deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "memory", sessionId });
|
|
1519
|
-
}
|
|
1520
|
-
catch {
|
|
1521
|
-
}
|
|
1522
|
-
return undefined;
|
|
1523
|
-
}
|
|
1524
|
-
};
|
|
1525
|
-
memoryEngineSession = { engine: writeEngine, handle: writeHandle, inject: injectFn, harvest: harvestSafe };
|
|
1526
|
-
}
|
|
1527
|
-
catch (err) {
|
|
1528
|
-
if (typeof err.code === "string" && (err.code.startsWith("config.memory_scope") || err.code.startsWith("config.memory_project"))) {
|
|
1529
|
-
throw err;
|
|
1530
|
-
}
|
|
1531
|
-
deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "memory", sessionId });
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
let memoryBlock;
|
|
1535
|
-
if (memorySpec && memorySpec.enabled && !useMemoryEngine) {
|
|
1536
|
-
const detail = deps.memoryStore
|
|
1537
|
-
? "RunnerDeps.memoryStore is retired (design/138 S4): the legacy remember/recall tools and <user_memory> injection no longer run. Configure RunnerDeps.memoryBackend (memory engine) instead; this task runs memory-less."
|
|
1538
|
-
: "TaskSpec.memory is enabled but RunnerDeps.memoryBackend is not configured; memory is inactive for this task (the legacy memoryStore fallback was retired in design/138 S4).";
|
|
1539
|
-
deps.onError?.(new Error(detail), { phase: "config", sessionId });
|
|
1540
|
-
}
|
|
1541
|
-
if (memoryEngineSession) {
|
|
1542
|
-
const injection = memoryEngineSession.inject();
|
|
1543
|
-
if (injection.block.trim())
|
|
1544
|
-
memoryBlock = injection.block;
|
|
1545
|
-
}
|
|
1365
|
+
const { memoryEngineSession, memoryBlock: memoryBlockFromEngine } = await prepareMemory({ spec, deps, sessionId, taskRootPath, memoryWriteGateRef });
|
|
1366
|
+
let memoryBlock = memoryBlockFromEngine;
|
|
1546
1367
|
let instructionSources;
|
|
1547
1368
|
if (deps.loadProjectMemory) {
|
|
1548
1369
|
let projectMemoryPhase = spec.sessionId ? "resume" : "fresh";
|
|
@@ -1616,7 +1437,7 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
1616
1437
|
e.code = "config.reserved_tool_name";
|
|
1617
1438
|
throw e;
|
|
1618
1439
|
}
|
|
1619
|
-
tools.push(
|
|
1440
|
+
tools.push(createSkillTool(skillSpecs, skillScope));
|
|
1620
1441
|
}
|
|
1621
1442
|
const skillsListing = skillSpecs.length > 0
|
|
1622
1443
|
? {
|
|
@@ -1852,10 +1673,10 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
1852
1673
|
});
|
|
1853
1674
|
const assembled = assemblePrompt(buildAssembleInputs(centerAdoption !== undefined ? artifactDeclarations(centerAdoption.artifact) : undefined));
|
|
1854
1675
|
if (centerAdoption !== undefined && assembled.centerMounted !== true) {
|
|
1855
|
-
const ownsWholePrompt = assembled.constitution === "
|
|
1676
|
+
const ownsWholePrompt = assembled.constitution === "provider-assembled";
|
|
1856
1677
|
const digest = centerAdoption.artifact.artifactDigest.slice(0, 23);
|
|
1857
1678
|
if (ownsWholePrompt) {
|
|
1858
|
-
const e = new Error(`center prompt artifact ${digest}… cannot mount: this PromptProvider owns the whole prompt (
|
|
1679
|
+
const e = new Error(`center prompt artifact ${digest}… cannot mount: this PromptProvider owns the whole prompt (assembled-identity pass-through) — upgrade the provider to stableBlocks/stableSystem or remove RunnerDeps.promptSource for this deployment`);
|
|
1859
1680
|
e.code = "prompt.center_unmountable";
|
|
1860
1681
|
throw e;
|
|
1861
1682
|
}
|
|
@@ -1948,7 +1769,7 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
1948
1769
|
throw e;
|
|
1949
1770
|
}
|
|
1950
1771
|
const registry = buildDeferredRegistry(deferred, tools);
|
|
1951
|
-
const placeholders = new Map([...registry.values()].map((i) => [i.name,
|
|
1772
|
+
const placeholders = new Map([...registry.values()].map((i) => [i.name, createPlaceholderTool(i)]));
|
|
1952
1773
|
const { messages } = await session.buildContext();
|
|
1953
1774
|
for (const n of extractDiscoveredToolNames(messages, registry)) {
|
|
1954
1775
|
if (deferred.has(n))
|
|
@@ -1982,7 +1803,7 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
1982
1803
|
}
|
|
1983
1804
|
};
|
|
1984
1805
|
rebuildHarnessToolsRef.current = () => rematerialize(activeTools);
|
|
1985
|
-
toolSearch =
|
|
1806
|
+
toolSearch = createToolSearchTool({
|
|
1986
1807
|
registry,
|
|
1987
1808
|
active: activeTools,
|
|
1988
1809
|
rematerialize,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Model } from "../../internal/llm.js";
|
|
2
|
-
import type { AgentMessage, ThinkingLevel } from "../../internal/harness.js";
|
|
2
|
+
import type { AgentMessage, ThinkingLevel } from "../../internal/harness-types.js";
|
|
3
3
|
import type { Brain } from "../types.js";
|
|
4
4
|
import type { ModelPricing } from "../pricing.js";
|
|
5
5
|
export interface SuggestionLLM {
|