replicas-engine 0.1.1360 → 0.1.1363

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.
@@ -8,9 +8,9 @@ import {
8
8
  listRunningCodexModels,
9
9
  restartCodexAspHost,
10
10
  restartCodexAspHostIfRunning
11
- } from "./chunk-R4KV2YTR.js";
11
+ } from "./chunk-2WJHTBM5.js";
12
12
  import "./chunk-YQI4XGIX.js";
13
- import "./chunk-64HL4Y7U.js";
13
+ import "./chunk-B4JWWQR5.js";
14
14
  import "./chunk-QCX45VR3.js";
15
15
  import "./chunk-UZSNFLDQ.js";
16
16
  import "./chunk-TQ6XAXNA.js";
@@ -14,7 +14,7 @@ import {
14
14
  import {
15
15
  AppServerProcess,
16
16
  buildCodexAgentEnv
17
- } from "./chunk-64HL4Y7U.js";
17
+ } from "./chunk-B4JWWQR5.js";
18
18
  import {
19
19
  SUBPROCESS_MAX_BUFFER,
20
20
  execFileAsync
@@ -319,7 +319,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
319
319
  await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
320
320
  await this.applyCredentialsResponse(data);
321
321
  setAgentCredentialSnapshot("codex", data);
322
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-V53SLUTD.js");
322
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-UNKNQSUT.js");
323
323
  await restartCodexAspHostIfRunning2();
324
324
  });
325
325
  await this.start(true);
@@ -341,7 +341,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
341
341
  const accountChanged = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex?.credentialId !== data.credentialId;
342
342
  await this.applyCredentialsResponse(data);
343
343
  if (restartOnChange && (accountChanged || CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index]))) {
344
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-V53SLUTD.js");
344
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-UNKNQSUT.js");
345
345
  await restartCodexAspHostIfRunning2();
346
346
  }
347
347
  setAgentCredentialSnapshot("codex", data);
@@ -240,7 +240,7 @@ function getCodexModelProvider(method) {
240
240
  if (method === "foundry") return "azure";
241
241
  return method === "ollama" || method === "openai-compatible" ? "replicas_openai_compatible" : "openai";
242
242
  }
243
- var ENGINE_PACKAGE_VERSION = "0.1.1360";
243
+ var ENGINE_PACKAGE_VERSION = "0.1.1363";
244
244
  var INITIALIZE_METHOD = "initialize";
245
245
  var INITIALIZED_NOTIFICATION = "initialized";
246
246
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  AspClient
6
- } from "./chunk-64HL4Y7U.js";
6
+ } from "./chunk-B4JWWQR5.js";
7
7
  import {
8
8
  ASTER_BASE_URL,
9
9
  ASTER_PROVIDER,
@@ -14,11 +14,11 @@ import {
14
14
  recoverCompletedTurn,
15
15
  spawnMuseMsp,
16
16
  startMuseSession
17
- } from "./chunk-CMXQTGY7.js";
17
+ } from "./chunk-TPN7XDWM.js";
18
18
  import {
19
19
  AppServerProcess,
20
20
  buildCodexAgentEnv
21
- } from "./chunk-64HL4Y7U.js";
21
+ } from "./chunk-B4JWWQR5.js";
22
22
  import "./chunk-QCX45VR3.js";
23
23
  import {
24
24
  AGENT,
package/dist/src/index.js CHANGED
@@ -65,7 +65,7 @@ import {
65
65
  spawnMuseMsp,
66
66
  startMuseSession,
67
67
  uuidV7
68
- } from "./chunk-CMXQTGY7.js";
68
+ } from "./chunk-TPN7XDWM.js";
69
69
  import {
70
70
  publishedPullRequestUrls
71
71
  } from "./chunk-6FLA4WPX.js";
@@ -143,7 +143,7 @@ import {
143
143
  timestampFromSeconds,
144
144
  upsertCredentialFileLines,
145
145
  writeSecureCredentialFile
146
- } from "./chunk-R4KV2YTR.js";
146
+ } from "./chunk-2WJHTBM5.js";
147
147
  import {
148
148
  ENGINE_ENV,
149
149
  monolithRequest,
@@ -156,7 +156,7 @@ import {
156
156
  } from "./chunk-YQI4XGIX.js";
157
157
  import {
158
158
  getCodexModelProvider
159
- } from "./chunk-64HL4Y7U.js";
159
+ } from "./chunk-B4JWWQR5.js";
160
160
  import {
161
161
  SUBPROCESS_MAX_BUFFER,
162
162
  execAsync,
@@ -11721,6 +11721,7 @@ var CodingAgentManager = class _CodingAgentManager {
11721
11721
  usesAutoCompactTokens;
11722
11722
  autoCompactTokens = null;
11723
11723
  unreadSteers = /* @__PURE__ */ new Map();
11724
+ // A harness can read a steer before steerRequest returns, so a read is noted here until the steer settles.
11724
11725
  steersInFlight = /* @__PURE__ */ new Map();
11725
11726
  steerSettlements = /* @__PURE__ */ new Set();
11726
11727
  earlySteers = [];
@@ -11962,7 +11963,8 @@ ${request.message}` }, senderKey };
11962
11963
  getQueue() {
11963
11964
  return [
11964
11965
  ...[...this.unreadSteers.values()].map(({ message, steeredAt }) => ({ ...toQueuedMessageInfo(message), steeredAt })),
11965
- ...[...this.steersInFlight.values(), ...this.messageQueue.getQueue()].map(toQueuedMessageInfo)
11966
+ ...[...this.steersInFlight.values()].filter(({ read }) => !read).map(({ message }) => toQueuedMessageInfo(message)),
11967
+ ...this.messageQueue.getQueue().map(toQueuedMessageInfo)
11966
11968
  ];
11967
11969
  }
11968
11970
  async removeFromQueue(messageId, persistRemoval) {
@@ -12018,7 +12020,6 @@ ${request.message}` }, senderKey };
12018
12020
  if (!taken) {
12019
12021
  return { success: false, queue: this.getQueue() };
12020
12022
  }
12021
- this.steersInFlight.set(messageId, taken.message);
12022
12023
  let steered = false;
12023
12024
  const { request: withSender, senderKey } = this.withSenderLine(taken.message);
12024
12025
  const note = wrapInTag("You received this message while working. The chat folds everything before your last message of this turn, so that message must answer it too, even if you already did earlier.", REPLICAS_INSTRUCTIONS_TAG);
@@ -12026,18 +12027,21 @@ ${request.message}` }, senderKey };
12026
12027
  const delivered = command ? withSender : { ...withSender, message: `${withSender.message}
12027
12028
 
12028
12029
  ${note}` };
12030
+ const inFlight = { message: taken.message, delivered, read: false };
12031
+ this.steersInFlight.set(messageId, inFlight);
12029
12032
  try {
12030
12033
  steered = this.earlySteers.length === 0 && await this.steerRequest(delivered);
12031
- if (!steered && this.turnOpen && !command && this.steerRequest !== _CodingAgentManager.prototype.steerRequest) {
12034
+ if (!steered && !inFlight.read && this.turnOpen && !command && this.steerRequest !== _CodingAgentManager.prototype.steerRequest) {
12032
12035
  this.earlySteers.push(delivered);
12033
12036
  steered = true;
12034
12037
  void this.deliverEarlySteers();
12035
12038
  }
12036
- if (steered) await this.saveLastSenderKey(senderKey);
12039
+ if (steered || inFlight.read) await this.saveLastSenderKey(senderKey);
12037
12040
  } catch (error) {
12038
12041
  console.error("[CodingAgentManager] steerRequest threw, keeping message queued:", error);
12039
12042
  }
12040
12043
  this.steersInFlight.delete(messageId);
12044
+ if (inFlight.read) return { success: true, queue: this.getQueue() };
12041
12045
  if (steered) {
12042
12046
  this.unreadSteers.set(messageId, { message: taken.message, delivered, steeredAt: (/* @__PURE__ */ new Date()).toISOString() });
12043
12047
  this.onQueueChanged();
@@ -12052,7 +12056,9 @@ ${note}` };
12052
12056
  if (!queued && !this.unreadSteers.has(messageId)) return { success: false, queue: this.getQueue() };
12053
12057
  const turnRunning = this.messageQueue.isProcessing();
12054
12058
  if (turnRunning && this.canDeliverSteersNow()) {
12055
- if (queued) await this.steerFromQueue(messageId);
12059
+ if (queued && (await this.steerFromQueue(messageId)).success && !this.unreadSteers.has(messageId)) {
12060
+ return { success: true, queue: this.getQueue() };
12061
+ }
12056
12062
  if (this.unreadSteers.has(messageId)) {
12057
12063
  await this.deliverSteersNow();
12058
12064
  return { success: true, queue: this.getQueue() };
@@ -12087,7 +12093,12 @@ ${note}` };
12087
12093
  markSteerRead(messageId) {
12088
12094
  const steer = this.unreadSteers.get(messageId);
12089
12095
  if (this.unreadSteers.delete(messageId)) this.onQueueChanged();
12090
- return steer?.delivered ?? this.messageQueue.takeFromQueue(messageId)?.message;
12096
+ const inFlight = this.steersInFlight.get(messageId);
12097
+ if (inFlight && !inFlight.read) {
12098
+ inFlight.read = true;
12099
+ this.onQueueChanged();
12100
+ }
12101
+ return steer?.delivered ?? inFlight?.delivered ?? this.messageQueue.takeFromQueue(messageId)?.message;
12091
12102
  }
12092
12103
  canDeliverSteersNow() {
12093
12104
  return false;
@@ -12857,14 +12868,26 @@ function isClaudeSessionActive(activity) {
12857
12868
  // src/managers/claude-background-tasks.ts
12858
12869
  var ClaudeBackgroundTasks = class {
12859
12870
  active = /* @__PURE__ */ new Set();
12860
- foreground = /* @__PURE__ */ new Set();
12871
+ // The main agent's blocking tasks, by tool_use id; a subagent's own commands are its to wait on.
12872
+ foreground = /* @__PURE__ */ new Map();
12873
+ // A task counts as the main agent's only when its tool call is one the main agent made, so a task
12874
+ // whose owner can't be told apart is left running.
12875
+ mainToolUses = /* @__PURE__ */ new Set();
12861
12876
  reset() {
12862
12877
  this.active.clear();
12863
12878
  this.foreground.clear();
12879
+ this.mainToolUses.clear();
12864
12880
  }
12865
12881
  update(message) {
12882
+ if (message.type === "assistant" && message.parent_tool_use_id === null) {
12883
+ for (const block of message.message.content) if (block.type === "tool_use") this.mainToolUses.add(block.id);
12884
+ }
12885
+ if (message.type === "result") this.mainToolUses.clear();
12866
12886
  if (message.type !== "system") return;
12867
- if (message.subtype === "task_started" && message.is_backgrounded === false) this.foreground.add(message.task_id);
12887
+ const ownedBySubagent = "owned_by_subagent" in message && message.owned_by_subagent === true;
12888
+ if (message.subtype === "task_started" && message.is_backgrounded === false && !message.parent_task_id && !ownedBySubagent && message.tool_use_id && this.mainToolUses.delete(message.tool_use_id)) {
12889
+ this.foreground.set(message.task_id, message.tool_use_id);
12890
+ }
12868
12891
  if (message.subtype === "task_notification") this.foreground.delete(message.task_id);
12869
12892
  if (message.subtype === "task_updated" && (message.patch.is_backgrounded || message.patch.status && message.patch.status !== "running")) {
12870
12893
  this.foreground.delete(message.task_id);
@@ -13219,7 +13242,8 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
13219
13242
  return this.activeQuery !== null && this.backgroundTasks.foreground.size > 0;
13220
13243
  }
13221
13244
  async deliverSteersNow() {
13222
- await this.activeQuery?.backgroundTasks();
13245
+ const query2 = this.activeQuery;
13246
+ if (query2) await Promise.all([...this.backgroundTasks.foreground.values()].map((toolUseId) => query2.backgroundTasks(toolUseId)));
13223
13247
  }
13224
13248
  // Claude Code folds a `next`-priority prompt into the running turn at its next tool boundary.
13225
13249
  async steerRequest(request) {
@@ -13992,6 +14016,14 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
13992
14016
  return {};
13993
14017
  }],
13994
14018
  timeout: 30
14019
+ }, {
14020
+ // Only Send now backgrounds commands here, so Claude Code's "manually backgrounded by user" isn't true.
14021
+ matcher: "Bash",
14022
+ hooks: [async (input) => {
14023
+ const response2 = input.hook_event_name === "PostToolUse" ? input.tool_response : void 0;
14024
+ return isRecord(response2) && response2.backgroundedByUser === true ? { hookSpecificOutput: { hookEventName: "PostToolUse", updatedToolOutput: { ...response2, backgroundedByUser: false, backgroundedToDeliverMessage: true } } } : {};
14025
+ }],
14026
+ timeout: 30
13995
14027
  }, {
13996
14028
  matcher: "Workflow",
13997
14029
  hooks: [async (input) => {
@@ -61949,8 +61981,10 @@ ${note}`;
61949
61981
  }
61950
61982
  const stillProcessing = processing || forked;
61951
61983
  const answer = chat.turnAnswer;
61984
+ const request = chat.turnRequest;
61952
61985
  chat.turnAnswer = null;
61953
- const responseComplete = this.publishTurnCompleted(chat, completedAt, stillProcessing, answer, userTurn);
61986
+ if (answer) chat.turnRequest = null;
61987
+ const responseComplete = this.publishTurnCompleted(chat, completedAt, stillProcessing, answer, request, userTurn);
61954
61988
  const completion = this.publishAgentTurnCompleteWebhook(chat, completedAt, stillProcessing, forked ? null : exhaustion, responseComplete, chat.turnCompletion).catch((error) => console.error("[ChatService] Failed to report turn completion:", { chatId, error })).finally(() => {
61955
61989
  if (chat.turnCompletion === completion) chat.turnCompletion = null;
61956
61990
  this.notifyWorkspaceAgentIdle();
@@ -61958,7 +61992,7 @@ ${note}`;
61958
61992
  });
61959
61993
  chat.turnCompletion = completion;
61960
61994
  }
61961
- async publishTurnCompleted(chat, completedAt, processing, answer, userTurn) {
61995
+ async publishTurnCompleted(chat, completedAt, processing, answer, request, userTurn) {
61962
61996
  if (chat.persisted.parentChatId) {
61963
61997
  this.publish({ type: "chat.updated", payload: { chat: this.toSummary(chat) } }).catch(() => {
61964
61998
  });
@@ -61981,7 +62015,7 @@ ${note}`;
61981
62015
  completedAt,
61982
62016
  processing,
61983
62017
  ...userTurn || answer ? { chatId: chat.persisted.id } : {},
61984
- ...answer ? { finalMessage: answer, ...chat.turnRequest ? { request: chat.turnRequest } : {} } : {},
62018
+ ...answer ? { finalMessage: answer, ...request ? { request } : {} } : {},
61985
62019
  ...isPullRequestFeedbackChat(chat.persisted) ? { pullRequestFeedback: true } : {}
61986
62020
  }
61987
62021
  }, AbortSignal.timeout(1e4));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.1360",
3
+ "version": "0.1.1363",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",