replicas-engine 0.1.700 → 0.1.701

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.
@@ -6837,7 +6837,7 @@ var DEFAULT_CODEX_ARGS = [
6837
6837
  var MIN_CODEX_CLI_VERSION = "0.144.6";
6838
6838
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
6839
6839
  var codexCliVersionEnsured = null;
6840
- var ENGINE_PACKAGE_VERSION = "0.1.700";
6840
+ var ENGINE_PACKAGE_VERSION = "0.1.701";
6841
6841
  var INITIALIZE_METHOD = "initialize";
6842
6842
  var INITIALIZED_NOTIFICATION = "initialized";
6843
6843
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -7,7 +7,7 @@ import {
7
7
  headlessAgentRequestSchema,
8
8
  putPresignedFile,
9
9
  recoverCompletedTurn
10
- } from "./chunk-HMWJSWP2.js";
10
+ } from "./chunk-OI5T44T7.js";
11
11
 
12
12
  // src/headless-agent.ts
13
13
  import { createHash } from "crypto";
package/dist/src/index.js CHANGED
@@ -202,13 +202,13 @@ import {
202
202
  serializeCanvasContentResponse,
203
203
  shellQuotePosix,
204
204
  stripAgentDiagnosticErrors
205
- } from "./chunk-HMWJSWP2.js";
205
+ } from "./chunk-OI5T44T7.js";
206
206
 
207
207
  // src/index.ts
208
208
  import { serve } from "@hono/node-server";
209
209
  import { Hono as Hono2 } from "hono";
210
210
  import { existsSync as existsSync12 } from "fs";
211
- import { randomUUID as randomUUID12 } from "crypto";
211
+ import { randomUUID as randomUUID11 } from "crypto";
212
212
  import { connect } from "net";
213
213
 
214
214
  // src/managers/github-token-manager.ts
@@ -2825,7 +2825,7 @@ async function registerDesktopPreview() {
2825
2825
  import { existsSync as existsSync9 } from "fs";
2826
2826
  import { appendFile as appendFile4, copyFile, mkdir as mkdir17, readFile as readFile17, rename as rename3, rm as rm2 } from "fs/promises";
2827
2827
  import { join as join29 } from "path";
2828
- import { randomUUID as randomUUID10 } from "crypto";
2828
+ import { randomUUID as randomUUID9 } from "crypto";
2829
2829
 
2830
2830
  // ../shared/src/workspace-chat.ts
2831
2831
  var WORKSPACE_CHATS_QUERY_SCHEMA_VERSION = 1;
@@ -3749,6 +3749,7 @@ var CodingAgentManager = class {
3749
3749
  initialSessionId;
3750
3750
  onSaveSessionId;
3751
3751
  onEvent;
3752
+ onUsageUpdate;
3752
3753
  hostOnTurnComplete;
3753
3754
  onProcessingChanged;
3754
3755
  onMessageStarted;
@@ -3759,6 +3760,8 @@ var CodingAgentManager = class {
3759
3760
  this.initialSessionId = options.initialSessionId;
3760
3761
  this.onSaveSessionId = options.onSaveSessionId;
3761
3762
  this.onEvent = options.onEvent;
3763
+ this.onUsageUpdate = options.onUsageUpdate ?? (() => {
3764
+ });
3762
3765
  this.hostOnTurnComplete = options.onTurnComplete;
3763
3766
  this.onProcessingChanged = options.onProcessingChanged ?? (() => {
3764
3767
  });
@@ -8494,6 +8497,7 @@ ${instructions}
8494
8497
  const outputTokens = finiteNumber(update.usage.outputTokens);
8495
8498
  const rawTotalTokens = inputTokens + cacheReadTokens + cacheWriteTokens + outputTokens;
8496
8499
  if (rawTotalTokens <= 0) return;
8500
+ this.onUsageUpdate(update, (/* @__PURE__ */ new Date()).toISOString());
8497
8501
  const maxTokens = CURSOR_COMPOSER_CONTEXT_WINDOW;
8498
8502
  const { totalTokens, totalProcessedTokens } = clampTokensToWindow(rawTotalTokens, maxTokens);
8499
8503
  const categories = [
@@ -8836,8 +8840,10 @@ var DeepseekManager = class extends CodingAgentManager {
8836
8840
  if (frame.type === "session/projection") {
8837
8841
  if (frame.key === "contextPressure" && isRecord2(frame.value)) this.contextPressure = frame.value;
8838
8842
  else if (frame.key === "contextBreakdown" && isRecord2(frame.value)) this.contextBreakdown = frame.value;
8839
- else if (frame.key === "tokenUsage" && isRecord2(frame.value)) this.tokenUsage = frame.value;
8840
- else return;
8843
+ else if (frame.key === "tokenUsage" && isRecord2(frame.value)) {
8844
+ this.tokenUsage = frame.value;
8845
+ this.onUsageUpdate(frame.value, (/* @__PURE__ */ new Date()).toISOString());
8846
+ } else return;
8841
8847
  this.emitDeepseekContextUsage();
8842
8848
  return;
8843
8849
  }
@@ -9187,6 +9193,7 @@ var AcpManager = class extends CodingAgentManager {
9187
9193
  } else if (update.sessionUpdate === "current_mode_update" && this.modes) {
9188
9194
  this.modes = { ...this.modes, currentModeId: update.currentModeId };
9189
9195
  } else if (update.sessionUpdate === "usage_update" && !this.replaying) {
9196
+ const occurredAt = (/* @__PURE__ */ new Date()).toISOString();
9190
9197
  const { used, size } = update;
9191
9198
  this.historyFile.append(this.emitContextUsage({
9192
9199
  provider: this.acp.provider,
@@ -9196,7 +9203,7 @@ var AcpManager = class extends CodingAgentManager {
9196
9203
  maxTokens: size,
9197
9204
  percentage: size > 0 ? used / size * 100 : 0,
9198
9205
  categories: [],
9199
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
9206
+ updatedAt: occurredAt
9200
9207
  }));
9201
9208
  }
9202
9209
  if (!this.replaying) {
@@ -10302,6 +10309,7 @@ var OpencodeManager = class extends CodingAgentManager {
10302
10309
  this.activeLinearForwarder.sendEvent(event);
10303
10310
  }
10304
10311
  recordOpencodePart(part) {
10312
+ if (part.type === "step-finish") this.onUsageUpdate(part, (/* @__PURE__ */ new Date()).toISOString());
10305
10313
  this.recordHistoryEvent(`opencode-part-${part.type}`, { part }, this.historyFile);
10306
10314
  this.forwardOpencodePartToLinear(part);
10307
10315
  }
@@ -10556,6 +10564,7 @@ var PiManager = class extends CodingAgentManager {
10556
10564
  return null;
10557
10565
  }
10558
10566
  handleEvent(event) {
10567
+ if (event.type === "message_end") this.onUsageUpdate(event, (/* @__PURE__ */ new Date()).toISOString());
10559
10568
  const payload = eventPayload(event);
10560
10569
  this.recordHistoryEvent(`pi-${event.type}`, payload, this.historyFile);
10561
10570
  }
@@ -11617,7 +11626,18 @@ var AgentChatActivityTrackerService = class {
11617
11626
  };
11618
11627
 
11619
11628
  // src/analytics/token-usage/agent-token-usage-tracker.ts
11620
- import { randomUUID as randomUUID9 } from "crypto";
11629
+ import { createHash as createHash2 } from "crypto";
11630
+
11631
+ // src/analytics/token-usage/types.ts
11632
+ function calculateCumulativeTokenUsageDelta(current, previous) {
11633
+ if (!previous || current.inputTokens < previous.inputTokens || current.outputTokens < previous.outputTokens || current.cacheReadInputTokens < previous.cacheReadInputTokens || current.cacheWriteInputTokens < previous.cacheWriteInputTokens) return current;
11634
+ return {
11635
+ inputTokens: current.inputTokens - previous.inputTokens,
11636
+ outputTokens: current.outputTokens - previous.outputTokens,
11637
+ cacheReadInputTokens: current.cacheReadInputTokens - previous.cacheReadInputTokens,
11638
+ cacheWriteInputTokens: current.cacheWriteInputTokens - previous.cacheWriteInputTokens
11639
+ };
11640
+ }
11621
11641
 
11622
11642
  // src/analytics/token-usage/claude/parse.ts
11623
11643
  function isClaudeModelUsage(value) {
@@ -11657,9 +11677,6 @@ function parseClaudeResult(payload) {
11657
11677
  };
11658
11678
  }
11659
11679
 
11660
- // src/analytics/token-usage/claude/types.ts
11661
- var CLAUDE_HARNESS = "claude";
11662
-
11663
11680
  // src/analytics/token-usage/claude/index.ts
11664
11681
  function isClaudeTokenUsageCheckpoint(value) {
11665
11682
  return isRecord(value) && isNonEmptyString(value.chatId) && isNonEmptyString(value.sessionId) && isRecord(value.snapshot) && Object.values(value.snapshot).every(isClaudeModelUsage);
@@ -11667,25 +11684,14 @@ function isClaudeTokenUsageCheckpoint(value) {
11667
11684
  function normalizeClaudeTokenUsage(result, previous, context, occurredAt) {
11668
11685
  return Object.entries(result.snapshot).flatMap(([model, currentMetrics]) => {
11669
11686
  const previousMetrics = previous?.[model];
11670
- const usage = !previousMetrics || currentMetrics.inputTokens < previousMetrics.inputTokens || currentMetrics.outputTokens < previousMetrics.outputTokens || currentMetrics.cacheReadInputTokens < previousMetrics.cacheReadInputTokens || currentMetrics.cacheWriteInputTokens < previousMetrics.cacheWriteInputTokens ? currentMetrics : {
11671
- inputTokens: currentMetrics.inputTokens - previousMetrics.inputTokens,
11672
- outputTokens: currentMetrics.outputTokens - previousMetrics.outputTokens,
11673
- cacheReadInputTokens: currentMetrics.cacheReadInputTokens - previousMetrics.cacheReadInputTokens,
11674
- cacheWriteInputTokens: currentMetrics.cacheWriteInputTokens - previousMetrics.cacheWriteInputTokens
11675
- };
11676
- const tokenCounts = {
11677
- inputTokens: usage.inputTokens,
11678
- outputTokens: usage.outputTokens,
11679
- cacheReadInputTokens: usage.cacheReadInputTokens,
11680
- cacheWriteInputTokens: usage.cacheWriteInputTokens
11681
- };
11687
+ const tokenCounts = calculateCumulativeTokenUsageDelta(currentMetrics, previousMetrics);
11682
11688
  const providerCostUsd = currentMetrics.costUsd === void 0 ? void 0 : previousMetrics?.costUsd === void 0 || currentMetrics.costUsd < previousMetrics.costUsd ? currentMetrics.costUsd : currentMetrics.costUsd - previousMetrics.costUsd;
11683
11689
  const pricingProvider = currentMetrics.pricingProvider ?? previousMetrics?.pricingProvider;
11684
11690
  return Object.values(tokenCounts).some((count) => count > 0) ? [{
11685
11691
  ...context,
11686
11692
  model,
11687
11693
  ...tokenCounts,
11688
- harness: CLAUDE_HARNESS,
11694
+ harness: AGENT.CLAUDE,
11689
11695
  occurredAt,
11690
11696
  ...pricingProvider ? { pricingProvider } : {},
11691
11697
  ...providerCostUsd !== void 0 ? { reportedCostUsd: providerCostUsd } : {}
@@ -11725,9 +11731,6 @@ var ClaudeTokenUsageService = class {
11725
11731
  }
11726
11732
  };
11727
11733
 
11728
- // src/analytics/token-usage/codex/index.ts
11729
- import { createHash as createHash2 } from "crypto";
11730
-
11731
11734
  // src/analytics/token-usage/codex/parse.ts
11732
11735
  function isTokenCount(value) {
11733
11736
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
@@ -11762,9 +11765,6 @@ function parseCodexModelReroute(value) {
11762
11765
  return turn ? { ...turn, model: value.toModel } : void 0;
11763
11766
  }
11764
11767
 
11765
- // src/analytics/token-usage/codex/types.ts
11766
- var CODEX_HARNESS = "codex";
11767
-
11768
11768
  // src/analytics/token-usage/codex/index.ts
11769
11769
  var CodexTokenUsageAdapter = class {
11770
11770
  constructor(chatId, getContext, recordEvent) {
@@ -11779,7 +11779,7 @@ var CodexTokenUsageAdapter = class {
11779
11779
  const context = this.getContext();
11780
11780
  if (!context) return;
11781
11781
  this.recordEvent({
11782
- harness: CODEX_HARNESS,
11782
+ harness: AGENT.CODEX,
11783
11783
  type: "turn-started",
11784
11784
  chatId: this.chatId,
11785
11785
  payload: { threadId, turnId },
@@ -11790,7 +11790,7 @@ var CodexTokenUsageAdapter = class {
11790
11790
  const context = this.getContext();
11791
11791
  if (!context) return;
11792
11792
  this.recordEvent({
11793
- harness: CODEX_HARNESS,
11793
+ harness: AGENT.CODEX,
11794
11794
  type: "usage-updated",
11795
11795
  chatId: this.chatId,
11796
11796
  payload: notification,
@@ -11801,7 +11801,7 @@ var CodexTokenUsageAdapter = class {
11801
11801
  onModelRerouted = (notification) => {
11802
11802
  if (!this.getContext()) return;
11803
11803
  this.recordEvent({
11804
- harness: CODEX_HARNESS,
11804
+ harness: AGENT.CODEX,
11805
11805
  type: "model-rerouted",
11806
11806
  chatId: this.chatId,
11807
11807
  payload: notification
@@ -11809,7 +11809,7 @@ var CodexTokenUsageAdapter = class {
11809
11809
  };
11810
11810
  onTurnCompleted = (threadId, turnId) => {
11811
11811
  this.recordEvent({
11812
- harness: CODEX_HARNESS,
11812
+ harness: AGENT.CODEX,
11813
11813
  type: "turn-completed",
11814
11814
  chatId: this.chatId,
11815
11815
  payload: { threadId, turnId }
@@ -11867,8 +11867,6 @@ var CodexTokenUsageService = class {
11867
11867
  }
11868
11868
  }
11869
11869
  }
11870
- restoreCheckpoint() {
11871
- }
11872
11870
  finishTurn(chatId, turn) {
11873
11871
  const key = getTurnKey(turn);
11874
11872
  const tracked = this.turns.get(key);
@@ -11879,9 +11877,11 @@ var CodexTokenUsageService = class {
11879
11877
  return {
11880
11878
  records: [{
11881
11879
  ...tracked.context,
11882
- eventId: createUuidFromHex(createHash2("sha256").update(`codex:${turn.threadId}:${turn.turnId}`).digest("hex")),
11883
- harness: CODEX_HARNESS,
11884
- inputTokens: tracked.latestUsage.inputTokens - tracked.latestUsage.cachedInputTokens - cacheWriteInputTokens,
11880
+ harness: AGENT.CODEX,
11881
+ inputTokens: Math.max(
11882
+ 0,
11883
+ tracked.latestUsage.inputTokens - tracked.latestUsage.cachedInputTokens - cacheWriteInputTokens
11884
+ ),
11885
11885
  outputTokens: tracked.latestUsage.outputTokens,
11886
11886
  cacheReadInputTokens: tracked.latestUsage.cachedInputTokens,
11887
11887
  cacheWriteInputTokens,
@@ -11891,13 +11891,150 @@ var CodexTokenUsageService = class {
11891
11891
  }
11892
11892
  };
11893
11893
 
11894
+ // src/analytics/token-usage/cursor/index.ts
11895
+ function parseCursorTokenUsage(payload) {
11896
+ if (!isRecord(payload) || payload.type !== "turn-ended" || !isRecord(payload.usage)) return void 0;
11897
+ const usage = {
11898
+ inputTokens: payload.usage.inputTokens,
11899
+ outputTokens: payload.usage.outputTokens,
11900
+ cacheReadInputTokens: payload.usage.cacheReadTokens,
11901
+ cacheWriteInputTokens: payload.usage.cacheWriteTokens
11902
+ };
11903
+ return isTokenUsageCounts(usage) ? usage : void 0;
11904
+ }
11905
+ var CursorTokenUsageService = class {
11906
+ turns = /* @__PURE__ */ new Map();
11907
+ record(event) {
11908
+ if (event.type === "usage-updated") {
11909
+ const usage = parseCursorTokenUsage(event.payload);
11910
+ if (!usage) return void 0;
11911
+ const turnId2 = event.turnId ?? event.chatId;
11912
+ this.turns.set(`${event.chatId}\0${turnId2}`, {
11913
+ context: event.context,
11914
+ usage,
11915
+ occurredAt: event.occurredAt
11916
+ });
11917
+ return void 0;
11918
+ }
11919
+ if (event.type !== "chat-ended") return void 0;
11920
+ const turnId = event.turnId ?? event.chatId;
11921
+ const key = `${event.chatId}\0${turnId}`;
11922
+ const turn = this.turns.get(key);
11923
+ if (!turn) return void 0;
11924
+ this.turns.delete(key);
11925
+ const record = {
11926
+ ...turn.context,
11927
+ harness: AGENT.CURSOR,
11928
+ ...turn.usage,
11929
+ occurredAt: turn.occurredAt
11930
+ };
11931
+ return { records: [record] };
11932
+ }
11933
+ };
11934
+
11935
+ // src/analytics/token-usage/deepseek/index.ts
11936
+ function parseDeepseekTokenUsage(payload) {
11937
+ if (!isRecord(payload)) return void 0;
11938
+ const source = isRecord(payload.totals) ? payload.totals : payload;
11939
+ const snapshot = {
11940
+ inputTokens: source.uncachedInputTokens,
11941
+ outputTokens: source.outputTokens,
11942
+ cacheReadInputTokens: source.cacheReadTokens,
11943
+ cacheWriteInputTokens: source.cacheWriteTokens
11944
+ };
11945
+ return isTokenUsageCounts(snapshot) ? snapshot : void 0;
11946
+ }
11947
+ var DeepseekTokenUsageService = class {
11948
+ snapshots = /* @__PURE__ */ new Map();
11949
+ record(event) {
11950
+ if (event.type !== "usage-updated") return void 0;
11951
+ const current = parseDeepseekTokenUsage(event.payload);
11952
+ if (!current) return void 0;
11953
+ const previous = this.snapshots.get(event.chatId);
11954
+ this.snapshots.set(event.chatId, current);
11955
+ const usage = calculateCumulativeTokenUsageDelta(current, previous);
11956
+ const records = Object.values(usage).some((count) => count > 0) ? [{ ...event.context, harness: AGENT.DEEPSEEK, ...usage, occurredAt: event.occurredAt }] : [];
11957
+ return {
11958
+ records,
11959
+ checkpoint: { chatId: event.chatId, snapshot: current }
11960
+ };
11961
+ }
11962
+ restoreCheckpoint(value) {
11963
+ if (!isRecord(value) || !isNonEmptyString(value.chatId) || !isTokenUsageCounts(value.snapshot)) return;
11964
+ this.snapshots.set(value.chatId, value.snapshot);
11965
+ }
11966
+ };
11967
+
11968
+ // src/analytics/token-usage/opencode/index.ts
11969
+ function parseOpencodeTokenUsage(payload) {
11970
+ if (!isRecord(payload) || payload.type !== "step-finish" || !isRecord(payload.tokens) || !isRecord(payload.tokens.cache)) return void 0;
11971
+ const usage = {
11972
+ inputTokens: payload.tokens.input,
11973
+ outputTokens: payload.tokens.output,
11974
+ cacheReadInputTokens: payload.tokens.cache.read,
11975
+ cacheWriteInputTokens: payload.tokens.cache.write
11976
+ };
11977
+ return isTokenUsageCounts(usage) ? usage : void 0;
11978
+ }
11979
+ var OpencodeTokenUsageService = class {
11980
+ record(event) {
11981
+ if (event.type !== "usage-updated") return void 0;
11982
+ const usage = parseOpencodeTokenUsage(event.payload);
11983
+ if (!usage) return void 0;
11984
+ const record = {
11985
+ ...event.context,
11986
+ harness: AGENT.OPENCODE,
11987
+ ...usage,
11988
+ occurredAt: event.occurredAt
11989
+ };
11990
+ return { records: [record] };
11991
+ }
11992
+ };
11993
+
11994
+ // src/analytics/token-usage/pi/index.ts
11995
+ function parsePiTokenUsage(payload) {
11996
+ if (!isRecord(payload) || payload.type !== "message_end" || !isRecord(payload.message) || payload.message.role !== "assistant" || !isRecord(payload.message.usage)) return void 0;
11997
+ const usage = {
11998
+ inputTokens: payload.message.usage.input,
11999
+ outputTokens: payload.message.usage.output,
12000
+ cacheReadInputTokens: payload.message.usage.cacheRead,
12001
+ cacheWriteInputTokens: payload.message.usage.cacheWrite
12002
+ };
12003
+ if (!isTokenUsageCounts(usage)) return void 0;
12004
+ const model = isNonEmptyString(payload.message.responseModel) ? payload.message.responseModel : isNonEmptyString(payload.message.model) ? payload.message.model : void 0;
12005
+ return { model, usage };
12006
+ }
12007
+ var PiTokenUsageService = class {
12008
+ record(event) {
12009
+ if (event.type !== "usage-updated") return void 0;
12010
+ const result = parsePiTokenUsage(event.payload);
12011
+ if (!result) return void 0;
12012
+ const record = {
12013
+ ...event.context,
12014
+ harness: AGENT.PI,
12015
+ model: result.model ?? event.context.model,
12016
+ ...result.usage,
12017
+ occurredAt: event.occurredAt
12018
+ };
12019
+ return { records: [record] };
12020
+ }
12021
+ };
12022
+
11894
12023
  // src/analytics/token-usage/agent-token-usage-factory.ts
11895
12024
  function createAgentTokenUsageService(harness) {
11896
12025
  switch (harness) {
11897
- case CLAUDE_HARNESS:
12026
+ case AGENT.CLAUDE:
11898
12027
  return new ClaudeTokenUsageService();
11899
- case CODEX_HARNESS:
12028
+ case AGENT.CODEX:
11900
12029
  return new CodexTokenUsageService();
12030
+ case AGENT.CURSOR:
12031
+ return new CursorTokenUsageService();
12032
+ case AGENT.DEEPSEEK:
12033
+ return new DeepseekTokenUsageService();
12034
+ case AGENT.OPENCODE:
12035
+ return new OpencodeTokenUsageService();
12036
+ case AGENT.PI:
12037
+ return new PiTokenUsageService();
11901
12038
  default:
11902
12039
  return void 0;
11903
12040
  }
@@ -11924,7 +12061,7 @@ var AgentTokenUsageTracker = class {
11924
12061
  });
11925
12062
  for (const batch of this.buffer.readStoredRecords()) {
11926
12063
  if (batch.checkpoint !== void 0) {
11927
- this.getService(batch.harness)?.restoreCheckpoint(batch.checkpoint);
12064
+ this.getService(batch.harness)?.restoreCheckpoint?.(batch.checkpoint);
11928
12065
  }
11929
12066
  }
11930
12067
  }
@@ -11945,6 +12082,10 @@ var AgentTokenUsageTracker = class {
11945
12082
  };
11946
12083
  }
11947
12084
  noteAgentEvent(chatId, event) {
12085
+ if (event.type !== "claude-result") return;
12086
+ this.noteUsage(chatId, event.payload, event.timestamp);
12087
+ }
12088
+ noteUsage(chatId, payload, occurredAt) {
11948
12089
  const context = this.activeTurns.get(chatId);
11949
12090
  const tokenUsageContext = this.getTokenUsageContext(chatId);
11950
12091
  if (!context || !tokenUsageContext) return;
@@ -11952,9 +12093,10 @@ var AgentTokenUsageTracker = class {
11952
12093
  harness: context.provider,
11953
12094
  type: "usage-updated",
11954
12095
  chatId,
11955
- payload: event.payload,
12096
+ turnId: context.turnId,
12097
+ payload,
11956
12098
  context: tokenUsageContext,
11957
- occurredAt: event.timestamp
12099
+ occurredAt
11958
12100
  });
11959
12101
  }
11960
12102
  endTurn(chatId) {
@@ -11963,7 +12105,8 @@ var AgentTokenUsageTracker = class {
11963
12105
  this.recordEvent({
11964
12106
  harness: context.provider,
11965
12107
  type: "chat-ended",
11966
- chatId
12108
+ chatId,
12109
+ turnId: context.turnId
11967
12110
  });
11968
12111
  this.activeTurns.delete(chatId);
11969
12112
  }
@@ -11980,7 +12123,13 @@ var AgentTokenUsageTracker = class {
11980
12123
  harness: event.harness,
11981
12124
  records: batch.records.map((record) => ({
11982
12125
  ...record,
11983
- eventId: record.eventId ?? randomUUID9()
12126
+ eventId: record.eventId ?? createUuidFromHex(createHash2("sha256").update(JSON.stringify([
12127
+ event.harness,
12128
+ event.type,
12129
+ event.chatId,
12130
+ event.turnId ?? "",
12131
+ record
12132
+ ])).digest("hex"))
11984
12133
  })),
11985
12134
  checkpoint: batch.checkpoint
11986
12135
  });
@@ -12784,7 +12933,7 @@ var ChatService = class {
12784
12933
  throw new ChatNotFoundError(parentChatId);
12785
12934
  }
12786
12935
  const persisted = {
12787
- id: request.id ?? randomUUID10(),
12936
+ id: request.id ?? randomUUID9(),
12788
12937
  provider: request.provider,
12789
12938
  title,
12790
12939
  createdAt: now,
@@ -13266,6 +13415,9 @@ var ChatService = class {
13266
13415
  const onProviderEvent = (event) => {
13267
13416
  this.handleTurnEvent(persisted.id, event);
13268
13417
  };
13418
+ const onProviderUsage = (payload, occurredAt) => {
13419
+ this.agentTokenUsageTracker.noteUsage(persisted.id, payload, occurredAt);
13420
+ };
13269
13421
  const onMessageStarted = (message) => this.handleTurnStarted(persisted.id, message);
13270
13422
  const onProcessingChanged = (processing) => {
13271
13423
  if (processing) return;
@@ -13324,7 +13476,8 @@ var ChatService = class {
13324
13476
  onTurnComplete: onProviderTurnComplete,
13325
13477
  onEvent: onProviderEvent,
13326
13478
  onProcessingChanged,
13327
- onMessageStarted
13479
+ onMessageStarted,
13480
+ onUsageUpdate: onProviderUsage
13328
13481
  });
13329
13482
  } else if (persisted.provider === "deepseek") {
13330
13483
  provider = new DeepseekManager({
@@ -13335,7 +13488,8 @@ var ChatService = class {
13335
13488
  onTurnComplete: onProviderTurnComplete,
13336
13489
  onEvent: onProviderEvent,
13337
13490
  onProcessingChanged,
13338
- onMessageStarted
13491
+ onMessageStarted,
13492
+ onUsageUpdate: onProviderUsage
13339
13493
  });
13340
13494
  } else if (persisted.provider === "fx") {
13341
13495
  provider = new FxManager({
@@ -13368,7 +13522,8 @@ var ChatService = class {
13368
13522
  onTurnComplete: onProviderTurnComplete,
13369
13523
  onEvent: onProviderEvent,
13370
13524
  onProcessingChanged,
13371
- onMessageStarted
13525
+ onMessageStarted,
13526
+ onUsageUpdate: onProviderUsage
13372
13527
  });
13373
13528
  } else if (persisted.provider === "pi") {
13374
13529
  provider = new PiManager({
@@ -13379,7 +13534,8 @@ var ChatService = class {
13379
13534
  onTurnComplete: onProviderTurnComplete,
13380
13535
  onEvent: onProviderEvent,
13381
13536
  onProcessingChanged,
13382
- onMessageStarted
13537
+ onMessageStarted,
13538
+ onUsageUpdate: onProviderUsage
13383
13539
  });
13384
13540
  } else {
13385
13541
  const codexTokenUsage = new CodexTokenUsageAdapter(
@@ -13665,7 +13821,7 @@ var ChatService = class {
13665
13821
  }
13666
13822
  async publish(input) {
13667
13823
  const event = {
13668
- id: randomUUID10(),
13824
+ id: randomUUID9(),
13669
13825
  ts: (/* @__PURE__ */ new Date()).toISOString(),
13670
13826
  ...input
13671
13827
  };
@@ -14407,7 +14563,7 @@ ${combinedScript}` : combinedScript;
14407
14563
  }
14408
14564
 
14409
14565
  // src/services/terminal-service.ts
14410
- import { randomUUID as randomUUID11 } from "crypto";
14566
+ import { randomUUID as randomUUID10 } from "crypto";
14411
14567
  import { existsSync as existsSync11 } from "fs";
14412
14568
  import { spawn as spawn7 } from "node-pty";
14413
14569
  var MAX_REPLAY_CHARS = 1024 * 1024;
@@ -14426,7 +14582,7 @@ var TerminalService = class {
14426
14582
  code: "limit"
14427
14583
  });
14428
14584
  }
14429
- const id = randomUUID11();
14585
+ const id = randomUUID10();
14430
14586
  const shell = process.env.SHELL && existsSync11(process.env.SHELL) ? process.env.SHELL : "/bin/bash";
14431
14587
  const pty = spawn7(shell, ["-l"], {
14432
14588
  name: "xterm-256color",
@@ -15674,7 +15830,7 @@ function startStatusBroadcaster() {
15674
15830
  if (serialized !== previousRepoStatus) {
15675
15831
  previousRepoStatus = serialized;
15676
15832
  eventService.publish({
15677
- id: randomUUID12(),
15833
+ id: randomUUID11(),
15678
15834
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15679
15835
  type: "repo.status.changed",
15680
15836
  payload: { repos }
@@ -15695,7 +15851,7 @@ function startStatusBroadcaster() {
15695
15851
  if (engineStatusJson !== previousEngineStatus) {
15696
15852
  previousEngineStatus = engineStatusJson;
15697
15853
  eventService.publish({
15698
- id: randomUUID12(),
15854
+ id: randomUUID11(),
15699
15855
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15700
15856
  type: "engine.status.changed",
15701
15857
  payload: { status: engineStatus }
@@ -15714,7 +15870,7 @@ function startStatusBroadcaster() {
15714
15870
  previousHookStatus = hookSnapshot;
15715
15871
  if (!lastHooksRunning && hooksRunning) {
15716
15872
  eventService.publish({
15717
- id: randomUUID12(),
15873
+ id: randomUUID11(),
15718
15874
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15719
15875
  type: "hooks.started",
15720
15876
  payload: { running: true, completed: false }
@@ -15723,7 +15879,7 @@ function startStatusBroadcaster() {
15723
15879
  }
15724
15880
  if (hooksRunning) {
15725
15881
  eventService.publish({
15726
- id: randomUUID12(),
15882
+ id: randomUUID11(),
15727
15883
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15728
15884
  type: "hooks.progress",
15729
15885
  payload: { running: true, completed: false }
@@ -15732,7 +15888,7 @@ function startStatusBroadcaster() {
15732
15888
  }
15733
15889
  if (lastHooksRunning && !hooksRunning && hooksCompleted && !hooksFailed) {
15734
15890
  eventService.publish({
15735
- id: randomUUID12(),
15891
+ id: randomUUID11(),
15736
15892
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15737
15893
  type: "hooks.completed",
15738
15894
  payload: { running: false, completed: true }
@@ -15741,7 +15897,7 @@ function startStatusBroadcaster() {
15741
15897
  }
15742
15898
  if (lastHooksRunning && !hooksRunning && hooksFailed) {
15743
15899
  eventService.publish({
15744
- id: randomUUID12(),
15900
+ id: randomUUID11(),
15745
15901
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15746
15902
  type: "hooks.failed",
15747
15903
  payload: { running: false, completed: hooksCompleted }
@@ -15749,7 +15905,7 @@ function startStatusBroadcaster() {
15749
15905
  });
15750
15906
  }
15751
15907
  eventService.publish({
15752
- id: randomUUID12(),
15908
+ id: randomUUID11(),
15753
15909
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15754
15910
  type: "hooks.status",
15755
15911
  payload: {
@@ -15804,20 +15960,20 @@ serve(
15804
15960
  }
15805
15961
  const repos = await gitService.listRepos();
15806
15962
  await eventService.publish({
15807
- id: randomUUID12(),
15963
+ id: randomUUID11(),
15808
15964
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15809
15965
  type: "repo.discovered",
15810
15966
  payload: { repos }
15811
15967
  });
15812
15968
  const repoStatuses = await gitService.listRepos();
15813
15969
  await eventService.publish({
15814
- id: randomUUID12(),
15970
+ id: randomUUID11(),
15815
15971
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15816
15972
  type: "repo.status.changed",
15817
15973
  payload: { repos: repoStatuses }
15818
15974
  });
15819
15975
  await eventService.publish({
15820
- id: randomUUID12(),
15976
+ id: randomUUID11(),
15821
15977
  ts: (/* @__PURE__ */ new Date()).toISOString(),
15822
15978
  type: "engine.ready",
15823
15979
  payload: { version: "v1" }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.700",
3
+ "version": "0.1.701",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",