@moxt-ai/mobius 0.0.26 → 0.0.28
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/acp/activity.d.ts +1 -0
- package/dist/acp/activity.d.ts.map +1 -1
- package/dist/acp/activity.js +14 -1
- package/dist/acp/activity.js.map +1 -1
- package/dist/acp/session-history.d.ts.map +1 -1
- package/dist/acp/session-history.js +10 -16
- package/dist/acp/session-history.js.map +1 -1
- package/dist/acp/session-manager.d.ts +7 -0
- package/dist/acp/session-manager.d.ts.map +1 -1
- package/dist/acp/session-manager.js +65 -11
- package/dist/acp/session-manager.js.map +1 -1
- package/dist/agent-catalog/publish-agent-catalog.js +3 -3
- package/dist/agent-catalog/publish-agent-catalog.js.map +1 -1
- package/dist/artifacts/runtime-artifact-uploader.d.ts +12 -0
- package/dist/artifacts/runtime-artifact-uploader.d.ts.map +1 -0
- package/dist/artifacts/runtime-artifact-uploader.js +157 -0
- package/dist/artifacts/runtime-artifact-uploader.js.map +1 -0
- package/dist/authorization/local-raster.d.ts +10 -0
- package/dist/authorization/local-raster.d.ts.map +1 -0
- package/dist/authorization/local-raster.js +134 -0
- package/dist/authorization/local-raster.js.map +1 -0
- package/dist/cli.js +1644 -235
- package/dist/cli.js.map +4 -4
- package/dist/index.js +1652 -251
- package/dist/index.js.map +4 -4
- package/dist/native-sessions/codex-history.d.ts.map +1 -1
- package/dist/native-sessions/codex-history.js +11 -11
- package/dist/native-sessions/codex-history.js.map +1 -1
- package/dist/native-sessions/history-images.d.ts +3 -0
- package/dist/native-sessions/history-images.d.ts.map +1 -0
- package/dist/native-sessions/history-images.js +74 -0
- package/dist/native-sessions/history-images.js.map +1 -0
- package/dist/prompt-artifact-resolver.d.ts.map +1 -1
- package/dist/prompt-artifact-resolver.js +7 -4
- package/dist/prompt-artifact-resolver.js.map +1 -1
- package/dist/relay-connection/connect.d.ts.map +1 -1
- package/dist/relay-connection/connect.js +3 -6
- package/dist/relay-connection/connect.js.map +1 -1
- package/dist/relay-connection/runtime-authentication.d.ts +3 -0
- package/dist/relay-connection/runtime-authentication.d.ts.map +1 -0
- package/dist/relay-connection/runtime-authentication.js +14 -0
- package/dist/relay-connection/runtime-authentication.js.map +1 -0
- package/dist/relay-connection/session-event-outbox.d.ts +32 -2
- package/dist/relay-connection/session-event-outbox.d.ts.map +1 -1
- package/dist/relay-connection/session-event-outbox.js +362 -11
- package/dist/relay-connection/session-event-outbox.js.map +1 -1
- package/dist/run-daemon.d.ts.map +1 -1
- package/dist/run-daemon.js +297 -24
- package/dist/run-daemon.js.map +1 -1
- package/dist/runtime.js +1654 -253
- package/dist/runtime.js.map +4 -4
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -16087,8 +16087,8 @@ function rewriteKeyNames(ctx) {
|
|
|
16087
16087
|
bySchema.set(entry.schema, entry);
|
|
16088
16088
|
}
|
|
16089
16089
|
const rewrites = /* @__PURE__ */ new Map();
|
|
16090
|
-
for (const
|
|
16091
|
-
const seen = ctx.seen.get(
|
|
16090
|
+
for (const record3 of pendingRecords.get(ctx) ?? []) {
|
|
16091
|
+
const seen = ctx.seen.get(record3);
|
|
16092
16092
|
const names = (seen?.def ?? seen?.schema)?.propertyNames;
|
|
16093
16093
|
if (!names || names === true || rewrites.has(names))
|
|
16094
16094
|
continue;
|
|
@@ -19045,6 +19045,7 @@ var elicitationFieldSchema = external_exports.strictObject({
|
|
|
19045
19045
|
type: external_exports.enum(["boolean", "integer", "multiselect", "number", "select", "string"])
|
|
19046
19046
|
}).readonly();
|
|
19047
19047
|
var displayContentSchema = external_exports.strictObject({
|
|
19048
|
+
artifactId: external_exports.string().max(128).default(""),
|
|
19048
19049
|
data: external_exports.string().max(4e6),
|
|
19049
19050
|
mimeType: external_exports.string().max(255),
|
|
19050
19051
|
name: external_exports.string().max(500),
|
|
@@ -19057,6 +19058,7 @@ var displayContentSchema = external_exports.strictObject({
|
|
|
19057
19058
|
uri: external_exports.string().max(4096)
|
|
19058
19059
|
}).readonly();
|
|
19059
19060
|
var recordedDisplayContentSchema = external_exports.strictObject({
|
|
19061
|
+
artifactId: external_exports.string().max(128).default(""),
|
|
19060
19062
|
data: external_exports.string().max(4e6),
|
|
19061
19063
|
mimeType: external_exports.string().max(255),
|
|
19062
19064
|
name: external_exports.string().max(500),
|
|
@@ -19340,6 +19342,9 @@ var SESSION_CANCEL_KIND = "session.cancel";
|
|
|
19340
19342
|
var RUNTIME_LIVENESS_READY_KIND = "runtime.liveness.ready";
|
|
19341
19343
|
var RUNTIME_HEARTBEAT_KIND = "runtime.heartbeat";
|
|
19342
19344
|
var RUNTIME_HEARTBEAT_ACK_KIND = "runtime.heartbeat.ack";
|
|
19345
|
+
var RUNTIME_DELIVERY_KIND = "runtime.delivery";
|
|
19346
|
+
var RUNTIME_DELIVERY_RECEIVED_KIND = "runtime.delivery.received";
|
|
19347
|
+
var RUNTIME_DELIVERY_COMMITTED_KIND = "runtime.delivery.committed";
|
|
19343
19348
|
var SESSION_STARTED_KIND = "session.started";
|
|
19344
19349
|
var AGENT_MESSAGE_DELTA_KIND = "agent.message.delta";
|
|
19345
19350
|
var AGENT_ACTIVITY_KIND = "agent.activity";
|
|
@@ -19362,6 +19367,7 @@ var DIRECTORY_IDENTIFIER_PATTERN2 = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,2047}$/;
|
|
|
19362
19367
|
var MAX_PROMPT_LENGTH = 1e4;
|
|
19363
19368
|
var MAX_PROMPT_ATTACHMENT_LENGTH = 6e6;
|
|
19364
19369
|
var MAX_EVENT_TEXT_LENGTH = 1e5;
|
|
19370
|
+
var MAX_RUNTIME_DELIVERY_PAYLOAD_LENGTH = 8 * 1024 * 1024;
|
|
19365
19371
|
var ACTIVITY_TYPES = /* @__PURE__ */ new Set(["plan", "progress", "reasoning", "tool"]);
|
|
19366
19372
|
var ACTIVITY_STATUSES = /* @__PURE__ */ new Set(["pending", "running", "completed", "failed"]);
|
|
19367
19373
|
var TOOL_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -19640,6 +19646,37 @@ function decodeRuntimeHeartbeatAckEvent(encoded) {
|
|
|
19640
19646
|
kind: RUNTIME_HEARTBEAT_ACK_KIND
|
|
19641
19647
|
};
|
|
19642
19648
|
}
|
|
19649
|
+
function decodeRuntimeDelivery(encoded) {
|
|
19650
|
+
const value = parseJson2(encoded);
|
|
19651
|
+
assertExactKeys(value, ["deliveryId", "kind", "payload", "sessionId"]);
|
|
19652
|
+
assertKind(value, RUNTIME_DELIVERY_KIND);
|
|
19653
|
+
return {
|
|
19654
|
+
deliveryId: readIdentifier(value, "deliveryId"),
|
|
19655
|
+
kind: RUNTIME_DELIVERY_KIND,
|
|
19656
|
+
payload: readString(value, "payload", MAX_RUNTIME_DELIVERY_PAYLOAD_LENGTH),
|
|
19657
|
+
sessionId: readIdentifier(value, "sessionId")
|
|
19658
|
+
};
|
|
19659
|
+
}
|
|
19660
|
+
function decodeRuntimeDeliveryReceived(encoded) {
|
|
19661
|
+
const value = parseJson2(encoded);
|
|
19662
|
+
assertExactKeys(value, ["deliveryId", "kind", "sessionId"]);
|
|
19663
|
+
assertKind(value, RUNTIME_DELIVERY_RECEIVED_KIND);
|
|
19664
|
+
return {
|
|
19665
|
+
deliveryId: readIdentifier(value, "deliveryId"),
|
|
19666
|
+
kind: RUNTIME_DELIVERY_RECEIVED_KIND,
|
|
19667
|
+
sessionId: readIdentifier(value, "sessionId")
|
|
19668
|
+
};
|
|
19669
|
+
}
|
|
19670
|
+
function decodeRuntimeDeliveryCommitted(encoded) {
|
|
19671
|
+
const value = parseJson2(encoded);
|
|
19672
|
+
assertExactKeys(value, ["deliveryId", "kind", "sessionId"]);
|
|
19673
|
+
assertKind(value, RUNTIME_DELIVERY_COMMITTED_KIND);
|
|
19674
|
+
return {
|
|
19675
|
+
deliveryId: readIdentifier(value, "deliveryId"),
|
|
19676
|
+
kind: RUNTIME_DELIVERY_COMMITTED_KIND,
|
|
19677
|
+
sessionId: readIdentifier(value, "sessionId")
|
|
19678
|
+
};
|
|
19679
|
+
}
|
|
19643
19680
|
function decodeSessionStartedEvent(encoded) {
|
|
19644
19681
|
const value = parseJson2(encoded);
|
|
19645
19682
|
assertExactKeys(value, ["commandId", "kind", "attemptId", "sessionId"]);
|
|
@@ -19727,6 +19764,9 @@ function decodeSessionFailedEvent(encoded) {
|
|
|
19727
19764
|
function encodeRuntimeHeartbeatEvent(message) {
|
|
19728
19765
|
return JSON.stringify(decodeRuntimeHeartbeatEvent(JSON.stringify(message)));
|
|
19729
19766
|
}
|
|
19767
|
+
function encodeRuntimeDeliveryReceived(message) {
|
|
19768
|
+
return JSON.stringify(decodeRuntimeDeliveryReceived(JSON.stringify(message)));
|
|
19769
|
+
}
|
|
19730
19770
|
function encodeSessionStartedEvent(message) {
|
|
19731
19771
|
return JSON.stringify(decodeSessionStartedEvent(JSON.stringify(message)));
|
|
19732
19772
|
}
|
|
@@ -20425,7 +20465,8 @@ var SESSION_EVENT_COMMITTED_KIND = "session.event.committed";
|
|
|
20425
20465
|
var SESSION_EVENT_REJECTED_KIND = "session.event.rejected";
|
|
20426
20466
|
var SessionEventRejectionCode = {
|
|
20427
20467
|
SessionDeleted: "session_deleted",
|
|
20428
|
-
SessionNotFound: "session_not_found"
|
|
20468
|
+
SessionNotFound: "session_not_found",
|
|
20469
|
+
SessionRejected: "session_rejected"
|
|
20429
20470
|
};
|
|
20430
20471
|
var IDENTIFIER_PATTERN4 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
20431
20472
|
var CURSOR_PATTERN = /^[A-Za-z0-9_-]{1,512}$/;
|
|
@@ -21162,6 +21203,212 @@ import {
|
|
|
21162
21203
|
RequestError
|
|
21163
21204
|
} from "@agentclientprotocol/sdk";
|
|
21164
21205
|
|
|
21206
|
+
// src/authorization/local-raster.ts
|
|
21207
|
+
import { readFile, realpath as realpath2, stat as stat2 } from "node:fs/promises";
|
|
21208
|
+
import { basename, isAbsolute, normalize, relative, sep } from "node:path";
|
|
21209
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
21210
|
+
var MAX_LOCAL_RASTER_BYTES = 3e6;
|
|
21211
|
+
var PNG_SIGNATURE = Uint8Array.of(137, 80, 78, 71);
|
|
21212
|
+
var JPEG_SIGNATURE = Uint8Array.of(255, 216, 255);
|
|
21213
|
+
var GIF87_SIGNATURE = new TextEncoder().encode("GIF87a");
|
|
21214
|
+
var GIF89_SIGNATURE = new TextEncoder().encode("GIF89a");
|
|
21215
|
+
var RIFF_SIGNATURE = new TextEncoder().encode("RIFF");
|
|
21216
|
+
var WEBP_SIGNATURE = new TextEncoder().encode("WEBP");
|
|
21217
|
+
var LocalRasterImage = class {
|
|
21218
|
+
bytes;
|
|
21219
|
+
mimeType;
|
|
21220
|
+
name;
|
|
21221
|
+
constructor(name, mimeType, bytes) {
|
|
21222
|
+
this.bytes = bytes;
|
|
21223
|
+
this.mimeType = mimeType;
|
|
21224
|
+
this.name = name;
|
|
21225
|
+
}
|
|
21226
|
+
base64 = () => Buffer.from(this.bytes).toString("base64");
|
|
21227
|
+
};
|
|
21228
|
+
function startsWith(bytes, signature, offset = 0) {
|
|
21229
|
+
if (bytes.byteLength < offset + signature.byteLength) {
|
|
21230
|
+
return false;
|
|
21231
|
+
}
|
|
21232
|
+
return signature.every((value, index) => bytes[offset + index] === value);
|
|
21233
|
+
}
|
|
21234
|
+
function sniffRasterMime(bytes) {
|
|
21235
|
+
if (startsWith(bytes, PNG_SIGNATURE)) {
|
|
21236
|
+
return "image/png";
|
|
21237
|
+
}
|
|
21238
|
+
if (startsWith(bytes, JPEG_SIGNATURE)) {
|
|
21239
|
+
return "image/jpeg";
|
|
21240
|
+
}
|
|
21241
|
+
if (startsWith(bytes, GIF87_SIGNATURE) || startsWith(bytes, GIF89_SIGNATURE)) {
|
|
21242
|
+
return "image/gif";
|
|
21243
|
+
}
|
|
21244
|
+
if (startsWith(bytes, RIFF_SIGNATURE) && startsWith(bytes, WEBP_SIGNATURE, 8)) {
|
|
21245
|
+
return "image/webp";
|
|
21246
|
+
}
|
|
21247
|
+
return null;
|
|
21248
|
+
}
|
|
21249
|
+
function isInsideRoot(root, target) {
|
|
21250
|
+
const relation = relative(root, target);
|
|
21251
|
+
return relation !== ".." && !relation.startsWith(`..${sep}`) && !isAbsolute(relation);
|
|
21252
|
+
}
|
|
21253
|
+
async function resolveCanonicalPath(requested, signal) {
|
|
21254
|
+
signal.throwIfAborted();
|
|
21255
|
+
if (!isAbsolute(requested) || requested.includes("\0") || normalize(requested) !== requested) {
|
|
21256
|
+
return null;
|
|
21257
|
+
}
|
|
21258
|
+
try {
|
|
21259
|
+
const target = await realpath2(requested);
|
|
21260
|
+
signal.throwIfAborted();
|
|
21261
|
+
if (!isAbsolute(target) || normalize(target) !== target) {
|
|
21262
|
+
return null;
|
|
21263
|
+
}
|
|
21264
|
+
return target;
|
|
21265
|
+
} catch (cause) {
|
|
21266
|
+
signal.throwIfAborted();
|
|
21267
|
+
if (cause instanceof Error && cause.name === "AbortError") {
|
|
21268
|
+
throw cause;
|
|
21269
|
+
}
|
|
21270
|
+
return null;
|
|
21271
|
+
}
|
|
21272
|
+
}
|
|
21273
|
+
function parseLocalImageUri(uri) {
|
|
21274
|
+
const trimmed = uri.trim();
|
|
21275
|
+
if (trimmed.length === 0 || trimmed.length > 2048 || trimmed.includes("\0")) {
|
|
21276
|
+
return null;
|
|
21277
|
+
}
|
|
21278
|
+
if (trimmed.startsWith("data:")) {
|
|
21279
|
+
return null;
|
|
21280
|
+
}
|
|
21281
|
+
if (trimmed.startsWith("file:")) {
|
|
21282
|
+
try {
|
|
21283
|
+
const url2 = new URL(trimmed);
|
|
21284
|
+
if (url2.protocol !== "file:" || url2.host.length > 0) {
|
|
21285
|
+
return null;
|
|
21286
|
+
}
|
|
21287
|
+
return fileURLToPath2(url2);
|
|
21288
|
+
} catch {
|
|
21289
|
+
return null;
|
|
21290
|
+
}
|
|
21291
|
+
}
|
|
21292
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
|
|
21293
|
+
return null;
|
|
21294
|
+
}
|
|
21295
|
+
return trimmed;
|
|
21296
|
+
}
|
|
21297
|
+
async function readAuthorizedRaster(uri, roots, signal) {
|
|
21298
|
+
signal.throwIfAborted();
|
|
21299
|
+
const requested = parseLocalImageUri(uri);
|
|
21300
|
+
if (requested === null) {
|
|
21301
|
+
return null;
|
|
21302
|
+
}
|
|
21303
|
+
const target = await resolveCanonicalPath(requested, signal);
|
|
21304
|
+
if (target === null) {
|
|
21305
|
+
return null;
|
|
21306
|
+
}
|
|
21307
|
+
const targetMetadata = await stat2(target);
|
|
21308
|
+
signal.throwIfAborted();
|
|
21309
|
+
if (!targetMetadata.isFile() || targetMetadata.size < 1 || targetMetadata.size > MAX_LOCAL_RASTER_BYTES) {
|
|
21310
|
+
return null;
|
|
21311
|
+
}
|
|
21312
|
+
const authorizedRoots = [];
|
|
21313
|
+
for (const root of roots) {
|
|
21314
|
+
const directory = await resolveCanonicalPath(root, signal);
|
|
21315
|
+
if (directory === null) {
|
|
21316
|
+
continue;
|
|
21317
|
+
}
|
|
21318
|
+
const metadata = await stat2(directory);
|
|
21319
|
+
signal.throwIfAborted();
|
|
21320
|
+
if (metadata.isDirectory()) {
|
|
21321
|
+
authorizedRoots.push(directory);
|
|
21322
|
+
}
|
|
21323
|
+
}
|
|
21324
|
+
if (!authorizedRoots.some((root) => isInsideRoot(root, target))) {
|
|
21325
|
+
return null;
|
|
21326
|
+
}
|
|
21327
|
+
const bytes = new Uint8Array(await readFile(target));
|
|
21328
|
+
signal.throwIfAborted();
|
|
21329
|
+
if (bytes.byteLength < 1 || bytes.byteLength > MAX_LOCAL_RASTER_BYTES) {
|
|
21330
|
+
return null;
|
|
21331
|
+
}
|
|
21332
|
+
const mimeType = sniffRasterMime(bytes);
|
|
21333
|
+
if (mimeType === null) {
|
|
21334
|
+
return null;
|
|
21335
|
+
}
|
|
21336
|
+
return new LocalRasterImage(basename(target) || "Image", mimeType, bytes);
|
|
21337
|
+
}
|
|
21338
|
+
|
|
21339
|
+
// src/native-sessions/history-images.ts
|
|
21340
|
+
var IMAGE_MARKER = /\[@image\]\(([^)\r\n]*)(?:\)|$)/g;
|
|
21341
|
+
async function embedLocalHistoryImages(history, roots, signal) {
|
|
21342
|
+
if (history.status !== "available") {
|
|
21343
|
+
return history;
|
|
21344
|
+
}
|
|
21345
|
+
const messages = [];
|
|
21346
|
+
let imageCharacters = 0;
|
|
21347
|
+
for (const message of history.messages) {
|
|
21348
|
+
signal.throwIfAborted();
|
|
21349
|
+
const resolved = await resolveMessageImages(message, roots, imageCharacters, signal);
|
|
21350
|
+
imageCharacters += (resolved.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
21351
|
+
messages.push(resolved);
|
|
21352
|
+
}
|
|
21353
|
+
return {
|
|
21354
|
+
...history,
|
|
21355
|
+
messages
|
|
21356
|
+
};
|
|
21357
|
+
}
|
|
21358
|
+
async function resolveMessageImages(message, roots, usedCharacters, signal) {
|
|
21359
|
+
const images = [...message.images ?? []];
|
|
21360
|
+
let imageCharacters = images.reduce((size, image) => size + image.data.length, 0);
|
|
21361
|
+
const text = await replaceImageMarkers(message.text, async (uri) => {
|
|
21362
|
+
if (images.length >= 8 || usedCharacters + imageCharacters >= SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
21363
|
+
return "[Image unavailable]";
|
|
21364
|
+
}
|
|
21365
|
+
const embedded = parseNativeHistoryText(`[@image](${uri})`).images[0];
|
|
21366
|
+
if (embedded !== void 0) {
|
|
21367
|
+
if (usedCharacters + imageCharacters + embedded.data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
21368
|
+
return "[Image unavailable]";
|
|
21369
|
+
}
|
|
21370
|
+
images.push(embedded);
|
|
21371
|
+
imageCharacters += embedded.data.length;
|
|
21372
|
+
return "";
|
|
21373
|
+
}
|
|
21374
|
+
const local = await readAuthorizedRaster(uri, roots, signal);
|
|
21375
|
+
if (local === null) {
|
|
21376
|
+
return "[Image unavailable]";
|
|
21377
|
+
}
|
|
21378
|
+
const data = local.base64();
|
|
21379
|
+
if (usedCharacters + imageCharacters + data.length > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
21380
|
+
return "[Image unavailable]";
|
|
21381
|
+
}
|
|
21382
|
+
images.push({
|
|
21383
|
+
data,
|
|
21384
|
+
mimeType: local.mimeType,
|
|
21385
|
+
name: local.name
|
|
21386
|
+
});
|
|
21387
|
+
imageCharacters += data.length;
|
|
21388
|
+
return "";
|
|
21389
|
+
});
|
|
21390
|
+
return {
|
|
21391
|
+
...message,
|
|
21392
|
+
text,
|
|
21393
|
+
...images.length > 0 ? { images } : {}
|
|
21394
|
+
};
|
|
21395
|
+
}
|
|
21396
|
+
async function replaceImageMarkers(text, replace) {
|
|
21397
|
+
const matches = [...text.matchAll(IMAGE_MARKER)];
|
|
21398
|
+
if (matches.length === 0) {
|
|
21399
|
+
return text;
|
|
21400
|
+
}
|
|
21401
|
+
let cursor = 0;
|
|
21402
|
+
let rewritten = "";
|
|
21403
|
+
for (const match of matches) {
|
|
21404
|
+
const index = match.index ?? 0;
|
|
21405
|
+
rewritten += text.slice(cursor, index);
|
|
21406
|
+
rewritten += await replace(match[1] ?? "");
|
|
21407
|
+
cursor = index + match[0].length;
|
|
21408
|
+
}
|
|
21409
|
+
return `${rewritten}${text.slice(cursor)}`;
|
|
21410
|
+
}
|
|
21411
|
+
|
|
21165
21412
|
// src/acp/activity.ts
|
|
21166
21413
|
var TRUNCATION_MARKER = "\n\u2026 output truncated by Mobius";
|
|
21167
21414
|
function isRecord4(value) {
|
|
@@ -21259,6 +21506,7 @@ function readContentOutputDetail(content) {
|
|
|
21259
21506
|
function summarizeDisplayContent(content) {
|
|
21260
21507
|
return {
|
|
21261
21508
|
...content,
|
|
21509
|
+
artifactId: truncate(content.artifactId, 128),
|
|
21262
21510
|
data: truncate(content.data, AGENT_ACTIVITY_DETAIL_LIMIT),
|
|
21263
21511
|
mimeType: truncate(content.mimeType, 255),
|
|
21264
21512
|
name: truncate(content.name, 500),
|
|
@@ -21271,7 +21519,7 @@ function summarizeDisplayContent(content) {
|
|
|
21271
21519
|
};
|
|
21272
21520
|
}
|
|
21273
21521
|
function contentFitsRecordingEnvelope(content) {
|
|
21274
|
-
return content.data.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.mimeType.length <= 255 && content.name.length <= 500 && content.newText.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.oldText.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.path.length <= 2048 && content.terminalId.length <= 255 && content.text.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.uri.length <= 4096;
|
|
21522
|
+
return content.artifactId.length <= 128 && content.data.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.mimeType.length <= 255 && content.name.length <= 500 && content.newText.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.oldText.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.path.length <= 2048 && content.terminalId.length <= 255 && content.text.length <= AGENT_ACTIVITY_RECORDED_FIELD_LIMIT && content.uri.length <= 4096;
|
|
21275
21523
|
}
|
|
21276
21524
|
function encodedByteLength(value) {
|
|
21277
21525
|
return new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
@@ -21297,6 +21545,7 @@ function recordedDetail(activity) {
|
|
|
21297
21545
|
}
|
|
21298
21546
|
function emptyDisplayContent(type) {
|
|
21299
21547
|
return {
|
|
21548
|
+
artifactId: "",
|
|
21300
21549
|
data: "",
|
|
21301
21550
|
mimeType: "",
|
|
21302
21551
|
name: "",
|
|
@@ -21309,6 +21558,16 @@ function emptyDisplayContent(type) {
|
|
|
21309
21558
|
uri: ""
|
|
21310
21559
|
};
|
|
21311
21560
|
}
|
|
21561
|
+
function imageDisplayContent(mimeType, name, data, artifactId = "", uri = "") {
|
|
21562
|
+
return {
|
|
21563
|
+
...emptyDisplayContent("image"),
|
|
21564
|
+
artifactId,
|
|
21565
|
+
data,
|
|
21566
|
+
mimeType,
|
|
21567
|
+
name,
|
|
21568
|
+
uri
|
|
21569
|
+
};
|
|
21570
|
+
}
|
|
21312
21571
|
function normalizeContentBlock(content) {
|
|
21313
21572
|
if (content.type === "text") {
|
|
21314
21573
|
return { ...emptyDisplayContent("text"), text: content.text };
|
|
@@ -22100,7 +22359,6 @@ var AcpHistoryReplay = class {
|
|
|
22100
22359
|
#messages = [];
|
|
22101
22360
|
#lastMessageId = null;
|
|
22102
22361
|
#characters = 0;
|
|
22103
|
-
#imageCharacters = 0;
|
|
22104
22362
|
#truncated = false;
|
|
22105
22363
|
record = (update) => {
|
|
22106
22364
|
if (update.sessionUpdate !== "user_message_chunk" && update.sessionUpdate !== "agent_message_chunk") {
|
|
@@ -22111,40 +22369,30 @@ var AcpHistoryReplay = class {
|
|
|
22111
22369
|
}
|
|
22112
22370
|
const role = update.sessionUpdate === "user_message_chunk" ? "user" : "assistant";
|
|
22113
22371
|
const content = update.content;
|
|
22114
|
-
const
|
|
22115
|
-
|
|
22116
|
-
);
|
|
22117
|
-
const text = parsed.text;
|
|
22118
|
-
if (text.length === 0 && parsed.images.length === 0) {
|
|
22372
|
+
const text = content.type === "text" ? content.text : content.type === "image" ? content.data.length > 0 ? `[@image](data:${content.mimeType};base64,${content.data})` : content.uri != null && content.uri.length > 0 ? `[@image](${content.uri})` : "[image attachment]" : `[${content.type} attachment]`;
|
|
22373
|
+
if (text.length === 0) {
|
|
22119
22374
|
return;
|
|
22120
22375
|
}
|
|
22121
22376
|
const previous = this.#messages.at(-1);
|
|
22122
22377
|
const id = update.messageId ?? null;
|
|
22123
22378
|
const continuation = previous?.role === role && id === this.#lastMessageId;
|
|
22124
22379
|
const combined = continuation ? `${previous.text}${text}` : text;
|
|
22125
|
-
const allImages = continuation ? [...previous.images ?? [], ...parsed.images] : parsed.images;
|
|
22126
|
-
const images = allImages.slice(0, 8);
|
|
22127
|
-
this.#truncated ||= images.length < allImages.length;
|
|
22128
22380
|
if (continuation) {
|
|
22129
22381
|
this.#messages.pop();
|
|
22130
22382
|
this.#characters -= previous.text.length;
|
|
22131
|
-
this.#imageCharacters -= (previous.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
22132
22383
|
}
|
|
22133
22384
|
const bounded = combined.slice(-SESSION_HISTORY_CHARACTER_LIMIT);
|
|
22134
22385
|
this.#truncated ||= bounded.length < combined.length;
|
|
22135
22386
|
this.#messages.push({
|
|
22136
22387
|
role,
|
|
22137
|
-
text: bounded
|
|
22138
|
-
...images.length > 0 ? { images } : {}
|
|
22388
|
+
text: bounded
|
|
22139
22389
|
});
|
|
22140
22390
|
this.#characters += bounded.length;
|
|
22141
|
-
this.#imageCharacters += images.reduce((size, image) => size + image.data.length, 0);
|
|
22142
22391
|
this.#lastMessageId = id;
|
|
22143
|
-
while (this.#messages.length > SESSION_HISTORY_PREVIEW_MESSAGE_LIMIT || this.#characters > SESSION_HISTORY_CHARACTER_LIMIT
|
|
22392
|
+
while (this.#messages.length > SESSION_HISTORY_PREVIEW_MESSAGE_LIMIT || this.#characters > SESSION_HISTORY_CHARACTER_LIMIT) {
|
|
22144
22393
|
const removed = this.#messages.shift();
|
|
22145
22394
|
if (removed !== void 0) {
|
|
22146
22395
|
this.#characters -= removed.text.length;
|
|
22147
|
-
this.#imageCharacters -= (removed.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
22148
22396
|
}
|
|
22149
22397
|
this.#truncated = true;
|
|
22150
22398
|
}
|
|
@@ -22367,6 +22615,10 @@ var MAX_PRE_SESSION_UPDATES = 100;
|
|
|
22367
22615
|
var MAX_PRE_SESSION_UPDATE_BYTES = 1024 * 1024;
|
|
22368
22616
|
var SESSION_CONTROL_COMMAND_ID = "session-control";
|
|
22369
22617
|
var NullAcpSessionObserver = class {
|
|
22618
|
+
importLocalImage = (_sessionId, _image, signal) => {
|
|
22619
|
+
signal.throwIfAborted();
|
|
22620
|
+
return Promise.resolve("");
|
|
22621
|
+
};
|
|
22370
22622
|
onCommands = () => Promise.resolve();
|
|
22371
22623
|
onConfig = () => Promise.resolve();
|
|
22372
22624
|
onContent = () => Promise.resolve();
|
|
@@ -22989,11 +23241,75 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
22989
23241
|
);
|
|
22990
23242
|
await this.#updateTail;
|
|
22991
23243
|
signal.throwIfAborted();
|
|
22992
|
-
return
|
|
23244
|
+
return await embedLocalHistoryImages(
|
|
23245
|
+
history.snapshot(),
|
|
23246
|
+
[this.#cwd, ...this.#additionalDirectories],
|
|
23247
|
+
signal
|
|
23248
|
+
);
|
|
22993
23249
|
} finally {
|
|
22994
23250
|
this.#replay = { kind: "idle" };
|
|
22995
23251
|
}
|
|
22996
23252
|
};
|
|
23253
|
+
imageRoots = () => [this.#cwd, ...this.#additionalDirectories];
|
|
23254
|
+
emitAgentText = async (text, messageId) => {
|
|
23255
|
+
const signal = AbortSignal.timeout(2e4);
|
|
23256
|
+
const parts = text.split(/(\[@image\]\([^)\r\n]*(?:\)|$))/);
|
|
23257
|
+
let leftover = "";
|
|
23258
|
+
for (const part of parts) {
|
|
23259
|
+
const marker = /^\[@image\]\(([^)\r\n]*)(?:\)|$)/.exec(part);
|
|
23260
|
+
if (marker === null) {
|
|
23261
|
+
leftover += part;
|
|
23262
|
+
continue;
|
|
23263
|
+
}
|
|
23264
|
+
if (leftover.length > 0) {
|
|
23265
|
+
await this.#turn.onText(leftover, messageId);
|
|
23266
|
+
leftover = "";
|
|
23267
|
+
}
|
|
23268
|
+
const raster = await readAuthorizedRaster(marker[1] ?? "", this.imageRoots(), signal);
|
|
23269
|
+
if (raster === null) {
|
|
23270
|
+
leftover += "[Image unavailable]";
|
|
23271
|
+
continue;
|
|
23272
|
+
}
|
|
23273
|
+
await this.emitRaster(raster, messageId, signal);
|
|
23274
|
+
}
|
|
23275
|
+
if (leftover.length > 0) {
|
|
23276
|
+
await this.#turn.onText(leftover, messageId);
|
|
23277
|
+
}
|
|
23278
|
+
};
|
|
23279
|
+
emitAgentContent = async (content, messageId) => {
|
|
23280
|
+
if (content.type === "image" && content.data.length === 0 && content.uri.length > 0) {
|
|
23281
|
+
const signal = AbortSignal.timeout(2e4);
|
|
23282
|
+
const raster = await readAuthorizedRaster(content.uri, this.imageRoots(), signal);
|
|
23283
|
+
if (raster !== null) {
|
|
23284
|
+
await this.emitRaster(raster, messageId, signal);
|
|
23285
|
+
return;
|
|
23286
|
+
}
|
|
23287
|
+
}
|
|
23288
|
+
await this.#getObserver().onContent({
|
|
23289
|
+
commandId: this.#turn.commandId,
|
|
23290
|
+
content,
|
|
23291
|
+
contentId: `content-${crypto.randomUUID()}`,
|
|
23292
|
+
kind: AGENT_CONTENT_KIND,
|
|
23293
|
+
messageId,
|
|
23294
|
+
sessionId: this.#mobiusSessionId
|
|
23295
|
+
});
|
|
23296
|
+
};
|
|
23297
|
+
emitRaster = async (raster, messageId, signal) => {
|
|
23298
|
+
const artifactId = await this.#getObserver().importLocalImage(this.#mobiusSessionId, raster, signal);
|
|
23299
|
+
await this.#getObserver().onContent({
|
|
23300
|
+
commandId: this.#turn.commandId,
|
|
23301
|
+
content: imageDisplayContent(
|
|
23302
|
+
raster.mimeType,
|
|
23303
|
+
raster.name,
|
|
23304
|
+
artifactId.length > 0 ? "" : raster.base64(),
|
|
23305
|
+
artifactId
|
|
23306
|
+
),
|
|
23307
|
+
contentId: `content-${crypto.randomUUID()}`,
|
|
23308
|
+
kind: AGENT_CONTENT_KIND,
|
|
23309
|
+
messageId,
|
|
23310
|
+
sessionId: this.#mobiusSessionId
|
|
23311
|
+
});
|
|
23312
|
+
};
|
|
22997
23313
|
async #initializeAgent(signal) {
|
|
22998
23314
|
const initialized = await this.race(
|
|
22999
23315
|
this.#connection.agent.request(
|
|
@@ -23696,18 +24012,14 @@ var AcpProcessSession = class _AcpProcessSession {
|
|
|
23696
24012
|
);
|
|
23697
24013
|
} else {
|
|
23698
24014
|
await this.#turn.activities.finishNarrative();
|
|
23699
|
-
await this
|
|
24015
|
+
await this.emitAgentText(update.content.text, truncate3(update.messageId ?? "", 255));
|
|
23700
24016
|
}
|
|
23701
24017
|
} else {
|
|
23702
24018
|
await this.#turn.activities.finishNarrative();
|
|
23703
|
-
await this
|
|
23704
|
-
|
|
23705
|
-
|
|
23706
|
-
|
|
23707
|
-
kind: AGENT_CONTENT_KIND,
|
|
23708
|
-
messageId: truncate3(update.messageId ?? "", 255),
|
|
23709
|
-
sessionId: this.#mobiusSessionId
|
|
23710
|
-
});
|
|
24019
|
+
await this.emitAgentContent(
|
|
24020
|
+
normalizeContentBlock(update.content),
|
|
24021
|
+
truncate3(update.messageId ?? "", 255)
|
|
24022
|
+
);
|
|
23711
24023
|
}
|
|
23712
24024
|
return;
|
|
23713
24025
|
}
|
|
@@ -24573,7 +24885,7 @@ var AuditStore = class {
|
|
|
24573
24885
|
this.database.exec("ALTER TABLE audit_events ADD COLUMN details_json TEXT NOT NULL DEFAULT '{}'");
|
|
24574
24886
|
}
|
|
24575
24887
|
}
|
|
24576
|
-
record(
|
|
24888
|
+
record(record3) {
|
|
24577
24889
|
this.database.prepare(
|
|
24578
24890
|
`
|
|
24579
24891
|
INSERT INTO audit_events (
|
|
@@ -24586,10 +24898,10 @@ var AuditStore = class {
|
|
|
24586
24898
|
`
|
|
24587
24899
|
).run(
|
|
24588
24900
|
(/* @__PURE__ */ new Date()).toISOString(),
|
|
24589
|
-
|
|
24590
|
-
|
|
24591
|
-
|
|
24592
|
-
JSON.stringify(
|
|
24901
|
+
record3.event,
|
|
24902
|
+
record3.commandId,
|
|
24903
|
+
record3.sessionId,
|
|
24904
|
+
JSON.stringify(record3.details ?? {})
|
|
24593
24905
|
);
|
|
24594
24906
|
}
|
|
24595
24907
|
close() {
|
|
@@ -24611,7 +24923,7 @@ import { randomBytes } from "node:crypto";
|
|
|
24611
24923
|
|
|
24612
24924
|
// src/bots/local-bot-grant-store.ts
|
|
24613
24925
|
import { createHash, randomUUID } from "node:crypto";
|
|
24614
|
-
import { stat as
|
|
24926
|
+
import { stat as stat3 } from "node:fs/promises";
|
|
24615
24927
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
24616
24928
|
var LOCAL_BOT_GRANT_LIFETIME_MILLISECONDS = 90 * 24 * 60 * 60 * 1e3;
|
|
24617
24929
|
var LocalBotAuthorizationError = class extends Error {
|
|
@@ -24669,7 +24981,7 @@ function agentDigest(agent) {
|
|
|
24669
24981
|
);
|
|
24670
24982
|
}
|
|
24671
24983
|
async function workspaceDigest(path2) {
|
|
24672
|
-
const metadata = await
|
|
24984
|
+
const metadata = await stat3(path2);
|
|
24673
24985
|
if (!metadata.isDirectory()) {
|
|
24674
24986
|
throw new LocalBotAuthorizationError("binding_incompatible", "The Bot workspace is not a directory");
|
|
24675
24987
|
}
|
|
@@ -25207,7 +25519,7 @@ async function executeBotMessageCommand(arguments_, environment, signal) {
|
|
|
25207
25519
|
// src/bots/bot-outbound-ipc.ts
|
|
25208
25520
|
import { chmod, mkdir, unlink } from "node:fs/promises";
|
|
25209
25521
|
import { createServer } from "node:net";
|
|
25210
|
-
import { dirname as dirname3, isAbsolute } from "node:path";
|
|
25522
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2 } from "node:path";
|
|
25211
25523
|
import { fetch } from "undici";
|
|
25212
25524
|
var BOT_IPC_REQUEST_LIMIT = 32 * 1024;
|
|
25213
25525
|
var BOT_IPC_TIMEOUT_MILLISECONDS2 = 2e4;
|
|
@@ -25305,7 +25617,7 @@ var BotOutboundIpcServer = class {
|
|
|
25305
25617
|
#usesFilesystemSocket;
|
|
25306
25618
|
constructor(socketPath, relayUrl, registry2) {
|
|
25307
25619
|
const usesFilesystemSocket = !socketPath.startsWith(WINDOWS_NAMED_PIPE_PREFIX);
|
|
25308
|
-
if (usesFilesystemSocket && !
|
|
25620
|
+
if (usesFilesystemSocket && !isAbsolute2(socketPath)) {
|
|
25309
25621
|
throw new Error("The Bot IPC path must be absolute");
|
|
25310
25622
|
}
|
|
25311
25623
|
this.#registry = registry2;
|
|
@@ -25445,9 +25757,9 @@ var BotOutboundIpcServer = class {
|
|
|
25445
25757
|
|
|
25446
25758
|
// src/pairing/pair-local-machine.ts
|
|
25447
25759
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
25448
|
-
import { mkdir as mkdir4, open as open4, realpath as
|
|
25760
|
+
import { mkdir as mkdir4, open as open4, realpath as realpath7, rename as rename3, stat as stat7, writeFile as writeFile2 } from "node:fs/promises";
|
|
25449
25761
|
import { hostname as hostname3 } from "node:os";
|
|
25450
|
-
import { basename, join as join14, resolve as resolve3 } from "node:path";
|
|
25762
|
+
import { basename as basename2, join as join14, resolve as resolve3 } from "node:path";
|
|
25451
25763
|
import { fetch as fetch3 } from "undici";
|
|
25452
25764
|
|
|
25453
25765
|
// src/agent-catalog/agent-discovery.ts
|
|
@@ -25556,8 +25868,8 @@ var LocalAgentInventory = class {
|
|
|
25556
25868
|
};
|
|
25557
25869
|
|
|
25558
25870
|
// src/agent-installation/managed-npm-package.ts
|
|
25559
|
-
import { mkdir as mkdir2, mkdtemp, open as open2, realpath as
|
|
25560
|
-
import { delimiter, dirname as dirname4, isAbsolute as
|
|
25871
|
+
import { mkdir as mkdir2, mkdtemp, open as open2, realpath as realpath3, rename, rm, stat as stat4 } from "node:fs/promises";
|
|
25872
|
+
import { delimiter, dirname as dirname4, isAbsolute as isAbsolute3, join as join4, relative as relative2, sep as sep2 } from "node:path";
|
|
25561
25873
|
var INSTALL_TIMEOUT_MILLISECONDS = 5 * 60 * 1e3;
|
|
25562
25874
|
var PACKAGE_METADATA_LIMIT_BYTES = 64 * 1024;
|
|
25563
25875
|
var PACKAGE_LOCK_LIMIT_BYTES = 8 * 1024 * 1024;
|
|
@@ -25611,8 +25923,8 @@ function packagePath(root, packageName) {
|
|
|
25611
25923
|
return join4(root, "node_modules", ...packageName.split("/"));
|
|
25612
25924
|
}
|
|
25613
25925
|
function isContainedPath(root, candidate) {
|
|
25614
|
-
const difference =
|
|
25615
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${
|
|
25926
|
+
const difference = relative2(root, candidate);
|
|
25927
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep2}`) && !isAbsolute3(difference);
|
|
25616
25928
|
}
|
|
25617
25929
|
async function readJsonRecord(path2, maximumBytes) {
|
|
25618
25930
|
try {
|
|
@@ -25713,7 +26025,7 @@ function verifyPackageLockEntry(lock, definition, verifyDependencyClosure) {
|
|
|
25713
26025
|
}
|
|
25714
26026
|
}
|
|
25715
26027
|
async function verifyRequiredDependency(rootPath, lock, definition) {
|
|
25716
|
-
const dependencyRoot = await
|
|
26028
|
+
const dependencyRoot = await realpath3(packagePath(rootPath, definition.packageName));
|
|
25717
26029
|
if (!isContainedPath(rootPath, dependencyRoot)) {
|
|
25718
26030
|
throw new ManagedNpmPackageError(
|
|
25719
26031
|
"managed_package_verification_failed",
|
|
@@ -25742,8 +26054,8 @@ async function validateManagedNpmPackage(root, definition) {
|
|
|
25742
26054
|
}
|
|
25743
26055
|
}
|
|
25744
26056
|
async function validateManagedNpmPackageContents(root, definition) {
|
|
25745
|
-
const rootPath = await
|
|
25746
|
-
const packageRoot = await
|
|
26057
|
+
const rootPath = await realpath3(root);
|
|
26058
|
+
const packageRoot = await realpath3(packagePath(rootPath, definition.packageName));
|
|
25747
26059
|
if (!isContainedPath(rootPath, packageRoot)) {
|
|
25748
26060
|
throw new ManagedNpmPackageError(
|
|
25749
26061
|
"managed_package_verification_failed",
|
|
@@ -25778,7 +26090,7 @@ var ManagedNpmPackageInstaller = class {
|
|
|
25778
26090
|
install = async (root, definition, environment, signal) => {
|
|
25779
26091
|
signal.throwIfAborted();
|
|
25780
26092
|
try {
|
|
25781
|
-
const metadata = await
|
|
26093
|
+
const metadata = await stat4(root);
|
|
25782
26094
|
if (metadata.isDirectory()) {
|
|
25783
26095
|
return await validateManagedNpmPackage(root, definition);
|
|
25784
26096
|
}
|
|
@@ -26045,8 +26357,8 @@ var CursorCliAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26045
26357
|
};
|
|
26046
26358
|
|
|
26047
26359
|
// src/agent-catalog/agents/deepseek-harness-agent.ts
|
|
26048
|
-
import { realpath as
|
|
26049
|
-
import { isAbsolute as
|
|
26360
|
+
import { realpath as realpath4, stat as stat5 } from "node:fs/promises";
|
|
26361
|
+
import { isAbsolute as isAbsolute4, join as join6, normalize as normalize2 } from "node:path";
|
|
26050
26362
|
|
|
26051
26363
|
// src/agent-installation/deepseek-managed-package.ts
|
|
26052
26364
|
var DeepSeekHarnessManagedPackage = class extends SriManagedNpmPackageDefinition {
|
|
@@ -26064,12 +26376,12 @@ var DEEPSEEK_HARNESS_PACKAGE = new DeepSeekHarnessManagedPackage(
|
|
|
26064
26376
|
|
|
26065
26377
|
// src/agent-catalog/agents/deepseek-harness-agent.ts
|
|
26066
26378
|
async function validateAgentHome(path2) {
|
|
26067
|
-
if (!
|
|
26379
|
+
if (!isAbsolute4(path2) || normalize2(path2) !== path2) {
|
|
26068
26380
|
throw new AgentProbeError("agent_environment_invalid", "The configured Agent home is invalid");
|
|
26069
26381
|
}
|
|
26070
26382
|
try {
|
|
26071
|
-
const resolved = await
|
|
26072
|
-
const metadata = await
|
|
26383
|
+
const resolved = await realpath4(path2);
|
|
26384
|
+
const metadata = await stat5(resolved);
|
|
26073
26385
|
if (!metadata.isDirectory() || typeof process.getuid === "function" && metadata.uid !== process.getuid()) {
|
|
26074
26386
|
throw new Error("Agent home is not a user-owned directory");
|
|
26075
26387
|
}
|
|
@@ -26151,8 +26463,8 @@ var DeepSeekHarnessAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26151
26463
|
};
|
|
26152
26464
|
|
|
26153
26465
|
// src/agent-catalog/agents/grok-build-agent.ts
|
|
26154
|
-
import { realpath as
|
|
26155
|
-
import { isAbsolute as
|
|
26466
|
+
import { realpath as realpath5 } from "node:fs/promises";
|
|
26467
|
+
import { isAbsolute as isAbsolute5, join as join7, relative as relative3, sep as sep3 } from "node:path";
|
|
26156
26468
|
|
|
26157
26469
|
// src/agent-installation/grok-managed-package.ts
|
|
26158
26470
|
var GROK_BUILD_MANAGED_VERSION = "1.0.21";
|
|
@@ -26214,8 +26526,8 @@ function grokBuildManagedPackage(platform, architecture) {
|
|
|
26214
26526
|
|
|
26215
26527
|
// src/agent-catalog/agents/grok-build-agent.ts
|
|
26216
26528
|
function isContainedPath2(root, candidate) {
|
|
26217
|
-
const difference =
|
|
26218
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${
|
|
26529
|
+
const difference = relative3(root, candidate);
|
|
26530
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep3}`) && !isAbsolute5(difference);
|
|
26219
26531
|
}
|
|
26220
26532
|
var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
26221
26533
|
adapterVersion = GROK_BUILD_MANAGED_VERSION;
|
|
@@ -26242,7 +26554,7 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26242
26554
|
);
|
|
26243
26555
|
if (managed.path === agent.path) {
|
|
26244
26556
|
return Object.freeze({
|
|
26245
|
-
GROK_HOME: await
|
|
26557
|
+
GROK_HOME: await realpath5(
|
|
26246
26558
|
join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION, "home")
|
|
26247
26559
|
)
|
|
26248
26560
|
});
|
|
@@ -26254,7 +26566,7 @@ var GrokBuildAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26254
26566
|
};
|
|
26255
26567
|
resolveManagedAgent = async (stateDirectory, platform, signal) => {
|
|
26256
26568
|
signal.throwIfAborted();
|
|
26257
|
-
const versionRoot = await
|
|
26569
|
+
const versionRoot = await realpath5(join7(stateDirectory, "agents", this.id, GROK_BUILD_MANAGED_VERSION));
|
|
26258
26570
|
await validateManagedNpmPackage(join7(versionRoot, "package"), grokBuildManagedPackage(platform, process.arch));
|
|
26259
26571
|
const executable = await resolveExecutablePath(join7(versionRoot, "home", "bin", "grok"), platform);
|
|
26260
26572
|
signal.throwIfAborted();
|
|
@@ -26279,8 +26591,8 @@ import { join as join9 } from "node:path";
|
|
|
26279
26591
|
// src/agent-installation/managed-agent-archive.ts
|
|
26280
26592
|
import { createHash as createHash2 } from "node:crypto";
|
|
26281
26593
|
import { createReadStream } from "node:fs";
|
|
26282
|
-
import { chmod as chmod2, copyFile, mkdir as mkdir3, mkdtemp as mkdtemp2, open as open3, realpath as
|
|
26283
|
-
import { dirname as dirname5, isAbsolute as
|
|
26594
|
+
import { chmod as chmod2, copyFile, mkdir as mkdir3, mkdtemp as mkdtemp2, open as open3, realpath as realpath6, rename as rename2, rm as rm2, stat as stat6, writeFile } from "node:fs/promises";
|
|
26595
|
+
import { dirname as dirname5, isAbsolute as isAbsolute6, join as join8, relative as relative4, sep as sep4 } from "node:path";
|
|
26284
26596
|
|
|
26285
26597
|
// src/agent-installation/verified-download.ts
|
|
26286
26598
|
import { fetch as fetch2 } from "undici";
|
|
@@ -26385,8 +26697,8 @@ function isRecord10(value) {
|
|
|
26385
26697
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
26386
26698
|
}
|
|
26387
26699
|
function isContainedPath3(root, candidate) {
|
|
26388
|
-
const difference =
|
|
26389
|
-
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${
|
|
26700
|
+
const difference = relative4(root, candidate);
|
|
26701
|
+
return difference.length > 0 && difference !== ".." && !difference.startsWith(`..${sep4}`) && !isAbsolute6(difference);
|
|
26390
26702
|
}
|
|
26391
26703
|
async function hashFile(path2, signal) {
|
|
26392
26704
|
signal.throwIfAborted();
|
|
@@ -26460,8 +26772,8 @@ async function readManifest(path2) {
|
|
|
26460
26772
|
}
|
|
26461
26773
|
async function validateManagedAgentArchive(root, definition, signal) {
|
|
26462
26774
|
try {
|
|
26463
|
-
const rootPath = await
|
|
26464
|
-
const rootMetadata = await
|
|
26775
|
+
const rootPath = await realpath6(root);
|
|
26776
|
+
const rootMetadata = await stat6(rootPath);
|
|
26465
26777
|
if (!rootMetadata.isDirectory() || typeof process.getuid === "function" && rootMetadata.uid !== process.getuid()) {
|
|
26466
26778
|
throw new Error("Managed Agent root is not user-owned");
|
|
26467
26779
|
}
|
|
@@ -26676,7 +26988,7 @@ var PiAgentSpecification = class extends BridgedAcpAgentDefinition {
|
|
|
26676
26988
|
};
|
|
26677
26989
|
|
|
26678
26990
|
// src/agent-catalog/agents/workbuddy-agent.ts
|
|
26679
|
-
import { isAbsolute as
|
|
26991
|
+
import { isAbsolute as isAbsolute7, join as join11 } from "node:path";
|
|
26680
26992
|
|
|
26681
26993
|
// src/agent-installation/workbuddy-managed-package.ts
|
|
26682
26994
|
var WORKBUDDY_MANAGED_VERSION = "2.146.0";
|
|
@@ -26742,7 +27054,7 @@ var WorkBuddyAgentSpecification = class extends DirectAcpAgentDefinition {
|
|
|
26742
27054
|
}
|
|
26743
27055
|
const requestedPaths = [join11("/Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH)];
|
|
26744
27056
|
const homeDirectory = context.environment["HOME"];
|
|
26745
|
-
if (homeDirectory !== void 0 &&
|
|
27057
|
+
if (homeDirectory !== void 0 && isAbsolute7(homeDirectory)) {
|
|
26746
27058
|
requestedPaths.unshift(join11(homeDirectory, "Applications", ...WORKBUDDY_MACOS_EXECUTABLE_PATH));
|
|
26747
27059
|
}
|
|
26748
27060
|
const executables = [];
|
|
@@ -26788,7 +27100,7 @@ import {
|
|
|
26788
27100
|
} from "@agentclientprotocol/sdk";
|
|
26789
27101
|
|
|
26790
27102
|
// src/agent-catalog/executable-discovery.ts
|
|
26791
|
-
import { isAbsolute as
|
|
27103
|
+
import { isAbsolute as isAbsolute8, join as join13 } from "node:path";
|
|
26792
27104
|
|
|
26793
27105
|
// src/agent-installation/managed-adapter-installer.ts
|
|
26794
27106
|
import { join as join12 } from "node:path";
|
|
@@ -26893,7 +27205,7 @@ async function resolveManagedAdapterExecutable(specification, context) {
|
|
|
26893
27205
|
async function resolveSpecificationExecutables(executableName, overrideVariable, resolveInstalled, resolveManaged, context) {
|
|
26894
27206
|
const override = context.environment[overrideVariable];
|
|
26895
27207
|
if (override !== void 0) {
|
|
26896
|
-
if (override.length === 0 || !
|
|
27208
|
+
if (override.length === 0 || !isAbsolute8(override)) {
|
|
26897
27209
|
return [];
|
|
26898
27210
|
}
|
|
26899
27211
|
const executable = await resolveExecutablePath(override, context.platform);
|
|
@@ -27421,8 +27733,8 @@ async function resolveDefaultWorkspace(path2) {
|
|
|
27421
27733
|
const requestedWorkspace = resolve3(path2);
|
|
27422
27734
|
try {
|
|
27423
27735
|
await mkdir4(requestedWorkspace, { recursive: true, mode: 448 });
|
|
27424
|
-
const defaultWorkspace = await
|
|
27425
|
-
const metadata = await
|
|
27736
|
+
const defaultWorkspace = await realpath7(requestedWorkspace);
|
|
27737
|
+
const metadata = await stat7(defaultWorkspace);
|
|
27426
27738
|
if (!metadata.isDirectory()) {
|
|
27427
27739
|
throw new PairingClientError("invalid_workspace", "The default workspace is not a directory");
|
|
27428
27740
|
}
|
|
@@ -27468,12 +27780,12 @@ function decodePairingResponse(value, credentialField, expectedKeys) {
|
|
|
27468
27780
|
throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
|
|
27469
27781
|
}
|
|
27470
27782
|
const channelId = value["channelId"];
|
|
27471
|
-
const
|
|
27783
|
+
const runtimeCredential2 = value[credentialField];
|
|
27472
27784
|
const runtimeId = value["runtimeId"];
|
|
27473
|
-
if (typeof channelId !== "string" || !IDENTIFIER_PATTERN6.test(channelId) || typeof
|
|
27785
|
+
if (typeof channelId !== "string" || !IDENTIFIER_PATTERN6.test(channelId) || typeof runtimeCredential2 !== "string" || !TOKEN_PATTERN2.test(runtimeCredential2) || typeof runtimeId !== "string" || !IDENTIFIER_PATTERN6.test(runtimeId)) {
|
|
27474
27786
|
throw new PairingClientError("invalid_relay_response", "The relay returned an invalid pairing response");
|
|
27475
27787
|
}
|
|
27476
|
-
return { channelId, runtimeCredential, runtimeId };
|
|
27788
|
+
return { channelId, runtimeCredential: runtimeCredential2, runtimeId };
|
|
27477
27789
|
}
|
|
27478
27790
|
async function claimPairing(options, defaultWorkspace, localAgents, installableAgents, signal) {
|
|
27479
27791
|
const agents = localAgents.map((agent) => ({
|
|
@@ -27492,7 +27804,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
27492
27804
|
installableAgents,
|
|
27493
27805
|
machineName: hostname3(),
|
|
27494
27806
|
pairingCode: options.code,
|
|
27495
|
-
workspaceName:
|
|
27807
|
+
workspaceName: basename2(defaultWorkspace) || "Local workspace"
|
|
27496
27808
|
}),
|
|
27497
27809
|
dispatcher: environmentProxyDispatcher,
|
|
27498
27810
|
headers: { "content-type": "application/json" },
|
|
@@ -27508,7 +27820,7 @@ async function claimPairing(options, defaultWorkspace, localAgents, installableA
|
|
|
27508
27820
|
}
|
|
27509
27821
|
return options.pairingId.length > 0 ? decodePairingResponse(value, "runtimeCredential", REDEEM_RESPONSE_KEYS) : decodePairingResponse(value, "daemonToken", CLAIM_RESPONSE_KEYS);
|
|
27510
27822
|
}
|
|
27511
|
-
async function persistConnection(channelId, relayOrigin,
|
|
27823
|
+
async function persistConnection(channelId, relayOrigin, runtimeCredential2, defaultWorkspace, environment) {
|
|
27512
27824
|
const connectionsDirectory = join14(readStateDirectory(environment), "connections");
|
|
27513
27825
|
await mkdir4(connectionsDirectory, { mode: 448, recursive: true });
|
|
27514
27826
|
const connectionPath = join14(connectionsDirectory, `${channelId}.json`);
|
|
@@ -27520,7 +27832,7 @@ async function persistConnection(channelId, relayOrigin, runtimeCredential, defa
|
|
|
27520
27832
|
defaultWorkspace,
|
|
27521
27833
|
channelId,
|
|
27522
27834
|
relayOrigin: relayOrigin.toString(),
|
|
27523
|
-
runtimeCredential
|
|
27835
|
+
runtimeCredential: runtimeCredential2
|
|
27524
27836
|
},
|
|
27525
27837
|
null,
|
|
27526
27838
|
2
|
|
@@ -27537,16 +27849,16 @@ function decodeSavedConnection(value, expectedChannelId) {
|
|
|
27537
27849
|
}
|
|
27538
27850
|
const defaultWorkspace = value["defaultWorkspace"];
|
|
27539
27851
|
const channelId = value["channelId"];
|
|
27540
|
-
const
|
|
27852
|
+
const runtimeCredential2 = value["runtimeCredential"] ?? value["daemonToken"];
|
|
27541
27853
|
const relayOrigin = value["relayOrigin"];
|
|
27542
|
-
if (typeof defaultWorkspace !== "string" || typeof channelId !== "string" || channelId !== expectedChannelId || !IDENTIFIER_PATTERN6.test(channelId) || typeof
|
|
27854
|
+
if (typeof defaultWorkspace !== "string" || typeof channelId !== "string" || channelId !== expectedChannelId || !IDENTIFIER_PATTERN6.test(channelId) || typeof runtimeCredential2 !== "string" || !TOKEN_PATTERN2.test(runtimeCredential2) || typeof relayOrigin !== "string") {
|
|
27543
27855
|
throw new PairingClientError("invalid_connection", "The saved connection is invalid");
|
|
27544
27856
|
}
|
|
27545
27857
|
return {
|
|
27546
27858
|
defaultWorkspace,
|
|
27547
27859
|
channelId,
|
|
27548
27860
|
relayOrigin: parseRelayOrigin(relayOrigin),
|
|
27549
|
-
runtimeCredential
|
|
27861
|
+
runtimeCredential: runtimeCredential2
|
|
27550
27862
|
};
|
|
27551
27863
|
}
|
|
27552
27864
|
async function readSavedConnection(channelId, environment) {
|
|
@@ -27663,12 +27975,29 @@ async function resumeLocalMachine(arguments_, signal = new AbortController().sig
|
|
|
27663
27975
|
|
|
27664
27976
|
// src/run-daemon.ts
|
|
27665
27977
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
27666
|
-
import { basename as
|
|
27978
|
+
import { basename as basename5, join as join16 } from "node:path";
|
|
27667
27979
|
import { styleText } from "node:util";
|
|
27668
|
-
import { fetch as
|
|
27980
|
+
import { fetch as fetch7, WebSocket as WebSocket2 } from "undici";
|
|
27669
27981
|
|
|
27670
27982
|
// src/agent-catalog/publish-agent-catalog.ts
|
|
27671
27983
|
import { fetch as fetch4 } from "undici";
|
|
27984
|
+
|
|
27985
|
+
// src/relay-connection/runtime-authentication.ts
|
|
27986
|
+
function runtimeCredential(relayUrl) {
|
|
27987
|
+
return relayUrl.searchParams.get("token") ?? "";
|
|
27988
|
+
}
|
|
27989
|
+
function runtimeAuthorization(relayUrl) {
|
|
27990
|
+
const credential = runtimeCredential(relayUrl);
|
|
27991
|
+
return credential.length === 0 ? {} : { authorization: `Bearer ${credential}` };
|
|
27992
|
+
}
|
|
27993
|
+
function relayHttpEndpoint(relayUrl) {
|
|
27994
|
+
const endpoint = new URL(relayUrl);
|
|
27995
|
+
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
27996
|
+
endpoint.search = "";
|
|
27997
|
+
return endpoint;
|
|
27998
|
+
}
|
|
27999
|
+
|
|
28000
|
+
// src/agent-catalog/publish-agent-catalog.ts
|
|
27672
28001
|
var CATALOG_UPDATE_TIMEOUT_MILLISECONDS = 2e4;
|
|
27673
28002
|
var AgentCatalogPublishError = class extends Error {
|
|
27674
28003
|
code = "agent_catalog_update_failed";
|
|
@@ -27678,8 +28007,7 @@ var AgentCatalogPublishError = class extends Error {
|
|
|
27678
28007
|
}
|
|
27679
28008
|
};
|
|
27680
28009
|
function catalogEndpoint(config2) {
|
|
27681
|
-
const endpoint =
|
|
27682
|
-
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
28010
|
+
const endpoint = relayHttpEndpoint(config2.relayUrl);
|
|
27683
28011
|
if (endpoint.pathname.endsWith("/daemon")) {
|
|
27684
28012
|
endpoint.pathname = `${endpoint.pathname.slice(0, -"/daemon".length)}/catalog`;
|
|
27685
28013
|
return endpoint;
|
|
@@ -27710,7 +28038,7 @@ async function publishAgentCatalog(config2, signal) {
|
|
|
27710
28038
|
installableAgents: catalog.installableAgents
|
|
27711
28039
|
}),
|
|
27712
28040
|
dispatcher: environmentProxyDispatcher,
|
|
27713
|
-
headers: { "content-type": "application/json" },
|
|
28041
|
+
headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
|
|
27714
28042
|
method: "PUT",
|
|
27715
28043
|
signal: requestSignal
|
|
27716
28044
|
});
|
|
@@ -28192,103 +28520,499 @@ var FixedInstallationExecutor = class {
|
|
|
28192
28520
|
};
|
|
28193
28521
|
};
|
|
28194
28522
|
|
|
28195
|
-
// src/
|
|
28196
|
-
import {
|
|
28197
|
-
|
|
28198
|
-
|
|
28199
|
-
var
|
|
28200
|
-
|
|
28201
|
-
|
|
28202
|
-
|
|
28203
|
-
|
|
28204
|
-
|
|
28205
|
-
this.directoryId = directoryId2;
|
|
28206
|
-
this.directoryLabel = directoryLabel;
|
|
28207
|
-
this.entries = entries;
|
|
28208
|
-
this.parentDirectoryId = parentDirectoryId;
|
|
28523
|
+
// src/artifacts/runtime-artifact-uploader.ts
|
|
28524
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
28525
|
+
|
|
28526
|
+
// ../mobius-sdk/src/errors.ts
|
|
28527
|
+
var MobiusError = class extends Error {
|
|
28528
|
+
code;
|
|
28529
|
+
constructor(code, message, options = {}) {
|
|
28530
|
+
super(message, options);
|
|
28531
|
+
this.code = code;
|
|
28532
|
+
this.name = "MobiusError";
|
|
28209
28533
|
}
|
|
28210
28534
|
};
|
|
28211
|
-
|
|
28212
|
-
|
|
28213
|
-
|
|
28214
|
-
|
|
28535
|
+
var MobiusProtocolError = class extends MobiusError {
|
|
28536
|
+
constructor(message, options = {}) {
|
|
28537
|
+
super("invalid_service_response", message, options);
|
|
28538
|
+
this.name = "MobiusProtocolError";
|
|
28215
28539
|
}
|
|
28216
|
-
|
|
28540
|
+
};
|
|
28541
|
+
var MobiusValidationError = class extends MobiusError {
|
|
28542
|
+
constructor(message, options = {}) {
|
|
28543
|
+
super("invalid_request", message, options);
|
|
28544
|
+
this.name = "MobiusValidationError";
|
|
28545
|
+
}
|
|
28546
|
+
};
|
|
28547
|
+
|
|
28548
|
+
// ../mobius-sdk/src/resources.ts
|
|
28549
|
+
var IDENTIFIER_PATTERN7 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
28550
|
+
function invalidResponse(message) {
|
|
28551
|
+
return new MobiusProtocolError(message);
|
|
28217
28552
|
}
|
|
28218
|
-
function
|
|
28219
|
-
|
|
28220
|
-
|
|
28221
|
-
|
|
28553
|
+
function isRecord12(value) {
|
|
28554
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28555
|
+
}
|
|
28556
|
+
function record2(value, name) {
|
|
28557
|
+
if (!isRecord12(value)) {
|
|
28558
|
+
throw invalidResponse(`The service returned an invalid ${name}`);
|
|
28222
28559
|
}
|
|
28223
|
-
|
|
28224
|
-
|
|
28225
|
-
|
|
28560
|
+
return value;
|
|
28561
|
+
}
|
|
28562
|
+
function stringField(value, field, maximumLength = 85e5) {
|
|
28563
|
+
const candidate = value[field];
|
|
28564
|
+
if (typeof candidate !== "string" || candidate.length > maximumLength) {
|
|
28565
|
+
throw invalidResponse(`The service returned an invalid ${field}`);
|
|
28226
28566
|
}
|
|
28227
|
-
return
|
|
28567
|
+
return candidate;
|
|
28228
28568
|
}
|
|
28229
|
-
|
|
28230
|
-
|
|
28231
|
-
|
|
28232
|
-
|
|
28233
|
-
this.#bindingId = bindingId;
|
|
28234
|
-
this.#defaultWorkspace = defaultWorkspace;
|
|
28569
|
+
function identifierField(value, field) {
|
|
28570
|
+
const candidate = stringField(value, field, 128);
|
|
28571
|
+
if (!IDENTIFIER_PATTERN7.test(candidate)) {
|
|
28572
|
+
throw invalidResponse(`The service returned an invalid ${field}`);
|
|
28235
28573
|
}
|
|
28236
|
-
|
|
28237
|
-
|
|
28238
|
-
|
|
28239
|
-
|
|
28240
|
-
|
|
28241
|
-
|
|
28242
|
-
|
|
28243
|
-
|
|
28244
|
-
|
|
28245
|
-
|
|
28246
|
-
|
|
28247
|
-
}
|
|
28248
|
-
|
|
28249
|
-
|
|
28250
|
-
|
|
28251
|
-
|
|
28252
|
-
|
|
28253
|
-
|
|
28254
|
-
|
|
28255
|
-
|
|
28256
|
-
|
|
28257
|
-
|
|
28258
|
-
|
|
28259
|
-
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
28260
|
-
}
|
|
28261
|
-
try {
|
|
28262
|
-
const target = await realpath7(requested);
|
|
28263
|
-
signal.throwIfAborted();
|
|
28264
|
-
const metadata = await stat7(target);
|
|
28265
|
-
signal.throwIfAborted();
|
|
28266
|
-
if (!isAbsolute8(target) || normalize2(target) !== target || !metadata.isDirectory()) {
|
|
28267
|
-
throw new LocalAuthorizationError("The selected location is not a directory");
|
|
28268
|
-
}
|
|
28269
|
-
return target;
|
|
28270
|
-
} catch (cause) {
|
|
28271
|
-
signal.throwIfAborted();
|
|
28272
|
-
if (cause instanceof LocalAuthorizationError) {
|
|
28273
|
-
throw cause;
|
|
28274
|
-
}
|
|
28275
|
-
throw new LocalAuthorizationError("This directory is missing or unavailable to your user account", {
|
|
28276
|
-
cause
|
|
28277
|
-
});
|
|
28574
|
+
return candidate;
|
|
28575
|
+
}
|
|
28576
|
+
function integerField(value, field) {
|
|
28577
|
+
const candidate = value[field];
|
|
28578
|
+
if (typeof candidate !== "number" || !Number.isSafeInteger(candidate) || candidate < 0) {
|
|
28579
|
+
throw invalidResponse(`The service returned an invalid ${field}`);
|
|
28580
|
+
}
|
|
28581
|
+
return candidate;
|
|
28582
|
+
}
|
|
28583
|
+
function validateTimestamp(value, field) {
|
|
28584
|
+
if (Number.isNaN(Date.parse(value))) {
|
|
28585
|
+
throw invalidResponse(`The service returned an invalid ${field}`);
|
|
28586
|
+
}
|
|
28587
|
+
return value;
|
|
28588
|
+
}
|
|
28589
|
+
var MobiusArtifactUploadRequest = class {
|
|
28590
|
+
byteLength;
|
|
28591
|
+
mediaType;
|
|
28592
|
+
name;
|
|
28593
|
+
sha256;
|
|
28594
|
+
constructor(name, mediaType, byteLength, sha256) {
|
|
28595
|
+
if (name.length < 1 || name.length > 500 || name.includes("\0") || mediaType.length < 1 || mediaType.length > 255 || mediaType.includes("\r") || mediaType.includes("\n") || !Number.isSafeInteger(byteLength) || byteLength < 1 || !/^[a-f0-9]{64}$/.test(sha256)) {
|
|
28596
|
+
throw new MobiusValidationError("The artifact upload request is invalid");
|
|
28278
28597
|
}
|
|
28279
|
-
|
|
28280
|
-
|
|
28281
|
-
|
|
28282
|
-
|
|
28283
|
-
}
|
|
28284
|
-
|
|
28285
|
-
|
|
28286
|
-
|
|
28287
|
-
|
|
28288
|
-
|
|
28289
|
-
|
|
28290
|
-
|
|
28291
|
-
|
|
28598
|
+
this.byteLength = byteLength;
|
|
28599
|
+
this.mediaType = mediaType;
|
|
28600
|
+
this.name = name;
|
|
28601
|
+
this.sha256 = sha256;
|
|
28602
|
+
}
|
|
28603
|
+
};
|
|
28604
|
+
var MobiusArtifact = class {
|
|
28605
|
+
artifactId;
|
|
28606
|
+
byteLength;
|
|
28607
|
+
createdAt;
|
|
28608
|
+
mediaType;
|
|
28609
|
+
name;
|
|
28610
|
+
sessionId;
|
|
28611
|
+
sha256;
|
|
28612
|
+
constructor(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt) {
|
|
28613
|
+
this.artifactId = artifactId;
|
|
28614
|
+
this.byteLength = byteLength;
|
|
28615
|
+
this.createdAt = createdAt;
|
|
28616
|
+
this.mediaType = mediaType;
|
|
28617
|
+
this.name = name;
|
|
28618
|
+
this.sessionId = sessionId;
|
|
28619
|
+
this.sha256 = sha256;
|
|
28620
|
+
}
|
|
28621
|
+
};
|
|
28622
|
+
var MobiusUploadingArtifact = class extends MobiusArtifact {
|
|
28623
|
+
expiresAt;
|
|
28624
|
+
state = "uploading";
|
|
28625
|
+
constructor(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt, expiresAt) {
|
|
28626
|
+
super(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt);
|
|
28627
|
+
this.expiresAt = expiresAt;
|
|
28628
|
+
}
|
|
28629
|
+
};
|
|
28630
|
+
var MobiusArtifactUpload = class extends MobiusUploadingArtifact {
|
|
28631
|
+
uploadToken;
|
|
28632
|
+
constructor(artifact, uploadToken) {
|
|
28633
|
+
super(
|
|
28634
|
+
artifact.sessionId,
|
|
28635
|
+
artifact.artifactId,
|
|
28636
|
+
artifact.name,
|
|
28637
|
+
artifact.mediaType,
|
|
28638
|
+
artifact.byteLength,
|
|
28639
|
+
artifact.sha256,
|
|
28640
|
+
artifact.createdAt,
|
|
28641
|
+
artifact.expiresAt
|
|
28642
|
+
);
|
|
28643
|
+
this.uploadToken = uploadToken;
|
|
28644
|
+
}
|
|
28645
|
+
};
|
|
28646
|
+
var MobiusAvailableArtifact = class extends MobiusArtifact {
|
|
28647
|
+
availableAt;
|
|
28648
|
+
state = "available";
|
|
28649
|
+
constructor(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt, availableAt) {
|
|
28650
|
+
super(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt);
|
|
28651
|
+
this.availableAt = availableAt;
|
|
28652
|
+
}
|
|
28653
|
+
};
|
|
28654
|
+
var MobiusExpiredArtifact = class extends MobiusArtifact {
|
|
28655
|
+
expiredAt;
|
|
28656
|
+
state = "expired";
|
|
28657
|
+
constructor(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt, expiredAt) {
|
|
28658
|
+
super(sessionId, artifactId, name, mediaType, byteLength, sha256, createdAt);
|
|
28659
|
+
this.expiredAt = expiredAt;
|
|
28660
|
+
}
|
|
28661
|
+
};
|
|
28662
|
+
function artifactFields(value) {
|
|
28663
|
+
const sha256 = stringField(value, "sha256", 64);
|
|
28664
|
+
if (!/^[a-f0-9]{64}$/.test(sha256)) {
|
|
28665
|
+
throw invalidResponse("The service returned an invalid artifact digest");
|
|
28666
|
+
}
|
|
28667
|
+
return {
|
|
28668
|
+
artifactId: identifierField(value, "artifactId"),
|
|
28669
|
+
byteLength: integerField(value, "byteLength"),
|
|
28670
|
+
createdAt: validateTimestamp(stringField(value, "createdAt", 128), "createdAt"),
|
|
28671
|
+
mediaType: stringField(value, "mediaType", 255),
|
|
28672
|
+
name: stringField(value, "name", 500),
|
|
28673
|
+
sessionId: identifierField(value, "sessionId"),
|
|
28674
|
+
sha256
|
|
28675
|
+
};
|
|
28676
|
+
}
|
|
28677
|
+
function uploadingArtifact(value) {
|
|
28678
|
+
const fields = artifactFields(value);
|
|
28679
|
+
return new MobiusUploadingArtifact(
|
|
28680
|
+
fields.sessionId,
|
|
28681
|
+
fields.artifactId,
|
|
28682
|
+
fields.name,
|
|
28683
|
+
fields.mediaType,
|
|
28684
|
+
fields.byteLength,
|
|
28685
|
+
fields.sha256,
|
|
28686
|
+
fields.createdAt,
|
|
28687
|
+
validateTimestamp(stringField(value, "expiresAt", 128), "expiresAt")
|
|
28688
|
+
);
|
|
28689
|
+
}
|
|
28690
|
+
function decodeMobiusArtifactUpload(value) {
|
|
28691
|
+
const artifact = record2(value, "artifact upload authorization");
|
|
28692
|
+
return new MobiusArtifactUpload(uploadingArtifact(artifact), stringField(artifact, "uploadToken", 256));
|
|
28693
|
+
}
|
|
28694
|
+
function decodeMobiusArtifact(value) {
|
|
28695
|
+
const artifact = record2(value, "artifact");
|
|
28696
|
+
const state = stringField(artifact, "state", 32);
|
|
28697
|
+
if (state === "uploading") {
|
|
28698
|
+
return uploadingArtifact(artifact);
|
|
28699
|
+
}
|
|
28700
|
+
const fields = artifactFields(artifact);
|
|
28701
|
+
if (state === "available") {
|
|
28702
|
+
return new MobiusAvailableArtifact(
|
|
28703
|
+
fields.sessionId,
|
|
28704
|
+
fields.artifactId,
|
|
28705
|
+
fields.name,
|
|
28706
|
+
fields.mediaType,
|
|
28707
|
+
fields.byteLength,
|
|
28708
|
+
fields.sha256,
|
|
28709
|
+
fields.createdAt,
|
|
28710
|
+
validateTimestamp(stringField(artifact, "availableAt", 128), "availableAt")
|
|
28711
|
+
);
|
|
28712
|
+
}
|
|
28713
|
+
if (state === "expired") {
|
|
28714
|
+
return new MobiusExpiredArtifact(
|
|
28715
|
+
fields.sessionId,
|
|
28716
|
+
fields.artifactId,
|
|
28717
|
+
fields.name,
|
|
28718
|
+
fields.mediaType,
|
|
28719
|
+
fields.byteLength,
|
|
28720
|
+
fields.sha256,
|
|
28721
|
+
fields.createdAt,
|
|
28722
|
+
validateTimestamp(stringField(artifact, "expiredAt", 128), "expiredAt")
|
|
28723
|
+
);
|
|
28724
|
+
}
|
|
28725
|
+
throw invalidResponse("The service returned an invalid artifact state");
|
|
28726
|
+
}
|
|
28727
|
+
function decodeMobiusAvailableArtifact(value) {
|
|
28728
|
+
const artifact = decodeMobiusArtifact(value);
|
|
28729
|
+
if (!(artifact instanceof MobiusAvailableArtifact)) {
|
|
28730
|
+
throw invalidResponse("The service did not make the artifact available");
|
|
28731
|
+
}
|
|
28732
|
+
return artifact;
|
|
28733
|
+
}
|
|
28734
|
+
var MobiusRuntimePairingLifecycle = Object.freeze({
|
|
28735
|
+
Expired: "expired",
|
|
28736
|
+
Paired: "paired",
|
|
28737
|
+
Pending: "pending",
|
|
28738
|
+
Revoked: "revoked"
|
|
28739
|
+
});
|
|
28740
|
+
|
|
28741
|
+
// src/artifacts/runtime-artifact-uploader.ts
|
|
28742
|
+
import { fetch as fetch5 } from "undici";
|
|
28743
|
+
var UPLOAD_TIMEOUT_MILLISECONDS = 2e4;
|
|
28744
|
+
var RuntimeArtifactUploadError = class extends Error {
|
|
28745
|
+
code;
|
|
28746
|
+
constructor(code, message, options = {}) {
|
|
28747
|
+
super(message, options);
|
|
28748
|
+
this.code = code;
|
|
28749
|
+
this.name = "RuntimeArtifactUploadError";
|
|
28750
|
+
}
|
|
28751
|
+
};
|
|
28752
|
+
var UploadedRuntimeArtifact = class {
|
|
28753
|
+
artifactId;
|
|
28754
|
+
byteLength;
|
|
28755
|
+
mimeType;
|
|
28756
|
+
name;
|
|
28757
|
+
sha256;
|
|
28758
|
+
constructor(artifactId, name, mimeType, byteLength, sha256) {
|
|
28759
|
+
this.artifactId = artifactId;
|
|
28760
|
+
this.byteLength = byteLength;
|
|
28761
|
+
this.mimeType = mimeType;
|
|
28762
|
+
this.name = name;
|
|
28763
|
+
this.sha256 = sha256;
|
|
28764
|
+
}
|
|
28765
|
+
};
|
|
28766
|
+
function daemonToken2(config2) {
|
|
28767
|
+
const token = config2.relayUrl.searchParams.get("token");
|
|
28768
|
+
if (token === null || token.length < 32) {
|
|
28769
|
+
throw new RuntimeArtifactUploadError("artifact_endpoint_invalid", "The Relay daemon token is missing");
|
|
28770
|
+
}
|
|
28771
|
+
return token;
|
|
28772
|
+
}
|
|
28773
|
+
function channelOrigin(config2) {
|
|
28774
|
+
const url2 = new URL(config2.relayUrl);
|
|
28775
|
+
url2.protocol = url2.protocol === "wss:" ? "https:" : "http:";
|
|
28776
|
+
let channelPath = "";
|
|
28777
|
+
if (url2.pathname.endsWith("/daemon")) {
|
|
28778
|
+
channelPath = url2.pathname.slice(0, -"/daemon".length);
|
|
28779
|
+
} else {
|
|
28780
|
+
const runtimePath = `${MOBIUS_API_PREFIX}/v1/runtimes/connect`;
|
|
28781
|
+
if (!url2.pathname.endsWith("/v1/runtimes/connect") && !url2.pathname.endsWith(runtimePath)) {
|
|
28782
|
+
throw new RuntimeArtifactUploadError("artifact_endpoint_invalid", "The Relay artifact endpoint is invalid");
|
|
28783
|
+
}
|
|
28784
|
+
channelPath = `${url2.pathname.replace(/\/v1\/runtimes\/connect$/, "")}/channels/${encodeURIComponent(config2.channelId)}`;
|
|
28785
|
+
}
|
|
28786
|
+
url2.pathname = channelPath;
|
|
28787
|
+
url2.search = "";
|
|
28788
|
+
url2.hash = "";
|
|
28789
|
+
return url2;
|
|
28790
|
+
}
|
|
28791
|
+
function uploadError(code, message, cause) {
|
|
28792
|
+
return new RuntimeArtifactUploadError(code, message, cause === void 0 ? {} : { cause });
|
|
28793
|
+
}
|
|
28794
|
+
function translateSdkError(cause) {
|
|
28795
|
+
if (cause instanceof MobiusValidationError) {
|
|
28796
|
+
throw uploadError("artifact_upload_failed", cause.message, cause);
|
|
28797
|
+
}
|
|
28798
|
+
if (cause instanceof MobiusProtocolError) {
|
|
28799
|
+
throw uploadError("artifact_upload_failed", "The Relay returned an invalid upload response", cause);
|
|
28800
|
+
}
|
|
28801
|
+
throw cause;
|
|
28802
|
+
}
|
|
28803
|
+
async function readJson(response) {
|
|
28804
|
+
try {
|
|
28805
|
+
return await response.json();
|
|
28806
|
+
} catch (cause) {
|
|
28807
|
+
throw uploadError("artifact_upload_failed", "The Relay returned an invalid upload response", cause);
|
|
28808
|
+
}
|
|
28809
|
+
}
|
|
28810
|
+
async function readAuthorization(response) {
|
|
28811
|
+
try {
|
|
28812
|
+
return decodeMobiusArtifactUpload(await readJson(response));
|
|
28813
|
+
} catch (cause) {
|
|
28814
|
+
translateSdkError(cause);
|
|
28815
|
+
}
|
|
28816
|
+
}
|
|
28817
|
+
function sessionArtifactUrl(origin, sessionId, resourcePath, token) {
|
|
28818
|
+
const url2 = new URL(`${origin.pathname}/sessions/${encodeURIComponent(sessionId)}/${resourcePath}`, origin);
|
|
28819
|
+
url2.searchParams.set("token", token);
|
|
28820
|
+
return url2;
|
|
28821
|
+
}
|
|
28822
|
+
async function postLease(url2, request, signal) {
|
|
28823
|
+
return await fetch5(url2, {
|
|
28824
|
+
dispatcher: environmentProxyDispatcher,
|
|
28825
|
+
headers: { "content-type": "application/json" },
|
|
28826
|
+
method: "POST",
|
|
28827
|
+
body: JSON.stringify(request),
|
|
28828
|
+
signal
|
|
28829
|
+
});
|
|
28830
|
+
}
|
|
28831
|
+
async function putContent(url2, authorization, bytes, signal) {
|
|
28832
|
+
return await fetch5(url2, {
|
|
28833
|
+
dispatcher: environmentProxyDispatcher,
|
|
28834
|
+
headers: {
|
|
28835
|
+
"content-type": authorization.mediaType,
|
|
28836
|
+
"x-mobius-upload-token": authorization.uploadToken
|
|
28837
|
+
},
|
|
28838
|
+
method: "PUT",
|
|
28839
|
+
body: bytes,
|
|
28840
|
+
signal
|
|
28841
|
+
});
|
|
28842
|
+
}
|
|
28843
|
+
async function uploadRuntimeArtifact(config2, sessionId, image, signal) {
|
|
28844
|
+
signal.throwIfAborted();
|
|
28845
|
+
let request;
|
|
28846
|
+
try {
|
|
28847
|
+
request = new MobiusArtifactUploadRequest(
|
|
28848
|
+
image.name,
|
|
28849
|
+
image.mimeType,
|
|
28850
|
+
image.bytes.byteLength,
|
|
28851
|
+
createHash3("sha256").update(image.bytes).digest("hex")
|
|
28852
|
+
);
|
|
28853
|
+
} catch (cause) {
|
|
28854
|
+
translateSdkError(cause);
|
|
28855
|
+
}
|
|
28856
|
+
const timeoutSignal = AbortSignal.timeout(UPLOAD_TIMEOUT_MILLISECONDS);
|
|
28857
|
+
const requestSignal = AbortSignal.any([signal, timeoutSignal]);
|
|
28858
|
+
const origin = channelOrigin(config2);
|
|
28859
|
+
const token = daemonToken2(config2);
|
|
28860
|
+
let created;
|
|
28861
|
+
try {
|
|
28862
|
+
created = await postLease(
|
|
28863
|
+
sessionArtifactUrl(origin, sessionId, "artifacts/uploads", token),
|
|
28864
|
+
request,
|
|
28865
|
+
requestSignal
|
|
28866
|
+
);
|
|
28867
|
+
} catch (cause) {
|
|
28868
|
+
signal.throwIfAborted();
|
|
28869
|
+
throw uploadError(
|
|
28870
|
+
timeoutSignal.aborted ? "artifact_upload_timeout" : "artifact_upload_failed",
|
|
28871
|
+
timeoutSignal.aborted ? "The artifact upload authorization timed out" : "The artifact upload could not start",
|
|
28872
|
+
cause
|
|
28873
|
+
);
|
|
28874
|
+
}
|
|
28875
|
+
if (!created.ok) {
|
|
28876
|
+
await created.body?.cancel();
|
|
28877
|
+
throw uploadError("artifact_upload_rejected", "The Relay rejected the artifact upload");
|
|
28878
|
+
}
|
|
28879
|
+
const authorization = await readAuthorization(created);
|
|
28880
|
+
let uploaded;
|
|
28881
|
+
try {
|
|
28882
|
+
uploaded = await putContent(
|
|
28883
|
+
sessionArtifactUrl(
|
|
28884
|
+
origin,
|
|
28885
|
+
sessionId,
|
|
28886
|
+
`artifacts/${encodeURIComponent(authorization.artifactId)}/content`,
|
|
28887
|
+
token
|
|
28888
|
+
),
|
|
28889
|
+
authorization,
|
|
28890
|
+
image.bytes,
|
|
28891
|
+
requestSignal
|
|
28892
|
+
);
|
|
28893
|
+
} catch (cause) {
|
|
28894
|
+
signal.throwIfAborted();
|
|
28895
|
+
throw uploadError(
|
|
28896
|
+
timeoutSignal.aborted ? "artifact_upload_timeout" : "artifact_upload_failed",
|
|
28897
|
+
timeoutSignal.aborted ? "The artifact upload timed out" : "The artifact content could not be uploaded",
|
|
28898
|
+
cause
|
|
28899
|
+
);
|
|
28900
|
+
}
|
|
28901
|
+
if (!uploaded.ok) {
|
|
28902
|
+
await uploaded.body?.cancel();
|
|
28903
|
+
throw uploadError("artifact_upload_rejected", "The Relay rejected the artifact content");
|
|
28904
|
+
}
|
|
28905
|
+
try {
|
|
28906
|
+
const available = decodeMobiusAvailableArtifact(await readJson(uploaded));
|
|
28907
|
+
return new UploadedRuntimeArtifact(
|
|
28908
|
+
available.artifactId,
|
|
28909
|
+
available.name,
|
|
28910
|
+
available.mediaType,
|
|
28911
|
+
available.byteLength,
|
|
28912
|
+
available.sha256
|
|
28913
|
+
);
|
|
28914
|
+
} catch (cause) {
|
|
28915
|
+
translateSdkError(cause);
|
|
28916
|
+
}
|
|
28917
|
+
}
|
|
28918
|
+
|
|
28919
|
+
// src/authorization/workspace-directory.ts
|
|
28920
|
+
import { readdir, realpath as realpath8, stat as stat8 } from "node:fs/promises";
|
|
28921
|
+
import { homedir as homedir2 } from "node:os";
|
|
28922
|
+
import { basename as basename3, dirname as dirname6, isAbsolute as isAbsolute9, join as join15, normalize as normalize3, relative as relative5 } from "node:path";
|
|
28923
|
+
var WorkspaceDirectoryListing = class {
|
|
28924
|
+
directoryId;
|
|
28925
|
+
directoryLabel;
|
|
28926
|
+
entries;
|
|
28927
|
+
parentDirectoryId;
|
|
28928
|
+
constructor(directoryId2, directoryLabel, entries, parentDirectoryId) {
|
|
28929
|
+
this.directoryId = directoryId2;
|
|
28930
|
+
this.directoryLabel = directoryLabel;
|
|
28931
|
+
this.entries = entries;
|
|
28932
|
+
this.parentDirectoryId = parentDirectoryId;
|
|
28933
|
+
}
|
|
28934
|
+
};
|
|
28935
|
+
function encodePath(path2) {
|
|
28936
|
+
const encoded = Buffer.from(path2, "utf8").toString("base64url");
|
|
28937
|
+
if (encoded.length === 0 || encoded.length > 2e3) {
|
|
28938
|
+
throw new LocalAuthorizationError("The local directory path is too long to select");
|
|
28939
|
+
}
|
|
28940
|
+
return `path-${encoded}`;
|
|
28941
|
+
}
|
|
28942
|
+
function decodePath(value, prefix) {
|
|
28943
|
+
const encoded = value.slice(prefix.length);
|
|
28944
|
+
if (encoded.length === 0 || encoded.length > 2e3 || !/^[a-zA-Z0-9_-]+$/.test(encoded)) {
|
|
28945
|
+
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
28946
|
+
}
|
|
28947
|
+
const decoded = Buffer.from(encoded, "base64url").toString("utf8");
|
|
28948
|
+
if (Buffer.from(decoded, "utf8").toString("base64url") !== encoded || decoded.includes("\0") || normalize3(decoded) !== decoded) {
|
|
28949
|
+
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
28950
|
+
}
|
|
28951
|
+
return decoded;
|
|
28952
|
+
}
|
|
28953
|
+
var WorkspaceDirectoryService = class {
|
|
28954
|
+
#bindingId;
|
|
28955
|
+
#defaultWorkspace;
|
|
28956
|
+
constructor(bindingId, defaultWorkspace) {
|
|
28957
|
+
this.#bindingId = bindingId;
|
|
28958
|
+
this.#defaultWorkspace = defaultWorkspace;
|
|
28959
|
+
}
|
|
28960
|
+
authorizeMachine = (bindingId) => {
|
|
28961
|
+
if (bindingId !== this.#bindingId) {
|
|
28962
|
+
throw new LocalAuthorizationError("The runtime binding is not authorized");
|
|
28963
|
+
}
|
|
28964
|
+
};
|
|
28965
|
+
requestedPath = (id) => {
|
|
28966
|
+
if (id === "default") {
|
|
28967
|
+
return this.#defaultWorkspace;
|
|
28968
|
+
}
|
|
28969
|
+
if (id === "home") {
|
|
28970
|
+
return homedir2();
|
|
28971
|
+
}
|
|
28972
|
+
if (id.startsWith("path-")) {
|
|
28973
|
+
const path2 = decodePath(id, "path-");
|
|
28974
|
+
if (isAbsolute9(path2)) {
|
|
28975
|
+
return path2;
|
|
28976
|
+
}
|
|
28977
|
+
}
|
|
28978
|
+
throw new LocalAuthorizationError("The directory identifier is invalid");
|
|
28979
|
+
};
|
|
28980
|
+
resolvePath = async (requested, signal) => {
|
|
28981
|
+
signal.throwIfAborted();
|
|
28982
|
+
if (!isAbsolute9(requested) || requested.includes("\0") || normalize3(requested) !== requested) {
|
|
28983
|
+
throw new LocalAuthorizationError("The local directory path is invalid");
|
|
28984
|
+
}
|
|
28985
|
+
try {
|
|
28986
|
+
const target = await realpath8(requested);
|
|
28987
|
+
signal.throwIfAborted();
|
|
28988
|
+
const metadata = await stat8(target);
|
|
28989
|
+
signal.throwIfAborted();
|
|
28990
|
+
if (!isAbsolute9(target) || normalize3(target) !== target || !metadata.isDirectory()) {
|
|
28991
|
+
throw new LocalAuthorizationError("The selected location is not a directory");
|
|
28992
|
+
}
|
|
28993
|
+
return target;
|
|
28994
|
+
} catch (cause) {
|
|
28995
|
+
signal.throwIfAborted();
|
|
28996
|
+
if (cause instanceof LocalAuthorizationError) {
|
|
28997
|
+
throw cause;
|
|
28998
|
+
}
|
|
28999
|
+
throw new LocalAuthorizationError("This directory is missing or unavailable to your user account", {
|
|
29000
|
+
cause
|
|
29001
|
+
});
|
|
29002
|
+
}
|
|
29003
|
+
};
|
|
29004
|
+
label = (path2) => {
|
|
29005
|
+
const suffix = relative5(homedir2(), path2);
|
|
29006
|
+
return suffix === "" ? "~" : !isAbsolute9(suffix) && suffix !== ".." && !suffix.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) ? `~/${suffix.replaceAll("\\", "/")}` : path2;
|
|
29007
|
+
};
|
|
29008
|
+
identify = async (bindingId, requestedPath, signal) => {
|
|
29009
|
+
this.authorizeMachine(bindingId);
|
|
29010
|
+
const path2 = await this.resolvePath(requestedPath, signal);
|
|
29011
|
+
return {
|
|
29012
|
+
path: path2,
|
|
29013
|
+
directoryId: encodePath(path2),
|
|
29014
|
+
name: basename3(path2) || path2,
|
|
29015
|
+
label: this.label(path2)
|
|
28292
29016
|
};
|
|
28293
29017
|
};
|
|
28294
29018
|
resolve = async (bindingId, id, signal) => {
|
|
@@ -28381,7 +29105,7 @@ var EmbeddedBotContextApplicator = class {
|
|
|
28381
29105
|
|
|
28382
29106
|
// src/native-sessions/service.ts
|
|
28383
29107
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
28384
|
-
import { basename as
|
|
29108
|
+
import { basename as basename4 } from "node:path";
|
|
28385
29109
|
|
|
28386
29110
|
// src/native-sessions/codex-history.ts
|
|
28387
29111
|
import { spawn as spawn4 } from "node:child_process";
|
|
@@ -28414,7 +29138,6 @@ function decodeHistory(thread, value) {
|
|
|
28414
29138
|
const page = turnsSchema.parse(value);
|
|
28415
29139
|
const messages = [];
|
|
28416
29140
|
let characters = 0;
|
|
28417
|
-
let imageCharacters = 0;
|
|
28418
29141
|
let truncated = page.nextCursor != null;
|
|
28419
29142
|
for (const turn of page.data.toReversed()) {
|
|
28420
29143
|
for (const item of turn.items) {
|
|
@@ -28422,22 +29145,19 @@ function decodeHistory(thread, value) {
|
|
|
28422
29145
|
let message;
|
|
28423
29146
|
if (type === "userMessage") {
|
|
28424
29147
|
const { content } = userMessageSchema.parse(item);
|
|
28425
|
-
const
|
|
28426
|
-
|
|
28427
|
-
|
|
28428
|
-
|
|
28429
|
-
|
|
28430
|
-
|
|
28431
|
-
|
|
28432
|
-
|
|
28433
|
-
|
|
28434
|
-
|
|
28435
|
-
}).join("")
|
|
28436
|
-
);
|
|
29148
|
+
const text2 = content.map((block) => {
|
|
29149
|
+
const { type: type2 } = itemTypeSchema.parse(block);
|
|
29150
|
+
if (type2 === "text") {
|
|
29151
|
+
return textSchema.parse(block).text;
|
|
29152
|
+
}
|
|
29153
|
+
if (type2 === "image") {
|
|
29154
|
+
return `[@image](${imageSchema.parse(block).url})`;
|
|
29155
|
+
}
|
|
29156
|
+
return "[Attachment]";
|
|
29157
|
+
}).join("");
|
|
28437
29158
|
message = {
|
|
28438
29159
|
role: "user",
|
|
28439
|
-
text:
|
|
28440
|
-
...parsed.images.length > 0 ? { images: parsed.images } : {}
|
|
29160
|
+
text: text2
|
|
28441
29161
|
};
|
|
28442
29162
|
} else if (type === "agentMessage") {
|
|
28443
29163
|
const agent = agentMessageSchema.parse(item);
|
|
@@ -28455,12 +29175,10 @@ function decodeHistory(thread, value) {
|
|
|
28455
29175
|
truncated ||= text.length < message.text.length;
|
|
28456
29176
|
messages.push({ ...message, text });
|
|
28457
29177
|
characters += text.length;
|
|
28458
|
-
|
|
28459
|
-
while (messages.length > SESSION_HISTORY_PREVIEW_MESSAGE_LIMIT || characters > SESSION_HISTORY_CHARACTER_LIMIT || imageCharacters > SESSION_HISTORY_IMAGE_CHARACTER_LIMIT) {
|
|
29178
|
+
while (messages.length > SESSION_HISTORY_PREVIEW_MESSAGE_LIMIT || characters > SESSION_HISTORY_CHARACTER_LIMIT) {
|
|
28460
29179
|
const removed = messages.shift();
|
|
28461
29180
|
if (removed !== void 0) {
|
|
28462
29181
|
characters -= removed.text.length;
|
|
28463
|
-
imageCharacters -= (removed.images ?? []).reduce((size, image) => size + image.data.length, 0);
|
|
28464
29182
|
}
|
|
28465
29183
|
truncated = true;
|
|
28466
29184
|
}
|
|
@@ -28618,7 +29336,11 @@ async function readCodexHistory(agent, cwd, nativeSessionId, signal) {
|
|
|
28618
29336
|
params: { clientInfo: { name: "mobius_history", version: "1.0.0" } }
|
|
28619
29337
|
});
|
|
28620
29338
|
}
|
|
28621
|
-
|
|
29339
|
+
const snapshot = await response.promise;
|
|
29340
|
+
return {
|
|
29341
|
+
...snapshot,
|
|
29342
|
+
history: await embedLocalHistoryImages(snapshot.history, [cwd, snapshot.cwd], signal)
|
|
29343
|
+
};
|
|
28622
29344
|
} finally {
|
|
28623
29345
|
clearTimeout(timeout);
|
|
28624
29346
|
signal.removeEventListener("abort", abort);
|
|
@@ -28872,7 +29594,7 @@ var NativeSessionService = class {
|
|
|
28872
29594
|
}
|
|
28873
29595
|
resolvedPaths.add(path2);
|
|
28874
29596
|
additionalDirectories.push(path2);
|
|
28875
|
-
additionalEntries.push({ directoryId: directoryId2, name:
|
|
29597
|
+
additionalEntries.push({ directoryId: directoryId2, name: basename4(path2) });
|
|
28876
29598
|
}
|
|
28877
29599
|
const listing = await this.#directories.list(this.#config.bindingId, command.directoryId, signal);
|
|
28878
29600
|
const opened = await this.#sessions.forkSessionAtTurn(
|
|
@@ -29011,13 +29733,13 @@ var NativeSessionService = class {
|
|
|
29011
29733
|
};
|
|
29012
29734
|
|
|
29013
29735
|
// src/prompt-artifact-resolver.ts
|
|
29014
|
-
import { createHash as
|
|
29015
|
-
import { fetch as
|
|
29736
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
29737
|
+
import { fetch as fetch6 } from "undici";
|
|
29016
29738
|
var ARTIFACT_SCHEME = "mobius-artifact:";
|
|
29017
29739
|
var ARTIFACT_DOWNLOAD_TIMEOUT_MILLISECONDS = 2e4;
|
|
29018
29740
|
var MAX_AGENT_IMAGE_BASE64_LENGTH = 4e6;
|
|
29019
29741
|
var MAX_AGENT_RESOURCE_BYTE_LENGTH = 1e6;
|
|
29020
|
-
var
|
|
29742
|
+
var IDENTIFIER_PATTERN8 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
29021
29743
|
var PromptArtifactError = class extends Error {
|
|
29022
29744
|
code;
|
|
29023
29745
|
constructor(code, message, options = {}) {
|
|
@@ -29060,14 +29782,13 @@ function parseReference(resource) {
|
|
|
29060
29782
|
const encodedByteLength2 = url2.searchParams.get("byteLength") ?? "";
|
|
29061
29783
|
const sha256 = url2.searchParams.get("sha256") ?? "";
|
|
29062
29784
|
const byteLength = Number(encodedByteLength2);
|
|
29063
|
-
if (url2.protocol !== ARTIFACT_SCHEME || url2.hash.length > 0 || resource.type !== "link" || resource.text.length > 0 || !
|
|
29785
|
+
if (url2.protocol !== ARTIFACT_SCHEME || url2.hash.length > 0 || resource.type !== "link" || resource.text.length > 0 || !IDENTIFIER_PATTERN8.test(artifactId) || keys.length !== 2 || keys[0] !== "byteLength" || keys[1] !== "sha256" || !/^[1-9][0-9]*$/.test(encodedByteLength2) || !Number.isSafeInteger(byteLength) || !/^[a-f0-9]{64}$/.test(sha256)) {
|
|
29064
29786
|
throw new PromptArtifactError("artifact_reference_invalid", "The prompt artifact reference is invalid");
|
|
29065
29787
|
}
|
|
29066
29788
|
return new PromptArtifactReference(artifactId, byteLength, sha256, resource);
|
|
29067
29789
|
}
|
|
29068
29790
|
function downloadUrl(config2, command, reference) {
|
|
29069
|
-
const url2 =
|
|
29070
|
-
url2.protocol = url2.protocol === "wss:" ? "https:" : "http:";
|
|
29791
|
+
const url2 = relayHttpEndpoint(config2.relayUrl);
|
|
29071
29792
|
let channelPath = "";
|
|
29072
29793
|
if (url2.pathname.endsWith("/daemon")) {
|
|
29073
29794
|
channelPath = url2.pathname.slice(0, -"/daemon".length);
|
|
@@ -29079,7 +29800,6 @@ function downloadUrl(config2, command, reference) {
|
|
|
29079
29800
|
channelPath = `${url2.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}`;
|
|
29080
29801
|
}
|
|
29081
29802
|
url2.pathname = `${channelPath}/sessions/${encodeURIComponent(command.sessionId)}/commands/${encodeURIComponent(command.commandId)}/artifacts/${encodeURIComponent(reference.artifactId)}/content`;
|
|
29082
|
-
url2.searchParams.delete("liveness");
|
|
29083
29803
|
return url2;
|
|
29084
29804
|
}
|
|
29085
29805
|
async function responseBytes(response, expectedByteLength, signal) {
|
|
@@ -29128,9 +29848,13 @@ async function download(config2, command, reference, signal) {
|
|
|
29128
29848
|
const requestSignal = AbortSignal.any([signal, timeoutSignal]);
|
|
29129
29849
|
let response;
|
|
29130
29850
|
try {
|
|
29131
|
-
response = await
|
|
29851
|
+
response = await fetch6(downloadUrl(config2, command, reference), {
|
|
29132
29852
|
dispatcher: environmentProxyDispatcher,
|
|
29133
|
-
headers: {
|
|
29853
|
+
headers: {
|
|
29854
|
+
accept: reference.resource.mimeType,
|
|
29855
|
+
"accept-encoding": "identity",
|
|
29856
|
+
...runtimeAuthorization(config2.relayUrl)
|
|
29857
|
+
},
|
|
29134
29858
|
signal: requestSignal
|
|
29135
29859
|
});
|
|
29136
29860
|
if (!response.ok) {
|
|
@@ -29148,7 +29872,7 @@ async function download(config2, command, reference, signal) {
|
|
|
29148
29872
|
);
|
|
29149
29873
|
}
|
|
29150
29874
|
const bytes = await responseBytes(response, reference.byteLength, requestSignal);
|
|
29151
|
-
if (
|
|
29875
|
+
if (createHash4("sha256").update(bytes).digest("hex") !== reference.sha256) {
|
|
29152
29876
|
throw new PromptArtifactError(
|
|
29153
29877
|
"artifact_integrity_failed",
|
|
29154
29878
|
"The prompt artifact failed integrity validation"
|
|
@@ -29240,12 +29964,8 @@ function connectRelay(url2, signal) {
|
|
|
29240
29964
|
signal.throwIfAborted();
|
|
29241
29965
|
return new Promise((resolve6, reject) => {
|
|
29242
29966
|
const endpoint = new URL(url2);
|
|
29243
|
-
const headers =
|
|
29244
|
-
|
|
29245
|
-
const runtimeCredential = endpoint.searchParams.get("token") ?? "";
|
|
29246
|
-
endpoint.searchParams.delete("token");
|
|
29247
|
-
headers["authorization"] = `Bearer ${runtimeCredential}`;
|
|
29248
|
-
}
|
|
29967
|
+
const headers = runtimeAuthorization(endpoint);
|
|
29968
|
+
endpoint.searchParams.delete("token");
|
|
29249
29969
|
const socket = new WebSocket(endpoint, {
|
|
29250
29970
|
dispatcher: environmentProxyDispatcher,
|
|
29251
29971
|
headers
|
|
@@ -29568,6 +30288,42 @@ var RelayConnectionLiveness = class {
|
|
|
29568
30288
|
import { mkdirSync as mkdirSync3 } from "node:fs";
|
|
29569
30289
|
import { dirname as dirname7 } from "node:path";
|
|
29570
30290
|
import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
|
|
30291
|
+
var DEFAULT_OUTBOX_LIMITS = {
|
|
30292
|
+
criticalEventBytes: 136 * 1024 * 1024,
|
|
30293
|
+
criticalEventCount: 10128,
|
|
30294
|
+
runtimeDeliveryBytes: 64 * 1024 * 1024,
|
|
30295
|
+
runtimeDeliveryCount: 64,
|
|
30296
|
+
standardEventBytes: 128 * 1024 * 1024,
|
|
30297
|
+
standardEventCount: 1e4
|
|
30298
|
+
};
|
|
30299
|
+
var SessionEventOutboxCapacityError = class extends Error {
|
|
30300
|
+
code = "session_event_outbox_full";
|
|
30301
|
+
constructor() {
|
|
30302
|
+
super("The durable Session event outbox is full");
|
|
30303
|
+
this.name = "SessionEventOutboxCapacityError";
|
|
30304
|
+
}
|
|
30305
|
+
};
|
|
30306
|
+
var RuntimeDeliveryInboxCapacityError = class extends Error {
|
|
30307
|
+
code = "runtime_delivery_inbox_full";
|
|
30308
|
+
constructor() {
|
|
30309
|
+
super("The durable Runtime delivery inbox is full");
|
|
30310
|
+
this.name = "RuntimeDeliveryInboxCapacityError";
|
|
30311
|
+
}
|
|
30312
|
+
};
|
|
30313
|
+
var StoredRuntimeDelivery = class {
|
|
30314
|
+
deliveryId;
|
|
30315
|
+
duplicate;
|
|
30316
|
+
payload;
|
|
30317
|
+
sessionId;
|
|
30318
|
+
state;
|
|
30319
|
+
constructor(deliveryId, sessionId, payload, state, duplicate) {
|
|
30320
|
+
this.deliveryId = deliveryId;
|
|
30321
|
+
this.duplicate = duplicate;
|
|
30322
|
+
this.payload = payload;
|
|
30323
|
+
this.sessionId = sessionId;
|
|
30324
|
+
this.state = state;
|
|
30325
|
+
}
|
|
30326
|
+
};
|
|
29571
30327
|
function readPendingEnvelope(row) {
|
|
29572
30328
|
if (typeof row !== "object" || row === null || Array.isArray(row)) {
|
|
29573
30329
|
throw new Error("SQLite returned an invalid session event outbox row");
|
|
@@ -29578,9 +30334,26 @@ function readPendingEnvelope(row) {
|
|
|
29578
30334
|
}
|
|
29579
30335
|
return envelope2;
|
|
29580
30336
|
}
|
|
30337
|
+
function rowNumber(row, field) {
|
|
30338
|
+
const value = typeof row === "object" && row !== null ? Reflect.get(row, field) : void 0;
|
|
30339
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
|
|
30340
|
+
throw new Error(`SQLite returned an invalid ${field} value`);
|
|
30341
|
+
}
|
|
30342
|
+
return value;
|
|
30343
|
+
}
|
|
30344
|
+
function rowString2(row, field) {
|
|
30345
|
+
const value = typeof row === "object" && row !== null ? Reflect.get(row, field) : void 0;
|
|
30346
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
30347
|
+
throw new Error(`SQLite returned an invalid ${field} value`);
|
|
30348
|
+
}
|
|
30349
|
+
return value;
|
|
30350
|
+
}
|
|
29581
30351
|
var SessionEventOutbox = class {
|
|
29582
30352
|
#database;
|
|
29583
|
-
|
|
30353
|
+
#limits;
|
|
30354
|
+
constructor(path2, limits = DEFAULT_OUTBOX_LIMITS) {
|
|
30355
|
+
validateLimits(limits);
|
|
30356
|
+
this.#limits = limits;
|
|
29584
30357
|
mkdirSync3(dirname7(path2), { recursive: true });
|
|
29585
30358
|
this.#database = new DatabaseSync4(path2);
|
|
29586
30359
|
this.#database.exec(`
|
|
@@ -29589,6 +30362,7 @@ var SessionEventOutbox = class {
|
|
|
29589
30362
|
event_id TEXT NOT NULL UNIQUE,
|
|
29590
30363
|
session_id TEXT NOT NULL,
|
|
29591
30364
|
source_key TEXT NOT NULL,
|
|
30365
|
+
byte_length INTEGER NOT NULL,
|
|
29592
30366
|
envelope_json TEXT NOT NULL
|
|
29593
30367
|
) STRICT;
|
|
29594
30368
|
CREATE INDEX IF NOT EXISTS relay_session_event_outbox_order
|
|
@@ -29599,7 +30373,7 @@ var SessionEventOutbox = class {
|
|
|
29599
30373
|
session_id TEXT NOT NULL,
|
|
29600
30374
|
envelope_json TEXT NOT NULL,
|
|
29601
30375
|
rejection_code TEXT NOT NULL CHECK (
|
|
29602
|
-
rejection_code IN ('session_deleted', 'session_not_found')
|
|
30376
|
+
rejection_code IN ('session_deleted', 'session_not_found', 'session_rejected')
|
|
29603
30377
|
)
|
|
29604
30378
|
) STRICT;
|
|
29605
30379
|
CREATE TABLE IF NOT EXISTS relay_session_event_sources (
|
|
@@ -29615,7 +30389,53 @@ var SessionEventOutbox = class {
|
|
|
29615
30389
|
state IN ('dispatching', 'running', 'succeeded', 'failed', 'cancelled')
|
|
29616
30390
|
)
|
|
29617
30391
|
) STRICT;
|
|
30392
|
+
CREATE TABLE IF NOT EXISTS relay_session_event_outbox_state (
|
|
30393
|
+
singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
|
|
30394
|
+
event_count INTEGER NOT NULL,
|
|
30395
|
+
total_bytes INTEGER NOT NULL
|
|
30396
|
+
) STRICT;
|
|
30397
|
+
INSERT OR IGNORE INTO relay_session_event_outbox_state (
|
|
30398
|
+
singleton, event_count, total_bytes
|
|
30399
|
+
) VALUES (1, 0, 0);
|
|
30400
|
+
CREATE TABLE IF NOT EXISTS relay_runtime_deliveries (
|
|
30401
|
+
delivery_id TEXT PRIMARY KEY,
|
|
30402
|
+
session_id TEXT NOT NULL,
|
|
30403
|
+
payload_json TEXT NOT NULL,
|
|
30404
|
+
payload_bytes INTEGER NOT NULL,
|
|
30405
|
+
state TEXT NOT NULL CHECK (
|
|
30406
|
+
state IN ('received', 'relay_committed', 'processed')
|
|
30407
|
+
),
|
|
30408
|
+
received_at INTEGER NOT NULL
|
|
30409
|
+
) STRICT;
|
|
29618
30410
|
`);
|
|
30411
|
+
const deadLetterTable = this.#database.prepare(
|
|
30412
|
+
`SELECT sql FROM sqlite_master
|
|
30413
|
+
WHERE type = 'table' AND name = 'relay_session_event_dead_letters'`
|
|
30414
|
+
).get();
|
|
30415
|
+
const deadLetterSql = typeof deadLetterTable === "object" && deadLetterTable !== null ? Reflect.get(deadLetterTable, "sql") : void 0;
|
|
30416
|
+
if (typeof deadLetterSql !== "string" || !deadLetterSql.includes("'session_rejected'")) {
|
|
30417
|
+
this.#database.exec(`
|
|
30418
|
+
BEGIN IMMEDIATE;
|
|
30419
|
+
ALTER TABLE relay_session_event_dead_letters
|
|
30420
|
+
RENAME TO relay_session_event_dead_letters_legacy;
|
|
30421
|
+
CREATE TABLE relay_session_event_dead_letters (
|
|
30422
|
+
ordinal INTEGER PRIMARY KEY,
|
|
30423
|
+
event_id TEXT NOT NULL UNIQUE,
|
|
30424
|
+
session_id TEXT NOT NULL,
|
|
30425
|
+
envelope_json TEXT NOT NULL,
|
|
30426
|
+
rejection_code TEXT NOT NULL CHECK (
|
|
30427
|
+
rejection_code IN ('session_deleted', 'session_not_found', 'session_rejected')
|
|
30428
|
+
)
|
|
30429
|
+
) STRICT;
|
|
30430
|
+
INSERT INTO relay_session_event_dead_letters (
|
|
30431
|
+
ordinal, event_id, session_id, envelope_json, rejection_code
|
|
30432
|
+
)
|
|
30433
|
+
SELECT ordinal, event_id, session_id, envelope_json, rejection_code
|
|
30434
|
+
FROM relay_session_event_dead_letters_legacy;
|
|
30435
|
+
DROP TABLE relay_session_event_dead_letters_legacy;
|
|
30436
|
+
COMMIT;
|
|
30437
|
+
`);
|
|
30438
|
+
}
|
|
29619
30439
|
const outboxColumns = this.#database.prepare("PRAGMA table_info(relay_session_event_outbox)").all();
|
|
29620
30440
|
const hasSourceKey = outboxColumns.some(
|
|
29621
30441
|
(column) => typeof column === "object" && column !== null && Reflect.get(column, "name") === "source_key"
|
|
@@ -29626,6 +30446,15 @@ var SessionEventOutbox = class {
|
|
|
29626
30446
|
ADD COLUMN source_key TEXT NOT NULL DEFAULT '';
|
|
29627
30447
|
`);
|
|
29628
30448
|
}
|
|
30449
|
+
const hasByteLength = outboxColumns.some(
|
|
30450
|
+
(column) => typeof column === "object" && column !== null && Reflect.get(column, "name") === "byte_length"
|
|
30451
|
+
);
|
|
30452
|
+
if (!hasByteLength) {
|
|
30453
|
+
this.#database.exec(`
|
|
30454
|
+
ALTER TABLE relay_session_event_outbox
|
|
30455
|
+
ADD COLUMN byte_length INTEGER NOT NULL DEFAULT 0;
|
|
30456
|
+
`);
|
|
30457
|
+
}
|
|
29629
30458
|
this.#database.exec(`
|
|
29630
30459
|
UPDATE relay_session_event_outbox
|
|
29631
30460
|
SET source_key = CASE json_extract(envelope_json, '$.source.kind')
|
|
@@ -29634,6 +30463,16 @@ var SessionEventOutbox = class {
|
|
|
29634
30463
|
ELSE 'runtime:' || session_id
|
|
29635
30464
|
END
|
|
29636
30465
|
WHERE source_key = '';
|
|
30466
|
+
UPDATE relay_session_event_outbox
|
|
30467
|
+
SET byte_length = length(CAST(envelope_json AS BLOB))
|
|
30468
|
+
WHERE byte_length = 0;
|
|
30469
|
+
UPDATE relay_session_event_outbox_state
|
|
30470
|
+
SET event_count = (SELECT COUNT(*) FROM relay_session_event_outbox),
|
|
30471
|
+
total_bytes = (
|
|
30472
|
+
SELECT COALESCE(SUM(byte_length), 0)
|
|
30473
|
+
FROM relay_session_event_outbox
|
|
30474
|
+
)
|
|
30475
|
+
WHERE singleton = 1;
|
|
29637
30476
|
CREATE INDEX IF NOT EXISTS relay_session_event_outbox_source_order
|
|
29638
30477
|
ON relay_session_event_outbox(source_key, ordinal);
|
|
29639
30478
|
`);
|
|
@@ -29694,13 +30533,19 @@ var SessionEventOutbox = class {
|
|
|
29694
30533
|
const state = typeof row === "object" && row !== null ? Reflect.get(row, "state") : void 0;
|
|
29695
30534
|
return state === "succeeded" || state === "failed" || state === "cancelled";
|
|
29696
30535
|
};
|
|
29697
|
-
acknowledge = (acknowledgement) => this.#
|
|
29698
|
-
`DELETE FROM relay_session_event_outbox
|
|
29699
|
-
WHERE event_id = ? AND session_id = ?`
|
|
29700
|
-
).run(acknowledgement.eventId, acknowledgement.sessionId).changes === 1;
|
|
30536
|
+
acknowledge = (acknowledgement) => this.#removeAcknowledgedEvent(acknowledgement.eventId, acknowledgement.sessionId);
|
|
29701
30537
|
quarantine = (rejection) => {
|
|
29702
30538
|
this.#database.exec("BEGIN IMMEDIATE");
|
|
29703
30539
|
try {
|
|
30540
|
+
const stored = this.#database.prepare(
|
|
30541
|
+
`SELECT byte_length FROM relay_session_event_outbox
|
|
30542
|
+
WHERE event_id = ? AND session_id = ?`
|
|
30543
|
+
).get(rejection.eventId, rejection.sessionId);
|
|
30544
|
+
if (stored === void 0) {
|
|
30545
|
+
this.#database.exec("COMMIT");
|
|
30546
|
+
return false;
|
|
30547
|
+
}
|
|
30548
|
+
const byteLength = rowNumber(stored, "byte_length");
|
|
29704
30549
|
const insertion = this.#database.prepare(
|
|
29705
30550
|
`INSERT INTO relay_session_event_dead_letters (
|
|
29706
30551
|
ordinal, event_id, session_id, envelope_json, rejection_code
|
|
@@ -29720,6 +30565,7 @@ var SessionEventOutbox = class {
|
|
|
29720
30565
|
if (deletion.changes !== 1) {
|
|
29721
30566
|
throw new Error("The rejected session event could not be removed from the durable outbox");
|
|
29722
30567
|
}
|
|
30568
|
+
this.#decrementEventState(byteLength);
|
|
29723
30569
|
this.#database.exec("COMMIT");
|
|
29724
30570
|
return true;
|
|
29725
30571
|
} catch (error61) {
|
|
@@ -29731,7 +30577,129 @@ var SessionEventOutbox = class {
|
|
|
29731
30577
|
this.#database.close();
|
|
29732
30578
|
};
|
|
29733
30579
|
enqueue = (sessionId, payload, attemptId = null) => {
|
|
29734
|
-
|
|
30580
|
+
return this.#enqueueBounded(
|
|
30581
|
+
sessionId,
|
|
30582
|
+
payload,
|
|
30583
|
+
attemptId ?? "",
|
|
30584
|
+
this.#limits.standardEventCount,
|
|
30585
|
+
this.#limits.standardEventBytes
|
|
30586
|
+
);
|
|
30587
|
+
};
|
|
30588
|
+
enqueueCritical = (sessionId, payload, attemptId = "") => this.#enqueueBounded(
|
|
30589
|
+
sessionId,
|
|
30590
|
+
payload,
|
|
30591
|
+
attemptId,
|
|
30592
|
+
this.#limits.criticalEventCount,
|
|
30593
|
+
this.#limits.criticalEventBytes
|
|
30594
|
+
);
|
|
30595
|
+
claimRuntimeDelivery = (delivery) => {
|
|
30596
|
+
const payloadBytes = new TextEncoder().encode(delivery.payload).byteLength;
|
|
30597
|
+
this.#database.exec("BEGIN IMMEDIATE");
|
|
30598
|
+
try {
|
|
30599
|
+
const existing = this.#database.prepare(
|
|
30600
|
+
`SELECT session_id, payload_json, state
|
|
30601
|
+
FROM relay_runtime_deliveries
|
|
30602
|
+
WHERE delivery_id = ?`
|
|
30603
|
+
).get(delivery.deliveryId);
|
|
30604
|
+
if (existing !== void 0) {
|
|
30605
|
+
const sessionId = rowString2(existing, "session_id");
|
|
30606
|
+
const payload = rowString2(existing, "payload_json");
|
|
30607
|
+
const state = runtimeDeliveryState(existing);
|
|
30608
|
+
if (sessionId !== delivery.sessionId || payload !== delivery.payload) {
|
|
30609
|
+
throw new Error("The Runtime delivery identity conflicts with its durable receipt");
|
|
30610
|
+
}
|
|
30611
|
+
this.#database.exec("COMMIT");
|
|
30612
|
+
return new StoredRuntimeDelivery(delivery.deliveryId, sessionId, payload, state, true);
|
|
30613
|
+
}
|
|
30614
|
+
const usage = this.#database.prepare(
|
|
30615
|
+
`SELECT COUNT(*) AS delivery_count,
|
|
30616
|
+
COALESCE(SUM(payload_bytes), 0) AS delivery_bytes
|
|
30617
|
+
FROM relay_runtime_deliveries`
|
|
30618
|
+
).get();
|
|
30619
|
+
if (rowNumber(usage, "delivery_count") + 1 > this.#limits.runtimeDeliveryCount || rowNumber(usage, "delivery_bytes") + payloadBytes > this.#limits.runtimeDeliveryBytes) {
|
|
30620
|
+
throw new RuntimeDeliveryInboxCapacityError();
|
|
30621
|
+
}
|
|
30622
|
+
this.#database.prepare(
|
|
30623
|
+
`INSERT INTO relay_runtime_deliveries (
|
|
30624
|
+
delivery_id, session_id, payload_json, payload_bytes, state, received_at
|
|
30625
|
+
) VALUES (?, ?, ?, ?, 'received', ?)`
|
|
30626
|
+
).run(delivery.deliveryId, delivery.sessionId, delivery.payload, payloadBytes, Date.now());
|
|
30627
|
+
this.#database.exec("COMMIT");
|
|
30628
|
+
return new StoredRuntimeDelivery(
|
|
30629
|
+
delivery.deliveryId,
|
|
30630
|
+
delivery.sessionId,
|
|
30631
|
+
delivery.payload,
|
|
30632
|
+
"received",
|
|
30633
|
+
false
|
|
30634
|
+
);
|
|
30635
|
+
} catch (error61) {
|
|
30636
|
+
this.#database.exec("ROLLBACK");
|
|
30637
|
+
throw error61;
|
|
30638
|
+
}
|
|
30639
|
+
};
|
|
30640
|
+
markRuntimeDeliveryCommitted = (deliveryId, sessionId) => {
|
|
30641
|
+
this.#database.exec("BEGIN IMMEDIATE");
|
|
30642
|
+
try {
|
|
30643
|
+
const row = this.#database.prepare(
|
|
30644
|
+
`SELECT state FROM relay_runtime_deliveries
|
|
30645
|
+
WHERE delivery_id = ? AND session_id = ?`
|
|
30646
|
+
).get(deliveryId, sessionId);
|
|
30647
|
+
if (row === void 0) {
|
|
30648
|
+
this.#database.exec("COMMIT");
|
|
30649
|
+
return false;
|
|
30650
|
+
}
|
|
30651
|
+
const state = runtimeDeliveryState(row);
|
|
30652
|
+
if (state === "processed") {
|
|
30653
|
+
this.#database.prepare(`DELETE FROM relay_runtime_deliveries WHERE delivery_id = ?`).run(deliveryId);
|
|
30654
|
+
} else if (state === "received") {
|
|
30655
|
+
this.#database.prepare(`UPDATE relay_runtime_deliveries SET state = 'relay_committed' WHERE delivery_id = ?`).run(deliveryId);
|
|
30656
|
+
}
|
|
30657
|
+
this.#database.exec("COMMIT");
|
|
30658
|
+
return true;
|
|
30659
|
+
} catch (error61) {
|
|
30660
|
+
this.#database.exec("ROLLBACK");
|
|
30661
|
+
throw error61;
|
|
30662
|
+
}
|
|
30663
|
+
};
|
|
30664
|
+
markRuntimeDeliveryProcessed = (deliveryId, sessionId) => {
|
|
30665
|
+
this.#database.exec("BEGIN IMMEDIATE");
|
|
30666
|
+
try {
|
|
30667
|
+
const row = this.#database.prepare(
|
|
30668
|
+
`SELECT state FROM relay_runtime_deliveries
|
|
30669
|
+
WHERE delivery_id = ? AND session_id = ?`
|
|
30670
|
+
).get(deliveryId, sessionId);
|
|
30671
|
+
if (row === void 0) {
|
|
30672
|
+
this.#database.exec("COMMIT");
|
|
30673
|
+
return false;
|
|
30674
|
+
}
|
|
30675
|
+
const state = runtimeDeliveryState(row);
|
|
30676
|
+
if (state === "relay_committed") {
|
|
30677
|
+
this.#database.prepare(`DELETE FROM relay_runtime_deliveries WHERE delivery_id = ?`).run(deliveryId);
|
|
30678
|
+
} else if (state === "received") {
|
|
30679
|
+
this.#database.prepare(`UPDATE relay_runtime_deliveries SET state = 'processed' WHERE delivery_id = ?`).run(deliveryId);
|
|
30680
|
+
}
|
|
30681
|
+
this.#database.exec("COMMIT");
|
|
30682
|
+
return true;
|
|
30683
|
+
} catch (error61) {
|
|
30684
|
+
this.#database.exec("ROLLBACK");
|
|
30685
|
+
throw error61;
|
|
30686
|
+
}
|
|
30687
|
+
};
|
|
30688
|
+
runtimeDeliveries = () => this.#database.prepare(
|
|
30689
|
+
`SELECT delivery_id, session_id, payload_json, state
|
|
30690
|
+
FROM relay_runtime_deliveries
|
|
30691
|
+
ORDER BY received_at, delivery_id`
|
|
30692
|
+
).all().map(
|
|
30693
|
+
(row) => new StoredRuntimeDelivery(
|
|
30694
|
+
rowString2(row, "delivery_id"),
|
|
30695
|
+
rowString2(row, "session_id"),
|
|
30696
|
+
rowString2(row, "payload_json"),
|
|
30697
|
+
runtimeDeliveryState(row),
|
|
30698
|
+
true
|
|
30699
|
+
)
|
|
30700
|
+
);
|
|
30701
|
+
#enqueueBounded = (sessionId, payload, attemptId, maximumEventCount, maximumEventBytes) => {
|
|
30702
|
+
const sourceKey = attemptId.length === 0 ? `runtime:${sessionId}` : `attempt:${sessionId}:${attemptId}`;
|
|
29735
30703
|
this.#database.exec("BEGIN IMMEDIATE");
|
|
29736
30704
|
try {
|
|
29737
30705
|
const row = this.#database.prepare(
|
|
@@ -29748,13 +30716,22 @@ var SessionEventOutbox = class {
|
|
|
29748
30716
|
kind: SESSION_EVENT_KIND,
|
|
29749
30717
|
payload,
|
|
29750
30718
|
sessionId,
|
|
29751
|
-
source: attemptId ===
|
|
30719
|
+
source: attemptId.length === 0 ? { kind: "runtime", sourceSeq: nextSourceSeq.toString() } : {
|
|
29752
30720
|
attemptId,
|
|
29753
30721
|
kind: "attempt",
|
|
29754
30722
|
sourceSeq: nextSourceSeq.toString()
|
|
29755
30723
|
}
|
|
29756
30724
|
};
|
|
29757
30725
|
const encoded = encodeSessionEventEnvelope(envelope2);
|
|
30726
|
+
const byteLength = new TextEncoder().encode(encoded).byteLength;
|
|
30727
|
+
const state = this.#database.prepare(
|
|
30728
|
+
`SELECT event_count, total_bytes
|
|
30729
|
+
FROM relay_session_event_outbox_state
|
|
30730
|
+
WHERE singleton = 1`
|
|
30731
|
+
).get();
|
|
30732
|
+
if (rowNumber(state, "event_count") + 1 > maximumEventCount || rowNumber(state, "total_bytes") + byteLength > maximumEventBytes) {
|
|
30733
|
+
throw new SessionEventOutboxCapacityError();
|
|
30734
|
+
}
|
|
29758
30735
|
this.#database.prepare(
|
|
29759
30736
|
`INSERT INTO relay_session_event_sources (
|
|
29760
30737
|
source_key, next_source_seq
|
|
@@ -29764,9 +30741,15 @@ var SessionEventOutbox = class {
|
|
|
29764
30741
|
).run(sourceKey, nextSourceSeq + 1);
|
|
29765
30742
|
this.#database.prepare(
|
|
29766
30743
|
`INSERT INTO relay_session_event_outbox (
|
|
29767
|
-
event_id, session_id, source_key, envelope_json
|
|
29768
|
-
) VALUES (?, ?, ?, ?)`
|
|
29769
|
-
).run(envelope2.eventId, envelope2.sessionId, sourceKey, encoded);
|
|
30744
|
+
event_id, session_id, source_key, byte_length, envelope_json
|
|
30745
|
+
) VALUES (?, ?, ?, ?, ?)`
|
|
30746
|
+
).run(envelope2.eventId, envelope2.sessionId, sourceKey, byteLength, encoded);
|
|
30747
|
+
this.#database.prepare(
|
|
30748
|
+
`UPDATE relay_session_event_outbox_state
|
|
30749
|
+
SET event_count = event_count + 1,
|
|
30750
|
+
total_bytes = total_bytes + ?
|
|
30751
|
+
WHERE singleton = 1`
|
|
30752
|
+
).run(byteLength);
|
|
29770
30753
|
this.#database.exec("COMMIT");
|
|
29771
30754
|
return encoded;
|
|
29772
30755
|
} catch (error61) {
|
|
@@ -29774,6 +30757,44 @@ var SessionEventOutbox = class {
|
|
|
29774
30757
|
throw error61;
|
|
29775
30758
|
}
|
|
29776
30759
|
};
|
|
30760
|
+
#removeAcknowledgedEvent = (eventId, sessionId) => {
|
|
30761
|
+
this.#database.exec("BEGIN IMMEDIATE");
|
|
30762
|
+
try {
|
|
30763
|
+
const stored = this.#database.prepare(
|
|
30764
|
+
`SELECT byte_length FROM relay_session_event_outbox
|
|
30765
|
+
WHERE event_id = ? AND session_id = ?`
|
|
30766
|
+
).get(eventId, sessionId);
|
|
30767
|
+
if (stored === void 0) {
|
|
30768
|
+
this.#database.exec("COMMIT");
|
|
30769
|
+
return false;
|
|
30770
|
+
}
|
|
30771
|
+
const byteLength = rowNumber(stored, "byte_length");
|
|
30772
|
+
const deletion = this.#database.prepare(
|
|
30773
|
+
`DELETE FROM relay_session_event_outbox
|
|
30774
|
+
WHERE event_id = ? AND session_id = ?`
|
|
30775
|
+
).run(eventId, sessionId);
|
|
30776
|
+
if (deletion.changes !== 1) {
|
|
30777
|
+
throw new Error("The acknowledged session event could not be removed from the durable outbox");
|
|
30778
|
+
}
|
|
30779
|
+
this.#decrementEventState(byteLength);
|
|
30780
|
+
this.#database.exec("COMMIT");
|
|
30781
|
+
return true;
|
|
30782
|
+
} catch (error61) {
|
|
30783
|
+
this.#database.exec("ROLLBACK");
|
|
30784
|
+
throw error61;
|
|
30785
|
+
}
|
|
30786
|
+
};
|
|
30787
|
+
#decrementEventState = (byteLength) => {
|
|
30788
|
+
const result = this.#database.prepare(
|
|
30789
|
+
`UPDATE relay_session_event_outbox_state
|
|
30790
|
+
SET event_count = event_count - 1,
|
|
30791
|
+
total_bytes = total_bytes - ?
|
|
30792
|
+
WHERE singleton = 1 AND event_count > 0 AND total_bytes >= ?`
|
|
30793
|
+
).run(byteLength, byteLength);
|
|
30794
|
+
if (result.changes !== 1) {
|
|
30795
|
+
throw new Error("The Session event outbox capacity state is inconsistent");
|
|
30796
|
+
}
|
|
30797
|
+
};
|
|
29777
30798
|
pending = () => this.#database.prepare(
|
|
29778
30799
|
`SELECT envelope_json
|
|
29779
30800
|
FROM relay_session_event_outbox
|
|
@@ -29800,7 +30821,68 @@ var SessionEventOutbox = class {
|
|
|
29800
30821
|
LIMIT ?`
|
|
29801
30822
|
).all(limit).map(readPendingEnvelope);
|
|
29802
30823
|
};
|
|
30824
|
+
pendingSourceHeads = (limit, excludedEventIds, excludedSourceKeys) => {
|
|
30825
|
+
if (!Number.isSafeInteger(limit) || limit < 1) {
|
|
30826
|
+
throw new Error("Session event replay batch limit must be a positive integer");
|
|
30827
|
+
}
|
|
30828
|
+
const exclusions = [];
|
|
30829
|
+
const parameters = [];
|
|
30830
|
+
if (excludedEventIds.length > 0) {
|
|
30831
|
+
exclusions.push(`event_id NOT IN (${excludedEventIds.map(() => "?").join(", ")})`);
|
|
30832
|
+
parameters.push(...excludedEventIds);
|
|
30833
|
+
}
|
|
30834
|
+
if (excludedSourceKeys.length > 0) {
|
|
30835
|
+
exclusions.push(`source_key NOT IN (${excludedSourceKeys.map(() => "?").join(", ")})`);
|
|
30836
|
+
parameters.push(...excludedSourceKeys);
|
|
30837
|
+
}
|
|
30838
|
+
parameters.push(limit.toString());
|
|
30839
|
+
const where = exclusions.length === 0 ? "" : `WHERE ${exclusions.join(" AND ")}`;
|
|
30840
|
+
return this.#database.prepare(
|
|
30841
|
+
`WITH available_events AS (
|
|
30842
|
+
SELECT ordinal, source_key
|
|
30843
|
+
FROM relay_session_event_outbox
|
|
30844
|
+
${where}
|
|
30845
|
+
), ranked_events AS (
|
|
30846
|
+
SELECT ordinal,
|
|
30847
|
+
ROW_NUMBER() OVER (
|
|
30848
|
+
PARTITION BY source_key
|
|
30849
|
+
ORDER BY ordinal
|
|
30850
|
+
) AS source_position
|
|
30851
|
+
FROM available_events
|
|
30852
|
+
)
|
|
30853
|
+
SELECT outbox.envelope_json
|
|
30854
|
+
FROM ranked_events AS ranked
|
|
30855
|
+
INNER JOIN relay_session_event_outbox AS outbox
|
|
30856
|
+
ON outbox.ordinal = ranked.ordinal
|
|
30857
|
+
WHERE ranked.source_position = 1
|
|
30858
|
+
ORDER BY outbox.ordinal
|
|
30859
|
+
LIMIT ?`
|
|
30860
|
+
).all(...parameters).map(readPendingEnvelope);
|
|
30861
|
+
};
|
|
29803
30862
|
};
|
|
30863
|
+
function validateLimits(limits) {
|
|
30864
|
+
const values = [
|
|
30865
|
+
limits.criticalEventBytes,
|
|
30866
|
+
limits.criticalEventCount,
|
|
30867
|
+
limits.runtimeDeliveryBytes,
|
|
30868
|
+
limits.runtimeDeliveryCount,
|
|
30869
|
+
limits.standardEventBytes,
|
|
30870
|
+
limits.standardEventCount
|
|
30871
|
+
];
|
|
30872
|
+
if (values.some((value) => !Number.isSafeInteger(value) || value < 1)) {
|
|
30873
|
+
throw new Error("Session event outbox limits must be positive integers");
|
|
30874
|
+
}
|
|
30875
|
+
if (limits.criticalEventBytes < limits.standardEventBytes || limits.criticalEventCount < limits.standardEventCount) {
|
|
30876
|
+
throw new Error("Critical Session event capacity must include the standard capacity");
|
|
30877
|
+
}
|
|
30878
|
+
}
|
|
30879
|
+
function runtimeDeliveryState(row) {
|
|
30880
|
+
const state = rowString2(row, "state");
|
|
30881
|
+
if (state !== "received" && state !== "relay_committed" && state !== "processed") {
|
|
30882
|
+
throw new Error("SQLite returned an invalid Runtime delivery state");
|
|
30883
|
+
}
|
|
30884
|
+
return state;
|
|
30885
|
+
}
|
|
29804
30886
|
function isDaemonExecutionState(value) {
|
|
29805
30887
|
return value === "cancelled" || value === "dispatching" || value === "failed" || value === "running" || value === "succeeded";
|
|
29806
30888
|
}
|
|
@@ -29826,10 +30908,23 @@ function botIpcSocketPath() {
|
|
|
29826
30908
|
return join16("/tmp", `mobius-bot-${randomUUID6()}.sock`);
|
|
29827
30909
|
}
|
|
29828
30910
|
var DaemonAcpObserver = class {
|
|
30911
|
+
#config;
|
|
29829
30912
|
#record;
|
|
29830
|
-
constructor(
|
|
29831
|
-
this.#
|
|
30913
|
+
constructor(config2, record3) {
|
|
30914
|
+
this.#config = config2;
|
|
30915
|
+
this.#record = record3;
|
|
29832
30916
|
}
|
|
30917
|
+
importLocalImage = async (sessionId, image, signal) => {
|
|
30918
|
+
try {
|
|
30919
|
+
return (await uploadRuntimeArtifact(this.#config, sessionId, image, signal)).artifactId;
|
|
30920
|
+
} catch (cause) {
|
|
30921
|
+
signal.throwIfAborted();
|
|
30922
|
+
if (cause instanceof Error && cause.name === "AbortError") {
|
|
30923
|
+
throw cause;
|
|
30924
|
+
}
|
|
30925
|
+
return "";
|
|
30926
|
+
}
|
|
30927
|
+
};
|
|
29833
30928
|
onCommands = (event) => {
|
|
29834
30929
|
this.#record(event.sessionId, encodeSessionCommandsUpdatedEvent(event));
|
|
29835
30930
|
return Promise.resolve();
|
|
@@ -30019,8 +31114,7 @@ var ActiveTurnReconciliationError = class extends Error {
|
|
|
30019
31114
|
}
|
|
30020
31115
|
};
|
|
30021
31116
|
function activeTurnReconciliationEndpoint(config2, turn) {
|
|
30022
|
-
const endpoint =
|
|
30023
|
-
endpoint.protocol = endpoint.protocol === "wss:" ? "https:" : "http:";
|
|
31117
|
+
const endpoint = relayHttpEndpoint(config2.relayUrl);
|
|
30024
31118
|
let channelPath = "";
|
|
30025
31119
|
if (endpoint.pathname.endsWith("/daemon")) {
|
|
30026
31120
|
channelPath = endpoint.pathname.slice(0, -"/daemon".length);
|
|
@@ -30032,7 +31126,6 @@ function activeTurnReconciliationEndpoint(config2, turn) {
|
|
|
30032
31126
|
channelPath = `${endpoint.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}`;
|
|
30033
31127
|
}
|
|
30034
31128
|
endpoint.pathname = `${channelPath}/sessions/${encodeURIComponent(turn.command.sessionId)}/attempts/${encodeURIComponent(turn.attemptId)}/reconciliation`;
|
|
30035
|
-
endpoint.searchParams.delete("liveness");
|
|
30036
31129
|
return endpoint;
|
|
30037
31130
|
}
|
|
30038
31131
|
async function reconcileActiveTurn(config2, turn, signal) {
|
|
@@ -30041,10 +31134,10 @@ async function reconcileActiveTurn(config2, turn, signal) {
|
|
|
30041
31134
|
const requestSignal = AbortSignal.any([signal, timeoutSignal]);
|
|
30042
31135
|
let response;
|
|
30043
31136
|
try {
|
|
30044
|
-
response = await
|
|
31137
|
+
response = await fetch7(activeTurnReconciliationEndpoint(config2, turn), {
|
|
30045
31138
|
body: JSON.stringify({ outcome: { kind: "running" } }),
|
|
30046
31139
|
dispatcher: environmentProxyDispatcher,
|
|
30047
|
-
headers: { "content-type": "application/json" },
|
|
31140
|
+
headers: { ...runtimeAuthorization(config2.relayUrl), "content-type": "application/json" },
|
|
30048
31141
|
method: "POST",
|
|
30049
31142
|
signal: requestSignal
|
|
30050
31143
|
});
|
|
@@ -30112,17 +31205,31 @@ var ConnectedDaemonSessionEventState = class extends DaemonSessionEventConnectio
|
|
|
30112
31205
|
}
|
|
30113
31206
|
};
|
|
30114
31207
|
};
|
|
30115
|
-
var SESSION_EVENT_REPLAY_WINDOW =
|
|
31208
|
+
var SESSION_EVENT_REPLAY_WINDOW = 16;
|
|
31209
|
+
var SESSION_EVENT_SOURCE_REPLAY_WINDOW = 4;
|
|
31210
|
+
var SESSION_EVENT_REPLAY_BYTE_LIMIT = 32 * 1024 * 1024;
|
|
31211
|
+
var InFlightSessionEvent = class {
|
|
31212
|
+
byteLength;
|
|
31213
|
+
sourceKey;
|
|
31214
|
+
constructor(sourceKey, byteLength) {
|
|
31215
|
+
this.byteLength = byteLength;
|
|
31216
|
+
this.sourceKey = sourceKey;
|
|
31217
|
+
}
|
|
31218
|
+
};
|
|
31219
|
+
function sessionEventSourceKey(envelope2) {
|
|
31220
|
+
return envelope2.source.kind === "attempt" ? `attempt:${envelope2.sessionId}:${envelope2.source.attemptId}` : `runtime:${envelope2.sessionId}`;
|
|
31221
|
+
}
|
|
30116
31222
|
var DaemonSessionEventPublisher = class {
|
|
30117
31223
|
#outbox;
|
|
30118
|
-
#
|
|
31224
|
+
#inFlightEvents = /* @__PURE__ */ new Map();
|
|
31225
|
+
#inFlightBytes = 0;
|
|
30119
31226
|
#connection = new DisconnectedDaemonSessionEventState();
|
|
30120
31227
|
constructor(outbox) {
|
|
30121
31228
|
this.#outbox = outbox;
|
|
30122
31229
|
}
|
|
30123
31230
|
connect = (socket) => {
|
|
30124
31231
|
this.#connection = new ConnectedDaemonSessionEventState(socket);
|
|
30125
|
-
this.#
|
|
31232
|
+
this.#clearInFlight();
|
|
30126
31233
|
this.#publishNextBatch();
|
|
30127
31234
|
};
|
|
30128
31235
|
disconnect = (socket) => {
|
|
@@ -30130,10 +31237,15 @@ var DaemonSessionEventPublisher = class {
|
|
|
30130
31237
|
return;
|
|
30131
31238
|
}
|
|
30132
31239
|
this.#connection = this.#connection.disconnect(socket);
|
|
30133
|
-
this.#
|
|
31240
|
+
this.#clearInFlight();
|
|
30134
31241
|
};
|
|
30135
31242
|
recordAttempt = (sessionId, payload, attemptId) => {
|
|
30136
|
-
|
|
31243
|
+
const kind = decodeMessageKind(payload);
|
|
31244
|
+
if (kind === SESSION_COMPLETED_KIND || kind === SESSION_FAILED_KIND) {
|
|
31245
|
+
this.#outbox.enqueueCritical(sessionId, payload, attemptId);
|
|
31246
|
+
} else {
|
|
31247
|
+
this.#outbox.enqueue(sessionId, payload, attemptId);
|
|
31248
|
+
}
|
|
30137
31249
|
this.#publishNextBatch();
|
|
30138
31250
|
};
|
|
30139
31251
|
recordRuntime = (sessionId, payload) => {
|
|
@@ -30144,7 +31256,7 @@ var DaemonSessionEventPublisher = class {
|
|
|
30144
31256
|
if (!this.#outbox.acknowledge(acknowledgement)) {
|
|
30145
31257
|
return;
|
|
30146
31258
|
}
|
|
30147
|
-
this.#
|
|
31259
|
+
this.#removeInFlight(acknowledgement.eventId);
|
|
30148
31260
|
this.#publishNextBatch();
|
|
30149
31261
|
};
|
|
30150
31262
|
quarantine = (rejection) => {
|
|
@@ -30152,24 +31264,60 @@ var DaemonSessionEventPublisher = class {
|
|
|
30152
31264
|
if (!quarantined) {
|
|
30153
31265
|
return false;
|
|
30154
31266
|
}
|
|
30155
|
-
this.#
|
|
31267
|
+
this.#removeInFlight(rejection.eventId);
|
|
30156
31268
|
this.#publishNextBatch();
|
|
30157
31269
|
return true;
|
|
30158
31270
|
};
|
|
30159
31271
|
#publishNextBatch = () => {
|
|
30160
|
-
|
|
30161
|
-
|
|
30162
|
-
|
|
30163
|
-
|
|
30164
|
-
|
|
30165
|
-
const
|
|
30166
|
-
|
|
30167
|
-
this.#
|
|
31272
|
+
while (this.#inFlightEvents.size < SESSION_EVENT_REPLAY_WINDOW) {
|
|
31273
|
+
const sourceCounts = /* @__PURE__ */ new Map();
|
|
31274
|
+
for (const inFlight of this.#inFlightEvents.values()) {
|
|
31275
|
+
sourceCounts.set(inFlight.sourceKey, (sourceCounts.get(inFlight.sourceKey) ?? 0) + 1);
|
|
31276
|
+
}
|
|
31277
|
+
const saturatedSources = [...sourceCounts.entries()].filter(([, count]) => count >= SESSION_EVENT_SOURCE_REPLAY_WINDOW).map(([sourceKey]) => sourceKey);
|
|
31278
|
+
const batch = this.#outbox.pendingSourceHeads(
|
|
31279
|
+
SESSION_EVENT_REPLAY_WINDOW - this.#inFlightEvents.size,
|
|
31280
|
+
[...this.#inFlightEvents.keys()],
|
|
31281
|
+
saturatedSources
|
|
31282
|
+
);
|
|
31283
|
+
let sent = 0;
|
|
31284
|
+
for (const encoded of batch) {
|
|
31285
|
+
const envelope2 = decodeSessionEventEnvelope(encoded);
|
|
31286
|
+
const sourceKey = sessionEventSourceKey(envelope2);
|
|
31287
|
+
const sourceCount = sourceCounts.get(sourceKey) ?? 0;
|
|
31288
|
+
if (sourceCount >= SESSION_EVENT_SOURCE_REPLAY_WINDOW) {
|
|
31289
|
+
continue;
|
|
31290
|
+
}
|
|
31291
|
+
const byteLength = new TextEncoder().encode(encoded).byteLength;
|
|
31292
|
+
if (this.#inFlightBytes + byteLength > SESSION_EVENT_REPLAY_BYTE_LIMIT) {
|
|
31293
|
+
continue;
|
|
31294
|
+
}
|
|
31295
|
+
if (!this.#connection.send(encoded)) {
|
|
31296
|
+
this.#clearInFlight();
|
|
31297
|
+
return;
|
|
31298
|
+
}
|
|
31299
|
+
this.#inFlightEvents.set(envelope2.eventId, new InFlightSessionEvent(sourceKey, byteLength));
|
|
31300
|
+
this.#inFlightBytes += byteLength;
|
|
31301
|
+
sourceCounts.set(sourceKey, sourceCount + 1);
|
|
31302
|
+
sent += 1;
|
|
31303
|
+
}
|
|
31304
|
+
if (sent === 0) {
|
|
30168
31305
|
return;
|
|
30169
31306
|
}
|
|
30170
|
-
this.#inFlightEventIds.add(envelope2.eventId);
|
|
30171
31307
|
}
|
|
30172
31308
|
};
|
|
31309
|
+
#removeInFlight = (eventId) => {
|
|
31310
|
+
const inFlight = this.#inFlightEvents.get(eventId);
|
|
31311
|
+
if (inFlight === void 0) {
|
|
31312
|
+
return;
|
|
31313
|
+
}
|
|
31314
|
+
this.#inFlightEvents.delete(eventId);
|
|
31315
|
+
this.#inFlightBytes -= inFlight.byteLength;
|
|
31316
|
+
};
|
|
31317
|
+
#clearInFlight = () => {
|
|
31318
|
+
this.#inFlightEvents.clear();
|
|
31319
|
+
this.#inFlightBytes = 0;
|
|
31320
|
+
};
|
|
30173
31321
|
};
|
|
30174
31322
|
var CoalescingDaemonActivityPublisher = class {
|
|
30175
31323
|
#pending = /* @__PURE__ */ new Map();
|
|
@@ -30302,7 +31450,7 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
|
|
|
30302
31450
|
additionalDirectories.push(directory);
|
|
30303
31451
|
additionalDirectoryEntries.push({
|
|
30304
31452
|
directoryId: additionalDirectoryId,
|
|
30305
|
-
name:
|
|
31453
|
+
name: basename5(directory)
|
|
30306
31454
|
});
|
|
30307
31455
|
}
|
|
30308
31456
|
return new ResolvedSessionDirectories(cwd, additionalDirectories, additionalDirectoryEntries);
|
|
@@ -30421,6 +31569,9 @@ async function executeSessionConfigure(publisher, socket, command, config2, dire
|
|
|
30421
31569
|
})
|
|
30422
31570
|
);
|
|
30423
31571
|
} catch (error61) {
|
|
31572
|
+
if (signal.aborted) {
|
|
31573
|
+
signal.throwIfAborted();
|
|
31574
|
+
}
|
|
30424
31575
|
reportOperationFailure(socket, command.requestId, command.sessionId, error61);
|
|
30425
31576
|
}
|
|
30426
31577
|
}
|
|
@@ -30760,6 +31911,7 @@ async function publishAgentCatalogUntilAvailable(config2, diagnostics, signal, t
|
|
|
30760
31911
|
}
|
|
30761
31912
|
async function runRelayConnection(config2, directories, audit, sessions, installations, installationObserver, nativeSessions, outbox, publisher, grants, contexts, applicator, ipc, activeTurns, activeAttemptIds, connectionEpoch, diagnostics, onConnected, signal, timer) {
|
|
30762
31913
|
const relayUrl = new URL(config2.relayUrl);
|
|
31914
|
+
relayUrl.searchParams.set("deliveryReceipts", "1");
|
|
30763
31915
|
relayUrl.searchParams.set("liveness", "1");
|
|
30764
31916
|
const socket = await connectRelay(relayUrl, signal);
|
|
30765
31917
|
const reconnectingTurns = [...activeTurns.values()];
|
|
@@ -30808,6 +31960,239 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30808
31960
|
closeRelaySocket(socket, code, reason);
|
|
30809
31961
|
rejectConnection(failure);
|
|
30810
31962
|
};
|
|
31963
|
+
const processingDeliveryIds = /* @__PURE__ */ new Set();
|
|
31964
|
+
const processDeliveredPrompt = async (delivery, command, trackActiveAttempt, execute) => {
|
|
31965
|
+
if (command.sessionId !== delivery.sessionId) {
|
|
31966
|
+
throw new Error("Runtime delivery Session identity does not match its payload");
|
|
31967
|
+
}
|
|
31968
|
+
const active = activeTurns.get(command.commandId);
|
|
31969
|
+
if (active !== void 0) {
|
|
31970
|
+
await active.completion;
|
|
31971
|
+
return;
|
|
31972
|
+
}
|
|
31973
|
+
const receipt = outbox.claimExecution(command.commandId, command.sessionId, delivery.payload);
|
|
31974
|
+
if (receipt.kind === "duplicate") {
|
|
31975
|
+
if (receipt.state === "running") {
|
|
31976
|
+
reportFailure(
|
|
31977
|
+
publisher,
|
|
31978
|
+
command,
|
|
31979
|
+
"agent_execution_interrupted",
|
|
31980
|
+
"The local Agent execution was interrupted before it completed",
|
|
31981
|
+
receipt.attemptId
|
|
31982
|
+
);
|
|
31983
|
+
outbox.transitionExecution(command.commandId, "failed");
|
|
31984
|
+
return;
|
|
31985
|
+
}
|
|
31986
|
+
if (receipt.state !== "dispatching") {
|
|
31987
|
+
return;
|
|
31988
|
+
}
|
|
31989
|
+
}
|
|
31990
|
+
const turn = new ActiveDaemonTurn(command, receipt.attemptId);
|
|
31991
|
+
activeTurns.set(command.commandId, turn);
|
|
31992
|
+
if (trackActiveAttempt) {
|
|
31993
|
+
activeAttemptIds.set(command.sessionId, receipt.attemptId);
|
|
31994
|
+
}
|
|
31995
|
+
try {
|
|
31996
|
+
await execute(receipt.attemptId, turn.signal);
|
|
31997
|
+
} finally {
|
|
31998
|
+
activeTurns.delete(command.commandId);
|
|
31999
|
+
if (activeAttemptIds.get(command.sessionId) === receipt.attemptId) {
|
|
32000
|
+
activeAttemptIds.delete(command.sessionId);
|
|
32001
|
+
}
|
|
32002
|
+
turn.finish();
|
|
32003
|
+
}
|
|
32004
|
+
};
|
|
32005
|
+
const processDeliveredPayload = async (delivery) => {
|
|
32006
|
+
const kind = decodeMessageKind(delivery.payload);
|
|
32007
|
+
if (kind === SESSION_CANCEL_KIND) {
|
|
32008
|
+
const cancellation = decodeSessionCancelCommand(delivery.payload);
|
|
32009
|
+
if (cancellation.sessionId !== delivery.sessionId) {
|
|
32010
|
+
throw new Error("Runtime delivery Session identity does not match its payload");
|
|
32011
|
+
}
|
|
32012
|
+
const turn = activeTurns.get(cancellation.commandId);
|
|
32013
|
+
if (turn === void 0 || !turn.matches(cancellation) || !turn.requestCancellation()) {
|
|
32014
|
+
return;
|
|
32015
|
+
}
|
|
32016
|
+
audit.record({
|
|
32017
|
+
commandId: cancellation.commandId,
|
|
32018
|
+
event: "session_cancellation_requested",
|
|
32019
|
+
sessionId: cancellation.sessionId
|
|
32020
|
+
});
|
|
32021
|
+
await sessions.cancelPrompt(cancellation.sessionId);
|
|
32022
|
+
return;
|
|
32023
|
+
}
|
|
32024
|
+
if (kind === SESSION_CONFIGURE_KIND) {
|
|
32025
|
+
const command = decodeSessionConfigureCommand(delivery.payload);
|
|
32026
|
+
if (command.sessionId !== delivery.sessionId) {
|
|
32027
|
+
throw new Error("Runtime delivery Session identity does not match its payload");
|
|
32028
|
+
}
|
|
32029
|
+
await executeSessionConfigure(
|
|
32030
|
+
publisher,
|
|
32031
|
+
socket,
|
|
32032
|
+
command,
|
|
32033
|
+
config2,
|
|
32034
|
+
directories,
|
|
32035
|
+
audit,
|
|
32036
|
+
sessions,
|
|
32037
|
+
connectionController.signal
|
|
32038
|
+
);
|
|
32039
|
+
return;
|
|
32040
|
+
}
|
|
32041
|
+
if (kind === SESSION_PERMISSION_RESPOND_KIND) {
|
|
32042
|
+
const command = decodeSessionPermissionRespondCommand(delivery.payload);
|
|
32043
|
+
if (command.sessionId !== delivery.sessionId) {
|
|
32044
|
+
throw new Error("Runtime delivery Session identity does not match its payload");
|
|
32045
|
+
}
|
|
32046
|
+
try {
|
|
32047
|
+
await sessions.respondPermission(command);
|
|
32048
|
+
audit.record({
|
|
32049
|
+
commandId: command.interactionId,
|
|
32050
|
+
event: "session_permission_resolved",
|
|
32051
|
+
sessionId: command.sessionId
|
|
32052
|
+
});
|
|
32053
|
+
} catch (error61) {
|
|
32054
|
+
reportOperationFailure(socket, command.interactionId, command.sessionId, error61);
|
|
32055
|
+
}
|
|
32056
|
+
return;
|
|
32057
|
+
}
|
|
32058
|
+
if (kind === SESSION_ELICITATION_RESPOND_KIND) {
|
|
32059
|
+
const command = decodeSessionElicitationRespondCommand(delivery.payload);
|
|
32060
|
+
if (command.sessionId !== delivery.sessionId) {
|
|
32061
|
+
throw new Error("Runtime delivery Session identity does not match its payload");
|
|
32062
|
+
}
|
|
32063
|
+
try {
|
|
32064
|
+
await sessions.respondElicitation(command);
|
|
32065
|
+
audit.record({
|
|
32066
|
+
commandId: command.interactionId,
|
|
32067
|
+
event: "session_elicitation_resolved",
|
|
32068
|
+
sessionId: command.sessionId
|
|
32069
|
+
});
|
|
32070
|
+
} catch (error61) {
|
|
32071
|
+
reportOperationFailure(socket, command.interactionId, command.sessionId, error61);
|
|
32072
|
+
}
|
|
32073
|
+
return;
|
|
32074
|
+
}
|
|
32075
|
+
if (kind === BOT_SESSION_PROMPT_KIND) {
|
|
32076
|
+
const command = decodeBotSessionPromptCommand(delivery.payload);
|
|
32077
|
+
await processDeliveredPrompt(
|
|
32078
|
+
delivery,
|
|
32079
|
+
command,
|
|
32080
|
+
true,
|
|
32081
|
+
(attemptId, executionSignal) => executeBotPrompt(
|
|
32082
|
+
outbox,
|
|
32083
|
+
publisher,
|
|
32084
|
+
command,
|
|
32085
|
+
config2,
|
|
32086
|
+
directories,
|
|
32087
|
+
audit,
|
|
32088
|
+
sessions,
|
|
32089
|
+
grants,
|
|
32090
|
+
contexts,
|
|
32091
|
+
applicator,
|
|
32092
|
+
ipc,
|
|
32093
|
+
attemptId,
|
|
32094
|
+
timer,
|
|
32095
|
+
executionSignal
|
|
32096
|
+
)
|
|
32097
|
+
);
|
|
32098
|
+
return;
|
|
32099
|
+
}
|
|
32100
|
+
if (kind === SESSION_PROMPT_KIND) {
|
|
32101
|
+
const command = decodeSessionPromptCommand(delivery.payload);
|
|
32102
|
+
await processDeliveredPrompt(
|
|
32103
|
+
delivery,
|
|
32104
|
+
command,
|
|
32105
|
+
command.disposition !== SessionPromptDisposition.Steer,
|
|
32106
|
+
(attemptId, executionSignal) => executePrompt(
|
|
32107
|
+
outbox,
|
|
32108
|
+
publisher,
|
|
32109
|
+
command,
|
|
32110
|
+
config2,
|
|
32111
|
+
directories,
|
|
32112
|
+
audit,
|
|
32113
|
+
sessions,
|
|
32114
|
+
attemptId,
|
|
32115
|
+
timer,
|
|
32116
|
+
executionSignal
|
|
32117
|
+
)
|
|
32118
|
+
);
|
|
32119
|
+
return;
|
|
32120
|
+
}
|
|
32121
|
+
throw new Error("Runtime delivery contains an unsupported protocol message");
|
|
32122
|
+
};
|
|
32123
|
+
const processRuntimeDelivery = (delivery, state) => {
|
|
32124
|
+
if (state === "processed" || processingDeliveryIds.has(delivery.deliveryId)) {
|
|
32125
|
+
return;
|
|
32126
|
+
}
|
|
32127
|
+
processingDeliveryIds.add(delivery.deliveryId);
|
|
32128
|
+
void processDeliveredPayload(delivery).then(() => {
|
|
32129
|
+
outbox.markRuntimeDeliveryProcessed(delivery.deliveryId, delivery.sessionId);
|
|
32130
|
+
}).catch((error61) => {
|
|
32131
|
+
if (connectionController.signal.aborted) {
|
|
32132
|
+
return;
|
|
32133
|
+
}
|
|
32134
|
+
console.error("Mobius daemon could not process a durable Runtime delivery", error61);
|
|
32135
|
+
failAndClose(
|
|
32136
|
+
new Error("Runtime delivery processing failed", { cause: error61 }),
|
|
32137
|
+
4008,
|
|
32138
|
+
"Invalid Runtime delivery",
|
|
32139
|
+
"delivery"
|
|
32140
|
+
);
|
|
32141
|
+
}).finally(() => processingDeliveryIds.delete(delivery.deliveryId));
|
|
32142
|
+
};
|
|
32143
|
+
const receiveRuntimeDelivery = (delivery) => {
|
|
32144
|
+
const payloadKind = decodeMessageKind(delivery.payload);
|
|
32145
|
+
let payloadSessionId = "";
|
|
32146
|
+
if (payloadKind === SESSION_CANCEL_KIND) {
|
|
32147
|
+
payloadSessionId = decodeSessionCancelCommand(delivery.payload).sessionId;
|
|
32148
|
+
} else if (payloadKind === SESSION_CONFIGURE_KIND) {
|
|
32149
|
+
payloadSessionId = decodeSessionConfigureCommand(delivery.payload).sessionId;
|
|
32150
|
+
} else if (payloadKind === SESSION_PERMISSION_RESPOND_KIND) {
|
|
32151
|
+
payloadSessionId = decodeSessionPermissionRespondCommand(delivery.payload).sessionId;
|
|
32152
|
+
} else if (payloadKind === SESSION_ELICITATION_RESPOND_KIND) {
|
|
32153
|
+
payloadSessionId = decodeSessionElicitationRespondCommand(delivery.payload).sessionId;
|
|
32154
|
+
} else if (payloadKind === SESSION_PROMPT_KIND) {
|
|
32155
|
+
payloadSessionId = decodeSessionPromptCommand(delivery.payload).sessionId;
|
|
32156
|
+
} else if (payloadKind === BOT_SESSION_PROMPT_KIND) {
|
|
32157
|
+
payloadSessionId = decodeBotSessionPromptCommand(delivery.payload).sessionId;
|
|
32158
|
+
} else {
|
|
32159
|
+
throw new Error("Runtime delivery contains an unsupported protocol message");
|
|
32160
|
+
}
|
|
32161
|
+
if (payloadSessionId !== delivery.sessionId) {
|
|
32162
|
+
throw new Error("Runtime delivery Session identity does not match its payload");
|
|
32163
|
+
}
|
|
32164
|
+
const stored = outbox.claimRuntimeDelivery(delivery);
|
|
32165
|
+
send(
|
|
32166
|
+
socket,
|
|
32167
|
+
encodeRuntimeDeliveryReceived({
|
|
32168
|
+
deliveryId: delivery.deliveryId,
|
|
32169
|
+
kind: RUNTIME_DELIVERY_RECEIVED_KIND,
|
|
32170
|
+
sessionId: delivery.sessionId
|
|
32171
|
+
})
|
|
32172
|
+
);
|
|
32173
|
+
processRuntimeDelivery(delivery, stored.state);
|
|
32174
|
+
};
|
|
32175
|
+
const resumeRuntimeDeliveries = () => {
|
|
32176
|
+
for (const stored of outbox.runtimeDeliveries()) {
|
|
32177
|
+
const delivery = {
|
|
32178
|
+
deliveryId: stored.deliveryId,
|
|
32179
|
+
kind: RUNTIME_DELIVERY_KIND,
|
|
32180
|
+
payload: stored.payload,
|
|
32181
|
+
sessionId: stored.sessionId
|
|
32182
|
+
};
|
|
32183
|
+
if (stored.state !== "relay_committed") {
|
|
32184
|
+
send(
|
|
32185
|
+
socket,
|
|
32186
|
+
encodeRuntimeDeliveryReceived({
|
|
32187
|
+
deliveryId: stored.deliveryId,
|
|
32188
|
+
kind: RUNTIME_DELIVERY_RECEIVED_KIND,
|
|
32189
|
+
sessionId: stored.sessionId
|
|
32190
|
+
})
|
|
32191
|
+
);
|
|
32192
|
+
}
|
|
32193
|
+
processRuntimeDelivery(delivery, stored.state);
|
|
32194
|
+
}
|
|
32195
|
+
};
|
|
30811
32196
|
const connectionLiveness = new RelayConnectionLiveness(timer, {
|
|
30812
32197
|
send: (message) => send(socket, message),
|
|
30813
32198
|
unresponsive: (heartbeatId, timeoutMilliseconds) => {
|
|
@@ -30846,6 +32231,17 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
30846
32231
|
}
|
|
30847
32232
|
try {
|
|
30848
32233
|
const kind = decodeMessageKind(encoded);
|
|
32234
|
+
if (kind === RUNTIME_DELIVERY_COMMITTED_KIND) {
|
|
32235
|
+
const committed = decodeRuntimeDeliveryCommitted(encoded);
|
|
32236
|
+
if (!outbox.markRuntimeDeliveryCommitted(committed.deliveryId, committed.sessionId)) {
|
|
32237
|
+
console.warn("Mobius daemon ignored confirmation for an unknown Runtime delivery");
|
|
32238
|
+
}
|
|
32239
|
+
return;
|
|
32240
|
+
}
|
|
32241
|
+
if (kind === RUNTIME_DELIVERY_KIND) {
|
|
32242
|
+
receiveRuntimeDelivery(decodeRuntimeDelivery(encoded));
|
|
32243
|
+
return;
|
|
32244
|
+
}
|
|
30849
32245
|
if (kind === SESSION_EVENT_ACK_KIND) {
|
|
30850
32246
|
publisher.acknowledge(decodeSessionEventAcknowledgement(encoded));
|
|
30851
32247
|
return;
|
|
@@ -31282,6 +32678,10 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31282
32678
|
});
|
|
31283
32679
|
} catch (error61) {
|
|
31284
32680
|
console.error("Mobius daemon rejected a message", error61);
|
|
32681
|
+
if (error61 instanceof RuntimeDeliveryInboxCapacityError) {
|
|
32682
|
+
failAndClose(error61, 4013, "Runtime delivery queue full", "delivery_backpressure");
|
|
32683
|
+
return;
|
|
32684
|
+
}
|
|
31285
32685
|
failAndClose(
|
|
31286
32686
|
new Error("Relay sent an invalid protocol message", { cause: error61 }),
|
|
31287
32687
|
4008,
|
|
@@ -31299,6 +32699,7 @@ async function runRelayConnection(config2, directories, audit, sessions, install
|
|
|
31299
32699
|
return;
|
|
31300
32700
|
}
|
|
31301
32701
|
publisher.connect(socket);
|
|
32702
|
+
resumeRuntimeDeliveries();
|
|
31302
32703
|
},
|
|
31303
32704
|
(error61) => {
|
|
31304
32705
|
if (finished) {
|
|
@@ -31351,7 +32752,7 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
31351
32752
|
}
|
|
31352
32753
|
publisher.recordAttempt(sessionId, payload, attemptId);
|
|
31353
32754
|
};
|
|
31354
|
-
const sessions = new AcpSessionManager(new DaemonAcpObserver(recordSessionEvent), sessionStore);
|
|
32755
|
+
const sessions = new AcpSessionManager(new DaemonAcpObserver(config2, recordSessionEvent), sessionStore);
|
|
31355
32756
|
const directories = new WorkspaceDirectoryService(config2.bindingId, config2.defaultWorkspace);
|
|
31356
32757
|
const installationObserver = new DaemonInstallationObserver();
|
|
31357
32758
|
const diagnostics = new RelayConnectionDiagnostics(audit, config2.channelId, config2.relayUrl);
|
|
@@ -31449,11 +32850,11 @@ async function runDaemon(config2, audit, signal, timer = systemDaemonTimer) {
|
|
|
31449
32850
|
}
|
|
31450
32851
|
|
|
31451
32852
|
// src/runtime.ts
|
|
31452
|
-
import { mkdir as mkdir5, realpath as
|
|
32853
|
+
import { mkdir as mkdir5, realpath as realpath9, stat as stat9 } from "node:fs/promises";
|
|
31453
32854
|
import { dirname as dirname8, join as join17, resolve as resolve5 } from "node:path";
|
|
31454
32855
|
var APP_CREDENTIAL_PATTERN = /^mapp_[a-zA-Z0-9_-]{22}_[a-zA-Z0-9_-]{43}$/;
|
|
31455
32856
|
var CONVERSATION_CREDENTIAL_PATTERN = /^mconv_[a-zA-Z0-9_-]{22}_[a-zA-Z0-9_-]{43}$/;
|
|
31456
|
-
var
|
|
32857
|
+
var IDENTIFIER_PATTERN9 = /^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,127}$/;
|
|
31457
32858
|
var RUNTIME_CREDENTIAL_PATTERN = /^[a-zA-Z0-9_-]{32,256}$/;
|
|
31458
32859
|
var MobiusRuntimeConfigurationError = class extends Error {
|
|
31459
32860
|
code = "runtime_configuration_invalid";
|
|
@@ -31511,7 +32912,7 @@ function relayUrlFromConnection(connection) {
|
|
|
31511
32912
|
}
|
|
31512
32913
|
function loadMobiusRuntimeConnection(environment = process.env) {
|
|
31513
32914
|
const channelId = requiredEnvironmentValue(environment, "MOBIUS_CHANNEL_ID");
|
|
31514
|
-
if (!
|
|
32915
|
+
if (!IDENTIFIER_PATTERN9.test(channelId)) {
|
|
31515
32916
|
throw new MobiusRuntimeConfigurationError("MOBIUS_CHANNEL_ID is invalid");
|
|
31516
32917
|
}
|
|
31517
32918
|
return Object.freeze({
|
|
@@ -31526,8 +32927,8 @@ async function resolveWorkspace(path2) {
|
|
|
31526
32927
|
const requested = resolve5(path2);
|
|
31527
32928
|
try {
|
|
31528
32929
|
await mkdir5(requested, { recursive: true, mode: 448 });
|
|
31529
|
-
const resolved = await
|
|
31530
|
-
const metadata = await
|
|
32930
|
+
const resolved = await realpath9(requested);
|
|
32931
|
+
const metadata = await stat9(resolved);
|
|
31531
32932
|
if (!metadata.isDirectory()) {
|
|
31532
32933
|
throw new MobiusRuntimeConfigurationError("The Runtime workspace is not a directory");
|
|
31533
32934
|
}
|