@sema-agent/core 2.12.0 → 3.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 +1 -0
- package/dist/agents/agent-transcript-tool.js +1 -1
- package/dist/agents/cascade.d.ts +4 -0
- package/dist/agents/cascade.js +54 -9
- package/dist/agents/repair-loop.d.ts +2 -0
- package/dist/agents/repair-loop.js +101 -2
- package/dist/agents/retain-ledger.d.ts +18 -2
- package/dist/agents/retain-ledger.js +37 -8
- package/dist/agents/roster-store.d.ts +4 -0
- package/dist/agents/roster-store.js +22 -1
- package/dist/agents/teacher.js +4 -2
- package/dist/agents/team.js +7 -4
- package/dist/agents/verify.d.ts +15 -2
- package/dist/agents/verify.js +36 -1
- package/dist/bin/sema-tb.js +2 -2
- package/dist/brain/circuit-breaker.d.ts +1 -0
- package/dist/brain/circuit-breaker.js +26 -9
- package/dist/brain/degrading.js +13 -1
- package/dist/brain/failover.js +2 -0
- package/dist/brain/repetition.js +10 -1
- package/dist/brain/routing.js +5 -1
- package/dist/brain/status-sink.js +5 -1
- package/dist/brain/stream-engine.js +4 -1
- package/dist/brain/tool-call-repair.js +32 -14
- package/dist/core/auto-compaction.js +17 -7
- package/dist/core/auto-promote.js +2 -1
- package/dist/core/checkpoint-store.d.ts +1 -0
- package/dist/core/checkpoint-store.js +28 -10
- package/dist/core/consolidate-scope.js +4 -3
- package/dist/core/context-edit.js +3 -0
- package/dist/core/context-guard.js +3 -0
- package/dist/core/git-worktree-env.d.ts +6 -1
- package/dist/core/git-worktree-env.js +17 -1
- package/dist/core/hooks.d.ts +1 -0
- package/dist/core/hooks.js +40 -2
- package/dist/core/lsp-diagnostics.js +13 -7
- package/dist/core/lsp-protocol.d.ts +1 -1
- package/dist/core/lsp-protocol.js +20 -8
- package/dist/core/lsp-session.d.ts +12 -2
- package/dist/core/lsp-session.js +114 -49
- package/dist/core/lsp.d.ts +13 -1
- package/dist/core/lsp.js +64 -9
- package/dist/core/mcp.d.ts +1 -0
- package/dist/core/mcp.js +4 -3
- package/dist/core/memory-engine/data-plane.js +4 -0
- package/dist/core/memory-engine/engine.d.ts +2 -1
- package/dist/core/memory-engine/engine.js +82 -7
- package/dist/core/memory-engine/file-backend.d.ts +1 -0
- package/dist/core/memory-engine/file-backend.js +13 -3
- package/dist/core/memory-engine/layout.js +12 -1
- package/dist/core/memory.js +3 -0
- package/dist/core/permission-rules.d.ts +2 -1
- package/dist/core/permission-rules.js +24 -3
- package/dist/core/runner/active-skill-scope.js +34 -6
- package/dist/core/runner/assemble-result.d.ts +1 -1
- package/dist/core/runner/assemble-result.js +0 -1
- package/dist/core/runner/prepare-task.js +23 -3
- package/dist/core/runner/runtask.js +48 -30
- package/dist/core/runner/tool-disclosure.d.ts +1 -0
- package/dist/core/runner/tool-disclosure.js +26 -7
- package/dist/core/runner/usage-accounting.d.ts +6 -0
- package/dist/core/runner/usage-accounting.js +9 -8
- package/dist/core/secret-env.js +5 -1
- package/dist/core/sensitive-path-policy.js +9 -3
- package/dist/core/session-store.js +15 -4
- package/dist/core/skill-tool-specifier.d.ts +8 -0
- package/dist/core/skill-tool-specifier.js +58 -0
- package/dist/core/skills-directory.d.ts +1 -1
- package/dist/core/skills-directory.js +16 -4
- package/dist/core/store-contracts/session-repo-contract.js +40 -0
- package/dist/core/task-registry-monitor.js +7 -1
- package/dist/core/tool-policy.js +65 -17
- package/dist/core/trace.d.ts +1 -0
- package/dist/core/types.d.ts +3 -5
- package/dist/core/with-retry.js +0 -1
- package/dist/engine/compaction/compaction.d.ts +1 -0
- package/dist/engine/compaction/compaction.js +14 -5
- package/dist/engine/lsp/frame-decoder.js +6 -3
- package/dist/engine/lsp/node-lsp-manager.d.ts +2 -0
- package/dist/engine/lsp/node-lsp-manager.js +103 -26
- package/dist/engine/lsp/stdio-lsp-transport.js +16 -7
- package/dist/index.d.ts +1 -1
- package/dist/internal/harness.d.ts +1 -1
- package/dist/internal/harness.js +1 -1
- package/dist/internal/llm.d.ts +1 -1
- package/dist/orchestration/workflow-governance.js +43 -9
- package/dist/orchestration/workflow-sandbox-conformance.js +85 -51
- package/dist/orchestration/workflow-script-store.js +34 -4
- package/dist/orchestration/workflow.js +10 -6
- package/dist/prompt-assembly/artifact-store.d.ts +2 -0
- package/dist/prompt-assembly/artifact-store.js +39 -24
- package/dist/prompt-assembly/assemble.js +38 -7
- package/dist/prompt-assembly/epoch.js +19 -2
- package/dist/prompt-assembly/event-registry.js +3 -3
- package/dist/prompt-assembly/explain.js +1 -1
- package/dist/prompt-assembly/tool-catalog.js +16 -1
- package/dist/prompt-assembly/turn-snapshot.js +4 -1
- package/dist/stores/file/fs-atomic.d.ts +3 -0
- package/dist/stores/file/fs-atomic.js +53 -8
- package/dist/stores/file/index.d.ts +1 -0
- package/dist/stores/file/index.js +7 -0
- package/dist/stores/file/session-store.d.ts +2 -0
- package/dist/stores/file/session-store.js +28 -1
- package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -0
- package/dist/tools/fs/bash-readonly-classifier.js +57 -8
- package/dist/tools/fs/fs-bash.d.ts +1 -1
- package/dist/tools/fs/fs-bash.js +93 -5
- package/dist/tools/loop-tick.js +1 -1
- package/dist/tools/monitor.js +55 -9
- package/dist/tools/scheduler-tools.js +9 -3
- package/dist/tools/web.d.ts +8 -2
- package/dist/tools/web.js +46 -17
- package/dist/tools/worktree.d.ts +2 -0
- package/dist/tools/worktree.js +233 -143
- package/package.json +5 -2
package/dist/core/tool-policy.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
|
-
import { isAbsolute, join, sep } from "node:path";
|
|
2
|
+
import { isAbsolute, join, normalize as normalizePath, sep } from "node:path";
|
|
3
3
|
import { BASH_READONLY_DEFAULT_ALLOW, parseLeadingCommandName } from "../tools/fs/index.js";
|
|
4
|
+
import { writeTargetPath } from "../tools/fs/safety.js";
|
|
4
5
|
import { canonicalToolName } from "./tool-name-aliases.js";
|
|
5
6
|
export function decisionText(d) {
|
|
6
7
|
return d.message ?? d.reason;
|
|
@@ -106,7 +107,7 @@ export function combinePolicies(...policies) {
|
|
|
106
107
|
current = { ...current, args: d.updatedInput };
|
|
107
108
|
rewrite = d;
|
|
108
109
|
}
|
|
109
|
-
if (d.action === "ask" &&
|
|
110
|
+
if (d.action === "ask" && (asked === undefined || (d.requiresRealApproval === true && asked.requiresRealApproval !== true))) {
|
|
110
111
|
asked = d;
|
|
111
112
|
}
|
|
112
113
|
}
|
|
@@ -119,10 +120,13 @@ export function combinePolicies(...policies) {
|
|
|
119
120
|
};
|
|
120
121
|
}
|
|
121
122
|
export const COARSE_SHELL_TOOLS = ["Bash", "Monitor"];
|
|
123
|
+
function canonicalToolNameSet(tools) {
|
|
124
|
+
return new Set((tools ?? COARSE_SHELL_TOOLS).map(canonicalToolName));
|
|
125
|
+
}
|
|
122
126
|
export function createCoarseCommandNamePolicy(opts) {
|
|
123
127
|
const allow = opts.allow ? new Set(opts.allow) : undefined;
|
|
124
128
|
const deny = new Set(opts.deny ?? []);
|
|
125
|
-
const shellTools =
|
|
129
|
+
const shellTools = canonicalToolNameSet(opts.tools);
|
|
126
130
|
const defaultAction = opts.defaultAction ?? "ask";
|
|
127
131
|
const fallback = (reason) => defaultAction === "deny"
|
|
128
132
|
? { action: "deny", reason, decisionReason: "rule" }
|
|
@@ -154,6 +158,7 @@ const DELETE_HEADS = new Set(["rm", "xargs", "Remove-Item"]);
|
|
|
154
158
|
const DELETE_WRAPPERS = new Set([
|
|
155
159
|
"sudo", "command", "nohup", "time", "do", "then", "else",
|
|
156
160
|
"env", "nice", "ionice", "exec", "doas", "setsid", "stdbuf", "chroot", "eval",
|
|
161
|
+
"sh", "bash", "zsh", "dash", "ksh", "ash", "timeout", "case",
|
|
157
162
|
]);
|
|
158
163
|
const STATEMENT_SPLIT = /[;&|\n]+/;
|
|
159
164
|
const stripTokenEdges = (t) => t.replace(/^[("'{]+|[)"'}]+$/g, "");
|
|
@@ -209,7 +214,7 @@ export function findUnverifiableRecursiveDelete(command, safeVars = new Set(UNVE
|
|
|
209
214
|
}
|
|
210
215
|
return false;
|
|
211
216
|
};
|
|
212
|
-
const statements = command.split(STATEMENT_SPLIT);
|
|
217
|
+
const statements = command.replace(/\\\r?\n/g, " ").split(STATEMENT_SPLIT);
|
|
213
218
|
for (const stmt of statements) {
|
|
214
219
|
const tokens = stmt.trim().split(/\s+/).filter(Boolean);
|
|
215
220
|
let i = 0;
|
|
@@ -230,6 +235,10 @@ export function findUnverifiableRecursiveDelete(command, safeVars = new Set(UNVE
|
|
|
230
235
|
let sawWrapper = false;
|
|
231
236
|
while (i < tokens.length) {
|
|
232
237
|
const t = stripTokenEdges(tokens[i]).replace(/^\\/, "");
|
|
238
|
+
if (t === "") {
|
|
239
|
+
i++;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
233
242
|
if (DELETE_WRAPPERS.has(t)) {
|
|
234
243
|
sawWrapper = true;
|
|
235
244
|
i++;
|
|
@@ -237,8 +246,9 @@ export function findUnverifiableRecursiveDelete(command, safeVars = new Set(UNVE
|
|
|
237
246
|
i++;
|
|
238
247
|
continue;
|
|
239
248
|
}
|
|
240
|
-
if (
|
|
241
|
-
|
|
249
|
+
if (/\)$/.test(tokens[i]) && !DELETE_HEADS.has(t)) {
|
|
250
|
+
sawWrapper = true;
|
|
251
|
+
i++;
|
|
242
252
|
continue;
|
|
243
253
|
}
|
|
244
254
|
break;
|
|
@@ -368,7 +378,7 @@ function hasRecursiveForce(argvTail) {
|
|
|
368
378
|
}
|
|
369
379
|
export function createUnverifiableDeletePolicy(opts) {
|
|
370
380
|
const safeVars = new Set([...UNVERIFIABLE_DELETE_SAFE_VARS, ...(opts?.safeVars ?? [])]);
|
|
371
|
-
const shellTools =
|
|
381
|
+
const shellTools = canonicalToolNameSet(opts?.tools);
|
|
372
382
|
return {
|
|
373
383
|
check(req) {
|
|
374
384
|
if (!shellTools.has(canonicalToolName(req.toolName)))
|
|
@@ -390,10 +400,28 @@ export function createUnverifiableDeletePolicy(opts) {
|
|
|
390
400
|
},
|
|
391
401
|
};
|
|
392
402
|
}
|
|
403
|
+
function pathSegments(p) {
|
|
404
|
+
return p.split(/[\\/]/).filter(Boolean);
|
|
405
|
+
}
|
|
406
|
+
function lexicalPath(p, home) {
|
|
407
|
+
const norm = p.normalize("NFC");
|
|
408
|
+
const expanded = norm === "~" ? home : /^~[\\/]/.test(norm) ? join(home, norm.slice(2)) : norm;
|
|
409
|
+
return normalizePath(expanded);
|
|
410
|
+
}
|
|
411
|
+
const RELATIVE_TAIL_MIN_SEGMENTS = 2;
|
|
412
|
+
function relativeContinuesDirTail(segs, dirSegs) {
|
|
413
|
+
const from = Math.min(RELATIVE_TAIL_MIN_SEGMENTS, dirSegs.length);
|
|
414
|
+
for (let k = from; k <= Math.min(segs.length, dirSegs.length); k++) {
|
|
415
|
+
const tail = dirSegs.slice(dirSegs.length - k);
|
|
416
|
+
if (tail.every((s, i) => s === segs[i]))
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
393
421
|
export function createTranscriptIntegrityPolicy(opts) {
|
|
394
422
|
const home = homedir();
|
|
395
423
|
const defaultRoot = (process.env.AGENT_DATA_DIR ?? join(home, ".ai-agent")).normalize("NFC");
|
|
396
|
-
const dirs = (opts?.sessionsDirs ?? [join(defaultRoot, "sessions")]).map((d) => d
|
|
424
|
+
const dirs = (opts?.sessionsDirs ?? [join(defaultRoot, "sessions")]).map((d) => lexicalPath(d, home).replace(/(?<=.)[\\/]+$/, ""));
|
|
397
425
|
const textualForms = dirs.flatMap((d) => {
|
|
398
426
|
const forms = [d];
|
|
399
427
|
if (d.startsWith(home + sep)) {
|
|
@@ -403,13 +431,34 @@ export function createTranscriptIntegrityPolicy(opts) {
|
|
|
403
431
|
return forms;
|
|
404
432
|
});
|
|
405
433
|
const readAllow = new Set(opts?.readAllow ?? BASH_READONLY_DEFAULT_ALLOW);
|
|
406
|
-
const shellTools =
|
|
434
|
+
const shellTools = canonicalToolNameSet(opts?.tools);
|
|
435
|
+
const dirSegs = dirs.map(pathSegments);
|
|
407
436
|
const inProtectedDir = (p) => {
|
|
408
|
-
const
|
|
409
|
-
const
|
|
410
|
-
if (
|
|
411
|
-
return
|
|
412
|
-
|
|
437
|
+
const abs = lexicalPath(p, home);
|
|
438
|
+
const segs = pathSegments(abs);
|
|
439
|
+
if (isAbsolute(abs)) {
|
|
440
|
+
return dirSegs.some((d) => d.length <= segs.length && d.every((s, i) => s === segs[i]));
|
|
441
|
+
}
|
|
442
|
+
return dirSegs.some((d) => relativeContinuesDirTail(segs, d));
|
|
443
|
+
};
|
|
444
|
+
const referencesProtectedDir = (cmd) => {
|
|
445
|
+
if (textualForms.some((f) => cmd.includes(f)))
|
|
446
|
+
return true;
|
|
447
|
+
for (const raw of cmd.split(/[\s;&|<>()]+/)) {
|
|
448
|
+
if (raw === "")
|
|
449
|
+
continue;
|
|
450
|
+
const unquoted = raw.replace(/["'`]/g, "");
|
|
451
|
+
if (unquoted === "")
|
|
452
|
+
continue;
|
|
453
|
+
const expanded = unquoted.startsWith("${HOME}")
|
|
454
|
+
? home + unquoted.slice("${HOME}".length)
|
|
455
|
+
: unquoted.startsWith("$HOME")
|
|
456
|
+
? home + unquoted.slice("$HOME".length)
|
|
457
|
+
: unquoted;
|
|
458
|
+
if (inProtectedDir(expanded))
|
|
459
|
+
return true;
|
|
460
|
+
}
|
|
461
|
+
return false;
|
|
413
462
|
};
|
|
414
463
|
const askReason = (what) => ({
|
|
415
464
|
action: "ask",
|
|
@@ -428,7 +477,7 @@ export function createTranscriptIntegrityPolicy(opts) {
|
|
|
428
477
|
if (typeof command !== "string")
|
|
429
478
|
return ALLOW;
|
|
430
479
|
const cmd = command.normalize("NFC");
|
|
431
|
-
if (!
|
|
480
|
+
if (!referencesProtectedDir(cmd))
|
|
432
481
|
return ALLOW;
|
|
433
482
|
const parsed = parseLeadingCommandName(command);
|
|
434
483
|
if ("name" in parsed && readAllow.has(parsed.name))
|
|
@@ -438,8 +487,7 @@ export function createTranscriptIntegrityPolicy(opts) {
|
|
|
438
487
|
: "the command references the transcript directory and is not a single read-only command (fail-closed)");
|
|
439
488
|
}
|
|
440
489
|
if (toolName === "Write" || toolName === "Edit" || toolName === "NotebookEdit") {
|
|
441
|
-
const
|
|
442
|
-
const p = a?.file_path ?? a?.notebook_path;
|
|
490
|
+
const p = writeTargetPath(toolName, req.args);
|
|
443
491
|
if (typeof p === "string" && inProtectedDir(p)) {
|
|
444
492
|
return askReason(`"${p}" is inside the session-transcript directory`);
|
|
445
493
|
}
|
package/dist/core/trace.d.ts
CHANGED
package/dist/core/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { TSchema } from "typebox";
|
|
2
2
|
import type { AgentTool, ThinkingLevel } from "../internal/harness.js";
|
|
3
|
-
import type { DocumentContent, ImageContent, Model, ResilienceOptions, StreamFn, TextContent } from "../internal/llm.js";
|
|
3
|
+
import type { CompleteSimpleFn, DocumentContent, ImageContent, Model, ResilienceOptions, StreamFn, TextContent } from "../internal/llm.js";
|
|
4
4
|
import type { TaskNotificationPayload } from "./task-notification.js";
|
|
5
5
|
export type ModelRef = string | Model;
|
|
6
6
|
export type ModelRole = "default" | "summarize" | "subagent" | "team" | "synthesize" | "advisor" | "verifier" | "classifier";
|
|
@@ -13,10 +13,7 @@ export type RoleSpec = ModelRef | {
|
|
|
13
13
|
export type ModelRoles = Partial<Record<ModelRole, RoleSpec>>;
|
|
14
14
|
export interface Brain {
|
|
15
15
|
stream: StreamFn;
|
|
16
|
-
complete?:
|
|
17
|
-
systemPrompt?: string;
|
|
18
|
-
messages: unknown[];
|
|
19
|
-
}, options?: unknown) => Promise<unknown>;
|
|
16
|
+
complete?: CompleteSimpleFn;
|
|
20
17
|
}
|
|
21
18
|
export type ToolEffect = "read" | "write" | "idempotent";
|
|
22
19
|
export interface ToolSpec<TParams extends TSchema = TSchema> {
|
|
@@ -527,6 +524,7 @@ export type TaskEvent = ({
|
|
|
527
524
|
type: "turn_end";
|
|
528
525
|
usage?: {
|
|
529
526
|
inputTokens: number;
|
|
527
|
+
totalInputTokens: number;
|
|
530
528
|
outputTokens: number;
|
|
531
529
|
cacheReadTokens: number;
|
|
532
530
|
cacheWriteTokens: number;
|
package/dist/core/with-retry.js
CHANGED
|
@@ -78,3 +78,4 @@ export interface CompactionPreparation {
|
|
|
78
78
|
export declare function prepareCompaction(pathEntries: SessionTreeEntry[], settings: CompactionSettings, charsPerToken?: number, windowTokens?: number): Result<CompactionPreparation | undefined, CompactionError>;
|
|
79
79
|
export { computeFileLists, serializeConversation } from "./utils.js";
|
|
80
80
|
export declare function compact(preparation: CompactionPreparation, model: Model, apiKey: string | undefined, headers?: Record<string, string>, customInstructions?: string, signal?: AbortSignal, thinkingLevel?: ThinkingLevel, streamFn?: StreamFn, runtime?: AgentCoreCompletionRuntimeDeps, charsPerToken?: number, onInputTruncated?: (info: SummarizationInputTruncation) => void, onPtlRetry?: () => void): Promise<Result<CompactionResult, CompactionError>>;
|
|
81
|
+
export declare function turnPrefixSummarizationPrompt(customInstructions?: string): string;
|
|
@@ -132,6 +132,9 @@ export function shouldCompact(contextTokens, contextWindow, settings) {
|
|
|
132
132
|
if (!settings.enabled) {
|
|
133
133
|
return false;
|
|
134
134
|
}
|
|
135
|
+
if (!Number.isFinite(contextWindow) || contextWindow <= 0) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
135
138
|
return contextTokens > contextWindow - settings.reserveTokens;
|
|
136
139
|
}
|
|
137
140
|
export function estimateTokens(message, charsPerToken = DEFAULT_CHARS_PER_TOKEN) {
|
|
@@ -539,7 +542,7 @@ export function dryRunSummarizationClamp(preparation, model, customInstructions,
|
|
|
539
542
|
if (isSplitTurn && turnPrefixMessages.length > 0) {
|
|
540
543
|
const text = serializeConversation(convertToLlm(turnPrefixMessages));
|
|
541
544
|
conversationChars += text.length;
|
|
542
|
-
const clamped = clampSummarizationConversation(text, model, cpt, SUMMARIZATION_SYSTEM_PROMPT.length +
|
|
545
|
+
const clamped = clampSummarizationConversation(text, model, cpt, SUMMARIZATION_SYSTEM_PROMPT.length + turnPrefixSummarizationPrompt(customInstructions).length + 128, Math.floor(0.5 * summaryBudget));
|
|
543
546
|
dropped += Math.max(0, clamped.droppedChars);
|
|
544
547
|
kept += clamped.keptChars;
|
|
545
548
|
}
|
|
@@ -879,7 +882,7 @@ export async function compact(preparation, model, apiKey, headers, customInstruc
|
|
|
879
882
|
? generateSummary(messagesToSummarize, model, summaryBudget, apiKey, headers, signal, customInstructions, previousSummary, thinkingLevel, streamFn, runtime, charsPerToken, onInputTruncated, onPtlRetry)
|
|
880
883
|
:
|
|
881
884
|
Promise.resolve(ok(previousSummary ? stripFileOperationsFooter(previousSummary) : "No prior history.")),
|
|
882
|
-
generateTurnPrefixSummary(turnPrefixMessages, model, summaryBudget, apiKey, headers, signal, thinkingLevel, streamFn, runtime, charsPerToken, onInputTruncated, onPtlRetry),
|
|
885
|
+
generateTurnPrefixSummary(turnPrefixMessages, model, summaryBudget, apiKey, headers, signal, customInstructions, thinkingLevel, streamFn, runtime, charsPerToken, onInputTruncated, onPtlRetry),
|
|
883
886
|
]);
|
|
884
887
|
if (!historyResult.ok) {
|
|
885
888
|
return err(historyResult.error);
|
|
@@ -913,16 +916,22 @@ export async function compact(preparation, model, apiKey, headers, customInstruc
|
|
|
913
916
|
},
|
|
914
917
|
});
|
|
915
918
|
}
|
|
916
|
-
|
|
919
|
+
export function turnPrefixSummarizationPrompt(customInstructions) {
|
|
920
|
+
return customInstructions
|
|
921
|
+
? `${TURN_PREFIX_SUMMARIZATION_PROMPT}\n\nAdditional Instructions:\n${customInstructions}`
|
|
922
|
+
: TURN_PREFIX_SUMMARIZATION_PROMPT;
|
|
923
|
+
}
|
|
924
|
+
async function generateTurnPrefixSummary(messages, model, summaryBudgetTokens, apiKey, headers, signal, customInstructions, thinkingLevel, streamFn, runtime, charsPerToken, onInputTruncated, onPtlRetry) {
|
|
917
925
|
const llmMessages = convertToLlm(messages);
|
|
926
|
+
const basePrompt = turnPrefixSummarizationPrompt(customInstructions);
|
|
918
927
|
return summarizeWithPtlRetry({
|
|
919
928
|
label: "Turn prefix summarization",
|
|
920
929
|
truncationLabel: "turn_prefix",
|
|
921
930
|
llmMessages,
|
|
922
|
-
buildPromptText: (conversationText) => `<conversation>\n${conversationText}\n</conversation>\n\n${
|
|
931
|
+
buildPromptText: (conversationText) => `<conversation>\n${conversationText}\n</conversation>\n\n${basePrompt}`,
|
|
923
932
|
model,
|
|
924
933
|
cpt: charsPerToken ?? model.charsPerToken ?? DEFAULT_CHARS_PER_TOKEN,
|
|
925
|
-
fixedPromptChars: SUMMARIZATION_SYSTEM_PROMPT.length +
|
|
934
|
+
fixedPromptChars: SUMMARIZATION_SYSTEM_PROMPT.length + basePrompt.length + 128,
|
|
926
935
|
baseMaxTokens: Math.floor(0.5 * summaryBudgetTokens),
|
|
927
936
|
apiKey,
|
|
928
937
|
headers,
|
|
@@ -8,8 +8,7 @@ export function createFrameDecoder(maxBytes = 50 * 1024 * 1024) {
|
|
|
8
8
|
return function decode(chunk) {
|
|
9
9
|
const frames = [];
|
|
10
10
|
buf = Buffer.concat([buf, chunk]);
|
|
11
|
-
|
|
12
|
-
buf = Buffer.alloc(0);
|
|
11
|
+
let awaiting;
|
|
13
12
|
for (;;) {
|
|
14
13
|
const he = buf.indexOf("\r\n\r\n");
|
|
15
14
|
if (he === -1)
|
|
@@ -25,11 +24,15 @@ export function createFrameDecoder(maxBytes = 50 * 1024 * 1024) {
|
|
|
25
24
|
continue;
|
|
26
25
|
}
|
|
27
26
|
const start = he + 4;
|
|
28
|
-
if (buf.length < start + len)
|
|
27
|
+
if (buf.length < start + len) {
|
|
28
|
+
awaiting = start + len;
|
|
29
29
|
break;
|
|
30
|
+
}
|
|
30
31
|
frames.push(buf.subarray(start, start + len).toString("utf8"));
|
|
31
32
|
buf = buf.subarray(start + len);
|
|
32
33
|
}
|
|
34
|
+
if (buf.length > (awaiting ?? maxBytes + HEADER_SLACK))
|
|
35
|
+
buf = Buffer.alloc(0);
|
|
33
36
|
return frames;
|
|
34
37
|
};
|
|
35
38
|
}
|
|
@@ -29,6 +29,7 @@ export declare class NodeLspManager implements LspServerManager {
|
|
|
29
29
|
private readonly cache;
|
|
30
30
|
private readonly opening;
|
|
31
31
|
private readonly failed;
|
|
32
|
+
private readonly initFailures;
|
|
32
33
|
private disposed;
|
|
33
34
|
constructor(opts?: NodeLspManagerOptions);
|
|
34
35
|
private sweepIdle;
|
|
@@ -37,6 +38,7 @@ export declare class NodeLspManager implements LspServerManager {
|
|
|
37
38
|
private evictOverCap;
|
|
38
39
|
evict(root: string): Promise<void>;
|
|
39
40
|
clearFailed(root?: string): void;
|
|
41
|
+
unavailableReason(filePath: string, env?: ExecutionEnv): string | undefined;
|
|
40
42
|
private openSession;
|
|
41
43
|
private serverCmd;
|
|
42
44
|
dispose(): Promise<void>;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { killProcessTree } from "../execution-env/kill-tree.js";
|
|
3
|
-
import { readFile, stat } from "node:fs/promises";
|
|
3
|
+
import { open, readFile, stat } from "node:fs/promises";
|
|
4
4
|
import { basename, dirname, extname, resolve as resolvePath } from "node:path";
|
|
5
|
-
import { existsSync } from "node:fs";
|
|
5
|
+
import { constants as fsConstants, existsSync } from "node:fs";
|
|
6
6
|
import { pathToUri } from "../../core/lsp-protocol.js";
|
|
7
7
|
import { LspDiagnosticsRegistry } from "../../core/lsp-diagnostics.js";
|
|
8
8
|
import { TransportLspSession } from "../../core/lsp-session.js";
|
|
9
9
|
import { StdioLspTransport } from "./stdio-lsp-transport.js";
|
|
10
|
-
import { MAX_LSP_FILE_BYTES } from "../../core/lsp.js";
|
|
10
|
+
import { MAX_LSP_FILE_BYTES, SharedAbortScope, settleOnAbort } from "../../core/lsp.js";
|
|
11
11
|
export const DEFAULT_LSP_SERVERS = {
|
|
12
12
|
typescript: "typescript-language-server --stdio",
|
|
13
13
|
javascript: "typescript-language-server --stdio",
|
|
@@ -46,6 +46,7 @@ const CLIENT_CAPABILITIES = {
|
|
|
46
46
|
},
|
|
47
47
|
workspace: { symbol: {}, workspaceFolders: false },
|
|
48
48
|
};
|
|
49
|
+
const INIT_FAILURE_LATCH = 2;
|
|
49
50
|
export class NodeLspManager {
|
|
50
51
|
servers;
|
|
51
52
|
spawnFn;
|
|
@@ -60,6 +61,7 @@ export class NodeLspManager {
|
|
|
60
61
|
cache = new Map();
|
|
61
62
|
opening = new Map();
|
|
62
63
|
failed = new Map();
|
|
64
|
+
initFailures = new Map();
|
|
63
65
|
disposed = false;
|
|
64
66
|
constructor(opts = {}) {
|
|
65
67
|
this.servers = { ...DEFAULT_LSP_SERVERS, ...opts.servers };
|
|
@@ -79,6 +81,10 @@ export class NodeLspManager {
|
|
|
79
81
|
sweepIdle() {
|
|
80
82
|
const cutoff = Date.now() - this.idleTtlMs;
|
|
81
83
|
for (const [key, e] of [...this.cache]) {
|
|
84
|
+
if (e.session.inFlight > 0) {
|
|
85
|
+
e.lastUsed = Date.now();
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
82
88
|
if (e.lastUsed < cutoff) {
|
|
83
89
|
this.cache.delete(key);
|
|
84
90
|
this.log("lsp_evict_idle", { key });
|
|
@@ -106,19 +112,20 @@ export class NodeLspManager {
|
|
|
106
112
|
this.cache.delete(key);
|
|
107
113
|
const carry = cached.session.openedFiles();
|
|
108
114
|
this.log("lsp_heal", { language, root, carried: carry.length });
|
|
109
|
-
|
|
110
|
-
if (healed && carry.length)
|
|
111
|
-
await healed.warmOpen(carry, signal).catch(() => undefined);
|
|
112
|
-
return healed;
|
|
115
|
+
return this.open(key, language, root, signal, env, carry);
|
|
113
116
|
}
|
|
114
117
|
return this.open(key, language, root, signal, env);
|
|
115
118
|
}
|
|
116
|
-
open(key, language, root, signal, env) {
|
|
119
|
+
open(key, language, root, signal, env, carry = []) {
|
|
117
120
|
const inflight = this.opening.get(key);
|
|
118
|
-
if (inflight)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
if (inflight && !inflight.scope.signal.aborted) {
|
|
122
|
+
inflight.scope.join(signal);
|
|
123
|
+
return settleOnAbort(inflight.job, signal, () => undefined);
|
|
124
|
+
}
|
|
125
|
+
const scope = new SharedAbortScope();
|
|
126
|
+
scope.join(signal);
|
|
127
|
+
const entry = { root, cancelled: false, scope, job: undefined };
|
|
128
|
+
entry.job = this.openSession(language, root, scope.signal, env)
|
|
122
129
|
.then(async (session) => {
|
|
123
130
|
if (!session)
|
|
124
131
|
return undefined;
|
|
@@ -126,26 +133,41 @@ export class NodeLspManager {
|
|
|
126
133
|
await session.close().catch(() => undefined);
|
|
127
134
|
return undefined;
|
|
128
135
|
}
|
|
136
|
+
if (carry.length) {
|
|
137
|
+
const carried = await session.warmOpen(carry, scope.signal).catch(() => ({ opened: 0, failed: carry.length }));
|
|
138
|
+
this.log("lsp_heal_carried", { language, root, ...carried });
|
|
139
|
+
if (this.disposed || entry.cancelled) {
|
|
140
|
+
await session.close().catch(() => undefined);
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
129
144
|
this.evictOverCap();
|
|
130
145
|
this.cache.set(key, { session, root, lastUsed: Date.now() });
|
|
131
146
|
return session;
|
|
132
147
|
})
|
|
133
|
-
.finally(() =>
|
|
148
|
+
.finally(() => {
|
|
149
|
+
if (this.opening.get(key) === entry)
|
|
150
|
+
this.opening.delete(key);
|
|
151
|
+
});
|
|
134
152
|
this.opening.set(key, entry);
|
|
135
|
-
return entry.job;
|
|
153
|
+
return settleOnAbort(entry.job, signal, () => undefined);
|
|
136
154
|
}
|
|
137
155
|
evictOverCap() {
|
|
138
156
|
while (this.cache.size >= this.maxSessions) {
|
|
139
157
|
let lruKey;
|
|
140
158
|
let lruTime = Infinity;
|
|
141
159
|
for (const [k, e] of this.cache) {
|
|
160
|
+
if (e.session.inFlight > 0)
|
|
161
|
+
continue;
|
|
142
162
|
if (e.lastUsed < lruTime) {
|
|
143
163
|
lruTime = e.lastUsed;
|
|
144
164
|
lruKey = k;
|
|
145
165
|
}
|
|
146
166
|
}
|
|
147
|
-
if (lruKey === undefined)
|
|
167
|
+
if (lruKey === undefined) {
|
|
168
|
+
this.log("lsp_evict_deferred", { size: this.cache.size, maxSessions: this.maxSessions });
|
|
148
169
|
break;
|
|
170
|
+
}
|
|
149
171
|
const evicted = this.cache.get(lruKey);
|
|
150
172
|
this.cache.delete(lruKey);
|
|
151
173
|
this.log("lsp_evict_lru", { key: lruKey });
|
|
@@ -154,6 +176,7 @@ export class NodeLspManager {
|
|
|
154
176
|
}
|
|
155
177
|
async evict(root) {
|
|
156
178
|
const closing = [];
|
|
179
|
+
this.clearFailed(root);
|
|
157
180
|
for (const [key, e] of [...this.cache]) {
|
|
158
181
|
if (e.root === root) {
|
|
159
182
|
this.cache.delete(key);
|
|
@@ -174,8 +197,27 @@ export class NodeLspManager {
|
|
|
174
197
|
if (root !== undefined && e.root !== root)
|
|
175
198
|
continue;
|
|
176
199
|
this.failed.delete(key);
|
|
177
|
-
this.
|
|
200
|
+
this.initFailures.delete(key);
|
|
201
|
+
this.log("lsp_negative_cache_cleared", { key, attempts: e.attempts, kind: e.kind });
|
|
178
202
|
}
|
|
203
|
+
for (const [key, _n] of [...this.initFailures]) {
|
|
204
|
+
if (root === undefined || key.endsWith(` ${root}`))
|
|
205
|
+
this.initFailures.delete(key);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
unavailableReason(filePath, env) {
|
|
209
|
+
const language = languageFor(filePath);
|
|
210
|
+
if (!language)
|
|
211
|
+
return undefined;
|
|
212
|
+
const cmd = this.serverCmd(language);
|
|
213
|
+
if (!cmd)
|
|
214
|
+
return `no ${language} language server is configured in this environment`;
|
|
215
|
+
const e = this.failed.get(`${language} ${this.resolveRootFn(filePath, env)}`);
|
|
216
|
+
if (e?.kind === "missing_binary")
|
|
217
|
+
return `the ${language} language server ("${e.command}") is not installed on this host`;
|
|
218
|
+
if (e?.kind === "initialize")
|
|
219
|
+
return `the ${language} language server ("${e.command}") is installed but failed to initialize`;
|
|
220
|
+
return undefined;
|
|
179
221
|
}
|
|
180
222
|
async openSession(language, root, signal, _env) {
|
|
181
223
|
const cmd = this.serverCmd(language);
|
|
@@ -183,10 +225,18 @@ export class NodeLspManager {
|
|
|
183
225
|
return undefined;
|
|
184
226
|
const tokens = (cmd.match(/"[^"]*"|\S+/g) ?? []).map((t) => (t.startsWith('"') && t.endsWith('"') && t.length >= 2 ? t.slice(1, -1) : t));
|
|
185
227
|
const [command, ...args] = tokens.length > 0 ? tokens : [""];
|
|
186
|
-
const
|
|
228
|
+
const key = `${language} ${root}`;
|
|
229
|
+
let child;
|
|
230
|
+
try {
|
|
231
|
+
child = await this.spawnFn(command, args, root, signal);
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
this.log("lsp_spawn_error", { language, root, command, err: e instanceof Error ? e.message : String(e) });
|
|
235
|
+
return undefined;
|
|
236
|
+
}
|
|
187
237
|
if (!child) {
|
|
188
238
|
if (signal?.aborted !== true)
|
|
189
|
-
this.failed.set(
|
|
239
|
+
this.failed.set(key, { root, attempts: 1, kind: "missing_binary", command, language });
|
|
190
240
|
this.log("lsp_spawn_degraded", { language, root, command });
|
|
191
241
|
return undefined;
|
|
192
242
|
}
|
|
@@ -204,9 +254,18 @@ export class NodeLspManager {
|
|
|
204
254
|
}
|
|
205
255
|
catch (e) {
|
|
206
256
|
await transport.close();
|
|
207
|
-
|
|
257
|
+
const attempt = (this.initFailures.get(key) ?? 0) + 1;
|
|
258
|
+
const latched = attempt >= INIT_FAILURE_LATCH && signal?.aborted !== true;
|
|
259
|
+
if (latched) {
|
|
260
|
+
this.failed.set(key, { root, attempts: 1, kind: "initialize", command, language });
|
|
261
|
+
this.initFailures.delete(key);
|
|
262
|
+
}
|
|
263
|
+
else
|
|
264
|
+
this.initFailures.set(key, attempt);
|
|
265
|
+
this.log("lsp_init_degraded", { language, root, err: e instanceof Error ? e.message : String(e), attempt, latched });
|
|
208
266
|
return undefined;
|
|
209
267
|
}
|
|
268
|
+
this.initFailures.delete(key);
|
|
210
269
|
this.log("lsp_open", { language, root });
|
|
211
270
|
return new TransportLspSession(transport, language, this.readTextFn, this.log, this.warmup, this.diagnostics);
|
|
212
271
|
}
|
|
@@ -249,33 +308,51 @@ export const defaultLspReadText = async (fp, signal) => {
|
|
|
249
308
|
throw new Error(`not a regular file: ${fp}`);
|
|
250
309
|
if (st.size > MAX_LSP_FILE_BYTES)
|
|
251
310
|
throw new Error(`file too large for LSP analysis (${st.size} bytes exceeds ${MAX_LSP_FILE_BYTES})`);
|
|
252
|
-
|
|
311
|
+
const flags = fsConstants.O_RDONLY | (fsConstants.O_NONBLOCK ?? 0);
|
|
312
|
+
const fh = await open(fp, flags);
|
|
313
|
+
try {
|
|
314
|
+
const fst = await fh.stat();
|
|
315
|
+
if (!fst.isFile())
|
|
316
|
+
throw new Error(`not a regular file: ${fp}`);
|
|
317
|
+
if (fst.size > MAX_LSP_FILE_BYTES)
|
|
318
|
+
throw new Error(`file too large for LSP analysis (${fst.size} bytes exceeds ${MAX_LSP_FILE_BYTES})`);
|
|
319
|
+
return await readFile(fh, { encoding: "utf8", signal });
|
|
320
|
+
}
|
|
321
|
+
finally {
|
|
322
|
+
await fh.close().catch(() => undefined);
|
|
323
|
+
}
|
|
253
324
|
};
|
|
254
325
|
export function lspSpawnOptions(cwd) {
|
|
255
326
|
return process.platform === "win32"
|
|
256
327
|
? { cwd, stdio: ["pipe", "pipe", "ignore"], shell: true }
|
|
257
328
|
: { cwd, stdio: ["pipe", "pipe", "ignore"] };
|
|
258
329
|
}
|
|
259
|
-
export const defaultLspSpawn = (command, args, cwd, signal) => new Promise((resolve) => {
|
|
330
|
+
export const defaultLspSpawn = (command, args, cwd, signal) => new Promise((resolve, reject) => {
|
|
260
331
|
let child;
|
|
261
332
|
try {
|
|
262
333
|
child = spawn(command, args, lspSpawnOptions(cwd));
|
|
263
334
|
}
|
|
264
|
-
catch {
|
|
265
|
-
return
|
|
335
|
+
catch (e) {
|
|
336
|
+
return reject(e instanceof Error ? e : new Error(String(e)));
|
|
266
337
|
}
|
|
338
|
+
child.on("error", () => { });
|
|
267
339
|
const onSpawn = () => {
|
|
268
340
|
cleanup();
|
|
269
341
|
resolve(child);
|
|
270
342
|
};
|
|
271
|
-
const onError = () => {
|
|
343
|
+
const onError = (err) => {
|
|
272
344
|
cleanup();
|
|
273
|
-
|
|
345
|
+
if (err?.code === "ENOENT")
|
|
346
|
+
resolve(undefined);
|
|
347
|
+
else
|
|
348
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
274
349
|
};
|
|
275
350
|
const onAbort = () => {
|
|
276
351
|
cleanup();
|
|
277
352
|
try {
|
|
278
|
-
if (
|
|
353
|
+
if (child.pid === undefined)
|
|
354
|
+
return resolve(undefined);
|
|
355
|
+
if (process.platform === "win32")
|
|
279
356
|
killProcessTree(child.pid, { force: true });
|
|
280
357
|
else
|
|
281
358
|
child.kill();
|
|
@@ -16,7 +16,17 @@ export class StdioLspTransport {
|
|
|
16
16
|
for (const frame of this.decode(chunk))
|
|
17
17
|
this.onMessage(frame);
|
|
18
18
|
});
|
|
19
|
-
child.stdin.on("error", () =>
|
|
19
|
+
child.stdin.on("error", (e) => this.failAll(toError(e)));
|
|
20
|
+
const stdout = child.stdout;
|
|
21
|
+
if (typeof stdout.removeListener === "function" && typeof stdout.once === "function") {
|
|
22
|
+
for (const event of ["end", "close", "error"]) {
|
|
23
|
+
stdout.on(event, (arg) => {
|
|
24
|
+
if (Buffer.isBuffer(arg))
|
|
25
|
+
return;
|
|
26
|
+
this.failAll(new Error(`LSP server stdout ${event}`));
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
20
30
|
child.on("exit", () => this.failAll(new Error("LSP server exited")));
|
|
21
31
|
child.on("error", (e) => this.failAll(toError(e)));
|
|
22
32
|
}
|
|
@@ -36,7 +46,8 @@ export class StdioLspTransport {
|
|
|
36
46
|
try {
|
|
37
47
|
this.send({ jsonrpc: "2.0", id: msg.id, error: { code: -32601, message: `Method not found: ${String(msg.method)}` } });
|
|
38
48
|
}
|
|
39
|
-
catch {
|
|
49
|
+
catch (e) {
|
|
50
|
+
this.failAll(toError(e));
|
|
40
51
|
}
|
|
41
52
|
}
|
|
42
53
|
return;
|
|
@@ -121,10 +132,7 @@ export class StdioLspTransport {
|
|
|
121
132
|
this.send({ jsonrpc: "2.0", id, method, params });
|
|
122
133
|
}
|
|
123
134
|
catch (e) {
|
|
124
|
-
|
|
125
|
-
cleanup();
|
|
126
|
-
reject(brandLspFailure(e instanceof Error ? e : new Error(String(e)), "server_terminated"));
|
|
127
|
-
}
|
|
135
|
+
this.failAll(brandLspFailure(e instanceof Error ? e : new Error(String(e)), "server_terminated"));
|
|
128
136
|
}
|
|
129
137
|
});
|
|
130
138
|
}
|
|
@@ -134,7 +142,8 @@ export class StdioLspTransport {
|
|
|
134
142
|
try {
|
|
135
143
|
this.send({ jsonrpc: "2.0", method, params });
|
|
136
144
|
}
|
|
137
|
-
catch {
|
|
145
|
+
catch (e) {
|
|
146
|
+
this.failAll(toError(e));
|
|
138
147
|
}
|
|
139
148
|
}
|
|
140
149
|
async close() {
|
package/dist/index.d.ts
CHANGED
|
@@ -188,7 +188,7 @@ export { createDegradingBrain, readDegradation, DEGRADED_DIAGNOSTIC_TYPE, type D
|
|
|
188
188
|
export { retryBackoffMs, parseRetryAfter } from "./brain/retry.js";
|
|
189
189
|
export { type BrainTimeoutConfig } from "./brain/timeout.js";
|
|
190
190
|
export { createAssistantMessageEventStream } from "./internal/llm.js";
|
|
191
|
-
export type { AssistantMessage, AssistantMessageEvent, Context, DocumentContent, ImageContent, Message, StopReason, StreamFn, TextContent, ThinkingContent, ToolCall, ToolResultMessage, Usage, UserMessage, } from "./internal/llm.js";
|
|
191
|
+
export type { AssistantMessage, AssistantMessageEvent, CompleteSimpleFn, Context, DocumentContent, ImageContent, Message, StopReason, StreamFn, TextContent, ThinkingContent, ToolCall, ToolResultMessage, Usage, UserMessage, } from "./internal/llm.js";
|
|
192
192
|
export type { AgentDefinition, BeforeWriteHook, BeforeWriteRequest, BeforeWriteResult, HandsBandOptions, Brain, BrainStatus, BrainStatusPhase, ImageInput, McpElicitRequest, McpElicitResponse, McpServerSpec, OnElicit, Model, ModelRef, ProjectMemoryLoad, RunnerDeps, RuntimeCaps, BackgroundChildEvent, SkillManifest, SkillSpec, TaskEvent, TaskEventIdentity, ToolActivity, TaskResult, RemoteEnvFailureNote, TaskSpec, TaskStatus, TaskStream, CompactOutcome, ThinkingLevel, ToolExecuteContext, ToolReturn, ToolSpec, ToolEffect, WorkflowGovernanceBaseline, } from "./core/types.js";
|
|
193
193
|
export { Type } from "typebox";
|
|
194
194
|
export type { TSchema, Static } from "typebox";
|
|
@@ -2,7 +2,7 @@ export * from "./harness-types.js";
|
|
|
2
2
|
export { AgentHarness } from "../engine/harness/agent-harness.js";
|
|
3
3
|
export { CompactionError, ExecutionError, FileError, ok, err } from "../engine/harness/types.js";
|
|
4
4
|
export { DEFAULT_CHARS_PER_TOKEN, DEFAULT_CLAMP_TOLERANCE, DEFAULT_COMPACTION_SETTINGS, compact, computeFileLists, dryRunSummarizationClamp, estimateContextTokens, estimateTokens, prepareCompaction, shouldCompact, summaryOutputBudgetTokens, } from "../engine/compaction/compaction.js";
|
|
5
|
-
export { SKILL_RETENTION_PER_SKILL_MAX_CHARS, SKILL_RETENTION_TOTAL_MAX_CHARS, SKILL_RETENTION_TRUNCATION_MARKER, formatPersistedOutputRefs, readCompactionActiveTools, readRetainedInvokedSkills, renderInvokedSkillsRetention, } from "../engine/compaction/utils.js";
|
|
5
|
+
export { SKILL_RETENTION_PER_SKILL_MAX_CHARS, SKILL_RETENTION_TOTAL_MAX_CHARS, SKILL_RETENTION_TRUNCATION_MARKER, formatFileOperations, formatPersistedOutputRefs, readCompactionActiveTools, readRetainedInvokedSkills, renderInvokedSkillsRetention, } from "../engine/compaction/utils.js";
|
|
6
6
|
export { NodeExecutionEnv } from "../engine/execution-env/node-execution-env.js";
|
|
7
7
|
export { StoredSession, buildSessionContext } from "../engine/session/session.js";
|
|
8
8
|
export { getEntriesToFork } from "../engine/session/repo-utils.js";
|
package/dist/internal/harness.js
CHANGED
|
@@ -2,7 +2,7 @@ export * from "./harness-types.js";
|
|
|
2
2
|
export { AgentHarness } from "../engine/harness/agent-harness.js";
|
|
3
3
|
export { CompactionError, ExecutionError, FileError, ok, err } from "../engine/harness/types.js";
|
|
4
4
|
export { DEFAULT_CHARS_PER_TOKEN, DEFAULT_CLAMP_TOLERANCE, DEFAULT_COMPACTION_SETTINGS, compact, computeFileLists, dryRunSummarizationClamp, estimateContextTokens, estimateTokens, prepareCompaction, shouldCompact, summaryOutputBudgetTokens, } from "../engine/compaction/compaction.js";
|
|
5
|
-
export { SKILL_RETENTION_PER_SKILL_MAX_CHARS, SKILL_RETENTION_TOTAL_MAX_CHARS, SKILL_RETENTION_TRUNCATION_MARKER, formatPersistedOutputRefs, readCompactionActiveTools, readRetainedInvokedSkills, renderInvokedSkillsRetention, } from "../engine/compaction/utils.js";
|
|
5
|
+
export { SKILL_RETENTION_PER_SKILL_MAX_CHARS, SKILL_RETENTION_TOTAL_MAX_CHARS, SKILL_RETENTION_TRUNCATION_MARKER, formatFileOperations, formatPersistedOutputRefs, readCompactionActiveTools, readRetainedInvokedSkills, renderInvokedSkillsRetention, } from "../engine/compaction/utils.js";
|
|
6
6
|
export { NodeExecutionEnv } from "../engine/execution-env/node-execution-env.js";
|
|
7
7
|
export { StoredSession, buildSessionContext } from "../engine/session/session.js";
|
|
8
8
|
export { getEntriesToFork } from "../engine/session/repo-utils.js";
|