@sema-agent/core 1.452.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/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 +22 -834
- 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/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 +1 -0
- package/dist/core/exec-output-tail.js +6 -0
- 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.d.ts +1 -1
- 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 +19 -207
- 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-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-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 +51 -216
- package/dist/core/task-registry.js +127 -1940
- 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 +1 -1
- package/dist/core/tools.d.ts +2 -3
- package/dist/core/tools.js +0 -8
- package/dist/core/trace.d.ts +2 -2
- package/dist/core/types.d.ts +0 -29
- 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 +13 -0
- package/dist/engine/execution-env/node-execution-env.js +55 -25
- 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 +1 -1
- package/dist/engine/lsp/stdio-lsp-transport.js +2 -2
- package/dist/index.d.ts +16 -14
- package/dist/index.js +13 -11
- 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 +1 -1
- package/dist/orchestration/workflow-types.d.ts +193 -0
- package/dist/orchestration/workflow-types.js +54 -0
- package/dist/orchestration/workflow.d.ts +3 -193
- package/dist/orchestration/workflow.js +7 -59
- 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/file/background-agent-store.d.ts +2 -15
- package/dist/stores/file/background-agent-store.js +30 -100
- 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/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/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 -2090
- 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 +1 -1
- package/dist/tools/fs/safety.d.ts +1 -1
- package/dist/tools/fs/search.d.ts +1 -1
- package/dist/tools/monitor.d.ts +1 -1
- package/dist/tools/scheduler-tools.d.ts +1 -1
- package/dist/tools/web.d.ts +2 -2
- package/dist/tools/web.js +1 -1
- package/dist/tools/worktree.d.ts +1 -1
- 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,32 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
export declare const TASK_OUTPUT_TOOL_NAME = "TaskOutput";
|
|
3
|
+
export declare const TASK_STOP_TOOL_NAME = "TaskStop";
|
|
4
|
+
export declare const TASK_OUTPUT_ALIASES: readonly ["BashOutput", "AgentOutputTool", "BashOutputTool", "AgentOutput", "WorkflowStatus"];
|
|
5
|
+
export declare const TASK_STOP_ALIASES: readonly ["KillShell", "KillBash"];
|
|
6
|
+
export declare const TASK_OUTPUT_CONTRACT: {
|
|
7
|
+
readonly contractId: "core.task_output@1";
|
|
8
|
+
readonly implementationRevision: "1";
|
|
9
|
+
};
|
|
10
|
+
export declare const TASK_STOP_CONTRACT: {
|
|
11
|
+
readonly contractId: "core.task_stop@1";
|
|
12
|
+
readonly implementationRevision: "1";
|
|
13
|
+
};
|
|
14
|
+
export declare const TASK_OUTPUT_MISSING_ID_MESSAGE = "Error (TaskOutput): Missing required parameter: task_id";
|
|
15
|
+
export declare const TASK_STOP_MISSING_ID_MESSAGE = "Missing required parameter: task_id";
|
|
16
|
+
export declare const TASK_STOP_PARAMS: Type.TObject<{
|
|
17
|
+
task_id: Type.TOptional<Type.TString>;
|
|
18
|
+
shell_id: Type.TOptional<Type.TString>;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function resolveTaskIdArg(...values: unknown[]): string | undefined;
|
|
21
|
+
export interface TaskToolCapabilities {
|
|
22
|
+
lanes: boolean;
|
|
23
|
+
outputFile: boolean;
|
|
24
|
+
notification: boolean;
|
|
25
|
+
blockWait: boolean;
|
|
26
|
+
nameAddressing: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare const REGISTRY_TASK_TOOL_CAPS: TaskToolCapabilities;
|
|
29
|
+
export declare const ENV_DIRECT_TASK_TOOL_CAPS: TaskToolCapabilities;
|
|
30
|
+
export declare function composeTaskOutputDescription(caps: TaskToolCapabilities): string;
|
|
31
|
+
export declare function composeTaskStopDescription(caps: TaskToolCapabilities): string;
|
|
32
|
+
export declare function composeTaskOutputParams(caps: Pick<TaskToolCapabilities, "blockWait" | "lanes">): ReturnType<typeof Type.Object>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
export const TASK_OUTPUT_TOOL_NAME = "TaskOutput";
|
|
3
|
+
export const TASK_STOP_TOOL_NAME = "TaskStop";
|
|
4
|
+
export const TASK_OUTPUT_ALIASES = ["BashOutput", "AgentOutputTool", "BashOutputTool", "AgentOutput", "WorkflowStatus"];
|
|
5
|
+
export const TASK_STOP_ALIASES = ["KillShell", "KillBash"];
|
|
6
|
+
export const TASK_OUTPUT_CONTRACT = { contractId: "core.task_output@1", implementationRevision: "1" };
|
|
7
|
+
export const TASK_STOP_CONTRACT = { contractId: "core.task_stop@1", implementationRevision: "1" };
|
|
8
|
+
export const TASK_OUTPUT_MISSING_ID_MESSAGE = "Error (TaskOutput): Missing required parameter: task_id";
|
|
9
|
+
export const TASK_STOP_MISSING_ID_MESSAGE = "Missing required parameter: task_id";
|
|
10
|
+
export const TASK_STOP_PARAMS = Type.Object({
|
|
11
|
+
task_id: Type.Optional(Type.String({ description: "The ID of the background task to stop" })),
|
|
12
|
+
shell_id: Type.Optional(Type.String({ description: "Deprecated: use task_id instead" })),
|
|
13
|
+
});
|
|
14
|
+
export function resolveTaskIdArg(...values) {
|
|
15
|
+
for (const value of values) {
|
|
16
|
+
if (typeof value === "string" && value.trim() !== "")
|
|
17
|
+
return value.trim();
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
export const REGISTRY_TASK_TOOL_CAPS = {
|
|
22
|
+
lanes: true,
|
|
23
|
+
outputFile: true,
|
|
24
|
+
notification: true,
|
|
25
|
+
blockWait: true,
|
|
26
|
+
nameAddressing: true,
|
|
27
|
+
};
|
|
28
|
+
export const ENV_DIRECT_TASK_TOOL_CAPS = {
|
|
29
|
+
lanes: false,
|
|
30
|
+
outputFile: false,
|
|
31
|
+
notification: false,
|
|
32
|
+
blockWait: false,
|
|
33
|
+
nameAddressing: false,
|
|
34
|
+
};
|
|
35
|
+
export function composeTaskOutputDescription(caps) {
|
|
36
|
+
const parts = [];
|
|
37
|
+
if (caps.outputFile) {
|
|
38
|
+
parts.push("[Deprecated] — for background Bash tasks, prefer Read on the output file path; for agent tasks, use the Agent tool result directly. " +
|
|
39
|
+
"DEPRECATED: Background tasks return their output file path in the tool result" +
|
|
40
|
+
(caps.notification ? ", and you receive a <task-notification> with the same path when the task completes. " : ". "));
|
|
41
|
+
}
|
|
42
|
+
parts.push("Retrieve output or status for a background task by task_id. ");
|
|
43
|
+
parts.push(caps.lanes
|
|
44
|
+
? "Supports background Bash tasks and workflow tasks returned by RunWorkflow. Returns only the caller's own task scope; unknown and out-of-scope ids are " +
|
|
45
|
+
"reported the same way. "
|
|
46
|
+
: "Reads a background shell started with Bash(run_in_background): returns the run status (running / exited(code) / killed / failed) plus NEW stdout/stderr since your last call. ");
|
|
47
|
+
if (!caps.notification) {
|
|
48
|
+
parts.push('When using a background command as a wait condition, call this repeatedly until status is no longer "running" — completion ' +
|
|
49
|
+
"is signalled by status/exitCode, not by any automatic notification; after you see a terminal status, one more " +
|
|
50
|
+
"poll captures any final output. ");
|
|
51
|
+
}
|
|
52
|
+
if (!caps.lanes)
|
|
53
|
+
parts.push("Optional `filter` is a regex keeping only matching lines. ");
|
|
54
|
+
parts.push("Legacy bash_id and runId arguments are accepted for compatibility.");
|
|
55
|
+
return parts.join("");
|
|
56
|
+
}
|
|
57
|
+
export function composeTaskStopDescription(caps) {
|
|
58
|
+
return [
|
|
59
|
+
"- Stops a running background task by its ID",
|
|
60
|
+
"- Takes a task_id parameter identifying the task to stop",
|
|
61
|
+
...(caps.nameAddressing ? ["- To stop a background agent spawned with a name, pass that name as task_id"] : []),
|
|
62
|
+
"- Returns a success or failure status",
|
|
63
|
+
"- Use this tool when you need to terminate a long-running task",
|
|
64
|
+
].join("\n");
|
|
65
|
+
}
|
|
66
|
+
export function composeTaskOutputParams(caps) {
|
|
67
|
+
return Type.Object({
|
|
68
|
+
task_id: Type.Optional(Type.String({
|
|
69
|
+
description: caps.lanes
|
|
70
|
+
? "The task_id returned by Bash(run_in_background) or RunWorkflow."
|
|
71
|
+
: "The task_id returned by Bash(run_in_background).",
|
|
72
|
+
})),
|
|
73
|
+
...(caps.blockWait
|
|
74
|
+
? {
|
|
75
|
+
block: Type.Optional(Type.Boolean({
|
|
76
|
+
description: "Whether to wait for completion (default true — the call waits until the task finishes or `timeout`, saving re-poll turns). Pass false for an instantaneous snapshot.",
|
|
77
|
+
})),
|
|
78
|
+
timeout: Type.Optional(Type.Number({ description: "Optional timeout in milliseconds when block is true (default 30000, max 600000)." })),
|
|
79
|
+
}
|
|
80
|
+
: {}),
|
|
81
|
+
filter: Type.Optional(Type.String({ description: "Optional regex filter for background Bash output (sema extension)." })),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -29,10 +29,9 @@ export type PermissionResult = {
|
|
|
29
29
|
reason?: string;
|
|
30
30
|
decisionReason?: DecisionReason;
|
|
31
31
|
};
|
|
32
|
-
export type ToolDecision = PermissionResult;
|
|
33
32
|
export declare function decisionText(d: PermissionResult): string | undefined;
|
|
34
33
|
export interface ToolPolicy {
|
|
35
|
-
check(req: ToolCallRequest, signal?: AbortSignal):
|
|
34
|
+
check(req: ToolCallRequest, signal?: AbortSignal): PermissionResult | Promise<PermissionResult>;
|
|
36
35
|
}
|
|
37
36
|
export interface ToolPolicyNameSets {
|
|
38
37
|
readonly allow?: readonly string[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentMessage } from "../internal/harness.js";
|
|
1
|
+
import type { AgentMessage } from "../internal/harness-types.js";
|
|
2
2
|
import { type ToolResultStore } from "./tool-result-store.js";
|
|
3
3
|
export declare const AGGREGATE_TOOL_RESULT_BUDGET_CHARS = 200000;
|
|
4
4
|
export interface AggregateBudgetOptions {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentTool } from "../internal/harness.js";
|
|
1
|
+
import type { AgentTool } from "../internal/harness-types.js";
|
|
2
2
|
export interface ToolResultStore {
|
|
3
3
|
put(ref: string, content: string): Promise<void> | void;
|
|
4
4
|
get(ref: string, opts?: {
|
|
@@ -54,4 +54,4 @@ export declare function buildPreview(full: string, ref: string, sizes?: {
|
|
|
54
54
|
tail: number;
|
|
55
55
|
}): string;
|
|
56
56
|
export declare function withToolResultOffload(tool: AgentTool, store: ToolResultStore, thresholdChars: number, sessionId: string): AgentTool;
|
|
57
|
-
export declare function
|
|
57
|
+
export declare function createReadToolResultTool(store: ToolResultStore): AgentTool;
|
|
@@ -128,7 +128,7 @@ export function withToolResultOffload(tool, store, thresholdChars, sessionId) {
|
|
|
128
128
|
};
|
|
129
129
|
return { ...tool, execute: wrappedExecute };
|
|
130
130
|
}
|
|
131
|
-
export function
|
|
131
|
+
export function createReadToolResultTool(store) {
|
|
132
132
|
return defineTool({
|
|
133
133
|
name: OFFLOAD_TOOL_NAME,
|
|
134
134
|
contract: { contractId: "core.read_tool_result@1", implementationRevision: "1" },
|
package/dist/core/tools.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { TSchema } from "typebox";
|
|
2
|
-
import type { AgentTool
|
|
3
|
-
import type {
|
|
2
|
+
import type { AgentTool } from "../internal/harness.js";
|
|
3
|
+
import type { ToolSpec } from "./types.js";
|
|
4
4
|
export declare function errorResult(text: string, details?: unknown): {
|
|
5
5
|
content: string;
|
|
6
6
|
isError: true;
|
|
7
7
|
details?: unknown;
|
|
8
8
|
};
|
|
9
9
|
export declare function defineTool<TParams extends TSchema = TSchema>(spec: ToolSpec<TParams>): AgentTool<TParams>;
|
|
10
|
-
export declare function toSkill(spec: SkillSpec): Skill;
|
package/dist/core/tools.js
CHANGED
package/dist/core/trace.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TaskStatus, ToolEffect } from "./types.js";
|
|
2
|
-
import type { ThinkingLevel } from "../internal/harness.js";
|
|
2
|
+
import type { ThinkingLevel } from "../internal/harness-types.js";
|
|
3
3
|
export interface TraceMechanismsSummary {
|
|
4
4
|
finalizeInjected?: true;
|
|
5
5
|
nudgesSent?: number;
|
|
@@ -26,7 +26,7 @@ export type TraceEvent = {
|
|
|
26
26
|
kind: "prompt.assembled";
|
|
27
27
|
version: 1;
|
|
28
28
|
taskId: string;
|
|
29
|
-
constitution: "core" | "replaced" | "provider-assembled"
|
|
29
|
+
constitution: "core" | "replaced" | "provider-assembled";
|
|
30
30
|
blocks: Array<{
|
|
31
31
|
id: string;
|
|
32
32
|
chars: number;
|
package/dist/core/types.d.ts
CHANGED
|
@@ -87,7 +87,6 @@ export interface ToolExecuteContext {
|
|
|
87
87
|
tokens: number;
|
|
88
88
|
turns: number;
|
|
89
89
|
tasks: number;
|
|
90
|
-
costUsd?: number;
|
|
91
90
|
costMicroUsd?: number;
|
|
92
91
|
}) => void;
|
|
93
92
|
model?: Model;
|
|
@@ -247,7 +246,6 @@ export interface TaskSpec {
|
|
|
247
246
|
appendSystemPrompt?: string;
|
|
248
247
|
promptProvider?: import("../prompts/default.js").PromptProvider;
|
|
249
248
|
memory?: import("./memory.js").MemorySpecInput;
|
|
250
|
-
memoryConsolidation?: MemoryConsolidationConfig;
|
|
251
249
|
suggestNextPrompts?: boolean | {
|
|
252
250
|
count?: number;
|
|
253
251
|
role?: ModelRole;
|
|
@@ -398,12 +396,10 @@ export interface TaskResult {
|
|
|
398
396
|
outputTokens?: number;
|
|
399
397
|
cacheWriteTokensLong?: number;
|
|
400
398
|
costMicroUsd?: number;
|
|
401
|
-
costUsd?: number;
|
|
402
399
|
nested?: {
|
|
403
400
|
tokens: number;
|
|
404
401
|
turns: number;
|
|
405
402
|
tasks: number;
|
|
406
|
-
costUsd?: number;
|
|
407
403
|
costMicroUsd?: number;
|
|
408
404
|
};
|
|
409
405
|
memory?: {
|
|
@@ -596,7 +592,6 @@ export type TaskEvent = ({
|
|
|
596
592
|
export type CompactOutcome = "compacted" | "failed" | "mooted" | "noop" | "blocked" | "disabled";
|
|
597
593
|
export interface TaskStream extends AsyncIterable<TaskEvent> {
|
|
598
594
|
result(): Promise<TaskResult>;
|
|
599
|
-
consolidation(): Promise<void>;
|
|
600
595
|
suggestions(): Promise<string[]>;
|
|
601
596
|
steer(text: string, options?: {
|
|
602
597
|
trusted?: boolean;
|
|
@@ -612,17 +607,6 @@ export interface TaskStream extends AsyncIterable<TaskEvent> {
|
|
|
612
607
|
interrupt(): Promise<void>;
|
|
613
608
|
destroy(): Promise<void>;
|
|
614
609
|
}
|
|
615
|
-
export interface MemoryConsolidationConfig {
|
|
616
|
-
enabled: boolean;
|
|
617
|
-
role?: ModelRole;
|
|
618
|
-
band?: {
|
|
619
|
-
lo: number;
|
|
620
|
-
hi: number;
|
|
621
|
-
};
|
|
622
|
-
searchLimit?: number;
|
|
623
|
-
maxNotesPerTask?: number;
|
|
624
|
-
timeoutSec?: number;
|
|
625
|
-
}
|
|
626
610
|
export interface WorkflowGovernanceBaseline {
|
|
627
611
|
base: Partial<TaskSpec>;
|
|
628
612
|
worktreeBase?: Partial<TaskSpec>;
|
|
@@ -729,7 +713,6 @@ export interface RunnerDeps {
|
|
|
729
713
|
onWorkflowAgentSpawn?: (handle: import("../orchestration/workflow.js").WorkflowAgentHandle) => void;
|
|
730
714
|
maxSuspends?: number;
|
|
731
715
|
now?: () => number;
|
|
732
|
-
memoryStore?: import("./memory.js").MemoryStore;
|
|
733
716
|
memoryBackend?: import("./memory-engine/types.js").MemoryBackend;
|
|
734
717
|
memoryEngineDir?: string;
|
|
735
718
|
onMemoryHarvestReport?: (report: import("./memory-engine/types.js").HarvestReport, info: {
|
|
@@ -751,17 +734,6 @@ export interface RunnerDeps {
|
|
|
751
734
|
path: string;
|
|
752
735
|
contentHash: string | null;
|
|
753
736
|
}> | null>;
|
|
754
|
-
utilityGate?: import("./memory.js").UtilityGate;
|
|
755
|
-
memoryConsolidation?: MemoryConsolidationConfig;
|
|
756
|
-
memoryRecall?: {
|
|
757
|
-
enabled?: boolean;
|
|
758
|
-
thresholdBytes?: number;
|
|
759
|
-
select?: import("./memory-recall.js").MemorySelector;
|
|
760
|
-
selectorModel?: ModelRef;
|
|
761
|
-
maxSelected?: number;
|
|
762
|
-
maxLinked?: number;
|
|
763
|
-
timeoutMs?: number;
|
|
764
|
-
};
|
|
765
737
|
promptProvider?: import("../prompts/default.js").PromptProvider;
|
|
766
738
|
onElicit?: OnElicit;
|
|
767
739
|
mcpImageResizer?: import("./mcp.js").McpImageResizer;
|
|
@@ -797,6 +769,5 @@ export interface RunnerDeps {
|
|
|
797
769
|
summaryProvider?: import("./auto-compaction.js").MaybeCompactOptions["summaryProvider"];
|
|
798
770
|
onCompaction?: import("./auto-compaction.js").MaybeCompactOptions["onCompaction"];
|
|
799
771
|
maxConsecutiveProviderReuse?: number;
|
|
800
|
-
dynamicRecall?: import("./dynamic-recall.js").DynamicRecallConfig;
|
|
801
772
|
}
|
|
802
773
|
export type { AgentTool, Model, StreamFn, ThinkingLevel };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type WorkflowRunStore } from "./workflow-run-store.js";
|
|
2
2
|
import type { WorkflowRun, WorkflowRunStatus } from "../orchestration/workflow.js";
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function createWorkflowRun(over?: Partial<WorkflowRun>): WorkflowRun;
|
|
4
4
|
export declare function workflowRunStoreContract(make: () => WorkflowRunStore, runAssertion?: (name: string, fn: () => Promise<void>) => void): Promise<void>;
|
|
5
5
|
export type { WorkflowRunStatus };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { strict as assert } from "node:assert";
|
|
2
2
|
import { summarizeWorkflowRun } from "./workflow-run-store.js";
|
|
3
|
-
export function
|
|
3
|
+
export function createWorkflowRun(over = {}) {
|
|
4
4
|
const createdAt = over.createdAt ?? 1_000;
|
|
5
5
|
return {
|
|
6
6
|
id: over.id ?? "run-1",
|
|
@@ -27,13 +27,13 @@ export async function workflowRunStoreContract(make, runAssertion = defaultSeque
|
|
|
27
27
|
};
|
|
28
28
|
run("put create-once → already_exists", async () => {
|
|
29
29
|
const store = make();
|
|
30
|
-
const r =
|
|
30
|
+
const r = createWorkflowRun();
|
|
31
31
|
await store.put(r.id, r);
|
|
32
32
|
await assert.rejects(store.put(r.id, r), (e) => e.code === "workflow_run.already_exists");
|
|
33
33
|
});
|
|
34
34
|
run("get returns a deep copy (mutating the result must not corrupt the store)", async () => {
|
|
35
35
|
const store = make();
|
|
36
|
-
const r =
|
|
36
|
+
const r = createWorkflowRun();
|
|
37
37
|
await store.put(r.id, r);
|
|
38
38
|
const got = await store.get(r.id);
|
|
39
39
|
assert.ok(got);
|
|
@@ -44,7 +44,7 @@ export async function workflowRunStoreContract(make, runAssertion = defaultSeque
|
|
|
44
44
|
});
|
|
45
45
|
run("update CAS: bumps rev, scope-mismatch loses, stale-rev loses, current-rev wins", async () => {
|
|
46
46
|
const store = make();
|
|
47
|
-
const r =
|
|
47
|
+
const r = createWorkflowRun({ status: "running" });
|
|
48
48
|
await store.put(r.id, r);
|
|
49
49
|
assert.equal(await store.update(r.id, r.scope, { ...r, status: "running", stats: { ...r.stats, tokens: 200 } }), true);
|
|
50
50
|
assert.equal((await store.get(r.id)).rev, 1);
|
|
@@ -54,11 +54,11 @@ export async function workflowRunStoreContract(make, runAssertion = defaultSeque
|
|
|
54
54
|
assert.equal(await store.update(r.id, r.scope, { ...r, status: "completed" }, { rev: 1 }), true);
|
|
55
55
|
assert.equal((await store.get(r.id)).rev, 2);
|
|
56
56
|
assert.equal((await store.get(r.id)).status, "completed");
|
|
57
|
-
assert.equal(await store.update("ghost", r.scope,
|
|
57
|
+
assert.equal(await store.update("ghost", r.scope, createWorkflowRun({ id: "ghost" })), false);
|
|
58
58
|
});
|
|
59
59
|
run("the key id is authoritative — a payload with a mismatched id never poisons the projection (codex BUG4)", async () => {
|
|
60
60
|
const store = make();
|
|
61
|
-
const r =
|
|
61
|
+
const r = createWorkflowRun({ id: "real", status: "running" });
|
|
62
62
|
await store.put("real", { ...r, id: "spoofed" });
|
|
63
63
|
assert.equal((await store.get("real")).id, "real");
|
|
64
64
|
assert.equal(await store.get("spoofed"), null);
|
|
@@ -70,10 +70,10 @@ export async function workflowRunStoreContract(make, runAssertion = defaultSeque
|
|
|
70
70
|
run("listByScope: history included (completed + failed + running), createdAt DESC, status filter + limit", async () => {
|
|
71
71
|
const store = make();
|
|
72
72
|
assert.deepEqual(await store.listByScope("tenant-a"), []);
|
|
73
|
-
const running =
|
|
74
|
-
const done =
|
|
75
|
-
const failed =
|
|
76
|
-
const other =
|
|
73
|
+
const running = createWorkflowRun({ id: "r-run", status: "running", createdAt: 3_000, endedAt: undefined });
|
|
74
|
+
const done = createWorkflowRun({ id: "r-done", status: "completed", createdAt: 2_000 });
|
|
75
|
+
const failed = createWorkflowRun({ id: "r-fail", status: "failed", createdAt: 1_000 });
|
|
76
|
+
const other = createWorkflowRun({ id: "r-other", scope: "tenant-b", createdAt: 9_000 });
|
|
77
77
|
for (const r of [running, done, failed, other])
|
|
78
78
|
await store.put(r.id, r);
|
|
79
79
|
const all = await store.listByScope("tenant-a");
|
|
@@ -88,7 +88,7 @@ export async function workflowRunStoreContract(make, runAssertion = defaultSeque
|
|
|
88
88
|
assert.equal(doneSummary.currentPhase, "build");
|
|
89
89
|
assert.equal(doneSummary.name, undefined);
|
|
90
90
|
assert.equal(doneSummary.description, undefined);
|
|
91
|
-
const named =
|
|
91
|
+
const named = createWorkflowRun({
|
|
92
92
|
id: "r-named", name: "find-flaky", description: "find flaky tests", createdAt: 4_000,
|
|
93
93
|
phases: [
|
|
94
94
|
{ title: "scan", status: "completed", startedAt: 4_000, endedAt: 4_001 },
|
|
@@ -103,10 +103,10 @@ export async function workflowRunStoreContract(make, runAssertion = defaultSeque
|
|
|
103
103
|
});
|
|
104
104
|
run("reap: only terminal runs, NEVER running; maxAgeMs + keep retention; no policy → no-op", async () => {
|
|
105
105
|
const store = make();
|
|
106
|
-
const running =
|
|
107
|
-
const oldDone =
|
|
108
|
-
const newDone =
|
|
109
|
-
const oldFail =
|
|
106
|
+
const running = createWorkflowRun({ id: "k-run", status: "running", createdAt: 100, endedAt: undefined });
|
|
107
|
+
const oldDone = createWorkflowRun({ id: "k-old", status: "completed", createdAt: 100, endedAt: 100 });
|
|
108
|
+
const newDone = createWorkflowRun({ id: "k-new", status: "completed", createdAt: 9_000, endedAt: 9_000 });
|
|
109
|
+
const oldFail = createWorkflowRun({ id: "k-fail", status: "failed", createdAt: 200, endedAt: 200 });
|
|
110
110
|
for (const r of [running, oldDone, newDone, oldFail])
|
|
111
111
|
await store.put(r.id, r);
|
|
112
112
|
assert.equal(await store.reap("tenant-a", 1_000_000), 0);
|
|
@@ -120,10 +120,10 @@ export async function workflowRunStoreContract(make, runAssertion = defaultSeque
|
|
|
120
120
|
});
|
|
121
121
|
run("reap keep-newest-N: deletes all but the newest N terminal runs; running excluded from the count", async () => {
|
|
122
122
|
const store = make();
|
|
123
|
-
const running =
|
|
124
|
-
const t1 =
|
|
125
|
-
const t2 =
|
|
126
|
-
const t3 =
|
|
123
|
+
const running = createWorkflowRun({ id: "p-run", status: "running", createdAt: 50, endedAt: undefined });
|
|
124
|
+
const t1 = createWorkflowRun({ id: "p-1", status: "completed", createdAt: 1_000 });
|
|
125
|
+
const t2 = createWorkflowRun({ id: "p-2", status: "completed", createdAt: 2_000 });
|
|
126
|
+
const t3 = createWorkflowRun({ id: "p-3", status: "failed", createdAt: 3_000 });
|
|
127
127
|
for (const r of [running, t1, t2, t3])
|
|
128
128
|
await store.put(r.id, r);
|
|
129
129
|
assert.equal(await store.reap("tenant-a", 99_999, { keep: 1 }), 2);
|
|
@@ -9,6 +9,19 @@ export declare function getShellConfig(customShellPath?: string): Promise<Result
|
|
|
9
9
|
shell: string;
|
|
10
10
|
args: string[];
|
|
11
11
|
}, ExecutionError>>;
|
|
12
|
+
export declare function decideSpoolReclaim(args: {
|
|
13
|
+
size: number;
|
|
14
|
+
cursor: number;
|
|
15
|
+
writerLive: boolean;
|
|
16
|
+
rotateBytes?: number;
|
|
17
|
+
hardCapBytes?: number;
|
|
18
|
+
}): {
|
|
19
|
+
reclaim: false;
|
|
20
|
+
} | {
|
|
21
|
+
reclaim: true;
|
|
22
|
+
live: boolean;
|
|
23
|
+
skippedBytes: number;
|
|
24
|
+
};
|
|
12
25
|
export declare function openSpoolPair(base: string): {
|
|
13
26
|
outPath: string;
|
|
14
27
|
errPath: string;
|
|
@@ -8,7 +8,7 @@ import { createInterface } from "node:readline";
|
|
|
8
8
|
import { ExecutionError, err, FileError, ok, toError, } from "../harness/types.js";
|
|
9
9
|
import { killProcessTree, shutdownDebug } from "./kill-tree.js";
|
|
10
10
|
import { scrubSecretEnv } from "../../core/secret-env.js";
|
|
11
|
-
import { RollingTailBuffer, markTruncated, newStreamCursorState, sliceStreamIncrement, } from "../../core/exec-output-tail.js";
|
|
11
|
+
import { RollingTailBuffer, markLiveSpoolRotations, markTruncated, newStreamCursorState, sliceStreamIncrement, } from "../../core/exec-output-tail.js";
|
|
12
12
|
import { BackgroundShellError } from "../../core/background-shell.js";
|
|
13
13
|
import { SchedulerError } from "../../core/scheduler.js";
|
|
14
14
|
const MAX_TIMER_TIMEOUT_MS = 2_147_000_000;
|
|
@@ -213,6 +213,23 @@ const EXEC_SPOOL_PUMP_MS = 200;
|
|
|
213
213
|
const EXEC_SPOOL_ROTATE_BYTES = 8 * 1024 * 1024;
|
|
214
214
|
const EXEC_SPOOL_FINAL_TAIL_BYTES = 8 * 1024 * 1024;
|
|
215
215
|
const EXEC_SPOOL_HARD_CAP_BYTES = 16 * 1024 * 1024;
|
|
216
|
+
export function decideSpoolReclaim(args) {
|
|
217
|
+
const rotate = args.rotateBytes ?? EXEC_SPOOL_ROTATE_BYTES;
|
|
218
|
+
const hardCap = args.hardCapBytes ?? EXEC_SPOOL_HARD_CAP_BYTES;
|
|
219
|
+
if (args.cursor < rotate)
|
|
220
|
+
return { reclaim: false };
|
|
221
|
+
if (args.size === args.cursor) {
|
|
222
|
+
if (!args.writerLive)
|
|
223
|
+
return { reclaim: true, live: false, skippedBytes: 0 };
|
|
224
|
+
if (args.size >= hardCap)
|
|
225
|
+
return { reclaim: true, live: true, skippedBytes: 0 };
|
|
226
|
+
return { reclaim: false };
|
|
227
|
+
}
|
|
228
|
+
if (args.size > args.cursor && args.size >= hardCap) {
|
|
229
|
+
return { reclaim: true, live: args.writerLive, skippedBytes: args.size - args.cursor };
|
|
230
|
+
}
|
|
231
|
+
return { reclaim: false };
|
|
232
|
+
}
|
|
216
233
|
const SIGNUM = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGABRT: 6, SIGKILL: 9, SIGSEGV: 11, SIGPIPE: 13, SIGTERM: 15 };
|
|
217
234
|
export function openSpoolPair(base) {
|
|
218
235
|
const outPath = `${base}.out.log`;
|
|
@@ -313,6 +330,9 @@ export class NodeExecutionEnv {
|
|
|
313
330
|
const adoptOnTimeoutRef = {};
|
|
314
331
|
const pumpSpoolRef = {};
|
|
315
332
|
const drainSpoolRef = {};
|
|
333
|
+
const liveRotations = { out: 0, err: 0 };
|
|
334
|
+
const liveRotationsTotal = () => liveRotations.out + liveRotations.err;
|
|
335
|
+
const writerLive = () => !settled && child !== undefined && child.exitCode === null && child.signalCode === null;
|
|
316
336
|
const armForceSettle = (result) => {
|
|
317
337
|
if (forceSettleRef.current || settled)
|
|
318
338
|
return;
|
|
@@ -331,7 +351,7 @@ export class NodeExecutionEnv {
|
|
|
331
351
|
drainSpoolRef.current?.();
|
|
332
352
|
const so = stdoutTail.result();
|
|
333
353
|
const se = stderrTail.result();
|
|
334
|
-
return { stdout: markTruncated(so.text, so.droppedBytes), stderr: markTruncated(se.text, se.droppedBytes) };
|
|
354
|
+
return { stdout: markTruncated(so.text, so.droppedBytes), stderr: markLiveSpoolRotations(markTruncated(se.text, se.droppedBytes), liveRotationsTotal()) };
|
|
335
355
|
};
|
|
336
356
|
const onAbort = () => {
|
|
337
357
|
abortKillInFlight = true;
|
|
@@ -520,16 +540,15 @@ export class NodeExecutionEnv {
|
|
|
520
540
|
if (spoolCursor[lane.cursor] < EXEC_SPOOL_ROTATE_BYTES)
|
|
521
541
|
return;
|
|
522
542
|
try {
|
|
523
|
-
const
|
|
524
|
-
if (
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
}
|
|
543
|
+
const d = decideSpoolReclaim({ size: statSync(lane.path).size, cursor: spoolCursor[lane.cursor], writerLive: writerLive() });
|
|
544
|
+
if (!d.reclaim)
|
|
545
|
+
return;
|
|
546
|
+
if (d.skippedBytes > 0)
|
|
547
|
+
lane.tail.recordSkippedBytes(d.skippedBytes);
|
|
548
|
+
if (d.live)
|
|
549
|
+
liveRotations[lane.cursor]++;
|
|
550
|
+
truncateSync(lane.path, 0);
|
|
551
|
+
spoolCursor[lane.cursor] = 0;
|
|
533
552
|
}
|
|
534
553
|
catch {
|
|
535
554
|
}
|
|
@@ -564,7 +583,9 @@ export class NodeExecutionEnv {
|
|
|
564
583
|
if (settled || !child)
|
|
565
584
|
return false;
|
|
566
585
|
pumpSpoolRef.current?.();
|
|
567
|
-
const shellId = this.adoptRunningChild(child, stdoutTail.result(), stderrTail.result(), execSpoolRef.current !== undefined
|
|
586
|
+
const shellId = this.adoptRunningChild(child, stdoutTail.result(), stderrTail.result(), execSpoolRef.current !== undefined
|
|
587
|
+
? { spool: execSpoolRef.current, cursors: { out: spoolCursor.out, err: spoolCursor.err }, liveRotations: liveRotationsTotal() }
|
|
588
|
+
: undefined);
|
|
568
589
|
if (shellId === undefined)
|
|
569
590
|
return false;
|
|
570
591
|
if (spoolPumpRef.current)
|
|
@@ -657,12 +678,12 @@ export class NodeExecutionEnv {
|
|
|
657
678
|
const signum = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGABRT: 6, SIGKILL: 9, SIGSEGV: 11, SIGPIPE: 13, SIGTERM: 15 };
|
|
658
679
|
settle(ok({
|
|
659
680
|
stdout: markTruncated(so.text, so.droppedBytes),
|
|
660
|
-
stderr: `${markTruncated(se.text, se.droppedBytes)}${se.text.endsWith("\n") || se.text === "" ? "" : "\n"}[process terminated by ${signal}]`,
|
|
681
|
+
stderr: markLiveSpoolRotations(`${markTruncated(se.text, se.droppedBytes)}${se.text.endsWith("\n") || se.text === "" ? "" : "\n"}[process terminated by ${signal}]`, liveRotationsTotal()),
|
|
661
682
|
exitCode: 128 + (signum[signal] ?? 9),
|
|
662
683
|
}));
|
|
663
684
|
return;
|
|
664
685
|
}
|
|
665
|
-
settle(ok({ stdout: markTruncated(so.text, so.droppedBytes), stderr: markTruncated(se.text, se.droppedBytes), exitCode: code ?? 0 }));
|
|
686
|
+
settle(ok({ stdout: markTruncated(so.text, so.droppedBytes), stderr: markLiveSpoolRotations(markTruncated(se.text, se.droppedBytes), liveRotationsTotal()), exitCode: code ?? 0 }));
|
|
666
687
|
};
|
|
667
688
|
child.on("close", (code, signal) => settleFromTermination(code, signal));
|
|
668
689
|
child.on("exit", (code, signal) => {
|
|
@@ -1030,6 +1051,7 @@ export class NodeExecutionEnv {
|
|
|
1030
1051
|
...(handover !== undefined
|
|
1031
1052
|
? { spool: { outPath: handover.spool.outPath, errPath: handover.spool.errPath, fileCursor: { ...handover.cursors }, ephemeral: true } }
|
|
1032
1053
|
: {}),
|
|
1054
|
+
...(handover !== undefined && (handover.liveRotations ?? 0) > 0 ? { liveRotations: handover.liveRotations } : {}),
|
|
1033
1055
|
};
|
|
1034
1056
|
const seedOut = Buffer.from(stdoutSoFar.text, "utf8");
|
|
1035
1057
|
const seedErr = Buffer.from(stderrSoFar.text, "utf8");
|
|
@@ -1219,9 +1241,14 @@ export class NodeExecutionEnv {
|
|
|
1219
1241
|
const out = sliceStreamIncrement(entry.stdout, terminal);
|
|
1220
1242
|
const er = sliceStreamIncrement(entry.stderr, terminal);
|
|
1221
1243
|
const droppedBeforeCursor = out.droppedBeforeCursor + er.droppedBeforeCursor;
|
|
1244
|
+
let stderrInc = er.inc;
|
|
1245
|
+
if (terminal && (entry.liveRotations ?? 0) > 0 && entry.liveRotationsDisclosed !== true) {
|
|
1246
|
+
entry.liveRotationsDisclosed = true;
|
|
1247
|
+
stderrInc = markLiveSpoolRotations(er.inc, entry.liveRotations ?? 0);
|
|
1248
|
+
}
|
|
1222
1249
|
return ok({
|
|
1223
1250
|
stdout: out.inc,
|
|
1224
|
-
stderr:
|
|
1251
|
+
stderr: stderrInc,
|
|
1225
1252
|
status: entry.status,
|
|
1226
1253
|
...(entry.exitCode !== undefined ? { exitCode: entry.exitCode } : {}),
|
|
1227
1254
|
...(droppedBeforeCursor > 0 ? { truncated: true, bytesDroppedBeforeCursor: droppedBeforeCursor } : {}),
|
|
@@ -1283,15 +1310,18 @@ export class NodeExecutionEnv {
|
|
|
1283
1310
|
}
|
|
1284
1311
|
}
|
|
1285
1312
|
if (spool.ephemeral && spool.fileCursor[lane] >= EXEC_SPOOL_ROTATE_BYTES) {
|
|
1286
|
-
const
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1313
|
+
const d = decideSpoolReclaim({
|
|
1314
|
+
size: statSync(path).size,
|
|
1315
|
+
cursor: spool.fileCursor[lane],
|
|
1316
|
+
writerLive: entry.status === "running" || (entry.child.exitCode === null && entry.child.signalCode === null),
|
|
1317
|
+
});
|
|
1318
|
+
if (d.reclaim) {
|
|
1319
|
+
if (d.skippedBytes > 0) {
|
|
1320
|
+
stream.tail.recordSkippedBytes(d.skippedBytes);
|
|
1321
|
+
stream.totalBytes += d.skippedBytes;
|
|
1322
|
+
}
|
|
1323
|
+
if (d.live)
|
|
1324
|
+
entry.liveRotations = (entry.liveRotations ?? 0) + 1;
|
|
1295
1325
|
truncateSync(path, 0);
|
|
1296
1326
|
spool.fileCursor[lane] = 0;
|
|
1297
1327
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare function encodeFrame(json: string): Buffer;
|
|
2
|
-
export declare function
|
|
2
|
+
export declare function createFrameDecoder(maxBytes?: number): (chunk: Buffer) => string[];
|
|
@@ -2,7 +2,7 @@ export function encodeFrame(json) {
|
|
|
2
2
|
const payload = Buffer.from(json, "utf8");
|
|
3
3
|
return Buffer.concat([Buffer.from(`Content-Length: ${payload.length}\r\n\r\n`, "ascii"), payload]);
|
|
4
4
|
}
|
|
5
|
-
export function
|
|
5
|
+
export function createFrameDecoder(maxBytes = 50 * 1024 * 1024) {
|
|
6
6
|
const HEADER_SLACK = 128;
|
|
7
7
|
let buf = Buffer.alloc(0);
|
|
8
8
|
return function decode(chunk) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type SessionWarmup } from "../../core/lsp-session.js";
|
|
2
2
|
import { type LspChildProcess } from "./stdio-lsp-transport.js";
|
|
3
3
|
import { type LspServerManager, type LspSession, type LspReadText } from "../../core/lsp.js";
|
|
4
|
-
import type { ExecutionEnv } from "../../internal/harness.js";
|
|
4
|
+
import type { ExecutionEnv } from "../../internal/harness-types.js";
|
|
5
5
|
export declare const DEFAULT_LSP_SERVERS: Readonly<Record<string, string>>;
|
|
6
6
|
export type LspSpawn = (command: string, args: string[], cwd: string, signal?: AbortSignal) => Promise<LspChildProcess | undefined>;
|
|
7
7
|
export interface NodeLspManagerOptions {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { encodeFrame,
|
|
1
|
+
import { encodeFrame, createFrameDecoder } from "./frame-decoder.js";
|
|
2
2
|
import { killProcessTree } from "../execution-env/kill-tree.js";
|
|
3
3
|
import { brandLspFailure } from "../../core/lsp.js";
|
|
4
4
|
export class StdioLspTransport {
|
|
@@ -7,7 +7,7 @@ export class StdioLspTransport {
|
|
|
7
7
|
nextId = 0;
|
|
8
8
|
pending = new Map();
|
|
9
9
|
isClosed = false;
|
|
10
|
-
decode =
|
|
10
|
+
decode = createFrameDecoder();
|
|
11
11
|
notificationHandlers = new Set();
|
|
12
12
|
constructor(child, requestTimeoutMs = 30_000) {
|
|
13
13
|
this.child = child;
|