@moxt-ai/mobius 0.0.323 → 0.0.325
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/handler/daemon/upgrade.d.ts.map +1 -1
- package/dist/cli/handler/daemon/upgrade.js +2 -5
- package/dist/cli/handler/daemon/upgrade.js.map +1 -1
- package/dist/cli.js +717 -559
- package/dist/cli.js.map +4 -4
- package/dist/daemon/lifecycle/manager-client.d.ts +1 -1
- package/dist/daemon/lifecycle/manager-client.d.ts.map +1 -1
- package/dist/daemon/lifecycle/manager-client.js +9 -1
- package/dist/daemon/lifecycle/manager-client.js.map +1 -1
- package/dist/daemon/lifecycle/worker.js +2 -2
- package/dist/daemon/lifecycle/worker.js.map +1 -1
- package/dist/daemon/pairing/pair-local-machine.d.ts +1 -0
- package/dist/daemon/pairing/pair-local-machine.d.ts.map +1 -1
- package/dist/daemon/pairing/pair-local-machine.js +10 -3
- package/dist/daemon/pairing/pair-local-machine.js.map +1 -1
- 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 +427 -328
- 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.325",
|
|
32279
32386
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
32280
32387
|
type: "module",
|
|
32281
32388
|
bin: {
|
|
@@ -83028,59 +83135,6 @@ async function openRuntimeInstallationStore(options, signal) {
|
|
|
83028
83135
|
return await RuntimeInstallationStore.open(options, signal);
|
|
83029
83136
|
}
|
|
83030
83137
|
|
|
83031
|
-
// src/daemon/control/local-client.ts
|
|
83032
|
-
var MAXIMUM_MESSAGE_BYTES = 64 * 1024;
|
|
83033
|
-
var managerPlatform = platformSupportFor(process.platform);
|
|
83034
|
-
|
|
83035
|
-
// src/daemon/control/protocol.ts
|
|
83036
|
-
var workerLaunch = external_exports.object({
|
|
83037
|
-
executable: external_exports.string().min(1),
|
|
83038
|
-
entry: external_exports.string().min(1),
|
|
83039
|
-
version: external_exports.string().min(1).max(128)
|
|
83040
|
-
}).readonly();
|
|
83041
|
-
var transition = {
|
|
83042
|
-
id: external_exports.string().min(1).max(256),
|
|
83043
|
-
context: external_exports.string().max(256),
|
|
83044
|
-
previous: workerLaunch,
|
|
83045
|
-
next: workerLaunch
|
|
83046
|
-
};
|
|
83047
|
-
var daemonSwitchState = external_exports.discriminatedUnion("kind", [
|
|
83048
|
-
external_exports.object({ ...transition, kind: external_exports.literal("switching") }),
|
|
83049
|
-
external_exports.object({ ...transition, kind: external_exports.literal("switched") }),
|
|
83050
|
-
external_exports.object({
|
|
83051
|
-
...transition,
|
|
83052
|
-
kind: external_exports.literal("rolled-back"),
|
|
83053
|
-
code: external_exports.string(),
|
|
83054
|
-
message: external_exports.string(),
|
|
83055
|
-
stdout: external_exports.string().max(4096),
|
|
83056
|
-
stderr: external_exports.string().max(4096),
|
|
83057
|
-
retryAfter: external_exports.number().int().nonnegative()
|
|
83058
|
-
})
|
|
83059
|
-
]).readonly();
|
|
83060
|
-
var lifecycleCommand = external_exports.discriminatedUnion("kind", [
|
|
83061
|
-
external_exports.object({ kind: external_exports.literal("status") }),
|
|
83062
|
-
external_exports.object({ kind: external_exports.literal("ensure"), launch: workerLaunch }),
|
|
83063
|
-
external_exports.object({ kind: external_exports.literal("stop") }),
|
|
83064
|
-
external_exports.object({
|
|
83065
|
-
kind: external_exports.literal("switch"),
|
|
83066
|
-
id: external_exports.string().min(1).max(256),
|
|
83067
|
-
context: external_exports.string().max(256),
|
|
83068
|
-
launch: workerLaunch
|
|
83069
|
-
}),
|
|
83070
|
-
external_exports.object({ kind: external_exports.literal("switch-status"), wait: external_exports.boolean() })
|
|
83071
|
-
]).readonly();
|
|
83072
|
-
var lifecycleResponse = external_exports.discriminatedUnion("kind", [
|
|
83073
|
-
external_exports.object({
|
|
83074
|
-
kind: external_exports.literal("status"),
|
|
83075
|
-
protocolVersion: external_exports.literal(2),
|
|
83076
|
-
worker: external_exports.object({ pid: external_exports.number().int().positive(), version: external_exports.string() }).readonly().nullable()
|
|
83077
|
-
}),
|
|
83078
|
-
external_exports.object({ kind: external_exports.literal("switch-status"), state: daemonSwitchState.nullable() }),
|
|
83079
|
-
external_exports.object({ kind: external_exports.literal("stopped") }),
|
|
83080
|
-
external_exports.object({ kind: external_exports.literal("switching") }),
|
|
83081
|
-
external_exports.object({ kind: external_exports.literal("error"), code: external_exports.string(), message: external_exports.string() })
|
|
83082
|
-
]).readonly();
|
|
83083
|
-
|
|
83084
83138
|
// src/daemon/pairing/pair-local-machine.ts
|
|
83085
83139
|
var PAIRING_TIMEOUT_MILLISECONDS = 2e4;
|
|
83086
83140
|
var PAIRING_CODE_PATTERN = /^[A-HJ-NP-Z2-9]{4}(?:-[A-HJ-NP-Z2-9]{4}){4}$/;
|
|
@@ -83559,7 +83613,8 @@ var PreparedSession = class {
|
|
|
83559
83613
|
configOptions;
|
|
83560
83614
|
prompted;
|
|
83561
83615
|
restored;
|
|
83562
|
-
|
|
83616
|
+
configurationRevision;
|
|
83617
|
+
constructor(agentName, agentVersion, capabilities, commands, configOptions, prompted, restored, configurationRevision) {
|
|
83563
83618
|
this.agentName = agentName;
|
|
83564
83619
|
this.agentVersion = agentVersion;
|
|
83565
83620
|
this.capabilities = capabilities;
|
|
@@ -83567,6 +83622,7 @@ var PreparedSession = class {
|
|
|
83567
83622
|
this.configOptions = configOptions;
|
|
83568
83623
|
this.prompted = prompted;
|
|
83569
83624
|
this.restored = restored;
|
|
83625
|
+
this.configurationRevision = configurationRevision;
|
|
83570
83626
|
}
|
|
83571
83627
|
};
|
|
83572
83628
|
var AgentSettingsSnapshot = class {
|
|
@@ -84385,7 +84441,7 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
84385
84441
|
session.store.remove(session.sessionId);
|
|
84386
84442
|
stored = session.metrics.measureSync("session-state-read", () => session.store.read(session.sessionId));
|
|
84387
84443
|
}
|
|
84388
|
-
let
|
|
84444
|
+
let lifecycleResponse;
|
|
84389
84445
|
if (origin?.kind === "fork") {
|
|
84390
84446
|
if (!session.capabilities.unstableForkSession) {
|
|
84391
84447
|
throw new AcpExecutionError(
|
|
@@ -84431,7 +84487,7 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
84431
84487
|
if (recovery.kind === "execution-only") {
|
|
84432
84488
|
session.startExecutionOnlyCapture();
|
|
84433
84489
|
}
|
|
84434
|
-
|
|
84490
|
+
lifecycleResponse = forked;
|
|
84435
84491
|
} else if (stored instanceof FoundStoredSession && stored.session.agentId === session.agentId && stored.session.cwd === session.cwd && arraysEqual(stored.session.additionalDirectories, session.additionalDirectories)) {
|
|
84436
84492
|
session.selectNativeSession(stored.session.nativeSessionId);
|
|
84437
84493
|
session.setPrompted(stored.session.prompted);
|
|
@@ -84445,13 +84501,13 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
84445
84501
|
"native_history_unsupported"
|
|
84446
84502
|
);
|
|
84447
84503
|
}
|
|
84448
|
-
|
|
84504
|
+
lifecycleResponse = await session.metrics.measure(
|
|
84449
84505
|
"session-load",
|
|
84450
84506
|
async () => (await session.loadSession(signal, "ACP agent exited while loading a session")).response
|
|
84451
84507
|
);
|
|
84452
84508
|
} else if (recovery.kind === "execution-only") {
|
|
84453
84509
|
try {
|
|
84454
|
-
|
|
84510
|
+
lifecycleResponse = await session.metrics.measure(
|
|
84455
84511
|
"session-resume",
|
|
84456
84512
|
async () => await session.race(
|
|
84457
84513
|
session.agentRequest(
|
|
@@ -84481,7 +84537,7 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
84481
84537
|
}
|
|
84482
84538
|
session.startExecutionOnlyCapture();
|
|
84483
84539
|
} else if (session.capabilities.resumeSession) {
|
|
84484
|
-
|
|
84540
|
+
lifecycleResponse = await session.metrics.measure(
|
|
84485
84541
|
"session-resume",
|
|
84486
84542
|
async () => await session.race(
|
|
84487
84543
|
session.agentRequest(
|
|
@@ -84499,7 +84555,7 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
84499
84555
|
)
|
|
84500
84556
|
);
|
|
84501
84557
|
} else if (session.capabilities.loadSession) {
|
|
84502
|
-
|
|
84558
|
+
lifecycleResponse = await session.metrics.measure(
|
|
84503
84559
|
"session-load",
|
|
84504
84560
|
async () => (await session.loadSession(signal, "ACP agent exited while loading a session")).response
|
|
84505
84561
|
);
|
|
@@ -84542,10 +84598,10 @@ async function restoreSession(session, signal, recovery, origin) {
|
|
|
84542
84598
|
if (recovery.kind === "execution-only") {
|
|
84543
84599
|
session.startExecutionOnlyCapture();
|
|
84544
84600
|
}
|
|
84545
|
-
|
|
84601
|
+
lifecycleResponse = created;
|
|
84546
84602
|
}
|
|
84547
|
-
session.restrictSessionCapabilities(
|
|
84548
|
-
session.setConfigOptions(session.sessionConfigProtocol.normalizeLifecycle(
|
|
84603
|
+
session.restrictSessionCapabilities(lifecycleResponse);
|
|
84604
|
+
session.setConfigOptions(session.sessionConfigProtocol.normalizeLifecycle(lifecycleResponse));
|
|
84549
84605
|
if (stored instanceof FoundStoredSession && session.restored) {
|
|
84550
84606
|
await session.restoreStoredConfigurations(stored.session, signal);
|
|
84551
84607
|
}
|
|
@@ -84606,7 +84662,8 @@ var AgentSession = class _AgentSession {
|
|
|
84606
84662
|
#agentVersion = "";
|
|
84607
84663
|
#capabilities = unsupportedSessionCapabilities();
|
|
84608
84664
|
#commands = [];
|
|
84609
|
-
#configRevision =
|
|
84665
|
+
#configRevision = crypto.randomUUID();
|
|
84666
|
+
#configurationChanges = new SerialTaskQueue();
|
|
84610
84667
|
#configOptions = [];
|
|
84611
84668
|
#sessionConfigurations = new SessionConfigurations();
|
|
84612
84669
|
#nativeHistoryOwnership = { kind: "unbound" };
|
|
@@ -84775,7 +84832,8 @@ var AgentSession = class _AgentSession {
|
|
|
84775
84832
|
this.#commands,
|
|
84776
84833
|
this.#configOptions,
|
|
84777
84834
|
this.#prompted,
|
|
84778
|
-
this.#restored
|
|
84835
|
+
this.#restored,
|
|
84836
|
+
this.#configRevision
|
|
84779
84837
|
);
|
|
84780
84838
|
ensureHistoryLoaded = async (signal) => {
|
|
84781
84839
|
if (!this.#capabilities.loadSession) {
|
|
@@ -84905,12 +84963,23 @@ var AgentSession = class _AgentSession {
|
|
|
84905
84963
|
const configured = await this.#adapter.configureSession(this.#target(), selection, signal);
|
|
84906
84964
|
if (this.#configRevision === configRevision) {
|
|
84907
84965
|
this.#configOptions = configured;
|
|
84966
|
+
this.#configRevision = crypto.randomUUID();
|
|
84967
|
+
await this.#publishConfiguration();
|
|
84908
84968
|
}
|
|
84909
84969
|
};
|
|
84910
|
-
|
|
84970
|
+
// The revision check and Agent mutation share one queue, including legacy callers.
|
|
84971
|
+
// A lost response may have committed: reread after a conflict, never replay an edit blindly.
|
|
84972
|
+
configure = async (options) => this.#configurationChanges.run(async (signal) => {
|
|
84973
|
+
if (options.expectedConfigurationRevision !== void 0 && options.expectedConfigurationRevision !== this.#configRevision) {
|
|
84974
|
+
throw new AcpExecutionError(
|
|
84975
|
+
"Session settings changed. Review the current settings before applying your selection again.",
|
|
84976
|
+
{},
|
|
84977
|
+
"session_configuration_conflict"
|
|
84978
|
+
);
|
|
84979
|
+
}
|
|
84911
84980
|
await this.#applyConfiguration(
|
|
84912
84981
|
options.valueType === "boolean" ? { type: "boolean", configId: options.configId, booleanValue: options.booleanValue } : { type: "select", configId: options.configId, value: options.value },
|
|
84913
|
-
|
|
84982
|
+
signal
|
|
84914
84983
|
);
|
|
84915
84984
|
const applied = this.#configOptions.find((option) => option.id === options.configId);
|
|
84916
84985
|
if (applied === void 0) {
|
|
@@ -84918,7 +84987,24 @@ var AgentSession = class _AgentSession {
|
|
|
84918
84987
|
}
|
|
84919
84988
|
this.#sessionConfigurations.select(applied);
|
|
84920
84989
|
this.writeStoredSession((/* @__PURE__ */ new Date()).toISOString());
|
|
84921
|
-
return this.#configOptions;
|
|
84990
|
+
return { configOptions: this.#configOptions, configurationRevision: this.#configRevision };
|
|
84991
|
+
}, options.signal);
|
|
84992
|
+
#publishConfiguration = async () => {
|
|
84993
|
+
const event = this.#store.events.append(this.#mobiusSessionId, {
|
|
84994
|
+
type: "acp",
|
|
84995
|
+
payload: {
|
|
84996
|
+
sessionUpdate: "config_option_update",
|
|
84997
|
+
configOptions: this.#configOptions.map((option) => ({
|
|
84998
|
+
category: option.category,
|
|
84999
|
+
description: option.description,
|
|
85000
|
+
id: option.id,
|
|
85001
|
+
name: option.name,
|
|
85002
|
+
...option.type === "boolean" ? { type: "boolean", currentValue: option.booleanValue } : { type: "select", currentValue: option.currentValue, options: option.values }
|
|
85003
|
+
}))
|
|
85004
|
+
}
|
|
85005
|
+
});
|
|
85006
|
+
await this.#getObserver().onSessionEvent?.(event);
|
|
85007
|
+
await this.emitConfigUpdate();
|
|
84922
85008
|
};
|
|
84923
85009
|
#target = () => ({
|
|
84924
85010
|
nativeSessionId: this.#updates.sessionId(),
|
|
@@ -85096,6 +85182,13 @@ var AgentSession = class _AgentSession {
|
|
|
85096
85182
|
this.#nativeHistoryOwnership = { kind: "agent-owned" };
|
|
85097
85183
|
};
|
|
85098
85184
|
#processEvent = async (event) => {
|
|
85185
|
+
if (event.kind === "configuration" || event.kind === "mode") {
|
|
85186
|
+
this.#configOptions = event.kind === "configuration" ? event.configOptions : this.#configOptions.map(
|
|
85187
|
+
(option) => option.category === "mode" ? { ...option, currentValue: event.modeId } : option
|
|
85188
|
+
);
|
|
85189
|
+
this.#configRevision = crypto.randomUUID();
|
|
85190
|
+
this.#captureSelectedConfigurationValues();
|
|
85191
|
+
}
|
|
85099
85192
|
if (this.#sessionLoad.kind === "capturing") {
|
|
85100
85193
|
await this.#sessionLoad.history.record(event.payload);
|
|
85101
85194
|
} else if (this.#sessionLoad.kind === "loaded" || this.#sessionLoad.kind === "execution-only") {
|
|
@@ -85116,17 +85209,7 @@ var AgentSession = class _AgentSession {
|
|
|
85116
85209
|
});
|
|
85117
85210
|
return;
|
|
85118
85211
|
case "configuration":
|
|
85119
|
-
this.#configOptions = event.configOptions;
|
|
85120
|
-
this.#configRevision += 1;
|
|
85121
|
-
this.#captureSelectedConfigurationValues();
|
|
85122
|
-
await this.emitConfigUpdate();
|
|
85123
|
-
return;
|
|
85124
85212
|
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
85213
|
await this.emitConfigUpdate();
|
|
85131
85214
|
return;
|
|
85132
85215
|
case "info":
|
|
@@ -85189,6 +85272,7 @@ var AgentSession = class _AgentSession {
|
|
|
85189
85272
|
}
|
|
85190
85273
|
setConfigOptions(options) {
|
|
85191
85274
|
this.#configOptions = options;
|
|
85275
|
+
this.#configRevision = crypto.randomUUID();
|
|
85192
85276
|
}
|
|
85193
85277
|
setNativeHistoryOwnership(ownership) {
|
|
85194
85278
|
this.#nativeHistoryOwnership = ownership;
|
|
@@ -85210,6 +85294,7 @@ var AgentSession = class _AgentSession {
|
|
|
85210
85294
|
emitConfigUpdate = async () => {
|
|
85211
85295
|
await this.#getObserver().onConfig({
|
|
85212
85296
|
configOptions: this.#configOptions,
|
|
85297
|
+
configurationRevision: this.#configRevision,
|
|
85213
85298
|
kind: SESSION_CONFIG_UPDATED_KIND,
|
|
85214
85299
|
requestId: `agent-update-${crypto.randomUUID()}`,
|
|
85215
85300
|
sessionId: this.#mobiusSessionId
|
|
@@ -85608,7 +85693,7 @@ var SessionManager2 = class {
|
|
|
85608
85693
|
(option) => option.id === "model" || option.category === "model"
|
|
85609
85694
|
);
|
|
85610
85695
|
const modelIsFixed = modelOption2?.type === "select" && modelOption2.values.length < 2 && modelOption2.currentValue === model;
|
|
85611
|
-
const configOptions = model === void 0 || modelIsFixed ? prepared.configOptions : await runtime.configure({
|
|
85696
|
+
const configOptions = model === void 0 || modelIsFixed ? prepared.configOptions : (await runtime.configure({
|
|
85612
85697
|
...options2,
|
|
85613
85698
|
booleanValue: false,
|
|
85614
85699
|
configId: modelOption2?.id ?? "model",
|
|
@@ -85616,7 +85701,7 @@ var SessionManager2 = class {
|
|
|
85616
85701
|
sessionId: `agent-settings-${crypto.randomUUID()}`,
|
|
85617
85702
|
value: model,
|
|
85618
85703
|
valueType: "select"
|
|
85619
|
-
});
|
|
85704
|
+
})).configOptions;
|
|
85620
85705
|
return new AgentSettingsSnapshot(
|
|
85621
85706
|
prepared.agentName,
|
|
85622
85707
|
prepared.agentVersion,
|
|
@@ -86452,19 +86537,22 @@ function promptContent(command) {
|
|
|
86452
86537
|
if (command.prompt.length > 0) {
|
|
86453
86538
|
content.push({ text: command.prompt, type: "text" });
|
|
86454
86539
|
}
|
|
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) {
|
|
86540
|
+
for (const attachment of command.attachments) {
|
|
86463
86541
|
content.push(
|
|
86464
|
-
|
|
86465
|
-
|
|
86466
|
-
|
|
86467
|
-
|
|
86542
|
+
attachment.kind === "image" ? {
|
|
86543
|
+
byteLength: attachment.byteLength,
|
|
86544
|
+
imageKey: attachment.contentKey,
|
|
86545
|
+
mimeType: attachment.mimeType,
|
|
86546
|
+
type: "external_image",
|
|
86547
|
+
uri: attachment.uri
|
|
86548
|
+
} : {
|
|
86549
|
+
byteLength: attachment.byteLength,
|
|
86550
|
+
encoding: "text",
|
|
86551
|
+
mimeType: attachment.mimeType,
|
|
86552
|
+
resourceKey: attachment.contentKey,
|
|
86553
|
+
type: "external_resource",
|
|
86554
|
+
uri: attachment.uri
|
|
86555
|
+
}
|
|
86468
86556
|
);
|
|
86469
86557
|
}
|
|
86470
86558
|
return content;
|
|
@@ -87143,8 +87231,7 @@ var SessionTurns = class {
|
|
|
87143
87231
|
queued.push({
|
|
87144
87232
|
commandId: candidate.command.commandId,
|
|
87145
87233
|
prompt: candidate.command.prompt,
|
|
87146
|
-
|
|
87147
|
-
resources: candidate.command.resources
|
|
87234
|
+
attachments: candidate.command.attachments
|
|
87148
87235
|
});
|
|
87149
87236
|
}
|
|
87150
87237
|
return { turn: turnSnapshot ?? null, queued };
|
|
@@ -87441,7 +87528,7 @@ import { join as join27 } from "node:path";
|
|
|
87441
87528
|
|
|
87442
87529
|
// src/storage/files/scratch-directory.ts
|
|
87443
87530
|
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";
|
|
87531
|
+
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
87532
|
import { dirname as dirname11, join as join26 } from "node:path";
|
|
87446
87533
|
async function atomicWrite(path7, bytes, signal) {
|
|
87447
87534
|
const temporary = `${path7}.${randomUUID15()}.tmp`;
|
|
@@ -87505,6 +87592,12 @@ var ScratchDirectory = class {
|
|
|
87505
87592
|
return null;
|
|
87506
87593
|
}
|
|
87507
87594
|
};
|
|
87595
|
+
/** Reads a regular file owned by this scratch directory after validating its canonical path. */
|
|
87596
|
+
read = async (path7, signal) => {
|
|
87597
|
+
const resolved = await this.resolveFile(path7);
|
|
87598
|
+
signal.throwIfAborted();
|
|
87599
|
+
return resolved === null ? null : new Uint8Array(await readFile6(resolved, { signal }));
|
|
87600
|
+
};
|
|
87508
87601
|
removeAll = async () => {
|
|
87509
87602
|
await rm3(this.#root, { force: true, recursive: true });
|
|
87510
87603
|
};
|
|
@@ -87606,6 +87699,11 @@ var LocalExternalContentStore = class {
|
|
|
87606
87699
|
signal.throwIfAborted();
|
|
87607
87700
|
return resolvedPath === null ? null : { mediaType: entry.mediaType, name: entry.name, path: resolvedPath };
|
|
87608
87701
|
};
|
|
87702
|
+
read = (sessionId, request, signal) => this.#track(async () => {
|
|
87703
|
+
const active = AbortSignal.any([signal, this.#lifetime.signal]);
|
|
87704
|
+
const resolved = await this.#resolve(sessionId, request, active);
|
|
87705
|
+
return resolved === null ? null : this.#scratch.read(resolved.path, active);
|
|
87706
|
+
});
|
|
87609
87707
|
[Symbol.asyncDispose] = async () => {
|
|
87610
87708
|
clearInterval(this.#expirationTimer);
|
|
87611
87709
|
this.#lifetime.abort();
|
|
@@ -88271,6 +88369,12 @@ function send(socket, message) {
|
|
|
88271
88369
|
}
|
|
88272
88370
|
socket.send(encodeDaemonToServiceMessage(message));
|
|
88273
88371
|
}
|
|
88372
|
+
function sendContentChunk(socket, requestId, sequence, bytes) {
|
|
88373
|
+
if (socket.readyState !== WebSocket2.OPEN) {
|
|
88374
|
+
throw new Error("Relay connection is not open");
|
|
88375
|
+
}
|
|
88376
|
+
socket.send(encodeContentChunkFrame({ bytes, requestId, sequence }));
|
|
88377
|
+
}
|
|
88274
88378
|
function reportOperationFailure(socket, requestId, sessionId, error62, runtimeTimings = []) {
|
|
88275
88379
|
if (socket.readyState !== WebSocket2.OPEN) {
|
|
88276
88380
|
return;
|
|
@@ -88890,13 +88994,133 @@ function createAgentSettingsCommands(context) {
|
|
|
88890
88994
|
];
|
|
88891
88995
|
}
|
|
88892
88996
|
|
|
88997
|
+
// src/runtime/command/registry/content-write/index.ts
|
|
88998
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
88999
|
+
function createContentWriteCommands(context) {
|
|
89000
|
+
const pending = /* @__PURE__ */ new Map();
|
|
89001
|
+
const operations = /* @__PURE__ */ new Set();
|
|
89002
|
+
const fail = (command, error62) => {
|
|
89003
|
+
pending.delete(command.requestId);
|
|
89004
|
+
send(context.socket, {
|
|
89005
|
+
code: "content_write_failed",
|
|
89006
|
+
kind: FILE_FAILED_KIND,
|
|
89007
|
+
message: error62 instanceof Error ? error62.message : "The content could not be stored",
|
|
89008
|
+
requestId: command.requestId,
|
|
89009
|
+
sessionId: command.sessionId
|
|
89010
|
+
});
|
|
89011
|
+
};
|
|
89012
|
+
const write = {
|
|
89013
|
+
kind: CONTENT_WRITE_KIND,
|
|
89014
|
+
handle: (_commandContext, message) => {
|
|
89015
|
+
if (message.kind !== CONTENT_WRITE_KIND) {
|
|
89016
|
+
throw new Error("Command kind mismatch");
|
|
89017
|
+
}
|
|
89018
|
+
const existing = pending.get(message.requestId);
|
|
89019
|
+
if (existing !== void 0) {
|
|
89020
|
+
if (JSON.stringify(existing.command) !== JSON.stringify(message)) {
|
|
89021
|
+
fail(message, new Error("The content request identifier is already in use"));
|
|
89022
|
+
return;
|
|
89023
|
+
}
|
|
89024
|
+
} else {
|
|
89025
|
+
pending.set(message.requestId, {
|
|
89026
|
+
bytes: new Uint8Array(message.byteLength),
|
|
89027
|
+
command: message,
|
|
89028
|
+
hash: createHash9("sha256"),
|
|
89029
|
+
receivedBytes: 0,
|
|
89030
|
+
sequence: 0
|
|
89031
|
+
});
|
|
89032
|
+
}
|
|
89033
|
+
send(context.socket, {
|
|
89034
|
+
kind: CONTENT_READY_KIND,
|
|
89035
|
+
requestId: message.requestId,
|
|
89036
|
+
sessionId: message.sessionId
|
|
89037
|
+
});
|
|
89038
|
+
}
|
|
89039
|
+
};
|
|
89040
|
+
const commit = {
|
|
89041
|
+
kind: CONTENT_COMMIT_KIND,
|
|
89042
|
+
handle: (_commandContext, message) => {
|
|
89043
|
+
if (message.kind !== CONTENT_COMMIT_KIND) {
|
|
89044
|
+
throw new Error("Command kind mismatch");
|
|
89045
|
+
}
|
|
89046
|
+
const state = pending.get(message.requestId);
|
|
89047
|
+
if (state === void 0 || state.command.sessionId !== message.sessionId) {
|
|
89048
|
+
fail(message, new Error("The content upload is unavailable"));
|
|
89049
|
+
return;
|
|
89050
|
+
}
|
|
89051
|
+
pending.delete(message.requestId);
|
|
89052
|
+
const operation = (async () => {
|
|
89053
|
+
try {
|
|
89054
|
+
if (state.receivedBytes !== state.command.byteLength) {
|
|
89055
|
+
throw new Error("The content upload ended at an unexpected length");
|
|
89056
|
+
}
|
|
89057
|
+
if (state.hash.digest("hex") !== state.command.contentKey) {
|
|
89058
|
+
throw new Error("The content upload failed integrity validation");
|
|
89059
|
+
}
|
|
89060
|
+
const stored = await context.externalContent.put({
|
|
89061
|
+
bytes: state.bytes,
|
|
89062
|
+
kind: state.command.contentKind,
|
|
89063
|
+
mediaType: state.command.mediaType,
|
|
89064
|
+
name: state.command.name,
|
|
89065
|
+
sessionId: state.command.sessionId,
|
|
89066
|
+
signal: context.signal
|
|
89067
|
+
});
|
|
89068
|
+
if (stored.key !== state.command.contentKey || stored.byteLength !== state.command.byteLength) {
|
|
89069
|
+
throw new Error("Stored content did not match the upload");
|
|
89070
|
+
}
|
|
89071
|
+
send(context.socket, {
|
|
89072
|
+
byteLength: stored.byteLength,
|
|
89073
|
+
contentKey: stored.key,
|
|
89074
|
+
kind: CONTENT_AVAILABLE_KIND,
|
|
89075
|
+
requestId: message.requestId,
|
|
89076
|
+
sessionId: message.sessionId
|
|
89077
|
+
});
|
|
89078
|
+
} catch (error62) {
|
|
89079
|
+
if (!context.signal.aborted) {
|
|
89080
|
+
fail(message, error62);
|
|
89081
|
+
}
|
|
89082
|
+
}
|
|
89083
|
+
})();
|
|
89084
|
+
operations.add(operation);
|
|
89085
|
+
void operation.finally(() => operations.delete(operation));
|
|
89086
|
+
}
|
|
89087
|
+
};
|
|
89088
|
+
return {
|
|
89089
|
+
commands: [write, commit],
|
|
89090
|
+
receiveChunk: (frame) => {
|
|
89091
|
+
const state = pending.get(frame.requestId);
|
|
89092
|
+
if (state === void 0) {
|
|
89093
|
+
context.diagnostics.daemonDiagnostic("content_chunk_discarded", frame.requestId, {
|
|
89094
|
+
reason: "upload_unavailable",
|
|
89095
|
+
sequence: frame.sequence.toString()
|
|
89096
|
+
});
|
|
89097
|
+
return;
|
|
89098
|
+
}
|
|
89099
|
+
if (frame.sequence !== state.sequence || state.receivedBytes + frame.bytes.byteLength > state.command.byteLength) {
|
|
89100
|
+
fail(state.command, new Error("The content upload contains invalid chunks"));
|
|
89101
|
+
return;
|
|
89102
|
+
}
|
|
89103
|
+
state.bytes.set(frame.bytes, state.receivedBytes);
|
|
89104
|
+
state.hash.update(frame.bytes);
|
|
89105
|
+
pending.set(frame.requestId, {
|
|
89106
|
+
...state,
|
|
89107
|
+
receivedBytes: state.receivedBytes + frame.bytes.byteLength,
|
|
89108
|
+
sequence: state.sequence + 1
|
|
89109
|
+
});
|
|
89110
|
+
},
|
|
89111
|
+
settle: async () => {
|
|
89112
|
+
pending.clear();
|
|
89113
|
+
await Promise.allSettled([...operations]);
|
|
89114
|
+
}
|
|
89115
|
+
};
|
|
89116
|
+
}
|
|
89117
|
+
|
|
88893
89118
|
// src/runtime/command/registry/file-read/index.ts
|
|
88894
89119
|
import { WebSocket as WebSocket5 } from "undici";
|
|
88895
89120
|
|
|
88896
89121
|
// src/session/content/session-files.ts
|
|
88897
89122
|
import { basename as basename8, extname as extname2, isAbsolute as isAbsolute16, join as join31, normalize as normalize3, resolve as resolve17 } from "node:path";
|
|
88898
89123
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
88899
|
-
var CHUNK_BYTES = 192 * 1024;
|
|
88900
89124
|
function requestedPath(value) {
|
|
88901
89125
|
if (value.includes("\0")) {
|
|
88902
89126
|
return null;
|
|
@@ -88936,7 +89160,7 @@ async function resolveFile(value, workingDirectory, signal) {
|
|
|
88936
89160
|
}
|
|
88937
89161
|
return null;
|
|
88938
89162
|
}
|
|
88939
|
-
async function streamLocalFile(command, send2, signal, workingDirectory, externalContent) {
|
|
89163
|
+
async function streamLocalFile(command, send2, sendChunk, signal, workingDirectory, externalContent) {
|
|
88940
89164
|
const external = await externalContent.resolve(command.sessionId, command.path, signal);
|
|
88941
89165
|
const target = external?.path ?? await resolveFile(command.path, workingDirectory, signal);
|
|
88942
89166
|
if (target === null) {
|
|
@@ -88958,14 +89182,8 @@ async function streamLocalFile(command, send2, signal, workingDirectory, externa
|
|
|
88958
89182
|
sessionId: command.sessionId
|
|
88959
89183
|
});
|
|
88960
89184
|
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
|
-
});
|
|
89185
|
+
for await (const bytes of readFileChunks(target, CONTENT_CHUNK_MAX_BYTES, signal)) {
|
|
89186
|
+
sendChunk(command.requestId, sequence, bytes);
|
|
88969
89187
|
sequence += 1;
|
|
88970
89188
|
}
|
|
88971
89189
|
const after = await readPathMetadata(target);
|
|
@@ -88990,6 +89208,7 @@ var fileReadCommand = {
|
|
|
88990
89208
|
void streamLocalFile(
|
|
88991
89209
|
message,
|
|
88992
89210
|
(response) => send(socket, response),
|
|
89211
|
+
(requestId, sequence, bytes) => sendContentChunk(socket, requestId, sequence, bytes),
|
|
88993
89212
|
signal,
|
|
88994
89213
|
sessions.findSessions([message.sessionId])[0]?.cwd ?? null,
|
|
88995
89214
|
externalContent
|
|
@@ -89587,7 +89806,7 @@ async function applySessionConfigurationSelection(sessions, options, selection,
|
|
|
89587
89806
|
if (sessionConfigurationMatches(option, selection)) {
|
|
89588
89807
|
return options;
|
|
89589
89808
|
}
|
|
89590
|
-
return await sessions.configureSession({
|
|
89809
|
+
return (await sessions.configureSession({
|
|
89591
89810
|
adapter,
|
|
89592
89811
|
additionalDirectories,
|
|
89593
89812
|
agent,
|
|
@@ -89599,7 +89818,7 @@ async function applySessionConfigurationSelection(sessions, options, selection,
|
|
|
89599
89818
|
signal,
|
|
89600
89819
|
value: selection.value,
|
|
89601
89820
|
valueType: selection.valueType
|
|
89602
|
-
});
|
|
89821
|
+
})).configOptions;
|
|
89603
89822
|
}
|
|
89604
89823
|
async function applyCompleteSessionConfiguration(sessions, initialOptions, selections, agent, adapter, cwd, additionalDirectories, commandId, sessionId, signal) {
|
|
89605
89824
|
let options = initialOptions;
|
|
@@ -89636,8 +89855,7 @@ function warnIgnoredSetting(event, commandId, sessionId, agentId, selection, cat
|
|
|
89636
89855
|
}
|
|
89637
89856
|
|
|
89638
89857
|
// src/session/prompt/prompt-artifacts.ts
|
|
89639
|
-
|
|
89640
|
-
var MAX_AGENT_IMAGE_BASE64_LENGTH = 4e6;
|
|
89858
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
89641
89859
|
var MAX_AGENT_RESOURCE_BYTE_LENGTH = 1e6;
|
|
89642
89860
|
var PromptArtifactError = class extends OperationError {
|
|
89643
89861
|
constructor(code, message, options = {}) {
|
|
@@ -89653,99 +89871,60 @@ var ResolvedPromptArtifacts = class {
|
|
|
89653
89871
|
this.resources = resources;
|
|
89654
89872
|
}
|
|
89655
89873
|
};
|
|
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
89874
|
function isTextMediaType(mediaType) {
|
|
89688
89875
|
return mediaType.startsWith("text/") || mediaType === "application/json" || mediaType.endsWith("+json") || mediaType === "application/xml" || mediaType.endsWith("+xml");
|
|
89689
89876
|
}
|
|
89690
|
-
async function resolvePromptArtifacts(
|
|
89691
|
-
const images = [
|
|
89877
|
+
async function resolvePromptArtifacts(read, attachments, signal) {
|
|
89878
|
+
const images = [];
|
|
89692
89879
|
const resources = [];
|
|
89693
|
-
for (const
|
|
89880
|
+
for (const attachment of attachments) {
|
|
89694
89881
|
signal.throwIfAborted();
|
|
89695
|
-
|
|
89696
|
-
|
|
89697
|
-
|
|
89882
|
+
const bytes = await read(attachment, signal);
|
|
89883
|
+
if (bytes.byteLength !== attachment.byteLength || createHash10("sha256").update(bytes).digest("hex") !== attachment.contentKey) {
|
|
89884
|
+
throw new PromptArtifactError(
|
|
89885
|
+
"artifact_integrity_failed",
|
|
89886
|
+
"The prompt attachment failed integrity validation"
|
|
89887
|
+
);
|
|
89698
89888
|
}
|
|
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) {
|
|
89889
|
+
if (attachment.kind === "image") {
|
|
89890
|
+
if (bytes.byteLength > PROMPT_IMAGE_MAX_BYTES || images.length >= 8) {
|
|
89714
89891
|
throw new PromptArtifactError(
|
|
89715
89892
|
"artifact_too_large_for_agent",
|
|
89716
|
-
"The prompt
|
|
89893
|
+
"The prompt attachment exceeds the Agent image limit"
|
|
89717
89894
|
);
|
|
89718
89895
|
}
|
|
89719
|
-
images.push({
|
|
89896
|
+
images.push({
|
|
89897
|
+
data: Buffer.from(bytes).toString("base64"),
|
|
89898
|
+
mimeType: attachment.mimeType,
|
|
89899
|
+
name: attachment.name
|
|
89900
|
+
});
|
|
89720
89901
|
continue;
|
|
89721
89902
|
}
|
|
89722
|
-
if (!isTextMediaType(
|
|
89903
|
+
if (!isTextMediaType(attachment.mimeType)) {
|
|
89723
89904
|
throw new PromptArtifactError(
|
|
89724
89905
|
"artifact_media_type_unsupported",
|
|
89725
|
-
"The Agent cannot consume this prompt
|
|
89906
|
+
"The Agent cannot consume this prompt attachment media type"
|
|
89726
89907
|
);
|
|
89727
89908
|
}
|
|
89728
89909
|
if (bytes.byteLength > MAX_AGENT_RESOURCE_BYTE_LENGTH || resources.length >= 16) {
|
|
89729
89910
|
throw new PromptArtifactError(
|
|
89730
89911
|
"artifact_too_large_for_agent",
|
|
89731
|
-
"The prompt
|
|
89912
|
+
"The prompt attachment exceeds the Agent resource limit"
|
|
89732
89913
|
);
|
|
89733
89914
|
}
|
|
89734
89915
|
let text2;
|
|
89735
89916
|
try {
|
|
89736
89917
|
text2 = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
89737
89918
|
} catch (cause) {
|
|
89738
|
-
throw new PromptArtifactError(
|
|
89739
|
-
|
|
89740
|
-
|
|
89919
|
+
throw new PromptArtifactError(
|
|
89920
|
+
"artifact_encoding_invalid",
|
|
89921
|
+
"The prompt attachment is not valid UTF-8 text",
|
|
89922
|
+
{
|
|
89923
|
+
cause
|
|
89924
|
+
}
|
|
89925
|
+
);
|
|
89741
89926
|
}
|
|
89742
|
-
resources.push({
|
|
89743
|
-
mimeType: resource.mimeType,
|
|
89744
|
-
name: resource.name,
|
|
89745
|
-
text: text2,
|
|
89746
|
-
type: "embedded",
|
|
89747
|
-
uri: resource.uri
|
|
89748
|
-
});
|
|
89927
|
+
resources.push({ mimeType: attachment.mimeType, text: text2, type: "embedded", uri: attachment.uri });
|
|
89749
89928
|
}
|
|
89750
89929
|
return new ResolvedPromptArtifacts(images, resources);
|
|
89751
89930
|
}
|
|
@@ -89756,7 +89935,7 @@ async function executePrompt({
|
|
|
89756
89935
|
eventProjection,
|
|
89757
89936
|
command,
|
|
89758
89937
|
resolveAgent,
|
|
89759
|
-
|
|
89938
|
+
readArtifact,
|
|
89760
89939
|
reportFailure,
|
|
89761
89940
|
directories,
|
|
89762
89941
|
sessions,
|
|
@@ -89838,7 +90017,7 @@ async function executePrompt({
|
|
|
89838
90017
|
stream.epoch,
|
|
89839
90018
|
availability.disposition
|
|
89840
90019
|
);
|
|
89841
|
-
const attachments = await resolvePromptArtifacts(
|
|
90020
|
+
const attachments = await resolvePromptArtifacts(readArtifact, command.attachments, signal);
|
|
89842
90021
|
let stopReason;
|
|
89843
90022
|
if (availability.disposition === SessionPromptDisposition.Steer) {
|
|
89844
90023
|
await sessions.steerPrompt({
|
|
@@ -89898,115 +90077,6 @@ async function executePrompt({
|
|
|
89898
90077
|
}
|
|
89899
90078
|
}
|
|
89900
90079
|
|
|
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
90080
|
// src/runtime/command/registry/prompt.ts
|
|
90011
90081
|
var sessionPromptCommand = {
|
|
90012
90082
|
kind: SESSION_PROMPT_KIND,
|
|
@@ -90060,7 +90130,17 @@ var sessionPromptCommand = {
|
|
|
90060
90130
|
eventProjection: context.eventProjection,
|
|
90061
90131
|
command: message,
|
|
90062
90132
|
resolveAgent: context.resolveAgent,
|
|
90063
|
-
|
|
90133
|
+
readArtifact: async (artifact, signal) => {
|
|
90134
|
+
const bytes = await context.externalContent.read(
|
|
90135
|
+
message.sessionId,
|
|
90136
|
+
`mobius-content:${artifact.kind}:${artifact.contentKey}`,
|
|
90137
|
+
signal
|
|
90138
|
+
);
|
|
90139
|
+
if (bytes === null) {
|
|
90140
|
+
throw new Error("The prompt attachment is unavailable");
|
|
90141
|
+
}
|
|
90142
|
+
return bytes;
|
|
90143
|
+
},
|
|
90064
90144
|
reportFailure: context.diagnostics.daemonDiagnostic,
|
|
90065
90145
|
directories: context.directories,
|
|
90066
90146
|
sessions: context.sessions,
|
|
@@ -90142,7 +90222,7 @@ async function prepareSession(command, recovery, closed, config2, resolveAgent,
|
|
|
90142
90222
|
};
|
|
90143
90223
|
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
90224
|
const configuration = command.configuration;
|
|
90145
|
-
const
|
|
90225
|
+
const snapshot = configuration === void 0 ? prepared : await metrics.measure(
|
|
90146
90226
|
"configuration",
|
|
90147
90227
|
async () => await sessions.configureSession({
|
|
90148
90228
|
...preparation,
|
|
@@ -90160,7 +90240,8 @@ async function prepareSession(command, recovery, closed, config2, resolveAgent,
|
|
|
90160
90240
|
agentVersion: prepared.agentVersion,
|
|
90161
90241
|
capabilities: prepared.capabilities,
|
|
90162
90242
|
commands: prepared.commands,
|
|
90163
|
-
configOptions,
|
|
90243
|
+
configOptions: snapshot.configOptions,
|
|
90244
|
+
configurationRevision: snapshot.configurationRevision,
|
|
90164
90245
|
directoryId: command.directoryId,
|
|
90165
90246
|
directoryLabel: resolved.directoryLabel,
|
|
90166
90247
|
kind: "session.ready",
|
|
@@ -90293,11 +90374,12 @@ async function executeSessionConfigure(socket, command, config2, resolveAgent, d
|
|
|
90293
90374
|
command.additionalDirectoryIds,
|
|
90294
90375
|
signal
|
|
90295
90376
|
);
|
|
90296
|
-
const
|
|
90377
|
+
const snapshot = await sessions.configureSession({
|
|
90297
90378
|
additionalDirectories: resolved.additionalDirectories,
|
|
90298
90379
|
...await resolveAgent(command.agentId, signal, command.sessionId),
|
|
90299
90380
|
booleanValue: command.booleanValue,
|
|
90300
90381
|
configId: command.configId,
|
|
90382
|
+
...command.expectedConfigurationRevision === void 0 ? {} : { expectedConfigurationRevision: command.expectedConfigurationRevision },
|
|
90301
90383
|
cwd: resolved.cwd,
|
|
90302
90384
|
requestId: command.requestId,
|
|
90303
90385
|
sessionId: command.sessionId,
|
|
@@ -90306,7 +90388,7 @@ async function executeSessionConfigure(socket, command, config2, resolveAgent, d
|
|
|
90306
90388
|
valueType: command.valueType
|
|
90307
90389
|
});
|
|
90308
90390
|
send(socket, {
|
|
90309
|
-
|
|
90391
|
+
...snapshot,
|
|
90310
90392
|
kind: "session.config.updated",
|
|
90311
90393
|
requestId: command.requestId,
|
|
90312
90394
|
sessionId: command.sessionId
|
|
@@ -90426,6 +90508,7 @@ async function executeSessionConfigRead(socket, command, config2, resolveAgent,
|
|
|
90426
90508
|
);
|
|
90427
90509
|
send(socket, {
|
|
90428
90510
|
configOptions: ready.configOptions,
|
|
90511
|
+
configurationRevision: ready.configurationRevision,
|
|
90429
90512
|
kind: SESSION_CONFIG_READ_RESULT_KIND,
|
|
90430
90513
|
requestId: command.requestId,
|
|
90431
90514
|
sessionId: command.sessionId
|
|
@@ -90465,6 +90548,7 @@ var sessionConfigReadCommand = {
|
|
|
90465
90548
|
|
|
90466
90549
|
// src/runtime/command/registry/index.ts
|
|
90467
90550
|
function createCommandRegistry(context) {
|
|
90551
|
+
const contentWrites = createContentWriteCommands(context);
|
|
90468
90552
|
const commands = [
|
|
90469
90553
|
runtimeDiagnosticsCommand,
|
|
90470
90554
|
runtimePingCommand,
|
|
@@ -90473,6 +90557,7 @@ function createCommandRegistry(context) {
|
|
|
90473
90557
|
...createNativeSessionCommands(context),
|
|
90474
90558
|
...createAgentCatalogCommands(context),
|
|
90475
90559
|
...createAgentSettingsCommands(context),
|
|
90560
|
+
...contentWrites.commands,
|
|
90476
90561
|
fileReadCommand,
|
|
90477
90562
|
sessionCancelCommand,
|
|
90478
90563
|
sessionCloseCommand,
|
|
@@ -90495,8 +90580,12 @@ function createCommandRegistry(context) {
|
|
|
90495
90580
|
}
|
|
90496
90581
|
command.handle(context, message);
|
|
90497
90582
|
},
|
|
90583
|
+
dispatchChunk: (message) => contentWrites.receiveChunk(decodeContentChunkFrame(message)),
|
|
90498
90584
|
settle: async () => {
|
|
90499
|
-
await Promise.all(
|
|
90585
|
+
await Promise.all([
|
|
90586
|
+
contentWrites.settle(),
|
|
90587
|
+
...commands.flatMap((command) => command.settle === void 0 ? [] : [command.settle()])
|
|
90588
|
+
]);
|
|
90500
90589
|
}
|
|
90501
90590
|
};
|
|
90502
90591
|
}
|
|
@@ -90558,6 +90647,7 @@ function connectRelay(url2, signal) {
|
|
|
90558
90647
|
dispatcher,
|
|
90559
90648
|
headers
|
|
90560
90649
|
});
|
|
90650
|
+
socket.binaryType = "arraybuffer";
|
|
90561
90651
|
let released = false;
|
|
90562
90652
|
const release = (reason) => {
|
|
90563
90653
|
if (released) {
|
|
@@ -90921,7 +91011,16 @@ async function runRelayConnection({
|
|
|
90921
91011
|
const handleMessage = (event) => {
|
|
90922
91012
|
const encoded = event.data;
|
|
90923
91013
|
if (typeof encoded !== "string") {
|
|
90924
|
-
|
|
91014
|
+
try {
|
|
91015
|
+
commands.dispatchChunk(encoded);
|
|
91016
|
+
} catch (error62) {
|
|
91017
|
+
failAndClose(
|
|
91018
|
+
new Error("Relay sent an invalid content chunk", { cause: error62 }),
|
|
91019
|
+
4008,
|
|
91020
|
+
"Invalid content chunk",
|
|
91021
|
+
"protocol"
|
|
91022
|
+
);
|
|
91023
|
+
}
|
|
90925
91024
|
return;
|
|
90926
91025
|
}
|
|
90927
91026
|
try {
|