replicas-engine 0.1.880 → 0.1.882

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.
@@ -5,9 +5,9 @@ import {
5
5
  getCodexAspHost,
6
6
  restartCodexAspHost,
7
7
  restartCodexAspHostIfRunning
8
- } from "./chunk-7F6BWE2P.js";
8
+ } from "./chunk-H42KW3RC.js";
9
9
  import "./chunk-4CF465DO.js";
10
- import "./chunk-SXUDMIPU.js";
10
+ import "./chunk-SFWJXPG3.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
12
  import "./chunk-PYQVWR2X.js";
13
13
  import "./chunk-VEQXQN22.js";
@@ -11,7 +11,7 @@ import {
11
11
  SUBPROCESS_MAX_BUFFER,
12
12
  buildCodexAgentEnv,
13
13
  execFileAsync
14
- } from "./chunk-SXUDMIPU.js";
14
+ } from "./chunk-SFWJXPG3.js";
15
15
  import {
16
16
  isRecord
17
17
  } from "./chunk-UZSNFLDQ.js";
@@ -68,6 +68,11 @@ function listCredentialFallbacks() {
68
68
  function listExhaustedCredentials(provider) {
69
69
  return [...exhaustedByAgent.get(provider)?.values() ?? []];
70
70
  }
71
+ function routineRefreshExclusions(provider) {
72
+ const live = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS[provider];
73
+ const excludeCredentials = listExhaustedCredentials(provider).filter((spent) => spent.method !== live?.method || spent.scope !== live?.scope);
74
+ return excludeCredentials.length > 0 ? { excludeCredentials } : {};
75
+ }
71
76
  function recordExhaustedCredential(provider, credential) {
72
77
  const spent = exhaustedByAgent.get(provider) ?? /* @__PURE__ */ new Map();
73
78
  spent.set(`${credential.method}|${credential.scope}`, credential);
@@ -240,13 +245,13 @@ var CodexTokenManager = class extends BaseRefreshManager {
240
245
  return null;
241
246
  }
242
247
  async doRefresh(_config) {
243
- await this.refreshWithRequest(void 0, true);
248
+ await this.refreshWithRequest(routineRefreshExclusions("codex"), true);
244
249
  }
245
250
  async switchCredentials(data) {
246
251
  await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
247
252
  await this.applyCredentialsResponse(data);
248
253
  if (data.scope) setAgentCredentialSnapshot("codex", { method: data.type, scope: data.scope, revision: data.revision });
249
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-4RDOJQ64.js");
254
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-AJ55PRBL.js");
250
255
  await restartCodexAspHostIfRunning2();
251
256
  });
252
257
  await this.start(true);
@@ -266,7 +271,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
266
271
  await this.applyCredentialUpdate(generation, async () => {
267
272
  await this.applyCredentialsResponse(data);
268
273
  if (restartOnChange && CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index])) {
269
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-4RDOJQ64.js");
274
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-AJ55PRBL.js");
270
275
  await restartCodexAspHostIfRunning2();
271
276
  }
272
277
  if (data.scope) {
@@ -505,6 +510,7 @@ export {
505
510
  clearCredentialFallbacks,
506
511
  recordCredentialFallback,
507
512
  listCredentialFallbacks,
513
+ routineRefreshExclusions,
508
514
  recordExhaustedCredential,
509
515
  BaseRefreshManager,
510
516
  applyAuthEnvTransition,
@@ -245,7 +245,7 @@ function getCodexModelProvider(method) {
245
245
  if (method === "foundry") return "azure";
246
246
  return method === "ollama" || method === "openai-compatible" ? "replicas_openai_compatible" : "openai";
247
247
  }
248
- var ENGINE_PACKAGE_VERSION = "0.1.880";
248
+ var ENGINE_PACKAGE_VERSION = "0.1.882";
249
249
  var INITIALIZE_METHOD = "initialize";
250
250
  var INITIALIZED_NOTIFICATION = "initialized";
251
251
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  AppServerProcess,
10
10
  buildCodexAgentEnv
11
- } from "./chunk-SXUDMIPU.js";
11
+ } from "./chunk-SFWJXPG3.js";
12
12
  import {
13
13
  AGENT,
14
14
  getMemoryOutputSafetyViolation,
package/dist/src/index.js CHANGED
@@ -131,8 +131,9 @@ import {
131
131
  listCredentialFallbacks,
132
132
  recordCredentialFallback,
133
133
  recordExhaustedCredential,
134
- restartCodexAspHost
135
- } from "./chunk-7F6BWE2P.js";
134
+ restartCodexAspHost,
135
+ routineRefreshExclusions
136
+ } from "./chunk-H42KW3RC.js";
136
137
  import {
137
138
  ENGINE_ENV,
138
139
  IS_WARMING_MODE,
@@ -146,7 +147,7 @@ import {
146
147
  execAsync,
147
148
  execFileAsync,
148
149
  getCodexModelProvider
149
- } from "./chunk-SXUDMIPU.js";
150
+ } from "./chunk-SFWJXPG3.js";
150
151
  import {
151
152
  isRecord as isRecord2
152
153
  } from "./chunk-UZSNFLDQ.js";
@@ -9431,7 +9432,7 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
9431
9432
  return null;
9432
9433
  }
9433
9434
  async doRefresh(_config) {
9434
- await this.refreshWithRequest();
9435
+ await this.refreshWithRequest(routineRefreshExclusions("claude"));
9435
9436
  }
9436
9437
  async switchCredentials(data) {
9437
9438
  await this.applyCredentialUpdate(++this.credentialGeneration, () => this.applyCredentialsResponse(data));
@@ -14749,7 +14750,6 @@ var CodexQuotaError = class extends Error {
14749
14750
  this.name = "CodexQuotaError";
14750
14751
  }
14751
14752
  };
14752
- var GOAL_TURN_CONTINUATION_GRACE_MS = 5e3;
14753
14753
  var CODEX_SLASH_COMMANDS_CACHE_MS = 3e4;
14754
14754
  var POLICY_REASON_INJECTION_TIMEOUT_MS = 5e3;
14755
14755
  function formatBlockedCommandReason(reason) {
@@ -14796,6 +14796,8 @@ var CodexAspManager = class extends CodingAgentManager {
14796
14796
  quotaStatus = new CodexQuotaStatusTracker();
14797
14797
  currentGoal = null;
14798
14798
  goalHistoryKnown = false;
14799
+ goalRevision = 0;
14800
+ onGoalChanged = null;
14799
14801
  itemUpdateCoalescer = new ItemUpdateCoalescer((itemId) => {
14800
14802
  const item = this.liveTurn?.items.get(itemId);
14801
14803
  if (this.liveTurn && item) this.onEvent(codexItemEvent(this.liveTurn.id, item, true));
@@ -14839,6 +14841,9 @@ var CodexAspManager = class extends CodingAgentManager {
14839
14841
  };
14840
14842
  }
14841
14843
  async interruptActiveTurn() {
14844
+ if (this.currentGoal?.status === "active") {
14845
+ await this.updateGoal({ status: "paused" });
14846
+ }
14842
14847
  if (!this.currentThreadId || !this.activeTurnId) {
14843
14848
  return;
14844
14849
  }
@@ -15291,9 +15296,9 @@ ${text.slice(-24e3)}`
15291
15296
  );
15292
15297
  this.recordGoalChange(response.goal, true);
15293
15298
  return { turn: null, tempImagePaths: [] };
15294
- }, { waitForActiveGoal: true });
15299
+ });
15295
15300
  }
15296
- async observeTurn(host, threadId, request, startTurn, options = {}) {
15301
+ async observeTurn(host, threadId, request, startTurn) {
15297
15302
  let resolveCompleted;
15298
15303
  const completed = new Promise((resolve7) => {
15299
15304
  resolveCompleted = resolve7;
@@ -15309,7 +15314,6 @@ ${text.slice(-24e3)}`
15309
15314
  const observedTurnIds = /* @__PURE__ */ new Set();
15310
15315
  let lastCompletedTurn = null;
15311
15316
  let completedResolved = false;
15312
- let goalContinuationTimer = null;
15313
15317
  const completedItems = [];
15314
15318
  const agentMessageDeltas = /* @__PURE__ */ new Map();
15315
15319
  const linearSessionId = this.linearSessionId;
@@ -15319,24 +15323,11 @@ ${text.slice(-24e3)}`
15319
15323
  const matchesTurn = (notificationThreadId, notificationTurnId) => notificationThreadId === threadId && (!observedTurnId || notificationTurnId === null || notificationTurnId === observedTurnId || notificationTurnId === this.activeTurnId);
15320
15324
  const resolveIfGoalIdle = () => {
15321
15325
  if (!lastCompletedTurn || completedResolved) return;
15322
- if (!options.waitForActiveGoal || this.currentGoal?.status !== "active") {
15323
- if (goalContinuationTimer) {
15324
- clearTimeout(goalContinuationTimer);
15325
- goalContinuationTimer = null;
15326
- }
15326
+ if (lastCompletedTurn.status !== "completed" || this.currentGoal?.status !== "active") {
15327
15327
  completedResolved = true;
15328
15328
  resolveCompleted(lastCompletedTurn);
15329
15329
  }
15330
15330
  };
15331
- const scheduleGoalContinuationFallback = () => {
15332
- if (!options.waitForActiveGoal || completedResolved || goalContinuationTimer) return;
15333
- goalContinuationTimer = setTimeout(() => {
15334
- goalContinuationTimer = null;
15335
- if (!lastCompletedTurn || completedResolved) return;
15336
- completedResolved = true;
15337
- resolveCompleted(lastCompletedTurn);
15338
- }, GOAL_TURN_CONTINUATION_GRACE_MS);
15339
- };
15340
15331
  const handlers = {
15341
15332
  [ACCOUNT_RATE_LIMITS_UPDATED_METHOD]: (notification) => {
15342
15333
  this.handleRateLimits(notification.params.rateLimits);
@@ -15354,12 +15345,10 @@ ${text.slice(-24e3)}`
15354
15345
  [THREAD_GOAL_UPDATED_METHOD]: (notification) => {
15355
15346
  if (notification.params.threadId !== threadId) return;
15356
15347
  this.recordGoalChange(notification.params.goal);
15357
- resolveIfGoalIdle();
15358
15348
  },
15359
15349
  [THREAD_GOAL_CLEARED_METHOD]: (notification) => {
15360
15350
  if (notification.params.threadId !== threadId) return;
15361
15351
  this.recordGoalChange(null);
15362
- resolveIfGoalIdle();
15363
15352
  },
15364
15353
  [THREAD_COMPACTED_METHOD]: (notification) => {
15365
15354
  if (!matchesTurn(notification.params.threadId, notification.params.turnId)) return;
@@ -15371,10 +15360,6 @@ ${text.slice(-24e3)}`
15371
15360
  observedTurnIds.add(notification.params.turn.id);
15372
15361
  this.activeTurnId = notification.params.turn.id;
15373
15362
  this.onCodexTurnStarted?.(threadId, notification.params.turn.id);
15374
- if (goalContinuationTimer) {
15375
- clearTimeout(goalContinuationTimer);
15376
- goalContinuationTimer = null;
15377
- }
15378
15363
  lastCompletedTurn = null;
15379
15364
  completedItems.length = 0;
15380
15365
  agentMessageDeltas.clear();
@@ -15452,11 +15437,11 @@ ${text.slice(-24e3)}`
15452
15437
  this.onCodexTurnCompleted?.(threadId, notification.params.turn.id);
15453
15438
  const completedTurn = recoverCompletedTurn(notification.params.turn, completedItems, agentMessageDeltas);
15454
15439
  this.completeTurn(completedTurn);
15440
+ if (this.activeTurnId === completedTurn.id) this.activeTurnId = null;
15455
15441
  lastCompletedTurn = completedTurn;
15456
15442
  resolveIfGoalIdle();
15457
- if (options.waitForActiveGoal && this.currentGoal?.status === "active") {
15458
- void this.refreshThreadGoal(host, threadId).then(resolveIfGoalIdle).catch(() => {
15459
- }).finally(scheduleGoalContinuationFallback);
15443
+ if (!completedResolved && this.currentGoal?.status === "active") {
15444
+ void this.refreshThreadGoal(host, threadId);
15460
15445
  }
15461
15446
  }
15462
15447
  };
@@ -15483,16 +15468,16 @@ ${text.slice(-24e3)}`
15483
15468
  host.client.on("notification", onNotification);
15484
15469
  host.client.on("serverRequest", onServerRequest);
15485
15470
  host.client.on("dispose", onDispose);
15471
+ this.onGoalChanged = resolveIfGoalIdle;
15486
15472
  try {
15487
15473
  const started = await startTurn();
15488
15474
  tempImagePaths = started.tempImagePaths;
15489
- if (started.turn) {
15490
- const alreadyObserved = observedTurnIds.has(started.turn.id);
15475
+ if (started.turn && !observedTurnIds.has(started.turn.id)) {
15491
15476
  observedTurnId = started.turn.id;
15492
15477
  observedTurnIds.add(started.turn.id);
15493
15478
  this.activeTurnId = started.turn.id;
15494
- if (!alreadyObserved) this.onCodexTurnStarted?.(threadId, started.turn.id);
15495
- if (!alreadyObserved) this.startTurn(started.turn);
15479
+ this.onCodexTurnStarted?.(threadId, started.turn.id);
15480
+ this.startTurn(started.turn);
15496
15481
  }
15497
15482
  const turn = await Promise.race([completed, disposed]);
15498
15483
  linearForwarder.flushThoughtAsResponse();
@@ -15501,9 +15486,7 @@ ${text.slice(-24e3)}`
15501
15486
  host.client.off("notification", onNotification);
15502
15487
  host.client.off("serverRequest", onServerRequest);
15503
15488
  host.client.off("dispose", onDispose);
15504
- if (goalContinuationTimer) {
15505
- clearTimeout(goalContinuationTimer);
15506
- }
15489
+ this.onGoalChanged = null;
15507
15490
  this.itemUpdateCoalescer.flushPending();
15508
15491
  await removeTempImageFiles(tempImagePaths);
15509
15492
  if (host.client.isDisposed) {
@@ -15745,29 +15728,33 @@ ${text.slice(-24e3)}`
15745
15728
  this.itemUpdateCoalescer.schedule(itemId);
15746
15729
  }
15747
15730
  async refreshThreadGoal(host, threadId) {
15731
+ const revision = this.goalRevision;
15732
+ const currentThreadId = this.currentThreadId;
15733
+ const attachedClient = this.attachedClient;
15748
15734
  try {
15749
15735
  const response = await host.client.request(
15750
15736
  THREAD_GOAL_GET_METHOD,
15751
15737
  { threadId }
15752
15738
  );
15753
- this.currentGoal = response.goal ? aspGoalToChatGoal(response.goal) : null;
15754
- this.goalHistoryKnown = true;
15739
+ if (this.goalRevision !== revision || this.currentThreadId !== currentThreadId || this.attachedClient !== attachedClient || host.client.isDisposed) return;
15740
+ this.recordGoalChange(response.goal);
15755
15741
  } catch (error) {
15756
15742
  console.warn("[CodexAspManager] Failed to read ASP thread goal:", error);
15757
15743
  }
15758
15744
  }
15759
15745
  recordGoalChange(goal, force = false) {
15746
+ this.goalRevision += 1;
15747
+ this.goalHistoryKnown = true;
15760
15748
  const nextGoal = goal ? aspGoalToChatGoal(goal) : null;
15761
- if (!force && JSON.stringify(this.currentGoal) === JSON.stringify(nextGoal)) {
15762
- return;
15749
+ if (force || JSON.stringify(this.currentGoal) !== JSON.stringify(nextGoal)) {
15750
+ this.currentGoal = nextGoal;
15751
+ const event = this.recordCodexHistoryEvent(
15752
+ CHAT_GOAL_EVENT_TYPE,
15753
+ { goal: nextGoal }
15754
+ );
15755
+ this.onEvent(event);
15763
15756
  }
15764
- this.currentGoal = nextGoal;
15765
- this.goalHistoryKnown = true;
15766
- const event = this.recordCodexHistoryEvent(
15767
- CHAT_GOAL_EVENT_TYPE,
15768
- { goal: nextGoal }
15769
- );
15770
- this.onEvent(event);
15757
+ this.onGoalChanged?.();
15771
15758
  }
15772
15759
  recordCodexHistoryEvent(type, payload) {
15773
15760
  const event = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.880",
3
+ "version": "0.1.882",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",