@sema-agent/core 5.16.0 → 5.17.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 +224 -0
- package/dist/agents/peer-admission.d.ts +58 -0
- package/dist/agents/peer-admission.js +175 -0
- package/dist/agents/retain-ledger.d.ts +1 -1
- package/dist/agents/retain-ledger.js +9 -1
- package/dist/agents/send-message-tool.d.ts +8 -0
- package/dist/agents/send-message-tool.js +171 -21
- package/dist/agents/subagent.d.ts +13 -0
- package/dist/agents/subagent.js +90 -5
- package/dist/core/ask-question.js +16 -1
- package/dist/core/canonical-json.js +176 -14
- package/dist/core/checkpoint-store.d.ts +14 -0
- package/dist/core/checkpoint-store.js +73 -0
- package/dist/core/hooks.d.ts +4 -1
- package/dist/core/hooks.js +24 -6
- package/dist/core/mailbox-store.d.ts +2 -0
- package/dist/core/mailbox-store.js +2 -2
- package/dist/core/mcp.d.ts +1 -0
- package/dist/core/mcp.js +15 -3
- package/dist/core/runner/prepare-task.d.ts +4 -0
- package/dist/core/runner/prepare-task.js +169 -46
- package/dist/core/runner/runtask.js +13 -1
- package/dist/core/runner/turn-attachments.d.ts +2 -1
- package/dist/core/runner/turn-attachments.js +9 -6
- package/dist/core/session-reconcile.js +19 -1
- package/dist/core/shared-memory/contract.d.ts +17 -0
- package/dist/core/shared-memory/contract.js +138 -0
- package/dist/core/shared-memory/normalize.d.ts +73 -0
- package/dist/core/shared-memory/normalize.js +259 -0
- package/dist/core/shared-memory/tools.d.ts +7 -0
- package/dist/core/shared-memory/tools.js +289 -0
- package/dist/core/shared-memory/types.d.ts +95 -0
- package/dist/core/shared-memory/types.js +18 -0
- package/dist/core/task-notification.d.ts +3 -0
- package/dist/core/task-registry-agent.d.ts +1 -1
- package/dist/core/task-registry-agent.js +2 -1
- package/dist/core/task-registry.d.ts +1 -1
- package/dist/core/task-registry.js +2 -0
- package/dist/core/tool-policy.d.ts +9 -0
- package/dist/core/tool-policy.js +28 -8
- package/dist/core/types.d.ts +8 -0
- package/dist/core/untrusted-text.d.ts +1 -0
- package/dist/core/untrusted-text.js +10 -0
- package/dist/core/wiring-manifest.js +2 -2
- package/dist/engine/harness/agent-harness.d.ts +1 -0
- package/dist/engine/harness/agent-harness.js +21 -2
- package/dist/engine/llm/validation.js +121 -5
- package/dist/engine/loop/agent-loop.d.ts +2 -0
- package/dist/engine/loop/agent-loop.js +17 -4
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/prompts/supervisor.d.ts +1 -1
- package/dist/prompts/supervisor.js +1 -1
- package/dist/stores/cc/mailbox-store.js +4 -0
- package/dist/stores/file/checkpoint-store.d.ts +1 -0
- package/dist/stores/file/checkpoint-store.js +1 -0
- package/dist/stores/file/mailbox-store.js +2 -2
- package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -0
- package/dist/tools/fs/bash-readonly-classifier.js +11 -10
- package/dist/tools/fs/fs-bash.js +6 -6
- package/dist/tools/fs/fs-read.d.ts +1 -1
- package/dist/tools/fs/fs-read.js +4 -3
- package/dist/tools/fs/fs-shared.d.ts +3 -0
- package/dist/tools/fs/fs-shared.js +8 -1
- package/dist/tools/fs/fs-write.js +8 -8
- package/dist/tools/fs/index.d.ts +1 -0
- package/dist/tools/fs/index.js +1 -1
- package/dist/tools/fs/safety.d.ts +1 -0
- package/dist/tools/fs/safety.js +9 -2
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import { Type } from "typebox";
|
|
|
3
3
|
import { defineTool, errorResult } from "../../core/tools.js";
|
|
4
4
|
import { sha256, resolveKey, violationText, violationDetails, requireRead, checkStale, checkEditMatch, checkNoChange, fileArgPath, resolveQuoteMatch, adaptNewStringQuotes, resolveEscapeMatch, adaptNewStringEscapes, escapeMatchWasAttempted, ESCAPE_MATCH_MISS_NOTE, deletionOldString, countOccurrences, READ_REFUSED_ESCAPE_HINT, } from "./safety.js";
|
|
5
5
|
import { decodeTextBytes, encodeTextForFile, normalizeEditText, normalizeFileText } from "./encoding.js";
|
|
6
|
-
import { MAX_EDIT_BYTES,
|
|
6
|
+
import { MAX_EDIT_BYTES, decodeEditBytes, tooLargeToEditMessage, truncatedUtf16BodyMessage, persistedTextOf, notReadRefusalText, enoentMessage, FILE_STATE_TRAILER, FILE_PATH_PARAMS, ipynbRedirect, countLines, } from "./fs-shared.js";
|
|
7
7
|
async function gateToolWrite(hook, tool, path, key, content) {
|
|
8
8
|
if (hook === undefined)
|
|
9
9
|
return undefined;
|
|
@@ -91,21 +91,21 @@ export function createEditFileTool(env, state, rootCanonical, cwdRef, additional
|
|
|
91
91
|
}
|
|
92
92
|
const editInfo = await env.fileInfo(r.key, ctx.signal);
|
|
93
93
|
if (editInfo.ok && editInfo.value.size > MAX_EDIT_BYTES) {
|
|
94
|
-
return errorResult(
|
|
94
|
+
return errorResult(tooLargeToEditMessage(path, editInfo.value.size));
|
|
95
95
|
}
|
|
96
96
|
if (singleOld === "") {
|
|
97
97
|
const preBin = await env.readBinaryFile(r.key, ctx.signal);
|
|
98
98
|
if (!preBin.ok)
|
|
99
99
|
return errorResult(`Error (Edit): cannot read "${path}": ${preBin.error.message}`);
|
|
100
100
|
if (preBin.value.byteLength > MAX_EDIT_BYTES) {
|
|
101
|
-
return errorResult(
|
|
101
|
+
return errorResult(tooLargeToEditMessage(path, preBin.value.byteLength));
|
|
102
102
|
}
|
|
103
103
|
const preDecResult = decodeEditBytes(preBin.value, path);
|
|
104
104
|
if (!preDecResult.ok)
|
|
105
105
|
return errorResult(preDecResult.message);
|
|
106
106
|
const preDec = preDecResult.value;
|
|
107
107
|
if (preDec.malformed)
|
|
108
|
-
return errorResult(
|
|
108
|
+
return errorResult(truncatedUtf16BodyMessage("Edit", path));
|
|
109
109
|
if (preDec.text.trim() !== "")
|
|
110
110
|
return errorResult(`Error (Edit): Cannot create new file - file already exists.`);
|
|
111
111
|
const priorRead = state.get(r.key);
|
|
@@ -141,14 +141,14 @@ export function createEditFileTool(env, state, rootCanonical, cwdRef, additional
|
|
|
141
141
|
if (!readBin.ok)
|
|
142
142
|
return errorResult(`Error (Edit): cannot read "${path}": ${readBin.error.message}`);
|
|
143
143
|
if (readBin.value.byteLength > MAX_EDIT_BYTES) {
|
|
144
|
-
return errorResult(
|
|
144
|
+
return errorResult(tooLargeToEditMessage(path, readBin.value.byteLength));
|
|
145
145
|
}
|
|
146
146
|
const decodedResult = decodeEditBytes(readBin.value, path);
|
|
147
147
|
if (!decodedResult.ok)
|
|
148
148
|
return errorResult(decodedResult.message);
|
|
149
149
|
const decoded = decodedResult.value;
|
|
150
150
|
if (decoded.malformed)
|
|
151
|
-
return errorResult(
|
|
151
|
+
return errorResult(truncatedUtf16BodyMessage("Edit", path));
|
|
152
152
|
const original = decoded.text;
|
|
153
153
|
const entry = state.get(r.key);
|
|
154
154
|
const readWasTruncated = entry?.truncated === true;
|
|
@@ -256,7 +256,7 @@ export function createWriteFileTool(env, state, rootCanonical, cwdRef, additiona
|
|
|
256
256
|
return errorResult(`Error (Write): cannot re-read "${path}" to verify it is unchanged: ${readBin.error.message}`);
|
|
257
257
|
const decodedPrev = decodeTextBytes(readBin.value);
|
|
258
258
|
if (decodedPrev.malformed)
|
|
259
|
-
return errorResult(
|
|
259
|
+
return errorResult(truncatedUtf16BodyMessage("Write", path));
|
|
260
260
|
const stale = checkStale(state.get(r.key), sha256(decodedPrev.text));
|
|
261
261
|
if (stale)
|
|
262
262
|
return errorResult(violationText("Write", stale));
|
|
@@ -340,7 +340,7 @@ export function createNotebookEditTool(env, state, rootCanonical, cwdRef, additi
|
|
|
340
340
|
return errorResult(`Error (NotebookEdit): cannot read "${notebook_path}": ${readBin.error.message}`);
|
|
341
341
|
const decodedNb = decodeTextBytes(readBin.value);
|
|
342
342
|
if (decodedNb.malformed)
|
|
343
|
-
return errorResult(
|
|
343
|
+
return errorResult(truncatedUtf16BodyMessage("NotebookEdit", notebook_path));
|
|
344
344
|
const nbText = decodedNb.text;
|
|
345
345
|
const stale = checkStale(state.get(r.key), sha256(nbText));
|
|
346
346
|
if (stale)
|
package/dist/tools/fs/index.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export interface HandsToolkitOptions {
|
|
|
34
34
|
autoBackgroundOnTimeout?: boolean;
|
|
35
35
|
readImageDownsampler?: ReadImageDownsamplerOption;
|
|
36
36
|
pdfModelCapabilities?: PdfModelCapabilities;
|
|
37
|
+
readCyberReminder?: boolean;
|
|
37
38
|
beforeWrite?: BeforeWriteHook;
|
|
38
39
|
monitorToolActive?: boolean;
|
|
39
40
|
}
|
package/dist/tools/fs/index.js
CHANGED
|
@@ -30,7 +30,7 @@ export function createHandsToolkit(env, readFileState, rootCanonical, opts = {})
|
|
|
30
30
|
...(opts.sessionId !== undefined ? { sessionId: opts.sessionId } : {}),
|
|
31
31
|
}, env);
|
|
32
32
|
const tools = [
|
|
33
|
-
createReadFileTool(env, readFileState, rootCanonical, readOnly ? undefined : cwdRef, readFaceRoots, opts.readImageDownsampler, opts.pdfModelCapabilities, bgOutputReadExemption),
|
|
33
|
+
createReadFileTool(env, readFileState, rootCanonical, readOnly ? undefined : cwdRef, readFaceRoots, opts.readImageDownsampler, opts.pdfModelCapabilities, bgOutputReadExemption, opts.readCyberReminder),
|
|
34
34
|
];
|
|
35
35
|
if (!readOnly) {
|
|
36
36
|
tools.push(createEditFileTool(env, readFileState, rootCanonical, cwdRef, additionalRoots, opts.beforeWrite), createWriteFileTool(env, readFileState, rootCanonical, cwdRef, additionalRoots, opts.beforeWrite), createNotebookEditTool(env, readFileState, rootCanonical, cwdRef, additionalRoots, opts.beforeWrite));
|
|
@@ -82,4 +82,5 @@ export declare function escapeMatchWasAttempted(oldString: string): boolean;
|
|
|
82
82
|
export declare const ESCAPE_MATCH_MISS_NOTE = "\n(note: Edit also tried swapping \\uXXXX escapes and their characters; neither form matched, so the mismatch is likely elsewhere in old_string. Re-read the file and copy the exact surrounding text.)";
|
|
83
83
|
export declare function adaptNewStringQuotes(matchedOld: string, newString: string): string;
|
|
84
84
|
export declare function deletionOldString(content: string, oldString: string, newString: string): string;
|
|
85
|
+
export declare const EDIT_ECHO_MAX_CHARS = 200;
|
|
85
86
|
export declare function checkEditMatch(content: string, oldString: string, replaceAll: boolean, truncated: boolean): FsViolation | undefined;
|
package/dist/tools/fs/safety.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { sliceHeadSafe } from "../../core/surrogate-safe-slice.js";
|
|
2
3
|
export function fileArgPath(args) {
|
|
3
4
|
const a = args;
|
|
4
5
|
const fp = a?.file_path;
|
|
@@ -577,6 +578,12 @@ export function deletionOldString(content, oldString, newString) {
|
|
|
577
578
|
return oldString + "\n";
|
|
578
579
|
return oldString;
|
|
579
580
|
}
|
|
581
|
+
export const EDIT_ECHO_MAX_CHARS = 200;
|
|
582
|
+
function boundEditEcho(oldString) {
|
|
583
|
+
if (oldString.length <= EDIT_ECHO_MAX_CHARS)
|
|
584
|
+
return oldString;
|
|
585
|
+
return `${sliceHeadSafe(oldString, EDIT_ECHO_MAX_CHARS)}… (truncated)`;
|
|
586
|
+
}
|
|
580
587
|
export function checkEditMatch(content, oldString, replaceAll, truncated) {
|
|
581
588
|
if (oldString === "") {
|
|
582
589
|
return { code: "invalid", message: "old_string must not be empty." };
|
|
@@ -585,13 +592,13 @@ export function checkEditMatch(content, oldString, replaceAll, truncated) {
|
|
|
585
592
|
if (n === 0) {
|
|
586
593
|
return {
|
|
587
594
|
code: "ambiguous_edit",
|
|
588
|
-
message: `String to replace not found in file.${truncated ? " (note: the read was truncated — it may be in the unshown portion)" : ""}\nString: ${oldString}`,
|
|
595
|
+
message: `String to replace not found in file.${truncated ? " (note: the read was truncated — it may be in the unshown portion)" : ""}\nString: ${boundEditEcho(oldString)}`,
|
|
589
596
|
};
|
|
590
597
|
}
|
|
591
598
|
if (n > 1 && !replaceAll) {
|
|
592
599
|
return {
|
|
593
600
|
code: "ambiguous_edit",
|
|
594
|
-
message: `Found ${n} matches of the string to replace, but replace_all is false. To replace all occurrences, set replace_all to true. To replace only one occurrence, please provide more context to uniquely identify the instance.${truncated ? " (the read was truncated; some matches may be in the unshown portion)" : ""}\nString: ${oldString}`,
|
|
601
|
+
message: `Found ${n} matches of the string to replace, but replace_all is false. To replace all occurrences, set replace_all to true. To replace only one occurrence, please provide more context to uniquely identify the instance.${truncated ? " (the read was truncated; some matches may be in the unshown portion)" : ""}\nString: ${boundEditEcho(oldString)}`,
|
|
595
602
|
};
|
|
596
603
|
}
|
|
597
604
|
return undefined;
|