replicas-engine 0.1.1036 → 0.1.1038

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.
@@ -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-3OBN7KPB.js";
6
+ } from "./chunk-MUS3ULTT.js";
7
7
  import {
8
8
  isRecord
9
9
  } from "./chunk-UZSNFLDQ.js";
10
10
  import {
11
11
  shouldRefreshPullRequests
12
- } from "./chunk-OPJ5KAGY.js";
12
+ } from "./chunk-MALHGZWB.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/services/post-tool-pr-notifier.ts
@@ -9,7 +9,7 @@ import {
9
9
  spawnSubagentRequestSchema,
10
10
  subagentResponseSchema,
11
11
  waitSubagentRequestSchema
12
- } from "./chunk-OPJ5KAGY.js";
12
+ } from "./chunk-MALHGZWB.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/subagent-mcp.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.1036",
3
+ "version": "0.1.1038",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -1,527 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire as __createRequire } from 'node:module';
3
- const require = __createRequire(import.meta.url);
4
- import {
5
- ENGINE_ENV,
6
- monolithRequest,
7
- setAgentCredentialSnapshot
8
- } from "./chunk-2RHUTB67.js";
9
- import {
10
- AppServerProcess,
11
- buildCodexAgentEnv
12
- } from "./chunk-AP442WDC.js";
13
- import {
14
- SUBPROCESS_MAX_BUFFER,
15
- execFileAsync
16
- } from "./chunk-KVJYQOUT.js";
17
- import {
18
- isRecord
19
- } from "./chunk-UZSNFLDQ.js";
20
- import {
21
- CODEX_AUTH_ENV_KEYS,
22
- CODEX_AUTH_ENV_KEYS_BY_METHOD,
23
- codexAuthEnvFromResponse,
24
- createErrorResult,
25
- createSuccessResult,
26
- isSameCredential,
27
- listOllamaModels,
28
- listOpenAICompatibleModels,
29
- readOllamaAuthEnv,
30
- resolveOpenAICompatibleModelsUrl
31
- } from "./chunk-OPJ5KAGY.js";
32
-
33
- // src/managers/codex-token-manager.ts
34
- import { promises as fs } from "fs";
35
- import path from "path";
36
-
37
- // src/managers/auth-env-transition.ts
38
- function applyAuthEnvTransition(params) {
39
- const prevOwned = new Set(params.authKeysByMethod[params.prevMethod]);
40
- for (const key of params.authKeys) {
41
- const value = params.newEnvVars[key];
42
- if (value !== void 0) {
43
- for (const env of params.envs) {
44
- env[key] = value;
45
- }
46
- } else if (prevOwned.has(key)) {
47
- for (const env of params.envs) {
48
- delete env[key];
49
- }
50
- }
51
- }
52
- }
53
-
54
- // src/services/credential-fallbacks.ts
55
- var fallbacksByAgent = /* @__PURE__ */ new Map();
56
- var exhaustedByAgent = /* @__PURE__ */ new Map();
57
- function clearCredentialFallbacks(provider) {
58
- fallbacksByAgent.delete(provider);
59
- exhaustedByAgent.delete(provider);
60
- }
61
- function recordCredentialFallback(notice) {
62
- fallbacksByAgent.set(notice.provider, notice);
63
- }
64
- function listCredentialFallbacks() {
65
- return [...fallbacksByAgent.values()].filter((notice) => {
66
- const live = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS[notice.provider];
67
- if (!live) return false;
68
- return notice.status === "switched" ? live.method === notice.candidateMethod && live.scope === notice.candidateScope : live.method === notice.exhaustedMethod && live.scope === notice.exhaustedScope;
69
- });
70
- }
71
- function listExhaustedCredentials(provider) {
72
- return [...exhaustedByAgent.get(provider)?.values() ?? []];
73
- }
74
- function routineRefreshRequest(provider) {
75
- const live = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS[provider];
76
- const excludeCredentials = listExhaustedCredentials(provider).filter((spent) => !live || !isSameCredential(spent, live));
77
- return {
78
- ...excludeCredentials.length > 0 ? { excludeCredentials } : {},
79
- ...live ? { currentCredential: live } : {}
80
- };
81
- }
82
- function recordExhaustedCredential(provider, credential) {
83
- const spent = exhaustedByAgent.get(provider) ?? /* @__PURE__ */ new Map();
84
- spent.set(`${credential.method}|${credential.scope}|${credential.credentialId ?? ""}`, credential);
85
- exhaustedByAgent.set(provider, spent);
86
- }
87
-
88
- // src/managers/base-refresh-manager.ts
89
- function credentialSwapError(error) {
90
- const message = error instanceof Error ? error.message : String(error);
91
- return createErrorResult({
92
- message,
93
- code: message.includes('"code":"no_credentials"') ? "no_credentials" : "refresh_failed"
94
- });
95
- }
96
- function refreshDelayMs(expiresAtMs, maxMs = 5 * 60 * 1e3) {
97
- const ttlMs = expiresAtMs - Date.now();
98
- return Number.isFinite(ttlMs) ? Math.max(1e3, Math.min(maxMs, Math.floor(ttlMs * 0.8))) : maxMs;
99
- }
100
- var BaseRefreshManager = class {
101
- constructor(managerName, intervalMs = 15 * 60 * 1e3) {
102
- this.managerName = managerName;
103
- this.intervalMs = intervalMs;
104
- this.health = {
105
- isRunning: false,
106
- intervalMs: this.intervalMs,
107
- lastAttemptAt: null,
108
- lastSuccessAt: null,
109
- lastErrorAt: null,
110
- lastErrorMessage: null
111
- };
112
- }
113
- managerName;
114
- intervalMs;
115
- credentialGeneration = 0;
116
- credentialUpdate = Promise.resolve();
117
- intervalHandle = null;
118
- pendingRefresh = null;
119
- health;
120
- async start(skipInitialRefresh = false) {
121
- if (this.intervalHandle) {
122
- return;
123
- }
124
- const skipReason = this.getSkipReason();
125
- if (skipReason) {
126
- console.log(`[${this.managerName}] Skipping: ${skipReason}`);
127
- return;
128
- }
129
- console.log(`[${this.managerName}] Starting token refresh service`);
130
- this.health.isRunning = true;
131
- const config = this.getRuntimeConfig();
132
- if (config && !skipInitialRefresh) {
133
- this.health.lastAttemptAt = (/* @__PURE__ */ new Date()).toISOString();
134
- for (let attempt = 1; attempt <= 3; attempt++) {
135
- try {
136
- await this.doRefresh(config);
137
- this.health.lastSuccessAt = (/* @__PURE__ */ new Date()).toISOString();
138
- this.health.lastErrorAt = null;
139
- this.health.lastErrorMessage = null;
140
- break;
141
- } catch (error) {
142
- const message = error instanceof Error ? error.message : "Unknown error";
143
- this.health.lastErrorAt = (/* @__PURE__ */ new Date()).toISOString();
144
- this.health.lastErrorMessage = message;
145
- if (attempt < 3) {
146
- console.warn(`[${this.managerName}] Initial refresh attempt ${attempt} failed, retrying in 2s...`);
147
- await new Promise((resolve) => setTimeout(resolve, 2e3));
148
- } else {
149
- console.error(`[${this.managerName}] Initial refresh failed after 3 attempts:`, error);
150
- }
151
- }
152
- }
153
- }
154
- this.scheduleNextRefresh();
155
- }
156
- async swapCredentials(params) {
157
- if (!this.getRuntimeConfig()) {
158
- return createErrorResult({ message: `${this.managerName} has no runtime config`, code: "not_configured" });
159
- }
160
- try {
161
- console.log(`[${this.managerName}] Fetching fresh credentials from monolith (${params.failureKind})...`);
162
- const excludeCredentials = listExhaustedCredentials(params.provider);
163
- await params.refresh({
164
- ...excludeCredentials.length > 0 ? { excludeCredentials } : {},
165
- ...params.allowedMethods ? { allowedMethods: [...params.allowedMethods] } : {}
166
- });
167
- if (params.isOauthNow()) {
168
- this.start().catch((error) => {
169
- console.error(`[${this.managerName}] Failed to restart OAuth refresh service after fallback:`, error);
170
- });
171
- }
172
- return createSuccessResult();
173
- } catch (error) {
174
- console.error(`[${this.managerName}] Failed to fetch fresh credentials:`, error);
175
- return credentialSwapError(error);
176
- }
177
- }
178
- async stop() {
179
- if (this.intervalHandle) clearTimeout(this.intervalHandle);
180
- this.intervalHandle = null;
181
- this.health.isRunning = false;
182
- await this.pendingRefresh;
183
- console.log(`[${this.managerName}] Stopped`);
184
- }
185
- getHealthStatus() {
186
- return { ...this.health };
187
- }
188
- getSkipReason() {
189
- return null;
190
- }
191
- getNextRefreshDelayMs() {
192
- return this.intervalMs;
193
- }
194
- applyCredentialUpdate(generation, apply) {
195
- const update = this.credentialUpdate.then(async () => {
196
- if (generation !== this.credentialGeneration) throw new Error("Credential changed during refresh; retry with the current credential.");
197
- await apply();
198
- });
199
- this.credentialUpdate = update.catch(() => {
200
- });
201
- return update;
202
- }
203
- getRuntimeConfig() {
204
- if (!ENGINE_ENV.REPLICAS_WORKSPACE_ID) {
205
- return null;
206
- }
207
- return {
208
- monolithUrl: ENGINE_ENV.REPLICAS_MONOLITH_URL,
209
- workspaceId: ENGINE_ENV.REPLICAS_WORKSPACE_ID,
210
- engineSecret: ENGINE_ENV.REPLICAS_ENGINE_SECRET
211
- };
212
- }
213
- scheduleNextRefresh() {
214
- const delayMs = this.getNextRefreshDelayMs();
215
- this.health.intervalMs = delayMs;
216
- this.intervalHandle = setTimeout(async () => {
217
- this.pendingRefresh = this.refreshOnce();
218
- await this.pendingRefresh;
219
- if (this.intervalHandle) this.scheduleNextRefresh();
220
- }, delayMs);
221
- console.log(`[${this.managerName}] Token refresh scheduled in ${Math.round(delayMs / 1e3)} seconds`);
222
- }
223
- async refreshOnce(force = false) {
224
- if (!force && this.getSkipReason()) {
225
- return createSuccessResult();
226
- }
227
- const config = this.getRuntimeConfig();
228
- if (!config) return createSuccessResult();
229
- this.health.lastAttemptAt = (/* @__PURE__ */ new Date()).toISOString();
230
- try {
231
- await this.doRefresh(config);
232
- this.health.lastSuccessAt = (/* @__PURE__ */ new Date()).toISOString();
233
- this.health.lastErrorAt = null;
234
- this.health.lastErrorMessage = null;
235
- return createSuccessResult();
236
- } catch (error) {
237
- const message = error instanceof Error ? error.message : "Unknown error";
238
- this.health.lastErrorAt = (/* @__PURE__ */ new Date()).toISOString();
239
- this.health.lastErrorMessage = message;
240
- console.error(`[${this.managerName}] Failed to refresh credentials:`, error);
241
- return createErrorResult({ message });
242
- }
243
- }
244
- };
245
-
246
- // src/managers/codex-token-manager.ts
247
- var CodexAspAuthMethodChangedError = class extends Error {
248
- name = "CodexAspAuthMethodChangedError";
249
- };
250
- var CodexTokenManager = class extends BaseRefreshManager {
251
- constructor() {
252
- super("CodexTokenManager");
253
- }
254
- getSkipReason() {
255
- if (!ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD && ENGINE_ENV.OPENAI_API_KEY) {
256
- return "OPENAI_API_KEY is set";
257
- }
258
- return null;
259
- }
260
- async doRefresh(_config) {
261
- await this.refreshWithRequest(routineRefreshRequest("codex"), true);
262
- }
263
- async switchCredentials(data) {
264
- await this.applyCredentialUpdate(++this.credentialGeneration, async () => {
265
- await this.applyCredentialsResponse(data);
266
- setAgentCredentialSnapshot("codex", data);
267
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-4JQWKA47.js");
268
- await restartCodexAspHostIfRunning2();
269
- });
270
- await this.start(true);
271
- }
272
- async refreshWithRequest(request, restartOnChange = false) {
273
- const generation = this.credentialGeneration;
274
- const previousEnv = CODEX_AUTH_ENV_KEYS.map((key) => process.env[key]);
275
- console.log("[CodexTokenManager] Refreshing Codex credentials...");
276
- const response = await monolithRequest("/v1/engine/codex/refresh-credentials", {
277
- body: { supportsOpenAICompatibleAuth: true, ...request }
278
- });
279
- if (!response.ok) {
280
- const errorText = await response.text();
281
- throw new Error(`Credentials refresh failed: ${response.status} ${errorText}`);
282
- }
283
- const data = await response.json();
284
- await this.applyCredentialUpdate(generation, async () => {
285
- const accountChanged = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex?.credentialId !== data.credentialId;
286
- await this.applyCredentialsResponse(data);
287
- if (restartOnChange && (accountChanged || CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index]))) {
288
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-4JQWKA47.js");
289
- await restartCodexAspHostIfRunning2();
290
- }
291
- setAgentCredentialSnapshot("codex", data);
292
- });
293
- console.log(`[CodexTokenManager] Credentials refreshed (method=${data.type})`);
294
- return data;
295
- }
296
- async prepareAspOauthOptions() {
297
- if (ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD !== "oauth") return {};
298
- const response = await this.refreshWithRequest(routineRefreshRequest("codex"));
299
- if (response.type !== "oauth") return {};
300
- const login = this.buildAspOauthLogin(response);
301
- let credential = login.credential;
302
- return {
303
- chatgptAuthTokens: login.tokens,
304
- refreshChatgptAuthTokens: async (params) => {
305
- const refreshed = await this.refreshAspOauthCredentials(
306
- credential,
307
- `Codex ASP requested an external token refresh (${params.reason})`
308
- );
309
- if (!refreshed.ok) {
310
- if (refreshed.error.code === "method_changed") {
311
- throw new CodexAspAuthMethodChangedError(refreshed.error.message);
312
- }
313
- throw new Error(refreshed.error.message);
314
- }
315
- credential = refreshed.data.credential;
316
- return refreshed.data.tokens;
317
- }
318
- };
319
- }
320
- async refreshAspOauthCredentials(failedCredential, failureReason) {
321
- try {
322
- const response = await this.refreshWithRequest({
323
- failedMethod: "oauth",
324
- ...failedCredential?.method === "oauth" ? { failedCredential } : {},
325
- failureKind: "rejected",
326
- failureReason
327
- });
328
- if (response.type !== "oauth") {
329
- return createErrorResult({
330
- message: `${failureReason}; credentials changed to ${response.type}, so the app server must restart`,
331
- code: "method_changed"
332
- });
333
- }
334
- return createSuccessResult(this.buildAspOauthLogin(response));
335
- } catch (error) {
336
- return credentialSwapError(error);
337
- }
338
- }
339
- async fetchFreshCredentials(failureReason, failureKind = "rejected", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex, allowedMethods) {
340
- const failedMethod = failedCredential?.method === "ollama" || failedCredential?.method === "oauth" || failedCredential?.method === "api_key" || failedCredential?.method === "openai-compatible" || failedCredential?.method === "foundry" ? failedCredential.method : ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD;
341
- return this.swapCredentials({
342
- provider: "codex",
343
- failureKind,
344
- allowedMethods,
345
- refresh: async (exclusions) => {
346
- await this.refreshWithRequest(
347
- failedMethod === "ollama" || failedMethod === "oauth" || failedMethod === "api_key" || failedMethod === "openai-compatible" || failedMethod === "foundry" ? {
348
- failedMethod,
349
- ...failedCredential?.method === failedMethod ? { failedCredential } : {},
350
- failureReason,
351
- failureKind,
352
- ...exclusions
353
- } : exclusions
354
- );
355
- },
356
- isOauthNow: () => ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD === "oauth"
357
- });
358
- }
359
- async applyCredentialsResponse(response) {
360
- await this.removeOauthCredentialsFile();
361
- const envVars = codexAuthEnvFromResponse(response);
362
- applyAuthEnvTransition({
363
- prevMethod: ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD ?? "none",
364
- authKeys: CODEX_AUTH_ENV_KEYS,
365
- authKeysByMethod: CODEX_AUTH_ENV_KEYS_BY_METHOD,
366
- newEnvVars: envVars,
367
- envs: [ENGINE_ENV, process.env]
368
- });
369
- if (response.type === "api_key") {
370
- for (const key of CODEX_AUTH_ENV_KEYS_BY_METHOD.api_key) {
371
- if (envVars[key] !== void 0) continue;
372
- delete ENGINE_ENV[key];
373
- delete process.env[key];
374
- }
375
- }
376
- }
377
- buildAspOauthLogin(response) {
378
- const credential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex;
379
- return {
380
- tokens: {
381
- accessToken: response.accessToken,
382
- chatgptAccountId: response.accountId,
383
- chatgptPlanType: null
384
- },
385
- ...credential?.method === "oauth" ? { credential } : {}
386
- };
387
- }
388
- async removeOauthCredentialsFile() {
389
- const authPath = path.join(ENGINE_ENV.HOME_DIR, ".codex", "auth.json");
390
- try {
391
- await fs.unlink(authPath);
392
- } catch (error) {
393
- if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) throw error;
394
- }
395
- }
396
- };
397
- var codexTokenManager = new CodexTokenManager();
398
-
399
- // src/managers/codex-asp/openai-compatible-model-catalog.ts
400
- import { writeFile } from "fs/promises";
401
- import { tmpdir } from "os";
402
- import { join } from "path";
403
- var CATALOG_TTL_MS = 6e4;
404
- var CODEX_MODEL_CATALOG_PATH = join(tmpdir(), "replicas-openai-compatible-model-catalog.json");
405
- var cachedCatalog = null;
406
- async function writeCodexModelCatalog(modelsUrl) {
407
- const ollama = ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD === "ollama" ? readOllamaAuthEnv("codex", process.env) : null;
408
- const [models, { stdout }] = await Promise.all([
409
- ollama ? listOllamaModels(ollama) : listOpenAICompatibleModels({
410
- apiKey: ENGINE_ENV.OPENAI_API_KEY,
411
- authorizationHeader: ENGINE_ENV.CODEX_OPENAI_AUTHORIZATION_HEADER,
412
- baseUrl: ENGINE_ENV.CODEX_OPENAI_BASE_URL ?? "",
413
- modelsUrl
414
- }),
415
- execFileAsync("codex", ["debug", "models"], { maxBuffer: SUBPROCESS_MAX_BUFFER })
416
- ]);
417
- const payload = JSON.parse(stdout);
418
- const template = isRecord(payload) && Array.isArray(payload.models) ? payload.models.find((model) => isRecord(model) && model.slug === "gpt-5.2") ?? payload.models.find(isRecord) : null;
419
- if (!isRecord(template)) throw new Error("Codex did not return a model catalog template");
420
- await writeFile(CODEX_MODEL_CATALOG_PATH, JSON.stringify({
421
- models: models.flatMap((model) => model.contextWindow ? [{
422
- ...template,
423
- ...ollama ? { apply_patch_tool_type: null, support_verbosity: false, supports_search_tool: false, input_modalities: ["text"] } : {},
424
- slug: model.id,
425
- display_name: model.displayName,
426
- description: model.description ?? model.displayName,
427
- context_window: model.contextWindow,
428
- max_context_window: model.contextWindow,
429
- effective_context_window_percent: 100,
430
- auto_compact_token_limit: Math.floor(model.contextWindow * 0.9)
431
- }] : [])
432
- }));
433
- return [
434
- `model_catalog_json=${JSON.stringify(CODEX_MODEL_CATALOG_PATH)}`,
435
- "features.remote_models=false"
436
- ];
437
- }
438
- async function getOpenAICompatibleCodexModelCatalogConfig() {
439
- if (ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD !== "openai-compatible" && ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD !== "ollama" || !ENGINE_ENV.CODEX_OPENAI_BASE_URL) return [];
440
- const modelsUrl = resolveOpenAICompatibleModelsUrl({
441
- baseUrl: ENGINE_ENV.CODEX_OPENAI_BASE_URL,
442
- modelsUrl: ENGINE_ENV.CODEX_OPENAI_MODELS_URL ?? ""
443
- });
444
- const key = `${modelsUrl}:${JSON.stringify(ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.codex ?? null)}`;
445
- if (!cachedCatalog || cachedCatalog.key !== key || cachedCatalog.expiresAt <= Date.now()) {
446
- cachedCatalog = {
447
- key,
448
- expiresAt: Date.now() + CATALOG_TTL_MS,
449
- config: writeCodexModelCatalog(modelsUrl).catch((error) => {
450
- console.warn("[CodexAspManager] Failed to prepare OpenAI-compatible model catalog:", error);
451
- return [];
452
- })
453
- };
454
- }
455
- return cachedCatalog.config;
456
- }
457
-
458
- // src/managers/codex-asp/asp-host.ts
459
- var hostPromise = null;
460
- var activeProcess = null;
461
- var restartPromise = null;
462
- async function getCodexAspHost() {
463
- if (restartPromise) {
464
- await restartPromise;
465
- }
466
- hostPromise ??= (async () => {
467
- try {
468
- const oauthOptions = await codexTokenManager.prepareAspOauthOptions();
469
- const process2 = new AppServerProcess({
470
- cwd: ENGINE_ENV.WORKSPACE_ROOT,
471
- env: buildCodexAgentEnv(),
472
- configOverrides: await getOpenAICompatibleCodexModelCatalogConfig(),
473
- ...oauthOptions
474
- });
475
- const { client } = await process2.start();
476
- activeProcess = process2;
477
- process2.on("exit", () => {
478
- if (activeProcess === process2) {
479
- activeProcess = null;
480
- }
481
- hostPromise = null;
482
- });
483
- return { client };
484
- } catch (error) {
485
- hostPromise = null;
486
- throw error;
487
- }
488
- })();
489
- return hostPromise;
490
- }
491
- async function restartCodexAspHost() {
492
- if (restartPromise) {
493
- return restartPromise;
494
- }
495
- restartPromise = (async () => {
496
- const process2 = activeProcess;
497
- hostPromise = null;
498
- activeProcess = null;
499
- if (process2) {
500
- await process2.stop();
501
- }
502
- })();
503
- try {
504
- await restartPromise;
505
- } finally {
506
- restartPromise = null;
507
- }
508
- }
509
- async function restartCodexAspHostIfRunning() {
510
- if (activeProcess) await restartCodexAspHost();
511
- }
512
-
513
- export {
514
- clearCredentialFallbacks,
515
- recordCredentialFallback,
516
- listCredentialFallbacks,
517
- routineRefreshRequest,
518
- recordExhaustedCredential,
519
- refreshDelayMs,
520
- BaseRefreshManager,
521
- applyAuthEnvTransition,
522
- getCodexAspHost,
523
- restartCodexAspHost,
524
- restartCodexAspHostIfRunning,
525
- CodexAspAuthMethodChangedError,
526
- codexTokenManager
527
- };