replicas-engine 0.1.165 → 0.1.167
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 +166 -1
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -20,6 +20,7 @@ import { readFileSync } from "fs";
|
|
|
20
20
|
|
|
21
21
|
// ../shared/src/event.ts
|
|
22
22
|
var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
|
|
23
|
+
var CONTEXT_USAGE_EVENT_TYPE = "context-usage";
|
|
23
24
|
|
|
24
25
|
// ../shared/src/pricing.ts
|
|
25
26
|
var PLANS = {
|
|
@@ -285,7 +286,7 @@ function parseReplicasConfigString(content, filename) {
|
|
|
285
286
|
}
|
|
286
287
|
|
|
287
288
|
// ../shared/src/engine/environment.ts
|
|
288
|
-
var DAYTONA_SNAPSHOT_ID = "13-05-2026-royal-york-
|
|
289
|
+
var DAYTONA_SNAPSHOT_ID = "13-05-2026-royal-york-v13";
|
|
289
290
|
|
|
290
291
|
// ../shared/src/engine/types.ts
|
|
291
292
|
var DEFAULT_CHAT_TITLES = {
|
|
@@ -2522,6 +2523,35 @@ var MessageQueueService = class {
|
|
|
2522
2523
|
this.queue = [];
|
|
2523
2524
|
return drained;
|
|
2524
2525
|
}
|
|
2526
|
+
/**
|
|
2527
|
+
* Get all queued messages (does not include the currently processing message)
|
|
2528
|
+
*/
|
|
2529
|
+
getQueue() {
|
|
2530
|
+
return [...this.queue];
|
|
2531
|
+
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Remove a message from the queue by its ID
|
|
2534
|
+
* @returns true if the message was found and removed
|
|
2535
|
+
*/
|
|
2536
|
+
removeFromQueue(messageId) {
|
|
2537
|
+
const index = this.queue.findIndex((m) => m.id === messageId);
|
|
2538
|
+
if (index === -1) return false;
|
|
2539
|
+
this.queue.splice(index, 1);
|
|
2540
|
+
return true;
|
|
2541
|
+
}
|
|
2542
|
+
/**
|
|
2543
|
+
* Move a message to a new position in the queue
|
|
2544
|
+
* @returns true if the message was found and moved
|
|
2545
|
+
*/
|
|
2546
|
+
reorderQueue(messageId, newPosition) {
|
|
2547
|
+
const index = this.queue.findIndex((m) => m.id === messageId);
|
|
2548
|
+
if (index === -1) return false;
|
|
2549
|
+
const clamped = Math.max(0, Math.min(newPosition, this.queue.length - 1));
|
|
2550
|
+
if (index === clamped) return true;
|
|
2551
|
+
const [item] = this.queue.splice(index, 1);
|
|
2552
|
+
this.queue.splice(clamped, 0, item);
|
|
2553
|
+
return true;
|
|
2554
|
+
}
|
|
2525
2555
|
/**
|
|
2526
2556
|
* Reset everything including clearing processing state
|
|
2527
2557
|
*/
|
|
@@ -2567,10 +2597,35 @@ var CodingAgentManager = class {
|
|
|
2567
2597
|
isProcessing() {
|
|
2568
2598
|
return this.messageQueue.isProcessing();
|
|
2569
2599
|
}
|
|
2600
|
+
getQueue() {
|
|
2601
|
+
return this.messageQueue.getQueue().map((m) => ({
|
|
2602
|
+
id: m.id,
|
|
2603
|
+
message: m.message,
|
|
2604
|
+
queuedAt: m.queuedAt,
|
|
2605
|
+
...m.senderUserId ? { senderUserId: m.senderUserId } : {},
|
|
2606
|
+
...m.senderEmail ? { senderEmail: m.senderEmail } : {},
|
|
2607
|
+
...m.senderDisplayName ? { senderDisplayName: m.senderDisplayName } : {}
|
|
2608
|
+
}));
|
|
2609
|
+
}
|
|
2610
|
+
removeFromQueue(messageId) {
|
|
2611
|
+
return this.messageQueue.removeFromQueue(messageId);
|
|
2612
|
+
}
|
|
2613
|
+
reorderQueue(messageId, newPosition) {
|
|
2614
|
+
return this.messageQueue.reorderQueue(messageId, newPosition);
|
|
2615
|
+
}
|
|
2570
2616
|
async enqueueMessage(request) {
|
|
2571
2617
|
await this.initialized;
|
|
2572
2618
|
return this.messageQueue.enqueue(request);
|
|
2573
2619
|
}
|
|
2620
|
+
emitContextUsage(payload) {
|
|
2621
|
+
const event = {
|
|
2622
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2623
|
+
type: CONTEXT_USAGE_EVENT_TYPE,
|
|
2624
|
+
payload: { ...payload }
|
|
2625
|
+
};
|
|
2626
|
+
this.onEvent(event);
|
|
2627
|
+
return event;
|
|
2628
|
+
}
|
|
2574
2629
|
buildCombinedInstructions(customInstructions) {
|
|
2575
2630
|
const startHooksInstruction = this.getStartHooksInstruction();
|
|
2576
2631
|
const repositorySystemPromptInstruction = this.getRepositorySystemPromptInstruction();
|
|
@@ -2881,6 +2936,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
2881
2936
|
}
|
|
2882
2937
|
}
|
|
2883
2938
|
if (msg.type === "result") {
|
|
2939
|
+
await this.recordContextUsage(response);
|
|
2884
2940
|
this.activePromptStream?.close();
|
|
2885
2941
|
break;
|
|
2886
2942
|
}
|
|
@@ -2902,6 +2958,45 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
2902
2958
|
}
|
|
2903
2959
|
}
|
|
2904
2960
|
}
|
|
2961
|
+
getContextUsageProvider() {
|
|
2962
|
+
return this.systemPromptOverride ? "relay" : "claude";
|
|
2963
|
+
}
|
|
2964
|
+
buildContextUsagePayload(usage) {
|
|
2965
|
+
const maxTokens = Number.isFinite(usage.maxTokens) ? usage.maxTokens : null;
|
|
2966
|
+
const percentage = Number.isFinite(usage.percentage) ? usage.percentage : maxTokens && maxTokens > 0 ? usage.totalTokens / maxTokens * 100 : 0;
|
|
2967
|
+
return {
|
|
2968
|
+
provider: this.getContextUsageProvider(),
|
|
2969
|
+
source: "claude_context",
|
|
2970
|
+
model: usage.model,
|
|
2971
|
+
totalTokens: usage.totalTokens,
|
|
2972
|
+
maxTokens,
|
|
2973
|
+
rawMaxTokens: Number.isFinite(usage.rawMaxTokens) ? usage.rawMaxTokens : maxTokens,
|
|
2974
|
+
percentage,
|
|
2975
|
+
categories: usage.categories.map((category) => ({
|
|
2976
|
+
name: category.name,
|
|
2977
|
+
tokens: category.tokens,
|
|
2978
|
+
percentage: maxTokens && maxTokens > 0 ? category.tokens / maxTokens * 100 : 0,
|
|
2979
|
+
color: category.color,
|
|
2980
|
+
...category.isDeferred !== void 0 ? { isDeferred: category.isDeferred } : {}
|
|
2981
|
+
})),
|
|
2982
|
+
apiUsage: usage.apiUsage ? {
|
|
2983
|
+
inputTokens: usage.apiUsage.input_tokens,
|
|
2984
|
+
outputTokens: usage.apiUsage.output_tokens,
|
|
2985
|
+
cacheCreationInputTokens: usage.apiUsage.cache_creation_input_tokens,
|
|
2986
|
+
cacheReadInputTokens: usage.apiUsage.cache_read_input_tokens
|
|
2987
|
+
} : null,
|
|
2988
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2989
|
+
};
|
|
2990
|
+
}
|
|
2991
|
+
async recordContextUsage(response) {
|
|
2992
|
+
try {
|
|
2993
|
+
const usage = await response.getContextUsage();
|
|
2994
|
+
const event = this.emitContextUsage(this.buildContextUsagePayload(usage));
|
|
2995
|
+
await appendFile4(this.historyFile, JSON.stringify(event) + "\n", "utf-8");
|
|
2996
|
+
} catch (error) {
|
|
2997
|
+
console.warn("[ClaudeManager] Failed to record context usage:", error instanceof Error ? error.message : error);
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
2905
3000
|
/**
|
|
2906
3001
|
* Determines if an error is an OAuth authentication failure from the Claude SDK.
|
|
2907
3002
|
* Known patterns:
|
|
@@ -3971,6 +4066,15 @@ var RelayManager = class {
|
|
|
3971
4066
|
isProcessing() {
|
|
3972
4067
|
return this.inner.isProcessing();
|
|
3973
4068
|
}
|
|
4069
|
+
getQueue() {
|
|
4070
|
+
return this.inner.getQueue();
|
|
4071
|
+
}
|
|
4072
|
+
removeFromQueue(messageId) {
|
|
4073
|
+
return this.inner.removeFromQueue(messageId);
|
|
4074
|
+
}
|
|
4075
|
+
reorderQueue(messageId, newPosition) {
|
|
4076
|
+
return this.inner.reorderQueue(messageId, newPosition);
|
|
4077
|
+
}
|
|
3974
4078
|
};
|
|
3975
4079
|
|
|
3976
4080
|
// src/services/keep-alive-service.ts
|
|
@@ -4221,6 +4325,30 @@ var ChatService = class {
|
|
|
4221
4325
|
});
|
|
4222
4326
|
return result;
|
|
4223
4327
|
}
|
|
4328
|
+
getChatQueue(chatId) {
|
|
4329
|
+
const chat = this.requireChat(chatId);
|
|
4330
|
+
return {
|
|
4331
|
+
chatId,
|
|
4332
|
+
processing: chat.provider.isProcessing(),
|
|
4333
|
+
queue: chat.provider.getQueue()
|
|
4334
|
+
};
|
|
4335
|
+
}
|
|
4336
|
+
removeFromQueue(chatId, messageId) {
|
|
4337
|
+
const chat = this.requireChat(chatId);
|
|
4338
|
+
const success = chat.provider.removeFromQueue(messageId);
|
|
4339
|
+
return {
|
|
4340
|
+
success,
|
|
4341
|
+
queue: chat.provider.getQueue()
|
|
4342
|
+
};
|
|
4343
|
+
}
|
|
4344
|
+
reorderQueue(chatId, messageId, position) {
|
|
4345
|
+
const chat = this.requireChat(chatId);
|
|
4346
|
+
const success = chat.provider.reorderQueue(messageId, position);
|
|
4347
|
+
return {
|
|
4348
|
+
success,
|
|
4349
|
+
queue: chat.provider.getQueue()
|
|
4350
|
+
};
|
|
4351
|
+
}
|
|
4224
4352
|
async deleteChat(chatId) {
|
|
4225
4353
|
const chat = this.requireChat(chatId);
|
|
4226
4354
|
if (chat.persisted.title === DEFAULT_CHAT_TITLES[chat.persisted.provider]) {
|
|
@@ -5112,6 +5240,43 @@ function createV1Routes(deps) {
|
|
|
5112
5240
|
return c.json(jsonError("Failed to interrupt chat", error instanceof Error ? error.message : "Unknown error"), 404);
|
|
5113
5241
|
}
|
|
5114
5242
|
});
|
|
5243
|
+
app2.get("/chats/:chatId/queue", (c) => {
|
|
5244
|
+
try {
|
|
5245
|
+
const result = deps.chatService.getChatQueue(c.req.param("chatId"));
|
|
5246
|
+
return c.json(result);
|
|
5247
|
+
} catch (error) {
|
|
5248
|
+
if (error instanceof ChatNotFoundError) {
|
|
5249
|
+
return c.json(jsonError("Chat not found", error.message), 404);
|
|
5250
|
+
}
|
|
5251
|
+
return c.json(jsonError("Failed to get queue", error instanceof Error ? error.message : "Unknown error"), 500);
|
|
5252
|
+
}
|
|
5253
|
+
});
|
|
5254
|
+
app2.delete("/chats/:chatId/queue/:messageId", (c) => {
|
|
5255
|
+
try {
|
|
5256
|
+
const result = deps.chatService.removeFromQueue(c.req.param("chatId"), c.req.param("messageId"));
|
|
5257
|
+
return c.json(result);
|
|
5258
|
+
} catch (error) {
|
|
5259
|
+
if (error instanceof ChatNotFoundError) {
|
|
5260
|
+
return c.json(jsonError("Chat not found", error.message), 404);
|
|
5261
|
+
}
|
|
5262
|
+
return c.json(jsonError("Failed to remove from queue", error instanceof Error ? error.message : "Unknown error"), 500);
|
|
5263
|
+
}
|
|
5264
|
+
});
|
|
5265
|
+
app2.patch("/chats/:chatId/queue/reorder", async (c) => {
|
|
5266
|
+
try {
|
|
5267
|
+
const body = await c.req.json();
|
|
5268
|
+
if (!body.messageId || typeof body.position !== "number" || !Number.isFinite(body.position)) {
|
|
5269
|
+
return c.json(jsonError("Invalid request", "messageId and position are required"), 400);
|
|
5270
|
+
}
|
|
5271
|
+
const result = deps.chatService.reorderQueue(c.req.param("chatId"), body.messageId, body.position);
|
|
5272
|
+
return c.json(result);
|
|
5273
|
+
} catch (error) {
|
|
5274
|
+
if (error instanceof ChatNotFoundError) {
|
|
5275
|
+
return c.json(jsonError("Chat not found", error.message), 404);
|
|
5276
|
+
}
|
|
5277
|
+
return c.json(jsonError("Failed to reorder queue", error instanceof Error ? error.message : "Unknown error"), 500);
|
|
5278
|
+
}
|
|
5279
|
+
});
|
|
5115
5280
|
app2.get("/repos", async (c) => {
|
|
5116
5281
|
const includeDiffs = c.req.query("includeDiffs") === "true";
|
|
5117
5282
|
const repos = await gitService.listRepos({ includeDiffs });
|