replicas-engine 0.1.518 → 0.1.520
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 +103 -64
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -609,7 +609,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
609
609
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
610
610
|
|
|
611
611
|
// ../shared/src/e2b.ts
|
|
612
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-
|
|
612
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-29-v2";
|
|
613
613
|
|
|
614
614
|
// ../shared/src/runtime-env.ts
|
|
615
615
|
function shellQuotePosix(value) {
|
|
@@ -10069,7 +10069,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
|
10069
10069
|
var MIN_CODEX_CLI_VERSION = "0.144.6";
|
|
10070
10070
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
10071
10071
|
var codexCliVersionEnsured = null;
|
|
10072
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
10072
|
+
var ENGINE_PACKAGE_VERSION = "0.1.520";
|
|
10073
10073
|
var INITIALIZE_METHOD = "initialize";
|
|
10074
10074
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
10075
10075
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -12451,6 +12451,7 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
12451
12451
|
const message = await this.toCursorMessage(request, includeInstructions);
|
|
12452
12452
|
const agent = await this.ensureAgent(request);
|
|
12453
12453
|
const model = request.model ?? DEFAULT_CURSOR_MODEL;
|
|
12454
|
+
this.activeModel = model;
|
|
12454
12455
|
this.recordHistoryEvent("event_msg", {
|
|
12455
12456
|
type: "user_message",
|
|
12456
12457
|
message: request.message
|
|
@@ -12459,11 +12460,11 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
12459
12460
|
model: { id: model },
|
|
12460
12461
|
mode: request.planMode ? "plan" : "agent",
|
|
12461
12462
|
onDelta: async (args) => {
|
|
12463
|
+
this.recordCursorContextUsage(args.update);
|
|
12462
12464
|
await this.handleCursorToolCall(cursorToolInputFromDelta(args.update));
|
|
12463
12465
|
}
|
|
12464
12466
|
});
|
|
12465
12467
|
this.activeRun = run;
|
|
12466
|
-
this.activeModel = model;
|
|
12467
12468
|
if (this.pendingCursorBlockReason) {
|
|
12468
12469
|
await run.cancel();
|
|
12469
12470
|
throw new Error(this.pendingCursorBlockReason);
|
|
@@ -12487,7 +12488,7 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
12487
12488
|
}
|
|
12488
12489
|
if (next.done) break;
|
|
12489
12490
|
const event = next.value;
|
|
12490
|
-
this.
|
|
12491
|
+
this.recordHistoryEvent(`cursor-${event.type}`, event, this.historyFile);
|
|
12491
12492
|
if (event.type === "tool_call" && event.status === "running") {
|
|
12492
12493
|
await this.handleCursorToolCall(cursorToolInputFromMessage(event));
|
|
12493
12494
|
}
|
|
@@ -12508,9 +12509,11 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
12508
12509
|
await this.onSaveSessionId(agent.agentId);
|
|
12509
12510
|
}
|
|
12510
12511
|
if (result.status === "error") {
|
|
12512
|
+
const detail = await this.readRunErrorDetail(agent.agentId, result.id);
|
|
12513
|
+
console.error("[CursorManager] Cursor run failed:", { runId: result.id, model, detail });
|
|
12511
12514
|
this.recordHistoryEvent("cursor-error", {
|
|
12512
12515
|
type: "error",
|
|
12513
|
-
message: result.result || "Cursor run failed",
|
|
12516
|
+
message: detail || result.result || "Cursor run failed",
|
|
12514
12517
|
runId: result.id
|
|
12515
12518
|
}, this.historyFile);
|
|
12516
12519
|
} else {
|
|
@@ -12532,6 +12535,21 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
12532
12535
|
await this.onTurnComplete();
|
|
12533
12536
|
}
|
|
12534
12537
|
}
|
|
12538
|
+
async readRunErrorDetail(agentId, runId) {
|
|
12539
|
+
try {
|
|
12540
|
+
const { SqliteLocalAgentStore } = await import("@cursor/sdk/sqlite");
|
|
12541
|
+
const store = await SqliteLocalAgentStore.open({ workspaceRef: this.workingDirectory });
|
|
12542
|
+
try {
|
|
12543
|
+
const record = await store.runs.get({ agentId, runId });
|
|
12544
|
+
return record?.error?.trim() || null;
|
|
12545
|
+
} finally {
|
|
12546
|
+
await store.dispose();
|
|
12547
|
+
}
|
|
12548
|
+
} catch (error) {
|
|
12549
|
+
console.error("[CursorManager] Failed to read Cursor run error detail:", error);
|
|
12550
|
+
return null;
|
|
12551
|
+
}
|
|
12552
|
+
}
|
|
12535
12553
|
async handleCursorToolCall(toolCall) {
|
|
12536
12554
|
if (!toolCall) return;
|
|
12537
12555
|
if (this.blockedToolCallIds.has(toolCall.toolUseId)) return;
|
|
@@ -12584,24 +12602,16 @@ ${request.message}` : request.message;
|
|
|
12584
12602
|
}))
|
|
12585
12603
|
};
|
|
12586
12604
|
}
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
if (!usage) return;
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
return null;
|
|
12596
|
-
}
|
|
12597
|
-
const usage = "usage" in event && event.usage && typeof event.usage === "object" ? event.usage : null;
|
|
12598
|
-
if (!usage) return null;
|
|
12599
|
-
const inputTokens = finiteNumber("inputTokens" in usage ? usage.inputTokens : null);
|
|
12600
|
-
const cacheReadTokens = finiteNumber("cacheReadTokens" in usage ? usage.cacheReadTokens : null);
|
|
12601
|
-
const cacheWriteTokens = finiteNumber("cacheWriteTokens" in usage ? usage.cacheWriteTokens : null);
|
|
12602
|
-
const outputTokens = finiteNumber("outputTokens" in usage ? usage.outputTokens : null);
|
|
12605
|
+
// `turn-ended` is only ever an `onDelta` interaction update — it is not part of
|
|
12606
|
+
// the `SDKMessage` union the run stream yields, so usage has to be read here.
|
|
12607
|
+
recordCursorContextUsage(update) {
|
|
12608
|
+
if (update.type !== "turn-ended" || !update.usage) return;
|
|
12609
|
+
const inputTokens = finiteNumber(update.usage.inputTokens);
|
|
12610
|
+
const cacheReadTokens = finiteNumber(update.usage.cacheReadTokens);
|
|
12611
|
+
const cacheWriteTokens = finiteNumber(update.usage.cacheWriteTokens);
|
|
12612
|
+
const outputTokens = finiteNumber(update.usage.outputTokens);
|
|
12603
12613
|
const rawTotalTokens = inputTokens + cacheReadTokens + cacheWriteTokens + outputTokens;
|
|
12604
|
-
if (rawTotalTokens <= 0) return
|
|
12614
|
+
if (rawTotalTokens <= 0) return;
|
|
12605
12615
|
const maxTokens = CURSOR_COMPOSER_CONTEXT_WINDOW;
|
|
12606
12616
|
const { totalTokens, totalProcessedTokens } = clampTokensToWindow(rawTotalTokens, maxTokens);
|
|
12607
12617
|
const categories = [
|
|
@@ -12630,7 +12640,7 @@ ${request.message}` : request.message;
|
|
|
12630
12640
|
color: CURSOR_CATEGORY_COLORS.output
|
|
12631
12641
|
}
|
|
12632
12642
|
].filter((category) => category.tokens > 0);
|
|
12633
|
-
|
|
12643
|
+
const payload = {
|
|
12634
12644
|
provider: "cursor",
|
|
12635
12645
|
source: "provider_usage",
|
|
12636
12646
|
model: this.activeModel,
|
|
@@ -12649,6 +12659,7 @@ ${request.message}` : request.message;
|
|
|
12649
12659
|
},
|
|
12650
12660
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
12651
12661
|
};
|
|
12662
|
+
this.historyFile.append(this.emitContextUsage(payload));
|
|
12652
12663
|
}
|
|
12653
12664
|
};
|
|
12654
12665
|
|
|
@@ -14396,7 +14407,10 @@ async function reconcileCanvasItems(filenames) {
|
|
|
14396
14407
|
}
|
|
14397
14408
|
|
|
14398
14409
|
// src/services/upload-chat-transcripts.ts
|
|
14399
|
-
import {
|
|
14410
|
+
import { createReadStream } from "fs";
|
|
14411
|
+
import { readdir as readdir7, readFile as readFile13, stat as stat4 } from "fs/promises";
|
|
14412
|
+
import { request as httpRequest } from "http";
|
|
14413
|
+
import { request as httpsRequest } from "https";
|
|
14400
14414
|
import { basename as basename2, join as join23 } from "path";
|
|
14401
14415
|
|
|
14402
14416
|
// src/services/chat/chat-senders.ts
|
|
@@ -14423,6 +14437,34 @@ var HISTORY_DIRS = [
|
|
|
14423
14437
|
join23(ENGINE_DIR2, "relay-histories"),
|
|
14424
14438
|
join23(ENGINE_DIR2, "codex-histories")
|
|
14425
14439
|
];
|
|
14440
|
+
async function putTranscript(uploadUrl, filePath, size) {
|
|
14441
|
+
await new Promise((resolve4, reject) => {
|
|
14442
|
+
const url = new URL(uploadUrl);
|
|
14443
|
+
const request = (url.protocol === "https:" ? httpsRequest : httpRequest)(url, {
|
|
14444
|
+
method: "PUT",
|
|
14445
|
+
headers: {
|
|
14446
|
+
"content-length": String(size),
|
|
14447
|
+
"content-type": "application/x-ndjson"
|
|
14448
|
+
}
|
|
14449
|
+
}, (response) => {
|
|
14450
|
+
response.setEncoding("utf8");
|
|
14451
|
+
let body = "";
|
|
14452
|
+
response.on("data", (chunk) => {
|
|
14453
|
+
body += chunk;
|
|
14454
|
+
});
|
|
14455
|
+
response.on("end", () => {
|
|
14456
|
+
const status = response.statusCode ?? 0;
|
|
14457
|
+
if (status >= 200 && status < 300) resolve4();
|
|
14458
|
+
else reject(new Error(`upload failed: ${status} ${body}`));
|
|
14459
|
+
});
|
|
14460
|
+
response.on("error", reject);
|
|
14461
|
+
});
|
|
14462
|
+
request.on("error", reject);
|
|
14463
|
+
const file = createReadStream(filePath, { start: 0, end: size - 1 });
|
|
14464
|
+
file.on("error", (error) => request.destroy(error));
|
|
14465
|
+
file.pipe(request);
|
|
14466
|
+
});
|
|
14467
|
+
}
|
|
14426
14468
|
async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
14427
14469
|
let flushed = 0;
|
|
14428
14470
|
let failed = 0;
|
|
@@ -14451,44 +14493,41 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
|
14451
14493
|
return { flushed, failed };
|
|
14452
14494
|
}
|
|
14453
14495
|
async function uploadChatTranscript(chatId, filePath, chat) {
|
|
14454
|
-
const
|
|
14455
|
-
if (
|
|
14456
|
-
|
|
14496
|
+
const { size } = await stat4(filePath);
|
|
14497
|
+
if (size === 0) return;
|
|
14498
|
+
const metadata = chat ? {
|
|
14499
|
+
provider: chat.provider,
|
|
14500
|
+
title: chat.title,
|
|
14501
|
+
createdAt: chat.createdAt,
|
|
14502
|
+
updatedAt: chat.updatedAt,
|
|
14503
|
+
parentChatId: chat.parentChatId,
|
|
14504
|
+
deletedAt: chat.deletedAt ?? null
|
|
14505
|
+
} : {};
|
|
14457
14506
|
try {
|
|
14458
|
-
senders = parseChatMessageSendersJsonl(
|
|
14507
|
+
metadata.senders = parseChatMessageSendersJsonl(
|
|
14508
|
+
await readFile13(chatMessageSendersFilePath(chatId), "utf-8")
|
|
14509
|
+
);
|
|
14459
14510
|
} catch (error) {
|
|
14460
14511
|
if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) throw error;
|
|
14461
14512
|
}
|
|
14462
|
-
const
|
|
14463
|
-
|
|
14464
|
-
|
|
14465
|
-
|
|
14466
|
-
|
|
14467
|
-
|
|
14468
|
-
createdAt: chat.createdAt,
|
|
14469
|
-
updatedAt: chat.updatedAt,
|
|
14470
|
-
parentChatId: chat.parentChatId,
|
|
14471
|
-
deletedAt: chat.deletedAt ?? null
|
|
14472
|
-
};
|
|
14473
|
-
form.append("provider", metadata.provider);
|
|
14474
|
-
form.append("title", metadata.title);
|
|
14475
|
-
form.append("created_at", metadata.createdAt);
|
|
14476
|
-
form.append("updated_at", metadata.updatedAt);
|
|
14477
|
-
if (metadata.parentChatId) form.append("parent_chat_id", metadata.parentChatId);
|
|
14478
|
-
form.append("deleted_at", metadata.deletedAt ?? "");
|
|
14513
|
+
const uploadRequest = { chatId, size, metadata };
|
|
14514
|
+
const prepareResponse = await monolithRequest("/v1/engine/chat-transcripts/upload-url", {
|
|
14515
|
+
body: uploadRequest
|
|
14516
|
+
});
|
|
14517
|
+
if (!prepareResponse.ok) {
|
|
14518
|
+
throw new Error(`prepare failed: ${prepareResponse.status} ${await prepareResponse.text()}`);
|
|
14479
14519
|
}
|
|
14480
|
-
|
|
14481
|
-
|
|
14520
|
+
const prepareBody = await prepareResponse.json();
|
|
14521
|
+
if (!isRecord(prepareBody) || typeof prepareBody.uploadUrl !== "string" && prepareBody.uploadUrl !== null) {
|
|
14522
|
+
throw new Error("prepare failed: invalid response");
|
|
14482
14523
|
}
|
|
14483
|
-
|
|
14484
|
-
|
|
14485
|
-
|
|
14486
|
-
|
|
14487
|
-
);
|
|
14488
|
-
|
|
14489
|
-
|
|
14490
|
-
const errorText = await response.text();
|
|
14491
|
-
throw new Error(`upload failed: ${response.status} ${errorText}`);
|
|
14524
|
+
if (prepareBody.uploadUrl === null) return;
|
|
14525
|
+
await putTranscript(prepareBody.uploadUrl, filePath, size);
|
|
14526
|
+
const finalizeResponse = await monolithRequest("/v1/engine/chat-transcripts/finalize", {
|
|
14527
|
+
body: uploadRequest
|
|
14528
|
+
});
|
|
14529
|
+
if (!finalizeResponse.ok) {
|
|
14530
|
+
throw new Error(`finalize failed: ${finalizeResponse.status} ${await finalizeResponse.text()}`);
|
|
14492
14531
|
}
|
|
14493
14532
|
}
|
|
14494
14533
|
|
|
@@ -14526,8 +14565,8 @@ async function flushRepoState() {
|
|
|
14526
14565
|
}
|
|
14527
14566
|
|
|
14528
14567
|
// src/services/upload-engine-logs.ts
|
|
14529
|
-
import { createReadStream } from "fs";
|
|
14530
|
-
import { readdir as readdir8, stat as
|
|
14568
|
+
import { createReadStream as createReadStream2 } from "fs";
|
|
14569
|
+
import { readdir as readdir8, stat as stat5 } from "fs/promises";
|
|
14531
14570
|
import { join as join24 } from "path";
|
|
14532
14571
|
var MAX_ENGINE_LOG_FLUSH_SESSIONS = 10;
|
|
14533
14572
|
var MAX_ENGINE_LOG_FLUSH_BYTES = 5 * 1024 * 1024;
|
|
@@ -14558,7 +14597,7 @@ async function flushAllEngineLogs() {
|
|
|
14558
14597
|
try {
|
|
14559
14598
|
const sessionId = filename.slice(0, -".log".length);
|
|
14560
14599
|
const filePath = join24(LOG_DIR, filename);
|
|
14561
|
-
const fileStat = await runBeforeDeadline(() =>
|
|
14600
|
+
const fileStat = await runBeforeDeadline(() => stat5(filePath), deadline);
|
|
14562
14601
|
if (!fileStat.isFile()) {
|
|
14563
14602
|
skipped++;
|
|
14564
14603
|
return null;
|
|
@@ -14590,7 +14629,7 @@ async function flushAllEngineLogs() {
|
|
|
14590
14629
|
const content = await runBeforeDeadline(async (signal) => {
|
|
14591
14630
|
if (candidate.length === 0) return Buffer.alloc(0);
|
|
14592
14631
|
const chunks = [];
|
|
14593
|
-
for await (const chunk of
|
|
14632
|
+
for await (const chunk of createReadStream2(candidate.filePath, {
|
|
14594
14633
|
start: candidate.offset,
|
|
14595
14634
|
end: candidate.offset + candidate.length - 1,
|
|
14596
14635
|
signal
|
|
@@ -15531,7 +15570,7 @@ var ChatService = class {
|
|
|
15531
15570
|
|
|
15532
15571
|
// src/services/repo-file-service.ts
|
|
15533
15572
|
import { execFile as execFile2 } from "child_process";
|
|
15534
|
-
import { readFile as readFile15, realpath, stat as
|
|
15573
|
+
import { readFile as readFile15, realpath, stat as stat6 } from "fs/promises";
|
|
15535
15574
|
import { join as join26, resolve as resolve2, extname as extname2 } from "path";
|
|
15536
15575
|
var CACHE_TTL_MS = 3e4;
|
|
15537
15576
|
var SEARCH_TIMEOUT_MS = 15e3;
|
|
@@ -15696,7 +15735,7 @@ var RepoFileService = class {
|
|
|
15696
15735
|
const repoRoot = await realpath(repo.path);
|
|
15697
15736
|
const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
|
|
15698
15737
|
if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
|
|
15699
|
-
const fileStat = await
|
|
15738
|
+
const fileStat = await stat6(fullPath);
|
|
15700
15739
|
if (!fileStat.isFile()) return null;
|
|
15701
15740
|
const sizeBytes = fileStat.size;
|
|
15702
15741
|
if (isBinaryExtension(filePath)) {
|
|
@@ -15799,7 +15838,7 @@ var RepoFileService = class {
|
|
|
15799
15838
|
// src/v1-routes.ts
|
|
15800
15839
|
import { Hono } from "hono";
|
|
15801
15840
|
import { z as z7 } from "zod";
|
|
15802
|
-
import { readdir as readdir10, stat as
|
|
15841
|
+
import { readdir as readdir10, stat as stat7, readFile as readFile18 } from "fs/promises";
|
|
15803
15842
|
import { join as join29, resolve as resolve3 } from "path";
|
|
15804
15843
|
|
|
15805
15844
|
// src/services/warm-hooks-service.ts
|
|
@@ -17189,7 +17228,7 @@ data: ${JSON.stringify("Terminal session not found")}
|
|
|
17189
17228
|
const sessions = await Promise.all(
|
|
17190
17229
|
logFiles.map(async (filename) => {
|
|
17191
17230
|
const filePath = join29(LOG_DIR, filename);
|
|
17192
|
-
const fileStat = await
|
|
17231
|
+
const fileStat = await stat7(filePath);
|
|
17193
17232
|
const sessionId = filename.replace(/\.log$/, "");
|
|
17194
17233
|
return {
|
|
17195
17234
|
sessionId,
|