@dimi-agent/cli 0.6.7 → 0.6.8
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 +2279 -92
- package/package.json +4 -4
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,1504 @@ 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
|
+
try {
|
|
215399
|
+
const model = this.modelCatalog.get(modelAlias);
|
|
215400
|
+
baseUrl = model.baseUrl;
|
|
215401
|
+
apiKey = (await this.providerRuntime.getAuth(model))?.auth.apiKey ?? "";
|
|
215402
|
+
} catch {}
|
|
215403
|
+
return {
|
|
215404
|
+
baseUrl: baseUrl || "https://api.openai.com/v1",
|
|
215405
|
+
apiKey,
|
|
215406
|
+
model: modelAlias || "gpt-4o",
|
|
215407
|
+
thinkingEffort: this.profile.getEffectiveThinkingLevel()
|
|
215408
|
+
};
|
|
215409
|
+
}
|
|
215410
|
+
};
|
|
215411
|
+
RustEngineTurnRunner = __decorate$1([
|
|
215412
|
+
__decorateParam(0, IAgentContextMemoryService),
|
|
215413
|
+
__decorateParam(1, IEventBus),
|
|
215414
|
+
__decorateParam(2, IWireService),
|
|
215415
|
+
__decorateParam(3, IConfigService),
|
|
215416
|
+
__decorateParam(4, IAgentPermissionModeService),
|
|
215417
|
+
__decorateParam(5, IAgentPermissionRulesService),
|
|
215418
|
+
__decorateParam(6, IAgentToolRegistryService),
|
|
215419
|
+
__decorateParam(7, IAgentUsageService),
|
|
215420
|
+
__decorateParam(8, IAgentProfileService),
|
|
215421
|
+
__decorateParam(9, IAgentScopeContext),
|
|
215422
|
+
__decorateParam(10, ISessionContext),
|
|
215423
|
+
__decorateParam(11, ISessionMetadata),
|
|
215424
|
+
__decorateParam(12, IAgentTaskService),
|
|
215425
|
+
__decorateParam(13, IModelCatalog),
|
|
215426
|
+
__decorateParam(14, IProviderRuntime),
|
|
215427
|
+
__decorateParam(15, IInstantiationService),
|
|
215428
|
+
__decorateParam(16, IAgentToolPolicyService),
|
|
215429
|
+
__decorateParam(17, ILogService)
|
|
215430
|
+
], RustEngineTurnRunner);
|
|
215431
|
+
registerScopedService(2, IRustEngineTurnRunner, RustEngineTurnRunner, 0, "rustEngineTurnRunner");
|
|
215432
|
+
}));
|
|
215433
|
+
//#endregion
|
|
213604
215434
|
//#region ../../packages/agent-core-v2/src/agent/rpc/prompt-metadata.ts
|
|
213605
215435
|
function promptMetadataTextFromPayload(payload) {
|
|
213606
215436
|
return promptMetadataTextFromContentParts(payload.input);
|
|
@@ -213669,6 +215499,7 @@ var init_rpcService = __esmMin((() => {
|
|
|
213669
215499
|
init_telemetry$2();
|
|
213670
215500
|
init_toolRegistry();
|
|
213671
215501
|
init_loop();
|
|
215502
|
+
init_rustEngineTurnRunner();
|
|
213672
215503
|
init_rpc$2();
|
|
213673
215504
|
init_prompt_metadata();
|
|
213674
215505
|
init_decorateParam();
|
|
@@ -213692,7 +215523,8 @@ var init_rpcService = __esmMin((() => {
|
|
|
213692
215523
|
sessionContext;
|
|
213693
215524
|
scopeContext;
|
|
213694
215525
|
agentLifecycle;
|
|
213695
|
-
|
|
215526
|
+
rustEngineTurnRunner;
|
|
215527
|
+
constructor(promptService, conversationUndo, loop, toolPolicy, permissionMode, fullCompaction, toolRegistry, context, contextSize, skills, telemetry, eventBus, eventService, plugins, metadata, sessionContext, scopeContext, agentLifecycle, rustEngineTurnRunner) {
|
|
213696
215528
|
this.promptService = promptService;
|
|
213697
215529
|
this.conversationUndo = conversationUndo;
|
|
213698
215530
|
this.loop = loop;
|
|
@@ -213711,6 +215543,7 @@ var init_rpcService = __esmMin((() => {
|
|
|
213711
215543
|
this.sessionContext = sessionContext;
|
|
213712
215544
|
this.scopeContext = scopeContext;
|
|
213713
215545
|
this.agentLifecycle = agentLifecycle;
|
|
215546
|
+
this.rustEngineTurnRunner = rustEngineTurnRunner;
|
|
213714
215547
|
}
|
|
213715
215548
|
async prompt(payload) {
|
|
213716
215549
|
if (payload.disabledTools !== void 0) try {
|
|
@@ -213720,6 +215553,13 @@ var init_rpcService = __esmMin((() => {
|
|
|
213720
215553
|
throw error;
|
|
213721
215554
|
}
|
|
213722
215555
|
await this.updatePromptMetadata(promptMetadataTextFromPayload(payload));
|
|
215556
|
+
if (RustEngineTurnRunner.isEnabled()) {
|
|
215557
|
+
const launched = await this.rustEngineTurnRunner.runTurn({
|
|
215558
|
+
input: [...payload.input],
|
|
215559
|
+
origin: { kind: "user" }
|
|
215560
|
+
});
|
|
215561
|
+
return launched === void 0 ? void 0 : { turn_id: launched.turnId };
|
|
215562
|
+
}
|
|
213723
215563
|
const handle = await this.promptService.enqueue({ message: {
|
|
213724
215564
|
role: "user",
|
|
213725
215565
|
content: [...payload.input],
|
|
@@ -213732,6 +215572,17 @@ var init_rpcService = __esmMin((() => {
|
|
|
213732
215572
|
}
|
|
213733
215573
|
async steer(payload) {
|
|
213734
215574
|
this.telemetry.track2("input_steer", { parts: payload.input.length });
|
|
215575
|
+
if (RustEngineTurnRunner.isEnabled()) {
|
|
215576
|
+
if (this.rustEngineTurnRunner.steer({
|
|
215577
|
+
input: [...payload.input],
|
|
215578
|
+
origin: { kind: "user" }
|
|
215579
|
+
})) return { turn_id: 0 };
|
|
215580
|
+
const launched = await this.rustEngineTurnRunner.runTurn({
|
|
215581
|
+
input: [...payload.input],
|
|
215582
|
+
origin: { kind: "user" }
|
|
215583
|
+
});
|
|
215584
|
+
return launched === void 0 ? void 0 : { turn_id: launched.turnId };
|
|
215585
|
+
}
|
|
213735
215586
|
const submitted = await this.promptService.enqueueOrSteer({ message: {
|
|
213736
215587
|
role: "user",
|
|
213737
215588
|
content: [...payload.input],
|
|
@@ -213742,6 +215593,10 @@ var init_rpcService = __esmMin((() => {
|
|
|
213742
215593
|
return turn === void 0 ? void 0 : { turn_id: turn.id };
|
|
213743
215594
|
}
|
|
213744
215595
|
cancel({ turnId }) {
|
|
215596
|
+
if (RustEngineTurnRunner.isEnabled()) {
|
|
215597
|
+
this.rustEngineTurnRunner.cancel(turnId);
|
|
215598
|
+
return;
|
|
215599
|
+
}
|
|
213745
215600
|
if (this.loop.status().state === "running") this.telemetry.track2("cancel", {
|
|
213746
215601
|
from: "streaming",
|
|
213747
215602
|
trace_id: this.loop.status().activeTraceId
|
|
@@ -213846,7 +215701,8 @@ var init_rpcService = __esmMin((() => {
|
|
|
213846
215701
|
__decorateParam(14, ISessionMetadata),
|
|
213847
215702
|
__decorateParam(15, ISessionContext),
|
|
213848
215703
|
__decorateParam(16, IAgentScopeContext),
|
|
213849
|
-
__decorateParam(17, IAgentLifecycleService)
|
|
215704
|
+
__decorateParam(17, IAgentLifecycleService),
|
|
215705
|
+
__decorateParam(18, IRustEngineTurnRunner)
|
|
213850
215706
|
], AgentRPCService);
|
|
213851
215707
|
registerScopedService(2, IAgentRPCService, AgentRPCService, 0, "rpc");
|
|
213852
215708
|
}));
|
|
@@ -216423,13 +218279,6 @@ var init_args_validator = __esmMin((() => {
|
|
|
216423
218279
|
]);
|
|
216424
218280
|
}));
|
|
216425
218281
|
//#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
218282
|
//#region ../../packages/agent-core-v2/src/agent/toolExecutor/toolScheduler.ts
|
|
216434
218283
|
function createControlledPromise() {
|
|
216435
218284
|
let resolve;
|
|
@@ -217493,7 +219342,7 @@ var init_src$6 = __esmMin((() => {
|
|
|
217493
219342
|
init_migration();
|
|
217494
219343
|
init_sessionLogService();
|
|
217495
219344
|
init_telemetry$2();
|
|
217496
|
-
init_events$
|
|
219345
|
+
init_events$8();
|
|
217497
219346
|
init_telemetryService();
|
|
217498
219347
|
init_agentTelemetryContext();
|
|
217499
219348
|
init_agentTelemetryContextService();
|
|
@@ -217688,6 +219537,8 @@ var init_src$6 = __esmMin((() => {
|
|
|
217688
219537
|
init_wait();
|
|
217689
219538
|
init_waitService();
|
|
217690
219539
|
init_waitForTool();
|
|
219540
|
+
init_agent_output$1();
|
|
219541
|
+
init_agentOutputTool();
|
|
217691
219542
|
init_completion();
|
|
217692
219543
|
init_allDoneTool();
|
|
217693
219544
|
init_configSection$4();
|
|
@@ -218578,7 +220429,7 @@ var modelCatalogItemSchema$1, providerCatalogStatusSchema$1, providerCatalogItem
|
|
|
218578
220429
|
provider: string$2().min(1),
|
|
218579
220430
|
reason: string$2().min(1)
|
|
218580
220431
|
});
|
|
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$
|
|
220432
|
+
})), 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
220433
|
init_zod$1();
|
|
218583
220434
|
init_display$1();
|
|
218584
220435
|
init_message$1();
|
|
@@ -219352,7 +221203,7 @@ var modelCatalogItemSchema$1, providerCatalogStatusSchema$1, providerCatalogItem
|
|
|
219352
221203
|
})), 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
221204
|
var init_ws_control$1 = __esmMin((() => {
|
|
219354
221205
|
init_zod$1();
|
|
219355
|
-
init_events$
|
|
221206
|
+
init_events$7();
|
|
219356
221207
|
init_time();
|
|
219357
221208
|
sessionCursorSchema$1 = object({
|
|
219358
221209
|
seq: number$2().int().nonnegative(),
|
|
@@ -219897,7 +221748,7 @@ var init_tool$2 = __esmMin((() => {
|
|
|
219897
221748
|
var skillDescriptorSchema$1;
|
|
219898
221749
|
var init_skill$2 = __esmMin((() => {
|
|
219899
221750
|
init_zod$1();
|
|
219900
|
-
init_events$
|
|
221751
|
+
init_events$7();
|
|
219901
221752
|
skillDescriptorSchema$1 = object({
|
|
219902
221753
|
name: string$2().min(1),
|
|
219903
221754
|
description: string$2(),
|
|
@@ -220630,7 +222481,7 @@ var init_src$5 = __esmMin((() => {
|
|
|
220630
222481
|
init_pagination$1();
|
|
220631
222482
|
init_time();
|
|
220632
222483
|
init_request_id$2();
|
|
220633
|
-
init_events$
|
|
222484
|
+
init_events$7();
|
|
220634
222485
|
init_display$1();
|
|
220635
222486
|
init_ws_control$1();
|
|
220636
222487
|
init_asyncapi$1();
|
|
@@ -220669,7 +222520,7 @@ var init_src$5 = __esmMin((() => {
|
|
|
220669
222520
|
}));
|
|
220670
222521
|
//#endregion
|
|
220671
222522
|
//#region ../../packages/node-sdk/src/events.ts
|
|
220672
|
-
var init_events$
|
|
222523
|
+
var init_events$6 = __esmMin((() => {
|
|
220673
222524
|
init_src$5();
|
|
220674
222525
|
}));
|
|
220675
222526
|
//#endregion
|
|
@@ -220724,7 +222575,7 @@ var MAIN_AGENT_ID$6, Session;
|
|
|
220724
222575
|
var init_session$3 = __esmMin((() => {
|
|
220725
222576
|
init_src$6();
|
|
220726
222577
|
init_errors$3();
|
|
220727
|
-
init_events$
|
|
222578
|
+
init_events$6();
|
|
220728
222579
|
MAIN_AGENT_ID$6 = "main";
|
|
220729
222580
|
Session = class {
|
|
220730
222581
|
id;
|
|
@@ -221753,7 +223604,7 @@ var init_helpers = __esmMin((() => {
|
|
|
221753
223604
|
removed: array$2(string$2()),
|
|
221754
223605
|
changed: array$2(string$2())
|
|
221755
223606
|
});
|
|
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;
|
|
223607
|
+
})), 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
223608
|
var init_rpc$1 = __esmMin((() => {
|
|
221758
223609
|
init_zod$1();
|
|
221759
223610
|
init_helpers();
|
|
@@ -221792,7 +223643,7 @@ var init_rpc$1 = __esmMin((() => {
|
|
|
221792
223643
|
command: string$2(),
|
|
221793
223644
|
commandId: string$2().optional()
|
|
221794
223645
|
});
|
|
221795
|
-
shellCommandResultSchema = object({
|
|
223646
|
+
shellCommandResultSchema$1 = object({
|
|
221796
223647
|
stdout: string$2(),
|
|
221797
223648
|
stderr: string$2(),
|
|
221798
223649
|
isError: boolean$2().optional(),
|
|
@@ -221924,7 +223775,7 @@ var init_services = __esmMin((() => {
|
|
|
221924
223775
|
agentShellCommandContract = {
|
|
221925
223776
|
run: {
|
|
221926
223777
|
input: tuple([runShellCommandPayloadSchema]),
|
|
221927
|
-
output: shellCommandResultSchema
|
|
223778
|
+
output: shellCommandResultSchema$1
|
|
221928
223779
|
},
|
|
221929
223780
|
cancel: {
|
|
221930
223781
|
input: tuple([string$2()]),
|
|
@@ -222868,7 +224719,7 @@ var init_contract$1 = __esmMin((() => {
|
|
|
222868
224719
|
//#endregion
|
|
222869
224720
|
//#region ../../packages/klient/src/contract/global/events.ts
|
|
222870
224721
|
var configChangedSchema, reloadSummarySchema, sessionMetaUpdatedSchema, globalEvents;
|
|
222871
|
-
var init_events$
|
|
224722
|
+
var init_events$5 = __esmMin((() => {
|
|
222872
224723
|
init_zod$1();
|
|
222873
224724
|
configChangedSchema = object({
|
|
222874
224725
|
domain: string$2(),
|
|
@@ -222932,7 +224783,7 @@ var init_events$4 = __esmMin((() => {
|
|
|
222932
224783
|
//#endregion
|
|
222933
224784
|
//#region ../../packages/klient/src/contract/session/events.ts
|
|
222934
224785
|
var sessionEvents;
|
|
222935
|
-
var init_events$
|
|
224786
|
+
var init_events$4 = __esmMin((() => {
|
|
222936
224787
|
init_zod$1();
|
|
222937
224788
|
init_interaction$1();
|
|
222938
224789
|
init_metadata();
|
|
@@ -222958,7 +224809,7 @@ var init_events$3 = __esmMin((() => {
|
|
|
222958
224809
|
//#endregion
|
|
222959
224810
|
//#region ../../packages/klient/src/contract/agent/events.ts
|
|
222960
224811
|
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$
|
|
224812
|
+
var init_events$3 = __esmMin((() => {
|
|
222962
224813
|
init_zod$1();
|
|
222963
224814
|
turnStartedEventSchema$1 = object({
|
|
222964
224815
|
type: literal("turn.started"),
|
|
@@ -223592,9 +225443,9 @@ function createKlientFromChannel(channel, options = {}) {
|
|
|
223592
225443
|
}
|
|
223593
225444
|
var init_klient = __esmMin((() => {
|
|
223594
225445
|
init_contract$1();
|
|
225446
|
+
init_events$5();
|
|
223595
225447
|
init_events$4();
|
|
223596
225448
|
init_events$3();
|
|
223597
|
-
init_events$2();
|
|
223598
225449
|
init_hub();
|
|
223599
225450
|
init_global();
|
|
223600
225451
|
init_session$2();
|
|
@@ -226020,7 +227871,7 @@ var init_src$4 = __esmMin((() => {
|
|
|
226020
227871
|
init_errors$3();
|
|
226021
227872
|
init_logging();
|
|
226022
227873
|
init_src$6();
|
|
226023
|
-
init_events$
|
|
227874
|
+
init_events$6();
|
|
226024
227875
|
}));
|
|
226025
227876
|
//#endregion
|
|
226026
227877
|
//#region ../../packages/telemetry/src/index.ts
|
|
@@ -232272,7 +234123,7 @@ var init_schema$1 = __esmMin((() => {
|
|
|
232272
234123
|
seq: transcriptSeqSchema.optional()
|
|
232273
234124
|
});
|
|
232274
234125
|
})), transcriptResetEventSchema, transcriptOpsEventSchema;
|
|
232275
|
-
var init_events$
|
|
234126
|
+
var init_events$2 = __esmMin((() => {
|
|
232276
234127
|
init_zod$1();
|
|
232277
234128
|
init_schema$1();
|
|
232278
234129
|
transcriptResetEventSchema = transcriptResetPayloadSchema.extend({ type: literal("transcript.reset") });
|
|
@@ -232303,7 +234154,7 @@ var init_src$2 = __esmMin((() => {
|
|
|
232303
234154
|
init_groupTurns();
|
|
232304
234155
|
init_foldFacts();
|
|
232305
234156
|
init_schema$1();
|
|
232306
|
-
init_events$
|
|
234157
|
+
init_events$2();
|
|
232307
234158
|
}));
|
|
232308
234159
|
//#endregion
|
|
232309
234160
|
//#region ../../packages/agent-core-v2/src/agent/contextMemory/protocolMessage.ts
|
|
@@ -259106,7 +260957,7 @@ function isVolatileEventType(type) {
|
|
|
259106
260957
|
return volatileEventTypeSet.has(type);
|
|
259107
260958
|
}
|
|
259108
260959
|
var VOLATILE_EVENT_TYPES, volatileEventTypeSet;
|
|
259109
|
-
var init_events = __esmMin((() => {
|
|
260960
|
+
var init_events$1 = __esmMin((() => {
|
|
259110
260961
|
VOLATILE_EVENT_TYPES = [
|
|
259111
260962
|
"assistant.delta",
|
|
259112
260963
|
"thinking.delta",
|
|
@@ -259344,11 +261195,11 @@ function registerApprovalsRoutes(app, core) {
|
|
|
259344
261195
|
const listRoute = defineRoute({
|
|
259345
261196
|
method: "GET",
|
|
259346
261197
|
path: "/sessions/{session_id}/approvals",
|
|
259347
|
-
params: sessionIdParamSchema$
|
|
261198
|
+
params: sessionIdParamSchema$10,
|
|
259348
261199
|
querystring: listPendingApprovalsQuerySchema,
|
|
259349
261200
|
success: { data: listPendingApprovalsResponseSchema },
|
|
259350
261201
|
errors: {
|
|
259351
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
261202
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$8 },
|
|
259352
261203
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
259353
261204
|
},
|
|
259354
261205
|
description: "List pending approval requests for a session",
|
|
@@ -259371,7 +261222,7 @@ function registerApprovalsRoutes(app, core) {
|
|
|
259371
261222
|
body: approvalResolveRequestSchema,
|
|
259372
261223
|
success: { data: approvalResolveResultSchema },
|
|
259373
261224
|
errors: {
|
|
259374
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
261225
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$8 },
|
|
259375
261226
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
259376
261227
|
[ErrorCode.APPROVAL_NOT_FOUND]: {},
|
|
259377
261228
|
[ErrorCode.APPROVAL_ALREADY_RESOLVED]: { dataSchema: approvalAlreadyResolvedDataSchema }
|
|
@@ -259434,7 +261285,7 @@ function toWireApproval(interaction, sessionId) {
|
|
|
259434
261285
|
expires_at: new Date(interaction.createdAt + APPROVAL_EXPIRY_MS).toISOString()
|
|
259435
261286
|
};
|
|
259436
261287
|
}
|
|
259437
|
-
var sessionIdParamSchema$
|
|
261288
|
+
var sessionIdParamSchema$10, approvalParamsSchema, detailsSchema$8, APPROVAL_EXPIRY_MS;
|
|
259438
261289
|
var init_approvals = __esmMin((() => {
|
|
259439
261290
|
init_src$6();
|
|
259440
261291
|
init_error_codes();
|
|
@@ -259443,12 +261294,12 @@ var init_approvals = __esmMin((() => {
|
|
|
259443
261294
|
init_envelope();
|
|
259444
261295
|
init_requestLog();
|
|
259445
261296
|
init_defineRoute();
|
|
259446
|
-
sessionIdParamSchema$
|
|
261297
|
+
sessionIdParamSchema$10 = object({ session_id: string$2().min(1) });
|
|
259447
261298
|
approvalParamsSchema = object({
|
|
259448
261299
|
session_id: string$2().min(1),
|
|
259449
261300
|
approval_id: string$2().min(1)
|
|
259450
261301
|
});
|
|
259451
|
-
detailsSchema$
|
|
261302
|
+
detailsSchema$8 = array$2(object({
|
|
259452
261303
|
path: string$2(),
|
|
259453
261304
|
message: string$2()
|
|
259454
261305
|
}));
|
|
@@ -259507,11 +261358,11 @@ function registerQuestionsRoutes(app, core) {
|
|
|
259507
261358
|
const listRoute = defineRoute({
|
|
259508
261359
|
method: "GET",
|
|
259509
261360
|
path: "/sessions/{session_id}/questions",
|
|
259510
|
-
params: sessionIdParamSchema$
|
|
261361
|
+
params: sessionIdParamSchema$9,
|
|
259511
261362
|
querystring: listPendingQuestionsQuerySchema,
|
|
259512
261363
|
success: { data: listPendingQuestionsResponseSchema },
|
|
259513
261364
|
errors: {
|
|
259514
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
261365
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$7 },
|
|
259515
261366
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
259516
261367
|
},
|
|
259517
261368
|
description: "List pending question requests for a session",
|
|
@@ -259533,7 +261384,7 @@ function registerQuestionsRoutes(app, core) {
|
|
|
259533
261384
|
params: tailParamsSchema,
|
|
259534
261385
|
success: { data: questionResolveResultSchema },
|
|
259535
261386
|
errors: {
|
|
259536
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
261387
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$7 },
|
|
259537
261388
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
259538
261389
|
[ErrorCode.QUESTION_NOT_FOUND]: {},
|
|
259539
261390
|
[ErrorCode.APPROVAL_ALREADY_RESOLVED]: { dataSchema: questionAlreadyResolvedDataSchema },
|
|
@@ -259717,7 +261568,7 @@ function toInProcessResponse(resp, request) {
|
|
|
259717
261568
|
if (resp.method !== void 0 && resp.method !== "click") out.method = resp.method;
|
|
259718
261569
|
return out;
|
|
259719
261570
|
}
|
|
259720
|
-
var sessionIdParamSchema$
|
|
261571
|
+
var sessionIdParamSchema$9, tailParamsSchema, detailsSchema$7;
|
|
259721
261572
|
var init_questions = __esmMin((() => {
|
|
259722
261573
|
init_src$6();
|
|
259723
261574
|
init_error_codes();
|
|
@@ -259728,12 +261579,12 @@ var init_questions = __esmMin((() => {
|
|
|
259728
261579
|
init_requestLog();
|
|
259729
261580
|
init_defineRoute();
|
|
259730
261581
|
init_action_suffix();
|
|
259731
|
-
sessionIdParamSchema$
|
|
261582
|
+
sessionIdParamSchema$9 = object({ session_id: string$2().min(1) });
|
|
259732
261583
|
tailParamsSchema = object({
|
|
259733
261584
|
session_id: string$2().min(1),
|
|
259734
261585
|
tail: string$2().min(1)
|
|
259735
261586
|
});
|
|
259736
|
-
detailsSchema$
|
|
261587
|
+
detailsSchema$7 = array$2(object({
|
|
259737
261588
|
path: string$2(),
|
|
259738
261589
|
message: string$2()
|
|
259739
261590
|
}));
|
|
@@ -260411,7 +262262,7 @@ function sessionCreatedPayload(payload) {
|
|
|
260411
262262
|
var GLOBAL_SESSION_ID, TRANSCRIPT_RESET_TAIL_TURNS, SessionEventBroadcaster, volatileSignalTypeSet, TRANSCRIPT_PROJECTED_EVENT_TYPES;
|
|
260412
262263
|
var init_sessionEventBroadcaster = __esmMin((() => {
|
|
260413
262264
|
init_src$6();
|
|
260414
|
-
init_events();
|
|
262265
|
+
init_events$1();
|
|
260415
262266
|
init_src$2();
|
|
260416
262267
|
init_approvals();
|
|
260417
262268
|
init_questions();
|
|
@@ -264961,11 +266812,11 @@ function registerMessagesRoutes(app, core) {
|
|
|
264961
266812
|
const listRoute = defineRoute({
|
|
264962
266813
|
method: "GET",
|
|
264963
266814
|
path: "/sessions/{session_id}/messages",
|
|
264964
|
-
params: sessionIdParamSchema$
|
|
266815
|
+
params: sessionIdParamSchema$8,
|
|
264965
266816
|
querystring: messagesListQueryCoercion,
|
|
264966
266817
|
success: { data: listMessagesResponseSchema },
|
|
264967
266818
|
errors: {
|
|
264968
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
266819
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$6 },
|
|
264969
266820
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
264970
266821
|
},
|
|
264971
266822
|
description: "List messages for a session",
|
|
@@ -264986,7 +266837,7 @@ function registerMessagesRoutes(app, core) {
|
|
|
264986
266837
|
params: messageIdParamSchema,
|
|
264987
266838
|
success: { data: getMessageResponseSchema },
|
|
264988
266839
|
errors: {
|
|
264989
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
266840
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$6 },
|
|
264990
266841
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
264991
266842
|
[ErrorCode.MESSAGE_NOT_FOUND]: {}
|
|
264992
266843
|
},
|
|
@@ -265023,7 +266874,7 @@ function sendMappedError$7(reply, req, err) {
|
|
|
265023
266874
|
log?.error({ err }, "message request failed");
|
|
265024
266875
|
reply.send(errEnvelope(ErrorCode.INTERNAL_ERROR, err instanceof Error ? err.message : String(err), requestId, err instanceof Error ? err.stack : void 0));
|
|
265025
266876
|
}
|
|
265026
|
-
var messagesListQueryCoercion, sessionIdParamSchema$
|
|
266877
|
+
var messagesListQueryCoercion, sessionIdParamSchema$8, messageIdParamSchema, detailsSchema$6;
|
|
265027
266878
|
var init_messages = __esmMin((() => {
|
|
265028
266879
|
init_src$6();
|
|
265029
266880
|
init_protocolMessage();
|
|
@@ -265047,12 +266898,12 @@ var init_messages = __esmMin((() => {
|
|
|
265047
266898
|
params: { code: ErrorCode.VALIDATION_FAILED }
|
|
265048
266899
|
});
|
|
265049
266900
|
});
|
|
265050
|
-
sessionIdParamSchema$
|
|
266901
|
+
sessionIdParamSchema$8 = object({ session_id: string$2().min(1) });
|
|
265051
266902
|
messageIdParamSchema = object({
|
|
265052
266903
|
session_id: string$2().min(1),
|
|
265053
266904
|
message_id: string$2().min(1)
|
|
265054
266905
|
});
|
|
265055
|
-
detailsSchema$
|
|
266906
|
+
detailsSchema$6 = array$2(object({
|
|
265056
266907
|
path: string$2(),
|
|
265057
266908
|
message: string$2()
|
|
265058
266909
|
}));
|
|
@@ -265405,6 +267256,107 @@ var init_registerDebugRoutes = __esmMin((() => {
|
|
|
265405
267256
|
init_serviceDispatcherRoutes();
|
|
265406
267257
|
}));
|
|
265407
267258
|
//#endregion
|
|
267259
|
+
//#region ../../packages/kap-server/src/routes/events.ts
|
|
267260
|
+
function registerEventsRoute(app, opts) {
|
|
267261
|
+
app.get("/sessions/:session_id/events", { schema: {
|
|
267262
|
+
params: {
|
|
267263
|
+
type: "object",
|
|
267264
|
+
properties: { session_id: { type: "string" } },
|
|
267265
|
+
required: ["session_id"]
|
|
267266
|
+
},
|
|
267267
|
+
querystring: {
|
|
267268
|
+
type: "object",
|
|
267269
|
+
properties: { event_seq: { type: "string" } },
|
|
267270
|
+
required: []
|
|
267271
|
+
}
|
|
267272
|
+
} }, async (req, reply) => {
|
|
267273
|
+
const { session_id } = req.params;
|
|
267274
|
+
if (!session_id) {
|
|
267275
|
+
await reply.code(400).send({
|
|
267276
|
+
code: 4e4,
|
|
267277
|
+
msg: "session_id required",
|
|
267278
|
+
data: null,
|
|
267279
|
+
request_id: req.id
|
|
267280
|
+
});
|
|
267281
|
+
return;
|
|
267282
|
+
}
|
|
267283
|
+
const eventSeq = parseEventSeq(req.query.event_seq);
|
|
267284
|
+
if (eventSeq !== void 0 && (!Number.isInteger(eventSeq) || eventSeq < 0)) {
|
|
267285
|
+
await reply.code(400).send({
|
|
267286
|
+
code: 4e4,
|
|
267287
|
+
msg: "event_seq must be a non-negative integer",
|
|
267288
|
+
data: null,
|
|
267289
|
+
request_id: req.id
|
|
267290
|
+
});
|
|
267291
|
+
return;
|
|
267292
|
+
}
|
|
267293
|
+
reply.hijack();
|
|
267294
|
+
const raw = reply.raw;
|
|
267295
|
+
raw.writeHead(200, SSE_HEADERS);
|
|
267296
|
+
raw.write(": connected\n\n");
|
|
267297
|
+
let closed = false;
|
|
267298
|
+
const target = { send(envelope) {
|
|
267299
|
+
if (closed) return;
|
|
267300
|
+
raw.write(`event: ${envelope.type}\ndata: ${JSON.stringify(envelope)}\n\n`);
|
|
267301
|
+
} };
|
|
267302
|
+
if (!await opts.broadcaster.subscribe(session_id, target)) {
|
|
267303
|
+
if (await opts.core.accessor.get(ISessionLifecycleService).resume(session_id) === void 0) {
|
|
267304
|
+
closed = true;
|
|
267305
|
+
raw.write("event: error\ndata: {\"code\":40401,\"msg\":\"session not found\"}\n\n");
|
|
267306
|
+
raw.end();
|
|
267307
|
+
return;
|
|
267308
|
+
}
|
|
267309
|
+
if (!await opts.broadcaster.subscribe(session_id, target)) {
|
|
267310
|
+
closed = true;
|
|
267311
|
+
raw.write("event: error\ndata: {\"code\":40401,\"msg\":\"session not found\"}\n\n");
|
|
267312
|
+
raw.end();
|
|
267313
|
+
return;
|
|
267314
|
+
}
|
|
267315
|
+
}
|
|
267316
|
+
if (eventSeq !== void 0) {
|
|
267317
|
+
const result = await opts.broadcaster.getBufferedSince(session_id, { seq: eventSeq });
|
|
267318
|
+
if (result.resyncRequired !== false) raw.write(`event: resync_required\ndata: ${JSON.stringify({
|
|
267319
|
+
type: "resync_required",
|
|
267320
|
+
session_id,
|
|
267321
|
+
reason: result.resyncRequired,
|
|
267322
|
+
current_seq: result.currentSeq,
|
|
267323
|
+
epoch: result.epoch
|
|
267324
|
+
})}\n\n`);
|
|
267325
|
+
else for (const { envelope } of result.events) target.send(envelope);
|
|
267326
|
+
}
|
|
267327
|
+
const heartbeat = setInterval(() => {
|
|
267328
|
+
if (!closed) raw.write(": ping\n\n");
|
|
267329
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
267330
|
+
req.raw.on("close", () => {
|
|
267331
|
+
closed = true;
|
|
267332
|
+
clearInterval(heartbeat);
|
|
267333
|
+
opts.broadcaster.unsubscribe(session_id, target);
|
|
267334
|
+
});
|
|
267335
|
+
});
|
|
267336
|
+
}
|
|
267337
|
+
/**
|
|
267338
|
+
* Parse the optional `?event_seq=` replay cursor. `undefined` = absent
|
|
267339
|
+
* (live-only stream); `NaN` = present but malformed — the caller rejects it
|
|
267340
|
+
* with a 400. A valid cursor is a non-negative integer (the journal seq
|
|
267341
|
+
* domain, matching `sessionCursorSchema.seq`).
|
|
267342
|
+
*/
|
|
267343
|
+
function parseEventSeq(raw) {
|
|
267344
|
+
if (raw === void 0) return void 0;
|
|
267345
|
+
if (typeof raw !== "string" || !/^\d+$/.test(raw)) return NaN;
|
|
267346
|
+
return Number(raw);
|
|
267347
|
+
}
|
|
267348
|
+
var SSE_HEADERS, HEARTBEAT_INTERVAL_MS;
|
|
267349
|
+
var init_events = __esmMin((() => {
|
|
267350
|
+
init_src$6();
|
|
267351
|
+
SSE_HEADERS = {
|
|
267352
|
+
"Content-Type": "text/event-stream",
|
|
267353
|
+
"Cache-Control": "no-cache",
|
|
267354
|
+
Connection: "keep-alive",
|
|
267355
|
+
"X-Accel-Buffering": "no"
|
|
267356
|
+
};
|
|
267357
|
+
HEARTBEAT_INTERVAL_MS = 15e3;
|
|
267358
|
+
}));
|
|
267359
|
+
//#endregion
|
|
265408
267360
|
//#region ../../packages/kap-server/src/protocol/rest-meta.ts
|
|
265409
267361
|
var metaCapabilitiesSchema, metaResponseSchema;
|
|
265410
267362
|
var init_rest_meta = __esmMin((() => {
|
|
@@ -266010,7 +267962,7 @@ function registerPromptsRoutes(app, core) {
|
|
|
266010
267962
|
const listRoute = defineRoute({
|
|
266011
267963
|
method: "GET",
|
|
266012
267964
|
path: "/sessions/{session_id}/prompts",
|
|
266013
|
-
params: sessionIdParamSchema$
|
|
267965
|
+
params: sessionIdParamSchema$7,
|
|
266014
267966
|
success: { data: promptListResponseSchema },
|
|
266015
267967
|
errors: { [ErrorCode.SESSION_NOT_FOUND]: {} },
|
|
266016
267968
|
description: "List the active prompt and queued prompts for a session",
|
|
@@ -266030,7 +267982,7 @@ function registerPromptsRoutes(app, core) {
|
|
|
266030
267982
|
method: "POST",
|
|
266031
267983
|
path: "/sessions/{session_id}/prompts",
|
|
266032
267984
|
body: promptSubmissionSchema,
|
|
266033
|
-
params: sessionIdParamSchema$
|
|
267985
|
+
params: sessionIdParamSchema$7,
|
|
266034
267986
|
success: { data: promptSubmitResultSchema },
|
|
266035
267987
|
errors: {
|
|
266036
267988
|
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: validationDetailsSchema },
|
|
@@ -266096,7 +268048,7 @@ function registerPromptsRoutes(app, core) {
|
|
|
266096
268048
|
method: "POST",
|
|
266097
268049
|
path: "/sessions/{session_id}/prompts::steer",
|
|
266098
268050
|
body: promptSteerRequestSchema,
|
|
266099
|
-
params: sessionIdParamSchema$
|
|
268051
|
+
params: sessionIdParamSchema$7,
|
|
266100
268052
|
success: { data: promptSteerResultSchema },
|
|
266101
268053
|
errors: {
|
|
266102
268054
|
[ErrorCode.VALIDATION_FAILED]: {},
|
|
@@ -266588,7 +268540,7 @@ function authModelDetails(err) {
|
|
|
266588
268540
|
if (typeof providerId === "string") details.provider_id = providerId;
|
|
266589
268541
|
return Object.keys(details).length === 0 ? null : details;
|
|
266590
268542
|
}
|
|
266591
|
-
var sessionIdParamSchema$
|
|
268543
|
+
var sessionIdParamSchema$7, validationDetailsSchema, authProviderDetailsSchema, authModelDetailsSchema, VIDEO_EXT_BY_MIME, ATTACHMENT_NAME_MAX;
|
|
266592
268544
|
var init_prompts$1 = __esmMin((() => {
|
|
266593
268545
|
init_src$6();
|
|
266594
268546
|
init_error_codes();
|
|
@@ -266599,7 +268551,7 @@ var init_prompts$1 = __esmMin((() => {
|
|
|
266599
268551
|
init_defineRoute();
|
|
266600
268552
|
init_mainAgent();
|
|
266601
268553
|
init_action_suffix();
|
|
266602
|
-
sessionIdParamSchema$
|
|
268554
|
+
sessionIdParamSchema$7 = object({ session_id: string$2().min(1) });
|
|
266603
268555
|
validationDetailsSchema = array$2(object({
|
|
266604
268556
|
path: string$2(),
|
|
266605
268557
|
message: string$2()
|
|
@@ -266881,7 +268833,7 @@ function registerSessionsRoutes(app, core) {
|
|
|
266881
268833
|
body: createSessionRequestSchema,
|
|
266882
268834
|
success: { data: sessionSchema },
|
|
266883
268835
|
errors: {
|
|
266884
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
268836
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
266885
268837
|
[ErrorCode.WORKSPACE_NOT_FOUND]: {},
|
|
266886
268838
|
[ErrorCode.FS_PATH_NOT_FOUND]: {}
|
|
266887
268839
|
},
|
|
@@ -266919,6 +268871,7 @@ function registerSessionsRoutes(app, core) {
|
|
|
266919
268871
|
const touched = await registry.createOrTouch(workDir);
|
|
266920
268872
|
const handle = await core.accessor.get(ISessionLifecycleService).create({ workDir });
|
|
266921
268873
|
if (typeof body.title === "string") await handle.accessor.get(ISessionMetadata).setTitle(body.title);
|
|
268874
|
+
if (body.metadata !== void 0 && Object.keys(body.metadata).length > 0) await handle.accessor.get(ISessionMetadata).update({ custom: { ...body.metadata } });
|
|
266922
268875
|
const session = toWireSession({
|
|
266923
268876
|
...await handle.accessor.get(ISessionMetadata).read(),
|
|
266924
268877
|
workspaceId: touched.id
|
|
@@ -266947,7 +268900,7 @@ function registerSessionsRoutes(app, core) {
|
|
|
266947
268900
|
querystring: sessionsListQueryCoercion,
|
|
266948
268901
|
success: { data: pageResponseSchema(sessionSchema) },
|
|
266949
268902
|
errors: {
|
|
266950
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
268903
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
266951
268904
|
[ErrorCode.WORKSPACE_NOT_FOUND]: {}
|
|
266952
268905
|
},
|
|
266953
268906
|
description: "List sessions",
|
|
@@ -267015,10 +268968,10 @@ function registerSessionsRoutes(app, core) {
|
|
|
267015
268968
|
const getRoute = defineRoute({
|
|
267016
268969
|
method: "GET",
|
|
267017
268970
|
path: "/sessions/{session_id}",
|
|
267018
|
-
params: sessionIdParamSchema$
|
|
268971
|
+
params: sessionIdParamSchema$6,
|
|
267019
268972
|
success: { data: sessionSchema },
|
|
267020
268973
|
errors: {
|
|
267021
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
268974
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267022
268975
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267023
268976
|
},
|
|
267024
268977
|
description: "Get a session by ID",
|
|
@@ -267041,10 +268994,10 @@ function registerSessionsRoutes(app, core) {
|
|
|
267041
268994
|
const getProfileRoute = defineRoute({
|
|
267042
268995
|
method: "GET",
|
|
267043
268996
|
path: "/sessions/{session_id}/profile",
|
|
267044
|
-
params: sessionIdParamSchema$
|
|
268997
|
+
params: sessionIdParamSchema$6,
|
|
267045
268998
|
success: { data: sessionSchema },
|
|
267046
268999
|
errors: {
|
|
267047
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269000
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267048
269001
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267049
269002
|
},
|
|
267050
269003
|
description: "Get session profile",
|
|
@@ -267067,11 +269020,11 @@ function registerSessionsRoutes(app, core) {
|
|
|
267067
269020
|
const updateProfileRoute = defineRoute({
|
|
267068
269021
|
method: "POST",
|
|
267069
269022
|
path: "/sessions/{session_id}/profile",
|
|
267070
|
-
params: sessionIdParamSchema$
|
|
269023
|
+
params: sessionIdParamSchema$6,
|
|
267071
269024
|
body: updateSessionProfileRequestSchema,
|
|
267072
269025
|
success: { data: sessionSchema },
|
|
267073
269026
|
errors: {
|
|
267074
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269027
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267075
269028
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267076
269029
|
},
|
|
267077
269030
|
description: "Update session profile (title, metadata, agent_config)",
|
|
@@ -267113,7 +269066,7 @@ function registerSessionsRoutes(app, core) {
|
|
|
267113
269066
|
archiveSessionResponseSchema
|
|
267114
269067
|
]) },
|
|
267115
269068
|
errors: {
|
|
267116
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269069
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267117
269070
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
267118
269071
|
[ErrorCode.SESSION_BUSY]: {},
|
|
267119
269072
|
[ErrorCode.COMPACTION_UNABLE]: {},
|
|
@@ -267252,11 +269205,11 @@ function registerSessionsRoutes(app, core) {
|
|
|
267252
269205
|
const listChildrenRoute = defineRoute({
|
|
267253
269206
|
method: "GET",
|
|
267254
269207
|
path: "/sessions/{session_id}/children",
|
|
267255
|
-
params: sessionIdParamSchema$
|
|
269208
|
+
params: sessionIdParamSchema$6,
|
|
267256
269209
|
querystring: sessionChildrenListQueryCoercion,
|
|
267257
269210
|
success: { data: listSessionChildrenResponseSchema },
|
|
267258
269211
|
errors: {
|
|
267259
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269212
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267260
269213
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267261
269214
|
},
|
|
267262
269215
|
description: "List child sessions",
|
|
@@ -267290,11 +269243,11 @@ function registerSessionsRoutes(app, core) {
|
|
|
267290
269243
|
const createChildRoute = defineRoute({
|
|
267291
269244
|
method: "POST",
|
|
267292
269245
|
path: "/sessions/{session_id}/children",
|
|
267293
|
-
params: sessionIdParamSchema$
|
|
269246
|
+
params: sessionIdParamSchema$6,
|
|
267294
269247
|
body: createSessionChildRequestSchema,
|
|
267295
269248
|
success: { data: sessionSchema },
|
|
267296
269249
|
errors: {
|
|
267297
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269250
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267298
269251
|
[ErrorCode.SESSION_NOT_FOUND]: {},
|
|
267299
269252
|
[ErrorCode.SESSION_BUSY]: {}
|
|
267300
269253
|
},
|
|
@@ -267331,10 +269284,10 @@ function registerSessionsRoutes(app, core) {
|
|
|
267331
269284
|
const statusRoute = defineRoute({
|
|
267332
269285
|
method: "GET",
|
|
267333
269286
|
path: "/sessions/{session_id}/status",
|
|
267334
|
-
params: sessionIdParamSchema$
|
|
269287
|
+
params: sessionIdParamSchema$6,
|
|
267335
269288
|
success: { data: sessionStatusResponseSchema },
|
|
267336
269289
|
errors: {
|
|
267337
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269290
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267338
269291
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267339
269292
|
},
|
|
267340
269293
|
description: "Get realtime session status (best-effort in this slice)",
|
|
@@ -267352,10 +269305,10 @@ function registerSessionsRoutes(app, core) {
|
|
|
267352
269305
|
const sessionWarningsRoute = defineRoute({
|
|
267353
269306
|
method: "GET",
|
|
267354
269307
|
path: "/sessions/{session_id}/warnings",
|
|
267355
|
-
params: sessionIdParamSchema$
|
|
269308
|
+
params: sessionIdParamSchema$6,
|
|
267356
269309
|
success: { data: sessionWarningsResponseSchema },
|
|
267357
269310
|
errors: {
|
|
267358
|
-
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$
|
|
269311
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$5 },
|
|
267359
269312
|
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
267360
269313
|
},
|
|
267361
269314
|
description: "Get session-level warnings (e.g. oversized AGENTS.md)",
|
|
@@ -267511,7 +269464,7 @@ function sendMappedError$4(reply, req, err) {
|
|
|
267511
269464
|
log?.error({ err }, "session request failed");
|
|
267512
269465
|
reply.send(errEnvelope(ErrorCode.INTERNAL_ERROR, err instanceof Error ? err.message : String(err), requestId, err instanceof Error ? err.stack : void 0));
|
|
267513
269466
|
}
|
|
267514
|
-
var booleanQueryParam, DEFAULT_SESSION_LIST_PAGE_SIZE, sessionsListQueryCoercion, sessionIdParamSchema$
|
|
269467
|
+
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
269468
|
var init_sessions = __esmMin((() => {
|
|
267516
269469
|
init_src$6();
|
|
267517
269470
|
init_error_codes();
|
|
@@ -267555,7 +269508,7 @@ var init_sessions = __esmMin((() => {
|
|
|
267555
269508
|
params: { code: ErrorCode.VALIDATION_FAILED }
|
|
267556
269509
|
});
|
|
267557
269510
|
});
|
|
267558
|
-
sessionIdParamSchema$
|
|
269511
|
+
sessionIdParamSchema$6 = object({ session_id: string$2().min(1) });
|
|
267559
269512
|
sessionChildrenListQueryCoercion = object({
|
|
267560
269513
|
before_id: string$2().min(1).optional(),
|
|
267561
269514
|
after_id: string$2().min(1).optional(),
|
|
@@ -267577,7 +269530,7 @@ var init_sessions = __esmMin((() => {
|
|
|
267577
269530
|
count: number$2().int().positive().optional(),
|
|
267578
269531
|
page_size: number$2().int().min(1).max(100).optional()
|
|
267579
269532
|
}));
|
|
267580
|
-
detailsSchema$
|
|
269533
|
+
detailsSchema$5 = array$2(object({
|
|
267581
269534
|
path: string$2(),
|
|
267582
269535
|
message: string$2()
|
|
267583
269536
|
}));
|
|
@@ -267585,6 +269538,60 @@ var init_sessions = __esmMin((() => {
|
|
|
267585
269538
|
MAX_UNDO_MESSAGE_PAGE_SIZE = 100;
|
|
267586
269539
|
}));
|
|
267587
269540
|
//#endregion
|
|
269541
|
+
//#region ../../packages/kap-server/src/routes/shell.ts
|
|
269542
|
+
function registerShellRoute(app, core) {
|
|
269543
|
+
const runShellCommandRoute = defineRoute({
|
|
269544
|
+
method: "POST",
|
|
269545
|
+
path: "/sessions/{session_id}/shell",
|
|
269546
|
+
params: sessionIdParamSchema$5,
|
|
269547
|
+
body: shellCommandRequestSchema,
|
|
269548
|
+
success: { data: shellCommandResultSchema },
|
|
269549
|
+
errors: {
|
|
269550
|
+
[ErrorCode.VALIDATION_FAILED]: { detailsSchema: detailsSchema$4 },
|
|
269551
|
+
[ErrorCode.SESSION_NOT_FOUND]: {}
|
|
269552
|
+
},
|
|
269553
|
+
description: "Run a user-initiated `!` shell command in a session",
|
|
269554
|
+
tags: ["sessions"]
|
|
269555
|
+
}, async (req, reply) => {
|
|
269556
|
+
const { session_id } = req.params;
|
|
269557
|
+
const session = await core.accessor.get(ISessionLifecycleService).resume(session_id);
|
|
269558
|
+
if (session === void 0) {
|
|
269559
|
+
reply.send(errEnvelope(ErrorCode.SESSION_NOT_FOUND, `session ${session_id} does not exist`, req.id));
|
|
269560
|
+
return;
|
|
269561
|
+
}
|
|
269562
|
+
const result = await (await ensureMainAgent(session)).accessor.get(IAgentShellCommandService).run({
|
|
269563
|
+
command: req.body.command,
|
|
269564
|
+
commandId: req.body.commandId
|
|
269565
|
+
});
|
|
269566
|
+
reply.send(okEnvelope(result, req.id));
|
|
269567
|
+
});
|
|
269568
|
+
app.post(runShellCommandRoute.path, runShellCommandRoute.options, runShellCommandRoute.handler);
|
|
269569
|
+
}
|
|
269570
|
+
var sessionIdParamSchema$5, shellCommandRequestSchema, shellCommandResultSchema, detailsSchema$4;
|
|
269571
|
+
var init_shell = __esmMin((() => {
|
|
269572
|
+
init_src$6();
|
|
269573
|
+
init_zod$1();
|
|
269574
|
+
init_envelope();
|
|
269575
|
+
init_defineRoute();
|
|
269576
|
+
init_error_codes();
|
|
269577
|
+
init_mainAgent();
|
|
269578
|
+
sessionIdParamSchema$5 = object({ session_id: string$2().min(1) });
|
|
269579
|
+
shellCommandRequestSchema = object({
|
|
269580
|
+
command: string$2(),
|
|
269581
|
+
commandId: string$2().optional()
|
|
269582
|
+
});
|
|
269583
|
+
shellCommandResultSchema = object({
|
|
269584
|
+
stdout: string$2(),
|
|
269585
|
+
stderr: string$2(),
|
|
269586
|
+
isError: boolean$2().optional(),
|
|
269587
|
+
backgrounded: boolean$2().optional()
|
|
269588
|
+
});
|
|
269589
|
+
detailsSchema$4 = array$2(object({
|
|
269590
|
+
path: string$2(),
|
|
269591
|
+
message: string$2()
|
|
269592
|
+
}));
|
|
269593
|
+
}));
|
|
269594
|
+
//#endregion
|
|
267588
269595
|
//#region ../../packages/kap-server/src/routes/shutdown.ts
|
|
267589
269596
|
function registerShutdownRoutes(app, opts) {
|
|
267590
269597
|
const route = defineRoute({
|
|
@@ -269820,6 +271827,11 @@ async function registerApiV1Routes(app, core, opts) {
|
|
|
269820
271827
|
registerConfigRoutes(apiV1, core);
|
|
269821
271828
|
registerModelCatalogRoutes(apiV1, core);
|
|
269822
271829
|
registerSessionsRoutes(apiV1, core);
|
|
271830
|
+
registerShellRoute(apiV1, core);
|
|
271831
|
+
registerEventsRoute(apiV1, {
|
|
271832
|
+
broadcaster: opts.broadcaster,
|
|
271833
|
+
core
|
|
271834
|
+
});
|
|
269823
271835
|
registerSessionExportRoute(apiV1, core, { serverVersion: opts.serverVersion });
|
|
269824
271836
|
registerSkillsRoutes(apiV1, core);
|
|
269825
271837
|
registerMessagesRoutes(apiV1, core);
|
|
@@ -269878,6 +271890,7 @@ var init_registerApiV1Routes = __esmMin((() => {
|
|
|
269878
271890
|
init_guiStore();
|
|
269879
271891
|
init_messages();
|
|
269880
271892
|
init_registerDebugRoutes();
|
|
271893
|
+
init_events();
|
|
269881
271894
|
init_meta();
|
|
269882
271895
|
init_modelCatalog();
|
|
269883
271896
|
init_oauth();
|
|
@@ -269885,6 +271898,7 @@ var init_registerApiV1Routes = __esmMin((() => {
|
|
|
269885
271898
|
init_questions();
|
|
269886
271899
|
init_sessionExport();
|
|
269887
271900
|
init_sessions();
|
|
271901
|
+
init_shell();
|
|
269888
271902
|
init_shutdown();
|
|
269889
271903
|
init_snapshot();
|
|
269890
271904
|
init_skills$1();
|
|
@@ -273846,7 +275860,9 @@ var DEFAULT_MAX_BUFFER_SIZE, DEFAULT_FLUSH_INTERVAL_MS, DEFAULT_MAX_BATCH_SIZE,
|
|
|
273846
275860
|
var init_wsConnectionV1 = __esmMin((() => {
|
|
273847
275861
|
init_ws_control();
|
|
273848
275862
|
init_src$2();
|
|
275863
|
+
init_src$6();
|
|
273849
275864
|
init_node$3();
|
|
275865
|
+
init_error_codes();
|
|
273850
275866
|
init_protocol();
|
|
273851
275867
|
init_sessionEventBroadcaster();
|
|
273852
275868
|
init_fsWatchBridge();
|
|
@@ -273864,6 +275880,7 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
273864
275880
|
socket;
|
|
273865
275881
|
broadcaster;
|
|
273866
275882
|
fsWatchBridge;
|
|
275883
|
+
core;
|
|
273867
275884
|
validateCredential;
|
|
273868
275885
|
maxBufferSize;
|
|
273869
275886
|
flushIntervalMs;
|
|
@@ -273875,6 +275892,12 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
273875
275892
|
/** Per-session subscription state: legacy agent allowlist + opt-in transcript grades. */
|
|
273876
275893
|
subscriptions = /* @__PURE__ */ new Map();
|
|
273877
275894
|
/**
|
|
275895
|
+
* Terminal services this connection has attached to (one per session,
|
|
275896
|
+
* resolved lazily). Tracked so teardown can detach every terminal sink
|
|
275897
|
+
* the connection owns.
|
|
275898
|
+
*/
|
|
275899
|
+
terminalServices = /* @__PURE__ */ new Set();
|
|
275900
|
+
/**
|
|
273878
275901
|
* Serializes control-frame handling in receive order. Frames arrive
|
|
273879
275902
|
* back-to-back (e.g. `client_hello` immediately followed by
|
|
273880
275903
|
* `subscribe_v2`), and a later handler reads subscription state the
|
|
@@ -273896,6 +275919,7 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
273896
275919
|
this.socket = opts.socket;
|
|
273897
275920
|
this.broadcaster = opts.broadcaster;
|
|
273898
275921
|
this.fsWatchBridge = opts.fsWatchBridge;
|
|
275922
|
+
this.core = opts.core;
|
|
273899
275923
|
this.validateCredential = opts.validateCredential;
|
|
273900
275924
|
this.logger = opts.logger;
|
|
273901
275925
|
this.maxBufferSize = opts.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE;
|
|
@@ -273959,6 +275983,21 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
273959
275983
|
case "watch_fs_remove":
|
|
273960
275984
|
this.enqueueControl(() => this.onWatchFs(frame, false));
|
|
273961
275985
|
return;
|
|
275986
|
+
case "terminal_attach":
|
|
275987
|
+
this.enqueueControl(() => this.onTerminalAttach(frame));
|
|
275988
|
+
return;
|
|
275989
|
+
case "terminal_input":
|
|
275990
|
+
this.enqueueControl(() => this.onTerminalInput(frame));
|
|
275991
|
+
return;
|
|
275992
|
+
case "terminal_resize":
|
|
275993
|
+
this.enqueueControl(() => this.onTerminalResize(frame));
|
|
275994
|
+
return;
|
|
275995
|
+
case "terminal_close":
|
|
275996
|
+
this.enqueueControl(() => this.onTerminalClose(frame));
|
|
275997
|
+
return;
|
|
275998
|
+
case "terminal_detach":
|
|
275999
|
+
this.enqueueControl(() => this.onTerminalDetach(frame));
|
|
276000
|
+
return;
|
|
273962
276001
|
default: return;
|
|
273963
276002
|
}
|
|
273964
276003
|
}
|
|
@@ -274104,6 +276143,120 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
274104
276143
|
}));
|
|
274105
276144
|
}
|
|
274106
276145
|
/**
|
|
276146
|
+
* `terminal_attach` — attach this connection's sink to a session terminal
|
|
276147
|
+
* stream. The sink's frames (`terminal_output` / `terminal_exit`) are
|
|
276148
|
+
* delivered over the same subscription buffer as session events (coalesced
|
|
276149
|
+
* only when mergeable — terminal frames never merge, they just share the
|
|
276150
|
+
* flush window). `since_seq` replays buffered frames past the cursor, like
|
|
276151
|
+
* the REST/WS attach contract.
|
|
276152
|
+
*/
|
|
276153
|
+
async onTerminalAttach(frame) {
|
|
276154
|
+
const parsed = terminalAttachMessageSchema.safeParse(frame);
|
|
276155
|
+
if (!parsed.success) {
|
|
276156
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_attach payload", {}));
|
|
276157
|
+
return;
|
|
276158
|
+
}
|
|
276159
|
+
const { session_id, terminal_id, since_seq } = parsed.data.payload;
|
|
276160
|
+
try {
|
|
276161
|
+
const terminals = await this.resolveTerminalService(session_id);
|
|
276162
|
+
const sink = {
|
|
276163
|
+
id: this.id,
|
|
276164
|
+
send: (terminalFrame) => this.sendSubscribedFrame(terminalFrame)
|
|
276165
|
+
};
|
|
276166
|
+
const { replayed } = await terminals.attach(terminal_id, sink, { sinceSeq: since_seq });
|
|
276167
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", {
|
|
276168
|
+
attached: true,
|
|
276169
|
+
replayed
|
|
276170
|
+
}));
|
|
276171
|
+
} catch (error) {
|
|
276172
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276173
|
+
}
|
|
276174
|
+
}
|
|
276175
|
+
/** `terminal_input` — write bytes to the attached terminal's pty. */
|
|
276176
|
+
async onTerminalInput(frame) {
|
|
276177
|
+
const parsed = terminalInputMessageSchema.safeParse(frame);
|
|
276178
|
+
if (!parsed.success) {
|
|
276179
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_input payload", {}));
|
|
276180
|
+
return;
|
|
276181
|
+
}
|
|
276182
|
+
const { session_id, terminal_id, data } = parsed.data.payload;
|
|
276183
|
+
try {
|
|
276184
|
+
await (await this.resolveTerminalService(session_id)).write(terminal_id, data);
|
|
276185
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", { accepted: true }));
|
|
276186
|
+
} catch (error) {
|
|
276187
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276188
|
+
}
|
|
276189
|
+
}
|
|
276190
|
+
/** `terminal_resize` — resize the attached terminal's pty. */
|
|
276191
|
+
async onTerminalResize(frame) {
|
|
276192
|
+
const parsed = terminalResizeMessageSchema.safeParse(frame);
|
|
276193
|
+
if (!parsed.success) {
|
|
276194
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_resize payload", {}));
|
|
276195
|
+
return;
|
|
276196
|
+
}
|
|
276197
|
+
const { session_id, terminal_id, cols, rows } = parsed.data.payload;
|
|
276198
|
+
try {
|
|
276199
|
+
await (await this.resolveTerminalService(session_id)).resize(terminal_id, cols, rows);
|
|
276200
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", { resized: true }));
|
|
276201
|
+
} catch (error) {
|
|
276202
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276203
|
+
}
|
|
276204
|
+
}
|
|
276205
|
+
/** `terminal_close` — close the terminal's pty (idempotent). */
|
|
276206
|
+
async onTerminalClose(frame) {
|
|
276207
|
+
const parsed = terminalCloseMessageSchema.safeParse(frame);
|
|
276208
|
+
if (!parsed.success) {
|
|
276209
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_close payload", {}));
|
|
276210
|
+
return;
|
|
276211
|
+
}
|
|
276212
|
+
const { session_id, terminal_id } = parsed.data.payload;
|
|
276213
|
+
try {
|
|
276214
|
+
await (await this.resolveTerminalService(session_id)).close(terminal_id);
|
|
276215
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", { closed: true }));
|
|
276216
|
+
} catch (error) {
|
|
276217
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276218
|
+
}
|
|
276219
|
+
}
|
|
276220
|
+
/** `terminal_detach` — detach this connection's sink from a terminal stream. */
|
|
276221
|
+
async onTerminalDetach(frame) {
|
|
276222
|
+
const parsed = terminalDetachMessageSchema.safeParse(frame);
|
|
276223
|
+
if (!parsed.success) {
|
|
276224
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 1, "invalid terminal_detach payload", {}));
|
|
276225
|
+
return;
|
|
276226
|
+
}
|
|
276227
|
+
const { session_id, terminal_id } = parsed.data.payload;
|
|
276228
|
+
try {
|
|
276229
|
+
(await this.resolveTerminalService(session_id)).detach(terminal_id, this.id);
|
|
276230
|
+
this.sendImmediateFrame(buildAck(frame.id ?? "", 0, "success", { detached: true }));
|
|
276231
|
+
} catch (error) {
|
|
276232
|
+
this.sendTerminalErrorAck(frame.id, error);
|
|
276233
|
+
}
|
|
276234
|
+
}
|
|
276235
|
+
/**
|
|
276236
|
+
* Resolve a session's `ISessionTerminalService` (cold-loading a
|
|
276237
|
+
* persisted-but-not-live session, matching the REST terminal route).
|
|
276238
|
+
* The resolved service is remembered so `onClose` can detach every sink
|
|
276239
|
+
* this connection owns.
|
|
276240
|
+
*/
|
|
276241
|
+
async resolveTerminalService(sessionId) {
|
|
276242
|
+
const session = await this.core.accessor.get(ISessionLifecycleService).resume(sessionId);
|
|
276243
|
+
if (session === void 0) throw new Error2(ErrorCodes.SESSION_NOT_FOUND, `session ${sessionId} does not exist`);
|
|
276244
|
+
const terminals = session.accessor.get(ISessionTerminalService);
|
|
276245
|
+
this.terminalServices.add(terminals);
|
|
276246
|
+
return terminals;
|
|
276247
|
+
}
|
|
276248
|
+
/** Ack a terminal control failure with the wire error code when known. */
|
|
276249
|
+
sendTerminalErrorAck(id, error) {
|
|
276250
|
+
let code = 1;
|
|
276251
|
+
let msg = "internal error";
|
|
276252
|
+
if (isError2(error)) {
|
|
276253
|
+
if (error.code === ErrorCodes.SESSION_NOT_FOUND) code = ErrorCode.SESSION_NOT_FOUND;
|
|
276254
|
+
else if (error.code === ErrorCodes.TERMINAL_NOT_FOUND) code = ErrorCode.TERMINAL_NOT_FOUND;
|
|
276255
|
+
msg = error.message;
|
|
276256
|
+
} else if (error instanceof Error) msg = error.message;
|
|
276257
|
+
this.sendImmediateFrame(buildAck(id ?? "", code, msg, {}));
|
|
276258
|
+
}
|
|
276259
|
+
/**
|
|
274107
276260
|
* Shared attach path behind `client_hello` (legacy inline subscriptions)
|
|
274108
276261
|
* and `subscribe`. Subscribes the connection via the broadcaster, then
|
|
274109
276262
|
* either replays durable events since the client's cursor (with the
|
|
@@ -274248,6 +276401,7 @@ var init_wsConnectionV1 = __esmMin((() => {
|
|
|
274248
276401
|
this.outbound = [];
|
|
274249
276402
|
this.broadcaster.removeGlobalTarget(this);
|
|
274250
276403
|
for (const sid of this.subscriptions.keys()) this.broadcaster.unsubscribe(sid, this);
|
|
276404
|
+
for (const terminals of this.terminalServices) terminals.detachAllForSink(this.id);
|
|
274251
276405
|
this.fsWatchBridge?.detachConnection(this);
|
|
274252
276406
|
}
|
|
274253
276407
|
};
|
|
@@ -274266,6 +276420,7 @@ function registerWsV1(core, opts) {
|
|
|
274266
276420
|
broadcaster,
|
|
274267
276421
|
fsWatchBridge: opts.fsWatchBridge,
|
|
274268
276422
|
connectionRegistry: registry,
|
|
276423
|
+
core,
|
|
274269
276424
|
validateCredential: opts.validateCredential,
|
|
274270
276425
|
remoteAddress: req.socket.remoteAddress ?? null,
|
|
274271
276426
|
userAgent: req.headers["user-agent"] ?? null,
|
|
@@ -296567,6 +298722,15 @@ function stringifyToolOutput(output) {
|
|
|
296567
298722
|
if (typeof output === "string") return output;
|
|
296568
298723
|
return JSON.stringify(output) ?? String(output);
|
|
296569
298724
|
}
|
|
298725
|
+
function stringifyToolArgs(args) {
|
|
298726
|
+
if (typeof args === "string") return args;
|
|
298727
|
+
return JSON.stringify(args) ?? String(args);
|
|
298728
|
+
}
|
|
298729
|
+
function truncateChars(text, max) {
|
|
298730
|
+
if (text.length <= max) return text;
|
|
298731
|
+
const suffix = `… (${text.length - max} more chars)`;
|
|
298732
|
+
return `${text.slice(0, max - suffix.length)}${suffix}`;
|
|
298733
|
+
}
|
|
296570
298734
|
function writeVersion(version, outputFormat, stdout, stderr) {
|
|
296571
298735
|
if (outputFormat === "stream-json") {
|
|
296572
298736
|
const message = {
|
|
@@ -296595,16 +298759,23 @@ function writeResumeHint(sessionId, outputFormat, stdout, stderr) {
|
|
|
296595
298759
|
}
|
|
296596
298760
|
stderr.write(`${content}\n`);
|
|
296597
298761
|
}
|
|
296598
|
-
var PROMPT_BLOCK_BULLET, PROMPT_BLOCK_INDENT, PromptTranscriptWriter, PromptJsonWriter, PromptBlockWriter;
|
|
298762
|
+
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
298763
|
var init_prompt_render = __esmMin((() => {
|
|
296600
298764
|
PROMPT_BLOCK_BULLET = "• ";
|
|
296601
298765
|
PROMPT_BLOCK_INDENT = " ";
|
|
298766
|
+
TOOL_CALL_MARK = "⚒ ";
|
|
298767
|
+
TOOL_RESULT_MARK = "⚒ result: ";
|
|
298768
|
+
RETRY_MARK = "↻ retry";
|
|
298769
|
+
MAX_TOOL_CALL_ARGS_CHARS = 500;
|
|
298770
|
+
MAX_TOOL_RESULT_CHARS = 2e3;
|
|
296602
298771
|
PromptTranscriptWriter = class {
|
|
296603
298772
|
assistantWriter;
|
|
296604
298773
|
thinkingWriter;
|
|
298774
|
+
toolWriter;
|
|
296605
298775
|
constructor(stdout, stderr) {
|
|
296606
298776
|
this.assistantWriter = new PromptBlockWriter(stdout);
|
|
296607
298777
|
this.thinkingWriter = new PromptBlockWriter(stderr);
|
|
298778
|
+
this.toolWriter = new PromptBlockWriter(stderr);
|
|
296608
298779
|
}
|
|
296609
298780
|
writeAssistantDelta(delta) {
|
|
296610
298781
|
this.thinkingWriter.finish();
|
|
@@ -296619,10 +298790,25 @@ var init_prompt_render = __esmMin((() => {
|
|
|
296619
298790
|
writeThinkingDelta(delta) {
|
|
296620
298791
|
this.thinkingWriter.write(delta);
|
|
296621
298792
|
}
|
|
296622
|
-
writeToolCall() {
|
|
298793
|
+
writeToolCall(toolCallId, name, args) {
|
|
298794
|
+
this.thinkingWriter.finish();
|
|
298795
|
+
this.assistantWriter.finish();
|
|
298796
|
+
this.toolWriter.write(`${TOOL_CALL_MARK}${name}(${truncateChars(stringifyToolArgs(args), MAX_TOOL_CALL_ARGS_CHARS)})`);
|
|
298797
|
+
this.toolWriter.finish();
|
|
298798
|
+
}
|
|
296623
298799
|
writeToolCallDelta() {}
|
|
296624
|
-
writeToolResult() {
|
|
296625
|
-
|
|
298800
|
+
writeToolResult(toolCallId, output) {
|
|
298801
|
+
this.toolWriter.finish();
|
|
298802
|
+
this.toolWriter.write(`${TOOL_RESULT_MARK}${truncateChars(stringifyToolOutput(output), MAX_TOOL_RESULT_CHARS)}`);
|
|
298803
|
+
this.toolWriter.finish();
|
|
298804
|
+
}
|
|
298805
|
+
writeRetrying(event) {
|
|
298806
|
+
this.thinkingWriter.finish();
|
|
298807
|
+
this.assistantWriter.finish();
|
|
298808
|
+
const error = [event.errorName, event.errorMessage].filter(Boolean).join(": ");
|
|
298809
|
+
this.toolWriter.write(`${RETRY_MARK} ${event.failedAttempt}/${event.maxAttempts} (${error}) — ${event.delayMs}ms`);
|
|
298810
|
+
this.toolWriter.finish();
|
|
298811
|
+
}
|
|
296626
298812
|
flushAssistant() {
|
|
296627
298813
|
this.assistantWriter.finish();
|
|
296628
298814
|
}
|
|
@@ -296630,6 +298816,7 @@ var init_prompt_render = __esmMin((() => {
|
|
|
296630
298816
|
finish() {
|
|
296631
298817
|
this.thinkingWriter.finish();
|
|
296632
298818
|
this.assistantWriter.finish();
|
|
298819
|
+
this.toolWriter.finish();
|
|
296633
298820
|
}
|
|
296634
298821
|
};
|
|
296635
298822
|
PromptJsonWriter = class {
|