replicas-engine 0.1.578 → 0.1.580

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 CHANGED
@@ -8598,8 +8598,11 @@ var MessageQueueService = class {
8598
8598
  processing = false;
8599
8599
  messageIdCounter = 0;
8600
8600
  processMessage;
8601
- constructor(processMessage) {
8601
+ onProcessingChanged;
8602
+ constructor(processMessage, onProcessingChanged = () => {
8603
+ }) {
8602
8604
  this.processMessage = processMessage;
8605
+ this.onProcessingChanged = onProcessingChanged;
8603
8606
  }
8604
8607
  generateMessageId() {
8605
8608
  return `msg_${Date.now()}_${++this.messageIdCounter}`;
@@ -8655,12 +8658,16 @@ var MessageQueueService = class {
8655
8658
  }
8656
8659
  async startProcessing(queuedMessage) {
8657
8660
  this.processing = true;
8661
+ this.onProcessingChanged(true);
8658
8662
  try {
8659
8663
  await this.processMessage(queuedMessage);
8660
8664
  } catch (error) {
8661
8665
  console.error("[MessageQueue] Error processing message:", error);
8662
8666
  } finally {
8663
8667
  this.processing = false;
8668
+ if (this.queue.length === 0) {
8669
+ this.onProcessingChanged(false);
8670
+ }
8664
8671
  await this.processNextInQueue();
8665
8672
  }
8666
8673
  }
@@ -8767,6 +8774,7 @@ var CodingAgentManager = class {
8767
8774
  onSaveSessionId;
8768
8775
  onEvent;
8769
8776
  hostOnTurnComplete;
8777
+ onProcessingChanged;
8770
8778
  compacting = false;
8771
8779
  constructor(options) {
8772
8780
  this.workingDirectory = options.workingDirectory ?? ENGINE_ENV.WORKSPACE_ROOT;
@@ -8774,6 +8782,8 @@ var CodingAgentManager = class {
8774
8782
  this.onSaveSessionId = options.onSaveSessionId;
8775
8783
  this.onEvent = options.onEvent;
8776
8784
  this.hostOnTurnComplete = options.onTurnComplete;
8785
+ this.onProcessingChanged = options.onProcessingChanged ?? (() => {
8786
+ });
8777
8787
  }
8778
8788
  onTurnComplete = async () => {
8779
8789
  if (this.compacting) {
@@ -8815,7 +8825,7 @@ var CodingAgentManager = class {
8815
8825
  historyFile.append(event);
8816
8826
  }
8817
8827
  initializeManager(processMessage) {
8818
- this.messageQueue = new MessageQueueService(processMessage);
8828
+ this.messageQueue = new MessageQueueService(processMessage, this.onProcessingChanged);
8819
8829
  this.initialized = this.initialize();
8820
8830
  }
8821
8831
  async interrupt() {
@@ -9726,8 +9736,11 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
9726
9736
  }
9727
9737
  async interruptActiveTurn() {
9728
9738
  this.pendingInterrupt = true;
9729
- if (this.activeQuery) {
9730
- await this.activeQuery.interrupt();
9739
+ const query2 = this.activeQuery;
9740
+ if (query2) {
9741
+ const taskIds = [...this.activeBackgroundTasks];
9742
+ await Promise.allSettled(taskIds.map((taskId) => query2.stopTask(taskId)));
9743
+ await query2.interrupt();
9731
9744
  }
9732
9745
  await this.abortAllPendingToolInputs();
9733
9746
  }
@@ -9751,7 +9764,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
9751
9764
  return this.authRetrying;
9752
9765
  }
9753
9766
  isProcessing() {
9754
- return super.isProcessing() || isClaudeSessionActive(this.sessionActivity);
9767
+ return super.isProcessing() || isClaudeSessionActive(this.sessionActivity) || this.activeBackgroundTasks.size > 0;
9755
9768
  }
9756
9769
  hasActiveBackgroundTasks() {
9757
9770
  return this.activeBackgroundTasks.size > 0;
@@ -10437,6 +10450,10 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
10437
10450
  }
10438
10451
  static updateBackgroundTaskState(message, activeTasks) {
10439
10452
  if (message.type !== "system") return;
10453
+ if (message.subtype === "session_state_changed" && message.state === "idle") {
10454
+ activeTasks.clear();
10455
+ return;
10456
+ }
10440
10457
  if (message.subtype === "background_tasks_changed") {
10441
10458
  activeTasks.clear();
10442
10459
  for (const task of message.tasks) {
@@ -10879,7 +10896,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
10879
10896
  var MIN_CODEX_CLI_VERSION = "0.144.6";
10880
10897
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
10881
10898
  var codexCliVersionEnsured = null;
10882
- var ENGINE_PACKAGE_VERSION = "0.1.578";
10899
+ var ENGINE_PACKAGE_VERSION = "0.1.580";
10883
10900
  var INITIALIZE_METHOD = "initialize";
10884
10901
  var INITIALIZED_NOTIFICATION = "initialized";
10885
10902
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -13805,6 +13822,7 @@ var OpencodeManager = class extends CodingAgentManager {
13805
13822
  nonAssistantMessageIds = /* @__PURE__ */ new Set();
13806
13823
  activeLinearForwarder = null;
13807
13824
  forwardedLinearPartKeys = /* @__PURE__ */ new Set();
13825
+ handledAccountRateLimit = false;
13808
13826
  modelVariants = /* @__PURE__ */ new Map();
13809
13827
  handledPermissionRequestIds = /* @__PURE__ */ new Set();
13810
13828
  pendingPermissionRequestIds = /* @__PURE__ */ new Set();
@@ -13827,18 +13845,20 @@ var OpencodeManager = class extends CodingAgentManager {
13827
13845
  return this.historyFile;
13828
13846
  }
13829
13847
  async interruptActiveTurn() {
13830
- this.activeAbortController?.abort();
13831
- if (this.client && this.sessionId) {
13832
- try {
13833
- await this.client.session.abort(
13834
- { sessionID: this.sessionId, directory: this.workingDirectory },
13835
- { throwOnError: true }
13836
- );
13837
- } catch (error) {
13838
- console.error("[OpencodeManager] Failed to abort Opencode session:", error);
13839
- }
13848
+ try {
13849
+ await this.abortActiveTurn();
13850
+ } catch (error) {
13851
+ console.error("[OpencodeManager] Failed to abort Opencode session:", error);
13840
13852
  }
13841
13853
  }
13854
+ async abortActiveTurn() {
13855
+ this.activeAbortController?.abort();
13856
+ if (!this.client || !this.sessionId) return;
13857
+ await this.client.session.abort(
13858
+ { sessionID: this.sessionId, directory: this.workingDirectory },
13859
+ { throwOnError: true }
13860
+ );
13861
+ }
13842
13862
  async getHistory() {
13843
13863
  await this.historyFile.flush();
13844
13864
  const history = await this.historyFile.load();
@@ -14000,6 +14020,7 @@ var OpencodeManager = class extends CodingAgentManager {
14000
14020
  const controller = new AbortController();
14001
14021
  const linearSessionId = ENGINE_ENV.REPLICAS_LINEAR_SESSION_ID;
14002
14022
  const linearForwarder = new LinearEventForwarder(linearSessionId);
14023
+ this.handledAccountRateLimit = false;
14003
14024
  this.activeAbortController = controller;
14004
14025
  this.activeLinearForwarder = linearForwarder;
14005
14026
  this.forwardedLinearPartKeys.clear();
@@ -14087,6 +14108,11 @@ var OpencodeManager = class extends CodingAgentManager {
14087
14108
  return;
14088
14109
  }
14089
14110
  if (event.type === "message.updated") this.recordOpencodeMessageRole(payload);
14111
+ if (event.type === "session.status") {
14112
+ this.handleAccountRateLimit(payload).catch((error) => {
14113
+ console.error("[OpencodeManager] Failed to stop account-rate-limited turn:", error);
14114
+ });
14115
+ }
14090
14116
  if (event.type === "session.next.tool.input.ended") {
14091
14117
  const callId = typeof payload.callID === "string" ? payload.callID : void 0;
14092
14118
  if (callId && typeof payload.text === "string") {
@@ -14106,6 +14132,15 @@ var OpencodeManager = class extends CodingAgentManager {
14106
14132
  if (this.recordOpencodeNextPart(event.type, payload)) return;
14107
14133
  this.recordHistoryEvent(`opencode-${event.type}`, payload, this.historyFile);
14108
14134
  }
14135
+ async handleAccountRateLimit(payload) {
14136
+ const status = isRecord4(payload.status) ? payload.status : null;
14137
+ const action = isRecord4(status?.action) ? status.action : null;
14138
+ if (status?.type !== "retry" || action?.reason !== "account_rate_limit" || this.handledAccountRateLimit) return;
14139
+ this.handledAccountRateLimit = true;
14140
+ const message = typeof status.message === "string" ? status.message : typeof action.message === "string" ? action.message : "OpenCode Go usage limit reached.";
14141
+ this.recordHistoryEvent("opencode-error", { message, code: "account_rate_limit" }, this.historyFile);
14142
+ await this.abortActiveTurn();
14143
+ }
14109
14144
  async respondToOpencodePermission(type, payload) {
14110
14145
  if (!this.client) return;
14111
14146
  const requestId = typeof payload.id === "string" ? payload.id : void 0;
@@ -14204,13 +14239,7 @@ var OpencodeManager = class extends CodingAgentManager {
14204
14239
  historyFile: this.historyFile,
14205
14240
  recordHistoryEvent: this.recordHistoryEvent.bind(this)
14206
14241
  });
14207
- this.activeAbortController?.abort();
14208
- if (this.client && this.sessionId) {
14209
- await this.client.session.abort(
14210
- { sessionID: this.sessionId, directory: this.workingDirectory },
14211
- { throwOnError: true }
14212
- );
14213
- }
14242
+ await this.abortActiveTurn();
14214
14243
  this.handledToolCallIds.add(toolUseId);
14215
14244
  } finally {
14216
14245
  this.pendingToolCallIds.delete(toolUseId);
@@ -15987,9 +16016,12 @@ function acceptedEventInCodexTranscript(acceptedEvent, transcript) {
15987
16016
  }
15988
16017
  var LAST_MESSAGE_PREVIEW_MAX = 200;
15989
16018
  var MAX_ACCEPTED_SEND_RESPONSES = 50;
15990
- function isChatActive(chat) {
16019
+ function hasActiveAgentWork(chat) {
15991
16020
  return chat.provider.isProcessing() || (chat.provider.hasActiveBackgroundTasks?.() ?? false);
15992
16021
  }
16022
+ function hasActiveChatTurn(chat) {
16023
+ return chat.hasActiveTurn || chat.pendingMessageIds.length > 0;
16024
+ }
15993
16025
  function isPersistedChat(value) {
15994
16026
  if (!isRecord4(value)) {
15995
16027
  return false;
@@ -16030,7 +16062,7 @@ var ChatService = class {
16030
16062
  this.workingDirectory = workingDirectory;
16031
16063
  this.analyticsService = analyticsService2;
16032
16064
  keepAliveService.setActivityCheck(
16033
- () => [...this.chats.values()].some((chat) => !chat.persisted.deletedAt && isChatActive(chat))
16065
+ () => [...this.chats.values()].some((chat) => !chat.persisted.deletedAt && hasActiveAgentWork(chat))
16034
16066
  );
16035
16067
  }
16036
16068
  workingDirectory;
@@ -16273,7 +16305,7 @@ var ChatService = class {
16273
16305
  const chat = this.requireChat(chatId);
16274
16306
  return {
16275
16307
  chatId,
16276
- processing: chat.provider.isProcessing(),
16308
+ processing: hasActiveChatTurn(chat),
16277
16309
  queue: chat.provider.getQueue()
16278
16310
  };
16279
16311
  }
@@ -16409,7 +16441,7 @@ var ChatService = class {
16409
16441
  getProcessingCount() {
16410
16442
  let count = 0;
16411
16443
  for (const chat of this.chats.values()) {
16412
- if (!chat.persisted.deletedAt && isChatActive(chat)) {
16444
+ if (!chat.persisted.deletedAt && hasActiveAgentWork(chat)) {
16413
16445
  count += 1;
16414
16446
  }
16415
16447
  }
@@ -16451,6 +16483,16 @@ var ChatService = class {
16451
16483
  const onProviderEvent = (event) => {
16452
16484
  this.handleTurnEvent(persisted.id, event);
16453
16485
  };
16486
+ const onProcessingChanged = (processing) => {
16487
+ if (processing) return;
16488
+ const chat = this.getRuntimeChat(persisted.id);
16489
+ if (!chat) return;
16490
+ this.publish({
16491
+ type: "chat.updated",
16492
+ payload: { chat: this.toSummary(chat) }
16493
+ }).catch(() => {
16494
+ });
16495
+ };
16454
16496
  if (persisted.parentChatId === void 0) {
16455
16497
  persisted.parentChatId = null;
16456
16498
  }
@@ -16462,7 +16504,8 @@ var ChatService = class {
16462
16504
  initialSessionId: persisted.providerSessionId,
16463
16505
  onSaveSessionId: saveSession,
16464
16506
  onTurnComplete: onProviderTurnComplete,
16465
- onEvent: onProviderEvent
16507
+ onEvent: onProviderEvent,
16508
+ onProcessingChanged
16466
16509
  });
16467
16510
  } else if (persisted.provider === "relay") {
16468
16511
  provider = new RelayManager({
@@ -16472,6 +16515,7 @@ var ChatService = class {
16472
16515
  onSaveSessionId: saveSession,
16473
16516
  onTurnComplete: onProviderTurnComplete,
16474
16517
  onEvent: onProviderEvent,
16518
+ onProcessingChanged,
16475
16519
  chatId: persisted.id,
16476
16520
  codexAvailable: isCodexAvailable(),
16477
16521
  opencodeAvailable: isOpencodeAvailable(),
@@ -16485,7 +16529,8 @@ var ChatService = class {
16485
16529
  initialSessionId: persisted.providerSessionId,
16486
16530
  onSaveSessionId: saveSession,
16487
16531
  onTurnComplete: onProviderTurnComplete,
16488
- onEvent: onProviderEvent
16532
+ onEvent: onProviderEvent,
16533
+ onProcessingChanged
16489
16534
  });
16490
16535
  } else if (persisted.provider === "opencode") {
16491
16536
  provider = new OpencodeManager({
@@ -16494,7 +16539,8 @@ var ChatService = class {
16494
16539
  initialSessionId: persisted.providerSessionId,
16495
16540
  onSaveSessionId: saveSession,
16496
16541
  onTurnComplete: onProviderTurnComplete,
16497
- onEvent: onProviderEvent
16542
+ onEvent: onProviderEvent,
16543
+ onProcessingChanged
16498
16544
  });
16499
16545
  } else if (persisted.provider === "pi") {
16500
16546
  provider = new PiManager({
@@ -16503,7 +16549,8 @@ var ChatService = class {
16503
16549
  initialSessionId: persisted.providerSessionId,
16504
16550
  onSaveSessionId: saveSession,
16505
16551
  onTurnComplete: onProviderTurnComplete,
16506
- onEvent: onProviderEvent
16552
+ onEvent: onProviderEvent,
16553
+ onProcessingChanged
16507
16554
  });
16508
16555
  } else {
16509
16556
  provider = new CodexAspManager({
@@ -16512,7 +16559,8 @@ var ChatService = class {
16512
16559
  initialSessionId: persisted.providerSessionId,
16513
16560
  onSaveSessionId: saveSession,
16514
16561
  onTurnComplete: onProviderTurnComplete,
16515
- onEvent: onProviderEvent
16562
+ onEvent: onProviderEvent,
16563
+ onProcessingChanged
16516
16564
  });
16517
16565
  }
16518
16566
  return {
@@ -16541,7 +16589,8 @@ var ChatService = class {
16541
16589
  title: chat.persisted.title,
16542
16590
  createdAt: chat.persisted.createdAt,
16543
16591
  updatedAt: chat.persisted.updatedAt,
16544
- processing: isChatActive(chat),
16592
+ processing: hasActiveChatTurn(chat),
16593
+ activityTrackingVersion: 1,
16545
16594
  awaitingInput: chat.provider.isAwaitingInput?.() ?? false,
16546
16595
  isCompacting: chat.provider.isCompacting?.() ?? false,
16547
16596
  isAuthRetrying: chat.provider.isAuthRetrying?.() ?? false,
@@ -16660,7 +16709,7 @@ var ChatService = class {
16660
16709
  payload: {
16661
16710
  chatId,
16662
16711
  isComplete: true,
16663
- processing: chat.provider.hasActiveBackgroundTasks?.() ?? false,
16712
+ processing: false,
16664
16713
  completedAt
16665
16714
  }
16666
16715
  }).catch(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.578",
3
+ "version": "0.1.580",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",