@pentoshi/clai 3.13.0 → 3.13.1
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/LICENSE +1 -1
- package/dist/agent/message-slim.d.ts +6 -18
- package/dist/agent/message-slim.js +41 -23
- package/dist/agent/message-slim.js.map +1 -1
- package/dist/agent/runner.js +8 -0
- package/dist/agent/runner.js.map +1 -1
- package/dist/prompts/embedded.js +1 -1
- package/dist/prompts/embedded.js.map +1 -1
- package/dist/prompts/index.js +3 -3
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/system.agent.md +2 -2
- package/dist/tools/elevated-shell.d.ts +4 -29
- package/dist/tools/elevated-shell.js +46 -71
- package/dist/tools/elevated-shell.js.map +1 -1
- package/dist/tools/registry.js +14 -4
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/shell.d.ts +2 -14
- package/dist/tools/shell.js +19 -43
- package/dist/tools/shell.js.map +1 -1
- package/dist/version.generated.d.ts +2 -2
- package/dist/version.generated.js +2 -2
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,24 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cap in-memory / re-sent message bulk from native toolCalls.
|
|
3
|
-
*
|
|
4
|
-
* fs.write / writeMany put entire file bodies in tool-call args. Those were
|
|
5
|
-
* stored verbatim in history and LoopGuard signatures, so a scaffold turn
|
|
6
|
-
* could hold many multi-MB strings — memory climbed into the multi-GB range
|
|
7
|
-
* and Macs heated under GC. Full file bodies remain on disk; tool results
|
|
8
|
-
* still report paths/bytes.
|
|
9
|
-
*/
|
|
10
|
-
/** Strings at or above this are replaced with a length+hash stub. */
|
|
11
1
|
export declare const SLIM_ARG_STRING_CHARS = 400;
|
|
12
|
-
/** Hard ceiling for a single string kept as-is in history (safety). */
|
|
13
2
|
export declare const SLIM_ARG_ABSOLUTE_MAX_CHARS = 8000;
|
|
14
|
-
|
|
15
|
-
* Replace large string values with a compact stub so history/loop-guard
|
|
16
|
-
* never retains full write payloads. Small strings and structure stay intact
|
|
17
|
-
* so path-based identity still works for loop detection.
|
|
18
|
-
*/
|
|
19
|
-
export declare function slimValue(value: unknown, depth?: number): unknown;
|
|
3
|
+
export declare function slimValue(value: unknown, depth?: number, key?: string): unknown;
|
|
20
4
|
export declare function slimToolArgs(args: Record<string, unknown>): Record<string, unknown>;
|
|
21
|
-
|
|
5
|
+
export declare function findElidedStubArg(value: unknown, path?: string, depth?: number): {
|
|
6
|
+
key: string;
|
|
7
|
+
value: string;
|
|
8
|
+
} | undefined;
|
|
9
|
+
export declare function elidedStubReuseMessage(key: string): string;
|
|
22
10
|
export declare function measureToolCallsChars(toolCalls: readonly {
|
|
23
11
|
readonly name?: string;
|
|
24
12
|
readonly id?: string;
|
|
@@ -1,33 +1,23 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Cap in-memory / re-sent message bulk from native toolCalls.
|
|
3
|
-
*
|
|
4
|
-
* fs.write / writeMany put entire file bodies in tool-call args. Those were
|
|
5
|
-
* stored verbatim in history and LoopGuard signatures, so a scaffold turn
|
|
6
|
-
* could hold many multi-MB strings — memory climbed into the multi-GB range
|
|
7
|
-
* and Macs heated under GC. Full file bodies remain on disk; tool results
|
|
8
|
-
* still report paths/bytes.
|
|
9
|
-
*/
|
|
10
1
|
import { createHash } from "node:crypto";
|
|
11
|
-
/** Strings at or above this are replaced with a length+hash stub. */
|
|
12
2
|
export const SLIM_ARG_STRING_CHARS = 400;
|
|
13
|
-
/** Hard ceiling for a single string kept as-is in history (safety). */
|
|
14
3
|
export const SLIM_ARG_ABSOLUTE_MAX_CHARS = 8_000;
|
|
15
|
-
/** Max depth when walking args trees (writeMany files[]). */
|
|
16
4
|
const SLIM_MAX_DEPTH = 6;
|
|
5
|
+
const BULK_ARG_KEYS = new Set(["content", "body"]);
|
|
6
|
+
const ELIDED_STUB_PATTERN = /^«\d+ chars sha256=[0-9a-f]{12}(?:\s+—.*)?»$/s;
|
|
17
7
|
function shortHash(text) {
|
|
18
8
|
return createHash("sha256").update(text).digest("hex").slice(0, 12);
|
|
19
9
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export function slimValue(value, depth = 0) {
|
|
10
|
+
function slimLimitForKey(key) {
|
|
11
|
+
return key !== undefined && BULK_ARG_KEYS.has(key)
|
|
12
|
+
? SLIM_ARG_STRING_CHARS
|
|
13
|
+
: SLIM_ARG_ABSOLUTE_MAX_CHARS;
|
|
14
|
+
}
|
|
15
|
+
export function slimValue(value, depth = 0, key) {
|
|
26
16
|
if (typeof value === "string") {
|
|
27
|
-
if (value.length <
|
|
17
|
+
if (value.length < slimLimitForKey(key))
|
|
28
18
|
return value;
|
|
29
19
|
const hash = shortHash(value);
|
|
30
|
-
return `«${value.length} chars sha256=${hash}»`;
|
|
20
|
+
return `«${value.length} chars sha256=${hash} — elided from history; never reuse this stub, regenerate the full value»`;
|
|
31
21
|
}
|
|
32
22
|
if (value === null || value === undefined)
|
|
33
23
|
return value;
|
|
@@ -42,8 +32,8 @@ export function slimValue(value, depth = 0) {
|
|
|
42
32
|
return value.map((entry) => slimValue(entry, depth + 1));
|
|
43
33
|
}
|
|
44
34
|
const out = {};
|
|
45
|
-
for (const
|
|
46
|
-
out[
|
|
35
|
+
for (const childKey of Object.keys(value).sort()) {
|
|
36
|
+
out[childKey] = slimValue(value[childKey], depth + 1, childKey);
|
|
47
37
|
}
|
|
48
38
|
return out;
|
|
49
39
|
}
|
|
@@ -54,7 +44,35 @@ export function slimToolArgs(args) {
|
|
|
54
44
|
}
|
|
55
45
|
return {};
|
|
56
46
|
}
|
|
57
|
-
|
|
47
|
+
export function findElidedStubArg(value, path = "args", depth = 0) {
|
|
48
|
+
if (typeof value === "string") {
|
|
49
|
+
return ELIDED_STUB_PATTERN.test(value) ? { key: path, value } : undefined;
|
|
50
|
+
}
|
|
51
|
+
if (value === null || value === undefined || typeof value !== "object") {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
if (depth >= SLIM_MAX_DEPTH)
|
|
55
|
+
return undefined;
|
|
56
|
+
if (Array.isArray(value)) {
|
|
57
|
+
for (let i = 0; i < value.length; i += 1) {
|
|
58
|
+
const found = findElidedStubArg(value[i], `${path}[${i}]`, depth + 1);
|
|
59
|
+
if (found)
|
|
60
|
+
return found;
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
for (const [childKey, childValue] of Object.entries(value)) {
|
|
65
|
+
const found = findElidedStubArg(childValue, path ? `${path}.${childKey}` : childKey, depth + 1);
|
|
66
|
+
if (found)
|
|
67
|
+
return found;
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
export function elidedStubReuseMessage(key) {
|
|
72
|
+
return (`Tool call rejected: argument "${key}" is an elided history placeholder («N chars sha256=…»), not a real value. ` +
|
|
73
|
+
"Compressed history replaces long arguments with those stubs and the original text cannot be recovered from them. " +
|
|
74
|
+
"Re-issue the tool call with the complete literal value — never copy «…» stubs from earlier context.");
|
|
75
|
+
}
|
|
58
76
|
export function measureToolCallsChars(toolCalls) {
|
|
59
77
|
if (!toolCalls?.length)
|
|
60
78
|
return 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-slim.js","sourceRoot":"","sources":["../../src/agent/message-slim.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"message-slim.js","sourceRoot":"","sources":["../../src/agent/message-slim.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/runner.js
CHANGED
|
@@ -39,6 +39,7 @@ function safeEngagementActionsForToolCall(call) {
|
|
|
39
39
|
}
|
|
40
40
|
import { availableToolNames, normalizeToolCall, runToolCall, BATCH_SAFE_TOOLS, } from "../tools/registry.js";
|
|
41
41
|
import { getToolDefinitions, getCompactToolDefinitions, RUNNER_META_TOOL_NAMES, } from "../tools/definitions.js";
|
|
42
|
+
import { elidedStubReuseMessage, findElidedStubArg, } from "./message-slim.js";
|
|
42
43
|
import { appendAssistantWithTools, ensureUniqueToolCallIds, toolCallIdsInHistory, appendToolResult, assertValidToolProtocol, fillMissingToolResults, repairToolProtocol, } from "./tool-history.js";
|
|
43
44
|
import { formatViewportHint, registerViewport } from "../ui/output-pane.js";
|
|
44
45
|
import { compactMessagesWithSummary, shouldApplyAutoCompact, COMPACTION_MEMORY_PREFIX, PLAN_IMPLEMENT_MEMORY_PREFIX, isCompactionMemoryMessage, } from "./context-manager.js";
|
|
@@ -1265,6 +1266,13 @@ export async function runAgentTurn(prompt, options = {}) {
|
|
|
1265
1266
|
emitToolResult(toolEventId, result, reason);
|
|
1266
1267
|
return { ok: false, call, result, contextOutput: reason };
|
|
1267
1268
|
}
|
|
1269
|
+
const elidedStub = findElidedStubArg(call.args);
|
|
1270
|
+
if (elidedStub) {
|
|
1271
|
+
const reason = elidedStubReuseMessage(elidedStub.key);
|
|
1272
|
+
const result = { ok: false, output: reason, exitCode: 1 };
|
|
1273
|
+
emitToolResult(toolEventId, result, reason);
|
|
1274
|
+
return { ok: false, call, result, contextOutput: reason };
|
|
1275
|
+
}
|
|
1268
1276
|
if (call.name === "image.ocr" && !imageOcrEnabled) {
|
|
1269
1277
|
writeNotice("info", "skipped OCR because the original image is attached to the vision model", chalk.dim(" ℹ skipped OCR — inspecting the attached image directly\n"));
|
|
1270
1278
|
const recoveryText = "The original image is attached to this message and you can inspect it directly. " +
|