replicas-engine 0.1.1280 → 0.1.1281

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,12 +8,12 @@ import {
8
8
  listRunningCodexModels,
9
9
  restartCodexAspHost,
10
10
  restartCodexAspHostIfRunning
11
- } from "./chunk-YPDZYUL7.js";
12
- import "./chunk-PM7AZN6N.js";
13
- import "./chunk-2V3IUQEJ.js";
14
- import "./chunk-22IJF5CU.js";
11
+ } from "./chunk-JPOHWGGI.js";
12
+ import "./chunk-4J7EZ245.js";
13
+ import "./chunk-5OYGVDKL.js";
14
+ import "./chunk-3MSBE24K.js";
15
15
  import "./chunk-UZSNFLDQ.js";
16
- import "./chunk-J5KG7UVX.js";
16
+ import "./chunk-5YU4KQIU.js";
17
17
  import "./chunk-VEQXQN22.js";
18
18
  export {
19
19
  CODEX_ULTRAFAST_SERVICE_TIER,
@@ -3,7 +3,7 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  HOOK_EXEC_MAX_BUFFER_BYTES
6
- } from "./chunk-J5KG7UVX.js";
6
+ } from "./chunk-5YU4KQIU.js";
7
7
 
8
8
  // src/utils/exec.ts
9
9
  import { exec, execFile } from "child_process";
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  SUBPROCESS_MAX_BUFFER,
6
6
  execFileAsync
7
- } from "./chunk-22IJF5CU.js";
7
+ } from "./chunk-3MSBE24K.js";
8
8
  import {
9
9
  isRecord as isRecord2
10
10
  } from "./chunk-UZSNFLDQ.js";
@@ -22,7 +22,7 @@ import {
22
22
  provisionedDeviceSchema,
23
23
  readReplicasRuntimeEnv,
24
24
  serializePosixEnvFile
25
- } from "./chunk-J5KG7UVX.js";
25
+ } from "./chunk-5YU4KQIU.js";
26
26
 
27
27
  // src/runtime-env-loader.ts
28
28
  import { readFileSync } from "fs";
@@ -3,10 +3,10 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  execFileAsync
6
- } from "./chunk-22IJF5CU.js";
6
+ } from "./chunk-3MSBE24K.js";
7
7
  import {
8
8
  isVersionBelow
9
- } from "./chunk-J5KG7UVX.js";
9
+ } from "./chunk-5YU4KQIU.js";
10
10
 
11
11
  // src/utils/codex-agent-env.ts
12
12
  function buildCodexAgentEnv(source = process.env) {
@@ -10564,8 +10564,10 @@ export {
10564
10564
  detectAgentQuotaLimit,
10565
10565
  listOpenAICompatibleModels,
10566
10566
  resolveOpenAICompatibleModelsUrl,
10567
+ openAICompatibleAuthEnvKeys,
10567
10568
  readOpenAICompatibleAuthEnv,
10568
10569
  OLLAMA_AGENTS,
10570
+ ollamaAuthEnvKeys,
10569
10571
  readOllamaAuthEnv,
10570
10572
  DEFAULT_OLLAMA_MODEL,
10571
10573
  getDefaultOllamaModel,
@@ -10,15 +10,15 @@ import {
10
10
  resolveDiffBase,
11
11
  runGitCommand,
12
12
  setAgentCredentialSnapshot
13
- } from "./chunk-PM7AZN6N.js";
13
+ } from "./chunk-4J7EZ245.js";
14
14
  import {
15
15
  AppServerProcess,
16
16
  buildCodexAgentEnv
17
- } from "./chunk-2V3IUQEJ.js";
17
+ } from "./chunk-5OYGVDKL.js";
18
18
  import {
19
19
  SUBPROCESS_MAX_BUFFER,
20
20
  execFileAsync
21
- } from "./chunk-22IJF5CU.js";
21
+ } from "./chunk-3MSBE24K.js";
22
22
  import {
23
23
  isRecord
24
24
  } from "./chunk-UZSNFLDQ.js";
@@ -55,7 +55,7 @@ import {
55
55
  resolveOpenAICompatibleModelsUrl,
56
56
  splitMothershipInstructions,
57
57
  withTimeout
58
- } from "./chunk-J5KG7UVX.js";
58
+ } from "./chunk-5YU4KQIU.js";
59
59
 
60
60
  // src/managers/codex-token-manager.ts
61
61
  import { promises as fs } from "fs";
@@ -291,7 +291,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
291
291
  await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
292
292
  await this.applyCredentialsResponse(data);
293
293
  setAgentCredentialSnapshot("codex", data);
294
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-OLAWGNOT.js");
294
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-VCIWMQXN.js");
295
295
  await restartCodexAspHostIfRunning2();
296
296
  });
297
297
  await this.start(true);
@@ -313,7 +313,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
313
313
  const accountChanged = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex?.credentialId !== data.credentialId;
314
314
  await this.applyCredentialsResponse(data);
315
315
  if (restartOnChange && (accountChanged || CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index]))) {
316
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-OLAWGNOT.js");
316
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-VCIWMQXN.js");
317
317
  await restartCodexAspHostIfRunning2();
318
318
  }
319
319
  setAgentCredentialSnapshot("codex", data);
@@ -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-2V3IUQEJ.js";
6
+ } from "./chunk-5OYGVDKL.js";
7
7
  import {
8
8
  ASTER_BASE_URL,
9
9
  ASTER_PROVIDER,
@@ -15,7 +15,7 @@ import {
15
15
  isRecord,
16
16
  readOllamaAuthEnv,
17
17
  readOpenAICompatibleAuthEnv
18
- } from "./chunk-J5KG7UVX.js";
18
+ } from "./chunk-5YU4KQIU.js";
19
19
 
20
20
  // src/managers/codex-asp/notification-dispatch.ts
21
21
  var TURN_STARTED_METHOD = "turn/started";
@@ -5,7 +5,7 @@ import {
5
5
  extractCommandProtectionCommandText,
6
6
  isRecord,
7
7
  parseCodeHostPrUrl
8
- } from "./chunk-J5KG7UVX.js";
8
+ } from "./chunk-5YU4KQIU.js";
9
9
 
10
10
  // src/services/published-pull-request-urls.ts
11
11
  function publishedPullRequestUrls(result) {
@@ -5,14 +5,14 @@ import {
5
5
  getOriginDefaultBranch,
6
6
  monolithRequest,
7
7
  runGitCommand
8
- } from "./chunk-PM7AZN6N.js";
8
+ } from "./chunk-4J7EZ245.js";
9
9
  import {
10
10
  extractCommandProtectionCommandText,
11
11
  findCommandProtectionGitLookups,
12
12
  findGitCommitSignals,
13
13
  findPrMergeSignals,
14
14
  parseCommandProtectionRequest
15
- } from "./chunk-J5KG7UVX.js";
15
+ } from "./chunk-5YU4KQIU.js";
16
16
 
17
17
  // src/services/command-protection-service.ts
18
18
  import { readFile, stat } from "fs/promises";
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  evaluateCommandProtection
6
- } from "./chunk-EF54GE6V.js";
7
- import "./chunk-PM7AZN6N.js";
8
- import "./chunk-22IJF5CU.js";
6
+ } from "./chunk-VI33T336.js";
7
+ import "./chunk-4J7EZ245.js";
8
+ import "./chunk-3MSBE24K.js";
9
9
  import {
10
10
  isRecord
11
11
  } from "./chunk-UZSNFLDQ.js";
12
- import "./chunk-J5KG7UVX.js";
12
+ import "./chunk-5YU4KQIU.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/command-protection-hook.ts
@@ -14,12 +14,12 @@ import {
14
14
  recoverCompletedTurn,
15
15
  spawnMuseMsp,
16
16
  startMuseSession
17
- } from "./chunk-4F62FSBJ.js";
17
+ } from "./chunk-OYPH6PPR.js";
18
18
  import {
19
19
  AppServerProcess,
20
20
  buildCodexAgentEnv
21
- } from "./chunk-2V3IUQEJ.js";
22
- import "./chunk-22IJF5CU.js";
21
+ } from "./chunk-5OYGVDKL.js";
22
+ import "./chunk-3MSBE24K.js";
23
23
  import {
24
24
  AGENT,
25
25
  OPENCODE_GO_PROVIDER,
@@ -29,7 +29,7 @@ import {
29
29
  headlessAgentUsagePath,
30
30
  isRecord,
31
31
  withTimeout
32
- } from "./chunk-J5KG7UVX.js";
32
+ } from "./chunk-5YU4KQIU.js";
33
33
  import "./chunk-VEQXQN22.js";
34
34
 
35
35
  // src/headless-agent.ts
package/dist/src/index.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  evaluateCommandProtection,
28
28
  extractToolCommand,
29
29
  reportCommandProtectionBlock
30
- } from "./chunk-EF54GE6V.js";
30
+ } from "./chunk-VI33T336.js";
31
31
  import {
32
32
  ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
33
33
  AGENT_MESSAGE_DELTA_METHOD,
@@ -65,10 +65,10 @@ import {
65
65
  spawnMuseMsp,
66
66
  startMuseSession,
67
67
  uuidV7
68
- } from "./chunk-4F62FSBJ.js";
68
+ } from "./chunk-OYPH6PPR.js";
69
69
  import {
70
70
  publishedPullRequestUrls
71
- } from "./chunk-IU3ZJUGP.js";
71
+ } from "./chunk-THAFUTL3.js";
72
72
  import {
73
73
  ACCOUNT_RATE_LIMITS_READ_METHOD,
74
74
  AsyncLock,
@@ -141,7 +141,7 @@ import {
141
141
  timestampFromSeconds,
142
142
  upsertCredentialFileLines,
143
143
  writeSecureCredentialFile
144
- } from "./chunk-YPDZYUL7.js";
144
+ } from "./chunk-JPOHWGGI.js";
145
145
  import {
146
146
  ENGINE_ENV,
147
147
  monolithRequest,
@@ -151,15 +151,15 @@ import {
151
151
  resolveDiffBase,
152
152
  setAgentCredentialSnapshot,
153
153
  setLinearSessionId
154
- } from "./chunk-PM7AZN6N.js";
154
+ } from "./chunk-4J7EZ245.js";
155
155
  import {
156
156
  getCodexModelProvider
157
- } from "./chunk-2V3IUQEJ.js";
157
+ } from "./chunk-5OYGVDKL.js";
158
158
  import {
159
159
  SUBPROCESS_MAX_BUFFER,
160
160
  execAsync,
161
161
  execFileAsync
162
- } from "./chunk-22IJF5CU.js";
162
+ } from "./chunk-3MSBE24K.js";
163
163
  import {
164
164
  isRecord as isRecord2
165
165
  } from "./chunk-UZSNFLDQ.js";
@@ -365,6 +365,8 @@ import {
365
365
  normalizeClaudeModel,
366
366
  normalizeCodexAspTranscriptStatus,
367
367
  normalizeContentBlocks,
368
+ ollamaAuthEnvKeys,
369
+ openAICompatibleAuthEnvKeys,
368
370
  paginateChatHistory,
369
371
  paginateEngineLogContent,
370
372
  parseAgentEventJsonlLine,
@@ -407,7 +409,7 @@ import {
407
409
  workspaceTokenRequestSchema,
408
410
  workspaceTokenResponseSchema,
409
411
  wrapInTag
410
- } from "./chunk-J5KG7UVX.js";
412
+ } from "./chunk-5YU4KQIU.js";
411
413
  import {
412
414
  cloneMcpConfig,
413
415
  ensureCompatibilityImports,
@@ -11230,11 +11232,57 @@ var MuseTokenManager = class extends BaseRefreshManager {
11230
11232
  };
11231
11233
  var museTokenManager = new MuseTokenManager();
11232
11234
 
11235
+ // src/managers/opencode-token-manager.ts
11236
+ var OPENCODE_AUTH_ENV_KEYS = [...ollamaAuthEnvKeys("opencode"), ...openAICompatibleAuthEnvKeys("opencode")];
11237
+ var OpencodeTokenManager = class extends BaseRefreshManager {
11238
+ constructor() {
11239
+ super("OpencodeTokenManager");
11240
+ }
11241
+ doRefresh() {
11242
+ return Promise.resolve();
11243
+ }
11244
+ async fetchFreshCredentials(failureReason, failureKind = "exhausted", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.opencode, allowedMethods, resetsAt) {
11245
+ const failedMethod = AGENT_CREDENTIAL_METHODS_IN_ORDER.opencode.find(({ method }) => method === failedCredential?.method)?.method;
11246
+ if (!failedMethod || allowedMethods && !allowedMethods.includes(failedMethod)) {
11247
+ return createErrorResult({ message: "OpenCode only switches between keys of the same provider", code: "no_credentials" });
11248
+ }
11249
+ return this.swapCredentials({
11250
+ provider: "opencode",
11251
+ failureKind,
11252
+ allowedMethods: [failedMethod],
11253
+ refresh: async (exclusions) => {
11254
+ const request = {
11255
+ failedMethod,
11256
+ ...failedCredential ? { failedCredential } : {},
11257
+ failureReason,
11258
+ failureKind,
11259
+ ...resetsAt ? { resetsAt } : {},
11260
+ ...exclusions
11261
+ };
11262
+ const response = await monolithRequest("/v1/engine/opencode/refresh-credentials", { body: request, signal: AbortSignal.timeout(12e4) });
11263
+ if (!response.ok) {
11264
+ throw new Error(`Credentials refresh failed: ${response.status} ${await response.text()}`);
11265
+ }
11266
+ const data = await response.json();
11267
+ for (const file of data.auth.files ?? []) {
11268
+ await writeSecureCredentialFile(file.path, file.contents, { ensureParentDir: true });
11269
+ }
11270
+ for (const key of OPENCODE_AUTH_ENV_KEYS) delete process.env[key];
11271
+ Object.assign(process.env, data.auth.env);
11272
+ setAgentCredentialSnapshot("opencode", data);
11273
+ },
11274
+ isOauthNow: () => false
11275
+ });
11276
+ }
11277
+ };
11278
+ var opencodeTokenManager = new OpencodeTokenManager();
11279
+
11233
11280
  // src/managers/auth-fallback.ts
11234
11281
  var SWAPPABLE_AGENTS = {
11235
11282
  claude: claudeTokenManager,
11236
11283
  codex: codexTokenManager,
11237
- muse: museTokenManager
11284
+ muse: museTokenManager,
11285
+ opencode: opencodeTokenManager
11238
11286
  };
11239
11287
  var QUOTA_STOP_NEXT_STEP = {
11240
11288
  failed: "The next credential in the fallback chain could not be used. Check it in Settings \u2192 Fallbacks and try again.",
@@ -16797,9 +16845,9 @@ var OPENCODE_COMMAND_PROTECTION_PLUGIN_SOURCE = join15(OPENCODE_SHIM_DIR, "openc
16797
16845
  var OPENCODE_COMMAND_PROTECTION_PLUGIN_PATH = join15(ENGINE_ENV.HOME_DIR, ".config", "opencode", "plugins", "replicas-command-protection.ts");
16798
16846
  var OPENCODE_LEGACY_COMMAND_PROTECTION_PLUGIN_PATH = join15(ENGINE_ENV.HOME_DIR, ".config", "opencode", "plugins", "replicas-command-protection.mjs");
16799
16847
  var OPENCODE_CONFIG_PATH = join15(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
16800
- var OPENCODE_FETCH_DISPATCHER = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
16801
16848
  var OPENCODE_SERVER_STARTUP_TIMEOUT_MS = 3e4;
16802
16849
  var OPENCODE_SLASH_COMMANDS_CACHE_MS = 3e4;
16850
+ var OPENCODE_SWITCHED_CREDENTIAL_PROMPT = "Your previous turn stopped at a usage limit. Continue from where you left off: first check what is already done, and do not repeat commands, edits, or messages you already completed.";
16803
16851
  async function getDefaultOpencodeModel(provider) {
16804
16852
  const ollama = readOllamaAuthEnv("opencode", process.env);
16805
16853
  if (provider === "ollama" && ollama) {
@@ -16912,13 +16960,16 @@ function opencodeErrorPayload(error) {
16912
16960
  ...status !== void 0 ? { status } : {}
16913
16961
  };
16914
16962
  }
16915
- function opencodeFetch(input, init) {
16916
- const requestInit = { ...init, dispatcher: OPENCODE_FETCH_DISPATCHER };
16917
- return fetch(input, requestInit);
16963
+ function opencodeFetch(dispatcher) {
16964
+ return (input, init) => {
16965
+ const requestInit = { ...init, dispatcher };
16966
+ return fetch(input, requestInit);
16967
+ };
16918
16968
  }
16919
16969
  var OpencodeManager = class extends CodingAgentManager {
16920
16970
  client = null;
16921
16971
  server = null;
16972
+ dispatcher = null;
16922
16973
  sessionId = null;
16923
16974
  historyFilePath;
16924
16975
  historyFile;
@@ -16936,6 +16987,9 @@ var OpencodeManager = class extends CodingAgentManager {
16936
16987
  activeLinearForwarder = null;
16937
16988
  forwardedLinearPartKeys = /* @__PURE__ */ new Set();
16938
16989
  handledAccountRateLimit = false;
16990
+ credentialSwitch = null;
16991
+ /** OpenCode reads its key when the server starts, so a server started on another credential has to restart. */
16992
+ serverCredential;
16939
16993
  modelVariants = /* @__PURE__ */ new Map();
16940
16994
  slashCommandsCache = null;
16941
16995
  slashCommandsRequest = null;
@@ -17026,11 +17080,9 @@ var OpencodeManager = class extends CodingAgentManager {
17026
17080
  try {
17027
17081
  if (reuseExisting && this.client) return this.client;
17028
17082
  const subagentMcpParentChatId = this.subagentMcpParentChatId();
17029
- if (this.client && (this.providerId !== providerId || this.serverSubagentMcpParentChatId !== subagentMcpParentChatId)) {
17030
- this.eventAbortController?.abort();
17031
- this.server?.close();
17083
+ if (this.client && (this.providerId !== providerId || this.serverSubagentMcpParentChatId !== subagentMcpParentChatId || this.serverCredential !== ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.opencode)) {
17084
+ this.stopServer();
17032
17085
  this.client = null;
17033
- this.server = null;
17034
17086
  this.configuredModels.clear();
17035
17087
  }
17036
17088
  this.providerId = providerId;
@@ -17056,8 +17108,7 @@ var OpencodeManager = class extends CodingAgentManager {
17056
17108
  process.env.REPLICAS_COMMAND_PROTECTION_HOOK_PATH = getCommandProtectionHookPath();
17057
17109
  process.env.REPLICAS_POST_TOOL_PR_HOOK_PATH = getPostToolPrHookPath();
17058
17110
  process.env.REPLICAS_COMMAND_PROTECTION_RUNTIME_PATH = process.execPath;
17059
- this.eventAbortController?.abort();
17060
- this.server?.close();
17111
+ this.stopServer();
17061
17112
  const pathEntries = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
17062
17113
  if (!pathEntries.includes(OPENCODE_SHIM_DIR)) {
17063
17114
  process.env.PATH = [OPENCODE_SHIM_DIR, ...pathEntries].join(delimiter);
@@ -17080,6 +17131,7 @@ var OpencodeManager = class extends CodingAgentManager {
17080
17131
  };
17081
17132
  }
17082
17133
  if (this.originChatId) process.env.REPLICAS_CHAT_ID = this.originChatId;
17134
+ const credential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.opencode;
17083
17135
  const serverStart = createOpencodeServer({
17084
17136
  port: 0,
17085
17137
  timeout: OPENCODE_SERVER_STARTUP_TIMEOUT_MS,
@@ -17087,16 +17139,19 @@ var OpencodeManager = class extends CodingAgentManager {
17087
17139
  });
17088
17140
  delete process.env.REPLICAS_CHAT_ID;
17089
17141
  const server3 = await serverStart;
17142
+ const dispatcher = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
17090
17143
  const client = createOpencodeClient({
17091
17144
  baseUrl: server3.url,
17092
- fetch: opencodeFetch,
17145
+ fetch: opencodeFetch(dispatcher),
17093
17146
  headers: {
17094
17147
  Authorization: `Basic ${Buffer.from(`opencode:${password}`).toString("base64")}`
17095
17148
  }
17096
17149
  });
17097
17150
  this.client = client;
17098
17151
  this.server = server3;
17152
+ this.dispatcher = dispatcher;
17099
17153
  this.serverSubagentMcpParentChatId = subagentMcpParentChatId;
17154
+ this.serverCredential = credential;
17100
17155
  this.configuredModels = new Set(providerModels);
17101
17156
  const eventController = new AbortController();
17102
17157
  this.eventAbortController = eventController;
@@ -17118,6 +17173,13 @@ var OpencodeManager = class extends CodingAgentManager {
17118
17173
  finishUpdate();
17119
17174
  }
17120
17175
  }
17176
+ stopServer() {
17177
+ this.eventAbortController?.abort();
17178
+ this.server?.close();
17179
+ void this.dispatcher?.destroy();
17180
+ this.server = null;
17181
+ this.dispatcher = null;
17182
+ }
17121
17183
  async ensureSession(client, providerID, model, agent, variant) {
17122
17184
  if (this.sessionId) {
17123
17185
  try {
@@ -17157,15 +17219,30 @@ var OpencodeManager = class extends CodingAgentManager {
17157
17219
  if (!thinkingLevel) return void 0;
17158
17220
  return opencodeThinkingVariant(await this.getModelVariants(client, providerID, model), thinkingLevel);
17159
17221
  }
17160
- async processMessageInternal(request) {
17161
- const provider = await getOpencodeProvider();
17162
- const controller = new AbortController();
17222
+ async processMessageInternal(request, signal) {
17163
17223
  const linearForwarder = new LinearEventForwarder(() => this.linearSessionId);
17164
- this.handledAccountRateLimit = false;
17165
- this.activeAbortController = controller;
17166
17224
  this.activeLinearForwarder = linearForwarder;
17167
17225
  this.forwardedLinearPartKeys.clear();
17226
+ this.credentialSwitch = null;
17227
+ try {
17228
+ let retry = false;
17229
+ while (await this.promptTurn(request, linearForwarder, signal, retry)) retry = true;
17230
+ } finally {
17231
+ this.activeAbortController = null;
17232
+ this.activeLinearForwarder = null;
17233
+ this.forwardedLinearPartKeys.clear();
17234
+ await this.historyFile.flush();
17235
+ await this.onTurnComplete();
17236
+ }
17237
+ }
17238
+ async promptTurn(request, linearForwarder, signal, retry) {
17239
+ const controller = new AbortController();
17240
+ this.handledAccountRateLimit = false;
17241
+ this.activeAbortController = controller;
17242
+ if (signal.aborted) controller.abort();
17168
17243
  try {
17244
+ controller.signal.throwIfAborted();
17245
+ const provider = await getOpencodeProvider();
17169
17246
  const model = request.model ?? await getDefaultOpencodeModel(provider);
17170
17247
  const client = await this.ensureClient(model, provider);
17171
17248
  const { providerID, modelID } = opencodeModelRef(this.providerId, model);
@@ -17173,7 +17250,7 @@ var OpencodeManager = class extends CodingAgentManager {
17173
17250
  const variant = await this.getThinkingVariant(client, providerID, modelID, request.thinkingLevel);
17174
17251
  const sessionId = await this.ensureSession(client, providerID, modelID, agent, variant);
17175
17252
  const system = this.buildCombinedInstructions(request.customInstructions);
17176
- this.recordUserMessageHistoryEvent(request, this.historyFile);
17253
+ if (!retry) this.recordUserMessageHistoryEvent(request, this.historyFile);
17177
17254
  const result = await client.session.prompt({
17178
17255
  sessionID: sessionId,
17179
17256
  directory: this.workingDirectory,
@@ -17182,26 +17259,28 @@ var OpencodeManager = class extends CodingAgentManager {
17182
17259
  ...variant ? { variant } : {},
17183
17260
  ...system ? { system } : {},
17184
17261
  ...this.subagentMcpParentChatId() ? { tools: { task: false } } : {},
17185
- parts: [{ type: "text", text: request.message }]
17262
+ parts: [{ type: "text", text: retry ? OPENCODE_SWITCHED_CREDENTIAL_PROMPT : request.message }]
17186
17263
  }, { signal: controller.signal, throwOnError: true });
17187
17264
  this.recordHistoryEvent("opencode-message.updated", { info: result.data.info }, this.historyFile);
17188
17265
  for (const part of result.data.parts) this.recordOpencodePart(part);
17189
17266
  linearForwarder.flushThoughtAsResponse();
17190
17267
  this.recordHistoryEvent("opencode-session.idle", { sessionID: sessionId }, this.historyFile);
17191
17268
  } catch (error) {
17269
+ const credentialSwitch = this.credentialSwitch;
17270
+ if (credentialSwitch) {
17271
+ this.credentialSwitch = null;
17272
+ await credentialSwitch.catch(() => {
17273
+ });
17274
+ if (!signal.aborted) return true;
17275
+ }
17192
17276
  if (controller.signal.aborted) {
17193
17277
  this.recordHistoryEvent("opencode-session.idle", { sessionID: this.sessionId }, this.historyFile);
17194
17278
  } else {
17195
17279
  console.error("[OpencodeManager] Turn failed:", error);
17196
17280
  this.recordHistoryEvent("opencode-error", opencodeErrorPayload(error), this.historyFile);
17197
17281
  }
17198
- } finally {
17199
- this.activeAbortController = null;
17200
- this.activeLinearForwarder = null;
17201
- this.forwardedLinearPartKeys.clear();
17202
- await this.historyFile.flush();
17203
- await this.onTurnComplete();
17204
17282
  }
17283
+ return false;
17205
17284
  }
17206
17285
  async subscribeToEvents(client, controller) {
17207
17286
  let streamError;
@@ -17254,8 +17333,15 @@ var OpencodeManager = class extends CodingAgentManager {
17254
17333
  if (status?.type !== "retry" || action?.reason !== "account_rate_limit" || this.handledAccountRateLimit) return;
17255
17334
  this.handledAccountRateLimit = true;
17256
17335
  const message = typeof status.message === "string" ? status.message : typeof action.message === "string" ? action.message : "OpenCode Go usage limit reached.";
17336
+ const controller = this.activeAbortController;
17337
+ const fallback = await this.fallBackCredential("rate_limit", message, this.serverCredential);
17338
+ if (!controller || controller.signal.aborted || controller !== this.activeAbortController) return;
17339
+ if (fallback.outcome === "switched") {
17340
+ this.credentialSwitch = this.abortActiveTurn();
17341
+ await this.credentialSwitch;
17342
+ return;
17343
+ }
17257
17344
  this.recordHistoryEvent("opencode-error", { message, code: "account_rate_limit" }, this.historyFile);
17258
- const fallback = await this.fallBackCredential("rate_limit", message);
17259
17345
  this.emitQuotaExhausted({
17260
17346
  provider: "opencode",
17261
17347
  reason: "rate_limit",
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  publishedPullRequestUrls
6
- } from "./chunk-IU3ZJUGP.js";
6
+ } from "./chunk-THAFUTL3.js";
7
7
  import {
8
8
  isRecord
9
9
  } from "./chunk-UZSNFLDQ.js";
10
10
  import {
11
11
  shouldRefreshPullRequests
12
- } from "./chunk-J5KG7UVX.js";
12
+ } from "./chunk-5YU4KQIU.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/services/post-tool-pr-notifier.ts
@@ -11,7 +11,7 @@ import {
11
11
  spawnSubagentRequestSchema,
12
12
  subagentResponseSchema,
13
13
  waitSubagentRequestSchema
14
- } from "./chunk-J5KG7UVX.js";
14
+ } from "./chunk-5YU4KQIU.js";
15
15
  import "./chunk-VEQXQN22.js";
16
16
 
17
17
  // src/subagent-mcp.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.1280",
3
+ "version": "0.1.1281",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",