replicas-engine 0.1.580 → 0.1.581
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/src/index.js +141 -37
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -3311,14 +3311,23 @@ function chatHistoryPageParamsFromQuery(query2) {
|
|
|
3311
3311
|
beforeTurn: parse(query2.beforeTurn)
|
|
3312
3312
|
};
|
|
3313
3313
|
}
|
|
3314
|
+
function getChatHistoryPageWindow(totalItems, limit, before) {
|
|
3315
|
+
const endIndex = Math.min(before ?? totalItems, totalItems);
|
|
3316
|
+
return { startIndex: Math.max(0, endIndex - Math.max(1, limit)), endIndex };
|
|
3317
|
+
}
|
|
3314
3318
|
function paginateChatHistory(full, params) {
|
|
3315
3319
|
if (params.limit === void 0) return { ...full, totalEvents: full.events.length };
|
|
3316
|
-
const
|
|
3317
|
-
|
|
3318
|
-
|
|
3320
|
+
const { startIndex: eventsStartIndex, endIndex: eventsEnd } = getChatHistoryPageWindow(
|
|
3321
|
+
full.events.length,
|
|
3322
|
+
params.limit,
|
|
3323
|
+
params.beforeEvent
|
|
3324
|
+
);
|
|
3319
3325
|
const turns = full.codexAspTranscript?.turns;
|
|
3320
|
-
const
|
|
3321
|
-
|
|
3326
|
+
const { startIndex: turnsStartIndex, endIndex: turnsEnd } = getChatHistoryPageWindow(
|
|
3327
|
+
turns?.length ?? 0,
|
|
3328
|
+
params.limit,
|
|
3329
|
+
params.beforeTurn
|
|
3330
|
+
);
|
|
3322
3331
|
const codexAspTranscript = full.codexAspTranscript && turns && (turnsStartIndex > 0 || turnsEnd < turns.length) ? { ...full.codexAspTranscript, turns: turns.slice(turnsStartIndex, turnsEnd) } : full.codexAspTranscript;
|
|
3323
3332
|
return {
|
|
3324
3333
|
...full,
|
|
@@ -9406,13 +9415,14 @@ function isNotFoundError(error) {
|
|
|
9406
9415
|
}
|
|
9407
9416
|
|
|
9408
9417
|
// src/managers/codex-asp/codex-history-file.ts
|
|
9409
|
-
import { appendFile as appendFile2, readFile as readFile9 } from "fs/promises";
|
|
9418
|
+
import { appendFile as appendFile2, open, readFile as readFile9 } from "fs/promises";
|
|
9410
9419
|
var CodexHistoryFile = class {
|
|
9411
9420
|
constructor(filePath) {
|
|
9412
9421
|
this.filePath = filePath;
|
|
9413
9422
|
}
|
|
9414
9423
|
filePath;
|
|
9415
9424
|
writeLock = new AsyncLock();
|
|
9425
|
+
eventLineIndex = null;
|
|
9416
9426
|
/** Best-effort ordered append; failures must not disrupt the turn. */
|
|
9417
9427
|
append(event) {
|
|
9418
9428
|
void this.writeLock.run(
|
|
@@ -9435,6 +9445,88 @@ var CodexHistoryFile = class {
|
|
|
9435
9445
|
return { events: [], transcript: null, transcriptsByThreadId: /* @__PURE__ */ new Map() };
|
|
9436
9446
|
}
|
|
9437
9447
|
}
|
|
9448
|
+
async loadEventsPage(page) {
|
|
9449
|
+
if (page.limit === void 0) {
|
|
9450
|
+
const history2 = await this.load();
|
|
9451
|
+
return { events: history2.events, eventsStartIndex: 0, totalEvents: history2.events.length };
|
|
9452
|
+
}
|
|
9453
|
+
let file;
|
|
9454
|
+
try {
|
|
9455
|
+
file = await open(this.filePath, "r");
|
|
9456
|
+
} catch (error) {
|
|
9457
|
+
if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) {
|
|
9458
|
+
console.error("[CodexHistoryFile] Failed to open history file:", error);
|
|
9459
|
+
}
|
|
9460
|
+
return { events: [], eventsStartIndex: 0, totalEvents: 0 };
|
|
9461
|
+
}
|
|
9462
|
+
try {
|
|
9463
|
+
const stats = await file.stat();
|
|
9464
|
+
let index = this.eventLineIndex;
|
|
9465
|
+
if (!index || index.size !== stats.size || index.mtimeMs !== stats.mtimeMs) {
|
|
9466
|
+
const starts = stats.size > 0 ? [0] : [];
|
|
9467
|
+
const buffer = Buffer.allocUnsafe(64 * 1024);
|
|
9468
|
+
let position = 0;
|
|
9469
|
+
while (position < stats.size) {
|
|
9470
|
+
const { bytesRead: bytesRead2 } = await file.read(
|
|
9471
|
+
buffer,
|
|
9472
|
+
0,
|
|
9473
|
+
Math.min(buffer.length, stats.size - position),
|
|
9474
|
+
position
|
|
9475
|
+
);
|
|
9476
|
+
if (bytesRead2 === 0) break;
|
|
9477
|
+
for (let offset = 0; offset < bytesRead2; offset += 1) {
|
|
9478
|
+
const next = position + offset + 1;
|
|
9479
|
+
if (buffer[offset] === 10 && next < stats.size) starts.push(next);
|
|
9480
|
+
}
|
|
9481
|
+
position += bytesRead2;
|
|
9482
|
+
}
|
|
9483
|
+
index = { size: stats.size, mtimeMs: stats.mtimeMs, starts };
|
|
9484
|
+
this.eventLineIndex = index;
|
|
9485
|
+
}
|
|
9486
|
+
const totalEvents2 = index.starts.length;
|
|
9487
|
+
const { startIndex: eventsStartIndex2, endIndex: eventsEnd2 } = getChatHistoryPageWindow(
|
|
9488
|
+
totalEvents2,
|
|
9489
|
+
page.limit,
|
|
9490
|
+
page.beforeEvent
|
|
9491
|
+
);
|
|
9492
|
+
const startByte = index.starts[eventsStartIndex2] ?? index.size;
|
|
9493
|
+
const endByte = index.starts[eventsEnd2] ?? index.size;
|
|
9494
|
+
const content = Buffer.allocUnsafe(endByte - startByte);
|
|
9495
|
+
let bytesRead = 0;
|
|
9496
|
+
while (bytesRead < content.length) {
|
|
9497
|
+
const result = await file.read(
|
|
9498
|
+
content,
|
|
9499
|
+
bytesRead,
|
|
9500
|
+
content.length - bytesRead,
|
|
9501
|
+
startByte + bytesRead
|
|
9502
|
+
);
|
|
9503
|
+
if (result.bytesRead === 0) break;
|
|
9504
|
+
bytesRead += result.bytesRead;
|
|
9505
|
+
}
|
|
9506
|
+
if (bytesRead === content.length) {
|
|
9507
|
+
const parsed = parseAgentEventJsonlWithCodexAspTranscript(content.toString("utf-8"));
|
|
9508
|
+
if (!parsed.transcript && parsed.events.length === eventsEnd2 - eventsStartIndex2) {
|
|
9509
|
+
return { events: parsed.events, eventsStartIndex: eventsStartIndex2, totalEvents: totalEvents2 };
|
|
9510
|
+
}
|
|
9511
|
+
}
|
|
9512
|
+
} catch (error) {
|
|
9513
|
+
console.error("[CodexHistoryFile] Failed to load history page:", error);
|
|
9514
|
+
} finally {
|
|
9515
|
+
await file.close();
|
|
9516
|
+
}
|
|
9517
|
+
const history = await this.load();
|
|
9518
|
+
const totalEvents = history.events.length;
|
|
9519
|
+
const { startIndex: eventsStartIndex, endIndex: eventsEnd } = getChatHistoryPageWindow(
|
|
9520
|
+
totalEvents,
|
|
9521
|
+
page.limit,
|
|
9522
|
+
page.beforeEvent
|
|
9523
|
+
);
|
|
9524
|
+
return {
|
|
9525
|
+
events: history.events.slice(eventsStartIndex, eventsEnd),
|
|
9526
|
+
eventsStartIndex,
|
|
9527
|
+
totalEvents
|
|
9528
|
+
};
|
|
9529
|
+
}
|
|
9438
9530
|
};
|
|
9439
9531
|
|
|
9440
9532
|
// src/managers/claude-activity.ts
|
|
@@ -10563,13 +10655,13 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
10563
10655
|
}
|
|
10564
10656
|
return null;
|
|
10565
10657
|
}
|
|
10566
|
-
async getHistory() {
|
|
10658
|
+
async getHistory(page = {}) {
|
|
10567
10659
|
await this.initialized;
|
|
10568
10660
|
await this.historyFile.flush();
|
|
10569
|
-
const history = await this.historyFile.
|
|
10661
|
+
const history = await this.historyFile.loadEventsPage(page);
|
|
10570
10662
|
return {
|
|
10571
10663
|
thread_id: this.sessionId,
|
|
10572
|
-
|
|
10664
|
+
...history
|
|
10573
10665
|
};
|
|
10574
10666
|
}
|
|
10575
10667
|
partialMessageStreamKey(message) {
|
|
@@ -10896,7 +10988,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
|
10896
10988
|
var MIN_CODEX_CLI_VERSION = "0.144.6";
|
|
10897
10989
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
10898
10990
|
var codexCliVersionEnsured = null;
|
|
10899
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
10991
|
+
var ENGINE_PACKAGE_VERSION = "0.1.581";
|
|
10900
10992
|
var INITIALIZE_METHOD = "initialize";
|
|
10901
10993
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
10902
10994
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -12009,22 +12101,24 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
12009
12101
|
this.recordUserMessageEvent(request);
|
|
12010
12102
|
return true;
|
|
12011
12103
|
}
|
|
12012
|
-
async getHistory() {
|
|
12104
|
+
async getHistory(page = {}) {
|
|
12013
12105
|
if (!this.currentThreadId) {
|
|
12014
|
-
return { thread_id: null, events: [], goal: null };
|
|
12106
|
+
return paginateChatHistory({ thread_id: null, events: [], goal: null }, page);
|
|
12015
12107
|
}
|
|
12016
|
-
if (this.
|
|
12017
|
-
|
|
12018
|
-
|
|
12019
|
-
|
|
12020
|
-
|
|
12108
|
+
if (this.codexAspTranscript?.threadId === this.currentThreadId) {
|
|
12109
|
+
if (page.beforeEvent === void 0 && page.beforeTurn === void 0) {
|
|
12110
|
+
try {
|
|
12111
|
+
const host = await getCodexAspHost();
|
|
12112
|
+
await this.refreshThreadGoal(host, this.currentThreadId);
|
|
12113
|
+
} catch {
|
|
12114
|
+
}
|
|
12021
12115
|
}
|
|
12022
|
-
return {
|
|
12116
|
+
return paginateChatHistory({
|
|
12023
12117
|
thread_id: this.currentThreadId,
|
|
12024
12118
|
events: [...this.historyEvents],
|
|
12025
12119
|
codexAspTranscript: this.codexAspTranscript,
|
|
12026
12120
|
goal: this.currentGoal
|
|
12027
|
-
};
|
|
12121
|
+
}, page);
|
|
12028
12122
|
}
|
|
12029
12123
|
try {
|
|
12030
12124
|
const host = await getCodexAspHost();
|
|
@@ -12039,20 +12133,20 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
12039
12133
|
if (transcript) {
|
|
12040
12134
|
transcript.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
12041
12135
|
}
|
|
12042
|
-
return {
|
|
12136
|
+
return paginateChatHistory({
|
|
12043
12137
|
thread_id: this.currentThreadId,
|
|
12044
12138
|
events: [...this.historyEvents],
|
|
12045
12139
|
codexAspTranscript: transcript,
|
|
12046
12140
|
goal: this.currentGoal
|
|
12047
|
-
};
|
|
12141
|
+
}, page);
|
|
12048
12142
|
} catch {
|
|
12049
12143
|
}
|
|
12050
|
-
return {
|
|
12144
|
+
return paginateChatHistory({
|
|
12051
12145
|
thread_id: this.currentThreadId,
|
|
12052
12146
|
events: [...this.historyEvents],
|
|
12053
12147
|
codexAspTranscript: this.codexAspTranscript,
|
|
12054
12148
|
goal: this.currentGoal
|
|
12055
|
-
};
|
|
12149
|
+
}, page);
|
|
12056
12150
|
}
|
|
12057
12151
|
getGoal() {
|
|
12058
12152
|
return this.currentGoal;
|
|
@@ -13260,12 +13354,12 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
13260
13354
|
}
|
|
13261
13355
|
this.agent = null;
|
|
13262
13356
|
}
|
|
13263
|
-
async getHistory() {
|
|
13357
|
+
async getHistory(page = {}) {
|
|
13264
13358
|
await this.historyFile.flush();
|
|
13265
|
-
const history = await this.historyFile.
|
|
13359
|
+
const history = await this.historyFile.loadEventsPage(page);
|
|
13266
13360
|
return {
|
|
13267
13361
|
thread_id: this.agent?.agentId ?? this.initialSessionId,
|
|
13268
|
-
|
|
13362
|
+
...history,
|
|
13269
13363
|
goal: null
|
|
13270
13364
|
};
|
|
13271
13365
|
}
|
|
@@ -13859,12 +13953,12 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
13859
13953
|
{ throwOnError: true }
|
|
13860
13954
|
);
|
|
13861
13955
|
}
|
|
13862
|
-
async getHistory() {
|
|
13956
|
+
async getHistory(page = {}) {
|
|
13863
13957
|
await this.historyFile.flush();
|
|
13864
|
-
const history = await this.historyFile.
|
|
13958
|
+
const history = await this.historyFile.loadEventsPage(page);
|
|
13865
13959
|
return {
|
|
13866
13960
|
thread_id: this.sessionId ?? this.initialSessionId,
|
|
13867
|
-
|
|
13961
|
+
...history,
|
|
13868
13962
|
goal: null
|
|
13869
13963
|
};
|
|
13870
13964
|
}
|
|
@@ -14435,10 +14529,10 @@ var PiManager = class extends CodingAgentManager {
|
|
|
14435
14529
|
this.recordUserMessage(session, request.message);
|
|
14436
14530
|
return true;
|
|
14437
14531
|
}
|
|
14438
|
-
async getHistory() {
|
|
14532
|
+
async getHistory(page = {}) {
|
|
14439
14533
|
await this.historyFile.flush();
|
|
14440
|
-
const history = await this.historyFile.
|
|
14441
|
-
return { thread_id: this.activeSessionFile ?? this.initialSessionId,
|
|
14534
|
+
const history = await this.historyFile.loadEventsPage(page);
|
|
14535
|
+
return { thread_id: this.activeSessionFile ?? this.initialSessionId, ...history, goal: null };
|
|
14442
14536
|
}
|
|
14443
14537
|
async listSlashCommands() {
|
|
14444
14538
|
await this.initialized;
|
|
@@ -15155,8 +15249,8 @@ var RelayManager = class {
|
|
|
15155
15249
|
async interrupt() {
|
|
15156
15250
|
return this.inner.interrupt();
|
|
15157
15251
|
}
|
|
15158
|
-
async getHistory() {
|
|
15159
|
-
return this.inner.getHistory();
|
|
15252
|
+
async getHistory(page = {}) {
|
|
15253
|
+
return this.inner.getHistory(page);
|
|
15160
15254
|
}
|
|
15161
15255
|
async listSlashCommands() {
|
|
15162
15256
|
return this.inner.listSlashCommands?.() ?? [];
|
|
@@ -16419,17 +16513,27 @@ var ChatService = class {
|
|
|
16419
16513
|
async getChatHistory(chatId, page = {}) {
|
|
16420
16514
|
const chat = this.requireChat(chatId);
|
|
16421
16515
|
const [history, senders] = await Promise.all([
|
|
16422
|
-
chat.provider.getHistory(),
|
|
16516
|
+
chat.provider.getHistory(page),
|
|
16423
16517
|
this.readSenders(chatId)
|
|
16424
16518
|
]);
|
|
16425
16519
|
for (const [messageId, acceptedEvent] of chat.acceptedUserEvents) {
|
|
16426
|
-
if (acceptedEventInCodexTranscript(acceptedEvent, history.codexAspTranscript)) {
|
|
16520
|
+
if (acceptedEventInCodexTranscript(acceptedEvent, history.codexAspTranscript) || history.events.some((event) => isSameAcceptedUserEvent(event, acceptedEvent))) {
|
|
16427
16521
|
chat.acceptedUserEvents.delete(messageId);
|
|
16428
16522
|
}
|
|
16429
16523
|
}
|
|
16524
|
+
const isLatestPage = page.beforeEvent === void 0 && page.beforeTurn === void 0;
|
|
16430
16525
|
const queuedMessageIds = new Set(chat.provider.getQueue().map((message) => message.id));
|
|
16431
|
-
const acceptedEvents = [...chat.acceptedUserEvents.entries()].filter(([messageId]) => messageId === chat.activeMessageId || !chat.hasActiveTurn && chat.pendingMessageIds[0] === messageId && !queuedMessageIds.has(messageId)).map(([, acceptedEvent]) => acceptedEvent).filter((acceptedEvent) => !acceptedEventInCodexTranscript(acceptedEvent, history.codexAspTranscript) && !history.events.some((event) => isSameAcceptedUserEvent(event, acceptedEvent)));
|
|
16526
|
+
const acceptedEvents = (isLatestPage ? [...chat.acceptedUserEvents.entries()] : []).filter(([messageId]) => messageId === chat.activeMessageId || !chat.hasActiveTurn && chat.pendingMessageIds[0] === messageId && !queuedMessageIds.has(messageId)).map(([, acceptedEvent]) => acceptedEvent).filter((acceptedEvent) => !acceptedEventInCodexTranscript(acceptedEvent, history.codexAspTranscript) && !history.events.some((event) => isSameAcceptedUserEvent(event, acceptedEvent)));
|
|
16432
16527
|
const events = [...history.events, ...acceptedEvents].sort((a, b) => getEventTimestampMs(a) - getEventTimestampMs(b));
|
|
16528
|
+
if (history.eventsStartIndex !== void 0) {
|
|
16529
|
+
return {
|
|
16530
|
+
...history,
|
|
16531
|
+
events,
|
|
16532
|
+
totalEvents: (history.totalEvents ?? history.eventsStartIndex + history.events.length) + acceptedEvents.length,
|
|
16533
|
+
goal: history.goal ?? chat.provider.getGoal?.() ?? null,
|
|
16534
|
+
senders
|
|
16535
|
+
};
|
|
16536
|
+
}
|
|
16433
16537
|
return paginateChatHistory({
|
|
16434
16538
|
thread_id: history.thread_id,
|
|
16435
16539
|
events,
|