@moxt-ai/mobius 0.0.147 → 0.0.149
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 +276 -161
- package/dist/cli.js.map +3 -3
- package/dist/daemon-active-turn.d.ts +15 -2
- package/dist/daemon-active-turn.d.ts.map +1 -1
- package/dist/daemon-active-turn.js +63 -25
- package/dist/daemon-active-turn.js.map +1 -1
- package/dist/daemon-command-handler.js +3 -3
- package/dist/daemon-history-commands.d.ts +4 -7
- package/dist/daemon-history-commands.d.ts.map +1 -1
- package/dist/daemon-history-commands.js.map +1 -1
- package/dist/daemon-prompt-executor.d.ts +1 -1
- package/dist/daemon-prompt-executor.d.ts.map +1 -1
- package/dist/daemon-prompt-executor.js +1 -3
- package/dist/daemon-prompt-executor.js.map +1 -1
- package/dist/daemon-turn-registry.d.ts +5 -43
- package/dist/daemon-turn-registry.d.ts.map +1 -1
- package/dist/daemon-turn-registry.js +40 -1
- package/dist/daemon-turn-registry.js.map +1 -1
- package/dist/index.js +275 -160
- package/dist/index.js.map +3 -3
- package/dist/native-sessions/live-history-page.d.ts +4 -7
- package/dist/native-sessions/live-history-page.d.ts.map +1 -1
- package/dist/native-sessions/live-history-page.js +163 -107
- package/dist/native-sessions/live-history-page.js.map +1 -1
- package/dist/runtime.js +275 -160
- package/dist/runtime.js.map +3 -3
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3381,7 +3381,7 @@ var program = new Command();
|
|
|
3381
3381
|
// package.json
|
|
3382
3382
|
var package_default = {
|
|
3383
3383
|
name: "@moxt-ai/mobius",
|
|
3384
|
-
version: "0.0.
|
|
3384
|
+
version: "0.0.149",
|
|
3385
3385
|
description: "Mobius CLI for pairing and running local AI agent services.",
|
|
3386
3386
|
type: "module",
|
|
3387
3387
|
bin: {
|
|
@@ -29624,18 +29624,21 @@ var activeTurnMessageSchema = external_exports.discriminatedUnion("role", [
|
|
|
29624
29624
|
activeTurnAssistantMessageSchema
|
|
29625
29625
|
]);
|
|
29626
29626
|
var activeTurnSnapshotSchema = external_exports.strictObject({
|
|
29627
|
-
activities: external_exports.array(activeTurnActivitySchema).readonly(),
|
|
29628
29627
|
commandId: identifierStringSchema,
|
|
29629
|
-
content: external_exports.array(displayContentSchema).readonly(),
|
|
29630
|
-
prompt: external_exports.string().max(1e5),
|
|
29631
|
-
text: external_exports.string(),
|
|
29632
|
-
truncated: external_exports.boolean(),
|
|
29633
29628
|
epoch: identifierStringSchema,
|
|
29629
|
+
hasOlder: external_exports.boolean(),
|
|
29634
29630
|
interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
|
|
29635
29631
|
messages: external_exports.array(activeTurnMessageSchema).max(SESSION_HISTORY_MESSAGE_LIMIT).readonly(),
|
|
29636
29632
|
sequence: external_exports.number().int().nonnegative(),
|
|
29637
|
-
state: external_exports.literal("running")
|
|
29638
|
-
|
|
29633
|
+
state: external_exports.literal("running"),
|
|
29634
|
+
truncated: external_exports.boolean()
|
|
29635
|
+
}).readonly().refine(
|
|
29636
|
+
(snapshot) => snapshot.messages.reduce(
|
|
29637
|
+
(total, message) => total + message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0),
|
|
29638
|
+
0
|
|
29639
|
+
) <= SESSION_HISTORY_CHARACTER_LIMIT,
|
|
29640
|
+
"Active Turn snapshot content is too large"
|
|
29641
|
+
);
|
|
29639
29642
|
var identity = {
|
|
29640
29643
|
...envelope,
|
|
29641
29644
|
kind: external_exports.literal(NATIVE_SESSION_REQUEST_KIND),
|
|
@@ -29779,27 +29782,14 @@ var encodeNativeSessionCancel = (value) => JSON.stringify(nativeSessionCancelSch
|
|
|
29779
29782
|
|
|
29780
29783
|
// ../protocol/src/session-events.ts
|
|
29781
29784
|
var SESSION_EVENT_KIND = "session.event";
|
|
29782
|
-
var SESSION_EVENT_COMMITTED_KIND = "session.event.committed";
|
|
29783
29785
|
var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
|
|
29784
29786
|
var eventEnvelopeSchema = external_exports.strictObject({
|
|
29785
29787
|
kind: external_exports.literal(SESSION_EVENT_KIND),
|
|
29786
29788
|
payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
|
|
29787
29789
|
sessionId: identifierStringSchema
|
|
29788
29790
|
}).readonly();
|
|
29789
|
-
var committedEventSchema = external_exports.strictObject({
|
|
29790
|
-
kind: external_exports.literal(SESSION_EVENT_COMMITTED_KIND),
|
|
29791
|
-
payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
|
|
29792
|
-
sessionId: identifierStringSchema
|
|
29793
|
-
}).readonly();
|
|
29794
29791
|
var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
|
|
29795
29792
|
var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
|
|
29796
|
-
var SESSION_TURN_UPDATED_KIND = "session.turn.updated";
|
|
29797
|
-
var sessionTurnUpdatedSchema = external_exports.strictObject({
|
|
29798
|
-
kind: external_exports.literal(SESSION_TURN_UPDATED_KIND),
|
|
29799
|
-
sessionId: identifierStringSchema,
|
|
29800
|
-
turn: activeTurnSnapshotSchema
|
|
29801
|
-
}).readonly();
|
|
29802
|
-
var decodeSessionTurnUpdatedEvent = (encoded) => decode5(encoded, sessionTurnUpdatedSchema);
|
|
29803
29793
|
function decode5(encoded, schema) {
|
|
29804
29794
|
let value;
|
|
29805
29795
|
try {
|
|
@@ -29829,8 +29819,6 @@ var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSche
|
|
|
29829
29819
|
function decodeRecordedSessionEvent(encoded) {
|
|
29830
29820
|
const kind = decodeMessageKind(encoded);
|
|
29831
29821
|
switch (kind) {
|
|
29832
|
-
case SESSION_TURN_UPDATED_KIND:
|
|
29833
|
-
return decodeSessionTurnUpdatedEvent(encoded);
|
|
29834
29822
|
case SESSION_QUEUE_CHANGED_KIND:
|
|
29835
29823
|
return decode5(encoded, sessionQueueChangedSchema);
|
|
29836
29824
|
case AGENT_ACTIVITY_KIND:
|
|
@@ -42207,6 +42195,28 @@ var DaemonInstallationObserver = class {
|
|
|
42207
42195
|
|
|
42208
42196
|
// src/daemon-active-turn.ts
|
|
42209
42197
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
42198
|
+
function activeMessageCharacters(message) {
|
|
42199
|
+
return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
|
|
42200
|
+
}
|
|
42201
|
+
var ACTIVE_TURN_TEXT_CHUNK_LIMIT = Math.floor(SESSION_HISTORY_CHARACTER_LIMIT / 2);
|
|
42202
|
+
function boundedRecoveryMessages(messages) {
|
|
42203
|
+
const selected = [];
|
|
42204
|
+
let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT;
|
|
42205
|
+
for (let index = messages.length - 1; index >= 0 && selected.length < SESSION_HISTORY_MESSAGE_LIMIT; index -= 1) {
|
|
42206
|
+
const message = messages[index];
|
|
42207
|
+
if (message === void 0) {
|
|
42208
|
+
break;
|
|
42209
|
+
}
|
|
42210
|
+
const characters = activeMessageCharacters(message);
|
|
42211
|
+
if (characters <= remainingCharacters) {
|
|
42212
|
+
selected.unshift(message);
|
|
42213
|
+
remainingCharacters -= characters;
|
|
42214
|
+
continue;
|
|
42215
|
+
}
|
|
42216
|
+
break;
|
|
42217
|
+
}
|
|
42218
|
+
return { hasOlder: selected.length !== messages.length, messages: selected };
|
|
42219
|
+
}
|
|
42210
42220
|
var ActiveDaemonTurn = class {
|
|
42211
42221
|
attemptId;
|
|
42212
42222
|
command;
|
|
@@ -42214,9 +42224,7 @@ var ActiveDaemonTurn = class {
|
|
|
42214
42224
|
#finished = Promise.withResolvers();
|
|
42215
42225
|
#cancellationRequested = false;
|
|
42216
42226
|
#dispatch;
|
|
42217
|
-
#text = "";
|
|
42218
42227
|
#activities = /* @__PURE__ */ new Map();
|
|
42219
|
-
#content = /* @__PURE__ */ new Map();
|
|
42220
42228
|
#timeline;
|
|
42221
42229
|
#sequence = 0;
|
|
42222
42230
|
#interaction = null;
|
|
@@ -42263,9 +42271,17 @@ var ActiveDaemonTurn = class {
|
|
|
42263
42271
|
effectiveDisposition = () => this.#dispatch.kind === "promoted" ? SessionPromptDisposition.Steer : this.command.disposition;
|
|
42264
42272
|
recordEvent = (event) => {
|
|
42265
42273
|
if (event.kind === AGENT_MESSAGE_DELTA_KIND) {
|
|
42266
|
-
|
|
42274
|
+
const sequence = this.advance();
|
|
42267
42275
|
this.appendMessageText(event.messageId, event.text);
|
|
42268
|
-
return
|
|
42276
|
+
return {
|
|
42277
|
+
commandId: this.command.commandId,
|
|
42278
|
+
epoch: this.#epoch,
|
|
42279
|
+
kind: AGENT_MESSAGE_DELTA_KIND,
|
|
42280
|
+
messageId: event.messageId,
|
|
42281
|
+
sequence,
|
|
42282
|
+
sessionId: this.command.sessionId,
|
|
42283
|
+
text: event.text
|
|
42284
|
+
};
|
|
42269
42285
|
}
|
|
42270
42286
|
if (event.sessionId !== this.command.sessionId || "commandId" in event && event.commandId !== this.command.commandId) {
|
|
42271
42287
|
return event;
|
|
@@ -42312,7 +42328,6 @@ var ActiveDaemonTurn = class {
|
|
|
42312
42328
|
toolKind: previous?.toolKind ?? ""
|
|
42313
42329
|
});
|
|
42314
42330
|
} else if (event.kind === AGENT_CONTENT_KIND) {
|
|
42315
|
-
this.#content.set(event.contentId, event.content);
|
|
42316
42331
|
const target = this.#timeline.findLastIndex(
|
|
42317
42332
|
(entry) => entry.kind === "message" && entry.sourceMessageId === event.messageId
|
|
42318
42333
|
);
|
|
@@ -42338,7 +42353,7 @@ var ActiveDaemonTurn = class {
|
|
|
42338
42353
|
this.#interaction = null;
|
|
42339
42354
|
}
|
|
42340
42355
|
if (event.kind === AGENT_ACTIVITY_KIND || event.kind === AGENT_ACTIVITY_NARRATION_KIND || event.kind === AGENT_CONTENT_KIND) {
|
|
42341
|
-
|
|
42356
|
+
this.advance();
|
|
42342
42357
|
}
|
|
42343
42358
|
return event;
|
|
42344
42359
|
};
|
|
@@ -42347,7 +42362,7 @@ var ActiveDaemonTurn = class {
|
|
|
42347
42362
|
while (remaining.length > 0) {
|
|
42348
42363
|
const latest = this.#timeline.at(-1);
|
|
42349
42364
|
if (latest?.kind === "message" && latest.sourceMessageId === messageId) {
|
|
42350
|
-
const available =
|
|
42365
|
+
const available = ACTIVE_TURN_TEXT_CHUNK_LIMIT - latest.text.length;
|
|
42351
42366
|
if (available > 0) {
|
|
42352
42367
|
this.#timeline = [
|
|
42353
42368
|
...this.#timeline.slice(0, -1),
|
|
@@ -42364,21 +42379,22 @@ var ActiveDaemonTurn = class {
|
|
|
42364
42379
|
id: decodeIdentifier(randomUUID2()),
|
|
42365
42380
|
kind: "message",
|
|
42366
42381
|
sourceMessageId: messageId,
|
|
42367
|
-
text: remaining.slice(0,
|
|
42382
|
+
text: remaining.slice(0, ACTIVE_TURN_TEXT_CHUNK_LIMIT)
|
|
42368
42383
|
}
|
|
42369
42384
|
];
|
|
42370
|
-
remaining = remaining.slice(
|
|
42385
|
+
remaining = remaining.slice(ACTIVE_TURN_TEXT_CHUNK_LIMIT);
|
|
42371
42386
|
}
|
|
42372
42387
|
}
|
|
42373
42388
|
recordSteeringPrompt = (command) => {
|
|
42374
42389
|
if (this.#dispatch.kind !== "running" || command.sessionId !== this.command.sessionId || command.targetCommandId !== this.command.commandId) {
|
|
42375
|
-
return
|
|
42390
|
+
return false;
|
|
42376
42391
|
}
|
|
42377
42392
|
this.#timeline = [
|
|
42378
42393
|
...this.#timeline,
|
|
42379
42394
|
{ id: decodeIdentifier(command.commandId), images: command.images, kind: "user", text: command.prompt }
|
|
42380
42395
|
];
|
|
42381
|
-
|
|
42396
|
+
this.advance();
|
|
42397
|
+
return true;
|
|
42382
42398
|
};
|
|
42383
42399
|
timelineMessages() {
|
|
42384
42400
|
return this.#timeline.flatMap((entry) => {
|
|
@@ -42400,32 +42416,39 @@ var ActiveDaemonTurn = class {
|
|
|
42400
42416
|
return activity2 === void 0 ? [] : [{ activities: [activity2], content: [], id: entry.id, role: "assistant", text: "" }];
|
|
42401
42417
|
});
|
|
42402
42418
|
}
|
|
42403
|
-
|
|
42404
|
-
this.#
|
|
42405
|
-
|
|
42406
|
-
if (turn === null) {
|
|
42407
|
-
throw new Error("Only a running turn can publish a snapshot");
|
|
42419
|
+
advance = () => {
|
|
42420
|
+
if (this.#dispatch.kind !== "running") {
|
|
42421
|
+
throw new Error("Only a running turn can advance its snapshot");
|
|
42408
42422
|
}
|
|
42409
|
-
|
|
42423
|
+
this.#sequence += 1;
|
|
42424
|
+
return this.#sequence;
|
|
42410
42425
|
};
|
|
42411
42426
|
snapshot = () => {
|
|
42412
42427
|
if (this.#dispatch.kind !== "running") {
|
|
42413
42428
|
return null;
|
|
42414
42429
|
}
|
|
42415
|
-
const
|
|
42416
|
-
const messages = completeMessages.slice(-SESSION_HISTORY_MESSAGE_LIMIT);
|
|
42430
|
+
const bounded2 = boundedRecoveryMessages(this.timelineMessages());
|
|
42417
42431
|
return {
|
|
42418
|
-
activities: [...this.#activities.values()].sort((left, right) => left.sequence - right.sequence),
|
|
42419
42432
|
commandId: decodeIdentifier(this.command.commandId),
|
|
42420
|
-
content: [...this.#content.values()],
|
|
42421
|
-
prompt: this.command.prompt,
|
|
42422
|
-
text: this.#text,
|
|
42423
|
-
truncated: messages.length !== completeMessages.length,
|
|
42424
42433
|
epoch: this.#epoch,
|
|
42434
|
+
hasOlder: bounded2.hasOlder,
|
|
42425
42435
|
interaction: this.#interaction,
|
|
42426
|
-
messages,
|
|
42436
|
+
messages: bounded2.messages,
|
|
42427
42437
|
sequence: this.#sequence,
|
|
42428
|
-
state: "running"
|
|
42438
|
+
state: "running",
|
|
42439
|
+
truncated: false
|
|
42440
|
+
};
|
|
42441
|
+
};
|
|
42442
|
+
recovery = () => {
|
|
42443
|
+
if (this.#dispatch.kind !== "running") {
|
|
42444
|
+
return null;
|
|
42445
|
+
}
|
|
42446
|
+
return {
|
|
42447
|
+
commandId: decodeIdentifier(this.command.commandId),
|
|
42448
|
+
epoch: this.#epoch,
|
|
42449
|
+
messages: this.timelineMessages(),
|
|
42450
|
+
state: "running",
|
|
42451
|
+
truncated: false
|
|
42429
42452
|
};
|
|
42430
42453
|
};
|
|
42431
42454
|
matches = (cancellation) => cancellation.commandId === this.command.commandId && cancellation.sessionId === this.command.sessionId;
|
|
@@ -42451,6 +42474,7 @@ var ActiveDaemonTurn = class {
|
|
|
42451
42474
|
};
|
|
42452
42475
|
|
|
42453
42476
|
// src/daemon-turn-registry.ts
|
|
42477
|
+
var COMPLETED_TURN_RECOVERY_LIMIT = 32;
|
|
42454
42478
|
var waitForTurnCompletion = (turn, waitSignal) => {
|
|
42455
42479
|
waitSignal.throwIfAborted();
|
|
42456
42480
|
return new Promise((resolve9, reject) => {
|
|
@@ -42477,6 +42501,7 @@ var waitForTurnCompletion = (turn, waitSignal) => {
|
|
|
42477
42501
|
};
|
|
42478
42502
|
var DaemonTurnRegistry = class {
|
|
42479
42503
|
#turns = /* @__PURE__ */ new Map();
|
|
42504
|
+
#completed = /* @__PURE__ */ new Map();
|
|
42480
42505
|
#operations;
|
|
42481
42506
|
constructor(operations) {
|
|
42482
42507
|
this.#operations = operations;
|
|
@@ -42488,7 +42513,22 @@ var DaemonTurnRegistry = class {
|
|
|
42488
42513
|
};
|
|
42489
42514
|
get = (commandId) => this.#turns.get(commandId);
|
|
42490
42515
|
finish = (turn) => {
|
|
42516
|
+
const recovery = turn.recovery();
|
|
42491
42517
|
this.#turns.delete(turn.command.commandId);
|
|
42518
|
+
if (recovery !== null) {
|
|
42519
|
+
this.#completed.delete(turn.command.sessionId);
|
|
42520
|
+
this.#completed.set(turn.command.sessionId, {
|
|
42521
|
+
command: turn.command,
|
|
42522
|
+
recovery: { ...recovery, state: "completed" }
|
|
42523
|
+
});
|
|
42524
|
+
while (this.#completed.size > COMPLETED_TURN_RECOVERY_LIMIT) {
|
|
42525
|
+
const oldestSessionId = this.#completed.keys().next().value;
|
|
42526
|
+
if (oldestSessionId === void 0) {
|
|
42527
|
+
break;
|
|
42528
|
+
}
|
|
42529
|
+
this.#completed.delete(oldestSessionId);
|
|
42530
|
+
}
|
|
42531
|
+
}
|
|
42492
42532
|
turn.finish();
|
|
42493
42533
|
};
|
|
42494
42534
|
recordEvent = (event) => {
|
|
@@ -42509,7 +42549,7 @@ var DaemonTurnRegistry = class {
|
|
|
42509
42549
|
};
|
|
42510
42550
|
recordSteeringPrompt = (command) => {
|
|
42511
42551
|
const target = this.#turns.get(command.targetCommandId);
|
|
42512
|
-
return target?.recordSteeringPrompt(command) ??
|
|
42552
|
+
return target?.recordSteeringPrompt(command) ?? false;
|
|
42513
42553
|
};
|
|
42514
42554
|
executionSnapshot = async (matches) => {
|
|
42515
42555
|
const matching = [];
|
|
@@ -42540,12 +42580,30 @@ var DaemonTurnRegistry = class {
|
|
|
42540
42580
|
}
|
|
42541
42581
|
return null;
|
|
42542
42582
|
};
|
|
42583
|
+
recovery = (matches) => {
|
|
42584
|
+
for (const turn of this.#turns.values()) {
|
|
42585
|
+
if (!matches(turn.command)) {
|
|
42586
|
+
continue;
|
|
42587
|
+
}
|
|
42588
|
+
const recovery = turn.recovery();
|
|
42589
|
+
if (recovery !== null) {
|
|
42590
|
+
return recovery;
|
|
42591
|
+
}
|
|
42592
|
+
}
|
|
42593
|
+
for (const completed of this.#completed.values()) {
|
|
42594
|
+
if (matches(completed.command)) {
|
|
42595
|
+
return completed.recovery;
|
|
42596
|
+
}
|
|
42597
|
+
}
|
|
42598
|
+
return null;
|
|
42599
|
+
};
|
|
42543
42600
|
close = async () => {
|
|
42544
42601
|
const turns = [...this.#turns.values()];
|
|
42545
42602
|
for (const turn of turns) {
|
|
42546
42603
|
turn.abortDaemon();
|
|
42547
42604
|
}
|
|
42548
42605
|
await Promise.all(turns.map((turn) => turn.completion));
|
|
42606
|
+
this.#completed.clear();
|
|
42549
42607
|
};
|
|
42550
42608
|
admitAndWait = async (turn, waitSignal, onQueued) => {
|
|
42551
42609
|
const command = turn.command;
|
|
@@ -44853,10 +44911,10 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
|
|
|
44853
44911
|
}
|
|
44854
44912
|
|
|
44855
44913
|
// src/native-sessions/live-history-page.ts
|
|
44856
|
-
function
|
|
44857
|
-
return Buffer.from(JSON.stringify(
|
|
44914
|
+
function encodeLiveHistoryCursor(cursor) {
|
|
44915
|
+
return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
|
|
44858
44916
|
}
|
|
44859
|
-
function
|
|
44917
|
+
function decodeLiveHistoryCursor(cursor, sessionId) {
|
|
44860
44918
|
try {
|
|
44861
44919
|
if (!/^[A-Za-z0-9_-]{1,512}$/u.test(cursor)) {
|
|
44862
44920
|
throw new Error("Invalid cursor alphabet");
|
|
@@ -44866,14 +44924,32 @@ function liveHistoryEndIndex(cursor, sessionId) {
|
|
|
44866
44924
|
throw new Error("Invalid cursor shape");
|
|
44867
44925
|
}
|
|
44868
44926
|
const record2 = Object.fromEntries(Object.entries(value));
|
|
44869
|
-
|
|
44927
|
+
const keys = Object.keys(record2).sort().join(",");
|
|
44928
|
+
const legacyNative = keys === "endIndex,sessionId";
|
|
44929
|
+
const kind = legacyNative ? "native" : record2["kind"];
|
|
44930
|
+
if (keys !== "endIndex,kind,sessionId" && keys !== "endIndex,epoch,kind,sessionId" && !legacyNative || record2["sessionId"] !== sessionId || kind !== "active" && kind !== "native" || typeof record2["endIndex"] !== "number" || !Number.isSafeInteger(record2["endIndex"]) || record2["endIndex"] < 0) {
|
|
44870
44931
|
throw new Error("Invalid cursor target");
|
|
44871
44932
|
}
|
|
44872
|
-
|
|
44933
|
+
if (kind === "active") {
|
|
44934
|
+
if (keys !== "endIndex,epoch,kind,sessionId" || typeof record2["epoch"] !== "string") {
|
|
44935
|
+
throw new Error("Invalid active cursor target");
|
|
44936
|
+
}
|
|
44937
|
+
return { endIndex: record2["endIndex"], epoch: record2["epoch"], kind, sessionId };
|
|
44938
|
+
}
|
|
44939
|
+
if (keys !== "endIndex,kind,sessionId" && !legacyNative) {
|
|
44940
|
+
throw new Error("Invalid native cursor target");
|
|
44941
|
+
}
|
|
44942
|
+
return { endIndex: record2["endIndex"], kind, sessionId };
|
|
44873
44943
|
} catch (cause) {
|
|
44874
44944
|
throw new AcpExecutionError("The native Session history cursor is invalid", { cause }, "invalid_cursor");
|
|
44875
44945
|
}
|
|
44876
44946
|
}
|
|
44947
|
+
function activeHistoryCursor(sessionId, epoch, endIndex) {
|
|
44948
|
+
return encodeLiveHistoryCursor({ endIndex, epoch, kind: "active", sessionId });
|
|
44949
|
+
}
|
|
44950
|
+
function nativeHistoryCursor(sessionId, endIndex) {
|
|
44951
|
+
return encodeLiveHistoryCursor({ endIndex, kind: "native", sessionId });
|
|
44952
|
+
}
|
|
44877
44953
|
function liveHistoryCoveredTurnRanges(history) {
|
|
44878
44954
|
const ranges = [];
|
|
44879
44955
|
let historyIndex = history.messages.length;
|
|
@@ -44894,139 +44970,180 @@ function liveHistoryCoveredTurnRanges(history) {
|
|
|
44894
44970
|
function historyMessageCharacters(message) {
|
|
44895
44971
|
return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
|
|
44896
44972
|
}
|
|
44897
|
-
function
|
|
44973
|
+
function isNativeHistoryImageMimeType(mimeType) {
|
|
44974
|
+
return mimeType === "image/png" || mimeType === "image/jpeg" || mimeType === "image/gif" || mimeType === "image/webp";
|
|
44975
|
+
}
|
|
44976
|
+
function selectMessagesBefore(messages, endIndex, messageLimit, characterLimit) {
|
|
44898
44977
|
const selected = [];
|
|
44899
44978
|
let remainingCharacters = characterLimit;
|
|
44900
|
-
|
|
44979
|
+
let startIndex = endIndex;
|
|
44980
|
+
for (let index = endIndex - 1; index >= 0 && selected.length < messageLimit; index -= 1) {
|
|
44901
44981
|
const message = messages[index];
|
|
44902
44982
|
if (message === void 0) {
|
|
44903
44983
|
break;
|
|
44904
44984
|
}
|
|
44905
44985
|
const characters = historyMessageCharacters(message);
|
|
44906
|
-
if (characters
|
|
44907
|
-
|
|
44908
|
-
remainingCharacters -= characters;
|
|
44909
|
-
continue;
|
|
44910
|
-
}
|
|
44911
|
-
const structuredCharacters = characters - message.text.length;
|
|
44912
|
-
if (selected.length === 0 && structuredCharacters <= remainingCharacters) {
|
|
44913
|
-
const textCharacters = remainingCharacters - structuredCharacters;
|
|
44914
|
-
selected.unshift({ ...message, text: textCharacters === 0 ? "" : message.text.slice(-textCharacters) });
|
|
44915
|
-
remainingCharacters = 0;
|
|
44986
|
+
if (characters > remainingCharacters) {
|
|
44987
|
+
break;
|
|
44916
44988
|
}
|
|
44917
|
-
|
|
44989
|
+
selected.unshift(message);
|
|
44990
|
+
remainingCharacters -= characters;
|
|
44991
|
+
startIndex = index;
|
|
44918
44992
|
}
|
|
44919
|
-
|
|
44920
|
-
|
|
44921
|
-
|
|
44922
|
-
|
|
44923
|
-
|
|
44993
|
+
if (selected.length === 0 && endIndex > 0) {
|
|
44994
|
+
throw new AcpExecutionError(
|
|
44995
|
+
"A native Session history item exceeds the page budget",
|
|
44996
|
+
{},
|
|
44997
|
+
"history_item_too_large"
|
|
44998
|
+
);
|
|
44999
|
+
}
|
|
45000
|
+
return { characters: characterLimit - remainingCharacters, messages: selected, startIndex };
|
|
44924
45001
|
}
|
|
44925
45002
|
function nativeActiveMessage(message) {
|
|
44926
|
-
|
|
44927
|
-
|
|
44928
|
-
|
|
44929
|
-
|
|
44930
|
-
|
|
44931
|
-
|
|
45003
|
+
if (message.role === "assistant") {
|
|
45004
|
+
return {
|
|
45005
|
+
activities: message.activities,
|
|
45006
|
+
content: message.content,
|
|
45007
|
+
role: "assistant",
|
|
45008
|
+
text: message.text
|
|
45009
|
+
};
|
|
45010
|
+
}
|
|
45011
|
+
const images = (message.images ?? []).flatMap((image) => {
|
|
45012
|
+
if (image.data.length < 4 || image.data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(image.data) || !isNativeHistoryImageMimeType(image.mimeType)) {
|
|
45013
|
+
return [];
|
|
45014
|
+
}
|
|
45015
|
+
return [{ data: image.data, mimeType: image.mimeType, name: image.name }];
|
|
45016
|
+
});
|
|
45017
|
+
return { ...images.length === 0 ? {} : { images }, role: "user", text: message.text };
|
|
45018
|
+
}
|
|
45019
|
+
function nativeHistoryCoversCompletedRecovery(history, recovery) {
|
|
45020
|
+
const root = recovery.messages.find((message) => message.role === "user" && message.id === recovery.commandId);
|
|
45021
|
+
if (root === void 0) {
|
|
45022
|
+
return false;
|
|
45023
|
+
}
|
|
45024
|
+
const rootIndex = history.messages.findLastIndex(
|
|
45025
|
+
(message) => message.role === "user" && message.text === root.text
|
|
45026
|
+
);
|
|
45027
|
+
if (rootIndex < 0) {
|
|
45028
|
+
return false;
|
|
45029
|
+
}
|
|
45030
|
+
const nativeAssistant = history.messages.slice(rootIndex + 1).filter((message) => message.role === "assistant");
|
|
45031
|
+
if (nativeAssistant.length === 0) {
|
|
45032
|
+
return false;
|
|
45033
|
+
}
|
|
45034
|
+
const recoveryAssistant = recovery.messages.filter((message) => message.role === "assistant");
|
|
45035
|
+
const recoveryText = recoveryAssistant.map((message) => message.text).join("");
|
|
45036
|
+
const nativeText = nativeAssistant.map((message) => message.text).join("");
|
|
45037
|
+
if (recoveryText.length > 0 && !nativeText.includes(recoveryText)) {
|
|
45038
|
+
return false;
|
|
45039
|
+
}
|
|
45040
|
+
const nativeContent = new Set(
|
|
45041
|
+
nativeAssistant.flatMap((message) => message.content).map((content) => JSON.stringify(content))
|
|
45042
|
+
);
|
|
45043
|
+
return recoveryAssistant.flatMap((message) => message.content).every((content) => nativeContent.has(JSON.stringify(content)));
|
|
44932
45044
|
}
|
|
44933
|
-
function
|
|
45045
|
+
function historyBeforeActiveTurn(history, activeTurn) {
|
|
44934
45046
|
if (history.status === "unavailable") {
|
|
44935
|
-
|
|
44936
|
-
throw new AcpExecutionError("Unavailable native Session history has no cursor", {}, "invalid_cursor");
|
|
44937
|
-
}
|
|
44938
|
-
return { cause: history.cause, nextCursor: null, status: "unavailable" };
|
|
45047
|
+
return history;
|
|
44939
45048
|
}
|
|
44940
|
-
const
|
|
45049
|
+
const activeRoot = activeTurn.messages.find(
|
|
45050
|
+
(message) => message.role === "user" && message.id === activeTurn.commandId
|
|
45051
|
+
);
|
|
45052
|
+
const matchingActiveUserIndex = activeRoot === void 0 ? -1 : activeTurn.state === "completed" || history.messages.at(-1)?.role === "user" && history.messages.at(-1)?.text === activeRoot.text || history.coveredCommandIds.includes(activeTurn.commandId) ? history.messages.findLastIndex((message) => message.role === "user" && message.text === activeRoot.text) : -1;
|
|
45053
|
+
const activeUserIndex = matchingActiveUserIndex >= 0 ? matchingActiveUserIndex : liveHistoryCoveredTurnRanges(history).find((range) => range.commandId === activeTurn.commandId)?.userIndex ?? -1;
|
|
45054
|
+
if (activeUserIndex < 0) {
|
|
45055
|
+
return history;
|
|
45056
|
+
}
|
|
45057
|
+
return {
|
|
45058
|
+
...history,
|
|
45059
|
+
coveredCommandIds: history.coveredCommandIds.filter((id) => id !== activeTurn.commandId),
|
|
45060
|
+
coveredMessageIds: history.coveredMessageIds.filter(
|
|
45061
|
+
(id) => id !== `${activeTurn.commandId}:user` && id !== `${activeTurn.commandId}:agent`
|
|
45062
|
+
),
|
|
45063
|
+
messages: history.messages.slice(0, activeUserIndex)
|
|
45064
|
+
};
|
|
45065
|
+
}
|
|
45066
|
+
function paginateAvailableNativeHistory(history, sessionId, endIndex, limit, characterLimit) {
|
|
44941
45067
|
if (endIndex > history.messages.length) {
|
|
44942
45068
|
throw new AcpExecutionError("The native Session history cursor is invalid", {}, "invalid_cursor");
|
|
44943
45069
|
}
|
|
44944
|
-
const
|
|
45070
|
+
const selected = selectMessagesBefore(history.messages, endIndex, limit, characterLimit);
|
|
44945
45071
|
const coveredMessageIds = new Set(history.coveredMessageIds);
|
|
44946
45072
|
const ranges = liveHistoryCoveredTurnRanges(history);
|
|
44947
45073
|
return {
|
|
44948
|
-
coveredCommandIds: ranges.filter((range) => range.userIndex >= startIndex && range.assistantEndIndex <= endIndex).map((range) => range.commandId),
|
|
45074
|
+
coveredCommandIds: ranges.filter((range) => range.userIndex >= selected.startIndex && range.assistantEndIndex <= endIndex).map((range) => range.commandId),
|
|
44949
45075
|
coveredMessageIds: ranges.flatMap((range) => [
|
|
44950
|
-
...range.userIndex >= startIndex && range.userIndex < endIndex && coveredMessageIds.has(`${range.commandId}:user`) ? [`${range.commandId}:user`] : [],
|
|
44951
|
-
...range.assistantStartIndex >= startIndex && range.assistantEndIndex <= endIndex && coveredMessageIds.has(`${range.commandId}:agent`) ? [`${range.commandId}:agent`] : []
|
|
45076
|
+
...range.userIndex >= selected.startIndex && range.userIndex < endIndex && coveredMessageIds.has(`${range.commandId}:user`) ? [`${range.commandId}:user`] : [],
|
|
45077
|
+
...range.assistantStartIndex >= selected.startIndex && range.assistantEndIndex <= endIndex && coveredMessageIds.has(`${range.commandId}:agent`) ? [`${range.commandId}:agent`] : []
|
|
44952
45078
|
]),
|
|
44953
|
-
messages:
|
|
44954
|
-
nextCursor: startIndex > 0 ?
|
|
45079
|
+
messages: selected.messages,
|
|
45080
|
+
nextCursor: selected.startIndex > 0 ? nativeHistoryCursor(sessionId, selected.startIndex) : null,
|
|
44955
45081
|
status: "available",
|
|
44956
45082
|
truncated: history.truncated
|
|
44957
45083
|
};
|
|
44958
45084
|
}
|
|
44959
|
-
function
|
|
44960
|
-
if (
|
|
44961
|
-
|
|
45085
|
+
function paginateNativeHistory(history, sessionId, cursor, limit) {
|
|
45086
|
+
if (cursor?.kind === "active") {
|
|
45087
|
+
throw new AcpExecutionError("The native Session history cursor is invalid", {}, "invalid_cursor");
|
|
44962
45088
|
}
|
|
44963
45089
|
if (history.status === "unavailable") {
|
|
44964
|
-
|
|
44965
|
-
|
|
44966
|
-
|
|
44967
|
-
|
|
44968
|
-
);
|
|
44969
|
-
return {
|
|
44970
|
-
coveredCommandIds: [],
|
|
44971
|
-
coveredMessageIds: [],
|
|
44972
|
-
messages: bounded3.messages,
|
|
44973
|
-
nextCursor: null,
|
|
44974
|
-
status: "available",
|
|
44975
|
-
truncated: activeTurn.truncated || bounded3.truncated
|
|
44976
|
-
};
|
|
45090
|
+
if (cursor !== null) {
|
|
45091
|
+
throw new AcpExecutionError("Unavailable native Session history has no cursor", {}, "invalid_cursor");
|
|
45092
|
+
}
|
|
45093
|
+
return { cause: history.cause, nextCursor: null, status: "unavailable" };
|
|
44977
45094
|
}
|
|
44978
|
-
|
|
44979
|
-
|
|
45095
|
+
return paginateAvailableNativeHistory(
|
|
45096
|
+
history,
|
|
45097
|
+
sessionId,
|
|
45098
|
+
cursor?.endIndex ?? history.messages.length,
|
|
45099
|
+
limit,
|
|
45100
|
+
SESSION_HISTORY_CHARACTER_LIMIT
|
|
44980
45101
|
);
|
|
44981
|
-
|
|
44982
|
-
|
|
44983
|
-
|
|
44984
|
-
|
|
44985
|
-
const activeUserIndex = matchingActiveUserIndex >= 0 ? matchingActiveUserIndex : liveHistoryCoveredTurnRanges(history).find((range) => range.commandId === activeTurn.commandId)?.userIndex ?? -1;
|
|
44986
|
-
if (activeUserIndex >= 0) {
|
|
44987
|
-
history = {
|
|
44988
|
-
...history,
|
|
44989
|
-
coveredCommandIds: history.coveredCommandIds.filter((id) => id !== activeTurn.commandId),
|
|
44990
|
-
coveredMessageIds: history.coveredMessageIds.filter(
|
|
44991
|
-
(id) => id !== `${activeTurn.commandId}:user` && id !== `${activeTurn.commandId}:agent`
|
|
44992
|
-
),
|
|
44993
|
-
messages: history.messages.slice(0, activeUserIndex + 1)
|
|
44994
|
-
};
|
|
44995
|
-
}
|
|
44996
|
-
const latestNativeMessage = history.messages.at(-1);
|
|
44997
|
-
const firstActiveMessage = activeTurn.messages[0];
|
|
44998
|
-
const preserveNativeRoot = activeUserIndex >= 0 || firstActiveMessage?.role === "user" && latestNativeMessage?.role === "user" && latestNativeMessage.text === firstActiveMessage.text;
|
|
44999
|
-
const activeMessages = activeTurn.messages.slice(preserveNativeRoot ? 1 : 0).map(nativeActiveMessage);
|
|
45000
|
-
const bounded2 = boundedActiveMessages(activeMessages, limit, SESSION_HISTORY_CHARACTER_LIMIT);
|
|
45001
|
-
let historicalMessageCount = 0;
|
|
45002
|
-
let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT - bounded2.characters;
|
|
45003
|
-
const historicalMessageLimit = Math.max(0, limit - bounded2.messages.length);
|
|
45004
|
-
for (let index = history.messages.length - 1; index >= 0 && historicalMessageCount < historicalMessageLimit; index -= 1) {
|
|
45005
|
-
const message = history.messages[index];
|
|
45006
|
-
if (message === void 0) {
|
|
45007
|
-
break;
|
|
45008
|
-
}
|
|
45009
|
-
const characters = historyMessageCharacters(message);
|
|
45010
|
-
if (characters > remainingCharacters) {
|
|
45011
|
-
break;
|
|
45012
|
-
}
|
|
45013
|
-
historicalMessageCount += 1;
|
|
45014
|
-
remainingCharacters -= characters;
|
|
45102
|
+
}
|
|
45103
|
+
function paginateActiveTurn(history, activeTurn, sessionId, endIndex, limit) {
|
|
45104
|
+
if (endIndex > activeTurn.messages.length) {
|
|
45105
|
+
throw new AcpExecutionError("The native Session history cursor is invalid", {}, "invalid_cursor");
|
|
45015
45106
|
}
|
|
45016
|
-
const
|
|
45017
|
-
|
|
45018
|
-
|
|
45019
|
-
|
|
45020
|
-
|
|
45021
|
-
|
|
45022
|
-
|
|
45023
|
-
|
|
45107
|
+
const activeMessages = activeTurn.messages.map(nativeActiveMessage);
|
|
45108
|
+
const active = selectMessagesBefore(activeMessages, endIndex, limit, SESSION_HISTORY_CHARACTER_LIMIT);
|
|
45109
|
+
const historicalLimit = limit - active.messages.length;
|
|
45110
|
+
const historicalCharacterLimit = SESSION_HISTORY_CHARACTER_LIMIT - active.characters;
|
|
45111
|
+
const pendingHistoricalCursor = history.status === "available" && history.messages.length > 0 ? nativeHistoryCursor(sessionId, history.messages.length) : null;
|
|
45112
|
+
const latestHistoricalMessage = history.status === "available" ? history.messages.at(-1) : void 0;
|
|
45113
|
+
const historicalPageFits = latestHistoricalMessage === void 0 || historyMessageCharacters(latestHistoricalMessage) <= historicalCharacterLimit;
|
|
45114
|
+
const historical = active.startIndex === 0 && history.status === "available" && historicalLimit > 0 && historicalPageFits ? paginateAvailableNativeHistory(
|
|
45115
|
+
history,
|
|
45116
|
+
sessionId,
|
|
45117
|
+
history.messages.length,
|
|
45118
|
+
historicalLimit,
|
|
45119
|
+
historicalCharacterLimit
|
|
45120
|
+
) : null;
|
|
45024
45121
|
return {
|
|
45025
|
-
|
|
45026
|
-
|
|
45027
|
-
|
|
45122
|
+
coveredCommandIds: historical?.coveredCommandIds ?? [],
|
|
45123
|
+
coveredMessageIds: [
|
|
45124
|
+
...historical?.coveredMessageIds ?? [],
|
|
45125
|
+
...active.startIndex === 0 ? [`${activeTurn.commandId}:user`, `${activeTurn.commandId}:agent`] : []
|
|
45126
|
+
],
|
|
45127
|
+
messages: [...historical?.messages ?? [], ...active.messages],
|
|
45128
|
+
nextCursor: active.startIndex > 0 ? activeHistoryCursor(sessionId, activeTurn.epoch, active.startIndex) : historical === null ? pendingHistoricalCursor : historical.nextCursor,
|
|
45129
|
+
status: "available",
|
|
45130
|
+
truncated: activeTurn.truncated || (historical?.truncated ?? false)
|
|
45028
45131
|
};
|
|
45029
45132
|
}
|
|
45133
|
+
function paginateLiveSessionHistory(history, activeTurn, sessionId, encodedCursor, limit) {
|
|
45134
|
+
const cursor = encodedCursor === null ? null : decodeLiveHistoryCursor(encodedCursor, sessionId);
|
|
45135
|
+
if (activeTurn === null || activeTurn.state === "completed" && history.status === "available" && nativeHistoryCoversCompletedRecovery(history, activeTurn)) {
|
|
45136
|
+
return paginateNativeHistory(history, sessionId, cursor, limit);
|
|
45137
|
+
}
|
|
45138
|
+
const historical = historyBeforeActiveTurn(history, activeTurn);
|
|
45139
|
+
if (cursor?.kind === "native") {
|
|
45140
|
+
return paginateNativeHistory(historical, sessionId, cursor, limit);
|
|
45141
|
+
}
|
|
45142
|
+
if (cursor !== null && cursor.epoch !== activeTurn.epoch) {
|
|
45143
|
+
throw new AcpExecutionError("The active Turn history cursor is stale", {}, "stale_cursor");
|
|
45144
|
+
}
|
|
45145
|
+
return paginateActiveTurn(historical, activeTurn, sessionId, cursor?.endIndex ?? activeTurn.messages.length, limit);
|
|
45146
|
+
}
|
|
45030
45147
|
function mergeLiveSessionHistory(history, activeTurn, sessionId) {
|
|
45031
45148
|
const page = paginateLiveSessionHistory(history, activeTurn, sessionId, null, 1e3);
|
|
45032
45149
|
if (page.status === "unavailable") {
|
|
@@ -45037,7 +45154,7 @@ function mergeLiveSessionHistory(history, activeTurn, sessionId) {
|
|
|
45037
45154
|
coveredMessageIds: page.coveredMessageIds,
|
|
45038
45155
|
messages: page.messages,
|
|
45039
45156
|
status: "available",
|
|
45040
|
-
truncated: page.truncated
|
|
45157
|
+
truncated: page.truncated || page.nextCursor !== null
|
|
45041
45158
|
};
|
|
45042
45159
|
}
|
|
45043
45160
|
|
|
@@ -45556,15 +45673,13 @@ async function executePrompt({
|
|
|
45556
45673
|
});
|
|
45557
45674
|
operations.transitionExecution(command.commandId, "running");
|
|
45558
45675
|
if (availability.disposition === SessionPromptDisposition.Steer) {
|
|
45559
|
-
|
|
45560
|
-
if (updated === null) {
|
|
45676
|
+
if (!recordSteeringPrompt()) {
|
|
45561
45677
|
throw new AcpExecutionError(
|
|
45562
45678
|
"The steering target is unavailable",
|
|
45563
45679
|
{},
|
|
45564
45680
|
"prompt_queue_target_unavailable"
|
|
45565
45681
|
);
|
|
45566
45682
|
}
|
|
45567
|
-
publisher.publish(command.sessionId, updated);
|
|
45568
45683
|
}
|
|
45569
45684
|
const stream = activateAttempt();
|
|
45570
45685
|
publisher.publish(command.sessionId, {
|
|
@@ -45952,7 +46067,7 @@ function createDaemonCommandHandler({
|
|
|
45952
46067
|
resolveEnvironment: resolveAgentCatalogEnvironment
|
|
45953
46068
|
});
|
|
45954
46069
|
const queueChanged = (sessionId) => publisher.publish(sessionId, { kind: "session.queue.changed", sessionId });
|
|
45955
|
-
const
|
|
46070
|
+
const activeTurnRecovery = (sessionId) => activeTurns.recovery((command) => command.sessionId === sessionId);
|
|
45956
46071
|
const nativeRequestHandler = createNativeSessionRequestHandler({
|
|
45957
46072
|
audit,
|
|
45958
46073
|
diagnostics,
|
|
@@ -45973,7 +46088,7 @@ function createDaemonCommandHandler({
|
|
|
45973
46088
|
directories,
|
|
45974
46089
|
audit,
|
|
45975
46090
|
sessions,
|
|
45976
|
-
|
|
46091
|
+
activeTurnRecovery,
|
|
45977
46092
|
signal
|
|
45978
46093
|
);
|
|
45979
46094
|
return;
|
|
@@ -45987,7 +46102,7 @@ function createDaemonCommandHandler({
|
|
|
45987
46102
|
directories,
|
|
45988
46103
|
audit,
|
|
45989
46104
|
sessions,
|
|
45990
|
-
|
|
46105
|
+
activeTurnRecovery,
|
|
45991
46106
|
signal
|
|
45992
46107
|
);
|
|
45993
46108
|
return;
|