@dimi-agent/cli 0.6.7 → 0.6.9
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/main.mjs +2281 -92
- package/package.json +5 -5
package/dist/main.mjs
CHANGED
|
@@ -34346,7 +34346,7 @@ var init_telemetry$2 = __esmMin((() => {
|
|
|
34346
34346
|
};
|
|
34347
34347
|
ITelemetryService = createDecorator("agentTelemetryService");
|
|
34348
34348
|
}));
|
|
34349
|
-
var init_events$
|
|
34349
|
+
var init_events$8 = __esmMin((() => {}));
|
|
34350
34350
|
//#endregion
|
|
34351
34351
|
//#region ../../packages/agent-core-v2/src/app/telemetry/telemetryService.ts
|
|
34352
34352
|
var TelemetryService, TelemetryContextView;
|
|
@@ -99307,6 +99307,11 @@ function loadNative() {
|
|
|
99307
99307
|
function coldRebuild(recordsJson) {
|
|
99308
99308
|
return loadNative().coldRebuild(recordsJson);
|
|
99309
99309
|
}
|
|
99310
|
+
/** Release an agent's scoped subagent registry (tasks + steering queues).
|
|
99311
|
+
* Call when the owning agent scope is disposed. */
|
|
99312
|
+
function dropTaskRegistry(registryId) {
|
|
99313
|
+
loadNative().dropTaskRegistry(registryId);
|
|
99314
|
+
}
|
|
99310
99315
|
/** `RustHostProcess.spawn` — the M2 exec spawn socket. */
|
|
99311
99316
|
async function rustHostProcessSpawn(command, args, options) {
|
|
99312
99317
|
return loadNative().RustHostProcess.spawn(command, [...args], options);
|
|
@@ -99337,7 +99342,7 @@ function rustHostEnvironmentProbe() {
|
|
|
99337
99342
|
function rustTerminalSpawn(options) {
|
|
99338
99343
|
return loadNative().RustTerminal.spawn(options);
|
|
99339
99344
|
}
|
|
99340
|
-
var nodeRequire$4, binding, PLATFORM_SUBPACKAGE, RustAgentTranscript, RustFileSystem;
|
|
99345
|
+
var nodeRequire$4, binding, PLATFORM_SUBPACKAGE, RustAgentTranscript, RustFileSystem, RustTurnSession;
|
|
99341
99346
|
var init_src$7 = __esmMin((() => {
|
|
99342
99347
|
nodeRequire$4 = createRequire(import.meta.url);
|
|
99343
99348
|
PLATFORM_SUBPACKAGE = `@dimi-agent/dimi-native-${process.platform}-${process.arch}`;
|
|
@@ -99397,6 +99402,89 @@ var init_src$7 = __esmMin((() => {
|
|
|
99397
99402
|
return loadNative().RustFileSystem.realpath(path);
|
|
99398
99403
|
}
|
|
99399
99404
|
};
|
|
99405
|
+
RustTurnSession = class {
|
|
99406
|
+
#inner;
|
|
99407
|
+
constructor(inputJson, policyJson, scriptedSegmentsJson, registryId) {
|
|
99408
|
+
const NativeClass = loadNative().RustTurnSession;
|
|
99409
|
+
this.#inner = new NativeClass(inputJson, policyJson, scriptedSegmentsJson ?? null, registryId);
|
|
99410
|
+
}
|
|
99411
|
+
/** Release the agent-scoped subagent registry (tasks + steering queues).
|
|
99412
|
+
* Call when the owning agent scope is disposed. */
|
|
99413
|
+
static dropTaskRegistry(registryId) {
|
|
99414
|
+
dropTaskRegistry(registryId);
|
|
99415
|
+
}
|
|
99416
|
+
/** Register the per-event callback: every engine event emitted by `run()` /
|
|
99417
|
+
* `resume()` is pushed through it as a JSON string, in emission order, as
|
|
99418
|
+
* it happens. Register before the first `run()`. */
|
|
99419
|
+
setOnEvent(callback) {
|
|
99420
|
+
this.#inner.setOnEvent(callback);
|
|
99421
|
+
}
|
|
99422
|
+
async run() {
|
|
99423
|
+
return this.#inner.run();
|
|
99424
|
+
}
|
|
99425
|
+
async resume(decisionJson) {
|
|
99426
|
+
return this.#inner.resume(decisionJson);
|
|
99427
|
+
}
|
|
99428
|
+
/** Record a session-scope approval (P1-6): the engine's policy is re-read
|
|
99429
|
+
* on every run/resume, so a pattern approved for the session mid-turn is
|
|
99430
|
+
* honored by the SAME turn's remaining batch. */
|
|
99431
|
+
addSessionApproval(pattern) {
|
|
99432
|
+
this.#inner.addSessionApproval(pattern);
|
|
99433
|
+
}
|
|
99434
|
+
/** Register the native-tool PreToolUse gate (A2 review): every registry
|
|
99435
|
+
* tool call is announced through `callback` (`{requestId, toolName,
|
|
99436
|
+
* arguments}` JSON); answer with `completeToolGate(requestId,
|
|
99437
|
+
* {decision:'allow'|'block', reason?})`. A block short-circuits the call. */
|
|
99438
|
+
setToolGate(callback) {
|
|
99439
|
+
this.#inner.setToolGate(callback);
|
|
99440
|
+
}
|
|
99441
|
+
/** Answer a pending gate request (see `setToolGate`). */
|
|
99442
|
+
completeToolGate(requestId, verdictJson) {
|
|
99443
|
+
this.#inner.completeToolGate(requestId, verdictJson);
|
|
99444
|
+
}
|
|
99445
|
+
/** Register a TS-side tool; `completeToolCall` finishes each call. The
|
|
99446
|
+
* definition (description + JSON parameters schema) is advertised to the
|
|
99447
|
+
* model from the next request on. */
|
|
99448
|
+
registerExternalTool(name, description, parametersJson, callback) {
|
|
99449
|
+
this.#inner.registerExternalTool(name, description, parametersJson, callback);
|
|
99450
|
+
}
|
|
99451
|
+
/** Advertise the LLM-facing definition (description + JSON parameters
|
|
99452
|
+
* schema) of a Rust-native tool (Agent / AgentOutput / WaitFor) registered
|
|
99453
|
+
* executor-first at construction. The executor stays the same; only the
|
|
99454
|
+
* def is updated, so the engine's request `tools` field carries it from
|
|
99455
|
+
* the next request on. */
|
|
99456
|
+
registerNativeToolDef(name, description, parametersJson) {
|
|
99457
|
+
this.#inner.registerNativeToolDef(name, description, parametersJson);
|
|
99458
|
+
}
|
|
99459
|
+
/** Steer the running turn (drained into its next LLM request). Returns
|
|
99460
|
+
* `false` when the turn has already finished — the caller must start a
|
|
99461
|
+
* new turn instead (the steer is never dropped). */
|
|
99462
|
+
steer(message) {
|
|
99463
|
+
return this.#inner.steer(message);
|
|
99464
|
+
}
|
|
99465
|
+
/** Steer a background subagent spawned by the `Agent` tool. */
|
|
99466
|
+
steerSubagent(agentId, message) {
|
|
99467
|
+
this.#inner.steerSubagent(agentId, message);
|
|
99468
|
+
}
|
|
99469
|
+
/** Cancel the running turn (engine stops at the next boundary). */
|
|
99470
|
+
cancel() {
|
|
99471
|
+
this.#inner.cancel();
|
|
99472
|
+
}
|
|
99473
|
+
/** Cancel a background task (TaskStop parity): the engine kills the
|
|
99474
|
+
* subagent nested turn / backgrounded bash command and settles "killed",
|
|
99475
|
+
* carrying the stop reason on the wire. */
|
|
99476
|
+
cancelTask(taskId, reason) {
|
|
99477
|
+
this.#inner.cancelTask(taskId, reason);
|
|
99478
|
+
}
|
|
99479
|
+
/** Close the session (agent dispose): task events stop forwarding, the
|
|
99480
|
+
* in-flight turn is cancelled. Background workers observe the close. */
|
|
99481
|
+
close() {
|
|
99482
|
+
this.#inner.close();
|
|
99483
|
+
}
|
|
99484
|
+
completeToolCall(requestId, resultJson) {
|
|
99485
|
+
this.#inner.completeToolCall(requestId, resultJson);
|
|
99486
|
+
}
|
|
99487
|
+
};
|
|
99400
99488
|
}));
|
|
99401
99489
|
//#endregion
|
|
99402
99490
|
//#region ../../packages/agent-core-v2/src/os/backends/rust-local/rustHostEnvironmentService.ts
|
|
@@ -121936,7 +122024,7 @@ function emptyOutputSnapshot() {
|
|
|
121936
122024
|
function agentTaskNotificationChildren(output) {
|
|
121937
122025
|
if (output.fullOutputAvailable && output.outputPath !== void 0) return [renderOutputFileBlock(output.outputPath, output.outputSizeBytes)];
|
|
121938
122026
|
if (output.preview.length === 0) return void 0;
|
|
121939
|
-
return [renderOutputPreviewBlock(output)];
|
|
122027
|
+
return [renderOutputPreviewBlock$1(output)];
|
|
121940
122028
|
}
|
|
121941
122029
|
function renderOutputFileBlock(outputPath, outputSizeBytes) {
|
|
121942
122030
|
return [
|
|
@@ -121945,7 +122033,7 @@ function renderOutputFileBlock(outputPath, outputSizeBytes) {
|
|
|
121945
122033
|
"</output-file>"
|
|
121946
122034
|
].join("\n");
|
|
121947
122035
|
}
|
|
121948
|
-
function renderOutputPreviewBlock(output) {
|
|
122036
|
+
function renderOutputPreviewBlock$1(output) {
|
|
121949
122037
|
return [
|
|
121950
122038
|
`<output-preview bytes="${String(output.previewBytes)}" total_bytes="${String(output.outputSizeBytes)}" truncated="${String(output.truncated)}">`,
|
|
121951
122039
|
output.truncated ? `Showing the last ${String(output.previewBytes)} bytes. No persisted full output is available.` : "No persisted full output is available; this preview is the currently buffered task output.",
|
|
@@ -122027,7 +122115,7 @@ function errorMessage$7(error) {
|
|
|
122027
122115
|
if (error instanceof Error) return error.message;
|
|
122028
122116
|
return String(error);
|
|
122029
122117
|
}
|
|
122030
|
-
var TaskNotificationDeliveryModel, MAX_OUTPUT_BYTES, TERMINAL_OUTPUT_TAIL_BYTES, MAX_TASK_OUTPUT_BYTES,
|
|
122118
|
+
var TaskNotificationDeliveryModel, MAX_OUTPUT_BYTES, TERMINAL_OUTPUT_TAIL_BYTES, MAX_TASK_OUTPUT_BYTES, TASK_ID_ALPHABET, SESSION_CLOSED_REASON, NOTIFICATION_FALLBACK_PREVIEW_BYTES, ACTIVE_BACKGROUND_TASK_INJECTION_VARIANT, ACTIVE_BACKGROUND_TASK_GUIDANCE, TaskNotificationStepRequest, taskGhostsKey, taskScheduledNotificationKeysKey, taskDeliveredNotificationKeysKey, taskActiveTaskReminderPendingKey, AgentTaskService;
|
|
122031
122119
|
var init_taskService = __esmMin((() => {
|
|
122032
122120
|
init_dist$5();
|
|
122033
122121
|
init_scope();
|
|
@@ -122075,7 +122163,6 @@ var init_taskService = __esmMin((() => {
|
|
|
122075
122163
|
MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
122076
122164
|
TERMINAL_OUTPUT_TAIL_BYTES = 4 * 1024;
|
|
122077
122165
|
MAX_TASK_OUTPUT_BYTES = 16 * 1024 * 1024;
|
|
122078
|
-
SIGTERM_GRACE_MS = 5e3;
|
|
122079
122166
|
TASK_ID_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
122080
122167
|
SESSION_CLOSED_REASON = "Session closed";
|
|
122081
122168
|
NOTIFICATION_FALLBACK_PREVIEW_BYTES = 3e3;
|
|
@@ -122274,7 +122361,7 @@ var init_taskService = __esmMin((() => {
|
|
|
122274
122361
|
};
|
|
122275
122362
|
this.assertCanRegister(detached);
|
|
122276
122363
|
const entry = {
|
|
122277
|
-
taskId: generateTaskId(task.idPrefix),
|
|
122364
|
+
taskId: options.taskId ?? generateTaskId(task.idPrefix),
|
|
122278
122365
|
task,
|
|
122279
122366
|
handle: void 0,
|
|
122280
122367
|
outputChunks: [],
|
|
@@ -122584,7 +122671,7 @@ var init_taskService = __esmMin((() => {
|
|
|
122584
122671
|
entry.stopReason = options.stopReason;
|
|
122585
122672
|
if (entry.handle) entry.handle.cancel();
|
|
122586
122673
|
else entry.abortController.abort(options.abortReason);
|
|
122587
|
-
const graceMs = resolveAgentTaskConfig(this.config)?.killGracePeriodMs ??
|
|
122674
|
+
const graceMs = resolveAgentTaskConfig(this.config)?.killGracePeriodMs ?? 5e3;
|
|
122588
122675
|
let graceTimer;
|
|
122589
122676
|
const graceful = await Promise.race([entry.lifecyclePromise.then(() => true, () => true), new Promise((resolve) => {
|
|
122590
122677
|
graceTimer = setTimeout(() => {
|
|
@@ -123262,6 +123349,258 @@ var init_waitForTool = __esmMin((() => {
|
|
|
123262
123349
|
});
|
|
123263
123350
|
}));
|
|
123264
123351
|
//#endregion
|
|
123352
|
+
//#region ../../packages/agent-core-v2/src/agent/tools/agent-output/agent-output.ts
|
|
123353
|
+
var AgentOutputInputSchema, AGENT_NOT_FOUND_MESSAGE, IAgentOutputTool;
|
|
123354
|
+
var init_agent_output$1 = __esmMin((() => {
|
|
123355
|
+
init_zod$1();
|
|
123356
|
+
init_instantiation();
|
|
123357
|
+
AgentOutputInputSchema = object({
|
|
123358
|
+
agent_id: string$2().describe("Agent ID of the subagent to inspect (returned by the Agent tool)."),
|
|
123359
|
+
tail_lines: number$2().int().min(1).max(500).optional().describe("How many of the most recent renderable records to show. Defaults to 60. The output is a transcript-style view of the subagent's latest activity.")
|
|
123360
|
+
});
|
|
123361
|
+
AGENT_NOT_FOUND_MESSAGE = "Agent instance not found.";
|
|
123362
|
+
IAgentOutputTool = createDecorator("agentOutputTool");
|
|
123363
|
+
}));
|
|
123364
|
+
//#endregion
|
|
123365
|
+
//#region ../../packages/agent-core-v2/src/agent/contextSize/contextSize.ts
|
|
123366
|
+
var IAgentContextSizeService;
|
|
123367
|
+
var init_contextSize = __esmMin((() => {
|
|
123368
|
+
init_instantiation();
|
|
123369
|
+
IAgentContextSizeService = createDecorator("agentContextSizeService");
|
|
123370
|
+
}));
|
|
123371
|
+
//#endregion
|
|
123372
|
+
//#region ../../packages/agent-core-v2/src/agent/tools/agent-output/agent-output.md?raw
|
|
123373
|
+
var agent_output_default;
|
|
123374
|
+
var init_agent_output = __esmMin((() => {
|
|
123375
|
+
agent_output_default = "Read the recent rendered output of a subagent — the same transcript-style view a human sees in the TUI: its latest assistant text, thinking, tool calls, and task progress, in time order.\n\nSubagents run fully asynchronously. Use this tool to check on one:\n\n- While you still have other work, do that work instead — the subagent's result (and completion notification) arrives on its own.\n- When you have nothing else to do and want to see what the subagent is doing, call this tool with the `agent_id` returned by the Agent tool.\n- If it is still working and you want to park until it progresses, call `WaitFor` with a reasonable `timeout_seconds` instead of polling this tool in a loop; the wait wakes you on the completion notification or the timeout, then check again with this tool.\n\nPass `tail_lines` to control how much of the recent activity to show (default 60). The `agent_id` is the Agent tool's `agent_id` parameter value (e.g. \"agent-6\"), NOT the `task_id` from its output.\n";
|
|
123376
|
+
}));
|
|
123377
|
+
//#endregion
|
|
123378
|
+
//#region ../../packages/agent-core-v2/src/agent/tools/agent-output/agentOutputTool.ts
|
|
123379
|
+
/**
|
|
123380
|
+
* `tools` domain (L7) — `AgentOutputTool` implementation (the `AgentOutput`
|
|
123381
|
+
* tool).
|
|
123382
|
+
*
|
|
123383
|
+
* Returns a transcript-style view of a subagent's recent activity by reading
|
|
123384
|
+
* the tail of its `wire.jsonl` journal (`<sessionDir>/agents/<agentId>/`):
|
|
123385
|
+
* assistant text, thinking, tool calls, and task progress in time order —
|
|
123386
|
+
* the same surface a human sees in the TUI. Subagents run fully
|
|
123387
|
+
* asynchronously, so this is the primary progress-check tool for the calling
|
|
123388
|
+
* agent (park with `WaitFor` instead of polling when there is nothing else
|
|
123389
|
+
* to do).
|
|
123390
|
+
*
|
|
123391
|
+
* Registered via the module-level `registerAgentToolService(IAgentOutputTool,
|
|
123392
|
+
* AgentOutputTool)` at the bottom of this file — the same "import = register"
|
|
123393
|
+
* pattern used by every agent tool. Bound at Agent scope.
|
|
123394
|
+
*/
|
|
123395
|
+
function toRenderable(line) {
|
|
123396
|
+
const trimmed = line.trim();
|
|
123397
|
+
if (trimmed.length === 0) return void 0;
|
|
123398
|
+
let parsed;
|
|
123399
|
+
try {
|
|
123400
|
+
parsed = JSON.parse(trimmed);
|
|
123401
|
+
} catch {
|
|
123402
|
+
return;
|
|
123403
|
+
}
|
|
123404
|
+
if (typeof parsed !== "object" || parsed === null) return void 0;
|
|
123405
|
+
const record = parsed;
|
|
123406
|
+
const timeMs = typeof record.time === "number" ? normalizeTimestampMs$1(record.time) : void 0;
|
|
123407
|
+
const turnStep = turnStepLabel(record.event);
|
|
123408
|
+
switch (record.type) {
|
|
123409
|
+
case "turn.prompt": return {
|
|
123410
|
+
timeMs: timeMs ?? 0,
|
|
123411
|
+
turnStep: "",
|
|
123412
|
+
lines: [`user: ${clip(textOfPrompt(record.input), PROMPT_MAX_CHARS)}`]
|
|
123413
|
+
};
|
|
123414
|
+
case "context.append_loop_event": {
|
|
123415
|
+
const event = record.event;
|
|
123416
|
+
const eventType = event?.type;
|
|
123417
|
+
if (eventType === "content.part" && typeof event?.part?.type === "string") {
|
|
123418
|
+
const partType = event.part.type;
|
|
123419
|
+
const text = partType === "think" ? typeof event.part.think === "string" ? event.part.think : "" : typeof event.part.text === "string" ? event.part.text : "";
|
|
123420
|
+
return {
|
|
123421
|
+
timeMs: timeMs ?? 0,
|
|
123422
|
+
turnStep,
|
|
123423
|
+
lines: [`${partType === "think" ? "think" : "assistant"}: ${clip(text, LINE_MAX_CHARS)}`]
|
|
123424
|
+
};
|
|
123425
|
+
}
|
|
123426
|
+
if (eventType === "tool.call" && typeof event?.name === "string") return {
|
|
123427
|
+
timeMs: timeMs ?? 0,
|
|
123428
|
+
turnStep,
|
|
123429
|
+
lines: [`tool: ${event.name}${argsLabel(event.args)}`]
|
|
123430
|
+
};
|
|
123431
|
+
if (eventType === "tool.result") {
|
|
123432
|
+
const done = event?.isError === true ? "error" : "done";
|
|
123433
|
+
return {
|
|
123434
|
+
timeMs: timeMs ?? 0,
|
|
123435
|
+
turnStep,
|
|
123436
|
+
lines: [` → ${done}`]
|
|
123437
|
+
};
|
|
123438
|
+
}
|
|
123439
|
+
return;
|
|
123440
|
+
}
|
|
123441
|
+
case "task.started":
|
|
123442
|
+
case "task.terminated": {
|
|
123443
|
+
const info = record.info;
|
|
123444
|
+
if (info === void 0) return void 0;
|
|
123445
|
+
const description = typeof info.description === "string" ? info.description : "";
|
|
123446
|
+
const taskId = typeof info.taskId === "string" ? info.taskId : "";
|
|
123447
|
+
const status = typeof info.status === "string" ? info.status : "";
|
|
123448
|
+
const label = record.type === "task.started" ? `task: ${clip(description, LINE_MAX_CHARS)} (running, ${taskId})` : `task: ${clip(description, LINE_MAX_CHARS)} (${status}, ${taskId})`;
|
|
123449
|
+
return {
|
|
123450
|
+
timeMs: timeMs ?? 0,
|
|
123451
|
+
turnStep: "",
|
|
123452
|
+
lines: [label]
|
|
123453
|
+
};
|
|
123454
|
+
}
|
|
123455
|
+
default: return;
|
|
123456
|
+
}
|
|
123457
|
+
}
|
|
123458
|
+
function turnStepLabel(event) {
|
|
123459
|
+
if (event === void 0) return "";
|
|
123460
|
+
const turn = typeof event.turnId === "string" ? event.turnId : void 0;
|
|
123461
|
+
const step = typeof event.step === "number" ? event.step : void 0;
|
|
123462
|
+
if (turn === void 0 && step === void 0) return "";
|
|
123463
|
+
return `[turn ${turn ?? "?"} step ${step ?? "?"}] `;
|
|
123464
|
+
}
|
|
123465
|
+
function argsLabel(args) {
|
|
123466
|
+
if (typeof args !== "object" || args === null) return "";
|
|
123467
|
+
return `(${clip(JSON.stringify(args), ARGS_MAX_CHARS)})`;
|
|
123468
|
+
}
|
|
123469
|
+
function textOfPrompt(input) {
|
|
123470
|
+
if (!Array.isArray(input)) return "";
|
|
123471
|
+
return input.flatMap((part) => typeof part === "object" && part !== null && part.type === "text" && typeof part.text === "string" ? [part.text] : []).join("").replaceAll(/\s+/g, " ").trim();
|
|
123472
|
+
}
|
|
123473
|
+
function clip(text, max) {
|
|
123474
|
+
const collapsed = text.replaceAll(/\s+/g, " ").trim();
|
|
123475
|
+
if (collapsed.length <= max) return collapsed;
|
|
123476
|
+
return `${collapsed.slice(0, max)}…`;
|
|
123477
|
+
}
|
|
123478
|
+
function normalizeTimestampMs$1(value) {
|
|
123479
|
+
return value > 0xe8d4a51000 ? Math.floor(value) : Math.floor(value * 1e3);
|
|
123480
|
+
}
|
|
123481
|
+
function formatTime(timeMs) {
|
|
123482
|
+
if (timeMs <= 0) return "";
|
|
123483
|
+
const date = new Date(timeMs);
|
|
123484
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
123485
|
+
return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
|
123486
|
+
}
|
|
123487
|
+
function formatTokens$2(size) {
|
|
123488
|
+
if (size < 1024) return `${String(size)} tokens`;
|
|
123489
|
+
return `${(size / 1024).toFixed(1)}k tokens`;
|
|
123490
|
+
}
|
|
123491
|
+
function isMissingPath$3(error) {
|
|
123492
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
123493
|
+
}
|
|
123494
|
+
var WIRE_FILENAME$1, TAIL_READ_BYTES, LINE_MAX_CHARS, ARGS_MAX_CHARS, PROMPT_MAX_CHARS, AgentOutputTool;
|
|
123495
|
+
var init_agentOutputTool = __esmMin((() => {
|
|
123496
|
+
init_dist$5();
|
|
123497
|
+
init_input_schema();
|
|
123498
|
+
init_rule_match();
|
|
123499
|
+
init_toolContribution();
|
|
123500
|
+
init_contextSize();
|
|
123501
|
+
init_loop();
|
|
123502
|
+
init_profile();
|
|
123503
|
+
init_agentLifecycle();
|
|
123504
|
+
init_sessionContext();
|
|
123505
|
+
init_agent_output$1();
|
|
123506
|
+
init_agent_output();
|
|
123507
|
+
init_decorateParam();
|
|
123508
|
+
init_decorate();
|
|
123509
|
+
WIRE_FILENAME$1 = "wire.jsonl";
|
|
123510
|
+
TAIL_READ_BYTES = 256 * 1024;
|
|
123511
|
+
LINE_MAX_CHARS = 240;
|
|
123512
|
+
ARGS_MAX_CHARS = 120;
|
|
123513
|
+
PROMPT_MAX_CHARS = 300;
|
|
123514
|
+
AgentOutputTool = class AgentOutputTool {
|
|
123515
|
+
lifecycle;
|
|
123516
|
+
session;
|
|
123517
|
+
name = "AgentOutput";
|
|
123518
|
+
description = agent_output_default;
|
|
123519
|
+
parameters = toInputJsonSchema(AgentOutputInputSchema);
|
|
123520
|
+
constructor(lifecycle, session) {
|
|
123521
|
+
this.lifecycle = lifecycle;
|
|
123522
|
+
this.session = session;
|
|
123523
|
+
}
|
|
123524
|
+
resolveExecution(args) {
|
|
123525
|
+
return {
|
|
123526
|
+
description: `Reading output of agent ${args.agent_id}`,
|
|
123527
|
+
taskMode: "control",
|
|
123528
|
+
approvalRule: this.name,
|
|
123529
|
+
matchesRule: (ruleArgs) => matchesGlobRuleSubject(ruleArgs, args.agent_id),
|
|
123530
|
+
execute: () => this.execute(args)
|
|
123531
|
+
};
|
|
123532
|
+
}
|
|
123533
|
+
async execute(args) {
|
|
123534
|
+
const target = this.lifecycle.get(args.agent_id);
|
|
123535
|
+
if (target === void 0) return {
|
|
123536
|
+
isError: true,
|
|
123537
|
+
output: `${AGENT_NOT_FOUND_MESSAGE} agent_id=${args.agent_id}`
|
|
123538
|
+
};
|
|
123539
|
+
const records = await this.readRecentRecords(args.agent_id, args.tail_lines ?? 60);
|
|
123540
|
+
const profileName = target.accessor.get(IAgentProfileService).data().profileName ?? "agent";
|
|
123541
|
+
const status = target.accessor.get(IAgentLoopService).status();
|
|
123542
|
+
const contextSize = target.accessor.get(IAgentContextSizeService)?.get().size ?? 0;
|
|
123543
|
+
const lines = [[
|
|
123544
|
+
`agent_id: ${args.agent_id}`,
|
|
123545
|
+
`type: ${profileName}`,
|
|
123546
|
+
`status: ${status.state}${status.activeTurnId !== void 0 ? ` · turn ${String(status.activeTurnId)}` : ""}`,
|
|
123547
|
+
`context: ${formatTokens$2(contextSize)}`
|
|
123548
|
+
].join(" · "), ""];
|
|
123549
|
+
if (records.length === 0) lines.push("(no activity recorded yet)");
|
|
123550
|
+
else for (const record of records) {
|
|
123551
|
+
const stamp = formatTime(record.timeMs);
|
|
123552
|
+
for (const line of record.lines) lines.push(`${stamp} ${record.turnStep}${line}`);
|
|
123553
|
+
}
|
|
123554
|
+
return {
|
|
123555
|
+
output: lines.join("\n"),
|
|
123556
|
+
isError: false
|
|
123557
|
+
};
|
|
123558
|
+
}
|
|
123559
|
+
async readRecentRecords(agentId, tailLines) {
|
|
123560
|
+
const path = join$5(this.session.sessionDir, "agents", agentId, WIRE_FILENAME$1);
|
|
123561
|
+
let file;
|
|
123562
|
+
try {
|
|
123563
|
+
file = await open(path, "r");
|
|
123564
|
+
} catch (error) {
|
|
123565
|
+
if (isMissingPath$3(error)) return [];
|
|
123566
|
+
throw error;
|
|
123567
|
+
}
|
|
123568
|
+
let input;
|
|
123569
|
+
try {
|
|
123570
|
+
const size = (await file.stat()).size;
|
|
123571
|
+
const start = Math.max(0, size - TAIL_READ_BYTES);
|
|
123572
|
+
input = size === 0 ? Readable.from([]) : file.createReadStream({
|
|
123573
|
+
encoding: "utf8",
|
|
123574
|
+
autoClose: false,
|
|
123575
|
+
start,
|
|
123576
|
+
end: size - 1
|
|
123577
|
+
});
|
|
123578
|
+
const lines = createInterface({
|
|
123579
|
+
input,
|
|
123580
|
+
crlfDelay: Infinity
|
|
123581
|
+
});
|
|
123582
|
+
const rendered = [];
|
|
123583
|
+
for await (const line of lines) {
|
|
123584
|
+
const record = toRenderable(line);
|
|
123585
|
+
if (record === void 0) continue;
|
|
123586
|
+
rendered.push(record);
|
|
123587
|
+
if (rendered.length > tailLines) rendered.shift();
|
|
123588
|
+
}
|
|
123589
|
+
return rendered;
|
|
123590
|
+
} finally {
|
|
123591
|
+
input?.destroy();
|
|
123592
|
+
if (input !== void 0) await finished(input, { cleanup: true }).catch(() => {});
|
|
123593
|
+
await file.close();
|
|
123594
|
+
}
|
|
123595
|
+
}
|
|
123596
|
+
};
|
|
123597
|
+
AgentOutputTool = __decorate$1([__decorateParam(0, IAgentLifecycleService), __decorateParam(1, ISessionContext)], AgentOutputTool);
|
|
123598
|
+
registerAgentToolService(IAgentOutputTool, AgentOutputTool, {
|
|
123599
|
+
name: "AgentOutput",
|
|
123600
|
+
domain: "subagent"
|
|
123601
|
+
});
|
|
123602
|
+
}));
|
|
123603
|
+
//#endregion
|
|
123265
123604
|
//#region ../../packages/agent-core-v2/src/agent/tools/all-done/all-done.md?raw
|
|
123266
123605
|
var all_done_default;
|
|
123267
123606
|
var init_all_done = __esmMin((() => {
|
|
@@ -139289,13 +139628,6 @@ var init_subagent_task = __esmMin((() => {
|
|
|
139289
139628
|
};
|
|
139290
139629
|
}));
|
|
139291
139630
|
//#endregion
|
|
139292
|
-
//#region ../../packages/agent-core-v2/src/agent/contextSize/contextSize.ts
|
|
139293
|
-
var IAgentContextSizeService;
|
|
139294
|
-
var init_contextSize = __esmMin((() => {
|
|
139295
|
-
init_instantiation();
|
|
139296
|
-
IAgentContextSizeService = createDecorator("agentContextSizeService");
|
|
139297
|
-
}));
|
|
139298
|
-
//#endregion
|
|
139299
139631
|
//#region ../../packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts
|
|
139300
139632
|
function emitAgentRunSpawned(requester, targetAgentId, meta) {
|
|
139301
139633
|
requester.accessor.get(IEventBus)?.publish({
|
|
@@ -208545,7 +208877,7 @@ function turnPromptText(input) {
|
|
|
208545
208877
|
const text = input.filter((part) => part.type === "text").map((part) => part.text).join("");
|
|
208546
208878
|
return text.length > 0 ? text : void 0;
|
|
208547
208879
|
}
|
|
208548
|
-
function isDisplayablePromptOrigin(origin) {
|
|
208880
|
+
function isDisplayablePromptOrigin$1(origin) {
|
|
208549
208881
|
if (origin.kind === "user") return true;
|
|
208550
208882
|
return (origin.kind === "skill_activation" || origin.kind === "plugin_command") && origin.trigger === "user-slash";
|
|
208551
208883
|
}
|
|
@@ -209007,7 +209339,7 @@ var init_loopService = __esmMin((() => {
|
|
|
209007
209339
|
type: "turn.started",
|
|
209008
209340
|
turnId: job.turn.id,
|
|
209009
209341
|
origin,
|
|
209010
|
-
prompt: isDisplayablePromptOrigin(origin) ? turnPromptText(job.seed.input) : void 0
|
|
209342
|
+
prompt: isDisplayablePromptOrigin$1(origin) ? turnPromptText(job.seed.input) : void 0
|
|
209011
209343
|
});
|
|
209012
209344
|
this.runTurn(job.turn, job.ready).then(job.result.resolve, job.result.reject);
|
|
209013
209345
|
}
|
|
@@ -213601,6 +213933,1506 @@ var init_rpc$2 = __esmMin((() => {
|
|
|
213601
213933
|
createDecorator("agentSessionRPCService");
|
|
213602
213934
|
}));
|
|
213603
213935
|
//#endregion
|
|
213936
|
+
//#region ../../packages/agent-core-v2/src/agent/loop/engineTaskAdapter.ts
|
|
213937
|
+
/** Extract a human-readable stop reason from an AbortSignal's abort reason:
|
|
213938
|
+
* TaskStop aborts with the normalized reason string; `stopByUser` aborts
|
|
213939
|
+
* with a `UserCancellationError` (its `.message` is the user-facing reason);
|
|
213940
|
+
* anything else (undefined / session close) yields no reason — the engine
|
|
213941
|
+
* falls back to "Stopped by TaskStop". An empty reason (e.g. an Error with
|
|
213942
|
+
* an empty message) counts as "no reason" too, so the wire settle carries
|
|
213943
|
+
* the documented fallback instead of an empty `error` string. */
|
|
213944
|
+
function abortReasonString(reason) {
|
|
213945
|
+
if (typeof reason === "string") return reason === "" ? void 0 : reason;
|
|
213946
|
+
if (reason instanceof Error) return reason.message === "" ? void 0 : reason.message;
|
|
213947
|
+
}
|
|
213948
|
+
var EngineTaskAdapter;
|
|
213949
|
+
var init_engineTaskAdapter = __esmMin((() => {
|
|
213950
|
+
EngineTaskAdapter = class {
|
|
213951
|
+
options;
|
|
213952
|
+
idPrefix;
|
|
213953
|
+
kind;
|
|
213954
|
+
description;
|
|
213955
|
+
sink;
|
|
213956
|
+
pendingOutput = "";
|
|
213957
|
+
pendingSettlement;
|
|
213958
|
+
pendingExitCode;
|
|
213959
|
+
exitCode;
|
|
213960
|
+
settleResolve;
|
|
213961
|
+
settled;
|
|
213962
|
+
removeAbortListener;
|
|
213963
|
+
/** UTF-8 bytes already pushed to the sink (or buffered pre-start). The
|
|
213964
|
+
* engine guarantees its `task.output` deltas concatenate byte-for-byte to
|
|
213965
|
+
* the settle's full output — the bash poller seeds a backgrounded command
|
|
213966
|
+
* with its pre-timeout foreground output as the FIRST delta, and the
|
|
213967
|
+
* subagent worker streams the nested turn's assistant deltas verbatim —
|
|
213968
|
+
* so `complete` appends only the not-yet-streamed tail. */
|
|
213969
|
+
streamedBytes = 0;
|
|
213970
|
+
constructor(options) {
|
|
213971
|
+
this.options = options;
|
|
213972
|
+
this.idPrefix = options.kind === "agent" ? "agent" : "bash";
|
|
213973
|
+
this.kind = options.kind;
|
|
213974
|
+
this.description = options.description;
|
|
213975
|
+
this.settled = new Promise((resolve) => {
|
|
213976
|
+
this.settleResolve = resolve;
|
|
213977
|
+
});
|
|
213978
|
+
}
|
|
213979
|
+
async start(sink) {
|
|
213980
|
+
this.sink = sink;
|
|
213981
|
+
const requestStop = () => {
|
|
213982
|
+
this.options.forceStop(abortReasonString(sink.signal.reason));
|
|
213983
|
+
};
|
|
213984
|
+
if (sink.signal.aborted) requestStop();
|
|
213985
|
+
else {
|
|
213986
|
+
sink.signal.addEventListener("abort", requestStop, { once: true });
|
|
213987
|
+
this.removeAbortListener = () => {
|
|
213988
|
+
sink.signal.removeEventListener("abort", requestStop);
|
|
213989
|
+
};
|
|
213990
|
+
}
|
|
213991
|
+
this.flush();
|
|
213992
|
+
await this.settled;
|
|
213993
|
+
}
|
|
213994
|
+
async forceStop() {
|
|
213995
|
+
this.options.forceStop();
|
|
213996
|
+
}
|
|
213997
|
+
/** Runner-side live output (engine `task.output` events): stream the delta
|
|
213998
|
+
* straight into the service sink so TaskOutput shows partial output while
|
|
213999
|
+
* the task runs. Deltas racing `start()` (settle/stream before the
|
|
214000
|
+
* service invoked start) are buffered and flushed with the settle. */
|
|
214001
|
+
appendOutput(delta) {
|
|
214002
|
+
this.streamedBytes += Buffer.byteLength(delta, "utf-8");
|
|
214003
|
+
if (this.sink !== void 0) this.sink.appendOutput(delta);
|
|
214004
|
+
else this.pendingOutput += delta;
|
|
214005
|
+
}
|
|
214006
|
+
/** Runner-side settle: record the final output/exit code and settle the
|
|
214007
|
+
* registry entry (the runner dispatches the wire `task.terminated` and
|
|
214008
|
+
* delivers the notification itself — the service's `recorded: false`
|
|
214009
|
+
* entry only drives TaskList/TaskStop). The settle output is the engine's
|
|
214010
|
+
* full accumulated output; the deltas streamed during the run already
|
|
214011
|
+
* landed in the sink, so only the not-yet-streamed tail is appended (the
|
|
214012
|
+
* concatenated deltas equal the settle output byte-for-byte). */
|
|
214013
|
+
complete(output, settlement, exitCode) {
|
|
214014
|
+
this.pendingSettlement = settlement;
|
|
214015
|
+
this.pendingExitCode = exitCode ?? null;
|
|
214016
|
+
const fullBytes = Buffer.byteLength(output, "utf-8");
|
|
214017
|
+
const streamed = this.streamedBytes;
|
|
214018
|
+
if (streamed < fullBytes) {
|
|
214019
|
+
const tail = Buffer.from(output, "utf-8").subarray(streamed).toString("utf-8");
|
|
214020
|
+
if (this.sink !== void 0) this.sink.appendOutput(tail);
|
|
214021
|
+
else this.pendingOutput += tail;
|
|
214022
|
+
}
|
|
214023
|
+
this.flush();
|
|
214024
|
+
}
|
|
214025
|
+
toInfo(base) {
|
|
214026
|
+
if (this.kind === "agent") return {
|
|
214027
|
+
...base,
|
|
214028
|
+
kind: "agent",
|
|
214029
|
+
agentId: this.options.agentId ?? "",
|
|
214030
|
+
subagentType: this.options.subagentType ?? this.options.description,
|
|
214031
|
+
detached: true
|
|
214032
|
+
};
|
|
214033
|
+
return {
|
|
214034
|
+
...base,
|
|
214035
|
+
kind: "process",
|
|
214036
|
+
command: this.description,
|
|
214037
|
+
pid: this.options.pid ?? 0,
|
|
214038
|
+
exitCode: this.exitCode ?? null,
|
|
214039
|
+
detached: true
|
|
214040
|
+
};
|
|
214041
|
+
}
|
|
214042
|
+
flush() {
|
|
214043
|
+
const sink = this.sink;
|
|
214044
|
+
const settlement = this.pendingSettlement;
|
|
214045
|
+
if (sink === void 0 || settlement === void 0) return;
|
|
214046
|
+
this.exitCode = this.pendingExitCode ?? null;
|
|
214047
|
+
if (this.pendingOutput.length > 0) sink.appendOutput(this.pendingOutput);
|
|
214048
|
+
this.pendingOutput = "";
|
|
214049
|
+
this.pendingSettlement = void 0;
|
|
214050
|
+
this.removeAbortListener?.();
|
|
214051
|
+
this.removeAbortListener = void 0;
|
|
214052
|
+
sink.settle(settlement);
|
|
214053
|
+
this.settleResolve?.();
|
|
214054
|
+
}
|
|
214055
|
+
};
|
|
214056
|
+
}));
|
|
214057
|
+
//#endregion
|
|
214058
|
+
//#region ../../packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncation.ts
|
|
214059
|
+
var IAgentToolResultTruncationService;
|
|
214060
|
+
var init_toolResultTruncation = __esmMin((() => {
|
|
214061
|
+
init_instantiation();
|
|
214062
|
+
IAgentToolResultTruncationService = createDecorator("agentToolResultTruncationService");
|
|
214063
|
+
}));
|
|
214064
|
+
//#endregion
|
|
214065
|
+
//#region ../../packages/agent-core-v2/src/agent/loop/rustEngineTurnRunner.ts
|
|
214066
|
+
/**
|
|
214067
|
+
* `rustEngineTurnRunner` — the default turn runner: one turn through the Rust
|
|
214068
|
+
* engine (`RustTurnSession` napi socket) instead of the TS loop.
|
|
214069
|
+
*
|
|
214070
|
+
* Enabled by default; the CLI `--legacy` flag sets `DIMI_LEGACY=1` to keep
|
|
214071
|
+
* the TS loop. The runner:
|
|
214072
|
+
* 1. records `turn.prompt` (turn clock) and appends the user message;
|
|
214073
|
+
* 2. assembles the LLM messages from the context (context assembly stays
|
|
214074
|
+
* on the TS side until slice 3);
|
|
214075
|
+
* 3. runs `RustTurnSession` (aimux-backed LLM in production, scripted
|
|
214076
|
+
* segments under test);
|
|
214077
|
+
* 4. streams the engine events onto the event bus as they happen (the
|
|
214078
|
+
* bridge pushes each event through a per-event callback while the turn
|
|
214079
|
+
* is in flight) — the transcript projection layer (`coreEventMap`)
|
|
214080
|
+
* folds them into wire ops exactly as it does for the TS loop — and
|
|
214081
|
+
* mirrors them into the context (`step.begin` / `content.part` /
|
|
214082
|
+
* `tool.call` / `tool.result` / `step.end` + the assistant message) so
|
|
214083
|
+
* the next turn's history is intact.
|
|
214084
|
+
*
|
|
214085
|
+
* Slice-1 scope: single turn, no queue/cancellation/undo (those land with
|
|
214086
|
+
* later slices). The runner is a parallel path — `loopService` is untouched.
|
|
214087
|
+
*/
|
|
214088
|
+
function wrapSystemReminder(text) {
|
|
214089
|
+
const trimmed = text.trim();
|
|
214090
|
+
if (trimmed.startsWith("<system-reminder>") && trimmed.endsWith("</system-reminder>")) return trimmed;
|
|
214091
|
+
return `<system-reminder>\n${trimmed}\n</system-reminder>`;
|
|
214092
|
+
}
|
|
214093
|
+
/**
|
|
214094
|
+
* The Rust engine is the default runtime; the CLI `--legacy` flag sets
|
|
214095
|
+
* `DIMI_LEGACY=1` to keep the TS loop (and the node-local OS backends).
|
|
214096
|
+
*/
|
|
214097
|
+
function rustEngineEnabled() {
|
|
214098
|
+
return process.env["DIMI_LEGACY"] !== "1";
|
|
214099
|
+
}
|
|
214100
|
+
/** Render an engine event/tool value as text (strings pass through). */
|
|
214101
|
+
function toText(value) {
|
|
214102
|
+
return typeof value === "string" ? value : JSON.stringify(value) ?? "";
|
|
214103
|
+
}
|
|
214104
|
+
/**
|
|
214105
|
+
* Serialize a TS `PromptOrigin` into the wire `TurnOrigin` JSON shape the
|
|
214106
|
+
* engine deserializes (`{ kind: 'user' }` / `{ kind: 'task', taskId }` /
|
|
214107
|
+
* … — see `dimi-wire` `model.rs`). Unknown kinds fall back to a plain user
|
|
214108
|
+
* origin (the wire default).
|
|
214109
|
+
*/
|
|
214110
|
+
function toEngineTurnOrigin(origin) {
|
|
214111
|
+
switch (origin.kind) {
|
|
214112
|
+
case "task": return {
|
|
214113
|
+
kind: "task",
|
|
214114
|
+
taskId: origin.taskId
|
|
214115
|
+
};
|
|
214116
|
+
case "cron_job": return {
|
|
214117
|
+
kind: "cron",
|
|
214118
|
+
taskId: origin.jobId
|
|
214119
|
+
};
|
|
214120
|
+
case "cron_missed": return { kind: "cron" };
|
|
214121
|
+
case "hook_result": return { kind: "hook" };
|
|
214122
|
+
case "compaction_summary": return { kind: "compaction" };
|
|
214123
|
+
default: return { kind: "user" };
|
|
214124
|
+
}
|
|
214125
|
+
}
|
|
214126
|
+
/**
|
|
214127
|
+
* TS `isDisplayablePromptOrigin` parity: only user-origin (and user-slash
|
|
214128
|
+
* skill/plugin) turns expose their prompt on `turn.started`; task/cron/hook
|
|
214129
|
+
* steering text must never leak into the transcript.
|
|
214130
|
+
*/
|
|
214131
|
+
function isDisplayablePromptOrigin(origin) {
|
|
214132
|
+
if (origin.kind === "user") return true;
|
|
214133
|
+
return (origin.kind === "skill_activation" || origin.kind === "plugin_command") && origin.trigger === "user-slash";
|
|
214134
|
+
}
|
|
214135
|
+
/**
|
|
214136
|
+
* Build a DimiErrorPayload-shaped error from the engine's `{ message, code }`
|
|
214137
|
+
* payload (TS `toDimiErrorPayload` parity): always carries `name` (the error
|
|
214138
|
+
* class name, mapped from the code when the engine omitted it), `retryable`
|
|
214139
|
+
* (mapped from the code per the TS registry) and `message`.
|
|
214140
|
+
*/
|
|
214141
|
+
function buildErrorPayload(rawError) {
|
|
214142
|
+
const error = { ...rawError };
|
|
214143
|
+
if (error["name"] === void 0 || error["name"] === null) error["name"] = error["code"] === "PROVIDER_FILTERED" ? "ProviderFilteredError" : "Error";
|
|
214144
|
+
if (error["retryable"] === void 0) error["retryable"] = typeof error["code"] === "string" && RETRYABLE_ERROR_CODES.has(error["code"]);
|
|
214145
|
+
return error;
|
|
214146
|
+
}
|
|
214147
|
+
/** Optional numeric engine field (pid / exitCode). */
|
|
214148
|
+
function toOptionalNumber(value) {
|
|
214149
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
214150
|
+
}
|
|
214151
|
+
/** Mirrors the task domain's `buildAgentTaskNotificationBody` (minus the
|
|
214152
|
+
* output-file block — the engine carries the tail inline). */
|
|
214153
|
+
function buildTaskNotificationBody(task) {
|
|
214154
|
+
const baseLine = task.status === "timed_out" ? `${task.description} timed out.` : task.status === "killed" && task.error !== void 0 ? `${task.description} was stopped. Reason: ${task.error}` : task.status === "failed" && task.error !== void 0 ? `${task.description} failed. Reason: ${task.error}` : `${task.description} ${task.status}.`;
|
|
214155
|
+
if (task.kind !== "agent" || task.status === "completed") return baseLine;
|
|
214156
|
+
return `${baseLine}${[
|
|
214157
|
+
"",
|
|
214158
|
+
`To recover or continue this subagent, call Agent(resume="${task.agentId}", prompt="Pick up where you left off; redo the last tool call if its result was never observed.").`,
|
|
214159
|
+
`Use agent_id ("${task.agentId}"), NOT source_id / task_id ("${task.taskId}") — the two look alike but only agent_id is accepted by the resume parameter.`,
|
|
214160
|
+
"Add run_in_background=true to keep it backgrounded, or omit it to take the result inline in the current turn.",
|
|
214161
|
+
"The subagent retains its full prior context across the restart, but any in-flight tool call lost its result and may need to be redone."
|
|
214162
|
+
].join("\n")}`;
|
|
214163
|
+
}
|
|
214164
|
+
/** Mirrors the task domain's `renderOutputPreviewBlock` (tail inline): the
|
|
214165
|
+
* engine's accumulated output is the "currently buffered" output, so the
|
|
214166
|
+
* preview is the last `NOTIFICATION_OUTPUT_PREVIEW_BYTES` bytes with the
|
|
214167
|
+
* same heading / `truncated` / `bytes` semantics the TS service renders. */
|
|
214168
|
+
function renderOutputPreviewBlock(output) {
|
|
214169
|
+
const fullBytes = Buffer.byteLength(output, "utf-8");
|
|
214170
|
+
const previewBytes = Math.min(NOTIFICATION_OUTPUT_PREVIEW_BYTES, fullBytes);
|
|
214171
|
+
const truncated = fullBytes > previewBytes;
|
|
214172
|
+
const preview = previewBytes > 0 ? Buffer.from(output, "utf-8").subarray(fullBytes - previewBytes).toString("utf-8") : "";
|
|
214173
|
+
return [
|
|
214174
|
+
`<output-preview bytes="${String(previewBytes)}" total_bytes="${String(fullBytes)}" truncated="${String(truncated)}">`,
|
|
214175
|
+
truncated ? `Showing the last ${String(previewBytes)} bytes. No persisted full output is available.` : "No persisted full output is available; this preview is the currently buffered task output.",
|
|
214176
|
+
escapeXml$1(preview),
|
|
214177
|
+
"</output-preview>"
|
|
214178
|
+
].join("\n");
|
|
214179
|
+
}
|
|
214180
|
+
/** Resolve once the signal aborts (used to race an approval wait). */
|
|
214181
|
+
function abortOnSignal(signal) {
|
|
214182
|
+
return new Promise((resolve) => {
|
|
214183
|
+
if (signal.aborted) {
|
|
214184
|
+
resolve();
|
|
214185
|
+
return;
|
|
214186
|
+
}
|
|
214187
|
+
signal.addEventListener("abort", () => {
|
|
214188
|
+
resolve();
|
|
214189
|
+
}, { once: true });
|
|
214190
|
+
});
|
|
214191
|
+
}
|
|
214192
|
+
var WAIT_FOR_NATIVE_DESCRIPTION, ENGINE_NATIVE_TOOLS, WAIT_FOR_NATIVE_PARAMETERS, IRustEngineTurnRunner, RETRYABLE_ERROR_CODES, TERMINAL_OUTPUT_TAIL_CHARS, NOTIFICATION_OUTPUT_PREVIEW_BYTES, RustEngineTurnRunner;
|
|
214193
|
+
var init_rustEngineTurnRunner = __esmMin((() => {
|
|
214194
|
+
init_src$7();
|
|
214195
|
+
init_xml_escape();
|
|
214196
|
+
init_contextMemory();
|
|
214197
|
+
init_permissionMode();
|
|
214198
|
+
init_toolRegistry();
|
|
214199
|
+
init_toolPolicy();
|
|
214200
|
+
init_permissionRules();
|
|
214201
|
+
init_engineTaskAdapter();
|
|
214202
|
+
init_notificationXml();
|
|
214203
|
+
init_taskOps();
|
|
214204
|
+
init_task$5();
|
|
214205
|
+
init_configSection$12();
|
|
214206
|
+
init_turnOps();
|
|
214207
|
+
init_eventBus();
|
|
214208
|
+
init_config$5();
|
|
214209
|
+
init_log();
|
|
214210
|
+
init_canonical_args();
|
|
214211
|
+
init_errors$11();
|
|
214212
|
+
init_externalHooksRunner();
|
|
214213
|
+
init_toolResultTruncation();
|
|
214214
|
+
init_approval$4();
|
|
214215
|
+
init_usage();
|
|
214216
|
+
init_profile();
|
|
214217
|
+
init_scopeContext();
|
|
214218
|
+
init_catalog$1();
|
|
214219
|
+
init_providerRuntime();
|
|
214220
|
+
init_sessionContext();
|
|
214221
|
+
init_sessionMetadata();
|
|
214222
|
+
init_usage$1();
|
|
214223
|
+
init_wire();
|
|
214224
|
+
init_compactionHandoff();
|
|
214225
|
+
init_compactionOps();
|
|
214226
|
+
init_completion();
|
|
214227
|
+
init_decorateParam();
|
|
214228
|
+
init_decorate();
|
|
214229
|
+
init_instantiation();
|
|
214230
|
+
init_scope();
|
|
214231
|
+
WAIT_FOR_NATIVE_DESCRIPTION = [
|
|
214232
|
+
"Wait for a background subagent task to finish (or time out).",
|
|
214233
|
+
"Pass the `agent_id` of a subagent launched by the Agent tool (from its launch output).",
|
|
214234
|
+
"The call blocks until that subagent completes, fails, or the timeout expires, then returns its final status and output.",
|
|
214235
|
+
"This waits on a specific subagent task, NOT on the user: user-wait (waking on user notifications) is not implemented.",
|
|
214236
|
+
"Prefer AgentOutput for a quick status check; use WaitFor when the turn should pause until the subagent finishes."
|
|
214237
|
+
].join(" ");
|
|
214238
|
+
ENGINE_NATIVE_TOOLS = new Set([
|
|
214239
|
+
"Bash",
|
|
214240
|
+
"Agent",
|
|
214241
|
+
"AgentOutput",
|
|
214242
|
+
"WaitFor"
|
|
214243
|
+
]);
|
|
214244
|
+
WAIT_FOR_NATIVE_PARAMETERS = {
|
|
214245
|
+
type: "object",
|
|
214246
|
+
properties: {
|
|
214247
|
+
agent_id: {
|
|
214248
|
+
type: "string",
|
|
214249
|
+
description: "Agent id of the running subagent task to wait for, as returned by the Agent tool launch output."
|
|
214250
|
+
},
|
|
214251
|
+
timeout_seconds: {
|
|
214252
|
+
type: "integer",
|
|
214253
|
+
minimum: 1,
|
|
214254
|
+
maximum: 1800,
|
|
214255
|
+
description: "How long to wait for the subagent before giving up. Defaults to 60; maximum 1800."
|
|
214256
|
+
}
|
|
214257
|
+
},
|
|
214258
|
+
required: ["agent_id"],
|
|
214259
|
+
additionalProperties: false
|
|
214260
|
+
};
|
|
214261
|
+
IRustEngineTurnRunner = createDecorator("rustEngineTurnRunner");
|
|
214262
|
+
RETRYABLE_ERROR_CODES = new Set([
|
|
214263
|
+
"provider.rate_limit",
|
|
214264
|
+
"provider.connection_error",
|
|
214265
|
+
"provider.overloaded",
|
|
214266
|
+
"context.overflow"
|
|
214267
|
+
]);
|
|
214268
|
+
TERMINAL_OUTPUT_TAIL_CHARS = 4 * 1024;
|
|
214269
|
+
NOTIFICATION_OUTPUT_PREVIEW_BYTES = 3e3;
|
|
214270
|
+
RustEngineTurnRunner = class RustEngineTurnRunner {
|
|
214271
|
+
context;
|
|
214272
|
+
eventBus;
|
|
214273
|
+
wire;
|
|
214274
|
+
config;
|
|
214275
|
+
modeService;
|
|
214276
|
+
rulesService;
|
|
214277
|
+
toolRegistry;
|
|
214278
|
+
usageService;
|
|
214279
|
+
profile;
|
|
214280
|
+
scopeContext;
|
|
214281
|
+
sessionContext;
|
|
214282
|
+
sessionMetadata;
|
|
214283
|
+
tasks;
|
|
214284
|
+
modelCatalog;
|
|
214285
|
+
providerRuntime;
|
|
214286
|
+
instantiation;
|
|
214287
|
+
toolPolicy;
|
|
214288
|
+
log;
|
|
214289
|
+
/** The in-flight Rust session, while a turn is running (steer/cancel target). */
|
|
214290
|
+
activeSession;
|
|
214291
|
+
/** FIFO queue of turns waiting behind the running one (TS loop queue
|
|
214292
|
+
* parity): prompts during an active turn wait for it to finish. */
|
|
214293
|
+
queued = [];
|
|
214294
|
+
/** Whether a turn is currently executing (queue gate). */
|
|
214295
|
+
turnRunning = false;
|
|
214296
|
+
/** turnId of the executing turn (cancel validation). */
|
|
214297
|
+
executingTurnId;
|
|
214298
|
+
/** Aborts the in-flight approval wait on cancel. */
|
|
214299
|
+
approvalAbort;
|
|
214300
|
+
/**
|
|
214301
|
+
* Rust-side task registry mirror: taskId → launch facts (description /
|
|
214302
|
+
* startedAt / pid) recorded from `task.started`, used to build the
|
|
214303
|
+
* terminal `task.terminated` info from `task.settled`. Entries are removed
|
|
214304
|
+
* once the settle is handled (a task settles exactly once), so the map
|
|
214305
|
+
* stays bounded by the number of tasks in flight.
|
|
214306
|
+
*/
|
|
214307
|
+
taskInfos = /* @__PURE__ */ new Map();
|
|
214308
|
+
/** Notification dedupe (TS `deliveredNotificationKeys` parity): guards a
|
|
214309
|
+
* single settle from being delivered twice. Keys are removed after the
|
|
214310
|
+
* delivery completes — a settled task never settles again — so the set
|
|
214311
|
+
* stays bounded; the mid-turn+idle double-delivery guard is the
|
|
214312
|
+
* single-call structure of `deliverTaskNotification`, not this set. */
|
|
214313
|
+
deliveredNotificationKeys = /* @__PURE__ */ new Set();
|
|
214314
|
+
/** Registry entries for engine background tasks (TaskList/TaskStop parity):
|
|
214315
|
+
* taskId → adapter registered with `IAgentTaskService`. Removed once the
|
|
214316
|
+
* task settles (a task settles exactly once), so the map stays bounded. */
|
|
214317
|
+
engineTaskAdapters = /* @__PURE__ */ new Map();
|
|
214318
|
+
/** Owning RustTurnSession per engine task id (F1): recorded at
|
|
214319
|
+
* `task.started` from the session whose EventSink delivered the event.
|
|
214320
|
+
* Tasks launched from background workers (a subagent spawning a
|
|
214321
|
+
* sub-subagent, or a subagent launching a backgrounded bash) emit their
|
|
214322
|
+
* start AFTER the launching turn ended, when `activeSession` is undefined
|
|
214323
|
+
* or a newer turn's session — and the engine's per-task cancel signal
|
|
214324
|
+
* lives on the OWNING session's task map (`RustTurnSession::new` creates
|
|
214325
|
+
* a fresh map per turn), so TaskStop must cancel through this session.
|
|
214326
|
+
* Removed once the task settles, so the map stays bounded. */
|
|
214327
|
+
taskSessions = /* @__PURE__ */ new Map();
|
|
214328
|
+
/** Every subagent agent id this runner has handed out (the engine's
|
|
214329
|
+
* `agent-<n>` ids across turns): the next-turn seed must continue past
|
|
214330
|
+
* them so ids stay monotonic within the session (TS
|
|
214331
|
+
* `nextAvailableAgentId` parity). */
|
|
214332
|
+
engineAgentIds = /* @__PURE__ */ new Set();
|
|
214333
|
+
/** Every RustTurnSession this runner created. Held until the agent scope
|
|
214334
|
+
* is disposed so a session's EventSink stays open while its background
|
|
214335
|
+
* tasks are still settling (a subagent launched in turn 1 must be able to
|
|
214336
|
+
* notify after turn 1 ends), and so teardown can close them all at once
|
|
214337
|
+
* (TS `taskService.dispose` parity). */
|
|
214338
|
+
sessions = /* @__PURE__ */ new Set();
|
|
214339
|
+
/** Whether the agent scope was disposed: late engine events (background
|
|
214340
|
+
* task settles racing the teardown) are ignored instead of dispatching
|
|
214341
|
+
* wire ops on a disposed wire / appending to a disposed context. */
|
|
214342
|
+
disposed = false;
|
|
214343
|
+
constructor(context, eventBus, wire, config, modeService, rulesService, toolRegistry, usageService, profile, scopeContext, sessionContext, sessionMetadata, tasks, modelCatalog, providerRuntime, instantiation, toolPolicy, log) {
|
|
214344
|
+
this.context = context;
|
|
214345
|
+
this.eventBus = eventBus;
|
|
214346
|
+
this.wire = wire;
|
|
214347
|
+
this.config = config;
|
|
214348
|
+
this.modeService = modeService;
|
|
214349
|
+
this.rulesService = rulesService;
|
|
214350
|
+
this.toolRegistry = toolRegistry;
|
|
214351
|
+
this.usageService = usageService;
|
|
214352
|
+
this.profile = profile;
|
|
214353
|
+
this.scopeContext = scopeContext;
|
|
214354
|
+
this.sessionContext = sessionContext;
|
|
214355
|
+
this.sessionMetadata = sessionMetadata;
|
|
214356
|
+
this.tasks = tasks;
|
|
214357
|
+
this.modelCatalog = modelCatalog;
|
|
214358
|
+
this.providerRuntime = providerRuntime;
|
|
214359
|
+
this.instantiation = instantiation;
|
|
214360
|
+
this.toolPolicy = toolPolicy;
|
|
214361
|
+
this.log = log;
|
|
214362
|
+
this.registryId = randomUUID();
|
|
214363
|
+
}
|
|
214364
|
+
/** Agent-scoped Rust subagent registry id (see constructor). */
|
|
214365
|
+
registryId;
|
|
214366
|
+
/** TS `stopHookContinuationUsed` parity: the Stop hook fires at most once
|
|
214367
|
+
* after a continuation was delivered. */
|
|
214368
|
+
stopHookContinuationUsed = false;
|
|
214369
|
+
static isEnabled() {
|
|
214370
|
+
return rustEngineEnabled();
|
|
214371
|
+
}
|
|
214372
|
+
/**
|
|
214373
|
+
* Steer the running turn. Mirrors the TS steer path (`steerTurn` op +
|
|
214374
|
+
* user message in the context) and forwards the text into the engine's
|
|
214375
|
+
* steer queue, where it is drained into the next LLM request. Returns
|
|
214376
|
+
* `false` when there is no steerable turn: either no session is active
|
|
214377
|
+
* (the caller starts a new turn) or the engine's turn already finished
|
|
214378
|
+
* (a steer racing the teardown — between the engine's final steer check
|
|
214379
|
+
* and this runner clearing `activeSession` — would land in a queue that
|
|
214380
|
+
* is never drained again; the caller's `runTurn` fallback queues it as
|
|
214381
|
+
* the next turn instead, so it is never lost).
|
|
214382
|
+
*/
|
|
214383
|
+
steer(payload) {
|
|
214384
|
+
if (this.disposed) return false;
|
|
214385
|
+
const session = this.activeSession;
|
|
214386
|
+
if (session === void 0) return false;
|
|
214387
|
+
const text = payload.input.filter((part) => part.type === "text").map((part) => part.text ?? "").join("");
|
|
214388
|
+
if (text.length === 0) return false;
|
|
214389
|
+
if (!session.steer(text)) return false;
|
|
214390
|
+
this.wire.dispatch(steerTurn({
|
|
214391
|
+
input: [...payload.input],
|
|
214392
|
+
origin: payload.origin
|
|
214393
|
+
}));
|
|
214394
|
+
this.context.append({
|
|
214395
|
+
role: "user",
|
|
214396
|
+
content: [...payload.input],
|
|
214397
|
+
toolCalls: [],
|
|
214398
|
+
origin: payload.origin,
|
|
214399
|
+
id: randomUUID()
|
|
214400
|
+
});
|
|
214401
|
+
return true;
|
|
214402
|
+
}
|
|
214403
|
+
/**
|
|
214404
|
+
* Run one turn through the Rust engine. The turn clock advances at enqueue
|
|
214405
|
+
* time (TS parity); the turn itself either starts immediately (resolves
|
|
214406
|
+
* with its id) or waits behind the running turn (resolves `undefined`,
|
|
214407
|
+
* like TS `state === 'pending'`).
|
|
214408
|
+
*/
|
|
214409
|
+
async runTurn(payload) {
|
|
214410
|
+
if (this.disposed) return void 0;
|
|
214411
|
+
this.wire.dispatch(promptTurn({
|
|
214412
|
+
input: [...payload.input],
|
|
214413
|
+
origin: payload.origin
|
|
214414
|
+
}));
|
|
214415
|
+
const turnId = this.wire.getModel(TurnModel).nextTurnId - 1;
|
|
214416
|
+
const userMessage = {
|
|
214417
|
+
role: "user",
|
|
214418
|
+
content: [...payload.input],
|
|
214419
|
+
toolCalls: [],
|
|
214420
|
+
origin: payload.origin,
|
|
214421
|
+
id: randomUUID()
|
|
214422
|
+
};
|
|
214423
|
+
this.context.append(userMessage);
|
|
214424
|
+
if (this.turnRunning) {
|
|
214425
|
+
this.queued.push({
|
|
214426
|
+
turnId,
|
|
214427
|
+
payload,
|
|
214428
|
+
cancelled: false
|
|
214429
|
+
});
|
|
214430
|
+
return;
|
|
214431
|
+
}
|
|
214432
|
+
this.startQueuedTurn({
|
|
214433
|
+
turnId,
|
|
214434
|
+
payload,
|
|
214435
|
+
cancelled: false
|
|
214436
|
+
});
|
|
214437
|
+
return { turnId };
|
|
214438
|
+
}
|
|
214439
|
+
/** Cancel the active turn; with `turnId`, also cancels a queued turn. */
|
|
214440
|
+
cancel(turnId) {
|
|
214441
|
+
const session = this.activeSession;
|
|
214442
|
+
if (session !== void 0 && (turnId === void 0 || turnId === this.executingTurnId)) {
|
|
214443
|
+
this.approvalAbort?.abort();
|
|
214444
|
+
session.cancel();
|
|
214445
|
+
return true;
|
|
214446
|
+
}
|
|
214447
|
+
let cancelled = false;
|
|
214448
|
+
for (const entry of this.queued) if (entry.turnId === turnId) {
|
|
214449
|
+
entry.cancelled = true;
|
|
214450
|
+
this.wire.dispatch(cancelTurn({ turnId }));
|
|
214451
|
+
cancelled = true;
|
|
214452
|
+
}
|
|
214453
|
+
return cancelled;
|
|
214454
|
+
}
|
|
214455
|
+
/**
|
|
214456
|
+
* Agent-scope teardown (TS `taskService.dispose` parity): every Rust
|
|
214457
|
+
* session is closed — its EventSink stops forwarding, the in-flight turn
|
|
214458
|
+
* is cancelled, and background workers/pollers observe the closed flag and
|
|
214459
|
+
* kill their processes — and late engine events are ignored instead of
|
|
214460
|
+
* dispatching wire ops on a disposed wire. The DI container invokes this
|
|
214461
|
+
* when the agent scope is disposed.
|
|
214462
|
+
*/
|
|
214463
|
+
dispose() {
|
|
214464
|
+
this.disposed = true;
|
|
214465
|
+
this.approvalAbort?.abort();
|
|
214466
|
+
for (const session of this.sessions) session.close();
|
|
214467
|
+
this.sessions.clear();
|
|
214468
|
+
this.taskSessions.clear();
|
|
214469
|
+
this.engineTaskAdapters.clear();
|
|
214470
|
+
RustTurnSession.dropTaskRegistry(this.registryId);
|
|
214471
|
+
}
|
|
214472
|
+
startQueuedTurn(entry) {
|
|
214473
|
+
this.turnRunning = true;
|
|
214474
|
+
this.executingTurnId = entry.turnId;
|
|
214475
|
+
this.runTurnNow(entry.turnId, entry.payload.origin).catch(() => void 0).finally(() => {
|
|
214476
|
+
this.turnRunning = false;
|
|
214477
|
+
this.executingTurnId = void 0;
|
|
214478
|
+
if (this.disposed) {
|
|
214479
|
+
this.queued.length = 0;
|
|
214480
|
+
return;
|
|
214481
|
+
}
|
|
214482
|
+
const next = this.queued.find((queued) => !queued.cancelled);
|
|
214483
|
+
if (next === void 0) return;
|
|
214484
|
+
this.queued.splice(this.queued.indexOf(next), 1);
|
|
214485
|
+
this.startQueuedTurn(next);
|
|
214486
|
+
});
|
|
214487
|
+
}
|
|
214488
|
+
async runTurnNow(turnId, origin) {
|
|
214489
|
+
if (this.disposed) return { turnId };
|
|
214490
|
+
const messages = [{
|
|
214491
|
+
role: "system",
|
|
214492
|
+
content: this.profile.getSystemPrompt()
|
|
214493
|
+
}, ...this.context.get().map((message) => this.toLlmMessage(message))];
|
|
214494
|
+
const provider = await this.providerConfig();
|
|
214495
|
+
const inputJson = JSON.stringify({
|
|
214496
|
+
turnId,
|
|
214497
|
+
origin: toEngineTurnOrigin(origin),
|
|
214498
|
+
usesWorkerRejectionGuidance: this.scopeContext.agentId !== "main",
|
|
214499
|
+
activeTools: this.effectiveActiveTools() ?? null,
|
|
214500
|
+
messages,
|
|
214501
|
+
tools: [],
|
|
214502
|
+
provider,
|
|
214503
|
+
maxStepsPerTurn: this.maxStepsPerTurn() ?? null,
|
|
214504
|
+
maxRetriesPerStep: this.maxRetriesPerStep() ?? null,
|
|
214505
|
+
maxContextTokens: this.maxContextTokens() ?? null,
|
|
214506
|
+
nextAgentId: await this.computeNextAgentId(),
|
|
214507
|
+
killGraceMs: this.killGracePeriodMs(),
|
|
214508
|
+
completionReview: {
|
|
214509
|
+
minSteps: 10,
|
|
214510
|
+
reminder: completion_review_default
|
|
214511
|
+
},
|
|
214512
|
+
cwd: this.profile.data().cwd ?? process.cwd()
|
|
214513
|
+
});
|
|
214514
|
+
const policyJson = JSON.stringify({
|
|
214515
|
+
mode: this.modeService.mode,
|
|
214516
|
+
rules: this.rulesService.rules,
|
|
214517
|
+
sessionApprovedPatterns: this.rulesService.sessionApprovalRulePatterns
|
|
214518
|
+
});
|
|
214519
|
+
const scripted = process.env["DIMI_RUST_ENGINE_SCRIPTED"];
|
|
214520
|
+
const session = new RustTurnSession(inputJson, policyJson, scripted ?? void 0, this.registryId);
|
|
214521
|
+
this.sessions.add(session);
|
|
214522
|
+
this.activeSession = session;
|
|
214523
|
+
session.setToolGate((payloadJson) => {
|
|
214524
|
+
(async () => {
|
|
214525
|
+
const payload = JSON.parse(payloadJson);
|
|
214526
|
+
let verdict = { decision: "allow" };
|
|
214527
|
+
try {
|
|
214528
|
+
const hooksRunner = this.instantiation.invokeFunction((accessor) => accessor.get(IExternalHooksRunnerService));
|
|
214529
|
+
if (hooksRunner !== void 0 && ENGINE_NATIVE_TOOLS.has(payload.toolName)) {
|
|
214530
|
+
const block = await hooksRunner.triggerBlock("PreToolUse", {
|
|
214531
|
+
matcherValue: payload.toolName,
|
|
214532
|
+
signal: new AbortController().signal,
|
|
214533
|
+
sessionId: this.sessionContext.sessionId,
|
|
214534
|
+
inputData: {
|
|
214535
|
+
toolName: payload.toolName,
|
|
214536
|
+
toolInput: isPlainRecord(payload.arguments) ? payload.arguments : {},
|
|
214537
|
+
toolCallId: `native-${payload.toolName}`
|
|
214538
|
+
}
|
|
214539
|
+
});
|
|
214540
|
+
if (block !== void 0) verdict = {
|
|
214541
|
+
decision: "block",
|
|
214542
|
+
reason: block.reason
|
|
214543
|
+
};
|
|
214544
|
+
}
|
|
214545
|
+
} catch {}
|
|
214546
|
+
session.completeToolGate(payload.requestId, JSON.stringify(verdict));
|
|
214547
|
+
})();
|
|
214548
|
+
});
|
|
214549
|
+
try {
|
|
214550
|
+
await this.runEngineSession(session, turnId, provider["model"], origin);
|
|
214551
|
+
} finally {
|
|
214552
|
+
this.activeSession = void 0;
|
|
214553
|
+
}
|
|
214554
|
+
return { turnId };
|
|
214555
|
+
}
|
|
214556
|
+
/**
|
|
214557
|
+
* Run one engine session to completion: register the TS tool ecosystem,
|
|
214558
|
+
* drive the approval loop, mirror the engine events into the context.
|
|
214559
|
+
*/
|
|
214560
|
+
async runEngineSession(session, turnId, providerModel, origin) {
|
|
214561
|
+
const engineNativeTools = ENGINE_NATIVE_TOOLS;
|
|
214562
|
+
const activeSet = this.effectiveActiveTools();
|
|
214563
|
+
const isToolActiveForRunner = (name) => activeSet === void 0 || activeSet.includes(name);
|
|
214564
|
+
for (const info of this.toolRegistry.list()) {
|
|
214565
|
+
if (!isToolActiveForRunner(info.name)) continue;
|
|
214566
|
+
try {
|
|
214567
|
+
if (engineNativeTools.has(info.name)) {
|
|
214568
|
+
if (info.name !== "Bash") if (info.name === "WaitFor") session.registerNativeToolDef(info.name, WAIT_FOR_NATIVE_DESCRIPTION, JSON.stringify(WAIT_FOR_NATIVE_PARAMETERS));
|
|
214569
|
+
else session.registerNativeToolDef(info.name, info.description, JSON.stringify(info.parameters ?? {
|
|
214570
|
+
type: "object",
|
|
214571
|
+
properties: {}
|
|
214572
|
+
}));
|
|
214573
|
+
continue;
|
|
214574
|
+
}
|
|
214575
|
+
const tool = this.toolRegistry.resolve(info.name);
|
|
214576
|
+
if (tool === void 0) continue;
|
|
214577
|
+
session.registerExternalTool(info.name, info.description, JSON.stringify(info.parameters ?? {
|
|
214578
|
+
type: "object",
|
|
214579
|
+
properties: {}
|
|
214580
|
+
}), (payloadJson) => {
|
|
214581
|
+
(async () => {
|
|
214582
|
+
const payload = JSON.parse(payloadJson);
|
|
214583
|
+
try {
|
|
214584
|
+
const toolCalls = (payload.toolCalls ?? []).map((call) => ({
|
|
214585
|
+
type: "function",
|
|
214586
|
+
id: call.id ?? payload.toolCallId ?? payload.requestId,
|
|
214587
|
+
name: call.name,
|
|
214588
|
+
arguments: typeof call.arguments === "string" ? call.arguments : JSON.stringify(call.arguments) ?? "null"
|
|
214589
|
+
}));
|
|
214590
|
+
const execution = await tool.resolveExecution(payload.arguments, { toolCalls });
|
|
214591
|
+
if (execution.isError === true) {
|
|
214592
|
+
session.completeToolCall(payload.requestId, JSON.stringify({
|
|
214593
|
+
toolCallId: payload.toolCallId ?? payload.requestId,
|
|
214594
|
+
toolName: payload.name,
|
|
214595
|
+
output: toText(execution.output),
|
|
214596
|
+
isError: true,
|
|
214597
|
+
stopTurn: execution.stopTurn === true,
|
|
214598
|
+
updates: []
|
|
214599
|
+
}));
|
|
214600
|
+
return;
|
|
214601
|
+
}
|
|
214602
|
+
const signal = new AbortController().signal;
|
|
214603
|
+
const hooksRunner = this.instantiation.invokeFunction((accessor) => accessor.get(IExternalHooksRunnerService));
|
|
214604
|
+
const toolInput = isPlainRecord(payload.arguments) ? payload.arguments : {};
|
|
214605
|
+
const toolCallId = payload.toolCallId ?? payload.requestId;
|
|
214606
|
+
if (hooksRunner !== void 0) {
|
|
214607
|
+
const block = await hooksRunner.triggerBlock("PreToolUse", {
|
|
214608
|
+
matcherValue: payload.name,
|
|
214609
|
+
signal,
|
|
214610
|
+
sessionId: this.sessionContext.sessionId,
|
|
214611
|
+
inputData: {
|
|
214612
|
+
toolName: payload.name,
|
|
214613
|
+
toolInput,
|
|
214614
|
+
toolCallId
|
|
214615
|
+
}
|
|
214616
|
+
});
|
|
214617
|
+
if (block !== void 0) {
|
|
214618
|
+
session.completeToolCall(payload.requestId, JSON.stringify({
|
|
214619
|
+
toolCallId,
|
|
214620
|
+
toolName: payload.name,
|
|
214621
|
+
output: block.reason,
|
|
214622
|
+
isError: true,
|
|
214623
|
+
stopTurn: false,
|
|
214624
|
+
updates: []
|
|
214625
|
+
}));
|
|
214626
|
+
return;
|
|
214627
|
+
}
|
|
214628
|
+
}
|
|
214629
|
+
const result = await execution.execute({
|
|
214630
|
+
turnId: 0,
|
|
214631
|
+
toolCallId,
|
|
214632
|
+
signal,
|
|
214633
|
+
onUpdate: (update) => {
|
|
214634
|
+
if (signal.aborted) return;
|
|
214635
|
+
this.eventBus.publish({
|
|
214636
|
+
type: "tool.progress",
|
|
214637
|
+
turnId,
|
|
214638
|
+
toolCallId,
|
|
214639
|
+
update
|
|
214640
|
+
});
|
|
214641
|
+
}
|
|
214642
|
+
});
|
|
214643
|
+
let finalResult = result;
|
|
214644
|
+
const truncation = this.instantiation.invokeFunction((accessor) => accessor.get(IAgentToolResultTruncationService));
|
|
214645
|
+
if (truncation !== void 0) try {
|
|
214646
|
+
finalResult = await truncation.truncateForModel({
|
|
214647
|
+
toolName: payload.name,
|
|
214648
|
+
toolCallId,
|
|
214649
|
+
result
|
|
214650
|
+
});
|
|
214651
|
+
} catch {}
|
|
214652
|
+
session.completeToolCall(payload.requestId, JSON.stringify({
|
|
214653
|
+
toolCallId,
|
|
214654
|
+
toolName: payload.name,
|
|
214655
|
+
output: toText(finalResult.output),
|
|
214656
|
+
isError: finalResult.isError === true,
|
|
214657
|
+
stopTurn: finalResult.stopTurn === true,
|
|
214658
|
+
updates: []
|
|
214659
|
+
}));
|
|
214660
|
+
if (hooksRunner !== void 0) {
|
|
214661
|
+
const outputText = toText(finalResult.output);
|
|
214662
|
+
const isError = finalResult.isError === true;
|
|
214663
|
+
hooksRunner.fireAndForgetTrigger(isError ? "PostToolUseFailure" : "PostToolUse", {
|
|
214664
|
+
matcherValue: payload.name,
|
|
214665
|
+
signal,
|
|
214666
|
+
sessionId: this.sessionContext.sessionId,
|
|
214667
|
+
inputData: {
|
|
214668
|
+
toolName: payload.name,
|
|
214669
|
+
toolInput,
|
|
214670
|
+
toolCallId,
|
|
214671
|
+
error: isError ? toDimiErrorPayload(outputText) : void 0,
|
|
214672
|
+
toolOutput: isError ? void 0 : outputText.slice(0, 2e3)
|
|
214673
|
+
}
|
|
214674
|
+
});
|
|
214675
|
+
}
|
|
214676
|
+
} catch (error) {
|
|
214677
|
+
session.completeToolCall(payload.requestId, JSON.stringify({
|
|
214678
|
+
toolCallId: payload.toolCallId ?? payload.requestId,
|
|
214679
|
+
toolName: payload.name,
|
|
214680
|
+
output: `Tool "${payload.name}" failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
214681
|
+
isError: true,
|
|
214682
|
+
stopTurn: false,
|
|
214683
|
+
updates: []
|
|
214684
|
+
}));
|
|
214685
|
+
}
|
|
214686
|
+
})();
|
|
214687
|
+
});
|
|
214688
|
+
} catch (error) {
|
|
214689
|
+
if (engineNativeTools.has(info.name) && info.name !== "Bash") {
|
|
214690
|
+
this.log.error("[rustEngineTurnRunner] failed to register native tool def", {
|
|
214691
|
+
name: info.name,
|
|
214692
|
+
error
|
|
214693
|
+
});
|
|
214694
|
+
this.eventBus.publish({
|
|
214695
|
+
type: "turn.ended",
|
|
214696
|
+
turnId,
|
|
214697
|
+
reason: "failed",
|
|
214698
|
+
error: {
|
|
214699
|
+
name: "ToolRegistrationError",
|
|
214700
|
+
message: `Failed to register native tool def "${info.name}"`
|
|
214701
|
+
}
|
|
214702
|
+
});
|
|
214703
|
+
this.eventBus.publish({
|
|
214704
|
+
type: "error",
|
|
214705
|
+
name: "ToolRegistrationError",
|
|
214706
|
+
message: `Failed to register native tool def "${info.name}"`
|
|
214707
|
+
});
|
|
214708
|
+
throw error;
|
|
214709
|
+
}
|
|
214710
|
+
this.log.error("[rustEngineTurnRunner] failed to register external tool", {
|
|
214711
|
+
name: info.name,
|
|
214712
|
+
error
|
|
214713
|
+
});
|
|
214714
|
+
}
|
|
214715
|
+
}
|
|
214716
|
+
let stepUuid;
|
|
214717
|
+
const segments = [];
|
|
214718
|
+
let stepSawToolCall = false;
|
|
214719
|
+
const nativeToolCalls = /* @__PURE__ */ new Map();
|
|
214720
|
+
let usage = emptyUsage();
|
|
214721
|
+
const publish = (event) => {
|
|
214722
|
+
const { type, ...rest } = event;
|
|
214723
|
+
this.eventBus.publish({
|
|
214724
|
+
type,
|
|
214725
|
+
...rest
|
|
214726
|
+
});
|
|
214727
|
+
};
|
|
214728
|
+
const flushParts = (turnId, step) => {
|
|
214729
|
+
for (const segment of segments.splice(0)) {
|
|
214730
|
+
const part = segment.type === "think" ? {
|
|
214731
|
+
type: "think",
|
|
214732
|
+
think: segment.text
|
|
214733
|
+
} : {
|
|
214734
|
+
type: "text",
|
|
214735
|
+
text: segment.text
|
|
214736
|
+
};
|
|
214737
|
+
this.context.appendLoopEvent({
|
|
214738
|
+
type: "content.part",
|
|
214739
|
+
stepUuid,
|
|
214740
|
+
part,
|
|
214741
|
+
uuid: randomUUID(),
|
|
214742
|
+
turnId: String(turnId),
|
|
214743
|
+
step
|
|
214744
|
+
});
|
|
214745
|
+
}
|
|
214746
|
+
};
|
|
214747
|
+
const handleEngineEvent = (event) => {
|
|
214748
|
+
if (this.disposed) return;
|
|
214749
|
+
if (event["type"] === "task.started") {
|
|
214750
|
+
this.taskSessions.set(toText(event["taskId"]), session);
|
|
214751
|
+
this.handleTaskStarted(event);
|
|
214752
|
+
return;
|
|
214753
|
+
}
|
|
214754
|
+
if (event["type"] === "task.output") {
|
|
214755
|
+
this.handleTaskOutput(event);
|
|
214756
|
+
return;
|
|
214757
|
+
}
|
|
214758
|
+
if (event["type"] === "task.settled") {
|
|
214759
|
+
this.handleTaskSettled(event);
|
|
214760
|
+
return;
|
|
214761
|
+
}
|
|
214762
|
+
if (event["type"] === "completion.review.injected") {
|
|
214763
|
+
this.context.append({
|
|
214764
|
+
role: "user",
|
|
214765
|
+
content: [{
|
|
214766
|
+
type: "text",
|
|
214767
|
+
text: wrapSystemReminder(toText(event["reminder"]))
|
|
214768
|
+
}],
|
|
214769
|
+
toolCalls: [],
|
|
214770
|
+
origin: {
|
|
214771
|
+
kind: "system_trigger",
|
|
214772
|
+
name: "completion_review"
|
|
214773
|
+
},
|
|
214774
|
+
id: randomUUID()
|
|
214775
|
+
});
|
|
214776
|
+
return;
|
|
214777
|
+
}
|
|
214778
|
+
const busEvent = { ...event };
|
|
214779
|
+
if (event["type"] === "turn.step.completed") {
|
|
214780
|
+
const engineUsage = event["usage"];
|
|
214781
|
+
if (engineUsage !== void 0) {
|
|
214782
|
+
const inputCacheRead = engineUsage.cachedTokens ?? 0;
|
|
214783
|
+
busEvent["usage"] = {
|
|
214784
|
+
inputOther: Math.max((engineUsage.inputTokens ?? 0) - inputCacheRead, 0),
|
|
214785
|
+
output: engineUsage.outputTokens ?? 0,
|
|
214786
|
+
inputCacheRead,
|
|
214787
|
+
inputCacheCreation: 0
|
|
214788
|
+
};
|
|
214789
|
+
} else busEvent["usage"] = emptyUsage();
|
|
214790
|
+
} else if (event["type"] === "turn.ended" && event["reason"] === "failed") {
|
|
214791
|
+
const rawError = event["error"];
|
|
214792
|
+
if (rawError !== void 0) busEvent["error"] = buildErrorPayload(rawError);
|
|
214793
|
+
} else if (event["type"] === "turn.started" && !isDisplayablePromptOrigin(origin)) delete busEvent["prompt"];
|
|
214794
|
+
publish(busEvent);
|
|
214795
|
+
switch (event["type"]) {
|
|
214796
|
+
case "turn.step.started": {
|
|
214797
|
+
const stepNumber = Number(event["step"] ?? 1);
|
|
214798
|
+
stepUuid = randomUUID();
|
|
214799
|
+
stepSawToolCall = false;
|
|
214800
|
+
this.context.appendLoopEvent({
|
|
214801
|
+
type: "step.begin",
|
|
214802
|
+
uuid: stepUuid,
|
|
214803
|
+
turnId: String(turnId),
|
|
214804
|
+
step: stepNumber
|
|
214805
|
+
});
|
|
214806
|
+
break;
|
|
214807
|
+
}
|
|
214808
|
+
case "thinking.delta": {
|
|
214809
|
+
const last = segments[segments.length - 1];
|
|
214810
|
+
if (last?.type === "think") last.text += toText(event["delta"]);
|
|
214811
|
+
else segments.push({
|
|
214812
|
+
type: "think",
|
|
214813
|
+
text: toText(event["delta"])
|
|
214814
|
+
});
|
|
214815
|
+
break;
|
|
214816
|
+
}
|
|
214817
|
+
case "assistant.delta": {
|
|
214818
|
+
const last = segments[segments.length - 1];
|
|
214819
|
+
if (last?.type === "text") last.text += toText(event["delta"]);
|
|
214820
|
+
else segments.push({
|
|
214821
|
+
type: "text",
|
|
214822
|
+
text: toText(event["delta"])
|
|
214823
|
+
});
|
|
214824
|
+
break;
|
|
214825
|
+
}
|
|
214826
|
+
case "tool.call.delta": break;
|
|
214827
|
+
case "tool.call.started": {
|
|
214828
|
+
const id = toText(event["toolCallId"]);
|
|
214829
|
+
const name = toText(event["name"]);
|
|
214830
|
+
stepSawToolCall = true;
|
|
214831
|
+
if (ENGINE_NATIVE_TOOLS.has(name)) nativeToolCalls.set(id, {
|
|
214832
|
+
name,
|
|
214833
|
+
input: event["args"]
|
|
214834
|
+
});
|
|
214835
|
+
this.context.appendLoopEvent({
|
|
214836
|
+
type: "tool.call",
|
|
214837
|
+
stepUuid,
|
|
214838
|
+
toolCallId: id,
|
|
214839
|
+
name,
|
|
214840
|
+
args: event["args"],
|
|
214841
|
+
uuid: randomUUID(),
|
|
214842
|
+
turnId: String(turnId),
|
|
214843
|
+
step: Number(event["step"] ?? 1)
|
|
214844
|
+
});
|
|
214845
|
+
break;
|
|
214846
|
+
}
|
|
214847
|
+
case "tool.result": {
|
|
214848
|
+
const id = toText(event["toolCallId"]);
|
|
214849
|
+
const output = toText(event["output"]);
|
|
214850
|
+
const isError = event["isError"] === true;
|
|
214851
|
+
const native = nativeToolCalls.get(id);
|
|
214852
|
+
if (native !== void 0) {
|
|
214853
|
+
nativeToolCalls.delete(id);
|
|
214854
|
+
const hooksRunner = this.instantiation.invokeFunction((accessor) => accessor.get(IExternalHooksRunnerService));
|
|
214855
|
+
if (hooksRunner !== void 0) hooksRunner.fireAndForgetTrigger(isError ? "PostToolUseFailure" : "PostToolUse", {
|
|
214856
|
+
matcherValue: native.name,
|
|
214857
|
+
signal: new AbortController().signal,
|
|
214858
|
+
sessionId: this.sessionContext.sessionId,
|
|
214859
|
+
inputData: {
|
|
214860
|
+
toolName: native.name,
|
|
214861
|
+
toolInput: isPlainRecord(native.input) ? native.input : {},
|
|
214862
|
+
toolCallId: id,
|
|
214863
|
+
error: isError ? toDimiErrorPayload(output) : void 0,
|
|
214864
|
+
toolOutput: isError ? void 0 : output.slice(0, 2e3)
|
|
214865
|
+
}
|
|
214866
|
+
});
|
|
214867
|
+
}
|
|
214868
|
+
this.context.appendLoopEvent({
|
|
214869
|
+
type: "tool.result",
|
|
214870
|
+
toolCallId: id,
|
|
214871
|
+
result: {
|
|
214872
|
+
output,
|
|
214873
|
+
isError
|
|
214874
|
+
},
|
|
214875
|
+
parentUuid: stepUuid
|
|
214876
|
+
});
|
|
214877
|
+
break;
|
|
214878
|
+
}
|
|
214879
|
+
case "context.compacted": {
|
|
214880
|
+
const summary = toText(event["summary"]);
|
|
214881
|
+
const tokensBefore = Number(event["tokensBefore"] ?? 0);
|
|
214882
|
+
const compactedCount = Number(event["compactedCount"] ?? 0);
|
|
214883
|
+
this.wire.dispatch(fullCompactionBegin({ source: "auto" }));
|
|
214884
|
+
const result = this.context.applyCompaction({
|
|
214885
|
+
summary,
|
|
214886
|
+
contextSummary: buildCompactionSummaryText(summary),
|
|
214887
|
+
compactedCount,
|
|
214888
|
+
tokensBefore
|
|
214889
|
+
});
|
|
214890
|
+
this.wire.dispatch(fullCompactionComplete({}));
|
|
214891
|
+
this.eventBus.publish({
|
|
214892
|
+
type: "compaction.completed",
|
|
214893
|
+
result
|
|
214894
|
+
});
|
|
214895
|
+
break;
|
|
214896
|
+
}
|
|
214897
|
+
case "turn.step.interrupted":
|
|
214898
|
+
if (stepSawToolCall) flushParts(turnId, Number(event["step"] ?? 1));
|
|
214899
|
+
break;
|
|
214900
|
+
case "turn.step.completed": {
|
|
214901
|
+
const stepFinish = toText(event["finishReason"] ?? "end_turn");
|
|
214902
|
+
const stepNumber = Number(event["step"] ?? 1);
|
|
214903
|
+
flushParts(turnId, stepNumber);
|
|
214904
|
+
const engineUsage = event["usage"];
|
|
214905
|
+
if (engineUsage !== void 0) {
|
|
214906
|
+
const inputCacheRead = engineUsage.cachedTokens ?? 0;
|
|
214907
|
+
usage = {
|
|
214908
|
+
inputOther: Math.max((engineUsage.inputTokens ?? 0) - inputCacheRead, 0),
|
|
214909
|
+
output: engineUsage.outputTokens ?? 0,
|
|
214910
|
+
inputCacheRead,
|
|
214911
|
+
inputCacheCreation: 0
|
|
214912
|
+
};
|
|
214913
|
+
} else usage = emptyUsage();
|
|
214914
|
+
this.usageService.record(providerModel, usage, {
|
|
214915
|
+
kind: "loop",
|
|
214916
|
+
turnId: String(turnId),
|
|
214917
|
+
step: stepNumber
|
|
214918
|
+
});
|
|
214919
|
+
this.context.appendLoopEvent({
|
|
214920
|
+
type: "step.end",
|
|
214921
|
+
uuid: stepUuid,
|
|
214922
|
+
turnId: String(turnId),
|
|
214923
|
+
step: stepNumber,
|
|
214924
|
+
finishReason: stepFinish,
|
|
214925
|
+
usage
|
|
214926
|
+
});
|
|
214927
|
+
if (stepFinish !== "tool_use" && stepFinish !== "filtered") this.runStopHook(turnId);
|
|
214928
|
+
break;
|
|
214929
|
+
}
|
|
214930
|
+
case "turn.ended":
|
|
214931
|
+
this.stopHookContinuationUsed = false;
|
|
214932
|
+
if (event["reason"] === "failed" && event["error"] !== void 0) this.eventBus.publish({
|
|
214933
|
+
type: "error",
|
|
214934
|
+
...buildErrorPayload(event["error"])
|
|
214935
|
+
});
|
|
214936
|
+
break;
|
|
214937
|
+
default: break;
|
|
214938
|
+
}
|
|
214939
|
+
};
|
|
214940
|
+
session.setOnEvent((eventJson) => {
|
|
214941
|
+
try {
|
|
214942
|
+
handleEngineEvent(JSON.parse(eventJson));
|
|
214943
|
+
} catch (error) {
|
|
214944
|
+
this.log.error("[rustEngineTurnRunner] failed to process engine event", { error });
|
|
214945
|
+
}
|
|
214946
|
+
});
|
|
214947
|
+
let progress = JSON.parse(await session.run());
|
|
214948
|
+
while (progress.progress.status === "needsApproval") {
|
|
214949
|
+
const approval = progress.progress.approval;
|
|
214950
|
+
const approvalRequest = {
|
|
214951
|
+
sessionId: this.sessionContext.sessionId,
|
|
214952
|
+
agentId: this.scopeContext.agentId,
|
|
214953
|
+
turnId,
|
|
214954
|
+
toolCallId: approval.toolCallId,
|
|
214955
|
+
toolName: approval.toolName,
|
|
214956
|
+
action: `Approve ${approval.toolName}`,
|
|
214957
|
+
display: {
|
|
214958
|
+
kind: "generic",
|
|
214959
|
+
summary: `Approve ${approval.toolName}`,
|
|
214960
|
+
detail: approval.toolInput
|
|
214961
|
+
}
|
|
214962
|
+
};
|
|
214963
|
+
this.eventBus.publish({
|
|
214964
|
+
type: "permission.approval.requested",
|
|
214965
|
+
...approvalRequest
|
|
214966
|
+
});
|
|
214967
|
+
let response = { decision: "approved" };
|
|
214968
|
+
const approvalController = new AbortController();
|
|
214969
|
+
this.approvalAbort = approvalController;
|
|
214970
|
+
try {
|
|
214971
|
+
const approvalService = this.instantiation.invokeFunction((accessor) => accessor.get(ISessionApprovalService));
|
|
214972
|
+
response = approvalService !== void 0 ? await Promise.race([approvalService.request(approvalRequest), abortOnSignal(approvalController.signal).then(() => ({ decision: "cancelled" }))]) : { decision: "approved" };
|
|
214973
|
+
} catch {
|
|
214974
|
+
response = { decision: "rejected" };
|
|
214975
|
+
} finally {
|
|
214976
|
+
this.approvalAbort = void 0;
|
|
214977
|
+
}
|
|
214978
|
+
this.eventBus.publish({
|
|
214979
|
+
type: "permission.approval.resolved",
|
|
214980
|
+
...approvalRequest,
|
|
214981
|
+
decision: response.decision
|
|
214982
|
+
});
|
|
214983
|
+
this.rulesService.recordApprovalResult({
|
|
214984
|
+
turnId,
|
|
214985
|
+
toolCallId: approvalRequest.toolCallId,
|
|
214986
|
+
toolName: approvalRequest.toolName,
|
|
214987
|
+
action: approvalRequest.action,
|
|
214988
|
+
sessionApprovalRule: response.decision === "approved" && response.scope === "session" ? approvalRequest.toolName : void 0,
|
|
214989
|
+
result: response
|
|
214990
|
+
});
|
|
214991
|
+
if (response.decision === "approved" && response.scope === "session") session.addSessionApproval(approvalRequest.toolName);
|
|
214992
|
+
progress = JSON.parse(await session.resume(JSON.stringify(response)));
|
|
214993
|
+
}
|
|
214994
|
+
}
|
|
214995
|
+
/**
|
|
214996
|
+
* TS `externalHooksService.runStop` parity (P1-3): after a non-tool step,
|
|
214997
|
+
* fire the Stop hook; a returned reason becomes a continuation message
|
|
214998
|
+
* (origin `system_trigger`/`stop_hook`) that keeps the turn alive —
|
|
214999
|
+
* steered into the running turn, or launched as a fresh turn when the
|
|
215000
|
+
* engine already finished (the task-notification fallback). Fires at most
|
|
215001
|
+
* once after a continuation was used, mirroring `stopHookContinuationUsed`.
|
|
215002
|
+
*/
|
|
215003
|
+
runStopHook(turnId) {
|
|
215004
|
+
if (this.stopHookContinuationUsed) return;
|
|
215005
|
+
this.stopHookContinuationUsed = true;
|
|
215006
|
+
const hooksRunner = this.instantiation.invokeFunction((accessor) => accessor.get(IExternalHooksRunnerService));
|
|
215007
|
+
if (hooksRunner === void 0) return;
|
|
215008
|
+
(async () => {
|
|
215009
|
+
try {
|
|
215010
|
+
const reason = (await hooksRunner.triggerBlock("Stop", {
|
|
215011
|
+
signal: new AbortController().signal,
|
|
215012
|
+
sessionId: this.sessionContext.sessionId,
|
|
215013
|
+
inputData: { stopHookActive: false }
|
|
215014
|
+
}))?.reason;
|
|
215015
|
+
if (reason === void 0 || reason.length === 0) return;
|
|
215016
|
+
const origin = {
|
|
215017
|
+
kind: "system_trigger",
|
|
215018
|
+
name: "stop_hook"
|
|
215019
|
+
};
|
|
215020
|
+
if (this.turnRunning && this.activeSession !== void 0 && this.activeSession.steer(reason)) {
|
|
215021
|
+
this.context.append({
|
|
215022
|
+
role: "user",
|
|
215023
|
+
content: [{
|
|
215024
|
+
type: "text",
|
|
215025
|
+
text: reason
|
|
215026
|
+
}],
|
|
215027
|
+
toolCalls: [],
|
|
215028
|
+
origin,
|
|
215029
|
+
id: randomUUID()
|
|
215030
|
+
});
|
|
215031
|
+
this.wire.dispatch(steerTurn({
|
|
215032
|
+
input: [{
|
|
215033
|
+
type: "text",
|
|
215034
|
+
text: reason
|
|
215035
|
+
}],
|
|
215036
|
+
origin
|
|
215037
|
+
}));
|
|
215038
|
+
} else this.runTurn({
|
|
215039
|
+
input: [{
|
|
215040
|
+
type: "text",
|
|
215041
|
+
text: reason
|
|
215042
|
+
}],
|
|
215043
|
+
origin
|
|
215044
|
+
}).catch(() => void 0);
|
|
215045
|
+
} catch {}
|
|
215046
|
+
})();
|
|
215047
|
+
}
|
|
215048
|
+
/**
|
|
215049
|
+
* `task.started` (engine transport) → TS records: the persisted
|
|
215050
|
+
* `task.started` wire op (TaskModel / transcript / TaskList) plus the
|
|
215051
|
+
* `subagent.spawned` session event for subagent launches.
|
|
215052
|
+
*/
|
|
215053
|
+
handleTaskStarted(event) {
|
|
215054
|
+
const taskId = toText(event["taskId"]);
|
|
215055
|
+
const agentId = toText(event["agentId"]);
|
|
215056
|
+
const kind = toText(event["kind"]);
|
|
215057
|
+
const description = toText(event["description"]);
|
|
215058
|
+
const startedAt = Date.now();
|
|
215059
|
+
const pid = toOptionalNumber(event["pid"]);
|
|
215060
|
+
this.taskInfos.set(taskId, {
|
|
215061
|
+
description,
|
|
215062
|
+
startedAt,
|
|
215063
|
+
pid
|
|
215064
|
+
});
|
|
215065
|
+
if (kind === "agent" && agentId !== "") this.engineAgentIds.add(agentId);
|
|
215066
|
+
const info = kind === "agent" ? {
|
|
215067
|
+
taskId,
|
|
215068
|
+
kind: "agent",
|
|
215069
|
+
agentId,
|
|
215070
|
+
subagentType: description,
|
|
215071
|
+
description,
|
|
215072
|
+
status: "running",
|
|
215073
|
+
detached: true,
|
|
215074
|
+
startedAt,
|
|
215075
|
+
endedAt: null
|
|
215076
|
+
} : {
|
|
215077
|
+
taskId,
|
|
215078
|
+
kind: "process",
|
|
215079
|
+
command: description,
|
|
215080
|
+
pid: pid ?? 0,
|
|
215081
|
+
exitCode: null,
|
|
215082
|
+
description,
|
|
215083
|
+
status: "running",
|
|
215084
|
+
detached: true,
|
|
215085
|
+
startedAt,
|
|
215086
|
+
endedAt: null
|
|
215087
|
+
};
|
|
215088
|
+
this.wire.dispatch(taskStarted({ info }));
|
|
215089
|
+
this.registerEngineTask(taskId, agentId, kind, description, pid);
|
|
215090
|
+
if (kind === "agent") {
|
|
215091
|
+
this.eventBus.publish({
|
|
215092
|
+
type: "subagent.spawned",
|
|
215093
|
+
subagentId: agentId,
|
|
215094
|
+
subagentName: description,
|
|
215095
|
+
parentToolCallId: toText(event["parentToolCallId"]),
|
|
215096
|
+
parentAgentId: this.scopeContext.agentId,
|
|
215097
|
+
callerAgentId: this.scopeContext.agentId,
|
|
215098
|
+
description,
|
|
215099
|
+
runInBackground: false
|
|
215100
|
+
});
|
|
215101
|
+
this.eventBus.publish({
|
|
215102
|
+
type: "subagent.started",
|
|
215103
|
+
subagentId: agentId
|
|
215104
|
+
});
|
|
215105
|
+
}
|
|
215106
|
+
}
|
|
215107
|
+
/**
|
|
215108
|
+
* `task.output` (engine transport) → the task-service entry's live sink:
|
|
215109
|
+
* append the streamed delta so TaskOutput shows partial output while the
|
|
215110
|
+
* engine task is still running (TS ProcessTask parity — TS streams chunks
|
|
215111
|
+
* as they arrive; the adapter's settle also appends only the not-yet-
|
|
215112
|
+
* streamed tail, so nothing is duplicated). No wire op / bus event: the
|
|
215113
|
+
* live output is the service's retained buffer, the wire `task.terminated`
|
|
215114
|
+
* tail comes from the settle's full output.
|
|
215115
|
+
*/
|
|
215116
|
+
handleTaskOutput(event) {
|
|
215117
|
+
const taskId = toText(event["taskId"]);
|
|
215118
|
+
const delta = toText(event["delta"]);
|
|
215119
|
+
if (delta.length === 0) return;
|
|
215120
|
+
const adapter = this.engineTaskAdapters.get(taskId);
|
|
215121
|
+
if (adapter !== void 0) {
|
|
215122
|
+
adapter.appendOutput(delta);
|
|
215123
|
+
return;
|
|
215124
|
+
}
|
|
215125
|
+
this.log.debug("[rustEngineTurnRunner] task.output for unregistered task", { taskId });
|
|
215126
|
+
}
|
|
215127
|
+
/**
|
|
215128
|
+
* Register an engine background task with `IAgentTaskService` (TaskList /
|
|
215129
|
+
* TaskStop / TaskOutput parity). The adapter bridges TaskStop into the
|
|
215130
|
+
* engine's per-task cancel (`session.cancelTask`) — the launching session's
|
|
215131
|
+
* worker/poller kills its work and settles "killed" — and its `start`
|
|
215132
|
+
* streams the settle output into the service's sink so TaskOutput and the
|
|
215133
|
+
* terminal info see it.
|
|
215134
|
+
*/
|
|
215135
|
+
registerEngineTask(taskId, agentId, kind, description, pid) {
|
|
215136
|
+
const session = this.taskSessions.get(taskId) ?? this.activeSession;
|
|
215137
|
+
const adapter = new EngineTaskAdapter({
|
|
215138
|
+
taskId,
|
|
215139
|
+
agentId,
|
|
215140
|
+
kind: kind === "agent" ? "agent" : "process",
|
|
215141
|
+
description,
|
|
215142
|
+
pid,
|
|
215143
|
+
subagentType: kind === "agent" ? description : void 0,
|
|
215144
|
+
forceStop: (reason) => {
|
|
215145
|
+
try {
|
|
215146
|
+
session?.cancelTask(taskId, reason);
|
|
215147
|
+
} catch (error) {
|
|
215148
|
+
this.log.error("[rustEngineTurnRunner] failed to cancel engine task", {
|
|
215149
|
+
taskId,
|
|
215150
|
+
error
|
|
215151
|
+
});
|
|
215152
|
+
}
|
|
215153
|
+
}
|
|
215154
|
+
});
|
|
215155
|
+
this.engineTaskAdapters.set(taskId, adapter);
|
|
215156
|
+
try {
|
|
215157
|
+
this.tasks.registerTask(adapter, {
|
|
215158
|
+
taskId,
|
|
215159
|
+
detached: false
|
|
215160
|
+
});
|
|
215161
|
+
} catch (error) {
|
|
215162
|
+
this.log.error("[rustEngineTurnRunner] failed to register engine task", {
|
|
215163
|
+
taskId,
|
|
215164
|
+
error
|
|
215165
|
+
});
|
|
215166
|
+
this.engineTaskAdapters.delete(taskId);
|
|
215167
|
+
}
|
|
215168
|
+
}
|
|
215169
|
+
/**
|
|
215170
|
+
* `task.settled` (engine transport) → TS records: the persisted
|
|
215171
|
+
* `task.terminated` wire op (bounded output tail), the `subagent.completed`
|
|
215172
|
+
* / `subagent.failed` session events, and the completion notification
|
|
215173
|
+
* delivered to the model (context message + `task.notified` + steer/new
|
|
215174
|
+
* turn — TS `activeOrNewTurn` parity).
|
|
215175
|
+
*/
|
|
215176
|
+
handleTaskSettled(event) {
|
|
215177
|
+
const taskId = toText(event["taskId"]);
|
|
215178
|
+
const agentId = toText(event["agentId"]);
|
|
215179
|
+
const kind = toText(event["kind"]);
|
|
215180
|
+
const status = toText(event["status"]);
|
|
215181
|
+
const output = toText(event["output"]);
|
|
215182
|
+
const error = event["error"] === void 0 || event["error"] === null ? void 0 : toText(event["error"]);
|
|
215183
|
+
const launch = this.taskInfos.get(taskId);
|
|
215184
|
+
const endedAt = Date.now();
|
|
215185
|
+
const stopReason = status === "failed" || status === "timed_out" || status === "killed" ? error : void 0;
|
|
215186
|
+
const base = {
|
|
215187
|
+
taskId,
|
|
215188
|
+
description: launch?.description ?? "",
|
|
215189
|
+
status,
|
|
215190
|
+
detached: true,
|
|
215191
|
+
startedAt: launch?.startedAt ?? endedAt,
|
|
215192
|
+
endedAt,
|
|
215193
|
+
stopReason
|
|
215194
|
+
};
|
|
215195
|
+
const info = kind === "agent" ? {
|
|
215196
|
+
...base,
|
|
215197
|
+
kind: "agent",
|
|
215198
|
+
agentId,
|
|
215199
|
+
subagentType: launch?.description ?? ""
|
|
215200
|
+
} : {
|
|
215201
|
+
...base,
|
|
215202
|
+
kind: "process",
|
|
215203
|
+
command: launch?.description ?? "",
|
|
215204
|
+
pid: launch?.pid ?? 0,
|
|
215205
|
+
exitCode: toOptionalNumber(event["exitCode"]) ?? null
|
|
215206
|
+
};
|
|
215207
|
+
this.wire.dispatch(taskTerminated({
|
|
215208
|
+
info,
|
|
215209
|
+
outputTail: output.slice(-TERMINAL_OUTPUT_TAIL_CHARS)
|
|
215210
|
+
}));
|
|
215211
|
+
if (kind === "agent") {
|
|
215212
|
+
if (status === "completed") this.eventBus.publish({
|
|
215213
|
+
type: "subagent.completed",
|
|
215214
|
+
subagentId: agentId,
|
|
215215
|
+
resultSummary: output
|
|
215216
|
+
});
|
|
215217
|
+
else if (status === "failed") this.eventBus.publish({
|
|
215218
|
+
type: "subagent.failed",
|
|
215219
|
+
subagentId: agentId,
|
|
215220
|
+
error: error ?? status
|
|
215221
|
+
});
|
|
215222
|
+
}
|
|
215223
|
+
const adapter = this.engineTaskAdapters.get(taskId);
|
|
215224
|
+
if (adapter !== void 0) {
|
|
215225
|
+
adapter.complete(output, {
|
|
215226
|
+
status,
|
|
215227
|
+
stopReason
|
|
215228
|
+
}, toOptionalNumber(event["exitCode"]));
|
|
215229
|
+
this.engineTaskAdapters.delete(taskId);
|
|
215230
|
+
}
|
|
215231
|
+
this.taskInfos.delete(taskId);
|
|
215232
|
+
this.taskSessions.delete(taskId);
|
|
215233
|
+
if (this.tasks.getTask(taskId)?.terminalNotificationSuppressed === true) return;
|
|
215234
|
+
this.deliverTaskNotification({
|
|
215235
|
+
taskId,
|
|
215236
|
+
agentId,
|
|
215237
|
+
kind,
|
|
215238
|
+
status,
|
|
215239
|
+
description: launch?.description ?? "",
|
|
215240
|
+
output,
|
|
215241
|
+
error
|
|
215242
|
+
});
|
|
215243
|
+
}
|
|
215244
|
+
/**
|
|
215245
|
+
* Deliver a task completion notification to the model — the Rust-engine
|
|
215246
|
+
* equivalent of the TS task domain's detached-task notification
|
|
215247
|
+
* (`TaskNotificationStepRequest`, `activeOrNewTurn` admission): append the
|
|
215248
|
+
* `<notification>` XML as a task-origin user message, fire the
|
|
215249
|
+
* `task.notified` hook event, then fold it into the running turn's next
|
|
215250
|
+
* step (steer) or launch a notification turn when idle.
|
|
215251
|
+
*/
|
|
215252
|
+
deliverTaskNotification(task) {
|
|
215253
|
+
const key = `task:${task.taskId}:${task.status}`;
|
|
215254
|
+
if (this.deliveredNotificationKeys.has(key)) return;
|
|
215255
|
+
this.deliveredNotificationKeys.add(key);
|
|
215256
|
+
const kindLabel = task.kind === "agent" ? "agent" : "process";
|
|
215257
|
+
const notification = {
|
|
215258
|
+
id: key,
|
|
215259
|
+
category: "task",
|
|
215260
|
+
type: `task.${task.status}`,
|
|
215261
|
+
source_kind: "background_task",
|
|
215262
|
+
source_id: task.taskId,
|
|
215263
|
+
agent_id: task.kind === "agent" ? task.agentId : void 0,
|
|
215264
|
+
title: `Background ${kindLabel} ${task.status}`,
|
|
215265
|
+
severity: task.status === "completed" ? "info" : "warning",
|
|
215266
|
+
body: buildTaskNotificationBody(task),
|
|
215267
|
+
children: task.output.length > 0 ? [renderOutputPreviewBlock(task.output)] : void 0
|
|
215268
|
+
};
|
|
215269
|
+
const xml = renderNotificationXml(notification);
|
|
215270
|
+
const origin = {
|
|
215271
|
+
kind: "task",
|
|
215272
|
+
taskId: task.taskId,
|
|
215273
|
+
status: task.status,
|
|
215274
|
+
notificationId: key
|
|
215275
|
+
};
|
|
215276
|
+
try {
|
|
215277
|
+
if (this.turnRunning && this.activeSession !== void 0 && this.activeSession.steer(xml)) {
|
|
215278
|
+
this.context.append({
|
|
215279
|
+
role: "user",
|
|
215280
|
+
content: [{
|
|
215281
|
+
type: "text",
|
|
215282
|
+
text: xml
|
|
215283
|
+
}],
|
|
215284
|
+
toolCalls: [],
|
|
215285
|
+
origin,
|
|
215286
|
+
id: randomUUID()
|
|
215287
|
+
});
|
|
215288
|
+
this.wire.dispatch(steerTurn({
|
|
215289
|
+
input: [{
|
|
215290
|
+
type: "text",
|
|
215291
|
+
text: xml
|
|
215292
|
+
}],
|
|
215293
|
+
origin
|
|
215294
|
+
}));
|
|
215295
|
+
} else this.runTurn({
|
|
215296
|
+
input: [{
|
|
215297
|
+
type: "text",
|
|
215298
|
+
text: xml
|
|
215299
|
+
}],
|
|
215300
|
+
origin
|
|
215301
|
+
}).catch(() => void 0);
|
|
215302
|
+
this.eventBus.publish({
|
|
215303
|
+
type: "task.notified",
|
|
215304
|
+
notificationType: `task.${task.status}`,
|
|
215305
|
+
title: notification.title,
|
|
215306
|
+
body: notification.body,
|
|
215307
|
+
severity: notification.severity,
|
|
215308
|
+
sourceKind: notification.source_kind,
|
|
215309
|
+
sourceId: notification.source_id
|
|
215310
|
+
});
|
|
215311
|
+
} finally {
|
|
215312
|
+
this.deliveredNotificationKeys.delete(key);
|
|
215313
|
+
}
|
|
215314
|
+
}
|
|
215315
|
+
toLlmMessage(message) {
|
|
215316
|
+
const text = message.content.filter((part) => part.type === "text").map((part) => part.text ?? "").join("");
|
|
215317
|
+
const media = message.content.filter((part) => part.type === "image_url" || part.type === "audio_url" || part.type === "video_url").map((part) => {
|
|
215318
|
+
return {
|
|
215319
|
+
type: "media_url",
|
|
215320
|
+
url: part.imageUrl?.url ?? part.audioUrl?.url ?? part.videoUrl?.url
|
|
215321
|
+
};
|
|
215322
|
+
}).filter((part) => part.url !== void 0);
|
|
215323
|
+
const toolCalls = message.toolCalls.map((call) => ({
|
|
215324
|
+
id: call.id,
|
|
215325
|
+
type: "function",
|
|
215326
|
+
function: {
|
|
215327
|
+
name: call.name,
|
|
215328
|
+
arguments: call.arguments
|
|
215329
|
+
}
|
|
215330
|
+
}));
|
|
215331
|
+
return {
|
|
215332
|
+
role: message.role,
|
|
215333
|
+
content: media.length > 0 ? [...media, ...text.length > 0 ? [{
|
|
215334
|
+
type: "text",
|
|
215335
|
+
text
|
|
215336
|
+
}] : []] : text,
|
|
215337
|
+
...message.role === "assistant" && toolCalls.length > 0 ? { toolCalls } : {},
|
|
215338
|
+
...message.role === "tool" && message.toolCallId !== void 0 ? { toolCallId: message.toolCallId } : {}
|
|
215339
|
+
};
|
|
215340
|
+
}
|
|
215341
|
+
/**
|
|
215342
|
+
* The next subagent agent-id number to hand to the engine for this turn
|
|
215343
|
+
* (TS `nextAvailableAgentId` parity): the max known `agent-<n>` suffix
|
|
215344
|
+
* among (a) the ids this runner's engine has already handed out across
|
|
215345
|
+
* turns and (b) the session's persisted agents, plus one. The engine seeds
|
|
215346
|
+
* its per-session counter from it, so ids stay monotonic across turns and
|
|
215347
|
+
* server restarts and never collide with TS-assigned ids.
|
|
215348
|
+
*/
|
|
215349
|
+
async computeNextAgentId() {
|
|
215350
|
+
let maxSuffix = -1;
|
|
215351
|
+
const consider = (id) => {
|
|
215352
|
+
const match = /^agent-(\d+)$/.exec(id);
|
|
215353
|
+
if (match !== null) maxSuffix = Math.max(maxSuffix, Number(match[1]));
|
|
215354
|
+
};
|
|
215355
|
+
for (const id of this.engineAgentIds) consider(id);
|
|
215356
|
+
try {
|
|
215357
|
+
const persisted = (await this.sessionMetadata.read()).agents ?? {};
|
|
215358
|
+
for (const id of Object.keys(persisted)) consider(id);
|
|
215359
|
+
} catch {
|
|
215360
|
+
this.log.warn("[rustEngineTurnRunner] failed to read session metadata; seeding next agent id from in-session engine ids only");
|
|
215361
|
+
}
|
|
215362
|
+
return maxSuffix + 1;
|
|
215363
|
+
}
|
|
215364
|
+
maxStepsPerTurn() {
|
|
215365
|
+
return this.config.get("loop_control")?.maxStepsPerTurn;
|
|
215366
|
+
}
|
|
215367
|
+
/**
|
|
215368
|
+
* The effective engine-side tool allowlist (TS `isToolActiveComposed`
|
|
215369
|
+
* parity): the runner's `IAgentToolPolicyService.isToolActive` composes
|
|
215370
|
+
* the profile allowlist/denylist, the global `[tools]` config, and the
|
|
215371
|
+
* session denylist — with MCP glob semantics for `mcp__*` tools. AllDone
|
|
215372
|
+
* stays active regardless (the completion-review protocol needs it).
|
|
215373
|
+
* `undefined` = unconstrained (all tools).
|
|
215374
|
+
*/
|
|
215375
|
+
effectiveActiveTools() {
|
|
215376
|
+
const all = this.toolRegistry.list().map((info) => info.name);
|
|
215377
|
+
const active = all.filter((name) => {
|
|
215378
|
+
if (name === "AllDone") return true;
|
|
215379
|
+
return this.toolPolicy.isToolActive(name);
|
|
215380
|
+
});
|
|
215381
|
+
return active.length === all.length ? void 0 : active;
|
|
215382
|
+
}
|
|
215383
|
+
maxRetriesPerStep() {
|
|
215384
|
+
return this.config.get("loop_control")?.maxRetriesPerStep;
|
|
215385
|
+
}
|
|
215386
|
+
killGracePeriodMs() {
|
|
215387
|
+
return resolveAgentTaskConfig(this.config)?.killGracePeriodMs ?? 5e3;
|
|
215388
|
+
}
|
|
215389
|
+
maxContextTokens() {
|
|
215390
|
+
const capability = this.profile.data().modelCapabilities;
|
|
215391
|
+
const max = capability.max_input_tokens ?? capability.max_context_tokens;
|
|
215392
|
+
return max > 0 ? max : void 0;
|
|
215393
|
+
}
|
|
215394
|
+
async providerConfig() {
|
|
215395
|
+
const modelAlias = this.profile.data().modelAlias ?? this.profile.getModel();
|
|
215396
|
+
let baseUrl = "";
|
|
215397
|
+
let apiKey = "";
|
|
215398
|
+
let modelId = modelAlias || "gpt-4o";
|
|
215399
|
+
try {
|
|
215400
|
+
const model = this.modelCatalog.get(modelAlias);
|
|
215401
|
+
baseUrl = model.baseUrl;
|
|
215402
|
+
apiKey = (await this.providerRuntime.getAuth(model))?.auth.apiKey ?? "";
|
|
215403
|
+
modelId = model.id;
|
|
215404
|
+
} catch {}
|
|
215405
|
+
return {
|
|
215406
|
+
baseUrl: baseUrl || "https://api.openai.com/v1",
|
|
215407
|
+
apiKey,
|
|
215408
|
+
model: modelId,
|
|
215409
|
+
thinkingEffort: this.profile.getEffectiveThinkingLevel()
|
|
215410
|
+
};
|
|
215411
|
+
}
|
|
215412
|
+
};
|
|
215413
|
+
RustEngineTurnRunner = __decorate$1([
|
|
215414
|
+
__decorateParam(0, IAgentContextMemoryService),
|
|
215415
|
+
__decorateParam(1, IEventBus),
|
|
215416
|
+
__decorateParam(2, IWireService),
|
|
215417
|
+
__decorateParam(3, IConfigService),
|
|
215418
|
+
__decorateParam(4, IAgentPermissionModeService),
|
|
215419
|
+
__decorateParam(5, IAgentPermissionRulesService),
|
|
215420
|
+
__decorateParam(6, IAgentToolRegistryService),
|
|
215421
|
+
__decorateParam(7, IAgentUsageService),
|
|
215422
|
+
__decorateParam(8, IAgentProfileService),
|
|
215423
|
+
__decorateParam(9, IAgentScopeContext),
|
|
215424
|
+
__decorateParam(10, ISessionContext),
|
|
215425
|
+
__decorateParam(11, ISessionMetadata),
|
|
215426
|
+
__decorateParam(12, IAgentTaskService),
|
|
215427
|
+
__decorateParam(13, IModelCatalog),
|
|
215428
|
+
__decorateParam(14, IProviderRuntime),
|
|
215429
|
+
__decorateParam(15, IInstantiationService),
|
|
215430
|
+
__decorateParam(16, IAgentToolPolicyService),
|
|
215431
|
+
__decorateParam(17, ILogService)
|
|
215432
|
+
], RustEngineTurnRunner);
|
|
215433
|
+
registerScopedService(2, IRustEngineTurnRunner, RustEngineTurnRunner, 0, "rustEngineTurnRunner");
|
|
215434
|
+
}));
|
|
215435
|
+
//#endregion
|
|
213604
215436
|
//#region ../../packages/agent-core-v2/src/agent/rpc/prompt-metadata.ts
|
|
213605
215437
|
function promptMetadataTextFromPayload(payload) {
|
|
213606
215438
|
return promptMetadataTextFromContentParts(payload.input);
|
|
@@ -213669,6 +215501,7 @@ var init_rpcService = __esmMin((() => {
|
|
|
213669
215501
|
init_telemetry$2();
|
|
213670
215502
|
init_toolRegistry();
|
|
213671
215503
|
init_loop();
|
|
215504
|
+
init_rustEngineTurnRunner();
|
|
213672
215505
|
init_rpc$2();
|
|
213673
215506
|
init_prompt_metadata();
|
|
213674
215507
|
init_decorateParam();
|
|
@@ -213692,7 +215525,8 @@ var init_rpcService = __esmMin((() => {
|
|
|
213692
215525
|
sessionContext;
|
|
213693
215526
|
scopeContext;
|
|
213694
215527
|
agentLifecycle;
|
|
213695
|
-
|
|
215528
|
+
rustEngineTurnRunner;
|
|
215529
|
+
constructor(promptService, conversationUndo, loop, toolPolicy, permissionMode, fullCompaction, toolRegistry, context, contextSize, skills, telemetry, eventBus, eventService, plugins, metadata, sessionContext, scopeContext, agentLifecycle, rustEngineTurnRunner) {
|
|
213696
215530
|
this.promptService = promptService;
|
|
213697
215531
|
this.conversationUndo = conversationUndo;
|
|
213698
215532
|
this.loop = loop;
|
|
@@ -213711,6 +215545,7 @@ var init_rpcService = __esmMin((() => {
|
|
|
213711
215545
|
this.sessionContext = sessionContext;
|
|
213712
215546
|
this.scopeContext = scopeContext;
|
|
213713
215547
|
this.agentLifecycle = agentLifecycle;
|
|
215548
|
+
this.rustEngineTurnRunner = rustEngineTurnRunner;
|
|
213714
215549
|
}
|
|
213715
215550
|
async prompt(payload) {
|
|
213716
215551
|
if (payload.disabledTools !== void 0) try {
|
|
@@ -213720,6 +215555,13 @@ var init_rpcService = __esmMin((() => {
|
|
|
213720
215555
|
throw error;
|
|
213721
215556
|
}
|
|
213722
215557
|
await this.updatePromptMetadata(promptMetadataTextFromPayload(payload));
|
|
215558
|
+
if (RustEngineTurnRunner.isEnabled()) {
|
|
215559
|
+
const launched = await this.rustEngineTurnRunner.runTurn({
|
|
215560
|
+
input: [...payload.input],
|
|
215561
|
+
origin: { kind: "user" }
|
|
215562
|
+
});
|
|
215563
|
+
return launched === void 0 ? void 0 : { turn_id: launched.turnId };
|
|
215564
|
+
}
|
|
213723
215565
|
const handle = await this.promptService.enqueue({ message: {
|
|
213724
215566
|
role: "user",
|
|
213725
215567
|
content: [...payload.input],
|
|
@@ -213732,6 +215574,17 @@ var init_rpcService = __esmMin((() => {
|
|
|
213732
215574
|
}
|
|
213733
215575
|
async steer(payload) {
|
|
213734
215576
|
this.telemetry.track2("input_steer", { parts: payload.input.length });
|
|
215577
|
+
if (RustEngineTurnRunner.isEnabled()) {
|
|
215578
|
+
if (this.rustEngineTurnRunner.steer({
|
|
215579
|
+
input: [...payload.input],
|
|
215580
|
+
origin: { kind: "user" }
|
|
215581
|
+
})) return { turn_id: 0 };
|
|
215582
|
+
const launched = await this.rustEngineTurnRunner.runTurn({
|
|
215583
|
+
input: [...payload.input],
|
|
215584
|
+
origin: { kind: "user" }
|
|
215585
|
+
});
|
|
215586
|
+
return launched === void 0 ? void 0 : { turn_id: launched.turnId };
|
|
215587
|
+
}
|
|
213735
215588
|
const submitted = await this.promptService.enqueueOrSteer({ message: {
|
|
213736
215589
|
role: "user",
|
|
213737
215590
|
content: [...payload.input],
|
|
@@ -213742,6 +215595,10 @@ var init_rpcService = __esmMin((() => {
|
|
|
213742
215595
|
return turn === void 0 ? void 0 : { turn_id: turn.id };
|
|
213743
215596
|
}
|
|
213744
215597
|
cancel({ turnId }) {
|
|
215598
|
+
if (RustEngineTurnRunner.isEnabled()) {
|
|
215599
|
+
this.rustEngineTurnRunner.cancel(turnId);
|
|
215600
|
+
return;
|
|
215601
|
+
}
|
|
213745
215602
|
if (this.loop.status().state === "running") this.telemetry.track2("cancel", {
|
|
213746
215603
|
from: "streaming",
|
|
213747
215604
|
trace_id: this.loop.status().activeTraceId
|
|
@@ -213846,7 +215703,8 @@ var init_rpcService = __esmMin((() => {
|
|
|
213846
215703
|
__decorateParam(14, ISessionMetadata),
|
|
213847
215704
|
__decorateParam(15, ISessionContext),
|
|
213848
215705
|
__decorateParam(16, IAgentScopeContext),
|
|
213849
|
-
__decorateParam(17, IAgentLifecycleService)
|
|
215706
|
+
__decorateParam(17, IAgentLifecycleService),
|
|
215707
|
+
__decorateParam(18, IRustEngineTurnRunner)
|
|
213850
215708
|
], AgentRPCService);
|
|
213851
215709
|
registerScopedService(2, IAgentRPCService, AgentRPCService, 0, "rpc");
|
|
213852
215710
|
}));
|
|
@@ -216423,13 +218281,6 @@ var init_args_validator = __esmMin((() => {
|
|
|
216423
218281
|
]);
|
|
216424
218282
|
}));
|
|
216425
218283
|
//#endregion
|
|
216426
|
-
//#region ../../packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncation.ts
|
|
216427
|
-
var IAgentToolResultTruncationService;
|
|
216428
|
-
var init_toolResultTruncation = __esmMin((() => {
|
|
216429
|
-
init_instantiation();
|
|
216430
|
-
IAgentToolResultTruncationService = createDecorator("agentToolResultTruncationService");
|
|
216431
|
-
}));
|
|
216432
|
-
//#endregion
|
|
216433
218284
|
//#region ../../packages/agent-core-v2/src/agent/toolExecutor/toolScheduler.ts
|
|
216434
218285
|
function createControlledPromise() {
|
|
216435
218286
|
let resolve;
|
|
@@ -217493,7 +219344,7 @@ var init_src$6 = __esmMin((() => {
|
|
|
217493
219344
|
init_migration();
|
|
217494
219345
|
init_sessionLogService();
|
|
217495
219346
|
init_telemetry$2();
|
|
217496
|
-
init_events$
|
|
219347
|
+
init_events$8();
|
|
217497
219348
|
init_telemetryService();
|
|
217498
219349
|
init_agentTelemetryContext();
|
|
217499
219350
|
init_agentTelemetryContextService();
|
|
@@ -217688,6 +219539,8 @@ var init_src$6 = __esmMin((() => {
|
|
|
217688
219539
|
init_wait();
|
|
217689
219540
|
init_waitService();
|
|
217690
219541
|
init_waitForTool();
|
|
219542
|
+
init_agent_output$1();
|
|
219543
|
+
init_agentOutputTool();
|
|
217691
219544
|
init_completion();
|
|
217692
219545
|
init_allDoneTool();
|
|
217693
219546
|
init_configSection$4();
|
|
@@ -218578,7 +220431,7 @@ var modelCatalogItemSchema$1, providerCatalogStatusSchema$1, providerCatalogItem
|
|
|
218578
220431
|
provider: string$2().min(1),
|
|
218579
220432
|
reason: string$2().min(1)
|
|
218580
220433
|
});
|
|
218581
|
-
})), tokenUsageSchema$2, finishReasonSchema$1, usageStatusSchema$2, permissionModeSchema$2, skillSourceSchema$2, userPromptOriginSchema$1, skillActivationOriginSchema$1, pluginCommandOriginSchema$1, injectionOriginSchema$1, shellCommandOriginSchema$1, compactionSummaryOriginSchema$1, systemTriggerOriginSchema$1, taskLifecycleStatusSchema$2, taskOriginSchema$1, cronJobOriginSchema$1, cronMissedOriginSchema$1, hookResultOriginSchema$1, retryOriginSchema$1, promptOriginSchema$1, dimiErrorCodeSchema$1, dimiErrorPayloadSchema$1, dimiErrorPayloadObjectSchema$1, taskInfoBaseSchema$1, processTaskInfoSchema$1, agentTaskInfoSchema$2, questionTaskInfoSchema$1, toolTaskInfoSchema$1, taskInfoSchema$1, compactionResultSchema$1, toolUpdateSchema$1, turnEndReasonSchema$2, agentPhaseSchema$1, agentStatusUpdatedEventSchema$2, sessionMetaUpdatedEventSchema$1, sessionCreatedEventSchema$1, workspaceCreatedEventSchema$1, workspaceUpdatedEventSchema$1, workspaceDeletedEventSchema$1, sessionWorkChangedEventSchema$1, sessionStatusChangedEventSchema$1, modelCatalogChangedEventSchema, skillActivatedEventSchema$1, pluginCommandActivatedEventSchema$1, errorEventSchema$2, warningEventSchema$2, turnStartedEventSchema$2, turnEndedEventSchema$2, turnStepStartedEventSchema$1, turnStepCompletedEventSchema$1, turnStepRetryingEventSchema$1, turnStepInterruptedEventSchema$1, assistantDeltaEventSchema$2, hookResultEventSchema$1, thinkingDeltaEventSchema$2, toolCallDeltaEventSchema$1, toolCallStartedEventSchema$2, toolProgressEventSchema$1, shellOutputEventSchema$1, shellStartedEventSchema$1, shellCompletedEventSchema$1, toolResultEventSchema$2, subagentSpawnedEventSchema$1, subagentStartedEventSchema$1, subagentSuspendedEventSchema$1, subagentCompletedEventSchema$1, subagentFailedEventSchema$1, compactionStartedEventSchema$1, compactionBlockedEventSchema$1, compactionCancelledEventSchema$1, compactionCompletedEventSchema$1, taskStartedEventSchema$1, taskTerminatedEventSchema$1, cronFiredEventSchema$1, promptSubmittedEventSchema$1, promptCompletedEventSchema$2, promptAbortedEventSchema$2, promptSteeredEventSchema$1, toolListUpdatedReasonSchema$1, toolListUpdatedEventSchema$1, mcpServerStatusPayloadSchema$1, mcpServerStatusEventSchema$1, agentEventSchema$1, eventSchema$1, VOLATILE_EVENT_TYPES$1, init_events$
|
|
220434
|
+
})), tokenUsageSchema$2, finishReasonSchema$1, usageStatusSchema$2, permissionModeSchema$2, skillSourceSchema$2, userPromptOriginSchema$1, skillActivationOriginSchema$1, pluginCommandOriginSchema$1, injectionOriginSchema$1, shellCommandOriginSchema$1, compactionSummaryOriginSchema$1, systemTriggerOriginSchema$1, taskLifecycleStatusSchema$2, taskOriginSchema$1, cronJobOriginSchema$1, cronMissedOriginSchema$1, hookResultOriginSchema$1, retryOriginSchema$1, promptOriginSchema$1, dimiErrorCodeSchema$1, dimiErrorPayloadSchema$1, dimiErrorPayloadObjectSchema$1, taskInfoBaseSchema$1, processTaskInfoSchema$1, agentTaskInfoSchema$2, questionTaskInfoSchema$1, toolTaskInfoSchema$1, taskInfoSchema$1, compactionResultSchema$1, toolUpdateSchema$1, turnEndReasonSchema$2, agentPhaseSchema$1, agentStatusUpdatedEventSchema$2, sessionMetaUpdatedEventSchema$1, sessionCreatedEventSchema$1, workspaceCreatedEventSchema$1, workspaceUpdatedEventSchema$1, workspaceDeletedEventSchema$1, sessionWorkChangedEventSchema$1, sessionStatusChangedEventSchema$1, modelCatalogChangedEventSchema, skillActivatedEventSchema$1, pluginCommandActivatedEventSchema$1, errorEventSchema$2, warningEventSchema$2, turnStartedEventSchema$2, turnEndedEventSchema$2, turnStepStartedEventSchema$1, turnStepCompletedEventSchema$1, turnStepRetryingEventSchema$1, turnStepInterruptedEventSchema$1, assistantDeltaEventSchema$2, hookResultEventSchema$1, thinkingDeltaEventSchema$2, toolCallDeltaEventSchema$1, toolCallStartedEventSchema$2, toolProgressEventSchema$1, shellOutputEventSchema$1, shellStartedEventSchema$1, shellCompletedEventSchema$1, toolResultEventSchema$2, subagentSpawnedEventSchema$1, subagentStartedEventSchema$1, subagentSuspendedEventSchema$1, subagentCompletedEventSchema$1, subagentFailedEventSchema$1, compactionStartedEventSchema$1, compactionBlockedEventSchema$1, compactionCancelledEventSchema$1, compactionCompletedEventSchema$1, taskStartedEventSchema$1, taskTerminatedEventSchema$1, cronFiredEventSchema$1, promptSubmittedEventSchema$1, promptCompletedEventSchema$2, promptAbortedEventSchema$2, promptSteeredEventSchema$1, toolListUpdatedReasonSchema$1, toolListUpdatedEventSchema$1, mcpServerStatusPayloadSchema$1, mcpServerStatusEventSchema$1, agentEventSchema$1, eventSchema$1, VOLATILE_EVENT_TYPES$1, init_events$7 = __esmMin((() => {
|
|
218582
220435
|
init_zod$1();
|
|
218583
220436
|
init_display$1();
|
|
218584
220437
|
init_message$1();
|
|
@@ -219352,7 +221205,7 @@ var modelCatalogItemSchema$1, providerCatalogStatusSchema$1, providerCatalogItem
|
|
|
219352
221205
|
})), sessionCursorSchema$1, cursorsBySessionSchema$1, wsEventEnvelopeSchema$1, wsAckEnvelopeSchema$1, serverHelloPayloadSchema$1, serverHelloMessageSchema$1, agentFilterSchema$1, clientHelloPayloadSchema$1, clientHelloMessageSchema$1, clientHelloAckPayloadSchema$1, clientHelloAckMessageSchema$1, watchFsConfigSchema$1, subscribePayloadSchema$1, subscribeMessageSchema$1, subscribeAckPayloadSchema$1, subscribeAckMessageSchema$1, unsubscribePayloadSchema$1, unsubscribeMessageSchema$1, unsubscribeAckPayloadSchema$1, unsubscribeAckMessageSchema$1, watchFsAddPayloadSchema$1, watchFsAddMessageSchema$1, watchFsRemovePayloadSchema$1, watchFsRemoveMessageSchema$1, watchFsAckPayloadSchema$1, watchFsAckMessageSchema$1, abortPayloadSchema$1, abortMessageSchema$1, abortAckPayloadSchema$1, abortAckMessageSchema$1, terminalAttachPayloadSchema$1, terminalAttachMessageSchema$1, terminalAttachAckPayloadSchema$1, terminalAttachAckMessageSchema$1, terminalDetachPayloadSchema$1, terminalDetachMessageSchema$1, terminalDetachAckPayloadSchema$1, terminalDetachAckMessageSchema$1, terminalInputPayloadSchema$1, terminalInputMessageSchema$1, terminalInputAckPayloadSchema$1, terminalInputAckMessageSchema$1, terminalResizePayloadSchema$1, terminalResizeMessageSchema$1, terminalResizeAckPayloadSchema$1, terminalResizeAckMessageSchema$1, terminalClosePayloadSchema$1, terminalCloseMessageSchema$1, terminalCloseAckPayloadSchema$1, terminalCloseAckMessageSchema$1, pingPayloadSchema$1, pingMessageSchema$1, pongPayloadSchema$1, pongMessageSchema$1, resyncRequiredPayloadSchema$1, resyncRequiredMessageSchema$1, wsErrorPayloadSchema$1, wsErrorMessageSchema$1, terminalOutputPayloadSchema$1, terminalExitPayloadSchema$1, clientControlOperations$1, serverSystemOperations$1;
|
|
219353
221206
|
var init_ws_control$1 = __esmMin((() => {
|
|
219354
221207
|
init_zod$1();
|
|
219355
|
-
init_events$
|
|
221208
|
+
init_events$7();
|
|
219356
221209
|
init_time();
|
|
219357
221210
|
sessionCursorSchema$1 = object({
|
|
219358
221211
|
seq: number$2().int().nonnegative(),
|
|
@@ -219897,7 +221750,7 @@ var init_tool$2 = __esmMin((() => {
|
|
|
219897
221750
|
var skillDescriptorSchema$1;
|
|
219898
221751
|
var init_skill$2 = __esmMin((() => {
|
|
219899
221752
|
init_zod$1();
|
|
219900
|
-
init_events$
|
|
221753
|
+
init_events$7();
|
|
219901
221754
|
skillDescriptorSchema$1 = object({
|
|
219902
221755
|
name: string$2().min(1),
|
|
219903
221756
|
description: string$2(),
|
|
@@ -220630,7 +222483,7 @@ var init_src$5 = __esmMin((() => {
|
|
|
220630
222483
|
init_pagination$1();
|
|
220631
222484
|
init_time();
|
|
220632
222485
|
init_request_id$2();
|
|
220633
|
-
init_events$
|
|
222486
|
+
init_events$7();
|
|
220634
222487
|
init_display$1();
|
|
220635
222488
|
init_ws_control$1();
|
|
220636
222489
|
init_asyncapi$1();
|
|
@@ -220669,7 +222522,7 @@ var init_src$5 = __esmMin((() => {
|
|
|
220669
222522
|
}));
|
|
220670
222523
|
//#endregion
|
|
220671
222524
|
//#region ../../packages/node-sdk/src/events.ts
|
|
220672
|
-
var init_events$
|
|
222525
|
+
var init_events$6 = __esmMin((() => {
|
|
220673
222526
|
init_src$5();
|
|
220674
222527
|
}));
|
|
220675
222528
|
//#endregion
|
|
@@ -220724,7 +222577,7 @@ var MAIN_AGENT_ID$6, Session;
|
|
|
220724
222577
|
var init_session$3 = __esmMin((() => {
|
|
220725
222578
|
init_src$6();
|
|
220726
222579
|
init_errors$3();
|
|
220727
|
-
init_events$
|
|
222580
|
+
init_events$6();
|
|
220728
222581
|
MAIN_AGENT_ID$6 = "main";
|
|
220729
222582
|
Session = class {
|
|
220730
222583
|
id;
|
|
@@ -221753,7 +223606,7 @@ var init_helpers = __esmMin((() => {
|
|
|
221753
223606
|
removed: array$2(string$2()),
|
|
221754
223607
|
changed: array$2(string$2())
|
|
221755
223608
|
});
|
|
221756
|
-
})), textPartSchema, imageUrlPartSchema, videoUrlPartSchema, promptPartSchema, emptyPayloadSchema, promptPayloadSchema, steerPayloadSchema, promptLaunchResultSchema, cancelPayloadSchema, runShellCommandPayloadSchema, shellCommandResultSchema, setModelResultSchema, permissionModeSchema$1, setPermissionPayloadSchema, tokenUsageSchema$1, usageStatusSchema$1, agentContextDataSchema, planDataSchema, taskLifecycleStatusSchema$1, taskInfoBaseFields, agentTaskInfoSchema$1, agentRpcContract;
|
|
223609
|
+
})), textPartSchema, imageUrlPartSchema, videoUrlPartSchema, promptPartSchema, emptyPayloadSchema, promptPayloadSchema, steerPayloadSchema, promptLaunchResultSchema, cancelPayloadSchema, runShellCommandPayloadSchema, shellCommandResultSchema$1, setModelResultSchema, permissionModeSchema$1, setPermissionPayloadSchema, tokenUsageSchema$1, usageStatusSchema$1, agentContextDataSchema, planDataSchema, taskLifecycleStatusSchema$1, taskInfoBaseFields, agentTaskInfoSchema$1, agentRpcContract;
|
|
221757
223610
|
var init_rpc$1 = __esmMin((() => {
|
|
221758
223611
|
init_zod$1();
|
|
221759
223612
|
init_helpers();
|
|
@@ -221792,7 +223645,7 @@ var init_rpc$1 = __esmMin((() => {
|
|
|
221792
223645
|
command: string$2(),
|
|
221793
223646
|
commandId: string$2().optional()
|
|
221794
223647
|
});
|
|
221795
|
-
shellCommandResultSchema = object({
|
|
223648
|
+
shellCommandResultSchema$1 = object({
|
|
221796
223649
|
stdout: string$2(),
|
|
221797
223650
|
stderr: string$2(),
|
|
221798
223651
|
isError: boolean$2().optional(),
|
|
@@ -221924,7 +223777,7 @@ var init_services = __esmMin((() => {
|
|
|
221924
223777
|
agentShellCommandContract = {
|
|
221925
223778
|
run: {
|
|
221926
223779
|
input: tuple([runShellCommandPayloadSchema]),
|
|
221927
|
-
output: shellCommandResultSchema
|
|
223780
|
+
output: shellCommandResultSchema$1
|
|
221928
223781
|
},
|
|
221929
223782
|
cancel: {
|
|
221930
223783
|
input: tuple([string$2()]),
|
|
@@ -222868,7 +224721,7 @@ var init_contract$1 = __esmMin((() => {
|
|
|
222868
224721
|
//#endregion
|
|
222869
224722
|
//#region ../../packages/klient/src/contract/global/events.ts
|
|
222870
224723
|
var configChangedSchema, reloadSummarySchema, sessionMetaUpdatedSchema, globalEvents;
|
|
222871
|
-
var init_events$
|
|
224724
|
+
var init_events$5 = __esmMin((() => {
|
|
222872
224725
|
init_zod$1();
|
|
222873
224726
|
configChangedSchema = object({
|
|
222874
224727
|
domain: string$2(),
|
|
@@ -222932,7 +224785,7 @@ var init_events$4 = __esmMin((() => {
|
|
|
222932
224785
|
//#endregion
|
|
222933
224786
|
//#region ../../packages/klient/src/contract/session/events.ts
|
|
222934
224787
|
var sessionEvents;
|
|
222935
|
-
var init_events$
|
|
224788
|
+
var init_events$4 = __esmMin((() => {
|
|
222936
224789
|
init_zod$1();
|
|
222937
224790
|
init_interaction$1();
|
|
222938
224791
|
init_metadata();
|
|
@@ -222958,7 +224811,7 @@ var init_events$3 = __esmMin((() => {
|
|
|
222958
224811
|
//#endregion
|
|
222959
224812
|
//#region ../../packages/klient/src/contract/agent/events.ts
|
|
222960
224813
|
var turnStartedEventSchema$1, turnEndedEventSchema$1, assistantDeltaEventSchema$1, thinkingDeltaEventSchema$1, toolCallStartedEventSchema$1, toolResultEventSchema$1, promptCompletedEventSchema$1, promptAbortedEventSchema$1, permissionApprovalRequestedEventSchema, permissionApprovalResolvedEventSchema, errorEventSchema$1, warningEventSchema$1, agentStatusUpdatedEventSchema$1, agentEvents;
|
|
222961
|
-
var init_events$
|
|
224814
|
+
var init_events$3 = __esmMin((() => {
|
|
222962
224815
|
init_zod$1();
|
|
222963
224816
|
turnStartedEventSchema$1 = object({
|
|
222964
224817
|
type: literal("turn.started"),
|
|
@@ -223592,9 +225445,9 @@ function createKlientFromChannel(channel, options = {}) {
|
|
|
223592
225445
|
}
|
|
223593
225446
|
var init_klient = __esmMin((() => {
|
|
223594
225447
|
init_contract$1();
|
|
225448
|
+
init_events$5();
|
|
223595
225449
|
init_events$4();
|
|
223596
225450
|
init_events$3();
|
|
223597
|
-
init_events$2();
|
|
223598
225451
|
init_hub();
|
|
223599
225452
|
init_global();
|
|
223600
225453
|
init_session$2();
|
|
@@ -226020,7 +227873,7 @@ var init_src$4 = __esmMin((() => {
|
|
|
226020
227873
|
init_errors$3();
|
|
226021
227874
|
init_logging();
|
|
226022
227875
|
init_src$6();
|
|
226023
|
-
init_events$
|
|
227876
|
+
init_events$6();
|
|
226024
227877
|
}));
|
|
226025
227878
|
//#endregion
|
|
226026
227879
|
//#region ../../packages/telemetry/src/index.ts
|
|
@@ -232272,7 +234125,7 @@ var init_schema$1 = __esmMin((() => {
|
|
|
232272
234125
|
seq: transcriptSeqSchema.optional()
|
|
232273
234126
|
});
|
|
232274
234127
|
})), transcriptResetEventSchema, transcriptOpsEventSchema;
|
|
232275
|
-
var init_events$
|
|
234128
|
+
var init_events$2 = __esmMin((() => {
|
|
232276
234129
|
init_zod$1();
|
|
232277
234130
|
init_schema$1();
|
|
232278
234131
|
transcriptResetEventSchema = transcriptResetPayloadSchema.extend({ type: literal("transcript.reset") });
|
|
@@ -232303,7 +234156,7 @@ var init_src$2 = __esmMin((() => {
|
|
|
232303
234156
|
init_groupTurns();
|
|
232304
234157
|
init_foldFacts();
|
|
232305
234158
|
init_schema$1();
|
|
232306
|
-
init_events$
|
|
234159
|
+
init_events$2();
|
|
232307
234160
|
}));
|
|
232308
234161
|
//#endregion
|
|
232309
234162
|
//#region ../../packages/agent-core-v2/src/agent/contextMemory/protocolMessage.ts
|
|
@@ -259106,7 +260959,7 @@ function isVolatileEventType(type) {
|
|
|
259106
260959
|
return volatileEventTypeSet.has(type);
|
|
259107
260960
|
}
|
|
259108
260961
|
var VOLATILE_EVENT_TYPES, volatileEventTypeSet;
|
|
259109
|
-
var init_events = __esmMin((() => {
|
|
260962
|
+
var init_events$1 = __esmMin((() => {
|
|
259110
260963
|
VOLATILE_EVENT_TYPES = [
|
|
259111
260964
|
"assistant.delta",
|
|
259112
260965
|
"thinking.delta",
|
|
@@ -259344,11 +261197,11 @@ function registerApprovalsRoutes(app, core) {
|
|
|
259344
261197
|
const listRoute = defineRoute({
|
|
259345
261198
|
method: "GET",
|
|
259346
261199
|
path: "/sessions/{session_id}/approvals",
|
|
259347
|
-
params: sessionIdParamSchema$
|
|
261200
|
+
params: sessionIdParamSchema$10,
|
|
259348
261201
|
querystring: listPendingApprovalsQuerySchema,
|
|
259349
261202
|
success: { data: listPendingApprovalsResponseSchema },
|
|
259350
261203
|
errors: {
|
|
259351
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
261204
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$8 },
|
|
259352
261205
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
259353
261206
|
},
|
|
259354
261207
|
description: "List pending approval requests for a session",
|
|
@@ -259371,7 +261224,7 @@ function registerApprovalsRoutes(app, core) {
|
|
|
259371
261224
|
body: approvalResolveRequestSchema,
|
|
259372
261225
|
success: { data: approvalResolveResultSchema },
|
|
259373
261226
|
errors: {
|
|
259374
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
261227
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$8 },
|
|
259375
261228
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
259376
261229
|
[ErrorCode.APPROVAL_NOT_FOUND]: {},
|
|
259377
261230
|
[ErrorCode.APPROVAL_ALREADY_RESOLVED]: { dataSchema: approvalAlreadyResolvedDataSchema }
|
|
@@ -259434,7 +261287,7 @@ function toWireApproval(interaction, sessionId) {
|
|
|
259434
261287
|
expires_at: new Date(interaction.createdAt + APPROVAL_EXPIRY_MS).toISOString()
|
|
259435
261288
|
};
|
|
259436
261289
|
}
|
|
259437
|
-
var sessionIdParamSchema$
|
|
261290
|
+
var sessionIdParamSchema$10, approvalParamsSchema, detailsSchema$8, APPROVAL_EXPIRY_MS;
|
|
259438
261291
|
var init_approvals = __esmMin((() => {
|
|
259439
261292
|
init_src$6();
|
|
259440
261293
|
init_error_codes();
|
|
@@ -259443,12 +261296,12 @@ var init_approvals = __esmMin((() => {
|
|
|
259443
261296
|
init_envelope();
|
|
259444
261297
|
init_requestLog();
|
|
259445
261298
|
init_defineRoute();
|
|
259446
|
-
sessionIdParamSchema$
|
|
261299
|
+
sessionIdParamSchema$10 = object({ session_id: string$2().min(1) });
|
|
259447
261300
|
approvalParamsSchema = object({
|
|
259448
261301
|
session_id: string$2().min(1),
|
|
259449
261302
|
approval_id: string$2().min(1)
|
|
259450
261303
|
});
|
|
259451
|
-
detailsSchema$
|
|
261304
|
+
detailsSchema$8 = array$2(object({
|
|
259452
261305
|
path: string$2(),
|
|
259453
261306
|
message: string$2()
|
|
259454
261307
|
}));
|
|
@@ -259507,11 +261360,11 @@ function registerQuestionsRoutes(app, core) {
|
|
|
259507
261360
|
const listRoute = defineRoute({
|
|
259508
261361
|
method: "GET",
|
|
259509
261362
|
path: "/sessions/{session_id}/questions",
|
|
259510
|
-
params: sessionIdParamSchema$
|
|
261363
|
+
params: sessionIdParamSchema$9,
|
|
259511
261364
|
querystring: listPendingQuestionsQuerySchema,
|
|
259512
261365
|
success: { data: listPendingQuestionsResponseSchema },
|
|
259513
261366
|
errors: {
|
|
259514
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
261367
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$7 },
|
|
259515
261368
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
259516
261369
|
},
|
|
259517
261370
|
description: "List pending question requests for a session",
|
|
@@ -259533,7 +261386,7 @@ function registerQuestionsRoutes(app, core) {
|
|
|
259533
261386
|
params: tailParamsSchema,
|
|
259534
261387
|
success: { data: questionResolveResultSchema },
|
|
259535
261388
|
errors: {
|
|
259536
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
261389
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$7 },
|
|
259537
261390
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
259538
261391
|
[ErrorCode.QUESTION_NOT_FOUND]: {},
|
|
259539
261392
|
[ErrorCode.APPROVAL_ALREADY_RESOLVED]: { dataSchema: questionAlreadyResolvedDataSchema },
|
|
@@ -259717,7 +261570,7 @@ function toInProcessResponse(resp, request) {
|
|
|
259717
261570
|
if (resp.method !== void 0 && resp.method !== "click") out.method = resp.method;
|
|
259718
261571
|
return out;
|
|
259719
261572
|
}
|
|
259720
|
-
var sessionIdParamSchema$
|
|
261573
|
+
var sessionIdParamSchema$9, tailParamsSchema, detailsSchema$7;
|
|
259721
261574
|
var init_questions = __esmMin((() => {
|
|
259722
261575
|
init_src$6();
|
|
259723
261576
|
init_error_codes();
|
|
@@ -259728,12 +261581,12 @@ var init_questions = __esmMin((() => {
|
|
|
259728
261581
|
init_requestLog();
|
|
259729
261582
|
init_defineRoute();
|
|
259730
261583
|
init_action_suffix();
|
|
259731
|
-
sessionIdParamSchema$
|
|
261584
|
+
sessionIdParamSchema$9 = object({ session_id: string$2().min(1) });
|
|
259732
261585
|
tailParamsSchema = object({
|
|
259733
261586
|
session_id: string$2().min(1),
|
|
259734
261587
|
tail: string$2().min(1)
|
|
259735
261588
|
});
|
|
259736
|
-
detailsSchema$
|
|
261589
|
+
detailsSchema$7 = array$2(object({
|
|
259737
261590
|
path: string$2(),
|
|
259738
261591
|
message: string$2()
|
|
259739
261592
|
}));
|
|
@@ -260411,7 +262264,7 @@ function sessionCreatedPayload(payload) {
|
|
|
260411
262264
|
var GLOBAL_SESSION_ID, TRANSCRIPT_RESET_TAIL_TURNS, SessionEventBroadcaster, volatileSignalTypeSet, TRANSCRIPT_PROJECTED_EVENT_TYPES;
|
|
260412
262265
|
var init_sessionEventBroadcaster = __esmMin((() => {
|
|
260413
262266
|
init_src$6();
|
|
260414
|
-
init_events();
|
|
262267
|
+
init_events$1();
|
|
260415
262268
|
init_src$2();
|
|
260416
262269
|
init_approvals();
|
|
260417
262270
|
init_questions();
|
|
@@ -264961,11 +266814,11 @@ function registerMessagesRoutes(app, core) {
|
|
|
264961
266814
|
const listRoute = defineRoute({
|
|
264962
266815
|
method: "GET",
|
|
264963
266816
|
path: "/sessions/{session_id}/messages",
|
|
264964
|
-
params: sessionIdParamSchema$
|
|
266817
|
+
params: sessionIdParamSchema$8,
|
|
264965
266818
|
querystring: messagesListQueryCoercion,
|
|
264966
266819
|
success: { data: listMessagesResponseSchema },
|
|
264967
266820
|
errors: {
|
|
264968
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
266821
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$6 },
|
|
264969
266822
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
264970
266823
|
},
|
|
264971
266824
|
description: "List messages for a session",
|
|
@@ -264986,7 +266839,7 @@ function registerMessagesRoutes(app, core) {
|
|
|
264986
266839
|
params: messageIdParamSchema,
|
|
264987
266840
|
success: { data: getMessageResponseSchema },
|
|
264988
266841
|
errors: {
|
|
264989
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
266842
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$6 },
|
|
264990
266843
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
264991
266844
|
[ErrorCode.MESSAGE_NOT_FOUND]: {}
|
|
264992
266845
|
},
|
|
@@ -265023,7 +266876,7 @@ function sendMappedError$7(reply, req, err) {
|
|
|
265023
266876
|
log?.error({ err }, "message request failed");
|
|
265024
266877
|
reply.send(errEnvelope(ErrorCode.INTERNAL_ERROR, err instanceof Error ? err.message : String(err), requestId, err instanceof Error ? err.stack : void 0));
|
|
265025
266878
|
}
|
|
265026
|
-
var messagesListQueryCoercion, sessionIdParamSchema$
|
|
266879
|
+
var messagesListQueryCoercion, sessionIdParamSchema$8, messageIdParamSchema, detailsSchema$6;
|
|
265027
266880
|
var init_messages = __esmMin((() => {
|
|
265028
266881
|
init_src$6();
|
|
265029
266882
|
init_protocolMessage();
|
|
@@ -265047,12 +266900,12 @@ var init_messages = __esmMin((() => {
|
|
|
265047
266900
|
params: { code: ErrorCode.VALIDATION_FAILED }
|
|
265048
266901
|
});
|
|
265049
266902
|
});
|
|
265050
|
-
sessionIdParamSchema$
|
|
266903
|
+
sessionIdParamSchema$8 = object({ session_id: string$2().min(1) });
|
|
265051
266904
|
messageIdParamSchema = object({
|
|
265052
266905
|
session_id: string$2().min(1),
|
|
265053
266906
|
message_id: string$2().min(1)
|
|
265054
266907
|
});
|
|
265055
|
-
detailsSchema$
|
|
266908
|
+
detailsSchema$6 = array$2(object({
|
|
265056
266909
|
path: string$2(),
|
|
265057
266910
|
message: string$2()
|
|
265058
266911
|
}));
|
|
@@ -265405,6 +267258,107 @@ var init_registerDebugRoutes = __esmMin((() => {
|
|
|
265405
267258
|
init_serviceDispatcherRoutes();
|
|
265406
267259
|
}));
|
|
265407
267260
|
//#endregion
|
|
267261
|
+
//#region ../../packages/kap-server/src/routes/events.ts
|
|
267262
|
+
function registerEventsRoute(app, opts) {
|
|
267263
|
+
app.get("/sessions/:session_id/events", { schema: {
|
|
267264
|
+
params: {
|
|
267265
|
+
type: "object",
|
|
267266
|
+
properties: { session_id: { type: "string" } },
|
|
267267
|
+
required: ["session_id"]
|
|
267268
|
+
},
|
|
267269
|
+
querystring: {
|
|
267270
|
+
type: "object",
|
|
267271
|
+
properties: { event_seq: { type: "string" } },
|
|
267272
|
+
required: []
|
|
267273
|
+
}
|
|
267274
|
+
} }, async (req, reply) => {
|
|
267275
|
+
const { session_id } = req.params;
|
|
267276
|
+
if (!session_id) {
|
|
267277
|
+
await reply.code(400).send({
|
|
267278
|
+
code: 4e4,
|
|
267279
|
+
msg: "session_id required",
|
|
267280
|
+
data: null,
|
|
267281
|
+
request_id: req.id
|
|
267282
|
+
});
|
|
267283
|
+
return;
|
|
267284
|
+
}
|
|
267285
|
+
const eventSeq = parseEventSeq(req.query.event_seq);
|
|
267286
|
+
if (eventSeq !== void 0 && (!Number.isInteger(eventSeq) || eventSeq < 0)) {
|
|
267287
|
+
await reply.code(400).send({
|
|
267288
|
+
code: 4e4,
|
|
267289
|
+
msg: "event_seq must be a non-negative integer",
|
|
267290
|
+
data: null,
|
|
267291
|
+
request_id: req.id
|
|
267292
|
+
});
|
|
267293
|
+
return;
|
|
267294
|
+
}
|
|
267295
|
+
reply.hijack();
|
|
267296
|
+
const raw = reply.raw;
|
|
267297
|
+
raw.writeHead(200, SSE_HEADERS);
|
|
267298
|
+
raw.write(": connected\n\n");
|
|
267299
|
+
let closed = false;
|
|
267300
|
+
const target = { send(envelope) {
|
|
267301
|
+
if (closed) return;
|
|
267302
|
+
raw.write(`event: ${envelope.type}\ndata: ${JSON.stringify(envelope)}\n\n`);
|
|
267303
|
+
} };
|
|
267304
|
+
if (!await opts.broadcaster.subscribe(session_id, target)) {
|
|
267305
|
+
if (await opts.core.accessor.get(ISessionLifecycleService).resume(session_id) === void 0) {
|
|
267306
|
+
closed = true;
|
|
267307
|
+
raw.write("event: error\ndata: {\"code\":40401,\"msg\":\"session not found\"}\n\n");
|
|
267308
|
+
raw.end();
|
|
267309
|
+
return;
|
|
267310
|
+
}
|
|
267311
|
+
if (!await opts.broadcaster.subscribe(session_id, target)) {
|
|
267312
|
+
closed = true;
|
|
267313
|
+
raw.write("event: error\ndata: {\"code\":40401,\"msg\":\"session not found\"}\n\n");
|
|
267314
|
+
raw.end();
|
|
267315
|
+
return;
|
|
267316
|
+
}
|
|
267317
|
+
}
|
|
267318
|
+
if (eventSeq !== void 0) {
|
|
267319
|
+
const result = await opts.broadcaster.getBufferedSince(session_id, { seq: eventSeq });
|
|
267320
|
+
if (result.resyncRequired !== false) raw.write(`event: resync_required\ndata: ${JSON.stringify({
|
|
267321
|
+
type: "resync_required",
|
|
267322
|
+
session_id,
|
|
267323
|
+
reason: result.resyncRequired,
|
|
267324
|
+
current_seq: result.currentSeq,
|
|
267325
|
+
epoch: result.epoch
|
|
267326
|
+
})}\n\n`);
|
|
267327
|
+
else for (const { envelope } of result.events) target.send(envelope);
|
|
267328
|
+
}
|
|
267329
|
+
const heartbeat = setInterval(() => {
|
|
267330
|
+
if (!closed) raw.write(": ping\n\n");
|
|
267331
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
267332
|
+
req.raw.on("close", () => {
|
|
267333
|
+
closed = true;
|
|
267334
|
+
clearInterval(heartbeat);
|
|
267335
|
+
opts.broadcaster.unsubscribe(session_id, target);
|
|
267336
|
+
});
|
|
267337
|
+
});
|
|
267338
|
+
}
|
|
267339
|
+
/**
|
|
267340
|
+
* Parse the optional `?event_seq=` replay cursor. `undefined` = absent
|
|
267341
|
+
* (live-only stream); `NaN` = present but malformed — the caller rejects it
|
|
267342
|
+
* with a 400. A valid cursor is a non-negative integer (the journal seq
|
|
267343
|
+
* domain, matching `sessionCursorSchema.seq`).
|
|
267344
|
+
*/
|
|
267345
|
+
function parseEventSeq(raw) {
|
|
267346
|
+
if (raw === void 0) return void 0;
|
|
267347
|
+
if (typeof raw !== "string" || !/^\d+$/.test(raw)) return NaN;
|
|
267348
|
+
return Number(raw);
|
|
267349
|
+
}
|
|
267350
|
+
var SSE_HEADERS, HEARTBEAT_INTERVAL_MS;
|
|
267351
|
+
var init_events = __esmMin((() => {
|
|
267352
|
+
init_src$6();
|
|
267353
|
+
SSE_HEADERS = {
|
|
267354
|
+
"Content-Type": "text/event-stream",
|
|
267355
|
+
"Cache-Control": "no-cache",
|
|
267356
|
+
Connection: "keep-alive",
|
|
267357
|
+
"X-Accel-Buffering": "no"
|
|
267358
|
+
};
|
|
267359
|
+
HEARTBEAT_INTERVAL_MS = 15e3;
|
|
267360
|
+
}));
|
|
267361
|
+
//#endregion
|
|
265408
267362
|
//#region ../../packages/kap-server/src/protocol/rest-meta.ts
|
|
265409
267363
|
var metaCapabilitiesSchema, metaResponseSchema;
|
|
265410
267364
|
var init_rest_meta = __esmMin((() => {
|
|
@@ -266010,7 +267964,7 @@ function registerPromptsRoutes(app, core) {
|
|
|
266010
267964
|
const listRoute = defineRoute({
|
|
266011
267965
|
method: "GET",
|
|
266012
267966
|
path: "/sessions/{session_id}/prompts",
|
|
266013
|
-
params: sessionIdParamSchema$
|
|
267967
|
+
params: sessionIdParamSchema$7,
|
|
266014
267968
|
success: { data: promptListResponseSchema },
|
|
266015
267969
|
errors: { [ErrorCode.SESSION_NOT_FOUND]: {} },
|
|
266016
267970
|
description: "List the active prompt and queued prompts for a session",
|
|
@@ -266030,7 +267984,7 @@ function registerPromptsRoutes(app, core) {
|
|
|
266030
267984
|
method: "POST",
|
|
266031
267985
|
path: "/sessions/{session_id}/prompts",
|
|
266032
267986
|
body: promptSubmissionSchema,
|
|
266033
|
-
params: sessionIdParamSchema$
|
|
267987
|
+
params: sessionIdParamSchema$7,
|
|
266034
267988
|
success: { data: promptSubmitResultSchema },
|
|
266035
267989
|
errors: {
|
|
266036
267990
|
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: validationDetailsSchema },
|
|
@@ -266096,7 +268050,7 @@ function registerPromptsRoutes(app, core) {
|
|
|
266096
268050
|
method: "POST",
|
|
266097
268051
|
path: "/sessions/{session_id}/prompts::steer",
|
|
266098
268052
|
body: promptSteerRequestSchema,
|
|
266099
|
-
params: sessionIdParamSchema$
|
|
268053
|
+
params: sessionIdParamSchema$7,
|
|
266100
268054
|
success: { data: promptSteerResultSchema },
|
|
266101
268055
|
errors: {
|
|
266102
268056
|
[ErrorCode.VALIDATION_FAILED]: {},
|
|
@@ -266588,7 +268542,7 @@ function authModelDetails(err) {
|
|
|
266588
268542
|
if (typeof providerId === "string") details.provider_id = providerId;
|
|
266589
268543
|
return Object.keys(details).length === 0 ? null : details;
|
|
266590
268544
|
}
|
|
266591
|
-
var sessionIdParamSchema$
|
|
268545
|
+
var sessionIdParamSchema$7, validationDetailsSchema, authProviderDetailsSchema, authModelDetailsSchema, VIDEO_EXT_BY_MIME, ATTACHMENT_NAME_MAX;
|
|
266592
268546
|
var init_prompts$1 = __esmMin((() => {
|
|
266593
268547
|
init_src$6();
|
|
266594
268548
|
init_error_codes();
|
|
@@ -266599,7 +268553,7 @@ var init_prompts$1 = __esmMin((() => {
|
|
|
266599
268553
|
init_defineRoute();
|
|
266600
268554
|
init_mainAgent();
|
|
266601
268555
|
init_action_suffix();
|
|
266602
|
-
sessionIdParamSchema$
|
|
268556
|
+
sessionIdParamSchema$7 = object({ session_id: string$2().min(1) });
|
|
266603
268557
|
validationDetailsSchema = array$2(object({
|
|
266604
268558
|
path: string$2(),
|
|
266605
268559
|
message: string$2()
|
|
@@ -266881,7 +268835,7 @@ function registerSessionsRoutes(app, core) {
|
|
|
266881
268835
|
body: createSessionRequestSchema,
|
|
266882
268836
|
success: { data: sessionSchema },
|
|
266883
268837
|
errors: {
|
|
266884
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
268838
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
266885
268839
|
[ErrorCode.WORKSPACE_NOT_FOUND]: {},
|
|
266886
268840
|
[ErrorCode.FS_PATH_NOT_FOUND]: {}
|
|
266887
268841
|
},
|
|
@@ -266919,6 +268873,7 @@ function registerSessionsRoutes(app, core) {
|
|
|
266919
268873
|
const touched = await registry.createOrTouch(workDir);
|
|
266920
268874
|
const handle = await core.accessor.get(ISessionLifecycleService).create({ workDir });
|
|
266921
268875
|
if (typeof body.title === "string") await handle.accessor.get(ISessionMetadata).setTitle(body.title);
|
|
268876
|
+
if (body.metadata !== void 0 && Object.keys(body.metadata).length > 0) await handle.accessor.get(ISessionMetadata).update({ custom: { ...body.metadata } });
|
|
266922
268877
|
const session = toWireSession({
|
|
266923
268878
|
...await handle.accessor.get(ISessionMetadata).read(),
|
|
266924
268879
|
workspaceId: touched.id
|
|
@@ -266947,7 +268902,7 @@ function registerSessionsRoutes(app, core) {
|
|
|
266947
268902
|
querystring: sessionsListQueryCoercion,
|
|
266948
268903
|
success: { data: pageResponseSchema(sessionSchema) },
|
|
266949
268904
|
errors: {
|
|
266950
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
268905
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
266951
268906
|
[ErrorCode.WORKSPACE_NOT_FOUND]: {}
|
|
266952
268907
|
},
|
|
266953
268908
|
description: "List sessions",
|
|
@@ -267015,10 +268970,10 @@ function registerSessionsRoutes(app, core) {
|
|
|
267015
268970
|
const getRoute = defineRoute({
|
|
267016
268971
|
method: "GET",
|
|
267017
268972
|
path: "/sessions/{session_id}",
|
|
267018
|
-
params: sessionIdParamSchema$
|
|
268973
|
+
params: sessionIdParamSchema$6,
|
|
267019
268974
|
success: { data: sessionSchema },
|
|
267020
268975
|
errors: {
|
|
267021
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
268976
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267022
268977
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267023
268978
|
},
|
|
267024
268979
|
description: "Get a session by ID",
|
|
@@ -267041,10 +268996,10 @@ function registerSessionsRoutes(app, core) {
|
|
|
267041
268996
|
const getProfileRoute = defineRoute({
|
|
267042
268997
|
method: "GET",
|
|
267043
268998
|
path: "/sessions/{session_id}/profile",
|
|
267044
|
-
params: sessionIdParamSchema$
|
|
268999
|
+
params: sessionIdParamSchema$6,
|
|
267045
269000
|
success: { data: sessionSchema },
|
|
267046
269001
|
errors: {
|
|
267047
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269002
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267048
269003
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267049
269004
|
},
|
|
267050
269005
|
description: "Get session profile",
|
|
@@ -267067,11 +269022,11 @@ function registerSessionsRoutes(app, core) {
|
|
|
267067
269022
|
const updateProfileRoute = defineRoute({
|
|
267068
269023
|
method: "POST",
|
|
267069
269024
|
path: "/sessions/{session_id}/profile",
|
|
267070
|
-
params: sessionIdParamSchema$
|
|
269025
|
+
params: sessionIdParamSchema$6,
|
|
267071
269026
|
body: updateSessionProfileRequestSchema,
|
|
267072
269027
|
success: { data: sessionSchema },
|
|
267073
269028
|
errors: {
|
|
267074
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269029
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267075
269030
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267076
269031
|
},
|
|
267077
269032
|
description: "Update session profile (title, metadata, agent_config)",
|
|
@@ -267113,7 +269068,7 @@ function registerSessionsRoutes(app, core) {
|
|
|
267113
269068
|
archiveSessionResponseSchema
|
|
267114
269069
|
]) },
|
|
267115
269070
|
errors: {
|
|
267116
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269071
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267117
269072
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
267118
269073
|
[ErrorCode.SESSION_BUSY]: {},
|
|
267119
269074
|
[ErrorCode.COMPACTION_UNABLE]: {},
|
|
@@ -267252,11 +269207,11 @@ function registerSessionsRoutes(app, core) {
|
|
|
267252
269207
|
const listChildrenRoute = defineRoute({
|
|
267253
269208
|
method: "GET",
|
|
267254
269209
|
path: "/sessions/{session_id}/children",
|
|
267255
|
-
params: sessionIdParamSchema$
|
|
269210
|
+
params: sessionIdParamSchema$6,
|
|
267256
269211
|
querystring: sessionChildrenListQueryCoercion,
|
|
267257
269212
|
success: { data: listSessionChildrenResponseSchema },
|
|
267258
269213
|
errors: {
|
|
267259
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269214
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267260
269215
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267261
269216
|
},
|
|
267262
269217
|
description: "List child sessions",
|
|
@@ -267290,11 +269245,11 @@ function registerSessionsRoutes(app, core) {
|
|
|
267290
269245
|
const createChildRoute = defineRoute({
|
|
267291
269246
|
method: "POST",
|
|
267292
269247
|
path: "/sessions/{session_id}/children",
|
|
267293
|
-
params: sessionIdParamSchema$
|
|
269248
|
+
params: sessionIdParamSchema$6,
|
|
267294
269249
|
body: createSessionChildRequestSchema,
|
|
267295
269250
|
success: { data: sessionSchema },
|
|
267296
269251
|
errors: {
|
|
267297
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269252
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267298
269253
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
267299
269254
|
[ErrorCode.SESSION_BUSY]: {}
|
|
267300
269255
|
},
|
|
@@ -267331,10 +269286,10 @@ function registerSessionsRoutes(app, core) {
|
|
|
267331
269286
|
const statusRoute = defineRoute({
|
|
267332
269287
|
method: "GET",
|
|
267333
269288
|
path: "/sessions/{session_id}/status",
|
|
267334
|
-
params: sessionIdParamSchema$
|
|
269289
|
+
params: sessionIdParamSchema$6,
|
|
267335
269290
|
success: { data: sessionStatusResponseSchema },
|
|
267336
269291
|
errors: {
|
|
267337
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269292
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267338
269293
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267339
269294
|
},
|
|
267340
269295
|
description: "Get realtime session status (best-effort in this slice)",
|
|
@@ -267352,10 +269307,10 @@ function registerSessionsRoutes(app, core) {
|
|
|
267352
269307
|
const sessionWarningsRoute = defineRoute({
|
|
267353
269308
|
method: "GET",
|
|
267354
269309
|
path: "/sessions/{session_id}/warnings",
|
|
267355
|
-
params: sessionIdParamSchema$
|
|
269310
|
+
params: sessionIdParamSchema$6,
|
|
267356
269311
|
success: { data: sessionWarningsResponseSchema },
|
|
267357
269312
|
errors: {
|
|
267358
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269313
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267359
269314
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267360
269315
|
},
|
|
267361
269316
|
description: "Get session-level warnings (e.g. oversized AGENTS.md)",
|
|
@@ -267511,7 +269466,7 @@ function sendMappedError$4(reply, req, err) {
|
|
|
267511
269466
|
log?.error({ err }, "session request failed");
|
|
267512
269467
|
reply.send(errEnvelope(ErrorCode.INTERNAL_ERROR, err instanceof Error ? err.message : String(err), requestId, err instanceof Error ? err.stack : void 0));
|
|
267513
269468
|
}
|
|
267514
|
-
var booleanQueryParam, DEFAULT_SESSION_LIST_PAGE_SIZE, sessionsListQueryCoercion, sessionIdParamSchema$
|
|
269469
|
+
var booleanQueryParam, DEFAULT_SESSION_LIST_PAGE_SIZE, sessionsListQueryCoercion, sessionIdParamSchema$6, sessionChildrenListQueryCoercion, sessionActionTailParamSchema, sessionActionRequestSchema, detailsSchema$5, DEFAULT_UNDO_MESSAGE_PAGE_SIZE, MAX_UNDO_MESSAGE_PAGE_SIZE;
|
|
267515
269470
|
var init_sessions = __esmMin((() => {
|
|
267516
269471
|
init_src$6();
|
|
267517
269472
|
init_error_codes();
|
|
@@ -267555,7 +269510,7 @@ var init_sessions = __esmMin((() => {
|
|
|
267555
269510
|
params: { code: ErrorCode.VALIDATION_FAILED }
|
|
267556
269511
|
});
|
|
267557
269512
|
});
|
|
267558
|
-
sessionIdParamSchema$
|
|
269513
|
+
sessionIdParamSchema$6 = object({ session_id: string$2().min(1) });
|
|
267559
269514
|
sessionChildrenListQueryCoercion = object({
|
|
267560
269515
|
before_id: string$2().min(1).optional(),
|
|
267561
269516
|
after_id: string$2().min(1).optional(),
|
|
@@ -267577,7 +269532,7 @@ var init_sessions = __esmMin((() => {
|
|
|
267577
269532
|
count: number$2().int().positive().optional(),
|
|
267578
269533
|
page_size: number$2().int().min(1).max(100).optional()
|
|
267579
269534
|
}));
|
|
267580
|
-
detailsSchema$
|
|
269535
|
+
detailsSchema$5 = array$2(object({
|
|
267581
269536
|
path: string$2(),
|
|
267582
269537
|
message: string$2()
|
|
267583
269538
|
}));
|
|
@@ -267585,6 +269540,60 @@ var init_sessions = __esmMin((() => {
|
|
|
267585
269540
|
MAX_UNDO_MESSAGE_PAGE_SIZE = 100;
|
|
267586
269541
|
}));
|
|
267587
269542
|
//#endregion
|
|
269543
|
+
//#region ../../packages/kap-server/src/routes/shell.ts
|
|
269544
|
+
function registerShellRoute(app, core) {
|
|
269545
|
+
const runShellCommandRoute = defineRoute({
|
|
269546
|
+
method: "POST",
|
|
269547
|
+
path: "/sessions/{session_id}/shell",
|
|
269548
|
+
params: sessionIdParamSchema$5,
|
|
269549
|
+
body: shellCommandRequestSchema,
|
|
269550
|
+
success: { data: shellCommandResultSchema },
|
|
269551
|
+
errors: {
|
|
269552
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$4 },
|
|
269553
|
+
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
269554
|
+
},
|
|
269555
|
+
description: "Run a user-initiated `!` shell command in a session",
|
|
269556
|
+
tags: ["sessions"]
|
|
269557
|
+
}, async (req, reply) => {
|
|
269558
|
+
const { session_id } = req.params;
|
|
269559
|
+
const session = await core.accessor.get(ISessionLifecycleService).resume(session_id);
|
|
269560
|
+
if (session === void 0) {
|
|
269561
|
+
reply.send(errEnvelope(ErrorCode.SESSION_NOT_FOUND, `session ${session_id} does not exist`, req.id));
|
|
269562
|
+
return;
|
|
269563
|
+
}
|
|
269564
|
+
const result = await (await ensureMainAgent(session)).accessor.get(IAgentShellCommandService).run({
|
|
269565
|
+
command: req.body.command,
|
|
269566
|
+
commandId: req.body.commandId
|
|
269567
|
+
});
|
|
269568
|
+
reply.send(okEnvelope(result, req.id));
|
|
269569
|
+
});
|
|
269570
|
+
app.post(runShellCommandRoute.path, runShellCommandRoute.options, runShellCommandRoute.handler);
|
|
269571
|
+
}
|
|
269572
|
+
var sessionIdParamSchema$5, shellCommandRequestSchema, shellCommandResultSchema, detailsSchema$4;
|
|
269573
|
+
var init_shell = __esmMin((() => {
|
|
269574
|
+
init_src$6();
|
|
269575
|
+
init_zod$1();
|
|
269576
|
+
init_envelope();
|
|
269577
|
+
init_defineRoute();
|
|
269578
|
+
init_error_codes();
|
|
269579
|
+
init_mainAgent();
|
|
269580
|
+
sessionIdParamSchema$5 = object({ session_id: string$2().min(1) });
|
|
269581
|
+
shellCommandRequestSchema = object({
|
|
269582
|
+
command: string$2(),
|
|
269583
|
+
commandId: string$2().optional()
|
|
269584
|
+
});
|
|
269585
|
+
shellCommandResultSchema = object({
|
|
269586
|
+
stdout: string$2(),
|
|
269587
|
+
stderr: string$2(),
|
|
269588
|
+
isError: boolean$2().optional(),
|
|
269589
|
+
backgrounded: boolean$2().optional()
|
|
269590
|
+
});
|
|
269591
|
+
detailsSchema$4 = array$2(object({
|
|
269592
|
+
path: string$2(),
|
|
269593
|
+
message: string$2()
|
|
269594
|
+
}));
|
|
269595
|
+
}));
|
|
269596
|
+
//#endregion
|
|
267588
269597
|
//#region ../../packages/kap-server/src/routes/shutdown.ts
|
|
267589
269598
|
function registerShutdownRoutes(app, opts) {
|
|
267590
269599
|
const route = defineRoute({
|
|
@@ -269820,6 +271829,11 @@ async function registerApiV1Routes(app, core, opts) {
|
|
|
269820
271829
|
registerConfigRoutes(apiV1, core);
|
|
269821
271830
|
registerModelCatalogRoutes(apiV1, core);
|
|
269822
271831
|
registerSessionsRoutes(apiV1, core);
|
|
271832
|
+
registerShellRoute(apiV1, core);
|
|
271833
|
+
registerEventsRoute(apiV1, {
|
|
271834
|
+
broadcaster: opts.broadcaster,
|
|
271835
|
+
core
|
|
271836
|
+
});
|
|
269823
271837
|
registerSessionExportRoute(apiV1, core, { serverVersion: opts.serverVersion });
|
|
269824
271838
|
registerSkillsRoutes(apiV1, core);
|
|
269825
271839
|
registerMessagesRoutes(apiV1, core);
|
|
@@ -269878,6 +271892,7 @@ var init_registerApiV1Routes = __esmMin((() => {
|
|
|
269878
271892
|
init_guiStore();
|
|
269879
271893
|
init_messages();
|
|
269880
271894
|
init_registerDebugRoutes();
|
|
271895
|
+
init_events();
|
|
269881
271896
|
init_meta();
|
|
269882
271897
|
init_modelCatalog();
|
|
269883
271898
|
init_oauth();
|
|
@@ -269885,6 +271900,7 @@ var init_registerApiV1Routes = __esmMin((() => {
|
|
|
269885
271900
|
init_questions();
|
|
269886
271901
|
init_sessionExport();
|
|
269887
271902
|
init_sessions();
|
|
271903
|
+
init_shell();
|
|
269888
271904
|
init_shutdown();
|
|
269889
271905
|
init_snapshot();
|
|
269890
271906
|
init_skills$1();
|
|
@@ -273846,7 +275862,9 @@ var DEFAULT_MAX_BUFFER_SIZE, DEFAULT_FLUSH_INTERVAL_MS, DEFAULT_MAX_BATCH_SIZE,
|
|
|
273846
275862
|
var init_wsConnectionV1 = __esmMin((() => {
|
|
273847
275863
|
init_ws_control();
|
|
273848
275864
|
init_src$2();
|
|
275865
|
+
init_src$6();
|
|
273849
275866
|
init_node$3();
|
|
275867
|
+
init_error_codes();
|
|
273850
275868
|
init_protocol();
|
|
273851
275869
|
init_sessionEventBroadcaster();
|
|
273852
275870
|
init_fsWatchBridge();
|
|
@@ -273864,6 +275882,7 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
273864
275882
|
socket;
|
|
273865
275883
|
broadcaster;
|
|
273866
275884
|
fsWatchBridge;
|
|
275885
|
+
core;
|
|
273867
275886
|
validateCredential;
|
|
273868
275887
|
maxBufferSize;
|
|
273869
275888
|
flushIntervalMs;
|
|
@@ -273875,6 +275894,12 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
273875
275894
|
/** Per-session subscription state: legacy agent allowlist + opt-in transcript grades. */
|
|
273876
275895
|
subscriptions = /* @__PURE__ */ new Map();
|
|
273877
275896
|
/**
|
|
275897
|
+
* Terminal services this connection has attached to (one per session,
|
|
275898
|
+
* resolved lazily). Tracked so teardown can detach every terminal sink
|
|
275899
|
+
* the connection owns.
|
|
275900
|
+
*/
|
|
275901
|
+
terminalServices = /* @__PURE__ */ new Set();
|
|
275902
|
+
/**
|
|
273878
275903
|
* Serializes control-frame handling in receive order. Frames arrive
|
|
273879
275904
|
* back-to-back (e.g. `client_hello` immediately followed by
|
|
273880
275905
|
* `subscribe_v2`), and a later handler reads subscription state the
|
|
@@ -273896,6 +275921,7 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
273896
275921
|
this.socket = opts.socket;
|
|
273897
275922
|
this.broadcaster = opts.broadcaster;
|
|
273898
275923
|
this.fsWatchBridge = opts.fsWatchBridge;
|
|
275924
|
+
this.core = opts.core;
|
|
273899
275925
|
this.validateCredential = opts.validateCredential;
|
|
273900
275926
|
this.logger = opts.logger;
|
|
273901
275927
|
this.maxBufferSize = opts.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;
|
|
@@ -273959,6 +275985,21 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
273959
275985
|
case "watch_fs_remove":
|
|
273960
275986
|
this.enqueueControl(() => this.onWatchFs(frame, false));
|
|
273961
275987
|
return;
|
|
275988
|
+
case "terminal_attach":
|
|
275989
|
+
this.enqueueControl(() => this.onTerminalAttach(frame));
|
|
275990
|
+
return;
|
|
275991
|
+
case "terminal_input":
|
|
275992
|
+
this.enqueueControl(() => this.onTerminalInput(frame));
|
|
275993
|
+
return;
|
|
275994
|
+
case "terminal_resize":
|
|
275995
|
+
this.enqueueControl(() => this.onTerminalResize(frame));
|
|
275996
|
+
return;
|
|
275997
|
+
case "terminal_close":
|
|
275998
|
+
this.enqueueControl(() => this.onTerminalClose(frame));
|
|
275999
|
+
return;
|
|
276000
|
+
case "terminal_detach":
|
|
276001
|
+
this.enqueueControl(() => this.onTerminalDetach(frame));
|
|
276002
|
+
return;
|
|
273962
276003
|
default: return;
|
|
273963
276004
|
}
|
|
273964
276005
|
}
|
|
@@ -274104,6 +276145,120 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
274104
276145
|
}));
|
|
274105
276146
|
}
|
|
274106
276147
|
/**
|
|
276148
|
+
* `terminal_attach` — attach this connection's sink to a session terminal
|
|
276149
|
+
* stream. The sink's frames (`terminal_output` / `terminal_exit`) are
|
|
276150
|
+
* delivered over the same subscription buffer as session events (coalesced
|
|
276151
|
+
* only when mergeable — terminal frames never merge, they just share the
|
|
276152
|
+
* flush window). `since_seq` replays buffered frames past the cursor, like
|
|
276153
|
+
* the REST/WS attach contract.
|
|
276154
|
+
*/
|
|
276155
|
+
async onTerminalAttach(frame) {
|
|
276156
|
+
const parsed = terminalAttachMessageSchema.safeParse(frame);
|
|
276157
|
+
if (!parsed.success) {
|
|
276158
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_attach payload", {}));
|
|
276159
|
+
return;
|
|
276160
|
+
}
|
|
276161
|
+
const { session_id, terminal_id, since_seq } = parsed.data.payload;
|
|
276162
|
+
try {
|
|
276163
|
+
const terminals = await this.resolveTerminalService(session_id);
|
|
276164
|
+
const sink = {
|
|
276165
|
+
id: this.id,
|
|
276166
|
+
send: (terminalFrame) => this.sendSubscribedFrame(terminalFrame)
|
|
276167
|
+
};
|
|
276168
|
+
const { replayed } = await terminals.attach(terminal_id, sink, { sinceSeq: since_seq });
|
|
276169
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", {
|
|
276170
|
+
attached: true,
|
|
276171
|
+
replayed
|
|
276172
|
+
}));
|
|
276173
|
+
} catch (error) {
|
|
276174
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276175
|
+
}
|
|
276176
|
+
}
|
|
276177
|
+
/** `terminal_input` — write bytes to the attached terminal's pty. */
|
|
276178
|
+
async onTerminalInput(frame) {
|
|
276179
|
+
const parsed = terminalInputMessageSchema.safeParse(frame);
|
|
276180
|
+
if (!parsed.success) {
|
|
276181
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_input payload", {}));
|
|
276182
|
+
return;
|
|
276183
|
+
}
|
|
276184
|
+
const { session_id, terminal_id, data } = parsed.data.payload;
|
|
276185
|
+
try {
|
|
276186
|
+
await (await this.resolveTerminalService(session_id)).write(terminal_id, data);
|
|
276187
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", { accepted: true }));
|
|
276188
|
+
} catch (error) {
|
|
276189
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276190
|
+
}
|
|
276191
|
+
}
|
|
276192
|
+
/** `terminal_resize` — resize the attached terminal's pty. */
|
|
276193
|
+
async onTerminalResize(frame) {
|
|
276194
|
+
const parsed = terminalResizeMessageSchema.safeParse(frame);
|
|
276195
|
+
if (!parsed.success) {
|
|
276196
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_resize payload", {}));
|
|
276197
|
+
return;
|
|
276198
|
+
}
|
|
276199
|
+
const { session_id, terminal_id, cols, rows } = parsed.data.payload;
|
|
276200
|
+
try {
|
|
276201
|
+
await (await this.resolveTerminalService(session_id)).resize(terminal_id, cols, rows);
|
|
276202
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", { resized: true }));
|
|
276203
|
+
} catch (error) {
|
|
276204
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276205
|
+
}
|
|
276206
|
+
}
|
|
276207
|
+
/** `terminal_close` — close the terminal's pty (idempotent). */
|
|
276208
|
+
async onTerminalClose(frame) {
|
|
276209
|
+
const parsed = terminalCloseMessageSchema.safeParse(frame);
|
|
276210
|
+
if (!parsed.success) {
|
|
276211
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_close payload", {}));
|
|
276212
|
+
return;
|
|
276213
|
+
}
|
|
276214
|
+
const { session_id, terminal_id } = parsed.data.payload;
|
|
276215
|
+
try {
|
|
276216
|
+
await (await this.resolveTerminalService(session_id)).close(terminal_id);
|
|
276217
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", { closed: true }));
|
|
276218
|
+
} catch (error) {
|
|
276219
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276220
|
+
}
|
|
276221
|
+
}
|
|
276222
|
+
/** `terminal_detach` — detach this connection's sink from a terminal stream. */
|
|
276223
|
+
async onTerminalDetach(frame) {
|
|
276224
|
+
const parsed = terminalDetachMessageSchema.safeParse(frame);
|
|
276225
|
+
if (!parsed.success) {
|
|
276226
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_detach payload", {}));
|
|
276227
|
+
return;
|
|
276228
|
+
}
|
|
276229
|
+
const { session_id, terminal_id } = parsed.data.payload;
|
|
276230
|
+
try {
|
|
276231
|
+
(await this.resolveTerminalService(session_id)).detach(terminal_id, this.id);
|
|
276232
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", { detached: true }));
|
|
276233
|
+
} catch (error) {
|
|
276234
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276235
|
+
}
|
|
276236
|
+
}
|
|
276237
|
+
/**
|
|
276238
|
+
* Resolve a session's `ISessionTerminalService` (cold-loading a
|
|
276239
|
+
* persisted-but-not-live session, matching the REST terminal route).
|
|
276240
|
+
* The resolved service is remembered so `onClose` can detach every sink
|
|
276241
|
+
* this connection owns.
|
|
276242
|
+
*/
|
|
276243
|
+
async resolveTerminalService(sessionId) {
|
|
276244
|
+
const session = await this.core.accessor.get(ISessionLifecycleService).resume(sessionId);
|
|
276245
|
+
if (session === void 0) throw new Error2(ErrorCodes.SESSION_NOT_FOUND, `session ${sessionId} does not exist`);
|
|
276246
|
+
const terminals = session.accessor.get(ISessionTerminalService);
|
|
276247
|
+
this.terminalServices.add(terminals);
|
|
276248
|
+
return terminals;
|
|
276249
|
+
}
|
|
276250
|
+
/** Ack a terminal control failure with the wire error code when known. */
|
|
276251
|
+
sendTerminalErrorAck(id, error) {
|
|
276252
|
+
let code = 1;
|
|
276253
|
+
let msg = "internal error";
|
|
276254
|
+
if (isError2(error)) {
|
|
276255
|
+
if (error.code === ErrorCodes.SESSION_NOT_FOUND) code = ErrorCode.SESSION_NOT_FOUND;
|
|
276256
|
+
else if (error.code === ErrorCodes.TERMINAL_NOT_FOUND) code = ErrorCode.TERMINAL_NOT_FOUND;
|
|
276257
|
+
msg = error.message;
|
|
276258
|
+
} else if (error instanceof Error) msg = error.message;
|
|
276259
|
+
this.sendImmediateFrame(buildAck(id ?? "", code, msg, {}));
|
|
276260
|
+
}
|
|
276261
|
+
/**
|
|
274107
276262
|
* Shared attach path behind `client_hello` (legacy inline subscriptions)
|
|
274108
276263
|
* and `subscribe`. Subscribes the connection via the broadcaster, then
|
|
274109
276264
|
* either replays durable events since the client's cursor (with the
|
|
@@ -274248,6 +276403,7 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
274248
276403
|
this.outbound = [];
|
|
274249
276404
|
this.broadcaster.removeGlobalTarget(this);
|
|
274250
276405
|
for (const sid of this.subscriptions.keys()) this.broadcaster.unsubscribe(sid, this);
|
|
276406
|
+
for (const terminals of this.terminalServices) terminals.detachAllForSink(this.id);
|
|
274251
276407
|
this.fsWatchBridge?.detachConnection(this);
|
|
274252
276408
|
}
|
|
274253
276409
|
};
|
|
@@ -274266,6 +276422,7 @@ function registerWsV1(core, opts) {
|
|
|
274266
276422
|
broadcaster,
|
|
274267
276423
|
fsWatchBridge: opts.fsWatchBridge,
|
|
274268
276424
|
connectionRegistry: registry,
|
|
276425
|
+
core,
|
|
274269
276426
|
validateCredential: opts.validateCredential,
|
|
274270
276427
|
remoteAddress: req.socket.remoteAddress ?? null,
|
|
274271
276428
|
userAgent: req.headers["user-agent"] ?? null,
|
|
@@ -296567,6 +298724,15 @@ function stringifyToolOutput(output) {
|
|
|
296567
298724
|
if (typeof output === "string") return output;
|
|
296568
298725
|
return JSON.stringify(output) ?? String(output);
|
|
296569
298726
|
}
|
|
298727
|
+
function stringifyToolArgs(args) {
|
|
298728
|
+
if (typeof args === "string") return args;
|
|
298729
|
+
return JSON.stringify(args) ?? String(args);
|
|
298730
|
+
}
|
|
298731
|
+
function truncateChars(text, max) {
|
|
298732
|
+
if (text.length <= max) return text;
|
|
298733
|
+
const suffix = `… (${text.length - max} more chars)`;
|
|
298734
|
+
return `${text.slice(0, max - suffix.length)}${suffix}`;
|
|
298735
|
+
}
|
|
296570
298736
|
function writeVersion(version, outputFormat, stdout, stderr) {
|
|
296571
298737
|
if (outputFormat === "stream-json") {
|
|
296572
298738
|
const message = {
|
|
@@ -296595,16 +298761,23 @@ function writeResumeHint(sessionId, outputFormat, stdout, stderr) {
|
|
|
296595
298761
|
}
|
|
296596
298762
|
stderr.write(`${content}\n`);
|
|
296597
298763
|
}
|
|
296598
|
-
var PROMPT_BLOCK_BULLET, PROMPT_BLOCK_INDENT, PromptTranscriptWriter, PromptJsonWriter, PromptBlockWriter;
|
|
298764
|
+
var PROMPT_BLOCK_BULLET, PROMPT_BLOCK_INDENT, TOOL_CALL_MARK, TOOL_RESULT_MARK, RETRY_MARK, MAX_TOOL_CALL_ARGS_CHARS, MAX_TOOL_RESULT_CHARS, PromptTranscriptWriter, PromptJsonWriter, PromptBlockWriter;
|
|
296599
298765
|
var init_prompt_render = __esmMin((() => {
|
|
296600
298766
|
PROMPT_BLOCK_BULLET = "• ";
|
|
296601
298767
|
PROMPT_BLOCK_INDENT = " ";
|
|
298768
|
+
TOOL_CALL_MARK = "⚒ ";
|
|
298769
|
+
TOOL_RESULT_MARK = "⚒ result: ";
|
|
298770
|
+
RETRY_MARK = "↻ retry";
|
|
298771
|
+
MAX_TOOL_CALL_ARGS_CHARS = 500;
|
|
298772
|
+
MAX_TOOL_RESULT_CHARS = 2e3;
|
|
296602
298773
|
PromptTranscriptWriter = class {
|
|
296603
298774
|
assistantWriter;
|
|
296604
298775
|
thinkingWriter;
|
|
298776
|
+
toolWriter;
|
|
296605
298777
|
constructor(stdout, stderr) {
|
|
296606
298778
|
this.assistantWriter = new PromptBlockWriter(stdout);
|
|
296607
298779
|
this.thinkingWriter = new PromptBlockWriter(stderr);
|
|
298780
|
+
this.toolWriter = new PromptBlockWriter(stderr);
|
|
296608
298781
|
}
|
|
296609
298782
|
writeAssistantDelta(delta) {
|
|
296610
298783
|
this.thinkingWriter.finish();
|
|
@@ -296619,10 +298792,25 @@ var init_prompt_render = __esmMin((() => {
|
|
|
296619
298792
|
writeThinkingDelta(delta) {
|
|
296620
298793
|
this.thinkingWriter.write(delta);
|
|
296621
298794
|
}
|
|
296622
|
-
writeToolCall() {
|
|
298795
|
+
writeToolCall(toolCallId, name, args) {
|
|
298796
|
+
this.thinkingWriter.finish();
|
|
298797
|
+
this.assistantWriter.finish();
|
|
298798
|
+
this.toolWriter.write(`${TOOL_CALL_MARK}${name}(${truncateChars(stringifyToolArgs(args), MAX_TOOL_CALL_ARGS_CHARS)})`);
|
|
298799
|
+
this.toolWriter.finish();
|
|
298800
|
+
}
|
|
296623
298801
|
writeToolCallDelta() {}
|
|
296624
|
-
writeToolResult() {
|
|
296625
|
-
|
|
298802
|
+
writeToolResult(toolCallId, output) {
|
|
298803
|
+
this.toolWriter.finish();
|
|
298804
|
+
this.toolWriter.write(`${TOOL_RESULT_MARK}${truncateChars(stringifyToolOutput(output), MAX_TOOL_RESULT_CHARS)}`);
|
|
298805
|
+
this.toolWriter.finish();
|
|
298806
|
+
}
|
|
298807
|
+
writeRetrying(event) {
|
|
298808
|
+
this.thinkingWriter.finish();
|
|
298809
|
+
this.assistantWriter.finish();
|
|
298810
|
+
const error = [event.errorName, event.errorMessage].filter(Boolean).join(": ");
|
|
298811
|
+
this.toolWriter.write(`${RETRY_MARK} ${event.failedAttempt}/${event.maxAttempts} (${error}) — ${event.delayMs}ms`);
|
|
298812
|
+
this.toolWriter.finish();
|
|
298813
|
+
}
|
|
296626
298814
|
flushAssistant() {
|
|
296627
298815
|
this.assistantWriter.finish();
|
|
296628
298816
|
}
|
|
@@ -296630,6 +298818,7 @@ var init_prompt_render = __esmMin((() => {
|
|
|
296630
298818
|
finish() {
|
|
296631
298819
|
this.thinkingWriter.finish();
|
|
296632
298820
|
this.assistantWriter.finish();
|
|
298821
|
+
this.toolWriter.finish();
|
|
296633
298822
|
}
|
|
296634
298823
|
};
|
|
296635
298824
|
PromptJsonWriter = class {
|