replicas-engine 0.1.220 → 0.1.221
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 +163 -28
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -32,6 +32,9 @@ function codexReasoningEffortForThinkingLevel(thinkingLevel) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// ../shared/src/event.ts
|
|
35
|
+
var ACCEPTED_USER_MESSAGE_SOURCE = "replicas-chat-turn-accepted";
|
|
36
|
+
var USER_MESSAGE_ID_PAYLOAD_KEY = "replicasMessageId";
|
|
37
|
+
var CODEX_ASP_ITEM_ID_PAYLOAD_KEY = "codexAspItemId";
|
|
35
38
|
var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
|
|
36
39
|
var COMPACTION_STATUS_EVENT_TYPE = "compaction-status";
|
|
37
40
|
var CHAT_GOAL_EVENT_TYPE = "chat-goal";
|
|
@@ -1761,7 +1764,7 @@ function parseReplicasConfigString(content, filename) {
|
|
|
1761
1764
|
}
|
|
1762
1765
|
|
|
1763
1766
|
// ../shared/src/engine/environment.ts
|
|
1764
|
-
var DAYTONA_SNAPSHOT_ID = "27-05-2026-royal-york-
|
|
1767
|
+
var DAYTONA_SNAPSHOT_ID = "27-05-2026-royal-york-v3";
|
|
1765
1768
|
|
|
1766
1769
|
// ../shared/src/engine/types.ts
|
|
1767
1770
|
var DEFAULT_CHAT_TITLES = {
|
|
@@ -1863,6 +1866,50 @@ var MEDIA_KIND = {
|
|
|
1863
1866
|
};
|
|
1864
1867
|
var MEDIA_KINDS = [MEDIA_KIND.IMAGE, MEDIA_KIND.VIDEO, MEDIA_KIND.AUDIO];
|
|
1865
1868
|
|
|
1869
|
+
// ../shared/src/agent-event-utils.ts
|
|
1870
|
+
function getUserMessage(event) {
|
|
1871
|
+
return event.type === "event_msg" && event.payload.type === "user_message" && typeof event.payload.message === "string" ? event.payload.message : null;
|
|
1872
|
+
}
|
|
1873
|
+
function getUserMessageId(event) {
|
|
1874
|
+
const messageId = event.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
|
|
1875
|
+
return typeof messageId === "string" ? messageId : null;
|
|
1876
|
+
}
|
|
1877
|
+
function getUserMessageItemId(event) {
|
|
1878
|
+
const itemId = event.payload[CODEX_ASP_ITEM_ID_PAYLOAD_KEY];
|
|
1879
|
+
return typeof itemId === "string" ? itemId : null;
|
|
1880
|
+
}
|
|
1881
|
+
function getEventTimestampMs(event) {
|
|
1882
|
+
const value = Date.parse(event.timestamp);
|
|
1883
|
+
return Number.isNaN(value) ? 0 : value;
|
|
1884
|
+
}
|
|
1885
|
+
function areSameUserMessageEvents(a, b) {
|
|
1886
|
+
const aMessage = getUserMessage(a);
|
|
1887
|
+
const bMessage = getUserMessage(b);
|
|
1888
|
+
if (!aMessage || aMessage !== bMessage) return false;
|
|
1889
|
+
const aMessageId = getUserMessageId(a);
|
|
1890
|
+
const bMessageId = getUserMessageId(b);
|
|
1891
|
+
if (aMessageId || bMessageId) return aMessageId === bMessageId;
|
|
1892
|
+
const aItemId = getUserMessageItemId(a);
|
|
1893
|
+
const bItemId = getUserMessageItemId(b);
|
|
1894
|
+
if (aItemId || bItemId) return aItemId === bItemId;
|
|
1895
|
+
return Math.abs(getEventTimestampMs(a) - getEventTimestampMs(b)) <= 3e4;
|
|
1896
|
+
}
|
|
1897
|
+
function mergeAgentEvents(primary, supplemental, options) {
|
|
1898
|
+
const merged = [...primary];
|
|
1899
|
+
const { areDuplicates, mergeEvent } = options;
|
|
1900
|
+
for (const event of supplemental) {
|
|
1901
|
+
const existingIndex = merged.findIndex((existing) => areDuplicates(existing, event));
|
|
1902
|
+
if (existingIndex === -1) {
|
|
1903
|
+
merged.push(event);
|
|
1904
|
+
continue;
|
|
1905
|
+
}
|
|
1906
|
+
if (mergeEvent) {
|
|
1907
|
+
merged[existingIndex] = mergeEvent(merged[existingIndex], event);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
return merged;
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1866
1913
|
// src/runtime-env-loader.ts
|
|
1867
1914
|
function loadRuntimeEnvFile() {
|
|
1868
1915
|
let content;
|
|
@@ -6265,21 +6312,27 @@ function itemToAgentEventDrafts(item, lifecycle) {
|
|
|
6265
6312
|
}
|
|
6266
6313
|
function threadToHistoryEvents(thread) {
|
|
6267
6314
|
const events = [];
|
|
6268
|
-
|
|
6315
|
+
const turns = thread.turns.map((turn, index) => ({ turn, index })).sort((a, b) => (a.turn.startedAt ?? a.turn.completedAt ?? Number.MAX_SAFE_INTEGER) - (b.turn.startedAt ?? b.turn.completedAt ?? Number.MAX_SAFE_INTEGER) || a.index - b.index);
|
|
6316
|
+
for (const { turn } of turns) {
|
|
6269
6317
|
const startedAt = timestampFromSeconds(turn.startedAt);
|
|
6270
6318
|
const completedAt = timestampFromSeconds(turn.completedAt ?? turn.startedAt);
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6319
|
+
const userMessages = turn.items.filter((item) => item.type === "userMessage");
|
|
6320
|
+
const agentItems = turn.items.filter((item) => item.type !== "userMessage");
|
|
6321
|
+
for (const item of userMessages) {
|
|
6322
|
+
const message = item.content.filter((input) => input.type === "text").map((input) => input.text).join("\n");
|
|
6323
|
+
if (message) {
|
|
6324
|
+
events.push({
|
|
6325
|
+
timestamp: startedAt,
|
|
6326
|
+
type: "event_msg",
|
|
6327
|
+
payload: {
|
|
6328
|
+
type: "user_message",
|
|
6329
|
+
message,
|
|
6330
|
+
[CODEX_ASP_ITEM_ID_PAYLOAD_KEY]: item.id
|
|
6331
|
+
}
|
|
6332
|
+
});
|
|
6282
6333
|
}
|
|
6334
|
+
}
|
|
6335
|
+
for (const item of agentItems) {
|
|
6283
6336
|
for (const draft of itemToAgentEventDrafts(item, "started")) {
|
|
6284
6337
|
events.push({ timestamp: startedAt, ...draft });
|
|
6285
6338
|
}
|
|
@@ -6380,6 +6433,49 @@ function dispatchAspNotification(notification, handlers) {
|
|
|
6380
6433
|
}
|
|
6381
6434
|
|
|
6382
6435
|
// src/managers/codex-asp/codex-asp-manager.ts
|
|
6436
|
+
function historyEventKey(event) {
|
|
6437
|
+
const payloadType = typeof event.payload.type === "string" ? event.payload.type : null;
|
|
6438
|
+
const callId = typeof event.payload.call_id === "string" ? event.payload.call_id : null;
|
|
6439
|
+
const itemId = typeof event.payload[CODEX_ASP_ITEM_ID_PAYLOAD_KEY] === "string" ? event.payload[CODEX_ASP_ITEM_ID_PAYLOAD_KEY] : null;
|
|
6440
|
+
const messageId = typeof event.payload[USER_MESSAGE_ID_PAYLOAD_KEY] === "string" ? event.payload[USER_MESSAGE_ID_PAYLOAD_KEY] : null;
|
|
6441
|
+
if (event.type === "response_item" && payloadType && callId) {
|
|
6442
|
+
return `${event.type}:${payloadType}:${callId}`;
|
|
6443
|
+
}
|
|
6444
|
+
if (event.type === "event_msg" && event.payload.type === "user_message") {
|
|
6445
|
+
if (messageId) return `${event.type}:user_message:message:${messageId}`;
|
|
6446
|
+
if (itemId) return `${event.type}:user_message:item:${itemId}`;
|
|
6447
|
+
const command = typeof event.payload.command === "string" ? event.payload.command : "";
|
|
6448
|
+
const message = typeof event.payload.message === "string" ? event.payload.message : "";
|
|
6449
|
+
return `${event.type}:user_message:${event.timestamp}:${command}:${message}`;
|
|
6450
|
+
}
|
|
6451
|
+
if (itemId && payloadType) {
|
|
6452
|
+
return `${event.type}:${payloadType}:item:${itemId}`;
|
|
6453
|
+
}
|
|
6454
|
+
return `${event.type}:${event.timestamp}:${JSON.stringify(event.payload)}`;
|
|
6455
|
+
}
|
|
6456
|
+
function areDuplicateHistoryEvents(a, b) {
|
|
6457
|
+
if (historyEventKey(a) === historyEventKey(b)) return true;
|
|
6458
|
+
return areSameUserMessageEvents(a, b);
|
|
6459
|
+
}
|
|
6460
|
+
function mergeHistoryEvent(current, candidate) {
|
|
6461
|
+
if (getUserMessage(current) && getUserMessage(current) === getUserMessage(candidate)) {
|
|
6462
|
+
return {
|
|
6463
|
+
...current,
|
|
6464
|
+
timestamp: getEventTimestampMs(current) <= getEventTimestampMs(candidate) ? current.timestamp : candidate.timestamp,
|
|
6465
|
+
payload: {
|
|
6466
|
+
...current.payload,
|
|
6467
|
+
...candidate.payload
|
|
6468
|
+
}
|
|
6469
|
+
};
|
|
6470
|
+
}
|
|
6471
|
+
return candidate;
|
|
6472
|
+
}
|
|
6473
|
+
function mergeHistoryEvents(primary, supplemental) {
|
|
6474
|
+
return mergeAgentEvents(primary, supplemental, {
|
|
6475
|
+
areDuplicates: areDuplicateHistoryEvents,
|
|
6476
|
+
mergeEvent: mergeHistoryEvent
|
|
6477
|
+
});
|
|
6478
|
+
}
|
|
6383
6479
|
var CodexAspManager = class extends CodingAgentManager {
|
|
6384
6480
|
currentThreadId = null;
|
|
6385
6481
|
activeTurnId = null;
|
|
@@ -6425,15 +6521,13 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6425
6521
|
),
|
|
6426
6522
|
this.refreshThreadGoal(host, this.currentThreadId)
|
|
6427
6523
|
]);
|
|
6428
|
-
const events = threadToHistoryEvents(response.thread);
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
};
|
|
6436
|
-
}
|
|
6524
|
+
const events = mergeHistoryEvents(this.historyEvents, threadToHistoryEvents(response.thread));
|
|
6525
|
+
this.historyEvents.splice(0, this.historyEvents.length, ...events);
|
|
6526
|
+
return {
|
|
6527
|
+
thread_id: this.currentThreadId,
|
|
6528
|
+
events,
|
|
6529
|
+
goal: this.currentGoal
|
|
6530
|
+
};
|
|
6437
6531
|
} catch {
|
|
6438
6532
|
}
|
|
6439
6533
|
return {
|
|
@@ -6492,8 +6586,8 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6492
6586
|
async executeGoalClearCommand(request, recordUserMessage) {
|
|
6493
6587
|
const host = await getCodexAspHost();
|
|
6494
6588
|
const developerInstructions = this.buildCombinedInstructions(request.customInstructions);
|
|
6495
|
-
const threadId = await this.ensureThread(host, request, developerInstructions);
|
|
6496
6589
|
recordUserMessage({ command: "goal" });
|
|
6590
|
+
const threadId = await this.ensureThread(host, request, developerInstructions);
|
|
6497
6591
|
await host.client.request(
|
|
6498
6592
|
THREAD_GOAL_CLEAR_METHOD,
|
|
6499
6593
|
{ threadId }
|
|
@@ -6511,8 +6605,8 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6511
6605
|
}
|
|
6512
6606
|
}
|
|
6513
6607
|
const developerInstructions = this.buildCombinedInstructions(request.customInstructions);
|
|
6514
|
-
const threadId = await this.ensureThread(host, request, developerInstructions);
|
|
6515
6608
|
recordUserMessage(options.userMessagePayload);
|
|
6609
|
+
const threadId = await this.ensureThread(host, request, developerInstructions);
|
|
6516
6610
|
const runTurn = options.runTurn ?? ((aspHost, aspThreadId, aspInstructions) => this.runTurn(aspHost, aspThreadId, request, aspInstructions));
|
|
6517
6611
|
let completedTurn;
|
|
6518
6612
|
try {
|
|
@@ -6747,8 +6841,7 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6747
6841
|
}
|
|
6748
6842
|
seedHistoryFromThread(thread) {
|
|
6749
6843
|
const events = threadToHistoryEvents(thread);
|
|
6750
|
-
|
|
6751
|
-
this.historyEvents.splice(0, this.historyEvents.length, ...events);
|
|
6844
|
+
this.historyEvents.splice(0, this.historyEvents.length, ...mergeHistoryEvents(this.historyEvents, events));
|
|
6752
6845
|
}
|
|
6753
6846
|
async refreshThreadGoal(host, threadId) {
|
|
6754
6847
|
try {
|
|
@@ -7457,6 +7550,19 @@ function isPersistedChat(value) {
|
|
|
7457
7550
|
const candidate = value;
|
|
7458
7551
|
return typeof candidate.id === "string" && (candidate.provider === "claude" || candidate.provider === "codex" || candidate.provider === "relay") && typeof candidate.title === "string" && typeof candidate.createdAt === "string" && typeof candidate.updatedAt === "string" && (candidate.providerSessionId === null || typeof candidate.providerSessionId === "string") && (candidate.parentChatId === void 0 || candidate.parentChatId === null || typeof candidate.parentChatId === "string");
|
|
7459
7552
|
}
|
|
7553
|
+
function createUserMessageEvent(message, messageId) {
|
|
7554
|
+
return {
|
|
7555
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7556
|
+
type: "event_msg",
|
|
7557
|
+
payload: {
|
|
7558
|
+
type: "user_message",
|
|
7559
|
+
message,
|
|
7560
|
+
source: ACCEPTED_USER_MESSAGE_SOURCE,
|
|
7561
|
+
[USER_MESSAGE_ID_PAYLOAD_KEY]: messageId
|
|
7562
|
+
}
|
|
7563
|
+
};
|
|
7564
|
+
}
|
|
7565
|
+
var isSameUserMessageEvent = areSameUserMessageEvents;
|
|
7460
7566
|
var ChatService = class {
|
|
7461
7567
|
constructor(workingDirectory) {
|
|
7462
7568
|
this.workingDirectory = workingDirectory;
|
|
@@ -7534,7 +7640,9 @@ var ChatService = class {
|
|
|
7534
7640
|
async sendMessage(chatId, request) {
|
|
7535
7641
|
const chat = this.requireChat(chatId);
|
|
7536
7642
|
const result = await chat.provider.enqueueMessage(request);
|
|
7643
|
+
const acceptedEvent = createUserMessageEvent(request.message, result.messageId);
|
|
7537
7644
|
chat.pendingMessageIds.push(result.messageId);
|
|
7645
|
+
chat.acceptedUserEvents.set(result.messageId, acceptedEvent);
|
|
7538
7646
|
this.touch(chat);
|
|
7539
7647
|
let recordedSender;
|
|
7540
7648
|
if (request.senderUserId && request.senderEmail) {
|
|
@@ -7553,6 +7661,7 @@ var ChatService = class {
|
|
|
7553
7661
|
messageId: result.messageId,
|
|
7554
7662
|
queued: result.queued,
|
|
7555
7663
|
position: result.position,
|
|
7664
|
+
event: acceptedEvent,
|
|
7556
7665
|
...recordedSender ? { sender: recordedSender } : {}
|
|
7557
7666
|
}
|
|
7558
7667
|
});
|
|
@@ -7599,8 +7708,10 @@ var ChatService = class {
|
|
|
7599
7708
|
const chat = this.requireChat(chatId);
|
|
7600
7709
|
const result = await chat.provider.interrupt();
|
|
7601
7710
|
chat.hasActiveTurn = false;
|
|
7711
|
+
chat.activeMessageId = null;
|
|
7602
7712
|
keepAliveService.stop();
|
|
7603
7713
|
chat.pendingMessageIds = [];
|
|
7714
|
+
chat.acceptedUserEvents.clear();
|
|
7604
7715
|
this.touch(chat);
|
|
7605
7716
|
await this.publish({
|
|
7606
7717
|
type: "chat.interrupted",
|
|
@@ -7690,9 +7801,10 @@ var ChatService = class {
|
|
|
7690
7801
|
chat.provider.getHistory(),
|
|
7691
7802
|
this.readSenders(chatId)
|
|
7692
7803
|
]);
|
|
7804
|
+
const acceptedEvents = [...chat.acceptedUserEvents.values()].filter((acceptedEvent) => !history.events.some((event) => isSameUserMessageEvent(event, acceptedEvent)));
|
|
7693
7805
|
return {
|
|
7694
7806
|
thread_id: history.thread_id,
|
|
7695
|
-
events: history.events,
|
|
7807
|
+
events: [...history.events, ...acceptedEvents],
|
|
7696
7808
|
goal: history.goal ?? chat.provider.getGoal?.() ?? null,
|
|
7697
7809
|
senders
|
|
7698
7810
|
};
|
|
@@ -7760,6 +7872,8 @@ var ChatService = class {
|
|
|
7760
7872
|
persisted,
|
|
7761
7873
|
provider,
|
|
7762
7874
|
pendingMessageIds: [],
|
|
7875
|
+
acceptedUserEvents: /* @__PURE__ */ new Map(),
|
|
7876
|
+
activeMessageId: null,
|
|
7763
7877
|
hasActiveTurn: false,
|
|
7764
7878
|
observedBranchesByRepo: /* @__PURE__ */ new Map()
|
|
7765
7879
|
};
|
|
@@ -7801,6 +7915,7 @@ var ChatService = class {
|
|
|
7801
7915
|
return;
|
|
7802
7916
|
}
|
|
7803
7917
|
chat.hasActiveTurn = true;
|
|
7918
|
+
chat.activeMessageId = messageId;
|
|
7804
7919
|
keepAliveService.start();
|
|
7805
7920
|
this.publish({
|
|
7806
7921
|
type: "chat.turn.started",
|
|
@@ -7811,6 +7926,25 @@ var ChatService = class {
|
|
|
7811
7926
|
}).catch(() => {
|
|
7812
7927
|
});
|
|
7813
7928
|
}
|
|
7929
|
+
let eventToPublish = event;
|
|
7930
|
+
if (event.type === "event_msg" && event.payload.type === "user_message") {
|
|
7931
|
+
if (chat.activeMessageId) {
|
|
7932
|
+
event.payload[USER_MESSAGE_ID_PAYLOAD_KEY] = chat.activeMessageId;
|
|
7933
|
+
eventToPublish = {
|
|
7934
|
+
...event,
|
|
7935
|
+
payload: {
|
|
7936
|
+
...event.payload,
|
|
7937
|
+
[USER_MESSAGE_ID_PAYLOAD_KEY]: chat.activeMessageId
|
|
7938
|
+
}
|
|
7939
|
+
};
|
|
7940
|
+
}
|
|
7941
|
+
for (const [messageId, acceptedEvent] of chat.acceptedUserEvents) {
|
|
7942
|
+
if (isSameUserMessageEvent(event, acceptedEvent)) {
|
|
7943
|
+
chat.acceptedUserEvents.delete(messageId);
|
|
7944
|
+
break;
|
|
7945
|
+
}
|
|
7946
|
+
}
|
|
7947
|
+
}
|
|
7814
7948
|
this.touch(chat);
|
|
7815
7949
|
this.observeCurrentBranches(chat).catch(() => {
|
|
7816
7950
|
});
|
|
@@ -7818,7 +7952,7 @@ var ChatService = class {
|
|
|
7818
7952
|
type: "chat.turn.delta",
|
|
7819
7953
|
payload: {
|
|
7820
7954
|
chatId,
|
|
7821
|
-
event
|
|
7955
|
+
event: eventToPublish
|
|
7822
7956
|
}
|
|
7823
7957
|
}).catch(() => {
|
|
7824
7958
|
});
|
|
@@ -7840,6 +7974,7 @@ var ChatService = class {
|
|
|
7840
7974
|
return;
|
|
7841
7975
|
}
|
|
7842
7976
|
chat.hasActiveTurn = false;
|
|
7977
|
+
chat.activeMessageId = null;
|
|
7843
7978
|
keepAliveService.stop();
|
|
7844
7979
|
this.publish({
|
|
7845
7980
|
type: "chat.turn.completed",
|