@moxt-ai/mobius 0.0.323 → 0.0.324
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +431 -280
- package/dist/cli.js.map +4 -4
- package/dist/runtime/command/dispatcher.d.ts +1 -0
- package/dist/runtime/command/dispatcher.d.ts.map +1 -1
- package/dist/runtime/command/dispatcher.js.map +1 -1
- package/dist/runtime/command/registry/content-write/index.d.ts +10 -0
- package/dist/runtime/command/registry/content-write/index.d.ts.map +1 -0
- package/dist/runtime/command/registry/content-write/index.js +125 -0
- package/dist/runtime/command/registry/content-write/index.js.map +1 -0
- package/dist/runtime/command/registry/file-read/index.d.ts.map +1 -1
- package/dist/runtime/command/registry/file-read/index.js +2 -2
- package/dist/runtime/command/registry/file-read/index.js.map +1 -1
- package/dist/runtime/command/registry/index.d.ts +2 -1
- package/dist/runtime/command/registry/index.d.ts.map +1 -1
- package/dist/runtime/command/registry/index.js +9 -1
- package/dist/runtime/command/registry/index.js.map +1 -1
- package/dist/runtime/command/registry/prompt.d.ts.map +1 -1
- package/dist/runtime/command/registry/prompt.js +7 -2
- package/dist/runtime/command/registry/prompt.js.map +1 -1
- package/dist/runtime/command/registry/session.d.ts.map +1 -1
- package/dist/runtime/command/registry/session.js +10 -5
- package/dist/runtime/command/registry/session.js.map +1 -1
- package/dist/runtime/command/transport.d.ts +1 -0
- package/dist/runtime/command/transport.d.ts.map +1 -1
- package/dist/runtime/command/transport.js +7 -1
- package/dist/runtime/command/transport.js.map +1 -1
- package/dist/runtime/relay/connect.d.ts.map +1 -1
- package/dist/runtime/relay/connect.js +1 -0
- package/dist/runtime/relay/connect.js.map +1 -1
- package/dist/runtime/relay/run-relay-connection.d.ts.map +1 -1
- package/dist/runtime/relay/run-relay-connection.js +6 -1
- package/dist/runtime/relay/run-relay-connection.js.map +1 -1
- package/dist/runtime.js +418 -266
- package/dist/runtime.js.map +4 -4
- package/dist/session/api/session-api.d.ts +11 -4
- package/dist/session/api/session-api.d.ts.map +1 -1
- package/dist/session/api/session-api.js +3 -1
- package/dist/session/api/session-api.js.map +1 -1
- package/dist/session/content/external-content-store.d.ts +2 -0
- package/dist/session/content/external-content-store.d.ts.map +1 -1
- package/dist/session/content/external-content-store.js +5 -0
- package/dist/session/content/external-content-store.js.map +1 -1
- package/dist/session/content/session-files.d.ts +1 -1
- package/dist/session/content/session-files.d.ts.map +1 -1
- package/dist/session/content/session-files.js +4 -11
- package/dist/session/content/session-files.js.map +1 -1
- package/dist/session/live/agent-session.d.ts +2 -2
- package/dist/session/live/agent-session.d.ts.map +1 -1
- package/dist/session/live/agent-session.js +45 -13
- package/dist/session/live/agent-session.js.map +1 -1
- package/dist/session/manager/session-manager.d.ts +3 -3
- package/dist/session/manager/session-manager.d.ts.map +1 -1
- package/dist/session/manager/session-manager.js +2 -2
- package/dist/session/manager/session-manager.js.map +1 -1
- package/dist/session/prompt/apply-session-configuration.d.ts.map +1 -1
- package/dist/session/prompt/apply-session-configuration.js +2 -2
- package/dist/session/prompt/apply-session-configuration.js.map +1 -1
- package/dist/session/prompt/execute-prompt.d.ts +3 -3
- package/dist/session/prompt/execute-prompt.d.ts.map +1 -1
- package/dist/session/prompt/execute-prompt.js +2 -2
- package/dist/session/prompt/execute-prompt.js.map +1 -1
- package/dist/session/prompt/prompt-artifacts.d.ts +7 -22
- package/dist/session/prompt/prompt-artifacts.d.ts.map +1 -1
- package/dist/session/prompt/prompt-artifacts.js +22 -76
- package/dist/session/prompt/prompt-artifacts.js.map +1 -1
- package/dist/session/prompt/prompt-lifecycle.d.ts.map +1 -1
- package/dist/session/prompt/prompt-lifecycle.js +15 -12
- package/dist/session/prompt/prompt-lifecycle.js.map +1 -1
- package/dist/session/turn/session-turns.d.ts +5 -9
- package/dist/session/turn/session-turns.d.ts.map +1 -1
- package/dist/session/turn/session-turns.js +1 -2
- package/dist/session/turn/session-turns.js.map +1 -1
- package/dist/storage/files/scratch-directory.d.ts +2 -0
- package/dist/storage/files/scratch-directory.d.ts.map +1 -1
- package/dist/storage/files/scratch-directory.js +7 -1
- package/dist/storage/files/scratch-directory.js.map +1 -1
- package/dist/util/filesystem/private-path.js +2 -3
- package/dist/util/filesystem/private-path.js.map +2 -2
- package/dist/util/platform/windows.d.ts.map +1 -1
- package/dist/util/platform/windows.js +3 -5
- package/dist/util/platform/windows.js.map +1 -1
- package/dist/util/process/executable.js +2 -3
- package/dist/util/process/executable.js.map +2 -2
- package/package.json +2 -2
- package/dist/runtime/relay/artifact-download.d.ts +0 -5
- package/dist/runtime/relay/artifact-download.d.ts.map +0 -1
- package/dist/runtime/relay/artifact-download.js +0 -105
- package/dist/runtime/relay/artifact-download.js.map +0 -1
package/dist/runtime.js
CHANGED
|
@@ -500,11 +500,10 @@ function terminateProcess2(child, signal) {
|
|
|
500
500
|
var windowsPermissions = `
|
|
501
501
|
$ErrorActionPreference = 'Stop'
|
|
502
502
|
$ProgressPreference = 'SilentlyContinue'
|
|
503
|
-
Import-Module (Join-Path $PSHOME 'Modules/Microsoft.PowerShell.Security/Microsoft.PowerShell.Security.psd1')
|
|
504
503
|
$item = Get-Item -LiteralPath $env:MOBIUS_PERMISSION_PATH -Force
|
|
505
504
|
if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { throw 'Unsafe path' }
|
|
506
505
|
$sid = [Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
507
|
-
$acl =
|
|
506
|
+
$acl = $item.GetAccessControl()
|
|
508
507
|
$owner = $acl.GetOwner([Security.Principal.SecurityIdentifier])
|
|
509
508
|
if ($owner -ne $sid -and -not ($owner.Value -eq 'S-1-5-32-544' -and ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator))) { throw 'Path is not user-owned' }
|
|
510
509
|
if ($env:MOBIUS_PERMISSION_PRIVATE -eq '1') {
|
|
@@ -518,7 +517,7 @@ if ($env:MOBIUS_PERMISSION_PRIVATE -eq '1') {
|
|
|
518
517
|
$private.SetOwner($sid)
|
|
519
518
|
$private.SetAccessRuleProtection($true, $false)
|
|
520
519
|
$private.AddAccessRule($rule)
|
|
521
|
-
|
|
520
|
+
$item.SetAccessControl($private)
|
|
522
521
|
}
|
|
523
522
|
`;
|
|
524
523
|
var windowsPermissionsTimeoutMs = 3e4;
|
|
@@ -21387,6 +21386,8 @@ var sessionConfigureCommandSchema = external_exports.object({
|
|
|
21387
21386
|
...sessionIdentityFields,
|
|
21388
21387
|
booleanValue: external_exports.boolean(),
|
|
21389
21388
|
configId: external_exports.string().min(1).max(128),
|
|
21389
|
+
// Omitted by legacy clients: explicit edits retain last-write-wins behavior.
|
|
21390
|
+
expectedConfigurationRevision: identifierStringSchema.optional(),
|
|
21390
21391
|
kind: external_exports.literal(SESSION_CONFIGURE_KIND),
|
|
21391
21392
|
requestId: identifierStringSchema,
|
|
21392
21393
|
value: external_exports.string().max(500),
|
|
@@ -21394,6 +21395,8 @@ var sessionConfigureCommandSchema = external_exports.object({
|
|
|
21394
21395
|
}).readonly();
|
|
21395
21396
|
var sessionConfigUpdatedEventSchema = external_exports.object({
|
|
21396
21397
|
configOptions: sessionConfigOptionsSchema,
|
|
21398
|
+
// An opaque Runtime generation token; absent on older Runtimes.
|
|
21399
|
+
configurationRevision: identifierStringSchema.optional(),
|
|
21397
21400
|
kind: external_exports.literal(SESSION_CONFIG_UPDATED_KIND),
|
|
21398
21401
|
requestId: identifierStringSchema,
|
|
21399
21402
|
sessionId: identifierStringSchema
|
|
@@ -21412,6 +21415,8 @@ var sessionConfigReadCommandSchema = external_exports.object({
|
|
|
21412
21415
|
}).readonly();
|
|
21413
21416
|
var sessionConfigReadResultSchema = external_exports.object({
|
|
21414
21417
|
configOptions: sessionConfigOptionsSchema,
|
|
21418
|
+
// An opaque Runtime generation token; absent on older Runtimes.
|
|
21419
|
+
configurationRevision: identifierStringSchema.optional(),
|
|
21415
21420
|
kind: external_exports.literal(SESSION_CONFIG_READ_RESULT_KIND),
|
|
21416
21421
|
requestId: identifierStringSchema,
|
|
21417
21422
|
sessionId: identifierStringSchema
|
|
@@ -21445,9 +21450,17 @@ var encodeSessionRenamedEvent = (message) => encodeZodMessage(message, sessionRe
|
|
|
21445
21450
|
// ../mobius-sdk/src/protocol/session/files/index.ts
|
|
21446
21451
|
var FILE_READ_KIND = "file.read";
|
|
21447
21452
|
var FILE_BEGIN_KIND = "file.begin";
|
|
21448
|
-
var FILE_CHUNK_KIND = "file.chunk";
|
|
21449
21453
|
var FILE_END_KIND = "file.end";
|
|
21450
21454
|
var FILE_FAILED_KIND = "file.failed";
|
|
21455
|
+
var CONTENT_WRITE_KIND = "content.write";
|
|
21456
|
+
var CONTENT_COMMIT_KIND = "content.commit";
|
|
21457
|
+
var CONTENT_READY_KIND = "content.ready";
|
|
21458
|
+
var CONTENT_AVAILABLE_KIND = "content.available";
|
|
21459
|
+
var CONTENT_CHUNK_MAX_BYTES = 192 * 1024;
|
|
21460
|
+
var CONTENT_WRITE_MAX_BYTES = 32 * 1024 * 1024;
|
|
21461
|
+
var PROMPT_IMAGE_MAX_BYTES = 5e6;
|
|
21462
|
+
var CONTENT_CHUNK_MAGIC = new Uint8Array([77, 66, 67, 49]);
|
|
21463
|
+
var CONTENT_CHUNK_HEADER_BYTES = CONTENT_CHUNK_MAGIC.byteLength + 1 + 4;
|
|
21451
21464
|
var fileReadCommandSchema = external_exports.object({
|
|
21452
21465
|
kind: external_exports.literal(FILE_READ_KIND),
|
|
21453
21466
|
maxBytes: external_exports.number().int().positive().max(128 * 1024 * 1024),
|
|
@@ -21464,13 +21477,86 @@ var fileBeginEventSchema = external_exports.object({
|
|
|
21464
21477
|
requestId: identifierStringSchema,
|
|
21465
21478
|
sessionId: identifierStringSchema
|
|
21466
21479
|
}).readonly();
|
|
21467
|
-
var
|
|
21468
|
-
|
|
21469
|
-
|
|
21480
|
+
var contentWriteCommandSchema = external_exports.object({
|
|
21481
|
+
byteLength: external_exports.number().int().positive().max(CONTENT_WRITE_MAX_BYTES),
|
|
21482
|
+
contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
|
|
21483
|
+
contentKind: external_exports.enum(["image", "resource"]),
|
|
21484
|
+
kind: external_exports.literal(CONTENT_WRITE_KIND),
|
|
21485
|
+
mediaType: external_exports.string().min(1).max(255),
|
|
21486
|
+
name: external_exports.string().min(1).max(500),
|
|
21487
|
+
requestId: identifierStringSchema,
|
|
21488
|
+
sessionId: identifierStringSchema
|
|
21489
|
+
}).readonly();
|
|
21490
|
+
var contentCommitCommandSchema = external_exports.object({
|
|
21491
|
+
kind: external_exports.literal(CONTENT_COMMIT_KIND),
|
|
21492
|
+
requestId: identifierStringSchema,
|
|
21493
|
+
sessionId: identifierStringSchema
|
|
21494
|
+
}).readonly();
|
|
21495
|
+
var contentReadyEventSchema = external_exports.object({
|
|
21496
|
+
kind: external_exports.literal(CONTENT_READY_KIND),
|
|
21497
|
+
requestId: identifierStringSchema,
|
|
21498
|
+
sessionId: identifierStringSchema
|
|
21499
|
+
}).readonly();
|
|
21500
|
+
var contentAvailableEventSchema = external_exports.object({
|
|
21501
|
+
byteLength: external_exports.number().int().positive().max(CONTENT_WRITE_MAX_BYTES),
|
|
21502
|
+
contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
|
|
21503
|
+
kind: external_exports.literal(CONTENT_AVAILABLE_KIND),
|
|
21470
21504
|
requestId: identifierStringSchema,
|
|
21471
|
-
sequence: external_exports.number().int().nonnegative().max(1024),
|
|
21472
21505
|
sessionId: identifierStringSchema
|
|
21473
21506
|
}).readonly();
|
|
21507
|
+
function binaryBytes(value) {
|
|
21508
|
+
if (value instanceof ArrayBuffer) {
|
|
21509
|
+
return new Uint8Array(value);
|
|
21510
|
+
}
|
|
21511
|
+
if (ArrayBuffer.isView(value)) {
|
|
21512
|
+
return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
21513
|
+
}
|
|
21514
|
+
throw new Error("Content chunk must be a binary WebSocket frame");
|
|
21515
|
+
}
|
|
21516
|
+
function encodeContentChunkFrame(frame) {
|
|
21517
|
+
if (!isIdentifier(frame.requestId)) {
|
|
21518
|
+
throw new Error("Content chunk request identifier is invalid");
|
|
21519
|
+
}
|
|
21520
|
+
if (!Number.isSafeInteger(frame.sequence) || frame.sequence < 0 || frame.sequence > 4294967295) {
|
|
21521
|
+
throw new Error("Content chunk sequence is invalid");
|
|
21522
|
+
}
|
|
21523
|
+
if (frame.bytes.byteLength < 1 || frame.bytes.byteLength > CONTENT_CHUNK_MAX_BYTES) {
|
|
21524
|
+
throw new Error("Content chunk size is invalid");
|
|
21525
|
+
}
|
|
21526
|
+
const requestId = new TextEncoder().encode(frame.requestId);
|
|
21527
|
+
if (requestId.byteLength > 255) {
|
|
21528
|
+
throw new Error("Content chunk request identifier is too long");
|
|
21529
|
+
}
|
|
21530
|
+
const encoded = new Uint8Array(CONTENT_CHUNK_HEADER_BYTES + requestId.byteLength + frame.bytes.byteLength);
|
|
21531
|
+
encoded.set(CONTENT_CHUNK_MAGIC, 0);
|
|
21532
|
+
encoded[CONTENT_CHUNK_MAGIC.byteLength] = requestId.byteLength;
|
|
21533
|
+
new DataView(encoded.buffer).setUint32(CONTENT_CHUNK_MAGIC.byteLength + 1, frame.sequence);
|
|
21534
|
+
encoded.set(requestId, CONTENT_CHUNK_HEADER_BYTES);
|
|
21535
|
+
encoded.set(frame.bytes, CONTENT_CHUNK_HEADER_BYTES + requestId.byteLength);
|
|
21536
|
+
return encoded;
|
|
21537
|
+
}
|
|
21538
|
+
function decodeContentChunkFrame(value) {
|
|
21539
|
+
const encoded = binaryBytes(value);
|
|
21540
|
+
if (encoded.byteLength <= CONTENT_CHUNK_HEADER_BYTES || !CONTENT_CHUNK_MAGIC.every((byte, index2) => encoded[index2] === byte)) {
|
|
21541
|
+
throw new Error("Content chunk frame header is invalid");
|
|
21542
|
+
}
|
|
21543
|
+
const requestIdLength = encoded[CONTENT_CHUNK_MAGIC.byteLength] ?? 0;
|
|
21544
|
+
const payloadOffset = CONTENT_CHUNK_HEADER_BYTES + requestIdLength;
|
|
21545
|
+
if (requestIdLength < 1 || payloadOffset >= encoded.byteLength) {
|
|
21546
|
+
throw new Error("Content chunk frame length is invalid");
|
|
21547
|
+
}
|
|
21548
|
+
const requestId = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(
|
|
21549
|
+
encoded.subarray(CONTENT_CHUNK_HEADER_BYTES, payloadOffset)
|
|
21550
|
+
);
|
|
21551
|
+
const bytes = encoded.slice(payloadOffset);
|
|
21552
|
+
const sequence = new DataView(encoded.buffer, encoded.byteOffset, encoded.byteLength).getUint32(
|
|
21553
|
+
CONTENT_CHUNK_MAGIC.byteLength + 1
|
|
21554
|
+
);
|
|
21555
|
+
if (!isIdentifier(requestId) || bytes.byteLength > CONTENT_CHUNK_MAX_BYTES) {
|
|
21556
|
+
throw new Error("Content chunk frame is invalid");
|
|
21557
|
+
}
|
|
21558
|
+
return { bytes, requestId, sequence };
|
|
21559
|
+
}
|
|
21474
21560
|
var fileEndEventSchema = external_exports.object({
|
|
21475
21561
|
kind: external_exports.literal(FILE_END_KIND),
|
|
21476
21562
|
requestId: identifierStringSchema,
|
|
@@ -21487,12 +21573,18 @@ var decodeFileReadCommand = (encoded) => decodeZodMessage(encoded, fileReadComma
|
|
|
21487
21573
|
var encodeFileReadCommand = (message) => encodeZodMessage(message, fileReadCommandSchema);
|
|
21488
21574
|
var decodeFileBeginEvent = (encoded) => decodeZodMessage(encoded, fileBeginEventSchema);
|
|
21489
21575
|
var encodeFileBeginEvent = (message) => encodeZodMessage(message, fileBeginEventSchema);
|
|
21490
|
-
var decodeFileChunkEvent = (encoded) => decodeZodMessage(encoded, fileChunkEventSchema);
|
|
21491
|
-
var encodeFileChunkEvent = (message) => encodeZodMessage(message, fileChunkEventSchema);
|
|
21492
21576
|
var decodeFileEndEvent = (encoded) => decodeZodMessage(encoded, fileEndEventSchema);
|
|
21493
21577
|
var encodeFileEndEvent = (message) => encodeZodMessage(message, fileEndEventSchema);
|
|
21494
21578
|
var decodeFileFailedEvent = (encoded) => decodeZodMessage(encoded, fileFailedEventSchema);
|
|
21495
21579
|
var encodeFileFailedEvent = (message) => encodeZodMessage(message, fileFailedEventSchema);
|
|
21580
|
+
var decodeContentWriteCommand = (encoded) => decodeZodMessage(encoded, contentWriteCommandSchema);
|
|
21581
|
+
var encodeContentWriteCommand = (message) => encodeZodMessage(message, contentWriteCommandSchema);
|
|
21582
|
+
var decodeContentCommitCommand = (encoded) => decodeZodMessage(encoded, contentCommitCommandSchema);
|
|
21583
|
+
var encodeContentCommitCommand = (message) => encodeZodMessage(message, contentCommitCommandSchema);
|
|
21584
|
+
var decodeContentReadyEvent = (encoded) => decodeZodMessage(encoded, contentReadyEventSchema);
|
|
21585
|
+
var encodeContentReadyEvent = (message) => encodeZodMessage(message, contentReadyEventSchema);
|
|
21586
|
+
var decodeContentAvailableEvent = (encoded) => decodeZodMessage(encoded, contentAvailableEventSchema);
|
|
21587
|
+
var encodeContentAvailableEvent = (message) => encodeZodMessage(message, contentAvailableEventSchema);
|
|
21496
21588
|
|
|
21497
21589
|
// ../mobius-sdk/src/protocol/shared/tool-input.ts
|
|
21498
21590
|
var MAX_CONTENT_LENGTH = 1e6;
|
|
@@ -21749,6 +21841,7 @@ var sessionReadyEventSchema = external_exports.object({
|
|
|
21749
21841
|
capabilities: sessionCapabilitiesSchema,
|
|
21750
21842
|
commands: external_exports.array(sessionCommandSchema).max(500).readonly(),
|
|
21751
21843
|
configOptions: sessionConfigOptionsSchema,
|
|
21844
|
+
configurationRevision: identifierStringSchema.optional(),
|
|
21752
21845
|
directoryId: DIRECTORY_IDENTIFIER,
|
|
21753
21846
|
directoryLabel: external_exports.string().min(1).max(MAX_WORKSPACE_PATH_LENGTH),
|
|
21754
21847
|
kind: external_exports.literal(SESSION_READY_KIND),
|
|
@@ -21836,21 +21929,16 @@ var SessionHistoryPolicy = Object.freeze({
|
|
|
21836
21929
|
ExecutionOnly: "execution-only"
|
|
21837
21930
|
});
|
|
21838
21931
|
var MAX_PROMPT_LENGTH = 1e5;
|
|
21839
|
-
var
|
|
21840
|
-
var
|
|
21841
|
-
|
|
21932
|
+
var MAX_PROMPT_ATTACHMENT_BYTES = 32 * 1024 * 1024;
|
|
21933
|
+
var promptAttachmentSchema = external_exports.object({
|
|
21934
|
+
byteLength: external_exports.number().int().positive().max(MAX_PROMPT_ATTACHMENT_BYTES),
|
|
21935
|
+
contentKey: external_exports.string().regex(/^[a-f0-9]{64}$/u),
|
|
21936
|
+
kind: external_exports.enum(["image", "resource"]),
|
|
21842
21937
|
mimeType: external_exports.string().min(1).max(255),
|
|
21843
|
-
name: external_exports.string().min(1).max(500)
|
|
21844
|
-
}).readonly();
|
|
21845
|
-
var promptResourceSchema = external_exports.object({
|
|
21846
|
-
mimeType: external_exports.string().max(255),
|
|
21847
21938
|
name: external_exports.string().min(1).max(500),
|
|
21848
|
-
text: external_exports.string().max(1e6),
|
|
21849
|
-
type: external_exports.enum(["embedded", "link"]),
|
|
21850
21939
|
uri: external_exports.string().min(1).max(4096)
|
|
21851
21940
|
}).readonly();
|
|
21852
|
-
var
|
|
21853
|
-
var decodePromptResourcesValue = (value) => decodeZodValue(value, external_exports.array(promptResourceSchema).max(16).readonly());
|
|
21941
|
+
var decodePromptAttachmentsValue = (value) => decodeZodValue(value, external_exports.array(promptAttachmentSchema).max(16).readonly());
|
|
21854
21942
|
function readPromptDisposition(value) {
|
|
21855
21943
|
const field = value["disposition"];
|
|
21856
21944
|
if (field === void 0 || field === SessionPromptDisposition.Reject) {
|
|
@@ -21869,13 +21957,12 @@ function decodeSessionPromptCommand(encoded) {
|
|
|
21869
21957
|
const hasSessionConfigurations = Object.hasOwn(value, "sessionConfigurations");
|
|
21870
21958
|
assertKind(value, SESSION_PROMPT_KIND);
|
|
21871
21959
|
const prompt = readText(value, "prompt", MAX_PROMPT_LENGTH);
|
|
21872
|
-
const
|
|
21873
|
-
const
|
|
21874
|
-
|
|
21875
|
-
if (attachmentLength > MAX_PROMPT_ATTACHMENT_LENGTH) {
|
|
21960
|
+
const attachments = !Object.hasOwn(value, "attachments") && Array.isArray(value["images"]) && Array.isArray(value["resources"]) ? [] : decodePromptAttachmentsValue(value["attachments"]);
|
|
21961
|
+
const attachmentBytes = attachments.reduce((total, attachment) => total + attachment.byteLength, 0);
|
|
21962
|
+
if (attachmentBytes > MAX_PROMPT_ATTACHMENT_BYTES) {
|
|
21876
21963
|
throw new ProtocolMessageError("Prompt attachments are too large");
|
|
21877
21964
|
}
|
|
21878
|
-
if (prompt.trim().length === 0 &&
|
|
21965
|
+
if (prompt.trim().length === 0 && attachments.length === 0) {
|
|
21879
21966
|
throw new ProtocolMessageError("Prompt must contain content");
|
|
21880
21967
|
}
|
|
21881
21968
|
const disposition = readPromptDisposition(value);
|
|
@@ -21895,13 +21982,12 @@ function decodeSessionPromptCommand(encoded) {
|
|
|
21895
21982
|
commandId: readIdentifier(value, "commandId"),
|
|
21896
21983
|
directoryId: readDirectoryIdentifier(value, "directoryId"),
|
|
21897
21984
|
disposition,
|
|
21898
|
-
|
|
21985
|
+
attachments,
|
|
21899
21986
|
...value["historyPolicy"] === void 0 ? {} : {
|
|
21900
21987
|
historyPolicy: readHistoryPolicy(value)
|
|
21901
21988
|
},
|
|
21902
21989
|
kind: SESSION_PROMPT_KIND,
|
|
21903
21990
|
prompt,
|
|
21904
|
-
resources,
|
|
21905
21991
|
...hasSessionConfigurations ? { sessionConfigurations } : {},
|
|
21906
21992
|
sessionId: readIdentifier(value, "sessionId"),
|
|
21907
21993
|
targetCommandId
|
|
@@ -21937,7 +22023,15 @@ function decodeSessionPromptDispositionCommand(encoded) {
|
|
|
21937
22023
|
};
|
|
21938
22024
|
}
|
|
21939
22025
|
function encodeSessionPromptCommand(message) {
|
|
21940
|
-
|
|
22026
|
+
const command = decodeSessionPromptCommand(JSON.stringify(message));
|
|
22027
|
+
return JSON.stringify({
|
|
22028
|
+
...command,
|
|
22029
|
+
// Keep text prompts compatible with the previous Runtime release while
|
|
22030
|
+
// attachments move to the content-key protocol. Older Runtimes ignore
|
|
22031
|
+
// `attachments` and require both legacy arrays to be present.
|
|
22032
|
+
images: [],
|
|
22033
|
+
resources: []
|
|
22034
|
+
});
|
|
21941
22035
|
}
|
|
21942
22036
|
function encodeSessionCancelCommand(message) {
|
|
21943
22037
|
return JSON.stringify(decodeSessionCancelCommand(JSON.stringify(message)));
|
|
@@ -22022,9 +22116,7 @@ var nativeSessionResultSchema = external_exports.discriminatedUnion("action", [
|
|
|
22022
22116
|
external_exports.object({
|
|
22023
22117
|
commandId: identifierStringSchema,
|
|
22024
22118
|
prompt: external_exports.string().max(1e5),
|
|
22025
|
-
|
|
22026
|
-
// Absent from daemons that predate it; a client then cannot restore the prompt's files.
|
|
22027
|
-
resources: external_exports.array(promptResourceSchema).max(16).readonly().optional()
|
|
22119
|
+
attachments: external_exports.array(promptAttachmentSchema).max(16).readonly()
|
|
22028
22120
|
}).readonly()
|
|
22029
22121
|
).readonly(),
|
|
22030
22122
|
turn: activeTurnSnapshotSchema.nullable()
|
|
@@ -22626,6 +22718,16 @@ var serviceToDaemonSignatures = {
|
|
|
22626
22718
|
decodeAgentCatalogDiscoverCommand
|
|
22627
22719
|
),
|
|
22628
22720
|
[FILE_READ_KIND]: defineMessageSignature(FILE_READ_KIND, encodeFileReadCommand, decodeFileReadCommand),
|
|
22721
|
+
[CONTENT_WRITE_KIND]: defineMessageSignature(
|
|
22722
|
+
CONTENT_WRITE_KIND,
|
|
22723
|
+
encodeContentWriteCommand,
|
|
22724
|
+
decodeContentWriteCommand
|
|
22725
|
+
),
|
|
22726
|
+
[CONTENT_COMMIT_KIND]: defineMessageSignature(
|
|
22727
|
+
CONTENT_COMMIT_KIND,
|
|
22728
|
+
encodeContentCommitCommand,
|
|
22729
|
+
decodeContentCommitCommand
|
|
22730
|
+
),
|
|
22629
22731
|
[SESSION_LIST_KIND]: defineMessageSignature(SESSION_LIST_KIND, encodeSessionListCommand, decodeSessionListCommand),
|
|
22630
22732
|
[SESSION_QUERY_KIND]: defineMessageSignature(
|
|
22631
22733
|
SESSION_QUERY_KIND,
|
|
@@ -22785,9 +22887,14 @@ var daemonToServiceSignatures = {
|
|
|
22785
22887
|
decodeAgentCatalogDiscoveryFailedEvent
|
|
22786
22888
|
),
|
|
22787
22889
|
[FILE_BEGIN_KIND]: defineMessageSignature(FILE_BEGIN_KIND, encodeFileBeginEvent, decodeFileBeginEvent),
|
|
22788
|
-
[FILE_CHUNK_KIND]: defineMessageSignature(FILE_CHUNK_KIND, encodeFileChunkEvent, decodeFileChunkEvent),
|
|
22789
22890
|
[FILE_END_KIND]: defineMessageSignature(FILE_END_KIND, encodeFileEndEvent, decodeFileEndEvent),
|
|
22790
22891
|
[FILE_FAILED_KIND]: defineMessageSignature(FILE_FAILED_KIND, encodeFileFailedEvent, decodeFileFailedEvent),
|
|
22892
|
+
[CONTENT_READY_KIND]: defineMessageSignature(CONTENT_READY_KIND, encodeContentReadyEvent, decodeContentReadyEvent),
|
|
22893
|
+
[CONTENT_AVAILABLE_KIND]: defineMessageSignature(
|
|
22894
|
+
CONTENT_AVAILABLE_KIND,
|
|
22895
|
+
encodeContentAvailableEvent,
|
|
22896
|
+
decodeContentAvailableEvent
|
|
22897
|
+
),
|
|
22791
22898
|
[SESSION_LISTED_KIND]: defineMessageSignature(
|
|
22792
22899
|
SESSION_LISTED_KIND,
|
|
22793
22900
|
encodeSessionsListedEvent,
|
|
@@ -32275,7 +32382,7 @@ import { fetch as fetch3 } from "undici";
|
|
|
32275
32382
|
// package.json
|
|
32276
32383
|
var package_default = {
|
|
32277
32384
|
name: "@moxt-ai/mobius",
|
|
32278
|
-
version: "0.0.
|
|
32385
|
+
version: "0.0.324",
|
|
32279
32386
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
32280
32387
|
type: "module",
|
|
32281
32388
|
bin: {
|
|
@@ -83559,7 +83666,8 @@ var PreparedSession = class {
|
|
|
83559
83666
|
configOptions;
|
|
83560
83667
|
prompted;
|
|
83561
83668
|
restored;
|
|
83562
|
-
|
|
83669
|
+
configurationRevision;
|
|
83670
|
+
constructor(agentName, agentVersion, capabilities, commands, configOptions, prompted, restored, configurationRevision) {
|
|
83563
83671
|
this.agentName = agentName;
|
|
83564
83672
|
this.agentVersion = agentVersion;
|
|
83565
83673
|
this.capabilities = capabilities;
|
|
@@ -83567,6 +83675,7 @@ var PreparedSession = class {
|
|
|
83567
83675
|
this.configOptions = configOptions;
|
|
83568
83676
|
this.prompted = prompted;
|
|
83569
83677
|
this.restored = restored;
|
|
83678
|
+
this.configurationRevision = configurationRevision;
|
|
83570
83679
|
}
|
|
83571
83680
|
};
|
|
83572
83681
|
var AgentSettingsSnapshot = class {
|
|
@@ -84606,7 +84715,8 @@ var AgentSession = class _AgentSession {
|
|
|
84606
84715
|
#agentVersion = "";
|
|
84607
84716
|
#capabilities = unsupportedSessionCapabilities();
|
|
84608
84717
|
#commands = [];
|
|
84609
|
-
#configRevision =
|
|
84718
|
+
#configRevision = crypto.randomUUID();
|
|
84719
|
+
#configurationChanges = new SerialTaskQueue();
|
|
84610
84720
|
#configOptions = [];
|
|
84611
84721
|
#sessionConfigurations = new SessionConfigurations();
|
|
84612
84722
|
#nativeHistoryOwnership = { kind: "unbound" };
|
|
@@ -84775,7 +84885,8 @@ var AgentSession = class _AgentSession {
|
|
|
84775
84885
|
this.#commands,
|
|
84776
84886
|
this.#configOptions,
|
|
84777
84887
|
this.#prompted,
|
|
84778
|
-
this.#restored
|
|
84888
|
+
this.#restored,
|
|
84889
|
+
this.#configRevision
|
|
84779
84890
|
);
|
|
84780
84891
|
ensureHistoryLoaded = async (signal) => {
|
|
84781
84892
|
if (!this.#capabilities.loadSession) {
|
|
@@ -84905,12 +85016,23 @@ var AgentSession = class _AgentSession {
|
|
|
84905
85016
|
const configured = await this.#adapter.configureSession(this.#target(), selection, signal);
|
|
84906
85017
|
if (this.#configRevision === configRevision) {
|
|
84907
85018
|
this.#configOptions = configured;
|
|
85019
|
+
this.#configRevision = crypto.randomUUID();
|
|
85020
|
+
await this.#publishConfiguration();
|
|
84908
85021
|
}
|
|
84909
85022
|
};
|
|
84910
|
-
|
|
85023
|
+
// The revision check and Agent mutation share one queue, including legacy callers.
|
|
85024
|
+
// A lost response may have committed: reread after a conflict, never replay an edit blindly.
|
|
85025
|
+
configure = async (options) => this.#configurationChanges.run(async (signal) => {
|
|
85026
|
+
if (options.expectedConfigurationRevision !== void 0 && options.expectedConfigurationRevision !== this.#configRevision) {
|
|
85027
|
+
throw new AcpExecutionError(
|
|
85028
|
+
"Session settings changed. Review the current settings before applying your selection again.",
|
|
85029
|
+
{},
|
|
85030
|
+
"session_configuration_conflict"
|
|
85031
|
+
);
|
|
85032
|
+
}
|
|
84911
85033
|
await this.#applyConfiguration(
|
|
84912
85034
|
options.valueType === "boolean" ? { type: "boolean", configId: options.configId, booleanValue: options.booleanValue } : { type: "select", configId: options.configId, value: options.value },
|
|
84913
|
-
|
|
85035
|
+
signal
|
|
84914
85036
|
);
|
|
84915
85037
|
const applied = this.#configOptions.find((option) => option.id === options.configId);
|
|
84916
85038
|
if (applied === void 0) {
|
|
@@ -84918,7 +85040,24 @@ var AgentSession = class _AgentSession {
|
|
|
84918
85040
|
}
|
|
84919
85041
|
this.#sessionConfigurations.select(applied);
|
|
84920
85042
|
this.writeStoredSession((/* @__PURE__ */ new Date()).toISOString());
|
|
84921
|
-
return this.#configOptions;
|
|
85043
|
+
return { configOptions: this.#configOptions, configurationRevision: this.#configRevision };
|
|
85044
|
+
}, options.signal);
|
|
85045
|
+
#publishConfiguration = async () => {
|
|
85046
|
+
const event = this.#store.events.append(this.#mobiusSessionId, {
|
|
85047
|
+
type: "acp",
|
|
85048
|
+
payload: {
|
|
85049
|
+
sessionUpdate: "config_option_update",
|
|
85050
|
+
configOptions: this.#configOptions.map((option) => ({
|
|
85051
|
+
category: option.category,
|
|
85052
|
+
description: option.description,
|
|
85053
|
+
id: option.id,
|
|
85054
|
+
name: option.name,
|
|
85055
|
+
...option.type === "boolean" ? { type: "boolean", currentValue: option.booleanValue } : { type: "select", currentValue: option.currentValue, options: option.values }
|
|
85056
|
+
}))
|
|
85057
|
+
}
|
|
85058
|
+
});
|
|
85059
|
+
await this.#getObserver().onSessionEvent?.(event);
|
|
85060
|
+
await this.emitConfigUpdate();
|
|
84922
85061
|
};
|
|
84923
85062
|
#target = () => ({
|
|
84924
85063
|
nativeSessionId: this.#updates.sessionId(),
|
|
@@ -85096,6 +85235,13 @@ var AgentSession = class _AgentSession {
|
|
|
85096
85235
|
this.#nativeHistoryOwnership = { kind: "agent-owned" };
|
|
85097
85236
|
};
|
|
85098
85237
|
#processEvent = async (event) => {
|
|
85238
|
+
if (event.kind === "configuration" || event.kind === "mode") {
|
|
85239
|
+
this.#configOptions = event.kind === "configuration" ? event.configOptions : this.#configOptions.map(
|
|
85240
|
+
(option) => option.category === "mode" ? { ...option, currentValue: event.modeId } : option
|
|
85241
|
+
);
|
|
85242
|
+
this.#configRevision = crypto.randomUUID();
|
|
85243
|
+
this.#captureSelectedConfigurationValues();
|
|
85244
|
+
}
|
|
85099
85245
|
if (this.#sessionLoad.kind === "capturing") {
|
|
85100
85246
|
await this.#sessionLoad.history.record(event.payload);
|
|
85101
85247
|
} else if (this.#sessionLoad.kind === "loaded" || this.#sessionLoad.kind === "execution-only") {
|
|
@@ -85116,17 +85262,7 @@ var AgentSession = class _AgentSession {
|
|
|
85116
85262
|
});
|
|
85117
85263
|
return;
|
|
85118
85264
|
case "configuration":
|
|
85119
|
-
this.#configOptions = event.configOptions;
|
|
85120
|
-
this.#configRevision += 1;
|
|
85121
|
-
this.#captureSelectedConfigurationValues();
|
|
85122
|
-
await this.emitConfigUpdate();
|
|
85123
|
-
return;
|
|
85124
85265
|
case "mode":
|
|
85125
|
-
this.#configOptions = this.#configOptions.map(
|
|
85126
|
-
(option) => option.category === "mode" ? { ...option, currentValue: event.modeId } : option
|
|
85127
|
-
);
|
|
85128
|
-
this.#configRevision += 1;
|
|
85129
|
-
this.#captureSelectedConfigurationValues();
|
|
85130
85266
|
await this.emitConfigUpdate();
|
|
85131
85267
|
return;
|
|
85132
85268
|
case "info":
|
|
@@ -85189,6 +85325,7 @@ var AgentSession = class _AgentSession {
|
|
|
85189
85325
|
}
|
|
85190
85326
|
setConfigOptions(options) {
|
|
85191
85327
|
this.#configOptions = options;
|
|
85328
|
+
this.#configRevision = crypto.randomUUID();
|
|
85192
85329
|
}
|
|
85193
85330
|
setNativeHistoryOwnership(ownership) {
|
|
85194
85331
|
this.#nativeHistoryOwnership = ownership;
|
|
@@ -85210,6 +85347,7 @@ var AgentSession = class _AgentSession {
|
|
|
85210
85347
|
emitConfigUpdate = async () => {
|
|
85211
85348
|
await this.#getObserver().onConfig({
|
|
85212
85349
|
configOptions: this.#configOptions,
|
|
85350
|
+
configurationRevision: this.#configRevision,
|
|
85213
85351
|
kind: SESSION_CONFIG_UPDATED_KIND,
|
|
85214
85352
|
requestId: `agent-update-${crypto.randomUUID()}`,
|
|
85215
85353
|
sessionId: this.#mobiusSessionId
|
|
@@ -85608,7 +85746,7 @@ var SessionManager2 = class {
|
|
|
85608
85746
|
(option) => option.id === "model" || option.category === "model"
|
|
85609
85747
|
);
|
|
85610
85748
|
const modelIsFixed = modelOption2?.type === "select" && modelOption2.values.length < 2 && modelOption2.currentValue === model;
|
|
85611
|
-
const configOptions = model === void 0 || modelIsFixed ? prepared.configOptions : await runtime.configure({
|
|
85749
|
+
const configOptions = model === void 0 || modelIsFixed ? prepared.configOptions : (await runtime.configure({
|
|
85612
85750
|
...options2,
|
|
85613
85751
|
booleanValue: false,
|
|
85614
85752
|
configId: modelOption2?.id ?? "model",
|
|
@@ -85616,7 +85754,7 @@ var SessionManager2 = class {
|
|
|
85616
85754
|
sessionId: `agent-settings-${crypto.randomUUID()}`,
|
|
85617
85755
|
value: model,
|
|
85618
85756
|
valueType: "select"
|
|
85619
|
-
});
|
|
85757
|
+
})).configOptions;
|
|
85620
85758
|
return new AgentSettingsSnapshot(
|
|
85621
85759
|
prepared.agentName,
|
|
85622
85760
|
prepared.agentVersion,
|
|
@@ -86452,19 +86590,22 @@ function promptContent(command) {
|
|
|
86452
86590
|
if (command.prompt.length > 0) {
|
|
86453
86591
|
content.push({ text: command.prompt, type: "text" });
|
|
86454
86592
|
}
|
|
86455
|
-
for (const
|
|
86456
|
-
content.push({
|
|
86457
|
-
data: image.data,
|
|
86458
|
-
mimeType: image.mimeType,
|
|
86459
|
-
type: "image"
|
|
86460
|
-
});
|
|
86461
|
-
}
|
|
86462
|
-
for (const resource of command.resources) {
|
|
86593
|
+
for (const attachment of command.attachments) {
|
|
86463
86594
|
content.push(
|
|
86464
|
-
|
|
86465
|
-
|
|
86466
|
-
|
|
86467
|
-
|
|
86595
|
+
attachment.kind === "image" ? {
|
|
86596
|
+
byteLength: attachment.byteLength,
|
|
86597
|
+
imageKey: attachment.contentKey,
|
|
86598
|
+
mimeType: attachment.mimeType,
|
|
86599
|
+
type: "external_image",
|
|
86600
|
+
uri: attachment.uri
|
|
86601
|
+
} : {
|
|
86602
|
+
byteLength: attachment.byteLength,
|
|
86603
|
+
encoding: "text",
|
|
86604
|
+
mimeType: attachment.mimeType,
|
|
86605
|
+
resourceKey: attachment.contentKey,
|
|
86606
|
+
type: "external_resource",
|
|
86607
|
+
uri: attachment.uri
|
|
86608
|
+
}
|
|
86468
86609
|
);
|
|
86469
86610
|
}
|
|
86470
86611
|
return content;
|
|
@@ -87143,8 +87284,7 @@ var SessionTurns = class {
|
|
|
87143
87284
|
queued.push({
|
|
87144
87285
|
commandId: candidate.command.commandId,
|
|
87145
87286
|
prompt: candidate.command.prompt,
|
|
87146
|
-
|
|
87147
|
-
resources: candidate.command.resources
|
|
87287
|
+
attachments: candidate.command.attachments
|
|
87148
87288
|
});
|
|
87149
87289
|
}
|
|
87150
87290
|
return { turn: turnSnapshot ?? null, queued };
|
|
@@ -87441,7 +87581,7 @@ import { join as join27 } from "node:path";
|
|
|
87441
87581
|
|
|
87442
87582
|
// src/storage/files/scratch-directory.ts
|
|
87443
87583
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
87444
|
-
import { lstat as lstat4, mkdir as mkdir5, readdir as readdir6, realpath as realpath7, rename as rename4, rm as rm3, stat as stat6, utimes, writeFile as writeFile2 } from "node:fs/promises";
|
|
87584
|
+
import { lstat as lstat4, mkdir as mkdir5, readdir as readdir6, readFile as readFile6, realpath as realpath7, rename as rename4, rm as rm3, stat as stat6, utimes, writeFile as writeFile2 } from "node:fs/promises";
|
|
87445
87585
|
import { dirname as dirname11, join as join26 } from "node:path";
|
|
87446
87586
|
async function atomicWrite(path7, bytes, signal) {
|
|
87447
87587
|
const temporary = `${path7}.${randomUUID15()}.tmp`;
|
|
@@ -87505,6 +87645,12 @@ var ScratchDirectory = class {
|
|
|
87505
87645
|
return null;
|
|
87506
87646
|
}
|
|
87507
87647
|
};
|
|
87648
|
+
/** Reads a regular file owned by this scratch directory after validating its canonical path. */
|
|
87649
|
+
read = async (path7, signal) => {
|
|
87650
|
+
const resolved = await this.resolveFile(path7);
|
|
87651
|
+
signal.throwIfAborted();
|
|
87652
|
+
return resolved === null ? null : new Uint8Array(await readFile6(resolved, { signal }));
|
|
87653
|
+
};
|
|
87508
87654
|
removeAll = async () => {
|
|
87509
87655
|
await rm3(this.#root, { force: true, recursive: true });
|
|
87510
87656
|
};
|
|
@@ -87606,6 +87752,11 @@ var LocalExternalContentStore = class {
|
|
|
87606
87752
|
signal.throwIfAborted();
|
|
87607
87753
|
return resolvedPath === null ? null : { mediaType: entry.mediaType, name: entry.name, path: resolvedPath };
|
|
87608
87754
|
};
|
|
87755
|
+
read = (sessionId, request, signal) => this.#track(async () => {
|
|
87756
|
+
const active = AbortSignal.any([signal, this.#lifetime.signal]);
|
|
87757
|
+
const resolved = await this.#resolve(sessionId, request, active);
|
|
87758
|
+
return resolved === null ? null : this.#scratch.read(resolved.path, active);
|
|
87759
|
+
});
|
|
87609
87760
|
[Symbol.asyncDispose] = async () => {
|
|
87610
87761
|
clearInterval(this.#expirationTimer);
|
|
87611
87762
|
this.#lifetime.abort();
|
|
@@ -88271,6 +88422,12 @@ function send(socket, message) {
|
|
|
88271
88422
|
}
|
|
88272
88423
|
socket.send(encodeDaemonToServiceMessage(message));
|
|
88273
88424
|
}
|
|
88425
|
+
function sendContentChunk(socket, requestId, sequence, bytes) {
|
|
88426
|
+
if (socket.readyState !== WebSocket2.OPEN) {
|
|
88427
|
+
throw new Error("Relay connection is not open");
|
|
88428
|
+
}
|
|
88429
|
+
socket.send(encodeContentChunkFrame({ bytes, requestId, sequence }));
|
|
88430
|
+
}
|
|
88274
88431
|
function reportOperationFailure(socket, requestId, sessionId, error62, runtimeTimings = []) {
|
|
88275
88432
|
if (socket.readyState !== WebSocket2.OPEN) {
|
|
88276
88433
|
return;
|
|
@@ -88890,13 +89047,133 @@ function createAgentSettingsCommands(context) {
|
|
|
88890
89047
|
];
|
|
88891
89048
|
}
|
|
88892
89049
|
|
|
89050
|
+
// src/runtime/command/registry/content-write/index.ts
|
|
89051
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
89052
|
+
function createContentWriteCommands(context) {
|
|
89053
|
+
const pending = /* @__PURE__ */ new Map();
|
|
89054
|
+
const operations = /* @__PURE__ */ new Set();
|
|
89055
|
+
const fail = (command, error62) => {
|
|
89056
|
+
pending.delete(command.requestId);
|
|
89057
|
+
send(context.socket, {
|
|
89058
|
+
code: "content_write_failed",
|
|
89059
|
+
kind: FILE_FAILED_KIND,
|
|
89060
|
+
message: error62 instanceof Error ? error62.message : "The content could not be stored",
|
|
89061
|
+
requestId: command.requestId,
|
|
89062
|
+
sessionId: command.sessionId
|
|
89063
|
+
});
|
|
89064
|
+
};
|
|
89065
|
+
const write = {
|
|
89066
|
+
kind: CONTENT_WRITE_KIND,
|
|
89067
|
+
handle: (_commandContext, message) => {
|
|
89068
|
+
if (message.kind !== CONTENT_WRITE_KIND) {
|
|
89069
|
+
throw new Error("Command kind mismatch");
|
|
89070
|
+
}
|
|
89071
|
+
const existing = pending.get(message.requestId);
|
|
89072
|
+
if (existing !== void 0) {
|
|
89073
|
+
if (JSON.stringify(existing.command) !== JSON.stringify(message)) {
|
|
89074
|
+
fail(message, new Error("The content request identifier is already in use"));
|
|
89075
|
+
return;
|
|
89076
|
+
}
|
|
89077
|
+
} else {
|
|
89078
|
+
pending.set(message.requestId, {
|
|
89079
|
+
bytes: new Uint8Array(message.byteLength),
|
|
89080
|
+
command: message,
|
|
89081
|
+
hash: createHash9("sha256"),
|
|
89082
|
+
receivedBytes: 0,
|
|
89083
|
+
sequence: 0
|
|
89084
|
+
});
|
|
89085
|
+
}
|
|
89086
|
+
send(context.socket, {
|
|
89087
|
+
kind: CONTENT_READY_KIND,
|
|
89088
|
+
requestId: message.requestId,
|
|
89089
|
+
sessionId: message.sessionId
|
|
89090
|
+
});
|
|
89091
|
+
}
|
|
89092
|
+
};
|
|
89093
|
+
const commit = {
|
|
89094
|
+
kind: CONTENT_COMMIT_KIND,
|
|
89095
|
+
handle: (_commandContext, message) => {
|
|
89096
|
+
if (message.kind !== CONTENT_COMMIT_KIND) {
|
|
89097
|
+
throw new Error("Command kind mismatch");
|
|
89098
|
+
}
|
|
89099
|
+
const state = pending.get(message.requestId);
|
|
89100
|
+
if (state === void 0 || state.command.sessionId !== message.sessionId) {
|
|
89101
|
+
fail(message, new Error("The content upload is unavailable"));
|
|
89102
|
+
return;
|
|
89103
|
+
}
|
|
89104
|
+
pending.delete(message.requestId);
|
|
89105
|
+
const operation = (async () => {
|
|
89106
|
+
try {
|
|
89107
|
+
if (state.receivedBytes !== state.command.byteLength) {
|
|
89108
|
+
throw new Error("The content upload ended at an unexpected length");
|
|
89109
|
+
}
|
|
89110
|
+
if (state.hash.digest("hex") !== state.command.contentKey) {
|
|
89111
|
+
throw new Error("The content upload failed integrity validation");
|
|
89112
|
+
}
|
|
89113
|
+
const stored = await context.externalContent.put({
|
|
89114
|
+
bytes: state.bytes,
|
|
89115
|
+
kind: state.command.contentKind,
|
|
89116
|
+
mediaType: state.command.mediaType,
|
|
89117
|
+
name: state.command.name,
|
|
89118
|
+
sessionId: state.command.sessionId,
|
|
89119
|
+
signal: context.signal
|
|
89120
|
+
});
|
|
89121
|
+
if (stored.key !== state.command.contentKey || stored.byteLength !== state.command.byteLength) {
|
|
89122
|
+
throw new Error("Stored content did not match the upload");
|
|
89123
|
+
}
|
|
89124
|
+
send(context.socket, {
|
|
89125
|
+
byteLength: stored.byteLength,
|
|
89126
|
+
contentKey: stored.key,
|
|
89127
|
+
kind: CONTENT_AVAILABLE_KIND,
|
|
89128
|
+
requestId: message.requestId,
|
|
89129
|
+
sessionId: message.sessionId
|
|
89130
|
+
});
|
|
89131
|
+
} catch (error62) {
|
|
89132
|
+
if (!context.signal.aborted) {
|
|
89133
|
+
fail(message, error62);
|
|
89134
|
+
}
|
|
89135
|
+
}
|
|
89136
|
+
})();
|
|
89137
|
+
operations.add(operation);
|
|
89138
|
+
void operation.finally(() => operations.delete(operation));
|
|
89139
|
+
}
|
|
89140
|
+
};
|
|
89141
|
+
return {
|
|
89142
|
+
commands: [write, commit],
|
|
89143
|
+
receiveChunk: (frame) => {
|
|
89144
|
+
const state = pending.get(frame.requestId);
|
|
89145
|
+
if (state === void 0) {
|
|
89146
|
+
context.diagnostics.daemonDiagnostic("content_chunk_discarded", frame.requestId, {
|
|
89147
|
+
reason: "upload_unavailable",
|
|
89148
|
+
sequence: frame.sequence.toString()
|
|
89149
|
+
});
|
|
89150
|
+
return;
|
|
89151
|
+
}
|
|
89152
|
+
if (frame.sequence !== state.sequence || state.receivedBytes + frame.bytes.byteLength > state.command.byteLength) {
|
|
89153
|
+
fail(state.command, new Error("The content upload contains invalid chunks"));
|
|
89154
|
+
return;
|
|
89155
|
+
}
|
|
89156
|
+
state.bytes.set(frame.bytes, state.receivedBytes);
|
|
89157
|
+
state.hash.update(frame.bytes);
|
|
89158
|
+
pending.set(frame.requestId, {
|
|
89159
|
+
...state,
|
|
89160
|
+
receivedBytes: state.receivedBytes + frame.bytes.byteLength,
|
|
89161
|
+
sequence: state.sequence + 1
|
|
89162
|
+
});
|
|
89163
|
+
},
|
|
89164
|
+
settle: async () => {
|
|
89165
|
+
pending.clear();
|
|
89166
|
+
await Promise.allSettled([...operations]);
|
|
89167
|
+
}
|
|
89168
|
+
};
|
|
89169
|
+
}
|
|
89170
|
+
|
|
88893
89171
|
// src/runtime/command/registry/file-read/index.ts
|
|
88894
89172
|
import { WebSocket as WebSocket5 } from "undici";
|
|
88895
89173
|
|
|
88896
89174
|
// src/session/content/session-files.ts
|
|
88897
89175
|
import { basename as basename8, extname as extname2, isAbsolute as isAbsolute16, join as join31, normalize as normalize3, resolve as resolve17 } from "node:path";
|
|
88898
89176
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
88899
|
-
var CHUNK_BYTES = 192 * 1024;
|
|
88900
89177
|
function requestedPath(value) {
|
|
88901
89178
|
if (value.includes("\0")) {
|
|
88902
89179
|
return null;
|
|
@@ -88936,7 +89213,7 @@ async function resolveFile(value, workingDirectory, signal) {
|
|
|
88936
89213
|
}
|
|
88937
89214
|
return null;
|
|
88938
89215
|
}
|
|
88939
|
-
async function streamLocalFile(command, send2, signal, workingDirectory, externalContent) {
|
|
89216
|
+
async function streamLocalFile(command, send2, sendChunk, signal, workingDirectory, externalContent) {
|
|
88940
89217
|
const external = await externalContent.resolve(command.sessionId, command.path, signal);
|
|
88941
89218
|
const target = external?.path ?? await resolveFile(command.path, workingDirectory, signal);
|
|
88942
89219
|
if (target === null) {
|
|
@@ -88958,14 +89235,8 @@ async function streamLocalFile(command, send2, signal, workingDirectory, externa
|
|
|
88958
89235
|
sessionId: command.sessionId
|
|
88959
89236
|
});
|
|
88960
89237
|
let sequence = 0;
|
|
88961
|
-
for await (const bytes of readFileChunks(target,
|
|
88962
|
-
|
|
88963
|
-
data: Buffer.from(bytes).toString("base64"),
|
|
88964
|
-
kind: FILE_CHUNK_KIND,
|
|
88965
|
-
requestId: command.requestId,
|
|
88966
|
-
sequence,
|
|
88967
|
-
sessionId: command.sessionId
|
|
88968
|
-
});
|
|
89238
|
+
for await (const bytes of readFileChunks(target, CONTENT_CHUNK_MAX_BYTES, signal)) {
|
|
89239
|
+
sendChunk(command.requestId, sequence, bytes);
|
|
88969
89240
|
sequence += 1;
|
|
88970
89241
|
}
|
|
88971
89242
|
const after = await readPathMetadata(target);
|
|
@@ -88990,6 +89261,7 @@ var fileReadCommand = {
|
|
|
88990
89261
|
void streamLocalFile(
|
|
88991
89262
|
message,
|
|
88992
89263
|
(response) => send(socket, response),
|
|
89264
|
+
(requestId, sequence, bytes) => sendContentChunk(socket, requestId, sequence, bytes),
|
|
88993
89265
|
signal,
|
|
88994
89266
|
sessions.findSessions([message.sessionId])[0]?.cwd ?? null,
|
|
88995
89267
|
externalContent
|
|
@@ -89587,7 +89859,7 @@ async function applySessionConfigurationSelection(sessions, options, selection,
|
|
|
89587
89859
|
if (sessionConfigurationMatches(option, selection)) {
|
|
89588
89860
|
return options;
|
|
89589
89861
|
}
|
|
89590
|
-
return await sessions.configureSession({
|
|
89862
|
+
return (await sessions.configureSession({
|
|
89591
89863
|
adapter,
|
|
89592
89864
|
additionalDirectories,
|
|
89593
89865
|
agent,
|
|
@@ -89599,7 +89871,7 @@ async function applySessionConfigurationSelection(sessions, options, selection,
|
|
|
89599
89871
|
signal,
|
|
89600
89872
|
value: selection.value,
|
|
89601
89873
|
valueType: selection.valueType
|
|
89602
|
-
});
|
|
89874
|
+
})).configOptions;
|
|
89603
89875
|
}
|
|
89604
89876
|
async function applyCompleteSessionConfiguration(sessions, initialOptions, selections, agent, adapter, cwd, additionalDirectories, commandId, sessionId, signal) {
|
|
89605
89877
|
let options = initialOptions;
|
|
@@ -89636,8 +89908,7 @@ function warnIgnoredSetting(event, commandId, sessionId, agentId, selection, cat
|
|
|
89636
89908
|
}
|
|
89637
89909
|
|
|
89638
89910
|
// src/session/prompt/prompt-artifacts.ts
|
|
89639
|
-
|
|
89640
|
-
var MAX_AGENT_IMAGE_BASE64_LENGTH = 4e6;
|
|
89911
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
89641
89912
|
var MAX_AGENT_RESOURCE_BYTE_LENGTH = 1e6;
|
|
89642
89913
|
var PromptArtifactError = class extends OperationError {
|
|
89643
89914
|
constructor(code, message, options = {}) {
|
|
@@ -89653,99 +89924,60 @@ var ResolvedPromptArtifacts = class {
|
|
|
89653
89924
|
this.resources = resources;
|
|
89654
89925
|
}
|
|
89655
89926
|
};
|
|
89656
|
-
var PromptArtifactReference = class {
|
|
89657
|
-
artifactId;
|
|
89658
|
-
byteLength;
|
|
89659
|
-
resource;
|
|
89660
|
-
sha256;
|
|
89661
|
-
constructor(artifactId, byteLength, sha256, resource) {
|
|
89662
|
-
this.artifactId = artifactId;
|
|
89663
|
-
this.byteLength = byteLength;
|
|
89664
|
-
this.resource = resource;
|
|
89665
|
-
this.sha256 = sha256;
|
|
89666
|
-
}
|
|
89667
|
-
};
|
|
89668
|
-
function parseReference(resource) {
|
|
89669
|
-
let url2;
|
|
89670
|
-
try {
|
|
89671
|
-
url2 = new URL(resource.uri);
|
|
89672
|
-
} catch (cause) {
|
|
89673
|
-
throw new PromptArtifactError("artifact_reference_invalid", "The prompt artifact reference is invalid", {
|
|
89674
|
-
cause
|
|
89675
|
-
});
|
|
89676
|
-
}
|
|
89677
|
-
const keys = [...url2.searchParams.keys()].sort();
|
|
89678
|
-
const artifactId = url2.pathname;
|
|
89679
|
-
const encodedByteLength = url2.searchParams.get("byteLength") ?? "";
|
|
89680
|
-
const sha256 = url2.searchParams.get("sha256") ?? "";
|
|
89681
|
-
const byteLength = Number(encodedByteLength);
|
|
89682
|
-
if (url2.protocol !== ARTIFACT_SCHEME || url2.hash.length > 0 || resource.type !== "link" || resource.text.length > 0 || !isIdentifier(artifactId) || keys.length !== 2 || keys[0] !== "byteLength" || keys[1] !== "sha256" || !/^[1-9][0-9]*$/.test(encodedByteLength) || !Number.isSafeInteger(byteLength) || !/^[a-f0-9]{64}$/.test(sha256)) {
|
|
89683
|
-
throw new PromptArtifactError("artifact_reference_invalid", "The prompt artifact reference is invalid");
|
|
89684
|
-
}
|
|
89685
|
-
return new PromptArtifactReference(artifactId, byteLength, sha256, resource);
|
|
89686
|
-
}
|
|
89687
89927
|
function isTextMediaType(mediaType) {
|
|
89688
89928
|
return mediaType.startsWith("text/") || mediaType === "application/json" || mediaType.endsWith("+json") || mediaType === "application/xml" || mediaType.endsWith("+xml");
|
|
89689
89929
|
}
|
|
89690
|
-
async function resolvePromptArtifacts(
|
|
89691
|
-
const images = [
|
|
89930
|
+
async function resolvePromptArtifacts(read, attachments, signal) {
|
|
89931
|
+
const images = [];
|
|
89692
89932
|
const resources = [];
|
|
89693
|
-
for (const
|
|
89933
|
+
for (const attachment of attachments) {
|
|
89694
89934
|
signal.throwIfAborted();
|
|
89695
|
-
|
|
89696
|
-
|
|
89697
|
-
|
|
89935
|
+
const bytes = await read(attachment, signal);
|
|
89936
|
+
if (bytes.byteLength !== attachment.byteLength || createHash10("sha256").update(bytes).digest("hex") !== attachment.contentKey) {
|
|
89937
|
+
throw new PromptArtifactError(
|
|
89938
|
+
"artifact_integrity_failed",
|
|
89939
|
+
"The prompt attachment failed integrity validation"
|
|
89940
|
+
);
|
|
89698
89941
|
}
|
|
89699
|
-
|
|
89700
|
-
|
|
89701
|
-
{
|
|
89702
|
-
artifactId: reference.artifactId,
|
|
89703
|
-
byteLength: reference.byteLength,
|
|
89704
|
-
commandId: command.commandId,
|
|
89705
|
-
mimeType: reference.resource.mimeType,
|
|
89706
|
-
sessionId: command.sessionId,
|
|
89707
|
-
sha256: reference.sha256
|
|
89708
|
-
},
|
|
89709
|
-
signal
|
|
89710
|
-
);
|
|
89711
|
-
if (resource.mimeType.startsWith("image/")) {
|
|
89712
|
-
const data = Buffer.from(bytes).toString("base64");
|
|
89713
|
-
if (data.length > MAX_AGENT_IMAGE_BASE64_LENGTH || images.length >= 8) {
|
|
89942
|
+
if (attachment.kind === "image") {
|
|
89943
|
+
if (bytes.byteLength > PROMPT_IMAGE_MAX_BYTES || images.length >= 8) {
|
|
89714
89944
|
throw new PromptArtifactError(
|
|
89715
89945
|
"artifact_too_large_for_agent",
|
|
89716
|
-
"The prompt
|
|
89946
|
+
"The prompt attachment exceeds the Agent image limit"
|
|
89717
89947
|
);
|
|
89718
89948
|
}
|
|
89719
|
-
images.push({
|
|
89949
|
+
images.push({
|
|
89950
|
+
data: Buffer.from(bytes).toString("base64"),
|
|
89951
|
+
mimeType: attachment.mimeType,
|
|
89952
|
+
name: attachment.name
|
|
89953
|
+
});
|
|
89720
89954
|
continue;
|
|
89721
89955
|
}
|
|
89722
|
-
if (!isTextMediaType(
|
|
89956
|
+
if (!isTextMediaType(attachment.mimeType)) {
|
|
89723
89957
|
throw new PromptArtifactError(
|
|
89724
89958
|
"artifact_media_type_unsupported",
|
|
89725
|
-
"The Agent cannot consume this prompt
|
|
89959
|
+
"The Agent cannot consume this prompt attachment media type"
|
|
89726
89960
|
);
|
|
89727
89961
|
}
|
|
89728
89962
|
if (bytes.byteLength > MAX_AGENT_RESOURCE_BYTE_LENGTH || resources.length >= 16) {
|
|
89729
89963
|
throw new PromptArtifactError(
|
|
89730
89964
|
"artifact_too_large_for_agent",
|
|
89731
|
-
"The prompt
|
|
89965
|
+
"The prompt attachment exceeds the Agent resource limit"
|
|
89732
89966
|
);
|
|
89733
89967
|
}
|
|
89734
89968
|
let text2;
|
|
89735
89969
|
try {
|
|
89736
89970
|
text2 = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
89737
89971
|
} catch (cause) {
|
|
89738
|
-
throw new PromptArtifactError(
|
|
89739
|
-
|
|
89740
|
-
|
|
89972
|
+
throw new PromptArtifactError(
|
|
89973
|
+
"artifact_encoding_invalid",
|
|
89974
|
+
"The prompt attachment is not valid UTF-8 text",
|
|
89975
|
+
{
|
|
89976
|
+
cause
|
|
89977
|
+
}
|
|
89978
|
+
);
|
|
89741
89979
|
}
|
|
89742
|
-
resources.push({
|
|
89743
|
-
mimeType: resource.mimeType,
|
|
89744
|
-
name: resource.name,
|
|
89745
|
-
text: text2,
|
|
89746
|
-
type: "embedded",
|
|
89747
|
-
uri: resource.uri
|
|
89748
|
-
});
|
|
89980
|
+
resources.push({ mimeType: attachment.mimeType, text: text2, type: "embedded", uri: attachment.uri });
|
|
89749
89981
|
}
|
|
89750
89982
|
return new ResolvedPromptArtifacts(images, resources);
|
|
89751
89983
|
}
|
|
@@ -89756,7 +89988,7 @@ async function executePrompt({
|
|
|
89756
89988
|
eventProjection,
|
|
89757
89989
|
command,
|
|
89758
89990
|
resolveAgent,
|
|
89759
|
-
|
|
89991
|
+
readArtifact,
|
|
89760
89992
|
reportFailure,
|
|
89761
89993
|
directories,
|
|
89762
89994
|
sessions,
|
|
@@ -89838,7 +90070,7 @@ async function executePrompt({
|
|
|
89838
90070
|
stream.epoch,
|
|
89839
90071
|
availability.disposition
|
|
89840
90072
|
);
|
|
89841
|
-
const attachments = await resolvePromptArtifacts(
|
|
90073
|
+
const attachments = await resolvePromptArtifacts(readArtifact, command.attachments, signal);
|
|
89842
90074
|
let stopReason;
|
|
89843
90075
|
if (availability.disposition === SessionPromptDisposition.Steer) {
|
|
89844
90076
|
await sessions.steerPrompt({
|
|
@@ -89898,115 +90130,6 @@ async function executePrompt({
|
|
|
89898
90130
|
}
|
|
89899
90131
|
}
|
|
89900
90132
|
|
|
89901
|
-
// src/runtime/relay/artifact-download.ts
|
|
89902
|
-
import { createHash as createHash9 } from "node:crypto";
|
|
89903
|
-
import { fetch as fetch4 } from "undici";
|
|
89904
|
-
var ARTIFACT_DOWNLOAD_TIMEOUT_MILLISECONDS = 2e4;
|
|
89905
|
-
function downloadUrl(config2, artifact) {
|
|
89906
|
-
const url2 = relayHttpEndpoint(config2.relayUrl);
|
|
89907
|
-
let channelPath = "";
|
|
89908
|
-
if (url2.pathname.endsWith("/daemon")) {
|
|
89909
|
-
channelPath = url2.pathname.slice(0, -"/daemon".length);
|
|
89910
|
-
} else {
|
|
89911
|
-
const runtimePath = "/v1/runtimes/connect";
|
|
89912
|
-
if (!url2.pathname.endsWith(runtimePath)) {
|
|
89913
|
-
throw new PromptArtifactError("artifact_endpoint_invalid", "The Relay artifact endpoint is invalid");
|
|
89914
|
-
}
|
|
89915
|
-
channelPath = `${url2.pathname.slice(0, -runtimePath.length)}/channels/${encodeURIComponent(config2.channelId)}`;
|
|
89916
|
-
}
|
|
89917
|
-
url2.pathname = `${channelPath}/sessions/${encodeURIComponent(artifact.sessionId)}/commands/${encodeURIComponent(artifact.commandId)}/artifacts/${encodeURIComponent(artifact.artifactId)}/content`;
|
|
89918
|
-
return url2;
|
|
89919
|
-
}
|
|
89920
|
-
async function responseBytes(response, expectedByteLength, signal) {
|
|
89921
|
-
const declaredLength = response.headers.get("content-length") ?? "";
|
|
89922
|
-
if (!/^(0|[1-9][0-9]*)$/.test(declaredLength) || Number(declaredLength) !== expectedByteLength || response.body === null) {
|
|
89923
|
-
throw new PromptArtifactError("artifact_integrity_failed", "The prompt artifact failed integrity validation");
|
|
89924
|
-
}
|
|
89925
|
-
const reader = response.body.getReader();
|
|
89926
|
-
const chunks = [];
|
|
89927
|
-
let byteLength = 0;
|
|
89928
|
-
try {
|
|
89929
|
-
while (true) {
|
|
89930
|
-
signal.throwIfAborted();
|
|
89931
|
-
const chunk = await reader.read();
|
|
89932
|
-
signal.throwIfAborted();
|
|
89933
|
-
if (chunk.done) {
|
|
89934
|
-
break;
|
|
89935
|
-
}
|
|
89936
|
-
byteLength += chunk.value.byteLength;
|
|
89937
|
-
if (byteLength > expectedByteLength) {
|
|
89938
|
-
await reader.cancel("Artifact response exceeded its authorization");
|
|
89939
|
-
throw new PromptArtifactError(
|
|
89940
|
-
"artifact_integrity_failed",
|
|
89941
|
-
"The prompt artifact failed integrity validation"
|
|
89942
|
-
);
|
|
89943
|
-
}
|
|
89944
|
-
chunks.push(chunk.value);
|
|
89945
|
-
}
|
|
89946
|
-
} finally {
|
|
89947
|
-
reader.releaseLock();
|
|
89948
|
-
}
|
|
89949
|
-
if (byteLength !== expectedByteLength) {
|
|
89950
|
-
throw new PromptArtifactError("artifact_integrity_failed", "The prompt artifact failed integrity validation");
|
|
89951
|
-
}
|
|
89952
|
-
const bytes = new Uint8Array(byteLength);
|
|
89953
|
-
let offset = 0;
|
|
89954
|
-
for (const chunk of chunks) {
|
|
89955
|
-
bytes.set(chunk, offset);
|
|
89956
|
-
offset += chunk.byteLength;
|
|
89957
|
-
}
|
|
89958
|
-
return bytes;
|
|
89959
|
-
}
|
|
89960
|
-
async function downloadPromptArtifact(config2, artifact, signal) {
|
|
89961
|
-
signal.throwIfAborted();
|
|
89962
|
-
const timeoutSignal = AbortSignal.timeout(ARTIFACT_DOWNLOAD_TIMEOUT_MILLISECONDS);
|
|
89963
|
-
const requestSignal = AbortSignal.any([signal, timeoutSignal]);
|
|
89964
|
-
let response;
|
|
89965
|
-
try {
|
|
89966
|
-
response = await fetch4(downloadUrl(config2, artifact), {
|
|
89967
|
-
dispatcher: environmentProxyDispatcher,
|
|
89968
|
-
headers: {
|
|
89969
|
-
accept: artifact.mimeType,
|
|
89970
|
-
"accept-encoding": "identity",
|
|
89971
|
-
...relayAuthorization(config2.relayUrl)
|
|
89972
|
-
},
|
|
89973
|
-
signal: requestSignal
|
|
89974
|
-
});
|
|
89975
|
-
if (!response.ok) {
|
|
89976
|
-
await response.body?.cancel();
|
|
89977
|
-
throw new PromptArtifactError(
|
|
89978
|
-
"artifact_download_rejected",
|
|
89979
|
-
"The Relay rejected the prompt artifact download"
|
|
89980
|
-
);
|
|
89981
|
-
}
|
|
89982
|
-
if (response.headers.get("content-type") !== artifact.mimeType || response.headers.get("x-mobius-artifact-id") !== artifact.artifactId || response.headers.get("x-mobius-sha256") !== artifact.sha256) {
|
|
89983
|
-
await response.body?.cancel();
|
|
89984
|
-
throw new PromptArtifactError(
|
|
89985
|
-
"artifact_integrity_failed",
|
|
89986
|
-
"The prompt artifact failed integrity validation"
|
|
89987
|
-
);
|
|
89988
|
-
}
|
|
89989
|
-
const bytes = await responseBytes(response, artifact.byteLength, requestSignal);
|
|
89990
|
-
if (createHash9("sha256").update(bytes).digest("hex") !== artifact.sha256) {
|
|
89991
|
-
throw new PromptArtifactError(
|
|
89992
|
-
"artifact_integrity_failed",
|
|
89993
|
-
"The prompt artifact failed integrity validation"
|
|
89994
|
-
);
|
|
89995
|
-
}
|
|
89996
|
-
return bytes;
|
|
89997
|
-
} catch (error62) {
|
|
89998
|
-
signal.throwIfAborted();
|
|
89999
|
-
if (error62 instanceof PromptArtifactError) {
|
|
90000
|
-
throw error62;
|
|
90001
|
-
}
|
|
90002
|
-
throw new PromptArtifactError(
|
|
90003
|
-
timeoutSignal.aborted ? "artifact_download_timeout" : "artifact_download_failed",
|
|
90004
|
-
timeoutSignal.aborted ? "The prompt artifact download timed out" : "The prompt artifact could not be downloaded",
|
|
90005
|
-
{ cause: error62 }
|
|
90006
|
-
);
|
|
90007
|
-
}
|
|
90008
|
-
}
|
|
90009
|
-
|
|
90010
90133
|
// src/runtime/command/registry/prompt.ts
|
|
90011
90134
|
var sessionPromptCommand = {
|
|
90012
90135
|
kind: SESSION_PROMPT_KIND,
|
|
@@ -90060,7 +90183,17 @@ var sessionPromptCommand = {
|
|
|
90060
90183
|
eventProjection: context.eventProjection,
|
|
90061
90184
|
command: message,
|
|
90062
90185
|
resolveAgent: context.resolveAgent,
|
|
90063
|
-
|
|
90186
|
+
readArtifact: async (artifact, signal) => {
|
|
90187
|
+
const bytes = await context.externalContent.read(
|
|
90188
|
+
message.sessionId,
|
|
90189
|
+
`mobius-content:${artifact.kind}:${artifact.contentKey}`,
|
|
90190
|
+
signal
|
|
90191
|
+
);
|
|
90192
|
+
if (bytes === null) {
|
|
90193
|
+
throw new Error("The prompt attachment is unavailable");
|
|
90194
|
+
}
|
|
90195
|
+
return bytes;
|
|
90196
|
+
},
|
|
90064
90197
|
reportFailure: context.diagnostics.daemonDiagnostic,
|
|
90065
90198
|
directories: context.directories,
|
|
90066
90199
|
sessions: context.sessions,
|
|
@@ -90142,7 +90275,7 @@ async function prepareSession(command, recovery, closed, config2, resolveAgent,
|
|
|
90142
90275
|
};
|
|
90143
90276
|
const prepared = command.transient === true ? await sessions.inspectSession(preparation, metrics) : recovery.kind === "history-required" ? await sessions.restoreSession(preparation, metrics, closed) : await sessions.prepareSession(preparation, metrics, closed);
|
|
90144
90277
|
const configuration = command.configuration;
|
|
90145
|
-
const
|
|
90278
|
+
const snapshot = configuration === void 0 ? prepared : await metrics.measure(
|
|
90146
90279
|
"configuration",
|
|
90147
90280
|
async () => await sessions.configureSession({
|
|
90148
90281
|
...preparation,
|
|
@@ -90160,7 +90293,8 @@ async function prepareSession(command, recovery, closed, config2, resolveAgent,
|
|
|
90160
90293
|
agentVersion: prepared.agentVersion,
|
|
90161
90294
|
capabilities: prepared.capabilities,
|
|
90162
90295
|
commands: prepared.commands,
|
|
90163
|
-
configOptions,
|
|
90296
|
+
configOptions: snapshot.configOptions,
|
|
90297
|
+
configurationRevision: snapshot.configurationRevision,
|
|
90164
90298
|
directoryId: command.directoryId,
|
|
90165
90299
|
directoryLabel: resolved.directoryLabel,
|
|
90166
90300
|
kind: "session.ready",
|
|
@@ -90293,11 +90427,12 @@ async function executeSessionConfigure(socket, command, config2, resolveAgent, d
|
|
|
90293
90427
|
command.additionalDirectoryIds,
|
|
90294
90428
|
signal
|
|
90295
90429
|
);
|
|
90296
|
-
const
|
|
90430
|
+
const snapshot = await sessions.configureSession({
|
|
90297
90431
|
additionalDirectories: resolved.additionalDirectories,
|
|
90298
90432
|
...await resolveAgent(command.agentId, signal, command.sessionId),
|
|
90299
90433
|
booleanValue: command.booleanValue,
|
|
90300
90434
|
configId: command.configId,
|
|
90435
|
+
...command.expectedConfigurationRevision === void 0 ? {} : { expectedConfigurationRevision: command.expectedConfigurationRevision },
|
|
90301
90436
|
cwd: resolved.cwd,
|
|
90302
90437
|
requestId: command.requestId,
|
|
90303
90438
|
sessionId: command.sessionId,
|
|
@@ -90306,7 +90441,7 @@ async function executeSessionConfigure(socket, command, config2, resolveAgent, d
|
|
|
90306
90441
|
valueType: command.valueType
|
|
90307
90442
|
});
|
|
90308
90443
|
send(socket, {
|
|
90309
|
-
|
|
90444
|
+
...snapshot,
|
|
90310
90445
|
kind: "session.config.updated",
|
|
90311
90446
|
requestId: command.requestId,
|
|
90312
90447
|
sessionId: command.sessionId
|
|
@@ -90426,6 +90561,7 @@ async function executeSessionConfigRead(socket, command, config2, resolveAgent,
|
|
|
90426
90561
|
);
|
|
90427
90562
|
send(socket, {
|
|
90428
90563
|
configOptions: ready.configOptions,
|
|
90564
|
+
configurationRevision: ready.configurationRevision,
|
|
90429
90565
|
kind: SESSION_CONFIG_READ_RESULT_KIND,
|
|
90430
90566
|
requestId: command.requestId,
|
|
90431
90567
|
sessionId: command.sessionId
|
|
@@ -90465,6 +90601,7 @@ var sessionConfigReadCommand = {
|
|
|
90465
90601
|
|
|
90466
90602
|
// src/runtime/command/registry/index.ts
|
|
90467
90603
|
function createCommandRegistry(context) {
|
|
90604
|
+
const contentWrites = createContentWriteCommands(context);
|
|
90468
90605
|
const commands = [
|
|
90469
90606
|
runtimeDiagnosticsCommand,
|
|
90470
90607
|
runtimePingCommand,
|
|
@@ -90473,6 +90610,7 @@ function createCommandRegistry(context) {
|
|
|
90473
90610
|
...createNativeSessionCommands(context),
|
|
90474
90611
|
...createAgentCatalogCommands(context),
|
|
90475
90612
|
...createAgentSettingsCommands(context),
|
|
90613
|
+
...contentWrites.commands,
|
|
90476
90614
|
fileReadCommand,
|
|
90477
90615
|
sessionCancelCommand,
|
|
90478
90616
|
sessionCloseCommand,
|
|
@@ -90495,8 +90633,12 @@ function createCommandRegistry(context) {
|
|
|
90495
90633
|
}
|
|
90496
90634
|
command.handle(context, message);
|
|
90497
90635
|
},
|
|
90636
|
+
dispatchChunk: (message) => contentWrites.receiveChunk(decodeContentChunkFrame(message)),
|
|
90498
90637
|
settle: async () => {
|
|
90499
|
-
await Promise.all(
|
|
90638
|
+
await Promise.all([
|
|
90639
|
+
contentWrites.settle(),
|
|
90640
|
+
...commands.flatMap((command) => command.settle === void 0 ? [] : [command.settle()])
|
|
90641
|
+
]);
|
|
90500
90642
|
}
|
|
90501
90643
|
};
|
|
90502
90644
|
}
|
|
@@ -90558,6 +90700,7 @@ function connectRelay(url2, signal) {
|
|
|
90558
90700
|
dispatcher,
|
|
90559
90701
|
headers
|
|
90560
90702
|
});
|
|
90703
|
+
socket.binaryType = "arraybuffer";
|
|
90561
90704
|
let released = false;
|
|
90562
90705
|
const release = (reason) => {
|
|
90563
90706
|
if (released) {
|
|
@@ -90921,7 +91064,16 @@ async function runRelayConnection({
|
|
|
90921
91064
|
const handleMessage = (event) => {
|
|
90922
91065
|
const encoded = event.data;
|
|
90923
91066
|
if (typeof encoded !== "string") {
|
|
90924
|
-
|
|
91067
|
+
try {
|
|
91068
|
+
commands.dispatchChunk(encoded);
|
|
91069
|
+
} catch (error62) {
|
|
91070
|
+
failAndClose(
|
|
91071
|
+
new Error("Relay sent an invalid content chunk", { cause: error62 }),
|
|
91072
|
+
4008,
|
|
91073
|
+
"Invalid content chunk",
|
|
91074
|
+
"protocol"
|
|
91075
|
+
);
|
|
91076
|
+
}
|
|
90925
91077
|
return;
|
|
90926
91078
|
}
|
|
90927
91079
|
try {
|