replicas-engine 0.1.444 → 0.1.445
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 +96 -83
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -168,6 +168,9 @@ var DEFAULT_CHAT_TITLES = {
|
|
|
168
168
|
opencode: "Opencode",
|
|
169
169
|
relay: "Relay"
|
|
170
170
|
};
|
|
171
|
+
function isDefaultChat(chat) {
|
|
172
|
+
return chat.title === DEFAULT_CHAT_TITLES[chat.provider];
|
|
173
|
+
}
|
|
171
174
|
var CLAUDE_OPUS_1M_MODEL = "opus[1m]";
|
|
172
175
|
var LEGACY_CLAUDE_OPUS_1M_MODEL = "opus-1m";
|
|
173
176
|
var CLAUDE_FABLE_5_MODEL = "claude-fable-5";
|
|
@@ -521,7 +524,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
521
524
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
522
525
|
|
|
523
526
|
// ../shared/src/e2b.ts
|
|
524
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-16-
|
|
527
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-16-v5";
|
|
525
528
|
|
|
526
529
|
// ../shared/src/runtime-env.ts
|
|
527
530
|
function shellQuotePosix(value) {
|
|
@@ -2726,6 +2729,11 @@ function isVersionBelow(version, minimum) {
|
|
|
2726
2729
|
return compareVersions(version, minimum) < 0;
|
|
2727
2730
|
}
|
|
2728
2731
|
|
|
2732
|
+
// ../shared/src/engine/chat-tabs.ts
|
|
2733
|
+
function hasChatStarted(chat) {
|
|
2734
|
+
return chat.processing || Boolean(chat.awaitingInput) || Boolean(chat.goal) || Boolean(chat.lastMessageText) || chat.updatedAt > chat.createdAt;
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2729
2737
|
// ../shared/src/engine/environment.ts
|
|
2730
2738
|
var DESKTOP_NOVNC_PORT = 6080;
|
|
2731
2739
|
|
|
@@ -8592,7 +8600,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
|
8592
8600
|
var MIN_CODEX_CLI_VERSION = "0.144.0";
|
|
8593
8601
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
8594
8602
|
var codexCliVersionEnsured = null;
|
|
8595
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
8603
|
+
var ENGINE_PACKAGE_VERSION = "0.1.445";
|
|
8596
8604
|
var INITIALIZE_METHOD = "initialize";
|
|
8597
8605
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
8598
8606
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -9491,18 +9499,6 @@ var CodexThreadNotFoundError = class extends Error {
|
|
|
9491
9499
|
this.name = "CodexThreadNotFoundError";
|
|
9492
9500
|
}
|
|
9493
9501
|
};
|
|
9494
|
-
var DefaultChatDeletionError = class extends Error {
|
|
9495
|
-
constructor() {
|
|
9496
|
-
super("Default chats cannot be deleted");
|
|
9497
|
-
this.name = "DefaultChatDeletionError";
|
|
9498
|
-
}
|
|
9499
|
-
};
|
|
9500
|
-
var ChatProcessingDeletionError = class extends Error {
|
|
9501
|
-
constructor() {
|
|
9502
|
-
super("Cannot delete a chat while it is processing");
|
|
9503
|
-
this.name = "ChatProcessingDeletionError";
|
|
9504
|
-
}
|
|
9505
|
-
};
|
|
9506
9502
|
var DuplicateDefaultChatError = class extends Error {
|
|
9507
9503
|
constructor(provider) {
|
|
9508
9504
|
super(`Default chat already exists for provider: ${provider}`);
|
|
@@ -12644,13 +12640,15 @@ async function uploadChatTranscript(chatId, filePath, chat) {
|
|
|
12644
12640
|
title: chat.title,
|
|
12645
12641
|
createdAt: chat.createdAt,
|
|
12646
12642
|
updatedAt: chat.updatedAt,
|
|
12647
|
-
parentChatId: chat.parentChatId
|
|
12643
|
+
parentChatId: chat.parentChatId,
|
|
12644
|
+
deletedAt: chat.deletedAt ?? null
|
|
12648
12645
|
};
|
|
12649
12646
|
form.append("provider", metadata.provider);
|
|
12650
12647
|
form.append("title", metadata.title);
|
|
12651
12648
|
form.append("created_at", metadata.createdAt);
|
|
12652
12649
|
form.append("updated_at", metadata.updatedAt);
|
|
12653
12650
|
if (metadata.parentChatId) form.append("parent_chat_id", metadata.parentChatId);
|
|
12651
|
+
form.append("deleted_at", metadata.deletedAt ?? "");
|
|
12654
12652
|
}
|
|
12655
12653
|
form.append(
|
|
12656
12654
|
"file",
|
|
@@ -12760,7 +12758,7 @@ function isPersistedChat(value) {
|
|
|
12760
12758
|
return false;
|
|
12761
12759
|
}
|
|
12762
12760
|
const candidate = value;
|
|
12763
|
-
return typeof candidate.id === "string" && (candidate.provider === "claude" || candidate.provider === "codex" || candidate.provider === "cursor" || candidate.provider === "opencode" || 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");
|
|
12761
|
+
return typeof candidate.id === "string" && (candidate.provider === "claude" || candidate.provider === "codex" || candidate.provider === "cursor" || candidate.provider === "opencode" || 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") && (candidate.deletedAt === void 0 || candidate.deletedAt === null || typeof candidate.deletedAt === "string");
|
|
12764
12762
|
}
|
|
12765
12763
|
function normalizePersistedChat(chat) {
|
|
12766
12764
|
const isLegacyCodexSdkChat = chat.provider === "codex" && (chat.codexBackend === "sdk" || chat.codexBackend === void 0 && chat.providerSessionId !== null);
|
|
@@ -12772,7 +12770,8 @@ function normalizePersistedChat(chat) {
|
|
|
12772
12770
|
updatedAt: chat.updatedAt,
|
|
12773
12771
|
providerSessionId: isLegacyCodexSdkChat ? null : chat.providerSessionId,
|
|
12774
12772
|
parentChatId: chat.parentChatId ?? null,
|
|
12775
|
-
lastMessageText: chat.lastMessageText ?? null
|
|
12773
|
+
lastMessageText: chat.lastMessageText ?? null,
|
|
12774
|
+
deletedAt: chat.deletedAt ?? null
|
|
12776
12775
|
};
|
|
12777
12776
|
}
|
|
12778
12777
|
function parsePersistedChatsContent(content) {
|
|
@@ -12802,7 +12801,9 @@ function createUserMessageEvent(message, messageId, images) {
|
|
|
12802
12801
|
var ChatService = class {
|
|
12803
12802
|
constructor(workingDirectory) {
|
|
12804
12803
|
this.workingDirectory = workingDirectory;
|
|
12805
|
-
keepAliveService.setActivityCheck(
|
|
12804
|
+
keepAliveService.setActivityCheck(
|
|
12805
|
+
() => [...this.chats.values()].some((chat) => !chat.persisted.deletedAt && isChatActive(chat))
|
|
12806
|
+
);
|
|
12806
12807
|
}
|
|
12807
12808
|
workingDirectory;
|
|
12808
12809
|
chats = /* @__PURE__ */ new Map();
|
|
@@ -12821,46 +12822,27 @@ var ChatService = class {
|
|
|
12821
12822
|
const runtime = this.createRuntimeChat(chat);
|
|
12822
12823
|
this.chats.set(chat.id, runtime);
|
|
12823
12824
|
}
|
|
12824
|
-
const
|
|
12825
|
-
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
(
|
|
12829
|
-
|
|
12830
|
-
|
|
12831
|
-
(c) => c.persisted.provider === "cursor" && c.persisted.title === "Cursor"
|
|
12832
|
-
);
|
|
12833
|
-
const hasOpencodeDefault = [...this.chats.values()].some(
|
|
12834
|
-
(c) => c.persisted.provider === "opencode" && c.persisted.title === "Opencode"
|
|
12835
|
-
);
|
|
12836
|
-
if (!hasClaudeDefault) {
|
|
12837
|
-
await this.createChat({ provider: "claude", title: "Claude Code" });
|
|
12838
|
-
}
|
|
12839
|
-
if (!hasCodexDefault) {
|
|
12840
|
-
await this.createChat({ provider: "codex", title: "Codex" });
|
|
12841
|
-
}
|
|
12842
|
-
if (!hasCursorDefault) {
|
|
12843
|
-
await this.createChat({ provider: "cursor", title: "Cursor" });
|
|
12844
|
-
}
|
|
12845
|
-
if (!hasOpencodeDefault) {
|
|
12846
|
-
await this.createChat({ provider: "opencode", title: "Opencode" });
|
|
12847
|
-
}
|
|
12848
|
-
const hasRelayDefault = [...this.chats.values()].some(
|
|
12849
|
-
(c) => c.persisted.provider === "relay" && c.persisted.title === "Relay"
|
|
12850
|
-
);
|
|
12851
|
-
if (!hasRelayDefault) {
|
|
12852
|
-
await this.createChat({ provider: "relay", title: "Relay" });
|
|
12825
|
+
for (const provider of VALID_AGENT_PROVIDERS) {
|
|
12826
|
+
const hasDefault = [...this.chats.values()].some(
|
|
12827
|
+
(c) => c.persisted.provider === provider && isDefaultChat(c.persisted)
|
|
12828
|
+
);
|
|
12829
|
+
if (!hasDefault) {
|
|
12830
|
+
await this.createChat({ provider, title: DEFAULT_CHAT_TITLES[provider] });
|
|
12831
|
+
}
|
|
12853
12832
|
}
|
|
12854
12833
|
}
|
|
12855
12834
|
listChats(includeChildren = false) {
|
|
12856
|
-
return Array.from(this.chats.values()).filter((chat) => includeChildren || chat.persisted.parentChatId === null).map((chat) => this.toSummary(chat)).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
12835
|
+
return Array.from(this.chats.values()).filter((chat) => !chat.persisted.deletedAt && (includeChildren || chat.persisted.parentChatId === null)).map((chat) => this.toSummary(chat)).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
12836
|
+
}
|
|
12837
|
+
listDeletedChats() {
|
|
12838
|
+
return Array.from(this.chats.values()).filter((chat) => chat.persisted.deletedAt && chat.persisted.parentChatId === null).map((chat) => this.toSummary(chat)).sort((a, b) => (b.deletedAt ?? "").localeCompare(a.deletedAt ?? ""));
|
|
12857
12839
|
}
|
|
12858
12840
|
listChildChats(parentChatId) {
|
|
12859
|
-
return Array.from(this.chats.values()).filter((chat) => chat.persisted.parentChatId === parentChatId).map((chat) => this.toSummary(chat)).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
12841
|
+
return Array.from(this.chats.values()).filter((chat) => !chat.persisted.deletedAt && chat.persisted.parentChatId === parentChatId).map((chat) => this.toSummary(chat)).sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
12860
12842
|
}
|
|
12861
12843
|
getChat(chatId) {
|
|
12862
12844
|
const chat = this.chats.get(chatId);
|
|
12863
|
-
return chat ? this.toSummary(chat) : null;
|
|
12845
|
+
return chat && !chat.persisted.deletedAt ? this.toSummary(chat) : null;
|
|
12864
12846
|
}
|
|
12865
12847
|
async listSlashCommands(chatId) {
|
|
12866
12848
|
const chat = this.requireChat(chatId);
|
|
@@ -12880,7 +12862,7 @@ var ChatService = class {
|
|
|
12880
12862
|
async createChat(request) {
|
|
12881
12863
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
12882
12864
|
const title = request.title?.trim() || `${request.provider} chat`;
|
|
12883
|
-
if (
|
|
12865
|
+
if (isDefaultChat({ provider: request.provider, title }) && Array.from(this.chats.values()).some((chat) => !chat.persisted.deletedAt && chat.persisted.provider === request.provider && isDefaultChat(chat.persisted))) {
|
|
12884
12866
|
throw new DuplicateDefaultChatError(request.provider);
|
|
12885
12867
|
}
|
|
12886
12868
|
const parentChatId = request.parentChatId ?? null;
|
|
@@ -13091,24 +13073,49 @@ var ChatService = class {
|
|
|
13091
13073
|
return chat.provider.respondToToolInput(requestId, selectionId);
|
|
13092
13074
|
}
|
|
13093
13075
|
async deleteChat(chatId) {
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
|
|
13076
|
+
this.requireChat(chatId);
|
|
13077
|
+
const toDelete = [chatId, ...this.collectDescendants(chatId)];
|
|
13078
|
+
const deletedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
13079
|
+
for (const id of toDelete) {
|
|
13080
|
+
const target = this.chats.get(id);
|
|
13081
|
+
if (!target || target.persisted.deletedAt) continue;
|
|
13082
|
+
if (target.provider.isProcessing()) {
|
|
13083
|
+
await target.provider.interrupt().catch(() => {
|
|
13084
|
+
});
|
|
13085
|
+
target.hasActiveTurn = false;
|
|
13086
|
+
target.activeMessageId = null;
|
|
13087
|
+
target.pendingMessageIds = [];
|
|
13088
|
+
target.acceptedUserEvents.clear();
|
|
13089
|
+
}
|
|
13090
|
+
if (hasChatStarted(this.toSummary(target))) {
|
|
13091
|
+
target.persisted.deletedAt = deletedAt;
|
|
13092
|
+
} else {
|
|
13093
|
+
this.chats.delete(id);
|
|
13094
|
+
target.provider.dispose?.();
|
|
13095
|
+
await this.deleteHistoryFile(target.persisted);
|
|
13096
|
+
}
|
|
13097
|
+
await this.publish({ type: "chat.deleted", payload: { chatId: id, chat: this.toSummary(target) } });
|
|
13097
13098
|
}
|
|
13098
|
-
|
|
13099
|
-
|
|
13099
|
+
await this.persistAllChats();
|
|
13100
|
+
}
|
|
13101
|
+
async restoreChat(chatId) {
|
|
13102
|
+
const chat = this.chats.get(chatId);
|
|
13103
|
+
if (!chat?.persisted.deletedAt) {
|
|
13104
|
+
throw new ChatNotFoundError(chatId);
|
|
13100
13105
|
}
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13106
|
+
if (isDefaultChat(chat.persisted) && Array.from(this.chats.values()).some((other) => other !== chat && !other.persisted.deletedAt && other.persisted.provider === chat.persisted.provider && other.persisted.title === chat.persisted.title)) {
|
|
13107
|
+
chat.persisted.title = `${chat.persisted.title} (restored)`;
|
|
13108
|
+
}
|
|
13109
|
+
const restoredAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
13110
|
+
for (const id of [chatId, ...this.collectDescendants(chatId)]) {
|
|
13104
13111
|
const target = this.chats.get(id);
|
|
13105
|
-
if (!target) continue;
|
|
13106
|
-
|
|
13107
|
-
target.
|
|
13108
|
-
await this.
|
|
13109
|
-
await this.publish({ type: "chat.deleted", payload: { chatId: id } });
|
|
13112
|
+
if (!target?.persisted.deletedAt) continue;
|
|
13113
|
+
target.persisted.deletedAt = null;
|
|
13114
|
+
target.persisted.updatedAt = restoredAt;
|
|
13115
|
+
await this.publish({ type: "chat.created", payload: { chat: this.toSummary(target) } });
|
|
13110
13116
|
}
|
|
13111
13117
|
await this.persistAllChats();
|
|
13118
|
+
return this.toSummary(chat);
|
|
13112
13119
|
}
|
|
13113
13120
|
/**
|
|
13114
13121
|
* Recursively collects all descendant chat IDs of a given parent.
|
|
@@ -13153,7 +13160,7 @@ var ChatService = class {
|
|
|
13153
13160
|
getProcessingCount() {
|
|
13154
13161
|
let count = 0;
|
|
13155
13162
|
for (const chat of this.chats.values()) {
|
|
13156
|
-
if (isChatActive(chat)) {
|
|
13163
|
+
if (!chat.persisted.deletedAt && isChatActive(chat)) {
|
|
13157
13164
|
count += 1;
|
|
13158
13165
|
}
|
|
13159
13166
|
}
|
|
@@ -13180,9 +13187,11 @@ var ChatService = class {
|
|
|
13180
13187
|
persisted.providerSessionId = sessionId;
|
|
13181
13188
|
persisted.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
13182
13189
|
await this.persistAllChats();
|
|
13190
|
+
const chat = this.getRuntimeChat(persisted.id);
|
|
13191
|
+
if (!chat) return;
|
|
13183
13192
|
await this.publish({
|
|
13184
13193
|
type: "chat.updated",
|
|
13185
|
-
payload: { chat: this.toSummary(
|
|
13194
|
+
payload: { chat: this.toSummary(chat) }
|
|
13186
13195
|
});
|
|
13187
13196
|
};
|
|
13188
13197
|
const onProviderTurnComplete = async () => {
|
|
@@ -13274,12 +13283,13 @@ var ChatService = class {
|
|
|
13274
13283
|
isAuthRetrying: chat.provider.isAuthRetrying?.() ?? false,
|
|
13275
13284
|
goal: chat.provider.getGoal?.() ?? null,
|
|
13276
13285
|
parentChatId: chat.persisted.parentChatId,
|
|
13277
|
-
lastMessageText: chat.persisted.lastMessageText ?? null
|
|
13286
|
+
lastMessageText: chat.persisted.lastMessageText ?? null,
|
|
13287
|
+
deletedAt: chat.persisted.deletedAt ?? null
|
|
13278
13288
|
};
|
|
13279
13289
|
}
|
|
13280
13290
|
requireChat(chatId) {
|
|
13281
13291
|
const chat = this.chats.get(chatId);
|
|
13282
|
-
if (!chat) {
|
|
13292
|
+
if (!chat || chat.persisted.deletedAt) {
|
|
13283
13293
|
throw new ChatNotFoundError(chatId);
|
|
13284
13294
|
}
|
|
13285
13295
|
return chat;
|
|
@@ -13388,7 +13398,8 @@ var ChatService = class {
|
|
|
13388
13398
|
await this.publishAgentTurnCompleteWebhook(chat);
|
|
13389
13399
|
}
|
|
13390
13400
|
getRuntimeChat(chatId) {
|
|
13391
|
-
|
|
13401
|
+
const chat = this.chats.get(chatId) ?? null;
|
|
13402
|
+
return chat && !chat.persisted.deletedAt ? chat : null;
|
|
13392
13403
|
}
|
|
13393
13404
|
async loadChats() {
|
|
13394
13405
|
try {
|
|
@@ -14400,7 +14411,8 @@ function createV1Routes(deps) {
|
|
|
14400
14411
|
app2.get("/chats", (c) => {
|
|
14401
14412
|
const includeChildren = c.req.query("includeChildren") === "true";
|
|
14402
14413
|
const response = {
|
|
14403
|
-
chats: deps.chatService.listChats(includeChildren)
|
|
14414
|
+
chats: deps.chatService.listChats(includeChildren),
|
|
14415
|
+
deletedChats: deps.chatService.listDeletedChats()
|
|
14404
14416
|
};
|
|
14405
14417
|
return c.json(response);
|
|
14406
14418
|
});
|
|
@@ -14444,24 +14456,25 @@ function createV1Routes(deps) {
|
|
|
14444
14456
|
return c.json({ success: true, chatId });
|
|
14445
14457
|
} catch (error) {
|
|
14446
14458
|
const details = error instanceof Error ? error.message : "Unknown error";
|
|
14447
|
-
if (error instanceof
|
|
14448
|
-
return c.json(jsonError("Failed to delete chat", "Default chats cannot be deleted"), 400);
|
|
14449
|
-
}
|
|
14450
|
-
if (error instanceof ChatProcessingDeletionError) {
|
|
14451
|
-
return c.json(jsonError("Failed to delete chat", "Cannot delete a chat while it is processing"), 400);
|
|
14452
|
-
}
|
|
14453
|
-
if (error instanceof ChatNotFoundError) {
|
|
14454
|
-
return c.json(jsonError("Failed to delete chat", details), 404);
|
|
14455
|
-
}
|
|
14456
|
-
if (details.includes("Default chats cannot be deleted") || details.includes("while it is processing")) {
|
|
14457
|
-
return c.json(jsonError("Failed to delete chat", details), 400);
|
|
14458
|
-
}
|
|
14459
|
-
if (details.includes("Chat not found")) {
|
|
14459
|
+
if (error instanceof ChatNotFoundError || details.includes("Chat not found")) {
|
|
14460
14460
|
return c.json(jsonError("Failed to delete chat", details), 404);
|
|
14461
14461
|
}
|
|
14462
14462
|
return c.json(jsonError("Failed to delete chat", details), 500);
|
|
14463
14463
|
}
|
|
14464
14464
|
});
|
|
14465
|
+
app2.post("/chats/:chatId/restore", async (c) => {
|
|
14466
|
+
const chatId = c.req.param("chatId");
|
|
14467
|
+
try {
|
|
14468
|
+
const chat = await deps.chatService.restoreChat(chatId);
|
|
14469
|
+
return c.json({ chat });
|
|
14470
|
+
} catch (error) {
|
|
14471
|
+
const details = error instanceof Error ? error.message : "Unknown error";
|
|
14472
|
+
if (error instanceof ChatNotFoundError) {
|
|
14473
|
+
return c.json(jsonError("Failed to restore chat", details), 404);
|
|
14474
|
+
}
|
|
14475
|
+
return c.json(jsonError("Failed to restore chat", details), 500);
|
|
14476
|
+
}
|
|
14477
|
+
});
|
|
14465
14478
|
app2.get("/chats/:chatId/history", async (c) => {
|
|
14466
14479
|
try {
|
|
14467
14480
|
const history = await deps.chatService.getChatHistory(
|