@moxt-ai/mobius 0.0.354 → 0.0.356
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/cli.js +613 -490
- package/dist/cli.js.map +4 -4
- package/dist/engine/agent/discovery/agent-discovery-context.d.ts +10 -0
- package/dist/engine/agent/discovery/agent-discovery-context.d.ts.map +1 -1
- package/dist/engine/agent/discovery/discover-agent.d.ts.map +1 -1
- package/dist/engine/agent/discovery/discover-agent.js +27 -6
- package/dist/engine/agent/discovery/discover-agent.js.map +1 -1
- package/dist/engine/agent/discovery/executable-discovery.d.ts.map +1 -1
- package/dist/engine/agent/discovery/executable-discovery.js +8 -1
- package/dist/engine/agent/discovery/executable-discovery.js.map +1 -1
- package/dist/engine/runtime/catalog/discover-agent-catalog.d.ts +4 -0
- package/dist/engine/runtime/catalog/discover-agent-catalog.d.ts.map +1 -0
- package/dist/engine/runtime/catalog/discover-agent-catalog.js +54 -0
- package/dist/engine/runtime/catalog/discover-agent-catalog.js.map +1 -0
- package/dist/engine/runtime/command/registry/interactions.d.ts.map +1 -1
- package/dist/engine/runtime/command/registry/interactions.js +7 -1
- package/dist/engine/runtime/command/registry/interactions.js.map +1 -1
- package/dist/engine/runtime/observability/diagnostic-log.d.ts.map +1 -1
- package/dist/engine/runtime/observability/diagnostic-log.js +6 -0
- package/dist/engine/runtime/observability/diagnostic-log.js.map +1 -1
- package/dist/engine/runtime/pairing.d.ts.map +1 -1
- package/dist/engine/runtime/pairing.js +6 -5
- package/dist/engine/runtime/pairing.js.map +1 -1
- package/dist/engine/runtime/runtime-loop.d.ts.map +1 -1
- package/dist/engine/runtime/runtime-loop.js +4 -3
- package/dist/engine/runtime/runtime-loop.js.map +1 -1
- package/dist/engine/session/live/agent-session-restore.d.ts +1 -1
- package/dist/engine/session/live/agent-session-restore.d.ts.map +1 -1
- package/dist/engine/session/live/agent-session.d.ts +1 -1
- package/dist/engine/session/live/agent-session.d.ts.map +1 -1
- package/dist/engine/session/live/agent-session.js +23 -2
- package/dist/engine/session/live/agent-session.js.map +1 -1
- package/dist/engine/session/live/session-configurations.d.ts +1 -1
- package/dist/engine/session/live/session-configurations.d.ts.map +1 -1
- package/dist/engine/session/live/session-configurations.js +1 -1
- package/dist/engine/session/live/session-configurations.js.map +1 -1
- package/dist/engine/session/live/session-restore.d.ts.map +1 -1
- package/dist/engine/session/live/session-restore.js +7 -1
- package/dist/engine/session/live/session-restore.js.map +1 -1
- package/dist/engine/session/native/native-session-browser.d.ts.map +1 -1
- package/dist/engine/session/native/native-session-browser.js +1 -0
- package/dist/engine/session/native/native-session-browser.js.map +1 -1
- package/dist/engine/session/prompt/execute-prompt.d.ts.map +1 -1
- package/dist/engine/session/prompt/execute-prompt.js +1 -0
- package/dist/engine/session/prompt/execute-prompt.js.map +1 -1
- package/dist/engine/session/turn/execution-receipts.d.ts +2 -0
- package/dist/engine/session/turn/execution-receipts.d.ts.map +1 -1
- package/dist/engine/session/turn/execution-receipts.js +7 -0
- package/dist/engine/session/turn/execution-receipts.js.map +1 -1
- package/dist/engine/util/process/executable.d.ts.map +1 -1
- package/dist/engine/util/process/executable.js +26 -8
- package/dist/engine/util/process/executable.js.map +1 -1
- package/dist/engine/util/process/process-error.d.ts +6 -1
- package/dist/engine/util/process/process-error.d.ts.map +1 -1
- package/dist/engine/util/process/process-error.js +2 -0
- package/dist/engine/util/process/process-error.js.map +1 -1
- package/dist/engine.js +572 -470
- package/dist/engine.js.map +4 -4
- package/package.json +2 -2
package/dist/engine.js
CHANGED
|
@@ -20794,38 +20794,6 @@ function isRecord2(value) {
|
|
|
20794
20794
|
}
|
|
20795
20795
|
var sessionEventBatchSchema = external_exports.array(sessionEventSchema).min(1).max(SESSION_EVENT_BATCH_MAX_SIZE).readonly();
|
|
20796
20796
|
var sessionLiveEventBatchSchema = external_exports.array(sessionLiveEventSchema).min(1).max(SESSION_EVENT_BATCH_MAX_SIZE).readonly();
|
|
20797
|
-
var sessionExportSchema = external_exports.object({
|
|
20798
|
-
binding: external_exports.object({
|
|
20799
|
-
bindingId: identifierStringSchema,
|
|
20800
|
-
runtimeId: identifierStringSchema
|
|
20801
|
-
}).readonly(),
|
|
20802
|
-
events: external_exports.array(sessionEventSchema).max(MAX_EVENT_COUNT).readonly(),
|
|
20803
|
-
sessionId: identifierStringSchema,
|
|
20804
|
-
truncated: external_exports.boolean()
|
|
20805
|
-
}).readonly().superRefine((session, context) => {
|
|
20806
|
-
const eventIds = /* @__PURE__ */ new Set();
|
|
20807
|
-
for (const [index2, event] of session.events.entries()) {
|
|
20808
|
-
if (event.sessionId !== session.sessionId) {
|
|
20809
|
-
context.addIssue({
|
|
20810
|
-
code: "custom",
|
|
20811
|
-
message: "Exported event belongs to a different Session",
|
|
20812
|
-
path: ["events", index2, "sessionId"]
|
|
20813
|
-
});
|
|
20814
|
-
}
|
|
20815
|
-
if (eventIds.has(event.eventId)) {
|
|
20816
|
-
context.addIssue({
|
|
20817
|
-
code: "custom",
|
|
20818
|
-
message: "Exported event identities are not unique",
|
|
20819
|
-
path: ["events", index2, "eventId"]
|
|
20820
|
-
});
|
|
20821
|
-
}
|
|
20822
|
-
eventIds.add(event.eventId);
|
|
20823
|
-
}
|
|
20824
|
-
});
|
|
20825
|
-
var mobiusSessionExportSchema = external_exports.object({
|
|
20826
|
-
formatVersion: external_exports.literal("2"),
|
|
20827
|
-
session: sessionExportSchema
|
|
20828
|
-
}).readonly();
|
|
20829
20797
|
var sessionEventEnvelopeSchema = external_exports.object({ events: sessionLiveEventBatchSchema, kind: external_exports.literal(SESSION_EVENT_KIND) }).readonly();
|
|
20830
20798
|
var sessionEventLogPageSchema = external_exports.object({
|
|
20831
20799
|
events: external_exports.array(sessionEventSchema).max(MAX_EVENT_COUNT).readonly(),
|
|
@@ -20838,12 +20806,9 @@ var sessionEventLogPageSchema = external_exports.object({
|
|
|
20838
20806
|
truncated: external_exports.boolean(),
|
|
20839
20807
|
version: external_exports.literal(2)
|
|
20840
20808
|
}).readonly();
|
|
20841
|
-
var sessionEventOmissionSchema = external_exports.literal("agent-reasoning");
|
|
20842
20809
|
var nativeEventPageRequestSchema = external_exports.object({
|
|
20843
20810
|
cursor: external_exports.string().min(1).max(512).nullable(),
|
|
20844
|
-
eventLimit: external_exports.number().int().min(1).max(1e4)
|
|
20845
|
-
// Legacy callers may still send this option; readers must ignore it.
|
|
20846
|
-
omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional()
|
|
20811
|
+
eventLimit: external_exports.number().int().min(1).max(1e4)
|
|
20847
20812
|
}).readonly();
|
|
20848
20813
|
var queuedPromptRequestEventLogSchema = external_exports.object({
|
|
20849
20814
|
commandId: identifierStringSchema,
|
|
@@ -21476,7 +21441,9 @@ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
|
|
|
21476
21441
|
// unrecognized delivery from a newer peer reads as absent instead of failing the snapshot.
|
|
21477
21442
|
command: commandDeliverySchema.optional().catch(void 0),
|
|
21478
21443
|
// Absent from older Runtimes and while the last started command is still running.
|
|
21479
|
-
lastTurn: lastTurnOutcomeSchema.optional().catch(void 0)
|
|
21444
|
+
lastTurn: lastTurnOutcomeSchema.optional().catch(void 0),
|
|
21445
|
+
// Runtime-owned support; older Relays strip this field before exposing the snapshot.
|
|
21446
|
+
queuedCancellation: external_exports.literal("before-start").optional().catch(void 0)
|
|
21480
21447
|
}).readonly(),
|
|
21481
21448
|
external_exports.object({
|
|
21482
21449
|
...resultEnvelope,
|
|
@@ -21522,8 +21489,6 @@ var SESSION_PREVIEW_HISTORY_PAGE_LOADED_KIND = "session.preview-history.page.loa
|
|
|
21522
21489
|
var pageRequestFields = {
|
|
21523
21490
|
cursor: external_exports.string().min(1).max(512).nullable(),
|
|
21524
21491
|
eventLimit: external_exports.number().int().min(1).max(1e4),
|
|
21525
|
-
// Decode old clients without rejecting their request; omission has no effect.
|
|
21526
|
-
omit: external_exports.array(sessionEventOmissionSchema).max(1).readonly().optional(),
|
|
21527
21492
|
requestId: identifierStringSchema,
|
|
21528
21493
|
sessionId: identifierStringSchema
|
|
21529
21494
|
};
|
|
@@ -59518,7 +59483,6 @@ function backgroundTaskId(result) {
|
|
|
59518
59483
|
}
|
|
59519
59484
|
|
|
59520
59485
|
// src/engine/acp/harness/claude/upstream/dist/context-resources.js
|
|
59521
|
-
import { extname } from "node:path";
|
|
59522
59486
|
function formatUriAsLink(uri) {
|
|
59523
59487
|
if (uri.startsWith("file://")) {
|
|
59524
59488
|
const path7 = uri.slice(7);
|
|
@@ -59533,91 +59497,6 @@ var formatContextBlock = (uri, text2) => `
|
|
|
59533
59497
|
<context ref="${uri}">
|
|
59534
59498
|
${text2}
|
|
59535
59499
|
</context>`;
|
|
59536
|
-
function parseContextBlock(block) {
|
|
59537
|
-
if (block.type !== "text" || typeof block.text !== "string") {
|
|
59538
|
-
return null;
|
|
59539
|
-
}
|
|
59540
|
-
const match = /^\n<context ref="([^"\r\n]+)">\n([\s\S]*)\n<\/context>$/u.exec(block.text);
|
|
59541
|
-
const uri = match?.[1];
|
|
59542
|
-
const text2 = match?.[2];
|
|
59543
|
-
if (uri === void 0 || text2 === void 0 || formatContextBlock(uri, text2) !== block.text) {
|
|
59544
|
-
return null;
|
|
59545
|
-
}
|
|
59546
|
-
return { uri, text: text2 };
|
|
59547
|
-
}
|
|
59548
|
-
function contextMimeType(uri) {
|
|
59549
|
-
let pathname = uri;
|
|
59550
|
-
try {
|
|
59551
|
-
pathname = new URL(uri).pathname;
|
|
59552
|
-
} catch {
|
|
59553
|
-
}
|
|
59554
|
-
switch (extname(pathname).toLowerCase()) {
|
|
59555
|
-
case ".html":
|
|
59556
|
-
case ".htm":
|
|
59557
|
-
return "text/html";
|
|
59558
|
-
case ".js":
|
|
59559
|
-
case ".mjs":
|
|
59560
|
-
case ".cjs":
|
|
59561
|
-
return "text/javascript";
|
|
59562
|
-
case ".css":
|
|
59563
|
-
return "text/css";
|
|
59564
|
-
case ".json":
|
|
59565
|
-
return "application/json";
|
|
59566
|
-
case ".md":
|
|
59567
|
-
case ".markdown":
|
|
59568
|
-
return "text/markdown";
|
|
59569
|
-
case ".xml":
|
|
59570
|
-
return "application/xml";
|
|
59571
|
-
case ".svg":
|
|
59572
|
-
return "image/svg+xml";
|
|
59573
|
-
case ".csv":
|
|
59574
|
-
return "text/csv";
|
|
59575
|
-
default:
|
|
59576
|
-
return "text/plain";
|
|
59577
|
-
}
|
|
59578
|
-
}
|
|
59579
|
-
function replayContextResources(content) {
|
|
59580
|
-
const contexts = [];
|
|
59581
|
-
let contextStart = content.length;
|
|
59582
|
-
for (let index2 = content.length - 1; index2 >= 0; index2 -= 1) {
|
|
59583
|
-
const block = content[index2];
|
|
59584
|
-
const parsed = block === void 0 ? null : parseContextBlock(block);
|
|
59585
|
-
if (parsed === null) {
|
|
59586
|
-
break;
|
|
59587
|
-
}
|
|
59588
|
-
contexts.push(parsed);
|
|
59589
|
-
contextStart = index2;
|
|
59590
|
-
}
|
|
59591
|
-
if (contexts.length === 0) {
|
|
59592
|
-
return null;
|
|
59593
|
-
}
|
|
59594
|
-
contexts.reverse();
|
|
59595
|
-
const links = new Set(contexts.map(({ uri }) => formatUriAsLink(uri)));
|
|
59596
|
-
const resources = /* @__PURE__ */ new Map();
|
|
59597
|
-
let nextContext = 0;
|
|
59598
|
-
for (let index2 = 0; index2 < contextStart; index2 += 1) {
|
|
59599
|
-
const block = content[index2];
|
|
59600
|
-
if (block?.type !== "text" || typeof block.text !== "string") {
|
|
59601
|
-
continue;
|
|
59602
|
-
}
|
|
59603
|
-
if (block.text.startsWith('\n<context ref="')) {
|
|
59604
|
-
return null;
|
|
59605
|
-
}
|
|
59606
|
-
if (!links.has(block.text)) {
|
|
59607
|
-
continue;
|
|
59608
|
-
}
|
|
59609
|
-
const context = contexts[nextContext];
|
|
59610
|
-
if (context === void 0 || block.text !== formatUriAsLink(context.uri)) {
|
|
59611
|
-
return null;
|
|
59612
|
-
}
|
|
59613
|
-
resources.set(index2, {
|
|
59614
|
-
type: "resource",
|
|
59615
|
-
resource: { ...context, mimeType: contextMimeType(context.uri) }
|
|
59616
|
-
});
|
|
59617
|
-
nextContext += 1;
|
|
59618
|
-
}
|
|
59619
|
-
return nextContext === contexts.length ? { contextStart, resources } : null;
|
|
59620
|
-
}
|
|
59621
59500
|
|
|
59622
59501
|
// src/engine/acp/harness/claude/upstream/dist/elicitation.js
|
|
59623
59502
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
@@ -66932,13 +66811,8 @@ function toAcpNotifications(content, role, sessionId, toolUseCache, client2, log
|
|
|
66932
66811
|
const toolUseResult = options?.toolUseResult !== void 0 && content.filter((c) => typeof c === "object" && c !== null && c.type === "tool_result").length === 1 ? options.toolUseResult : void 0;
|
|
66933
66812
|
const toolResultMeta = parseToolResultMeta(options?.toolResultMeta);
|
|
66934
66813
|
const output2 = [];
|
|
66935
|
-
const
|
|
66936
|
-
for (const [index2, chunk] of content.entries()) {
|
|
66937
|
-
if (replayedResources !== null && index2 >= replayedResources.contextStart) {
|
|
66938
|
-
break;
|
|
66939
|
-
}
|
|
66814
|
+
for (const chunk of content) {
|
|
66940
66815
|
let update = null;
|
|
66941
|
-
const resource = replayedResources?.resources.get(index2);
|
|
66942
66816
|
switch (chunk.type) {
|
|
66943
66817
|
case "text":
|
|
66944
66818
|
case "text_delta": {
|
|
@@ -66947,7 +66821,7 @@ function toAcpNotifications(content, role, sessionId, toolUseCache, client2, log
|
|
|
66947
66821
|
update = {
|
|
66948
66822
|
sessionUpdate: role === "assistant" ? "agent_message_chunk" : "user_message_chunk",
|
|
66949
66823
|
messageId,
|
|
66950
|
-
content:
|
|
66824
|
+
content: {
|
|
66951
66825
|
type: "text",
|
|
66952
66826
|
text: chunk.text
|
|
66953
66827
|
}
|
|
@@ -67717,14 +67591,16 @@ var macosProcessPlatform = {
|
|
|
67717
67591
|
// src/engine/util/process/platform/windows.ts
|
|
67718
67592
|
import { execFile as execFile4 } from "node:child_process";
|
|
67719
67593
|
import { readFile as readFile5, realpath as realpath6 } from "node:fs/promises";
|
|
67720
|
-
import { dirname as dirname6, extname
|
|
67594
|
+
import { dirname as dirname6, extname, join as join14, resolve as resolve8 } from "node:path";
|
|
67721
67595
|
|
|
67722
67596
|
// src/engine/util/process/process-error.ts
|
|
67723
67597
|
var ProcessExecutionError = class extends Error {
|
|
67724
67598
|
code;
|
|
67599
|
+
diagnosticDetails;
|
|
67725
67600
|
constructor(code, message, options = {}) {
|
|
67726
67601
|
super(message, options);
|
|
67727
67602
|
this.code = code;
|
|
67603
|
+
this.diagnosticDetails = options.diagnosticDetails ?? {};
|
|
67728
67604
|
this.name = "ProcessExecutionError";
|
|
67729
67605
|
}
|
|
67730
67606
|
};
|
|
@@ -67744,14 +67620,14 @@ function executableExtensions(executableName, environment) {
|
|
|
67744
67620
|
async function resolveExecutableTarget(path7) {
|
|
67745
67621
|
let resolvedPath;
|
|
67746
67622
|
try {
|
|
67747
|
-
resolvedPath = await realpath6(
|
|
67623
|
+
resolvedPath = await realpath6(extname(path7) === "" ? `${path7}.cmd` : path7);
|
|
67748
67624
|
} catch (cause) {
|
|
67749
|
-
if (
|
|
67625
|
+
if (extname(path7) !== "" || !(cause instanceof Error) || !("code" in cause) || cause.code !== "ENOENT") {
|
|
67750
67626
|
throw cause;
|
|
67751
67627
|
}
|
|
67752
67628
|
resolvedPath = await realpath6(path7);
|
|
67753
67629
|
}
|
|
67754
|
-
if (
|
|
67630
|
+
if (extname(resolvedPath).toLowerCase() === ".cmd") {
|
|
67755
67631
|
const shim = await readFile5(resolvedPath, "utf8");
|
|
67756
67632
|
if (shim.includes('SET "NPM_CLI_JS=%~dp0\\node_modules\\npm\\bin\\npm-cli.js"') && shim.includes('"%NODE_EXE%" "%NPM_CLI_JS%" %*')) {
|
|
67757
67633
|
return await realpath6(resolve8(dirname6(resolvedPath), "node_modules/npm/bin/npm-cli.js"));
|
|
@@ -68135,11 +68011,16 @@ async function runBoundedProcess(options) {
|
|
|
68135
68011
|
abort();
|
|
68136
68012
|
}
|
|
68137
68013
|
try {
|
|
68138
|
-
const
|
|
68139
|
-
child.once("error",
|
|
68140
|
-
child.once("exit", (code) =>
|
|
68014
|
+
const completion = new Promise((resolveCompletion, rejectCompletion) => {
|
|
68015
|
+
child.once("error", rejectCompletion);
|
|
68016
|
+
child.once("exit", (code) => {
|
|
68017
|
+
if (code !== 0) {
|
|
68018
|
+
resolveCompletion(code ?? 1);
|
|
68019
|
+
}
|
|
68020
|
+
});
|
|
68021
|
+
child.once("close", (code) => resolveCompletion(code ?? 1));
|
|
68141
68022
|
});
|
|
68142
|
-
const exitCode = await Promise.race([
|
|
68023
|
+
const exitCode = await Promise.race([completion, interrupted.promise.then(() => -1)]);
|
|
68143
68024
|
if (interruptionCleanupFailure !== null) {
|
|
68144
68025
|
throw interruptionCleanupFailure;
|
|
68145
68026
|
}
|
|
@@ -68151,12 +68032,19 @@ async function runBoundedProcess(options) {
|
|
|
68151
68032
|
}
|
|
68152
68033
|
return new ProcessResult(Buffer.concat(stdout).toString("utf8"), Buffer.concat(stderr).toString("utf8"));
|
|
68153
68034
|
} catch (error62) {
|
|
68154
|
-
|
|
68155
|
-
throw error62;
|
|
68156
|
-
}
|
|
68157
|
-
throw new ProcessExecutionError("process_spawn_failed", "The executable could not be started", {
|
|
68035
|
+
const failure2 = error62 instanceof ProcessExecutionError ? error62 : new ProcessExecutionError("process_spawn_failed", "The executable could not be started", {
|
|
68158
68036
|
cause: error62
|
|
68159
68037
|
});
|
|
68038
|
+
throw new ProcessExecutionError(failure2.code, failure2.message, {
|
|
68039
|
+
cause: error62,
|
|
68040
|
+
diagnosticDetails: {
|
|
68041
|
+
stdoutBytes: stdoutBytes.toString(),
|
|
68042
|
+
stderrBytes: stderrBytes.toString(),
|
|
68043
|
+
outputLimitBytes: outputLimitBytes.toString(),
|
|
68044
|
+
...child.exitCode === null ? {} : { exitCode: child.exitCode.toString() },
|
|
68045
|
+
...child.signalCode === null ? {} : { signal: child.signalCode }
|
|
68046
|
+
}
|
|
68047
|
+
});
|
|
68160
68048
|
} finally {
|
|
68161
68049
|
clearTimeout(timeout);
|
|
68162
68050
|
options.signal.removeEventListener("abort", abort);
|
|
@@ -71184,9 +71072,9 @@ import {
|
|
|
71184
71072
|
// src/engine/acp/harness/pi/upstream/dist/acp/agent.js
|
|
71185
71073
|
import { spawnSync } from "node:child_process";
|
|
71186
71074
|
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
71187
|
-
import { existsSync as existsSync7, readdirSync as readdirSync6, readFileSync as
|
|
71075
|
+
import { existsSync as existsSync7, readdirSync as readdirSync6, readFileSync as readFileSync9, realpathSync as realpathSync3, statSync as statSync3, unlinkSync as unlinkSync2 } from "node:fs";
|
|
71188
71076
|
import { basename as basename5, dirname as dirname8, isAbsolute as isAbsolute12, join as join20 } from "node:path";
|
|
71189
|
-
import { RequestError as
|
|
71077
|
+
import { RequestError as RequestError11 } from "@agentclientprotocol/sdk";
|
|
71190
71078
|
|
|
71191
71079
|
// src/engine/acp/harness/pi/upstream/dist/pi-rpc/process.js
|
|
71192
71080
|
import { spawn as spawn5 } from "node:child_process";
|
|
@@ -71699,8 +71587,62 @@ function toAvailableCommandsFromPiGetCommands(data, opts) {
|
|
|
71699
71587
|
return { commands: out2, raw: commandsRaw };
|
|
71700
71588
|
}
|
|
71701
71589
|
|
|
71590
|
+
// src/engine/acp/harness/pi/upstream/dist/acp/pi-history.js
|
|
71591
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
71592
|
+
import { RequestError as RequestError8 } from "@agentclientprotocol/sdk";
|
|
71593
|
+
var entrySchema = external_exports.object({
|
|
71594
|
+
type: external_exports.string(),
|
|
71595
|
+
id: external_exports.string(),
|
|
71596
|
+
parentId: external_exports.string().nullable()
|
|
71597
|
+
}).passthrough();
|
|
71598
|
+
var messageSchema = external_exports.object({
|
|
71599
|
+
role: external_exports.enum(["user", "assistant", "toolResult"]),
|
|
71600
|
+
content: external_exports.unknown()
|
|
71601
|
+
}).passthrough();
|
|
71602
|
+
function readPiHistory(sessionFile) {
|
|
71603
|
+
try {
|
|
71604
|
+
const entries = /* @__PURE__ */ new Map();
|
|
71605
|
+
let leaf = null;
|
|
71606
|
+
for (const line of readFileSync3(sessionFile, "utf8").split(/\r?\n/u)) {
|
|
71607
|
+
if (!line.trim()) {
|
|
71608
|
+
continue;
|
|
71609
|
+
}
|
|
71610
|
+
const value = JSON.parse(line);
|
|
71611
|
+
if (external_exports.object({ type: external_exports.literal("session") }).safeParse(value).success) {
|
|
71612
|
+
continue;
|
|
71613
|
+
}
|
|
71614
|
+
const entry = entrySchema.parse(value);
|
|
71615
|
+
entries.set(entry.id, entry);
|
|
71616
|
+
leaf = entry.id;
|
|
71617
|
+
}
|
|
71618
|
+
const history = [];
|
|
71619
|
+
const visited = /* @__PURE__ */ new Set();
|
|
71620
|
+
while (leaf !== null) {
|
|
71621
|
+
const entry = entries.get(leaf);
|
|
71622
|
+
if (entry === void 0 || visited.has(leaf)) {
|
|
71623
|
+
throw new Error("Invalid Pi history branch");
|
|
71624
|
+
}
|
|
71625
|
+
visited.add(leaf);
|
|
71626
|
+
if (entry.type === "message") {
|
|
71627
|
+
const { role } = external_exports.object({ role: external_exports.string() }).parse(entry.message);
|
|
71628
|
+
if (role === "user" || role === "assistant" || role === "toolResult") {
|
|
71629
|
+
history.push({ type: "message", message: messageSchema.parse(entry.message) });
|
|
71630
|
+
}
|
|
71631
|
+
} else if (entry.type === "compaction") {
|
|
71632
|
+
history.push({ type: "compaction", id: entry.id, summary: external_exports.string().parse(entry.summary) });
|
|
71633
|
+
}
|
|
71634
|
+
leaf = entry.parentId;
|
|
71635
|
+
}
|
|
71636
|
+
return history.reverse();
|
|
71637
|
+
} catch (cause) {
|
|
71638
|
+
const error62 = RequestError8.internalError({ code: "PI_HISTORY_READ_FAILED" }, "Unable to read Pi history");
|
|
71639
|
+
error62.cause = cause;
|
|
71640
|
+
throw error62;
|
|
71641
|
+
}
|
|
71642
|
+
}
|
|
71643
|
+
|
|
71702
71644
|
// src/engine/acp/harness/pi/upstream/dist/acp/pi-sessions.js
|
|
71703
|
-
import { closeSync as closeSync2, existsSync as existsSync4, openSync as openSync2, readdirSync as readdirSync4, readFileSync as
|
|
71645
|
+
import { closeSync as closeSync2, existsSync as existsSync4, openSync as openSync2, readdirSync as readdirSync4, readFileSync as readFileSync4, readSync as readSync2, statSync as statSync2 } from "node:fs";
|
|
71704
71646
|
import { isAbsolute as isAbsolute10, join as join17, resolve as resolve10 } from "node:path";
|
|
71705
71647
|
var DEFAULT_TAIL_BYTES = 256 * 1024;
|
|
71706
71648
|
var DEFAULT_HEAD_BYTES = 64 * 1024;
|
|
@@ -71714,7 +71656,7 @@ function readSessionDirFromSettings(agentDir) {
|
|
|
71714
71656
|
if (!existsSync4(settingsPath)) {
|
|
71715
71657
|
return null;
|
|
71716
71658
|
}
|
|
71717
|
-
const raw =
|
|
71659
|
+
const raw = readFileSync4(settingsPath, "utf8");
|
|
71718
71660
|
const data = JSON.parse(raw);
|
|
71719
71661
|
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
71720
71662
|
return null;
|
|
@@ -71930,7 +71872,7 @@ function pickUpdatedAtFromTail(tail) {
|
|
|
71930
71872
|
}
|
|
71931
71873
|
function pickFallbackTitleFromHead(path7) {
|
|
71932
71874
|
try {
|
|
71933
|
-
const raw =
|
|
71875
|
+
const raw = readFileSync4(path7, { encoding: "utf8" });
|
|
71934
71876
|
const lines = raw.split(/\r?\n/);
|
|
71935
71877
|
for (const line0 of lines) {
|
|
71936
71878
|
const line = line0.trim();
|
|
@@ -72026,7 +71968,7 @@ function findPiSession(sessionId, environment = process.env) {
|
|
|
72026
71968
|
}
|
|
72027
71969
|
|
|
72028
71970
|
// src/engine/acp/harness/pi/upstream/dist/acp/pi-settings.js
|
|
72029
|
-
import { existsSync as existsSync5, readFileSync as
|
|
71971
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
|
|
72030
71972
|
import { join as join18, resolve as resolve11 } from "node:path";
|
|
72031
71973
|
function isObject2(x) {
|
|
72032
71974
|
return Boolean(x) && typeof x === "object" && !Array.isArray(x);
|
|
@@ -72048,7 +71990,7 @@ function readJsonFile2(path7) {
|
|
|
72048
71990
|
if (!existsSync5(path7)) {
|
|
72049
71991
|
return {};
|
|
72050
71992
|
}
|
|
72051
|
-
const raw =
|
|
71993
|
+
const raw = readFileSync5(path7, "utf-8");
|
|
72052
71994
|
const data = JSON.parse(raw);
|
|
72053
71995
|
return isObject2(data) ? data : {};
|
|
72054
71996
|
} catch {
|
|
@@ -72093,12 +72035,12 @@ function getQuietStartup(cwd, environment = process.env) {
|
|
|
72093
72035
|
|
|
72094
72036
|
// src/engine/acp/harness/pi/upstream/dist/acp/session.js
|
|
72095
72037
|
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
72096
|
-
import { readFileSync as
|
|
72038
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
72097
72039
|
import { isAbsolute as isAbsolute11, resolve as resolvePath } from "node:path";
|
|
72098
|
-
import { RequestError as
|
|
72040
|
+
import { RequestError as RequestError10 } from "@agentclientprotocol/sdk";
|
|
72099
72041
|
|
|
72100
72042
|
// src/engine/acp/harness/pi/upstream/dist/acp/extension-questions.js
|
|
72101
|
-
import { RequestError as
|
|
72043
|
+
import { RequestError as RequestError9 } from "@agentclientprotocol/sdk";
|
|
72102
72044
|
var questionBase = {
|
|
72103
72045
|
id: external_exports.string().min(1).max(255),
|
|
72104
72046
|
title: external_exports.string().max(255),
|
|
@@ -72115,7 +72057,7 @@ var questionSchema = external_exports.discriminatedUnion("method", [
|
|
|
72115
72057
|
external_exports.object({ ...questionBase, method: external_exports.literal("editor"), prefill: external_exports.string().max(1e4).optional() })
|
|
72116
72058
|
]).readonly();
|
|
72117
72059
|
var QUESTION_TIMEOUT_MS = 36e5;
|
|
72118
|
-
var PiQuestionError = class extends
|
|
72060
|
+
var PiQuestionError = class extends RequestError9 {
|
|
72119
72061
|
constructor(kind, cause) {
|
|
72120
72062
|
const messages = {
|
|
72121
72063
|
request_failed: "Pi could not request an answer.",
|
|
@@ -72253,7 +72195,7 @@ var PiExtensionQuestions = class {
|
|
|
72253
72195
|
throw new PiQuestionError("invalid_response");
|
|
72254
72196
|
}
|
|
72255
72197
|
} catch (cause) {
|
|
72256
|
-
if (!signal.aborted && !(cause instanceof
|
|
72198
|
+
if (!signal.aborted && !(cause instanceof RequestError9 && cause.code === -32800)) {
|
|
72257
72199
|
turn.controller.abort(cause instanceof PiQuestionError ? cause : new PiQuestionError("request_failed", cause));
|
|
72258
72200
|
}
|
|
72259
72201
|
} finally {
|
|
@@ -72267,14 +72209,14 @@ var PiExtensionQuestions = class {
|
|
|
72267
72209
|
};
|
|
72268
72210
|
|
|
72269
72211
|
// src/engine/acp/harness/pi/upstream/dist/acp/session-store.js
|
|
72270
|
-
import { mkdirSync as mkdirSync2, readFileSync as
|
|
72212
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync } from "node:fs";
|
|
72271
72213
|
import { dirname as dirname7 } from "node:path";
|
|
72272
72214
|
function ensureParentDir(path7) {
|
|
72273
72215
|
mkdirSync2(dirname7(path7), { recursive: true });
|
|
72274
72216
|
}
|
|
72275
72217
|
function loadFile(path7) {
|
|
72276
72218
|
try {
|
|
72277
|
-
const raw =
|
|
72219
|
+
const raw = readFileSync6(path7, "utf-8");
|
|
72278
72220
|
const parsed = JSON.parse(raw);
|
|
72279
72221
|
if (parsed?.version !== 1 || typeof parsed.sessions !== "object" || !parsed.sessions) {
|
|
72280
72222
|
return { version: 1, sessions: {} };
|
|
@@ -72319,7 +72261,7 @@ var SessionStore = class {
|
|
|
72319
72261
|
};
|
|
72320
72262
|
|
|
72321
72263
|
// src/engine/acp/harness/pi/upstream/dist/acp/slash-commands.js
|
|
72322
|
-
import { existsSync as existsSync6, readdirSync as readdirSync5, readFileSync as
|
|
72264
|
+
import { existsSync as existsSync6, readdirSync as readdirSync5, readFileSync as readFileSync7 } from "node:fs";
|
|
72323
72265
|
import { join as join19, resolve as resolve12 } from "node:path";
|
|
72324
72266
|
function parseFrontmatter(content) {
|
|
72325
72267
|
const frontmatter = {};
|
|
@@ -72358,7 +72300,7 @@ function loadCommandsFromDir(dir, source, subdir = "") {
|
|
|
72358
72300
|
continue;
|
|
72359
72301
|
}
|
|
72360
72302
|
try {
|
|
72361
|
-
const rawContent =
|
|
72303
|
+
const rawContent = readFileSync7(fullPath, "utf-8");
|
|
72362
72304
|
const { frontmatter, content } = parseFrontmatter(rawContent);
|
|
72363
72305
|
const name2 = entry.name.slice(0, -3);
|
|
72364
72306
|
const sourceStr = source === "user" ? subdir ? `(user:${subdir})` : "(user)" : subdir ? `(project:${subdir})` : "(project)";
|
|
@@ -72533,6 +72475,16 @@ ${stderr}`);
|
|
|
72533
72475
|
}
|
|
72534
72476
|
|
|
72535
72477
|
// src/engine/acp/harness/pi/upstream/dist/acp/session.js
|
|
72478
|
+
var nativeUserMessageSchema = external_exports.object({
|
|
72479
|
+
role: external_exports.literal("user"),
|
|
72480
|
+
content: external_exports.union([
|
|
72481
|
+
external_exports.string().transform((text2) => [{ type: "text", text: text2 }]),
|
|
72482
|
+
external_exports.array(external_exports.discriminatedUnion("type", [
|
|
72483
|
+
external_exports.object({ type: external_exports.literal("text"), text: external_exports.string() }),
|
|
72484
|
+
external_exports.object({ type: external_exports.literal("image"), data: external_exports.string(), mimeType: external_exports.string() })
|
|
72485
|
+
]))
|
|
72486
|
+
])
|
|
72487
|
+
});
|
|
72536
72488
|
function toUsageUpdate(stats) {
|
|
72537
72489
|
const used = stats?.contextUsage?.tokens;
|
|
72538
72490
|
const size = stats?.contextUsage?.contextWindow;
|
|
@@ -72678,7 +72630,7 @@ var SessionManager = class {
|
|
|
72678
72630
|
});
|
|
72679
72631
|
} catch (e) {
|
|
72680
72632
|
if (e instanceof PiRpcSpawnError) {
|
|
72681
|
-
throw
|
|
72633
|
+
throw RequestError10.internalError({ code: e.code }, e.message);
|
|
72682
72634
|
}
|
|
72683
72635
|
throw e;
|
|
72684
72636
|
}
|
|
@@ -72707,7 +72659,7 @@ var SessionManager = class {
|
|
|
72707
72659
|
get(sessionId) {
|
|
72708
72660
|
const s = this.sessions.get(sessionId);
|
|
72709
72661
|
if (!s) {
|
|
72710
|
-
throw
|
|
72662
|
+
throw RequestError10.invalidParams(`Unknown sessionId: ${sessionId}`);
|
|
72711
72663
|
}
|
|
72712
72664
|
return s;
|
|
72713
72665
|
}
|
|
@@ -72807,8 +72759,8 @@ var PiAcpSession = class {
|
|
|
72807
72759
|
if (cause instanceof PiRpcProcessError) {
|
|
72808
72760
|
const pending = this.pendingTurn;
|
|
72809
72761
|
const reason = pending?.questionSignal.reason;
|
|
72810
|
-
const error62 = reason instanceof
|
|
72811
|
-
if (!(reason instanceof
|
|
72762
|
+
const error62 = reason instanceof RequestError10 ? reason : RequestError10.internalError({ code: cause.code, details: cause.message });
|
|
72763
|
+
if (!(reason instanceof RequestError10)) {
|
|
72812
72764
|
error62.cause = cause;
|
|
72813
72765
|
}
|
|
72814
72766
|
this.extensionQuestions.endTurn(error62);
|
|
@@ -72876,12 +72828,12 @@ var PiAcpSession = class {
|
|
|
72876
72828
|
const signal = this.extensionQuestions.startTurn();
|
|
72877
72829
|
try {
|
|
72878
72830
|
const result = await this.proc.compact(customInstructions, { signal, timeoutMs });
|
|
72879
|
-
if (signal.aborted && signal.reason instanceof
|
|
72831
|
+
if (signal.aborted && signal.reason instanceof RequestError10) {
|
|
72880
72832
|
throw signal.reason;
|
|
72881
72833
|
}
|
|
72882
72834
|
return result;
|
|
72883
72835
|
} catch (cause) {
|
|
72884
|
-
if (signal.aborted && signal.reason instanceof
|
|
72836
|
+
if (signal.aborted && signal.reason instanceof RequestError10) {
|
|
72885
72837
|
try {
|
|
72886
72838
|
await this.proc.abort({ signal: this.proc.signal, timeoutMs });
|
|
72887
72839
|
} catch (abortCause) {
|
|
@@ -72974,14 +72926,14 @@ var PiAcpSession = class {
|
|
|
72974
72926
|
await this.publishContextUsage();
|
|
72975
72927
|
const retryFailure = this.turnRetryFailure;
|
|
72976
72928
|
this.turnRetryFailure = null;
|
|
72977
|
-
if (questionSignal?.aborted && questionSignal.reason instanceof
|
|
72929
|
+
if (questionSignal?.aborted && questionSignal.reason instanceof RequestError10 && !this.cancelRequested) {
|
|
72978
72930
|
this.pendingTurn?.reject(questionSignal.reason);
|
|
72979
72931
|
} else if (retryFailure !== null && !this.cancelRequested) {
|
|
72980
72932
|
this.pendingTurn?.reject(
|
|
72981
72933
|
// The message rides in `data.details` so clients that unwrap the
|
|
72982
72934
|
// JSON-RPC internal-error envelope (like Mobius) surface the real
|
|
72983
72935
|
// model error; `code` keeps the failure machine-readable.
|
|
72984
|
-
|
|
72936
|
+
RequestError10.internalError({
|
|
72985
72937
|
code: "pi_retries_exhausted",
|
|
72986
72938
|
details: `Pi retries exhausted: ${retryFailure}`
|
|
72987
72939
|
})
|
|
@@ -73065,6 +73017,17 @@ var PiAcpSession = class {
|
|
|
73065
73017
|
handlePiEvent(ev2) {
|
|
73066
73018
|
const type = String(ev2.type ?? "");
|
|
73067
73019
|
switch (type) {
|
|
73020
|
+
case "message_start": {
|
|
73021
|
+
const message = nativeUserMessageSchema.safeParse(ev2.message);
|
|
73022
|
+
if (!message.success) {
|
|
73023
|
+
break;
|
|
73024
|
+
}
|
|
73025
|
+
this.lastEmit = this.lastEmit.then(() => this.conn.startUserMessage());
|
|
73026
|
+
for (const content of message.data.content) {
|
|
73027
|
+
this.emit({ sessionUpdate: "user_message_chunk", content });
|
|
73028
|
+
}
|
|
73029
|
+
break;
|
|
73030
|
+
}
|
|
73068
73031
|
case "message_update": {
|
|
73069
73032
|
const ame2 = ev2.assistantMessageEvent;
|
|
73070
73033
|
if (this.turnRetryFailure !== null && (ame2?.type === "text_delta" || ame2?.type === "thinking_delta" || ame2?.type === "toolcall_start")) {
|
|
@@ -73171,7 +73134,7 @@ var PiAcpSession = class {
|
|
|
73171
73134
|
if (p) {
|
|
73172
73135
|
try {
|
|
73173
73136
|
const abs = isAbsolute11(p) ? p : resolvePath(this.cwd, p);
|
|
73174
|
-
snapshotOldText =
|
|
73137
|
+
snapshotOldText = readFileSync8(abs, "utf8");
|
|
73175
73138
|
this.fileSnapshots.set(toolCallId, { path: p, oldText: snapshotOldText });
|
|
73176
73139
|
if (toolName === "edit") {
|
|
73177
73140
|
for (const needle of getEditOldTexts(args)) {
|
|
@@ -73254,7 +73217,7 @@ var PiAcpSession = class {
|
|
|
73254
73217
|
if (!isError && snapshot) {
|
|
73255
73218
|
try {
|
|
73256
73219
|
const abs = isAbsolute11(snapshot.path) ? snapshot.path : resolvePath(this.cwd, snapshot.path);
|
|
73257
|
-
const newText =
|
|
73220
|
+
const newText = readFileSync8(abs, "utf8");
|
|
73258
73221
|
if (snapshot.oldText === null || newText !== snapshot.oldText) {
|
|
73259
73222
|
hasStructuredDiff = true;
|
|
73260
73223
|
content = [
|
|
@@ -73576,7 +73539,7 @@ var PiAcpAgent = class {
|
|
|
73576
73539
|
const restorePromise = (async () => {
|
|
73577
73540
|
const stored = this.findStoredSession(sessionId);
|
|
73578
73541
|
if (!stored) {
|
|
73579
|
-
throw
|
|
73542
|
+
throw RequestError11.invalidParams(`Unknown sessionId: ${sessionId}`);
|
|
73580
73543
|
}
|
|
73581
73544
|
const cwd = opts?.cwd ?? stored.cwd;
|
|
73582
73545
|
let proc;
|
|
@@ -73589,7 +73552,7 @@ var PiAcpAgent = class {
|
|
|
73589
73552
|
});
|
|
73590
73553
|
} catch (e) {
|
|
73591
73554
|
if (e?.name === "PiRpcSpawnError") {
|
|
73592
|
-
throw
|
|
73555
|
+
throw RequestError11.internalError({ code: e?.code }, String(e?.message ?? e));
|
|
73593
73556
|
}
|
|
73594
73557
|
throw e;
|
|
73595
73558
|
}
|
|
@@ -73649,7 +73612,7 @@ var PiAcpAgent = class {
|
|
|
73649
73612
|
}
|
|
73650
73613
|
async newSession(params) {
|
|
73651
73614
|
if (!isAbsolute12(params.cwd)) {
|
|
73652
|
-
throw
|
|
73615
|
+
throw RequestError11.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
73653
73616
|
}
|
|
73654
73617
|
this.lastSessionCwd = params.cwd;
|
|
73655
73618
|
const fileCommands = loadSlashCommands(params.cwd, this.environment);
|
|
@@ -73688,16 +73651,16 @@ var PiAcpAgent = class {
|
|
|
73688
73651
|
}
|
|
73689
73652
|
if (availableModelsErr) {
|
|
73690
73653
|
this.cleanupFailedNewSession(session.sessionId, state);
|
|
73691
|
-
throw
|
|
73654
|
+
throw RequestError11.internalError({}, String(availableModelsErr?.message ?? availableModelsErr));
|
|
73692
73655
|
}
|
|
73693
73656
|
const rawModelsCount = Array.isArray(availableModels?.models) ? availableModels.models.length : 0;
|
|
73694
73657
|
if (rawModelsCount === 0) {
|
|
73695
73658
|
this.cleanupFailedNewSession(session.sessionId, state);
|
|
73696
|
-
throw
|
|
73659
|
+
throw RequestError11.authRequired({ authMethods: getAuthMethods() }, "Configure an API key or log in with an OAuth provider.");
|
|
73697
73660
|
}
|
|
73698
73661
|
if (stateErr && maybeAuthRequiredError(stateErr)) {
|
|
73699
73662
|
this.cleanupFailedNewSession(session.sessionId, state);
|
|
73700
|
-
throw
|
|
73663
|
+
throw RequestError11.authRequired({ authMethods: getAuthMethods() }, "Configure an API key or log in with an OAuth provider.");
|
|
73701
73664
|
}
|
|
73702
73665
|
let configuration;
|
|
73703
73666
|
try {
|
|
@@ -73707,7 +73670,7 @@ var PiAcpAgent = class {
|
|
|
73707
73670
|
configuration = await getSessionConfiguration(session.proc, { state, availableModels });
|
|
73708
73671
|
} catch (err) {
|
|
73709
73672
|
this.cleanupFailedNewSession(session.sessionId, state);
|
|
73710
|
-
throw maybeAuthRequiredError(err) ??
|
|
73673
|
+
throw maybeAuthRequiredError(err) ?? RequestError11.internalError({}, String(err?.message ?? err));
|
|
73711
73674
|
}
|
|
73712
73675
|
const { configOptions, models, modes } = configuration;
|
|
73713
73676
|
const quietStartup = getQuietStartup(params.cwd, this.environment);
|
|
@@ -73787,16 +73750,6 @@ var PiAcpAgent = class {
|
|
|
73787
73750
|
}
|
|
73788
73751
|
async promptSubmission(params, submission) {
|
|
73789
73752
|
const session = await this.restoreSession(params.sessionId);
|
|
73790
|
-
this.conn.startUserMessage();
|
|
73791
|
-
for (const content of params.prompt) {
|
|
73792
|
-
if (submission.aborted) {
|
|
73793
|
-
return { stopReason: "cancelled" };
|
|
73794
|
-
}
|
|
73795
|
-
await this.conn.sessionUpdate({
|
|
73796
|
-
sessionId: params.sessionId,
|
|
73797
|
-
update: { sessionUpdate: "user_message_chunk", content }
|
|
73798
|
-
});
|
|
73799
|
-
}
|
|
73800
73753
|
if (submission.aborted) {
|
|
73801
73754
|
return { stopReason: "cancelled" };
|
|
73802
73755
|
}
|
|
@@ -73807,6 +73760,9 @@ var PiAcpAgent = class {
|
|
|
73807
73760
|
const cmd = space === -1 ? trimmed.slice(1) : trimmed.slice(1, space);
|
|
73808
73761
|
const argsString = space === -1 ? "" : trimmed.slice(space + 1);
|
|
73809
73762
|
const args = parseCommandArgs(argsString);
|
|
73763
|
+
if (builtinAvailableCommands().some((command) => command.name === cmd)) {
|
|
73764
|
+
this.conn.startUserMessage();
|
|
73765
|
+
}
|
|
73810
73766
|
if (cmd === "compact") {
|
|
73811
73767
|
const customInstructions = args.join(" ").trim() || void 0;
|
|
73812
73768
|
const compactionId = randomUUID11();
|
|
@@ -74068,7 +74024,7 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74068
74024
|
}
|
|
74069
74025
|
let text2 = "";
|
|
74070
74026
|
try {
|
|
74071
|
-
text2 =
|
|
74027
|
+
text2 = readFileSync9(changelogPath, "utf-8");
|
|
74072
74028
|
} catch (e) {
|
|
74073
74029
|
await this.conn.sessionUpdate({
|
|
74074
74030
|
sessionId: session.sessionId,
|
|
@@ -74112,7 +74068,7 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74112
74068
|
return { stopReason: "end_turn" };
|
|
74113
74069
|
}
|
|
74114
74070
|
try {
|
|
74115
|
-
const raw =
|
|
74071
|
+
const raw = readFileSync9(sessionFile, "utf-8");
|
|
74116
74072
|
if (raw.trim().length === 0) {
|
|
74117
74073
|
await this.conn.sessionUpdate({
|
|
74118
74074
|
sessionId: session.sessionId,
|
|
@@ -74235,7 +74191,7 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74235
74191
|
signal.throwIfAborted();
|
|
74236
74192
|
const parsed = steerRequestSchema.safeParse(params);
|
|
74237
74193
|
if (!parsed.success) {
|
|
74238
|
-
throw
|
|
74194
|
+
throw RequestError11.invalidParams("Invalid steering request");
|
|
74239
74195
|
}
|
|
74240
74196
|
const session = this.sessions.maybeGet(parsed.data.sessionId);
|
|
74241
74197
|
if (session === void 0) {
|
|
@@ -74247,14 +74203,6 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74247
74203
|
case "idle":
|
|
74248
74204
|
return { outcome: "promptRequired", reason: "noRunningTurn" };
|
|
74249
74205
|
case "injected": {
|
|
74250
|
-
this.conn.startUserMessage();
|
|
74251
|
-
for (const content of parsed.data.prompt) {
|
|
74252
|
-
signal.throwIfAborted();
|
|
74253
|
-
await this.conn.sessionUpdate({
|
|
74254
|
-
sessionId: parsed.data.sessionId,
|
|
74255
|
-
update: { sessionUpdate: "user_message_chunk", content }
|
|
74256
|
-
});
|
|
74257
|
-
}
|
|
74258
74206
|
return { outcome: "injected" };
|
|
74259
74207
|
}
|
|
74260
74208
|
}
|
|
@@ -74288,11 +74236,11 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74288
74236
|
}
|
|
74289
74237
|
async forkSession(params) {
|
|
74290
74238
|
if (!isAbsolute12(params.cwd)) {
|
|
74291
|
-
throw
|
|
74239
|
+
throw RequestError11.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
74292
74240
|
}
|
|
74293
74241
|
const source = this.findStoredSession(params.sessionId);
|
|
74294
74242
|
if (!source) {
|
|
74295
|
-
throw
|
|
74243
|
+
throw RequestError11.invalidParams(`Unknown sessionId: ${params.sessionId}`);
|
|
74296
74244
|
}
|
|
74297
74245
|
this.lastSessionCwd = params.cwd;
|
|
74298
74246
|
const fileCommands = loadSlashCommands(params.cwd, this.environment);
|
|
@@ -74354,13 +74302,13 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74354
74302
|
}
|
|
74355
74303
|
async resumeSession(params) {
|
|
74356
74304
|
if (!isAbsolute12(params.cwd)) {
|
|
74357
|
-
throw
|
|
74305
|
+
throw RequestError11.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
74358
74306
|
}
|
|
74359
74307
|
this.sessions.close(params.sessionId);
|
|
74360
74308
|
this.lastSessionCwd = params.cwd;
|
|
74361
74309
|
const stored = this.findStoredSession(params.sessionId);
|
|
74362
74310
|
if (!stored) {
|
|
74363
|
-
throw
|
|
74311
|
+
throw RequestError11.invalidParams(`Unknown sessionId: ${params.sessionId}`);
|
|
74364
74312
|
}
|
|
74365
74313
|
const session = await this.restoreSession(params.sessionId, {
|
|
74366
74314
|
cwd: params.cwd,
|
|
@@ -74425,13 +74373,13 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74425
74373
|
}
|
|
74426
74374
|
async loadSession(params) {
|
|
74427
74375
|
if (!isAbsolute12(params.cwd)) {
|
|
74428
|
-
throw
|
|
74376
|
+
throw RequestError11.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
|
|
74429
74377
|
}
|
|
74430
74378
|
this.sessions.close(params.sessionId);
|
|
74431
74379
|
this.lastSessionCwd = params.cwd;
|
|
74432
74380
|
const stored = this.findStoredSession(params.sessionId);
|
|
74433
74381
|
if (!stored) {
|
|
74434
|
-
throw
|
|
74382
|
+
throw RequestError11.invalidParams(`Unknown sessionId: ${params.sessionId}`);
|
|
74435
74383
|
}
|
|
74436
74384
|
const enableSkillCommands = getEnableSkillCommands(params.cwd, this.environment);
|
|
74437
74385
|
const session = await this.restoreSession(params.sessionId, {
|
|
@@ -74454,9 +74402,29 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74454
74402
|
cwd: params.cwd,
|
|
74455
74403
|
sessionFile: stored.sessionFile
|
|
74456
74404
|
});
|
|
74457
|
-
const
|
|
74458
|
-
|
|
74459
|
-
|
|
74405
|
+
for (const entry of readPiHistory(stored.sessionFile)) {
|
|
74406
|
+
if (entry.type === "compaction") {
|
|
74407
|
+
await this.conn.sessionUpdate({
|
|
74408
|
+
sessionId: session.sessionId,
|
|
74409
|
+
update: {
|
|
74410
|
+
sessionUpdate: "compaction_update",
|
|
74411
|
+
compactionId: entry.id,
|
|
74412
|
+
status: "completed"
|
|
74413
|
+
}
|
|
74414
|
+
});
|
|
74415
|
+
if (entry.summary) {
|
|
74416
|
+
await this.conn.sessionUpdate({
|
|
74417
|
+
sessionId: session.sessionId,
|
|
74418
|
+
update: {
|
|
74419
|
+
sessionUpdate: "compaction_summary_chunk",
|
|
74420
|
+
compactionId: entry.id,
|
|
74421
|
+
content: { type: "text", text: entry.summary }
|
|
74422
|
+
}
|
|
74423
|
+
});
|
|
74424
|
+
}
|
|
74425
|
+
continue;
|
|
74426
|
+
}
|
|
74427
|
+
const m = entry.message;
|
|
74460
74428
|
const role = String(m?.role ?? "");
|
|
74461
74429
|
if (role === "user") {
|
|
74462
74430
|
const text2 = normalizePiMessageText(m?.content);
|
|
@@ -74606,7 +74574,7 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74606
74574
|
const session = await this.restoreSession(params.sessionId);
|
|
74607
74575
|
const mode = params.modeId;
|
|
74608
74576
|
if (typeof mode !== "string" || mode.length === 0) {
|
|
74609
|
-
throw
|
|
74577
|
+
throw RequestError11.invalidParams("Expected nonempty string modeId");
|
|
74610
74578
|
}
|
|
74611
74579
|
await session.proc.setThinkingLevel(mode);
|
|
74612
74580
|
await emitConfigOptionsUpdate(this.conn, session.sessionId, session.proc);
|
|
@@ -74617,18 +74585,18 @@ ${JSON.stringify(stats, null, 2)}`;
|
|
|
74617
74585
|
const configId = String(params.configId);
|
|
74618
74586
|
let modelChanged = false;
|
|
74619
74587
|
if (typeof params.value !== "string") {
|
|
74620
|
-
throw
|
|
74588
|
+
throw RequestError11.invalidParams(`Expected string value for config option: ${configId}`);
|
|
74621
74589
|
}
|
|
74622
74590
|
if (configId === MODEL_CONFIG_ID2) {
|
|
74623
74591
|
await setSessionModel(session.proc, params.value);
|
|
74624
74592
|
modelChanged = true;
|
|
74625
74593
|
} else if (configId === THOUGHT_LEVEL_CONFIG_ID) {
|
|
74626
74594
|
if (params.value.length === 0) {
|
|
74627
|
-
throw
|
|
74595
|
+
throw RequestError11.invalidParams("Expected nonempty thinking level");
|
|
74628
74596
|
}
|
|
74629
74597
|
await session.proc.setThinkingLevel(params.value);
|
|
74630
74598
|
} else {
|
|
74631
|
-
throw
|
|
74599
|
+
throw RequestError11.invalidParams(`Unknown config option: ${configId}`);
|
|
74632
74600
|
}
|
|
74633
74601
|
const configOptions = await emitConfigOptionsUpdate(this.conn, session.sessionId, session.proc);
|
|
74634
74602
|
if (modelChanged) {
|
|
@@ -74784,7 +74752,7 @@ async function setSessionModel(proc, requestedModelId) {
|
|
|
74784
74752
|
}
|
|
74785
74753
|
}
|
|
74786
74754
|
if (!provider || !modelId) {
|
|
74787
|
-
throw
|
|
74755
|
+
throw RequestError11.invalidParams(`Unknown modelId: ${requestedModelId}`);
|
|
74788
74756
|
}
|
|
74789
74757
|
await proc.setModel(provider, modelId);
|
|
74790
74758
|
}
|
|
@@ -74938,7 +74906,7 @@ function buildStartupInfo(opts) {
|
|
|
74938
74906
|
];
|
|
74939
74907
|
for (const settingsPath of settingsPaths) {
|
|
74940
74908
|
try {
|
|
74941
|
-
const settings = JSON.parse(
|
|
74909
|
+
const settings = JSON.parse(readFileSync9(settingsPath, "utf-8"));
|
|
74942
74910
|
const pkgs = Array.isArray(settings?.packages) ? settings.packages : [];
|
|
74943
74911
|
for (const pkg of pkgs) {
|
|
74944
74912
|
const s = String(pkg);
|
|
@@ -75623,7 +75591,14 @@ async function probeVersion(executable, arguments_, environment, defaultWorkspac
|
|
|
75623
75591
|
});
|
|
75624
75592
|
const version2 = normalize4(result.stdout || result.stderr);
|
|
75625
75593
|
if (version2.length === 0) {
|
|
75626
|
-
throw new ProcessExecutionError("process_exit_failed", "The executable did not report a version"
|
|
75594
|
+
throw new ProcessExecutionError("process_exit_failed", "The executable did not report a version", {
|
|
75595
|
+
diagnosticDetails: {
|
|
75596
|
+
probeReason: "empty_version_output",
|
|
75597
|
+
exitCode: "0",
|
|
75598
|
+
stdoutBytes: Buffer.byteLength(result.stdout).toString(),
|
|
75599
|
+
stderrBytes: Buffer.byteLength(result.stderr).toString()
|
|
75600
|
+
}
|
|
75601
|
+
});
|
|
75627
75602
|
}
|
|
75628
75603
|
return version2;
|
|
75629
75604
|
}
|
|
@@ -75645,9 +75620,27 @@ function isRetryableProbeFailure(error62) {
|
|
|
75645
75620
|
}
|
|
75646
75621
|
return error62 instanceof AgentProbeError && error62.code === "adapter_probe_timeout";
|
|
75647
75622
|
}
|
|
75648
|
-
async function probeWithRetry(
|
|
75623
|
+
async function probeWithRetry(context, specification, source, probe) {
|
|
75624
|
+
const signal = context.signal;
|
|
75625
|
+
const run = async (attempt) => {
|
|
75626
|
+
const startedAt = performance.now();
|
|
75627
|
+
try {
|
|
75628
|
+
return await probe();
|
|
75629
|
+
} catch (failure2) {
|
|
75630
|
+
context.onProbeDiagnostic?.({
|
|
75631
|
+
agentId: specification.id,
|
|
75632
|
+
source,
|
|
75633
|
+
event: signal.aborted ? "agent_probe_cancelled" : "agent_probe_failed",
|
|
75634
|
+
attempt,
|
|
75635
|
+
elapsedMilliseconds: Math.round(performance.now() - startedAt),
|
|
75636
|
+
timeoutMilliseconds: source === "acp_readiness" ? specification.acpProbeTimeoutMilliseconds : specification.versionProbeTimeoutMilliseconds,
|
|
75637
|
+
failure: failure2
|
|
75638
|
+
});
|
|
75639
|
+
throw failure2;
|
|
75640
|
+
}
|
|
75641
|
+
};
|
|
75649
75642
|
try {
|
|
75650
|
-
return await
|
|
75643
|
+
return await run(1);
|
|
75651
75644
|
} catch (error62) {
|
|
75652
75645
|
if (signal.aborted) {
|
|
75653
75646
|
signal.throwIfAborted();
|
|
@@ -75655,7 +75648,7 @@ async function probeWithRetry(signal, probe) {
|
|
|
75655
75648
|
if (!isRetryableProbeFailure(error62)) {
|
|
75656
75649
|
throw error62;
|
|
75657
75650
|
}
|
|
75658
|
-
return await
|
|
75651
|
+
return await run(2);
|
|
75659
75652
|
}
|
|
75660
75653
|
}
|
|
75661
75654
|
function integrationProbeFailure(specification, error62) {
|
|
@@ -75685,7 +75678,9 @@ async function discoverAgent(specification, context) {
|
|
|
75685
75678
|
let agentVersion = "";
|
|
75686
75679
|
try {
|
|
75687
75680
|
agentVersion = await probeWithRetry(
|
|
75688
|
-
context
|
|
75681
|
+
context,
|
|
75682
|
+
specification,
|
|
75683
|
+
"agent_version",
|
|
75689
75684
|
async () => await probeVersion(
|
|
75690
75685
|
agent,
|
|
75691
75686
|
specification.agentVersionArguments,
|
|
@@ -75733,7 +75728,9 @@ async function discoverAgent(specification, context) {
|
|
|
75733
75728
|
launchEnvironment = await specification.createLaunchEnvironment(agent, context);
|
|
75734
75729
|
if (specification.adapterVersionArguments.length > 0) {
|
|
75735
75730
|
adapterVersion = await probeWithRetry(
|
|
75736
|
-
context
|
|
75731
|
+
context,
|
|
75732
|
+
specification,
|
|
75733
|
+
"adapter_version",
|
|
75737
75734
|
async () => await probeVersion(
|
|
75738
75735
|
adapter,
|
|
75739
75736
|
specification.adapterVersionArguments,
|
|
@@ -75768,7 +75765,9 @@ async function discoverAgent(specification, context) {
|
|
|
75768
75765
|
);
|
|
75769
75766
|
try {
|
|
75770
75767
|
const readiness = await probeWithRetry(
|
|
75771
|
-
context
|
|
75768
|
+
context,
|
|
75769
|
+
specification,
|
|
75770
|
+
"acp_readiness",
|
|
75772
75771
|
async () => await probeAcpReadiness(
|
|
75773
75772
|
specification,
|
|
75774
75773
|
buildDefinition(adapterVersion, unsupportedSessionCapabilities()),
|
|
@@ -83471,6 +83470,266 @@ function describeEnvironmentProxyRoute(target) {
|
|
|
83471
83470
|
};
|
|
83472
83471
|
}
|
|
83473
83472
|
|
|
83473
|
+
// src/engine/runtime/observability/diagnostic-log.ts
|
|
83474
|
+
import { join as join26 } from "node:path";
|
|
83475
|
+
|
|
83476
|
+
// src/engine/storage/logs/bounded-log.ts
|
|
83477
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync10, renameSync as renameSync2, statSync as statSync5, writeFileSync as writeFileSync2 } from "node:fs";
|
|
83478
|
+
import { join as join24 } from "node:path";
|
|
83479
|
+
var BoundedLineLog = class {
|
|
83480
|
+
#path;
|
|
83481
|
+
#maximumBytes;
|
|
83482
|
+
#directory;
|
|
83483
|
+
#reportedFailure = false;
|
|
83484
|
+
#onWriteFailure;
|
|
83485
|
+
constructor(directory, filename, maximumBytes, onWriteFailure = () => void 0) {
|
|
83486
|
+
this.#directory = directory;
|
|
83487
|
+
this.#path = join24(directory, filename);
|
|
83488
|
+
this.#maximumBytes = maximumBytes;
|
|
83489
|
+
this.#onWriteFailure = onWriteFailure;
|
|
83490
|
+
}
|
|
83491
|
+
record = (line) => {
|
|
83492
|
+
try {
|
|
83493
|
+
mkdirSync4(this.#directory, { mode: 448, recursive: true });
|
|
83494
|
+
this.#append(line);
|
|
83495
|
+
} catch (cause) {
|
|
83496
|
+
if (!this.#reportedFailure) {
|
|
83497
|
+
this.#reportedFailure = true;
|
|
83498
|
+
this.#onWriteFailure(cause);
|
|
83499
|
+
}
|
|
83500
|
+
}
|
|
83501
|
+
};
|
|
83502
|
+
#append = (line) => {
|
|
83503
|
+
const encoded = `${line.replace(/[\r\n]+/gu, " ").trim()}
|
|
83504
|
+
`;
|
|
83505
|
+
const encodedBytes = Buffer.byteLength(encoded);
|
|
83506
|
+
let existingBytes = 0;
|
|
83507
|
+
try {
|
|
83508
|
+
existingBytes = statSync5(this.#path).size;
|
|
83509
|
+
} catch (cause) {
|
|
83510
|
+
if (!(cause instanceof Error && Reflect.get(cause, "code") === "ENOENT")) {
|
|
83511
|
+
throw cause;
|
|
83512
|
+
}
|
|
83513
|
+
}
|
|
83514
|
+
if (existingBytes + encodedBytes <= this.#maximumBytes) {
|
|
83515
|
+
appendFileSync2(this.#path, encoded, { encoding: "utf8", mode: 384 });
|
|
83516
|
+
return;
|
|
83517
|
+
}
|
|
83518
|
+
const lines = `${existingBytes === 0 ? "" : readFileSync10(this.#path, "utf8")}${encoded}`.split("\n").filter((candidate) => candidate.length > 0);
|
|
83519
|
+
let totalBytes = lines.reduce((total, candidate) => total + Buffer.byteLength(candidate) + 1, 0);
|
|
83520
|
+
while (totalBytes > this.#maximumBytes && lines.length > 0) {
|
|
83521
|
+
const oldest = lines.shift();
|
|
83522
|
+
if (oldest !== void 0) {
|
|
83523
|
+
totalBytes -= Buffer.byteLength(oldest) + 1;
|
|
83524
|
+
}
|
|
83525
|
+
}
|
|
83526
|
+
const temporaryPath = `${this.#path}.tmp`;
|
|
83527
|
+
writeFileSync2(temporaryPath, lines.length === 0 ? "" : `${lines.join("\n")}
|
|
83528
|
+
`, {
|
|
83529
|
+
encoding: "utf8",
|
|
83530
|
+
mode: 384
|
|
83531
|
+
});
|
|
83532
|
+
renameSync2(temporaryPath, this.#path);
|
|
83533
|
+
};
|
|
83534
|
+
};
|
|
83535
|
+
|
|
83536
|
+
// src/engine/storage/logs/log-files.ts
|
|
83537
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
83538
|
+
import { join as join25 } from "node:path";
|
|
83539
|
+
var DAEMON_LOG_FILENAME = "daemon.log";
|
|
83540
|
+
var WORKER_LIFECYCLE_LOG_FILENAME = "worker-lifecycle.log";
|
|
83541
|
+
function unhandledRejectionLogFilename(role) {
|
|
83542
|
+
return `unhandled-rejections-${role}.log`;
|
|
83543
|
+
}
|
|
83544
|
+
function logDirectory(dataDirectory) {
|
|
83545
|
+
return join25(dataDirectory, "logs");
|
|
83546
|
+
}
|
|
83547
|
+
function processLogPaths(dataDirectory) {
|
|
83548
|
+
return [
|
|
83549
|
+
WORKER_LIFECYCLE_LOG_FILENAME,
|
|
83550
|
+
unhandledRejectionLogFilename("manager"),
|
|
83551
|
+
unhandledRejectionLogFilename("worker")
|
|
83552
|
+
].map((filename) => join25(logDirectory(dataDirectory), filename));
|
|
83553
|
+
}
|
|
83554
|
+
function readLogText(path7) {
|
|
83555
|
+
try {
|
|
83556
|
+
return readFileSync11(path7, "utf8");
|
|
83557
|
+
} catch {
|
|
83558
|
+
return null;
|
|
83559
|
+
}
|
|
83560
|
+
}
|
|
83561
|
+
|
|
83562
|
+
// src/engine/runtime/observability/diagnostic-log.ts
|
|
83563
|
+
var MAXIMUM_RUNTIME_LOG_BYTES = 1 * 1024 * 1024;
|
|
83564
|
+
var MAXIMUM_ENTRIES = 200;
|
|
83565
|
+
var MAXIMUM_REPORT_BYTES = 6e4;
|
|
83566
|
+
var REMOTE_DIAGNOSTIC_FIELDS = [
|
|
83567
|
+
"agentId",
|
|
83568
|
+
"operation",
|
|
83569
|
+
"runtimeId",
|
|
83570
|
+
"closeCode",
|
|
83571
|
+
"timeoutMilliseconds",
|
|
83572
|
+
"attempt",
|
|
83573
|
+
"elapsedMilliseconds",
|
|
83574
|
+
"stdoutBytes",
|
|
83575
|
+
"stderrBytes",
|
|
83576
|
+
"outputLimitBytes",
|
|
83577
|
+
"probeReason",
|
|
83578
|
+
"proxyRoute",
|
|
83579
|
+
"timestamp",
|
|
83580
|
+
"event",
|
|
83581
|
+
"channelId",
|
|
83582
|
+
"requestId",
|
|
83583
|
+
"commandId",
|
|
83584
|
+
"sessionId",
|
|
83585
|
+
"turnId",
|
|
83586
|
+
"connectionEpoch",
|
|
83587
|
+
"code",
|
|
83588
|
+
"source",
|
|
83589
|
+
"kind",
|
|
83590
|
+
"pid",
|
|
83591
|
+
"version",
|
|
83592
|
+
"exitCode",
|
|
83593
|
+
"signal",
|
|
83594
|
+
"failureName",
|
|
83595
|
+
"failureCode",
|
|
83596
|
+
"failureStatusCode",
|
|
83597
|
+
"cause1Name",
|
|
83598
|
+
"cause1Code",
|
|
83599
|
+
"cause2Name",
|
|
83600
|
+
"cause2Code"
|
|
83601
|
+
];
|
|
83602
|
+
var FIELD_VALUE_PATTERN = /^[a-zA-Z0-9_.: -]{1,256}$/u;
|
|
83603
|
+
var RuntimeDiagnosticLog = class {
|
|
83604
|
+
#log;
|
|
83605
|
+
#maximumBytes;
|
|
83606
|
+
#sources;
|
|
83607
|
+
constructor(stateDirectory, options = {}) {
|
|
83608
|
+
const maximumBytes = options.maximumBytes ?? MAXIMUM_RUNTIME_LOG_BYTES;
|
|
83609
|
+
const directory = logDirectory(stateDirectory);
|
|
83610
|
+
this.#log = new BoundedLineLog(directory, DAEMON_LOG_FILENAME, maximumBytes);
|
|
83611
|
+
this.#maximumBytes = maximumBytes;
|
|
83612
|
+
const processLogsDirectory = options.processLogsDirectory;
|
|
83613
|
+
this.#sources = [
|
|
83614
|
+
{ maximumBytes, path: join26(directory, DAEMON_LOG_FILENAME) },
|
|
83615
|
+
// The process logs a Runtime does not own, but must read to explain its own deaths.
|
|
83616
|
+
...processLogsDirectory === void 0 ? [] : processLogPaths(processLogsDirectory).map((path7) => ({ maximumBytes: null, path: path7 }))
|
|
83617
|
+
];
|
|
83618
|
+
}
|
|
83619
|
+
// Export only correlation and failure metadata. Local messages and paths stay local.
|
|
83620
|
+
snapshot = () => {
|
|
83621
|
+
const merged = [];
|
|
83622
|
+
let truncated = false;
|
|
83623
|
+
for (const source of this.#sources) {
|
|
83624
|
+
const collected = this.#read(source);
|
|
83625
|
+
merged.push(...collected.entries);
|
|
83626
|
+
truncated ||= collected.truncated;
|
|
83627
|
+
}
|
|
83628
|
+
merged.sort(compareTimestamp);
|
|
83629
|
+
const entries = merged.slice(-MAXIMUM_ENTRIES);
|
|
83630
|
+
truncated ||= entries.length < merged.length;
|
|
83631
|
+
while (JSON.stringify(entries).length > MAXIMUM_REPORT_BYTES && entries.length > 0) {
|
|
83632
|
+
entries.shift();
|
|
83633
|
+
truncated = true;
|
|
83634
|
+
}
|
|
83635
|
+
return { entries, truncated };
|
|
83636
|
+
};
|
|
83637
|
+
record = (diagnostic) => {
|
|
83638
|
+
this.#log.record(diagnostic);
|
|
83639
|
+
};
|
|
83640
|
+
#read = (source) => {
|
|
83641
|
+
const content = readLogText(source.path);
|
|
83642
|
+
if (content === null) {
|
|
83643
|
+
return { entries: [], truncated: false };
|
|
83644
|
+
}
|
|
83645
|
+
const lines = content.split("\n").filter((line) => line.length > 0);
|
|
83646
|
+
const entries = [];
|
|
83647
|
+
for (const line of lines.slice(-MAXIMUM_ENTRIES)) {
|
|
83648
|
+
const start = line.indexOf("{");
|
|
83649
|
+
if (start < 0) {
|
|
83650
|
+
continue;
|
|
83651
|
+
}
|
|
83652
|
+
let value;
|
|
83653
|
+
try {
|
|
83654
|
+
value = JSON.parse(line.slice(start));
|
|
83655
|
+
} catch {
|
|
83656
|
+
continue;
|
|
83657
|
+
}
|
|
83658
|
+
if (typeof value !== "object" || value === null) {
|
|
83659
|
+
continue;
|
|
83660
|
+
}
|
|
83661
|
+
entries.push(exportedFields(value));
|
|
83662
|
+
}
|
|
83663
|
+
const nearRotation = source.maximumBytes !== null && Buffer.byteLength(content) >= source.maximumBytes - 4096;
|
|
83664
|
+
return { entries, truncated: lines.length > MAXIMUM_ENTRIES || nearRotation };
|
|
83665
|
+
};
|
|
83666
|
+
};
|
|
83667
|
+
function exportedFields(value) {
|
|
83668
|
+
const entry = {};
|
|
83669
|
+
for (const field of REMOTE_DIAGNOSTIC_FIELDS) {
|
|
83670
|
+
const item = Reflect.get(value, field);
|
|
83671
|
+
if (typeof item === "string" && FIELD_VALUE_PATTERN.test(item)) {
|
|
83672
|
+
entry[field] = item;
|
|
83673
|
+
} else if (typeof item === "number" && Number.isFinite(item)) {
|
|
83674
|
+
entry[field] = String(item);
|
|
83675
|
+
}
|
|
83676
|
+
}
|
|
83677
|
+
return entry;
|
|
83678
|
+
}
|
|
83679
|
+
function compareTimestamp(left, right) {
|
|
83680
|
+
const leftAt = left["timestamp"] ?? "";
|
|
83681
|
+
const rightAt = right["timestamp"] ?? "";
|
|
83682
|
+
return leftAt < rightAt ? -1 : leftAt > rightAt ? 1 : 0;
|
|
83683
|
+
}
|
|
83684
|
+
|
|
83685
|
+
// src/engine/runtime/catalog/discover-agent-catalog.ts
|
|
83686
|
+
function failureDetails(failure2) {
|
|
83687
|
+
const fields = {};
|
|
83688
|
+
let current = failure2;
|
|
83689
|
+
for (let depth = 0; depth < 3 && current instanceof Error; depth += 1) {
|
|
83690
|
+
const prefix = depth === 0 ? "failure" : `cause${depth.toString()}`;
|
|
83691
|
+
if (current instanceof ProcessExecutionError || current instanceof AgentProbeError) {
|
|
83692
|
+
fields[`${prefix}Name`] = current instanceof ProcessExecutionError ? "ProcessExecutionError" : "AgentProbeError";
|
|
83693
|
+
fields[`${prefix}Code`] = current.code;
|
|
83694
|
+
} else {
|
|
83695
|
+
fields[`${prefix}Name`] = "Error";
|
|
83696
|
+
}
|
|
83697
|
+
if (depth === 0 && current instanceof ProcessExecutionError) {
|
|
83698
|
+
Object.assign(fields, current.diagnosticDetails);
|
|
83699
|
+
}
|
|
83700
|
+
current = current.cause;
|
|
83701
|
+
}
|
|
83702
|
+
return fields;
|
|
83703
|
+
}
|
|
83704
|
+
async function discoverRuntimeAgentInventory(options, channelId) {
|
|
83705
|
+
const log = new RuntimeDiagnosticLog(options.dataDirectory);
|
|
83706
|
+
const record2 = (details) => {
|
|
83707
|
+
log.record(
|
|
83708
|
+
`Mobius agent discovery diagnostic ${JSON.stringify({
|
|
83709
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
83710
|
+
channelId,
|
|
83711
|
+
...details
|
|
83712
|
+
})}`
|
|
83713
|
+
);
|
|
83714
|
+
};
|
|
83715
|
+
const inventory = await discoverLocalAgentInventory({
|
|
83716
|
+
...options,
|
|
83717
|
+
onProbeDiagnostic: ({ failure: failure2, ...diagnostic }) => {
|
|
83718
|
+
record2({ ...diagnostic, ...failureDetails(failure2) });
|
|
83719
|
+
}
|
|
83720
|
+
});
|
|
83721
|
+
for (const { discovery, detectionMilliseconds } of inventory.results) {
|
|
83722
|
+
record2({
|
|
83723
|
+
event: "agent_discovery_result",
|
|
83724
|
+
agentId: discovery.specification.id,
|
|
83725
|
+
code: discovery instanceof UnavailableAgent ? discovery.code : "ready",
|
|
83726
|
+
source: discovery.status,
|
|
83727
|
+
elapsedMilliseconds: detectionMilliseconds
|
|
83728
|
+
});
|
|
83729
|
+
}
|
|
83730
|
+
return inventory;
|
|
83731
|
+
}
|
|
83732
|
+
|
|
83474
83733
|
// src/engine/runtime/catalog/publish-agent-catalog.ts
|
|
83475
83734
|
import { fetch as fetch2 } from "undici";
|
|
83476
83735
|
|
|
@@ -83917,21 +84176,27 @@ function buildSavedRuntimeConfig(connection, defaultWorkspace, inventory, localC
|
|
|
83917
84176
|
localContext,
|
|
83918
84177
|
new OpaqueRuntimeReconnectTarget(connection.connectionId),
|
|
83919
84178
|
createCatalogAgentResolver(
|
|
83920
|
-
(refreshSignal) =>
|
|
84179
|
+
(refreshSignal) => discoverRuntimeAgentInventory(
|
|
84180
|
+
{
|
|
84181
|
+
defaultWorkspace,
|
|
84182
|
+
dataDirectory: localContext.stateDirectory,
|
|
84183
|
+
environment: localContext.agentLaunchEnvironment,
|
|
84184
|
+
signal: refreshSignal
|
|
84185
|
+
},
|
|
84186
|
+
connection.channelId
|
|
84187
|
+
),
|
|
84188
|
+
() => config2,
|
|
84189
|
+
publishAgentCatalog
|
|
84190
|
+
),
|
|
84191
|
+
(refreshSignal) => discoverRuntimeAgentInventory(
|
|
84192
|
+
{
|
|
83921
84193
|
defaultWorkspace,
|
|
83922
84194
|
dataDirectory: localContext.stateDirectory,
|
|
83923
84195
|
environment: localContext.agentLaunchEnvironment,
|
|
83924
84196
|
signal: refreshSignal
|
|
83925
|
-
}
|
|
83926
|
-
|
|
83927
|
-
|
|
83928
|
-
),
|
|
83929
|
-
(refreshSignal) => discoverLocalAgentInventory({
|
|
83930
|
-
defaultWorkspace,
|
|
83931
|
-
dataDirectory: localContext.stateDirectory,
|
|
83932
|
-
environment: localContext.agentLaunchEnvironment,
|
|
83933
|
-
signal: refreshSignal
|
|
83934
|
-
}).then((inventory2) => inventory2.readyAgents())
|
|
84197
|
+
},
|
|
84198
|
+
connection.channelId
|
|
84199
|
+
).then((inventory2) => inventory2.readyAgents())
|
|
83935
84200
|
);
|
|
83936
84201
|
return config2;
|
|
83937
84202
|
}
|
|
@@ -83975,12 +84240,15 @@ async function pairRuntimeConnection(installation, options, signal, environment)
|
|
|
83975
84240
|
async function prepareRuntimeConnection(installation, connection, signal, environment, maxAcpProcesses) {
|
|
83976
84241
|
const localContext = new RuntimeLocalContext(installation.stateDirectory, environment, maxAcpProcesses);
|
|
83977
84242
|
const defaultWorkspace = await resolveDefaultWorkspace(connection.defaultWorkspace);
|
|
83978
|
-
const inventory = await
|
|
83979
|
-
|
|
83980
|
-
|
|
83981
|
-
|
|
83982
|
-
|
|
83983
|
-
|
|
84243
|
+
const inventory = await discoverRuntimeAgentInventory(
|
|
84244
|
+
{
|
|
84245
|
+
defaultWorkspace,
|
|
84246
|
+
dataDirectory: localContext.stateDirectory,
|
|
84247
|
+
environment: localContext.agentLaunchEnvironment,
|
|
84248
|
+
signal
|
|
84249
|
+
},
|
|
84250
|
+
connection.channelId
|
|
84251
|
+
);
|
|
83984
84252
|
return buildSavedRuntimeConfig(connection, defaultWorkspace, inventory, localContext);
|
|
83985
84253
|
}
|
|
83986
84254
|
|
|
@@ -84926,7 +85194,7 @@ var SessionConfigurations = class {
|
|
|
84926
85194
|
restore = async (stored, options, apply, signal) => {
|
|
84927
85195
|
this.#selected = stored;
|
|
84928
85196
|
for (const selection of this.#selected) {
|
|
84929
|
-
const current = options.find(
|
|
85197
|
+
const current = options().find(
|
|
84930
85198
|
(option) => option.id === selection.configId && option.type === selection.type
|
|
84931
85199
|
);
|
|
84932
85200
|
if (current === void 0) {
|
|
@@ -85118,6 +85386,7 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
85118
85386
|
session.store.remove(session.sessionId);
|
|
85119
85387
|
stored = session.metrics.measureSync("session-state-read", () => session.store.read(session.sessionId));
|
|
85120
85388
|
}
|
|
85389
|
+
const forkSource = origin?.kind === "fork" ? session.store.findNative(session.agentId, origin.nativeSessionId)[0] : void 0;
|
|
85121
85390
|
let lifecycleResponse;
|
|
85122
85391
|
if (origin?.kind === "fork") {
|
|
85123
85392
|
if (!session.capabilities.unstableForkSession) {
|
|
@@ -85279,7 +85548,9 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
85279
85548
|
}
|
|
85280
85549
|
session.restrictSessionCapabilities(lifecycleResponse);
|
|
85281
85550
|
session.setConfigOptions(session.sessionConfigProtocol.normalizeLifecycle(lifecycleResponse));
|
|
85282
|
-
if (
|
|
85551
|
+
if (forkSource !== void 0) {
|
|
85552
|
+
await session.restoreStoredConfigurations(forkSource, signal, "fork");
|
|
85553
|
+
} else if (stored instanceof FoundStoredSession && session.restored) {
|
|
85283
85554
|
await session.restoreStoredConfigurations(stored.session, signal);
|
|
85284
85555
|
}
|
|
85285
85556
|
await session.drained();
|
|
@@ -85491,13 +85762,31 @@ var AgentSession = class _AgentSession {
|
|
|
85491
85762
|
this.writeStoredSession((/* @__PURE__ */ new Date()).toISOString());
|
|
85492
85763
|
}
|
|
85493
85764
|
};
|
|
85494
|
-
restoreStoredConfigurations = async (session, signal) => {
|
|
85765
|
+
restoreStoredConfigurations = async (session, signal, intent = "restore") => {
|
|
85766
|
+
const configurations = intent === "fork" ? session.configurations.toSorted(
|
|
85767
|
+
(left, right) => Number(right.configId === "model") - Number(left.configId === "model")
|
|
85768
|
+
) : session.configurations;
|
|
85495
85769
|
await this.#sessionConfigurations.restore(
|
|
85496
|
-
|
|
85497
|
-
this.#configOptions,
|
|
85770
|
+
configurations,
|
|
85771
|
+
() => this.#configOptions,
|
|
85498
85772
|
this.#applyConfiguration,
|
|
85499
85773
|
signal
|
|
85500
85774
|
);
|
|
85775
|
+
if (intent === "fork") {
|
|
85776
|
+
for (const selection of session.configurations) {
|
|
85777
|
+
if (selection.configId !== "mode") {
|
|
85778
|
+
continue;
|
|
85779
|
+
}
|
|
85780
|
+
const current = this.#configOptions.find((option) => option.id === selection.configId);
|
|
85781
|
+
if (current?.type !== selection.type || (selection.type === "select" ? current.currentValue !== selection.value : current.booleanValue !== selection.booleanValue)) {
|
|
85782
|
+
throw new AcpExecutionError(
|
|
85783
|
+
"The Agent could not preserve the source Session mode for this Fork",
|
|
85784
|
+
{},
|
|
85785
|
+
"invalid_session_configuration"
|
|
85786
|
+
);
|
|
85787
|
+
}
|
|
85788
|
+
}
|
|
85789
|
+
}
|
|
85501
85790
|
};
|
|
85502
85791
|
restrictSessionCapabilities = (response) => {
|
|
85503
85792
|
this.#capabilities = restrictAcpSessionCapabilities(this.#capabilities, response);
|
|
@@ -86938,7 +87227,8 @@ var NativeSessionService = class {
|
|
|
86938
87227
|
requestId: command.requestId,
|
|
86939
87228
|
sessionId: command.sessionId,
|
|
86940
87229
|
targetSessionId: command.targetSessionId,
|
|
86941
|
-
...await this.#activeTurn(command, options)
|
|
87230
|
+
...await this.#activeTurn(command, options),
|
|
87231
|
+
queuedCancellation: "before-start"
|
|
86942
87232
|
};
|
|
86943
87233
|
}
|
|
86944
87234
|
const capabilities = await options.adapter.getCapabilities(options);
|
|
@@ -87548,6 +87838,11 @@ var ExecutionReceipts = class {
|
|
|
87548
87838
|
return void 0;
|
|
87549
87839
|
}
|
|
87550
87840
|
};
|
|
87841
|
+
/** Started identities remain authoritative after their detailed receipt is evicted. */
|
|
87842
|
+
hasStarted = (commandId, sessionId) => {
|
|
87843
|
+
const receipt = this.#executions.get(commandId);
|
|
87844
|
+
return receipt === void 0 ? this.#table.identity(commandId)?.sessionId === sessionId : receipt.sessionId === sessionId && receipt.started;
|
|
87845
|
+
};
|
|
87551
87846
|
/** Reserves an unseen command for cancellation before a delayed prompt can claim its identity. */
|
|
87552
87847
|
recordCancellationBeforeAdmission = (commandId, sessionId) => {
|
|
87553
87848
|
const existing = this.#executions.get(commandId);
|
|
@@ -88069,7 +88364,7 @@ var SessionTurns = class {
|
|
|
88069
88364
|
|
|
88070
88365
|
// src/engine/session/workspace/workspace-directory.ts
|
|
88071
88366
|
import { homedir as homedir3 } from "node:os";
|
|
88072
|
-
import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute15, join as
|
|
88367
|
+
import { basename as basename7, dirname as dirname10, isAbsolute as isAbsolute15, join as join27, normalize as normalize2, relative as relative2 } from "node:path";
|
|
88073
88368
|
var WorkspaceDirectoryListing = class {
|
|
88074
88369
|
directoryId;
|
|
88075
88370
|
directoryLabel;
|
|
@@ -88192,7 +88487,7 @@ var WorkspaceDirectoryService = class {
|
|
|
88192
88487
|
continue;
|
|
88193
88488
|
}
|
|
88194
88489
|
try {
|
|
88195
|
-
const path7 = await this.resolvePath(
|
|
88490
|
+
const path7 = await this.resolvePath(join27(target, child.name), signal);
|
|
88196
88491
|
entries.push({ directoryId: encodePath(path7), name: child.name });
|
|
88197
88492
|
} catch (cause) {
|
|
88198
88493
|
signal.throwIfAborted();
|
|
@@ -88348,12 +88643,12 @@ function buildSessionLayer(options) {
|
|
|
88348
88643
|
|
|
88349
88644
|
// src/engine/session/content/external-content-store.ts
|
|
88350
88645
|
import { createHash as createHash8 } from "node:crypto";
|
|
88351
|
-
import { extname as
|
|
88646
|
+
import { extname as extname2, join as join29 } from "node:path";
|
|
88352
88647
|
|
|
88353
88648
|
// src/engine/storage/files/scratch-directory.ts
|
|
88354
88649
|
import { randomUUID as randomUUID17 } from "node:crypto";
|
|
88355
88650
|
import { lstat as lstat4, mkdir as mkdir5, readdir as readdir6, readFile as readFile6, realpath as realpath7, rename as rename4, rm as rm3, stat as stat6, utimes, writeFile as writeFile2 } from "node:fs/promises";
|
|
88356
|
-
import { dirname as dirname11, join as
|
|
88651
|
+
import { dirname as dirname11, join as join28 } from "node:path";
|
|
88357
88652
|
async function atomicWrite(path7, bytes, signal) {
|
|
88358
88653
|
const temporary = `${path7}.${randomUUID17()}.tmp`;
|
|
88359
88654
|
try {
|
|
@@ -88367,7 +88662,7 @@ async function atomicWrite(path7, bytes, signal) {
|
|
|
88367
88662
|
var ScratchDirectory = class {
|
|
88368
88663
|
#root;
|
|
88369
88664
|
constructor(parent) {
|
|
88370
|
-
this.#root =
|
|
88665
|
+
this.#root = join28(parent, randomUUID17());
|
|
88371
88666
|
}
|
|
88372
88667
|
/** Refreshes this directory's lease and removes sibling directories whose lease is older than `leaseMilliseconds`. */
|
|
88373
88668
|
refreshLease = async (leaseMilliseconds) => {
|
|
@@ -88378,7 +88673,7 @@ var ScratchDirectory = class {
|
|
|
88378
88673
|
if (!directory.isDirectory() || !/^[a-f0-9-]{36}$/u.test(directory.name)) {
|
|
88379
88674
|
continue;
|
|
88380
88675
|
}
|
|
88381
|
-
const path7 =
|
|
88676
|
+
const path7 = join28(dirname11(this.#root), directory.name);
|
|
88382
88677
|
if (path7 === this.#root) {
|
|
88383
88678
|
continue;
|
|
88384
88679
|
}
|
|
@@ -88393,10 +88688,10 @@ var ScratchDirectory = class {
|
|
|
88393
88688
|
};
|
|
88394
88689
|
/** Writes `bytes` atomically to `<group>/<name>` with owner-only permissions and returns the path. */
|
|
88395
88690
|
write = async (group, name2, bytes, signal) => {
|
|
88396
|
-
const directory =
|
|
88691
|
+
const directory = join28(this.#root, group);
|
|
88397
88692
|
await mkdir5(directory, { mode: 448, recursive: true });
|
|
88398
88693
|
signal.throwIfAborted();
|
|
88399
|
-
const path7 =
|
|
88694
|
+
const path7 = join28(directory, name2);
|
|
88400
88695
|
await atomicWrite(path7, bytes, signal);
|
|
88401
88696
|
return path7;
|
|
88402
88697
|
};
|
|
@@ -88436,7 +88731,7 @@ var metadataSchema = external_exports.strictObject({
|
|
|
88436
88731
|
name: external_exports.string().min(1).max(500)
|
|
88437
88732
|
});
|
|
88438
88733
|
function contentFileName(key, name2) {
|
|
88439
|
-
const extension =
|
|
88734
|
+
const extension = extname2(name2).toLowerCase();
|
|
88440
88735
|
return /^\.[a-z0-9]{1,16}$/u.test(extension) ? `${key}${extension}` : key;
|
|
88441
88736
|
}
|
|
88442
88737
|
var LocalExternalContentStore = class {
|
|
@@ -88447,7 +88742,7 @@ var LocalExternalContentStore = class {
|
|
|
88447
88742
|
#expirationTimer;
|
|
88448
88743
|
#cleanup = Promise.resolve();
|
|
88449
88744
|
constructor(stateDirectory) {
|
|
88450
|
-
this.#scratch = new ScratchDirectory(
|
|
88745
|
+
this.#scratch = new ScratchDirectory(join29(stateDirectory, "tmp", "session-content"));
|
|
88451
88746
|
this.#expirationTimer = setInterval(() => {
|
|
88452
88747
|
void this.#expire().catch(() => void 0);
|
|
88453
88748
|
}, 6e4);
|
|
@@ -88821,212 +89116,6 @@ var AgentProcessPool = class {
|
|
|
88821
89116
|
};
|
|
88822
89117
|
};
|
|
88823
89118
|
|
|
88824
|
-
// src/engine/runtime/observability/diagnostic-log.ts
|
|
88825
|
-
import { join as join29 } from "node:path";
|
|
88826
|
-
|
|
88827
|
-
// src/engine/storage/logs/bounded-log.ts
|
|
88828
|
-
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync9, renameSync as renameSync2, statSync as statSync5, writeFileSync as writeFileSync2 } from "node:fs";
|
|
88829
|
-
import { join as join27 } from "node:path";
|
|
88830
|
-
var BoundedLineLog = class {
|
|
88831
|
-
#path;
|
|
88832
|
-
#maximumBytes;
|
|
88833
|
-
#directory;
|
|
88834
|
-
#reportedFailure = false;
|
|
88835
|
-
#onWriteFailure;
|
|
88836
|
-
constructor(directory, filename, maximumBytes, onWriteFailure = () => void 0) {
|
|
88837
|
-
this.#directory = directory;
|
|
88838
|
-
this.#path = join27(directory, filename);
|
|
88839
|
-
this.#maximumBytes = maximumBytes;
|
|
88840
|
-
this.#onWriteFailure = onWriteFailure;
|
|
88841
|
-
}
|
|
88842
|
-
record = (line) => {
|
|
88843
|
-
try {
|
|
88844
|
-
mkdirSync4(this.#directory, { mode: 448, recursive: true });
|
|
88845
|
-
this.#append(line);
|
|
88846
|
-
} catch (cause) {
|
|
88847
|
-
if (!this.#reportedFailure) {
|
|
88848
|
-
this.#reportedFailure = true;
|
|
88849
|
-
this.#onWriteFailure(cause);
|
|
88850
|
-
}
|
|
88851
|
-
}
|
|
88852
|
-
};
|
|
88853
|
-
#append = (line) => {
|
|
88854
|
-
const encoded = `${line.replace(/[\r\n]+/gu, " ").trim()}
|
|
88855
|
-
`;
|
|
88856
|
-
const encodedBytes = Buffer.byteLength(encoded);
|
|
88857
|
-
let existingBytes = 0;
|
|
88858
|
-
try {
|
|
88859
|
-
existingBytes = statSync5(this.#path).size;
|
|
88860
|
-
} catch (cause) {
|
|
88861
|
-
if (!(cause instanceof Error && Reflect.get(cause, "code") === "ENOENT")) {
|
|
88862
|
-
throw cause;
|
|
88863
|
-
}
|
|
88864
|
-
}
|
|
88865
|
-
if (existingBytes + encodedBytes <= this.#maximumBytes) {
|
|
88866
|
-
appendFileSync2(this.#path, encoded, { encoding: "utf8", mode: 384 });
|
|
88867
|
-
return;
|
|
88868
|
-
}
|
|
88869
|
-
const lines = `${existingBytes === 0 ? "" : readFileSync9(this.#path, "utf8")}${encoded}`.split("\n").filter((candidate) => candidate.length > 0);
|
|
88870
|
-
let totalBytes = lines.reduce((total, candidate) => total + Buffer.byteLength(candidate) + 1, 0);
|
|
88871
|
-
while (totalBytes > this.#maximumBytes && lines.length > 0) {
|
|
88872
|
-
const oldest = lines.shift();
|
|
88873
|
-
if (oldest !== void 0) {
|
|
88874
|
-
totalBytes -= Buffer.byteLength(oldest) + 1;
|
|
88875
|
-
}
|
|
88876
|
-
}
|
|
88877
|
-
const temporaryPath = `${this.#path}.tmp`;
|
|
88878
|
-
writeFileSync2(temporaryPath, lines.length === 0 ? "" : `${lines.join("\n")}
|
|
88879
|
-
`, {
|
|
88880
|
-
encoding: "utf8",
|
|
88881
|
-
mode: 384
|
|
88882
|
-
});
|
|
88883
|
-
renameSync2(temporaryPath, this.#path);
|
|
88884
|
-
};
|
|
88885
|
-
};
|
|
88886
|
-
|
|
88887
|
-
// src/engine/storage/logs/log-files.ts
|
|
88888
|
-
import { readFileSync as readFileSync10 } from "node:fs";
|
|
88889
|
-
import { join as join28 } from "node:path";
|
|
88890
|
-
var DAEMON_LOG_FILENAME = "daemon.log";
|
|
88891
|
-
var WORKER_LIFECYCLE_LOG_FILENAME = "worker-lifecycle.log";
|
|
88892
|
-
function unhandledRejectionLogFilename(role) {
|
|
88893
|
-
return `unhandled-rejections-${role}.log`;
|
|
88894
|
-
}
|
|
88895
|
-
function logDirectory(dataDirectory) {
|
|
88896
|
-
return join28(dataDirectory, "logs");
|
|
88897
|
-
}
|
|
88898
|
-
function processLogPaths(dataDirectory) {
|
|
88899
|
-
return [
|
|
88900
|
-
WORKER_LIFECYCLE_LOG_FILENAME,
|
|
88901
|
-
unhandledRejectionLogFilename("manager"),
|
|
88902
|
-
unhandledRejectionLogFilename("worker")
|
|
88903
|
-
].map((filename) => join28(logDirectory(dataDirectory), filename));
|
|
88904
|
-
}
|
|
88905
|
-
function readLogText(path7) {
|
|
88906
|
-
try {
|
|
88907
|
-
return readFileSync10(path7, "utf8");
|
|
88908
|
-
} catch {
|
|
88909
|
-
return null;
|
|
88910
|
-
}
|
|
88911
|
-
}
|
|
88912
|
-
|
|
88913
|
-
// src/engine/runtime/observability/diagnostic-log.ts
|
|
88914
|
-
var MAXIMUM_RUNTIME_LOG_BYTES = 1 * 1024 * 1024;
|
|
88915
|
-
var MAXIMUM_ENTRIES = 200;
|
|
88916
|
-
var MAXIMUM_REPORT_BYTES = 6e4;
|
|
88917
|
-
var REMOTE_DIAGNOSTIC_FIELDS = [
|
|
88918
|
-
"agentId",
|
|
88919
|
-
"operation",
|
|
88920
|
-
"runtimeId",
|
|
88921
|
-
"closeCode",
|
|
88922
|
-
"timeoutMilliseconds",
|
|
88923
|
-
"proxyRoute",
|
|
88924
|
-
"timestamp",
|
|
88925
|
-
"event",
|
|
88926
|
-
"channelId",
|
|
88927
|
-
"requestId",
|
|
88928
|
-
"commandId",
|
|
88929
|
-
"sessionId",
|
|
88930
|
-
"turnId",
|
|
88931
|
-
"connectionEpoch",
|
|
88932
|
-
"code",
|
|
88933
|
-
"source",
|
|
88934
|
-
"kind",
|
|
88935
|
-
"pid",
|
|
88936
|
-
"version",
|
|
88937
|
-
"exitCode",
|
|
88938
|
-
"signal",
|
|
88939
|
-
"failureName",
|
|
88940
|
-
"failureCode",
|
|
88941
|
-
"failureStatusCode",
|
|
88942
|
-
"cause1Name",
|
|
88943
|
-
"cause1Code",
|
|
88944
|
-
"cause2Name",
|
|
88945
|
-
"cause2Code"
|
|
88946
|
-
];
|
|
88947
|
-
var FIELD_VALUE_PATTERN = /^[a-zA-Z0-9_.: -]{1,256}$/u;
|
|
88948
|
-
var RuntimeDiagnosticLog = class {
|
|
88949
|
-
#log;
|
|
88950
|
-
#maximumBytes;
|
|
88951
|
-
#sources;
|
|
88952
|
-
constructor(stateDirectory, options = {}) {
|
|
88953
|
-
const maximumBytes = options.maximumBytes ?? MAXIMUM_RUNTIME_LOG_BYTES;
|
|
88954
|
-
const directory = logDirectory(stateDirectory);
|
|
88955
|
-
this.#log = new BoundedLineLog(directory, DAEMON_LOG_FILENAME, maximumBytes);
|
|
88956
|
-
this.#maximumBytes = maximumBytes;
|
|
88957
|
-
const processLogsDirectory = options.processLogsDirectory;
|
|
88958
|
-
this.#sources = [
|
|
88959
|
-
{ maximumBytes, path: join29(directory, DAEMON_LOG_FILENAME) },
|
|
88960
|
-
// The process logs a Runtime does not own, but must read to explain its own deaths.
|
|
88961
|
-
...processLogsDirectory === void 0 ? [] : processLogPaths(processLogsDirectory).map((path7) => ({ maximumBytes: null, path: path7 }))
|
|
88962
|
-
];
|
|
88963
|
-
}
|
|
88964
|
-
// Export only correlation and failure metadata. Local messages and paths stay local.
|
|
88965
|
-
snapshot = () => {
|
|
88966
|
-
const merged = [];
|
|
88967
|
-
let truncated = false;
|
|
88968
|
-
for (const source of this.#sources) {
|
|
88969
|
-
const collected = this.#read(source);
|
|
88970
|
-
merged.push(...collected.entries);
|
|
88971
|
-
truncated ||= collected.truncated;
|
|
88972
|
-
}
|
|
88973
|
-
merged.sort(compareTimestamp);
|
|
88974
|
-
const entries = merged.slice(-MAXIMUM_ENTRIES);
|
|
88975
|
-
truncated ||= entries.length < merged.length;
|
|
88976
|
-
while (JSON.stringify(entries).length > MAXIMUM_REPORT_BYTES && entries.length > 0) {
|
|
88977
|
-
entries.shift();
|
|
88978
|
-
truncated = true;
|
|
88979
|
-
}
|
|
88980
|
-
return { entries, truncated };
|
|
88981
|
-
};
|
|
88982
|
-
record = (diagnostic) => {
|
|
88983
|
-
this.#log.record(diagnostic);
|
|
88984
|
-
};
|
|
88985
|
-
#read = (source) => {
|
|
88986
|
-
const content = readLogText(source.path);
|
|
88987
|
-
if (content === null) {
|
|
88988
|
-
return { entries: [], truncated: false };
|
|
88989
|
-
}
|
|
88990
|
-
const lines = content.split("\n").filter((line) => line.length > 0);
|
|
88991
|
-
const entries = [];
|
|
88992
|
-
for (const line of lines.slice(-MAXIMUM_ENTRIES)) {
|
|
88993
|
-
const start = line.indexOf("{");
|
|
88994
|
-
if (start < 0) {
|
|
88995
|
-
continue;
|
|
88996
|
-
}
|
|
88997
|
-
let value;
|
|
88998
|
-
try {
|
|
88999
|
-
value = JSON.parse(line.slice(start));
|
|
89000
|
-
} catch {
|
|
89001
|
-
continue;
|
|
89002
|
-
}
|
|
89003
|
-
if (typeof value !== "object" || value === null) {
|
|
89004
|
-
continue;
|
|
89005
|
-
}
|
|
89006
|
-
entries.push(exportedFields(value));
|
|
89007
|
-
}
|
|
89008
|
-
const nearRotation = source.maximumBytes !== null && Buffer.byteLength(content) >= source.maximumBytes - 4096;
|
|
89009
|
-
return { entries, truncated: lines.length > MAXIMUM_ENTRIES || nearRotation };
|
|
89010
|
-
};
|
|
89011
|
-
};
|
|
89012
|
-
function exportedFields(value) {
|
|
89013
|
-
const entry = {};
|
|
89014
|
-
for (const field of REMOTE_DIAGNOSTIC_FIELDS) {
|
|
89015
|
-
const item = Reflect.get(value, field);
|
|
89016
|
-
if (typeof item === "string" && FIELD_VALUE_PATTERN.test(item)) {
|
|
89017
|
-
entry[field] = item;
|
|
89018
|
-
} else if (typeof item === "number" && Number.isFinite(item)) {
|
|
89019
|
-
entry[field] = String(item);
|
|
89020
|
-
}
|
|
89021
|
-
}
|
|
89022
|
-
return entry;
|
|
89023
|
-
}
|
|
89024
|
-
function compareTimestamp(left, right) {
|
|
89025
|
-
const leftAt = left["timestamp"] ?? "";
|
|
89026
|
-
const rightAt = right["timestamp"] ?? "";
|
|
89027
|
-
return leftAt < rightAt ? -1 : leftAt > rightAt ? 1 : 0;
|
|
89028
|
-
}
|
|
89029
|
-
|
|
89030
89119
|
// src/engine/runtime/relay/diagnostics.ts
|
|
89031
89120
|
var MAX_DIAGNOSTIC_TEXT_LENGTH = 256;
|
|
89032
89121
|
function sanitizeDiagnosticText(value) {
|
|
@@ -89951,7 +90040,7 @@ function createContentWriteCommands(context) {
|
|
|
89951
90040
|
import { WebSocket as WebSocket5 } from "undici";
|
|
89952
90041
|
|
|
89953
90042
|
// src/engine/session/content/session-files.ts
|
|
89954
|
-
import { basename as basename8, extname as
|
|
90043
|
+
import { basename as basename8, extname as extname3, isAbsolute as isAbsolute16, join as join30, normalize as normalize3, resolve as resolve16 } from "node:path";
|
|
89955
90044
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
89956
90045
|
function requestedPath(value) {
|
|
89957
90046
|
if (value.includes("\0")) {
|
|
@@ -90007,7 +90096,7 @@ async function streamLocalFile(command, send2, sendChunk, signal, workingDirecto
|
|
|
90007
90096
|
send2({
|
|
90008
90097
|
byteLength: before.size,
|
|
90009
90098
|
kind: FILE_BEGIN_KIND,
|
|
90010
|
-
mediaType: external?.mediaType ?? raster?.mimeType ?? (
|
|
90099
|
+
mediaType: external?.mediaType ?? raster?.mimeType ?? (extname3(target).toLowerCase() === ".svg" ? "image/svg+xml" : "application/octet-stream"),
|
|
90011
90100
|
modifiedAt: before.modifiedAt.toISOString(),
|
|
90012
90101
|
name: external?.name ?? (basename8(target) || "file"),
|
|
90013
90102
|
requestId: command.requestId,
|
|
@@ -90312,10 +90401,19 @@ var sessionCancelBeforeStartCommand = {
|
|
|
90312
90401
|
if (message.kind !== SESSION_CANCEL_BEFORE_START_KIND) {
|
|
90313
90402
|
throw new Error("Command kind mismatch");
|
|
90314
90403
|
}
|
|
90404
|
+
if (operations.hasStarted(message.commandId, message.sessionId)) {
|
|
90405
|
+
reportOperationFailure(
|
|
90406
|
+
socket,
|
|
90407
|
+
message.commandId,
|
|
90408
|
+
message.sessionId,
|
|
90409
|
+
new SessionError("turn_already_started", "The message already started and could not be withdrawn")
|
|
90410
|
+
);
|
|
90411
|
+
return;
|
|
90412
|
+
}
|
|
90315
90413
|
const turn = sessionTurns.get(message.commandId, message.sessionId);
|
|
90316
90414
|
if (turn === void 0) {
|
|
90317
90415
|
const outcome = operations.recordCancellationBeforeAdmission(message.commandId, message.sessionId);
|
|
90318
|
-
if (outcome
|
|
90416
|
+
if (outcome?.type === "lifecycle-metadata" && outcome.payload.kind === "prompt.completed" && outcome.payload.stopReason === "cancelled") {
|
|
90319
90417
|
void eventProjection.replayOutcome(message.sessionId, outcome).catch((error62) => {
|
|
90320
90418
|
reportOperationFailure(socket, message.commandId, message.sessionId, error62);
|
|
90321
90419
|
});
|
|
@@ -90787,6 +90885,7 @@ async function executePrompt({
|
|
|
90787
90885
|
);
|
|
90788
90886
|
prepared = await sessions.prepareExecutionSession(preparation);
|
|
90789
90887
|
}
|
|
90888
|
+
signal.throwIfAborted();
|
|
90790
90889
|
operations.markExecutionStarted(command.commandId);
|
|
90791
90890
|
if (availability.disposition === SessionPromptDisposition.Steer) {
|
|
90792
90891
|
if (!recordSteeringPrompt()) {
|
|
@@ -90969,7 +91068,7 @@ var sessionPromptCommand = {
|
|
|
90969
91068
|
// package.json
|
|
90970
91069
|
var package_default = {
|
|
90971
91070
|
name: "@moxt-ai/mobius",
|
|
90972
|
-
version: "0.0.
|
|
91071
|
+
version: "0.0.356",
|
|
90973
91072
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
90974
91073
|
type: "module",
|
|
90975
91074
|
bin: {
|
|
@@ -92426,13 +92525,16 @@ async function prepareProvidedRuntime({
|
|
|
92426
92525
|
const defaultWorkspace = await resolveWorkspace(connection.defaultWorkspace);
|
|
92427
92526
|
const specifications = supportedLocalAgentSpecifications();
|
|
92428
92527
|
const discoveryEnvironment = localContext.agentLaunchEnvironment;
|
|
92429
|
-
const discover = async (refreshSignal) => await
|
|
92430
|
-
|
|
92431
|
-
|
|
92432
|
-
|
|
92433
|
-
|
|
92434
|
-
|
|
92435
|
-
|
|
92528
|
+
const discover = async (refreshSignal) => await discoverRuntimeAgentInventory(
|
|
92529
|
+
{
|
|
92530
|
+
defaultWorkspace,
|
|
92531
|
+
dataDirectory: localContext.stateDirectory,
|
|
92532
|
+
environment: discoveryEnvironment,
|
|
92533
|
+
signal: refreshSignal,
|
|
92534
|
+
specifications
|
|
92535
|
+
},
|
|
92536
|
+
connection.channelId
|
|
92537
|
+
);
|
|
92436
92538
|
const inventory = await discover(signal);
|
|
92437
92539
|
const config2 = createRuntimeConfig(
|
|
92438
92540
|
{
|