@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/runtime.js
CHANGED
|
@@ -21034,18 +21034,21 @@ var activeTurnMessageSchema = external_exports.discriminatedUnion("role", [
|
|
|
21034
21034
|
activeTurnAssistantMessageSchema
|
|
21035
21035
|
]);
|
|
21036
21036
|
var activeTurnSnapshotSchema = external_exports.strictObject({
|
|
21037
|
-
activities: external_exports.array(activeTurnActivitySchema).readonly(),
|
|
21038
21037
|
commandId: identifierStringSchema,
|
|
21039
|
-
content: external_exports.array(displayContentSchema).readonly(),
|
|
21040
|
-
prompt: external_exports.string().max(1e5),
|
|
21041
|
-
text: external_exports.string(),
|
|
21042
|
-
truncated: external_exports.boolean(),
|
|
21043
21038
|
epoch: identifierStringSchema,
|
|
21039
|
+
hasOlder: external_exports.boolean(),
|
|
21044
21040
|
interaction: external_exports.discriminatedUnion("kind", [sessionPermissionRequestedEventSchema, sessionElicitationRequestedEventSchema]).nullable(),
|
|
21045
21041
|
messages: external_exports.array(activeTurnMessageSchema).max(SESSION_HISTORY_MESSAGE_LIMIT).readonly(),
|
|
21046
21042
|
sequence: external_exports.number().int().nonnegative(),
|
|
21047
|
-
state: external_exports.literal("running")
|
|
21048
|
-
|
|
21043
|
+
state: external_exports.literal("running"),
|
|
21044
|
+
truncated: external_exports.boolean()
|
|
21045
|
+
}).readonly().refine(
|
|
21046
|
+
(snapshot) => snapshot.messages.reduce(
|
|
21047
|
+
(total, message) => total + message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0),
|
|
21048
|
+
0
|
|
21049
|
+
) <= SESSION_HISTORY_CHARACTER_LIMIT,
|
|
21050
|
+
"Active Turn snapshot content is too large"
|
|
21051
|
+
);
|
|
21049
21052
|
var identity = {
|
|
21050
21053
|
...envelope,
|
|
21051
21054
|
kind: external_exports.literal(NATIVE_SESSION_REQUEST_KIND),
|
|
@@ -21189,27 +21192,14 @@ var encodeNativeSessionCancel = (value) => JSON.stringify(nativeSessionCancelSch
|
|
|
21189
21192
|
|
|
21190
21193
|
// ../protocol/src/session-events.ts
|
|
21191
21194
|
var SESSION_EVENT_KIND = "session.event";
|
|
21192
|
-
var SESSION_EVENT_COMMITTED_KIND = "session.event.committed";
|
|
21193
21195
|
var MAX_RECORDED_EVENT_LENGTH = 8 * 1024 * 1024;
|
|
21194
21196
|
var eventEnvelopeSchema = external_exports.strictObject({
|
|
21195
21197
|
kind: external_exports.literal(SESSION_EVENT_KIND),
|
|
21196
21198
|
payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
|
|
21197
21199
|
sessionId: identifierStringSchema
|
|
21198
21200
|
}).readonly();
|
|
21199
|
-
var committedEventSchema = external_exports.strictObject({
|
|
21200
|
-
kind: external_exports.literal(SESSION_EVENT_COMMITTED_KIND),
|
|
21201
|
-
payload: external_exports.string().min(2).max(MAX_RECORDED_EVENT_LENGTH),
|
|
21202
|
-
sessionId: identifierStringSchema
|
|
21203
|
-
}).readonly();
|
|
21204
21201
|
var SESSION_QUEUE_CHANGED_KIND = "session.queue.changed";
|
|
21205
21202
|
var sessionQueueChangedSchema = external_exports.strictObject({ kind: external_exports.literal(SESSION_QUEUE_CHANGED_KIND), sessionId: identifierStringSchema }).readonly();
|
|
21206
|
-
var SESSION_TURN_UPDATED_KIND = "session.turn.updated";
|
|
21207
|
-
var sessionTurnUpdatedSchema = external_exports.strictObject({
|
|
21208
|
-
kind: external_exports.literal(SESSION_TURN_UPDATED_KIND),
|
|
21209
|
-
sessionId: identifierStringSchema,
|
|
21210
|
-
turn: activeTurnSnapshotSchema
|
|
21211
|
-
}).readonly();
|
|
21212
|
-
var decodeSessionTurnUpdatedEvent = (encoded) => decode5(encoded, sessionTurnUpdatedSchema);
|
|
21213
21203
|
function decode5(encoded, schema) {
|
|
21214
21204
|
let value;
|
|
21215
21205
|
try {
|
|
@@ -21239,8 +21229,6 @@ var encodeSessionEventEnvelope = (message) => encode4(message, eventEnvelopeSche
|
|
|
21239
21229
|
function decodeRecordedSessionEvent(encoded) {
|
|
21240
21230
|
const kind = decodeMessageKind(encoded);
|
|
21241
21231
|
switch (kind) {
|
|
21242
|
-
case SESSION_TURN_UPDATED_KIND:
|
|
21243
|
-
return decodeSessionTurnUpdatedEvent(encoded);
|
|
21244
21232
|
case SESSION_QUEUE_CHANGED_KIND:
|
|
21245
21233
|
return decode5(encoded, sessionQueueChangedSchema);
|
|
21246
21234
|
case AGENT_ACTIVITY_KIND:
|
|
@@ -37853,6 +37841,28 @@ var DaemonInstallationObserver = class {
|
|
|
37853
37841
|
|
|
37854
37842
|
// src/daemon-active-turn.ts
|
|
37855
37843
|
import { randomUUID } from "node:crypto";
|
|
37844
|
+
function activeMessageCharacters(message) {
|
|
37845
|
+
return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
|
|
37846
|
+
}
|
|
37847
|
+
var ACTIVE_TURN_TEXT_CHUNK_LIMIT = Math.floor(SESSION_HISTORY_CHARACTER_LIMIT / 2);
|
|
37848
|
+
function boundedRecoveryMessages(messages) {
|
|
37849
|
+
const selected = [];
|
|
37850
|
+
let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT;
|
|
37851
|
+
for (let index = messages.length - 1; index >= 0 && selected.length < SESSION_HISTORY_MESSAGE_LIMIT; index -= 1) {
|
|
37852
|
+
const message = messages[index];
|
|
37853
|
+
if (message === void 0) {
|
|
37854
|
+
break;
|
|
37855
|
+
}
|
|
37856
|
+
const characters = activeMessageCharacters(message);
|
|
37857
|
+
if (characters <= remainingCharacters) {
|
|
37858
|
+
selected.unshift(message);
|
|
37859
|
+
remainingCharacters -= characters;
|
|
37860
|
+
continue;
|
|
37861
|
+
}
|
|
37862
|
+
break;
|
|
37863
|
+
}
|
|
37864
|
+
return { hasOlder: selected.length !== messages.length, messages: selected };
|
|
37865
|
+
}
|
|
37856
37866
|
var ActiveDaemonTurn = class {
|
|
37857
37867
|
attemptId;
|
|
37858
37868
|
command;
|
|
@@ -37860,9 +37870,7 @@ var ActiveDaemonTurn = class {
|
|
|
37860
37870
|
#finished = Promise.withResolvers();
|
|
37861
37871
|
#cancellationRequested = false;
|
|
37862
37872
|
#dispatch;
|
|
37863
|
-
#text = "";
|
|
37864
37873
|
#activities = /* @__PURE__ */ new Map();
|
|
37865
|
-
#content = /* @__PURE__ */ new Map();
|
|
37866
37874
|
#timeline;
|
|
37867
37875
|
#sequence = 0;
|
|
37868
37876
|
#interaction = null;
|
|
@@ -37909,9 +37917,17 @@ var ActiveDaemonTurn = class {
|
|
|
37909
37917
|
effectiveDisposition = () => this.#dispatch.kind === "promoted" ? SessionPromptDisposition.Steer : this.command.disposition;
|
|
37910
37918
|
recordEvent = (event) => {
|
|
37911
37919
|
if (event.kind === AGENT_MESSAGE_DELTA_KIND) {
|
|
37912
|
-
|
|
37920
|
+
const sequence = this.advance();
|
|
37913
37921
|
this.appendMessageText(event.messageId, event.text);
|
|
37914
|
-
return
|
|
37922
|
+
return {
|
|
37923
|
+
commandId: this.command.commandId,
|
|
37924
|
+
epoch: this.#epoch,
|
|
37925
|
+
kind: AGENT_MESSAGE_DELTA_KIND,
|
|
37926
|
+
messageId: event.messageId,
|
|
37927
|
+
sequence,
|
|
37928
|
+
sessionId: this.command.sessionId,
|
|
37929
|
+
text: event.text
|
|
37930
|
+
};
|
|
37915
37931
|
}
|
|
37916
37932
|
if (event.sessionId !== this.command.sessionId || "commandId" in event && event.commandId !== this.command.commandId) {
|
|
37917
37933
|
return event;
|
|
@@ -37958,7 +37974,6 @@ var ActiveDaemonTurn = class {
|
|
|
37958
37974
|
toolKind: previous?.toolKind ?? ""
|
|
37959
37975
|
});
|
|
37960
37976
|
} else if (event.kind === AGENT_CONTENT_KIND) {
|
|
37961
|
-
this.#content.set(event.contentId, event.content);
|
|
37962
37977
|
const target = this.#timeline.findLastIndex(
|
|
37963
37978
|
(entry) => entry.kind === "message" && entry.sourceMessageId === event.messageId
|
|
37964
37979
|
);
|
|
@@ -37984,7 +37999,7 @@ var ActiveDaemonTurn = class {
|
|
|
37984
37999
|
this.#interaction = null;
|
|
37985
38000
|
}
|
|
37986
38001
|
if (event.kind === AGENT_ACTIVITY_KIND || event.kind === AGENT_ACTIVITY_NARRATION_KIND || event.kind === AGENT_CONTENT_KIND) {
|
|
37987
|
-
|
|
38002
|
+
this.advance();
|
|
37988
38003
|
}
|
|
37989
38004
|
return event;
|
|
37990
38005
|
};
|
|
@@ -37993,7 +38008,7 @@ var ActiveDaemonTurn = class {
|
|
|
37993
38008
|
while (remaining.length > 0) {
|
|
37994
38009
|
const latest = this.#timeline.at(-1);
|
|
37995
38010
|
if (latest?.kind === "message" && latest.sourceMessageId === messageId) {
|
|
37996
|
-
const available =
|
|
38011
|
+
const available = ACTIVE_TURN_TEXT_CHUNK_LIMIT - latest.text.length;
|
|
37997
38012
|
if (available > 0) {
|
|
37998
38013
|
this.#timeline = [
|
|
37999
38014
|
...this.#timeline.slice(0, -1),
|
|
@@ -38010,21 +38025,22 @@ var ActiveDaemonTurn = class {
|
|
|
38010
38025
|
id: decodeIdentifier(randomUUID()),
|
|
38011
38026
|
kind: "message",
|
|
38012
38027
|
sourceMessageId: messageId,
|
|
38013
|
-
text: remaining.slice(0,
|
|
38028
|
+
text: remaining.slice(0, ACTIVE_TURN_TEXT_CHUNK_LIMIT)
|
|
38014
38029
|
}
|
|
38015
38030
|
];
|
|
38016
|
-
remaining = remaining.slice(
|
|
38031
|
+
remaining = remaining.slice(ACTIVE_TURN_TEXT_CHUNK_LIMIT);
|
|
38017
38032
|
}
|
|
38018
38033
|
}
|
|
38019
38034
|
recordSteeringPrompt = (command) => {
|
|
38020
38035
|
if (this.#dispatch.kind !== "running" || command.sessionId !== this.command.sessionId || command.targetCommandId !== this.command.commandId) {
|
|
38021
|
-
return
|
|
38036
|
+
return false;
|
|
38022
38037
|
}
|
|
38023
38038
|
this.#timeline = [
|
|
38024
38039
|
...this.#timeline,
|
|
38025
38040
|
{ id: decodeIdentifier(command.commandId), images: command.images, kind: "user", text: command.prompt }
|
|
38026
38041
|
];
|
|
38027
|
-
|
|
38042
|
+
this.advance();
|
|
38043
|
+
return true;
|
|
38028
38044
|
};
|
|
38029
38045
|
timelineMessages() {
|
|
38030
38046
|
return this.#timeline.flatMap((entry) => {
|
|
@@ -38046,32 +38062,39 @@ var ActiveDaemonTurn = class {
|
|
|
38046
38062
|
return activity2 === void 0 ? [] : [{ activities: [activity2], content: [], id: entry.id, role: "assistant", text: "" }];
|
|
38047
38063
|
});
|
|
38048
38064
|
}
|
|
38049
|
-
|
|
38050
|
-
this.#
|
|
38051
|
-
|
|
38052
|
-
if (turn === null) {
|
|
38053
|
-
throw new Error("Only a running turn can publish a snapshot");
|
|
38065
|
+
advance = () => {
|
|
38066
|
+
if (this.#dispatch.kind !== "running") {
|
|
38067
|
+
throw new Error("Only a running turn can advance its snapshot");
|
|
38054
38068
|
}
|
|
38055
|
-
|
|
38069
|
+
this.#sequence += 1;
|
|
38070
|
+
return this.#sequence;
|
|
38056
38071
|
};
|
|
38057
38072
|
snapshot = () => {
|
|
38058
38073
|
if (this.#dispatch.kind !== "running") {
|
|
38059
38074
|
return null;
|
|
38060
38075
|
}
|
|
38061
|
-
const
|
|
38062
|
-
const messages = completeMessages.slice(-SESSION_HISTORY_MESSAGE_LIMIT);
|
|
38076
|
+
const bounded2 = boundedRecoveryMessages(this.timelineMessages());
|
|
38063
38077
|
return {
|
|
38064
|
-
activities: [...this.#activities.values()].sort((left, right) => left.sequence - right.sequence),
|
|
38065
38078
|
commandId: decodeIdentifier(this.command.commandId),
|
|
38066
|
-
content: [...this.#content.values()],
|
|
38067
|
-
prompt: this.command.prompt,
|
|
38068
|
-
text: this.#text,
|
|
38069
|
-
truncated: messages.length !== completeMessages.length,
|
|
38070
38079
|
epoch: this.#epoch,
|
|
38080
|
+
hasOlder: bounded2.hasOlder,
|
|
38071
38081
|
interaction: this.#interaction,
|
|
38072
|
-
messages,
|
|
38082
|
+
messages: bounded2.messages,
|
|
38073
38083
|
sequence: this.#sequence,
|
|
38074
|
-
state: "running"
|
|
38084
|
+
state: "running",
|
|
38085
|
+
truncated: false
|
|
38086
|
+
};
|
|
38087
|
+
};
|
|
38088
|
+
recovery = () => {
|
|
38089
|
+
if (this.#dispatch.kind !== "running") {
|
|
38090
|
+
return null;
|
|
38091
|
+
}
|
|
38092
|
+
return {
|
|
38093
|
+
commandId: decodeIdentifier(this.command.commandId),
|
|
38094
|
+
epoch: this.#epoch,
|
|
38095
|
+
messages: this.timelineMessages(),
|
|
38096
|
+
state: "running",
|
|
38097
|
+
truncated: false
|
|
38075
38098
|
};
|
|
38076
38099
|
};
|
|
38077
38100
|
matches = (cancellation) => cancellation.commandId === this.command.commandId && cancellation.sessionId === this.command.sessionId;
|
|
@@ -38097,6 +38120,7 @@ var ActiveDaemonTurn = class {
|
|
|
38097
38120
|
};
|
|
38098
38121
|
|
|
38099
38122
|
// src/daemon-turn-registry.ts
|
|
38123
|
+
var COMPLETED_TURN_RECOVERY_LIMIT = 32;
|
|
38100
38124
|
var waitForTurnCompletion = (turn, waitSignal) => {
|
|
38101
38125
|
waitSignal.throwIfAborted();
|
|
38102
38126
|
return new Promise((resolve9, reject) => {
|
|
@@ -38123,6 +38147,7 @@ var waitForTurnCompletion = (turn, waitSignal) => {
|
|
|
38123
38147
|
};
|
|
38124
38148
|
var DaemonTurnRegistry = class {
|
|
38125
38149
|
#turns = /* @__PURE__ */ new Map();
|
|
38150
|
+
#completed = /* @__PURE__ */ new Map();
|
|
38126
38151
|
#operations;
|
|
38127
38152
|
constructor(operations) {
|
|
38128
38153
|
this.#operations = operations;
|
|
@@ -38134,7 +38159,22 @@ var DaemonTurnRegistry = class {
|
|
|
38134
38159
|
};
|
|
38135
38160
|
get = (commandId) => this.#turns.get(commandId);
|
|
38136
38161
|
finish = (turn) => {
|
|
38162
|
+
const recovery = turn.recovery();
|
|
38137
38163
|
this.#turns.delete(turn.command.commandId);
|
|
38164
|
+
if (recovery !== null) {
|
|
38165
|
+
this.#completed.delete(turn.command.sessionId);
|
|
38166
|
+
this.#completed.set(turn.command.sessionId, {
|
|
38167
|
+
command: turn.command,
|
|
38168
|
+
recovery: { ...recovery, state: "completed" }
|
|
38169
|
+
});
|
|
38170
|
+
while (this.#completed.size > COMPLETED_TURN_RECOVERY_LIMIT) {
|
|
38171
|
+
const oldestSessionId = this.#completed.keys().next().value;
|
|
38172
|
+
if (oldestSessionId === void 0) {
|
|
38173
|
+
break;
|
|
38174
|
+
}
|
|
38175
|
+
this.#completed.delete(oldestSessionId);
|
|
38176
|
+
}
|
|
38177
|
+
}
|
|
38138
38178
|
turn.finish();
|
|
38139
38179
|
};
|
|
38140
38180
|
recordEvent = (event) => {
|
|
@@ -38155,7 +38195,7 @@ var DaemonTurnRegistry = class {
|
|
|
38155
38195
|
};
|
|
38156
38196
|
recordSteeringPrompt = (command) => {
|
|
38157
38197
|
const target = this.#turns.get(command.targetCommandId);
|
|
38158
|
-
return target?.recordSteeringPrompt(command) ??
|
|
38198
|
+
return target?.recordSteeringPrompt(command) ?? false;
|
|
38159
38199
|
};
|
|
38160
38200
|
executionSnapshot = async (matches) => {
|
|
38161
38201
|
const matching = [];
|
|
@@ -38186,12 +38226,30 @@ var DaemonTurnRegistry = class {
|
|
|
38186
38226
|
}
|
|
38187
38227
|
return null;
|
|
38188
38228
|
};
|
|
38229
|
+
recovery = (matches) => {
|
|
38230
|
+
for (const turn of this.#turns.values()) {
|
|
38231
|
+
if (!matches(turn.command)) {
|
|
38232
|
+
continue;
|
|
38233
|
+
}
|
|
38234
|
+
const recovery = turn.recovery();
|
|
38235
|
+
if (recovery !== null) {
|
|
38236
|
+
return recovery;
|
|
38237
|
+
}
|
|
38238
|
+
}
|
|
38239
|
+
for (const completed of this.#completed.values()) {
|
|
38240
|
+
if (matches(completed.command)) {
|
|
38241
|
+
return completed.recovery;
|
|
38242
|
+
}
|
|
38243
|
+
}
|
|
38244
|
+
return null;
|
|
38245
|
+
};
|
|
38189
38246
|
close = async () => {
|
|
38190
38247
|
const turns = [...this.#turns.values()];
|
|
38191
38248
|
for (const turn of turns) {
|
|
38192
38249
|
turn.abortDaemon();
|
|
38193
38250
|
}
|
|
38194
38251
|
await Promise.all(turns.map((turn) => turn.completion));
|
|
38252
|
+
this.#completed.clear();
|
|
38195
38253
|
};
|
|
38196
38254
|
admitAndWait = async (turn, waitSignal, onQueued) => {
|
|
38197
38255
|
const command = turn.command;
|
|
@@ -40499,10 +40557,10 @@ async function resolveSessionDirectories(directories, bindingId, directoryId2, a
|
|
|
40499
40557
|
}
|
|
40500
40558
|
|
|
40501
40559
|
// src/native-sessions/live-history-page.ts
|
|
40502
|
-
function
|
|
40503
|
-
return Buffer.from(JSON.stringify(
|
|
40560
|
+
function encodeLiveHistoryCursor(cursor) {
|
|
40561
|
+
return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64url");
|
|
40504
40562
|
}
|
|
40505
|
-
function
|
|
40563
|
+
function decodeLiveHistoryCursor(cursor, sessionId) {
|
|
40506
40564
|
try {
|
|
40507
40565
|
if (!/^[A-Za-z0-9_-]{1,512}$/u.test(cursor)) {
|
|
40508
40566
|
throw new Error("Invalid cursor alphabet");
|
|
@@ -40512,14 +40570,32 @@ function liveHistoryEndIndex(cursor, sessionId) {
|
|
|
40512
40570
|
throw new Error("Invalid cursor shape");
|
|
40513
40571
|
}
|
|
40514
40572
|
const record2 = Object.fromEntries(Object.entries(value));
|
|
40515
|
-
|
|
40573
|
+
const keys = Object.keys(record2).sort().join(",");
|
|
40574
|
+
const legacyNative = keys === "endIndex,sessionId";
|
|
40575
|
+
const kind = legacyNative ? "native" : record2["kind"];
|
|
40576
|
+
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) {
|
|
40516
40577
|
throw new Error("Invalid cursor target");
|
|
40517
40578
|
}
|
|
40518
|
-
|
|
40579
|
+
if (kind === "active") {
|
|
40580
|
+
if (keys !== "endIndex,epoch,kind,sessionId" || typeof record2["epoch"] !== "string") {
|
|
40581
|
+
throw new Error("Invalid active cursor target");
|
|
40582
|
+
}
|
|
40583
|
+
return { endIndex: record2["endIndex"], epoch: record2["epoch"], kind, sessionId };
|
|
40584
|
+
}
|
|
40585
|
+
if (keys !== "endIndex,kind,sessionId" && !legacyNative) {
|
|
40586
|
+
throw new Error("Invalid native cursor target");
|
|
40587
|
+
}
|
|
40588
|
+
return { endIndex: record2["endIndex"], kind, sessionId };
|
|
40519
40589
|
} catch (cause) {
|
|
40520
40590
|
throw new AcpExecutionError("The native Session history cursor is invalid", { cause }, "invalid_cursor");
|
|
40521
40591
|
}
|
|
40522
40592
|
}
|
|
40593
|
+
function activeHistoryCursor(sessionId, epoch, endIndex) {
|
|
40594
|
+
return encodeLiveHistoryCursor({ endIndex, epoch, kind: "active", sessionId });
|
|
40595
|
+
}
|
|
40596
|
+
function nativeHistoryCursor(sessionId, endIndex) {
|
|
40597
|
+
return encodeLiveHistoryCursor({ endIndex, kind: "native", sessionId });
|
|
40598
|
+
}
|
|
40523
40599
|
function liveHistoryCoveredTurnRanges(history) {
|
|
40524
40600
|
const ranges = [];
|
|
40525
40601
|
let historyIndex = history.messages.length;
|
|
@@ -40540,139 +40616,180 @@ function liveHistoryCoveredTurnRanges(history) {
|
|
|
40540
40616
|
function historyMessageCharacters(message) {
|
|
40541
40617
|
return message.text.length + (message.role === "assistant" ? JSON.stringify(message.activities).length + JSON.stringify(message.content).length : 0);
|
|
40542
40618
|
}
|
|
40543
|
-
function
|
|
40619
|
+
function isNativeHistoryImageMimeType(mimeType) {
|
|
40620
|
+
return mimeType === "image/png" || mimeType === "image/jpeg" || mimeType === "image/gif" || mimeType === "image/webp";
|
|
40621
|
+
}
|
|
40622
|
+
function selectMessagesBefore(messages, endIndex, messageLimit, characterLimit) {
|
|
40544
40623
|
const selected = [];
|
|
40545
40624
|
let remainingCharacters = characterLimit;
|
|
40546
|
-
|
|
40625
|
+
let startIndex = endIndex;
|
|
40626
|
+
for (let index = endIndex - 1; index >= 0 && selected.length < messageLimit; index -= 1) {
|
|
40547
40627
|
const message = messages[index];
|
|
40548
40628
|
if (message === void 0) {
|
|
40549
40629
|
break;
|
|
40550
40630
|
}
|
|
40551
40631
|
const characters = historyMessageCharacters(message);
|
|
40552
|
-
if (characters
|
|
40553
|
-
|
|
40554
|
-
remainingCharacters -= characters;
|
|
40555
|
-
continue;
|
|
40556
|
-
}
|
|
40557
|
-
const structuredCharacters = characters - message.text.length;
|
|
40558
|
-
if (selected.length === 0 && structuredCharacters <= remainingCharacters) {
|
|
40559
|
-
const textCharacters = remainingCharacters - structuredCharacters;
|
|
40560
|
-
selected.unshift({ ...message, text: textCharacters === 0 ? "" : message.text.slice(-textCharacters) });
|
|
40561
|
-
remainingCharacters = 0;
|
|
40632
|
+
if (characters > remainingCharacters) {
|
|
40633
|
+
break;
|
|
40562
40634
|
}
|
|
40563
|
-
|
|
40635
|
+
selected.unshift(message);
|
|
40636
|
+
remainingCharacters -= characters;
|
|
40637
|
+
startIndex = index;
|
|
40564
40638
|
}
|
|
40565
|
-
|
|
40566
|
-
|
|
40567
|
-
|
|
40568
|
-
|
|
40569
|
-
|
|
40639
|
+
if (selected.length === 0 && endIndex > 0) {
|
|
40640
|
+
throw new AcpExecutionError(
|
|
40641
|
+
"A native Session history item exceeds the page budget",
|
|
40642
|
+
{},
|
|
40643
|
+
"history_item_too_large"
|
|
40644
|
+
);
|
|
40645
|
+
}
|
|
40646
|
+
return { characters: characterLimit - remainingCharacters, messages: selected, startIndex };
|
|
40570
40647
|
}
|
|
40571
40648
|
function nativeActiveMessage(message) {
|
|
40572
|
-
|
|
40573
|
-
|
|
40574
|
-
|
|
40575
|
-
|
|
40576
|
-
|
|
40577
|
-
|
|
40649
|
+
if (message.role === "assistant") {
|
|
40650
|
+
return {
|
|
40651
|
+
activities: message.activities,
|
|
40652
|
+
content: message.content,
|
|
40653
|
+
role: "assistant",
|
|
40654
|
+
text: message.text
|
|
40655
|
+
};
|
|
40656
|
+
}
|
|
40657
|
+
const images = (message.images ?? []).flatMap((image) => {
|
|
40658
|
+
if (image.data.length < 4 || image.data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(image.data) || !isNativeHistoryImageMimeType(image.mimeType)) {
|
|
40659
|
+
return [];
|
|
40660
|
+
}
|
|
40661
|
+
return [{ data: image.data, mimeType: image.mimeType, name: image.name }];
|
|
40662
|
+
});
|
|
40663
|
+
return { ...images.length === 0 ? {} : { images }, role: "user", text: message.text };
|
|
40664
|
+
}
|
|
40665
|
+
function nativeHistoryCoversCompletedRecovery(history, recovery) {
|
|
40666
|
+
const root = recovery.messages.find((message) => message.role === "user" && message.id === recovery.commandId);
|
|
40667
|
+
if (root === void 0) {
|
|
40668
|
+
return false;
|
|
40669
|
+
}
|
|
40670
|
+
const rootIndex = history.messages.findLastIndex(
|
|
40671
|
+
(message) => message.role === "user" && message.text === root.text
|
|
40672
|
+
);
|
|
40673
|
+
if (rootIndex < 0) {
|
|
40674
|
+
return false;
|
|
40675
|
+
}
|
|
40676
|
+
const nativeAssistant = history.messages.slice(rootIndex + 1).filter((message) => message.role === "assistant");
|
|
40677
|
+
if (nativeAssistant.length === 0) {
|
|
40678
|
+
return false;
|
|
40679
|
+
}
|
|
40680
|
+
const recoveryAssistant = recovery.messages.filter((message) => message.role === "assistant");
|
|
40681
|
+
const recoveryText = recoveryAssistant.map((message) => message.text).join("");
|
|
40682
|
+
const nativeText = nativeAssistant.map((message) => message.text).join("");
|
|
40683
|
+
if (recoveryText.length > 0 && !nativeText.includes(recoveryText)) {
|
|
40684
|
+
return false;
|
|
40685
|
+
}
|
|
40686
|
+
const nativeContent = new Set(
|
|
40687
|
+
nativeAssistant.flatMap((message) => message.content).map((content) => JSON.stringify(content))
|
|
40688
|
+
);
|
|
40689
|
+
return recoveryAssistant.flatMap((message) => message.content).every((content) => nativeContent.has(JSON.stringify(content)));
|
|
40578
40690
|
}
|
|
40579
|
-
function
|
|
40691
|
+
function historyBeforeActiveTurn(history, activeTurn) {
|
|
40580
40692
|
if (history.status === "unavailable") {
|
|
40581
|
-
|
|
40582
|
-
throw new AcpExecutionError("Unavailable native Session history has no cursor", {}, "invalid_cursor");
|
|
40583
|
-
}
|
|
40584
|
-
return { cause: history.cause, nextCursor: null, status: "unavailable" };
|
|
40693
|
+
return history;
|
|
40585
40694
|
}
|
|
40586
|
-
const
|
|
40695
|
+
const activeRoot = activeTurn.messages.find(
|
|
40696
|
+
(message) => message.role === "user" && message.id === activeTurn.commandId
|
|
40697
|
+
);
|
|
40698
|
+
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;
|
|
40699
|
+
const activeUserIndex = matchingActiveUserIndex >= 0 ? matchingActiveUserIndex : liveHistoryCoveredTurnRanges(history).find((range) => range.commandId === activeTurn.commandId)?.userIndex ?? -1;
|
|
40700
|
+
if (activeUserIndex < 0) {
|
|
40701
|
+
return history;
|
|
40702
|
+
}
|
|
40703
|
+
return {
|
|
40704
|
+
...history,
|
|
40705
|
+
coveredCommandIds: history.coveredCommandIds.filter((id) => id !== activeTurn.commandId),
|
|
40706
|
+
coveredMessageIds: history.coveredMessageIds.filter(
|
|
40707
|
+
(id) => id !== `${activeTurn.commandId}:user` && id !== `${activeTurn.commandId}:agent`
|
|
40708
|
+
),
|
|
40709
|
+
messages: history.messages.slice(0, activeUserIndex)
|
|
40710
|
+
};
|
|
40711
|
+
}
|
|
40712
|
+
function paginateAvailableNativeHistory(history, sessionId, endIndex, limit, characterLimit) {
|
|
40587
40713
|
if (endIndex > history.messages.length) {
|
|
40588
40714
|
throw new AcpExecutionError("The native Session history cursor is invalid", {}, "invalid_cursor");
|
|
40589
40715
|
}
|
|
40590
|
-
const
|
|
40716
|
+
const selected = selectMessagesBefore(history.messages, endIndex, limit, characterLimit);
|
|
40591
40717
|
const coveredMessageIds = new Set(history.coveredMessageIds);
|
|
40592
40718
|
const ranges = liveHistoryCoveredTurnRanges(history);
|
|
40593
40719
|
return {
|
|
40594
|
-
coveredCommandIds: ranges.filter((range) => range.userIndex >= startIndex && range.assistantEndIndex <= endIndex).map((range) => range.commandId),
|
|
40720
|
+
coveredCommandIds: ranges.filter((range) => range.userIndex >= selected.startIndex && range.assistantEndIndex <= endIndex).map((range) => range.commandId),
|
|
40595
40721
|
coveredMessageIds: ranges.flatMap((range) => [
|
|
40596
|
-
...range.userIndex >= startIndex && range.userIndex < endIndex && coveredMessageIds.has(`${range.commandId}:user`) ? [`${range.commandId}:user`] : [],
|
|
40597
|
-
...range.assistantStartIndex >= startIndex && range.assistantEndIndex <= endIndex && coveredMessageIds.has(`${range.commandId}:agent`) ? [`${range.commandId}:agent`] : []
|
|
40722
|
+
...range.userIndex >= selected.startIndex && range.userIndex < endIndex && coveredMessageIds.has(`${range.commandId}:user`) ? [`${range.commandId}:user`] : [],
|
|
40723
|
+
...range.assistantStartIndex >= selected.startIndex && range.assistantEndIndex <= endIndex && coveredMessageIds.has(`${range.commandId}:agent`) ? [`${range.commandId}:agent`] : []
|
|
40598
40724
|
]),
|
|
40599
|
-
messages:
|
|
40600
|
-
nextCursor: startIndex > 0 ?
|
|
40725
|
+
messages: selected.messages,
|
|
40726
|
+
nextCursor: selected.startIndex > 0 ? nativeHistoryCursor(sessionId, selected.startIndex) : null,
|
|
40601
40727
|
status: "available",
|
|
40602
40728
|
truncated: history.truncated
|
|
40603
40729
|
};
|
|
40604
40730
|
}
|
|
40605
|
-
function
|
|
40606
|
-
if (
|
|
40607
|
-
|
|
40731
|
+
function paginateNativeHistory(history, sessionId, cursor, limit) {
|
|
40732
|
+
if (cursor?.kind === "active") {
|
|
40733
|
+
throw new AcpExecutionError("The native Session history cursor is invalid", {}, "invalid_cursor");
|
|
40608
40734
|
}
|
|
40609
40735
|
if (history.status === "unavailable") {
|
|
40610
|
-
|
|
40611
|
-
|
|
40612
|
-
|
|
40613
|
-
|
|
40614
|
-
);
|
|
40615
|
-
return {
|
|
40616
|
-
coveredCommandIds: [],
|
|
40617
|
-
coveredMessageIds: [],
|
|
40618
|
-
messages: bounded3.messages,
|
|
40619
|
-
nextCursor: null,
|
|
40620
|
-
status: "available",
|
|
40621
|
-
truncated: activeTurn.truncated || bounded3.truncated
|
|
40622
|
-
};
|
|
40736
|
+
if (cursor !== null) {
|
|
40737
|
+
throw new AcpExecutionError("Unavailable native Session history has no cursor", {}, "invalid_cursor");
|
|
40738
|
+
}
|
|
40739
|
+
return { cause: history.cause, nextCursor: null, status: "unavailable" };
|
|
40623
40740
|
}
|
|
40624
|
-
|
|
40625
|
-
|
|
40741
|
+
return paginateAvailableNativeHistory(
|
|
40742
|
+
history,
|
|
40743
|
+
sessionId,
|
|
40744
|
+
cursor?.endIndex ?? history.messages.length,
|
|
40745
|
+
limit,
|
|
40746
|
+
SESSION_HISTORY_CHARACTER_LIMIT
|
|
40626
40747
|
);
|
|
40627
|
-
|
|
40628
|
-
|
|
40629
|
-
|
|
40630
|
-
|
|
40631
|
-
const activeUserIndex = matchingActiveUserIndex >= 0 ? matchingActiveUserIndex : liveHistoryCoveredTurnRanges(history).find((range) => range.commandId === activeTurn.commandId)?.userIndex ?? -1;
|
|
40632
|
-
if (activeUserIndex >= 0) {
|
|
40633
|
-
history = {
|
|
40634
|
-
...history,
|
|
40635
|
-
coveredCommandIds: history.coveredCommandIds.filter((id) => id !== activeTurn.commandId),
|
|
40636
|
-
coveredMessageIds: history.coveredMessageIds.filter(
|
|
40637
|
-
(id) => id !== `${activeTurn.commandId}:user` && id !== `${activeTurn.commandId}:agent`
|
|
40638
|
-
),
|
|
40639
|
-
messages: history.messages.slice(0, activeUserIndex + 1)
|
|
40640
|
-
};
|
|
40641
|
-
}
|
|
40642
|
-
const latestNativeMessage = history.messages.at(-1);
|
|
40643
|
-
const firstActiveMessage = activeTurn.messages[0];
|
|
40644
|
-
const preserveNativeRoot = activeUserIndex >= 0 || firstActiveMessage?.role === "user" && latestNativeMessage?.role === "user" && latestNativeMessage.text === firstActiveMessage.text;
|
|
40645
|
-
const activeMessages = activeTurn.messages.slice(preserveNativeRoot ? 1 : 0).map(nativeActiveMessage);
|
|
40646
|
-
const bounded2 = boundedActiveMessages(activeMessages, limit, SESSION_HISTORY_CHARACTER_LIMIT);
|
|
40647
|
-
let historicalMessageCount = 0;
|
|
40648
|
-
let remainingCharacters = SESSION_HISTORY_CHARACTER_LIMIT - bounded2.characters;
|
|
40649
|
-
const historicalMessageLimit = Math.max(0, limit - bounded2.messages.length);
|
|
40650
|
-
for (let index = history.messages.length - 1; index >= 0 && historicalMessageCount < historicalMessageLimit; index -= 1) {
|
|
40651
|
-
const message = history.messages[index];
|
|
40652
|
-
if (message === void 0) {
|
|
40653
|
-
break;
|
|
40654
|
-
}
|
|
40655
|
-
const characters = historyMessageCharacters(message);
|
|
40656
|
-
if (characters > remainingCharacters) {
|
|
40657
|
-
break;
|
|
40658
|
-
}
|
|
40659
|
-
historicalMessageCount += 1;
|
|
40660
|
-
remainingCharacters -= characters;
|
|
40748
|
+
}
|
|
40749
|
+
function paginateActiveTurn(history, activeTurn, sessionId, endIndex, limit) {
|
|
40750
|
+
if (endIndex > activeTurn.messages.length) {
|
|
40751
|
+
throw new AcpExecutionError("The native Session history cursor is invalid", {}, "invalid_cursor");
|
|
40661
40752
|
}
|
|
40662
|
-
const
|
|
40663
|
-
|
|
40664
|
-
|
|
40665
|
-
|
|
40666
|
-
|
|
40667
|
-
|
|
40668
|
-
|
|
40669
|
-
|
|
40753
|
+
const activeMessages = activeTurn.messages.map(nativeActiveMessage);
|
|
40754
|
+
const active = selectMessagesBefore(activeMessages, endIndex, limit, SESSION_HISTORY_CHARACTER_LIMIT);
|
|
40755
|
+
const historicalLimit = limit - active.messages.length;
|
|
40756
|
+
const historicalCharacterLimit = SESSION_HISTORY_CHARACTER_LIMIT - active.characters;
|
|
40757
|
+
const pendingHistoricalCursor = history.status === "available" && history.messages.length > 0 ? nativeHistoryCursor(sessionId, history.messages.length) : null;
|
|
40758
|
+
const latestHistoricalMessage = history.status === "available" ? history.messages.at(-1) : void 0;
|
|
40759
|
+
const historicalPageFits = latestHistoricalMessage === void 0 || historyMessageCharacters(latestHistoricalMessage) <= historicalCharacterLimit;
|
|
40760
|
+
const historical = active.startIndex === 0 && history.status === "available" && historicalLimit > 0 && historicalPageFits ? paginateAvailableNativeHistory(
|
|
40761
|
+
history,
|
|
40762
|
+
sessionId,
|
|
40763
|
+
history.messages.length,
|
|
40764
|
+
historicalLimit,
|
|
40765
|
+
historicalCharacterLimit
|
|
40766
|
+
) : null;
|
|
40670
40767
|
return {
|
|
40671
|
-
|
|
40672
|
-
|
|
40673
|
-
|
|
40768
|
+
coveredCommandIds: historical?.coveredCommandIds ?? [],
|
|
40769
|
+
coveredMessageIds: [
|
|
40770
|
+
...historical?.coveredMessageIds ?? [],
|
|
40771
|
+
...active.startIndex === 0 ? [`${activeTurn.commandId}:user`, `${activeTurn.commandId}:agent`] : []
|
|
40772
|
+
],
|
|
40773
|
+
messages: [...historical?.messages ?? [], ...active.messages],
|
|
40774
|
+
nextCursor: active.startIndex > 0 ? activeHistoryCursor(sessionId, activeTurn.epoch, active.startIndex) : historical === null ? pendingHistoricalCursor : historical.nextCursor,
|
|
40775
|
+
status: "available",
|
|
40776
|
+
truncated: activeTurn.truncated || (historical?.truncated ?? false)
|
|
40674
40777
|
};
|
|
40675
40778
|
}
|
|
40779
|
+
function paginateLiveSessionHistory(history, activeTurn, sessionId, encodedCursor, limit) {
|
|
40780
|
+
const cursor = encodedCursor === null ? null : decodeLiveHistoryCursor(encodedCursor, sessionId);
|
|
40781
|
+
if (activeTurn === null || activeTurn.state === "completed" && history.status === "available" && nativeHistoryCoversCompletedRecovery(history, activeTurn)) {
|
|
40782
|
+
return paginateNativeHistory(history, sessionId, cursor, limit);
|
|
40783
|
+
}
|
|
40784
|
+
const historical = historyBeforeActiveTurn(history, activeTurn);
|
|
40785
|
+
if (cursor?.kind === "native") {
|
|
40786
|
+
return paginateNativeHistory(historical, sessionId, cursor, limit);
|
|
40787
|
+
}
|
|
40788
|
+
if (cursor !== null && cursor.epoch !== activeTurn.epoch) {
|
|
40789
|
+
throw new AcpExecutionError("The active Turn history cursor is stale", {}, "stale_cursor");
|
|
40790
|
+
}
|
|
40791
|
+
return paginateActiveTurn(historical, activeTurn, sessionId, cursor?.endIndex ?? activeTurn.messages.length, limit);
|
|
40792
|
+
}
|
|
40676
40793
|
function mergeLiveSessionHistory(history, activeTurn, sessionId) {
|
|
40677
40794
|
const page = paginateLiveSessionHistory(history, activeTurn, sessionId, null, 1e3);
|
|
40678
40795
|
if (page.status === "unavailable") {
|
|
@@ -40683,7 +40800,7 @@ function mergeLiveSessionHistory(history, activeTurn, sessionId) {
|
|
|
40683
40800
|
coveredMessageIds: page.coveredMessageIds,
|
|
40684
40801
|
messages: page.messages,
|
|
40685
40802
|
status: "available",
|
|
40686
|
-
truncated: page.truncated
|
|
40803
|
+
truncated: page.truncated || page.nextCursor !== null
|
|
40687
40804
|
};
|
|
40688
40805
|
}
|
|
40689
40806
|
|
|
@@ -41202,15 +41319,13 @@ async function executePrompt({
|
|
|
41202
41319
|
});
|
|
41203
41320
|
operations.transitionExecution(command.commandId, "running");
|
|
41204
41321
|
if (availability.disposition === SessionPromptDisposition.Steer) {
|
|
41205
|
-
|
|
41206
|
-
if (updated === null) {
|
|
41322
|
+
if (!recordSteeringPrompt()) {
|
|
41207
41323
|
throw new AcpExecutionError(
|
|
41208
41324
|
"The steering target is unavailable",
|
|
41209
41325
|
{},
|
|
41210
41326
|
"prompt_queue_target_unavailable"
|
|
41211
41327
|
);
|
|
41212
41328
|
}
|
|
41213
|
-
publisher.publish(command.sessionId, updated);
|
|
41214
41329
|
}
|
|
41215
41330
|
const stream = activateAttempt();
|
|
41216
41331
|
publisher.publish(command.sessionId, {
|
|
@@ -41598,7 +41713,7 @@ function createDaemonCommandHandler({
|
|
|
41598
41713
|
resolveEnvironment: resolveAgentCatalogEnvironment
|
|
41599
41714
|
});
|
|
41600
41715
|
const queueChanged = (sessionId) => publisher.publish(sessionId, { kind: "session.queue.changed", sessionId });
|
|
41601
|
-
const
|
|
41716
|
+
const activeTurnRecovery = (sessionId) => activeTurns.recovery((command) => command.sessionId === sessionId);
|
|
41602
41717
|
const nativeRequestHandler = createNativeSessionRequestHandler({
|
|
41603
41718
|
audit,
|
|
41604
41719
|
diagnostics,
|
|
@@ -41619,7 +41734,7 @@ function createDaemonCommandHandler({
|
|
|
41619
41734
|
directories,
|
|
41620
41735
|
audit,
|
|
41621
41736
|
sessions,
|
|
41622
|
-
|
|
41737
|
+
activeTurnRecovery,
|
|
41623
41738
|
signal
|
|
41624
41739
|
);
|
|
41625
41740
|
return;
|
|
@@ -41633,7 +41748,7 @@ function createDaemonCommandHandler({
|
|
|
41633
41748
|
directories,
|
|
41634
41749
|
audit,
|
|
41635
41750
|
sessions,
|
|
41636
|
-
|
|
41751
|
+
activeTurnRecovery,
|
|
41637
41752
|
signal
|
|
41638
41753
|
);
|
|
41639
41754
|
return;
|