@rynfar/meridian 1.42.1 → 1.44.0

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.
@@ -31,10 +31,10 @@ import {
31
31
  resolveClaudeExecutableAsync,
32
32
  resolveSdkModelDefaults,
33
33
  stripExtendedContext
34
- } from "./cli-3jqvrake.js";
34
+ } from "./cli-yeazzt32.js";
35
35
  import {
36
36
  checkPluginConfigured
37
- } from "./cli-rtab0qa6.js";
37
+ } from "./cli-je60fevk.js";
38
38
  import {
39
39
  claudeLog,
40
40
  createPlatformCredentialStore,
@@ -43,7 +43,7 @@ import {
43
43
  startBackgroundRefresh,
44
44
  stopBackgroundRefresh,
45
45
  withClaudeLogContext
46
- } from "./cli-7k1fcprd.js";
46
+ } from "./cli-1kbcm3yn.js";
47
47
  import {
48
48
  __commonJS,
49
49
  __esm,
@@ -1242,7 +1242,7 @@ function getFeaturesForAdapter(adapterName) {
1242
1242
  };
1243
1243
  }
1244
1244
  function getAllFeatureConfigs() {
1245
- const adapters = ["opencode", "crush", "forgecode", "pi", "droid", "passthrough"];
1245
+ const adapters = ["opencode", "crush", "forgecode", "pi", "droid", "passthrough", "openai"];
1246
1246
  const result = {};
1247
1247
  for (const name of adapters) {
1248
1248
  result[name] = getFeaturesForAdapter(name);
@@ -1314,6 +1314,9 @@ var init_sdkFeatures = __esm(() => {
1314
1314
  ADAPTER_DEFAULTS = {
1315
1315
  passthrough: {
1316
1316
  codeSystemPrompt: false
1317
+ },
1318
+ openai: {
1319
+ codeSystemPrompt: false
1317
1320
  }
1318
1321
  };
1319
1322
  VALID_CLAUDE_MD_VALUES = new Set(["off", "project", "full"]);
@@ -3889,7 +3892,7 @@ var DEFAULT_PROXY_CONFIG = {
3889
3892
  host: "127.0.0.1",
3890
3893
  debug: (process.env.MERIDIAN_DEBUG ?? process.env.CLAUDE_PROXY_DEBUG) === "1",
3891
3894
  idleTimeoutSeconds: 120,
3892
- silent: false,
3895
+ silent: (process.env.MERIDIAN_SILENT ?? process.env.CLAUDE_PROXY_SILENT) === "1",
3893
3896
  profiles: undefined,
3894
3897
  defaultProfile: undefined,
3895
3898
  version: undefined
@@ -9193,7 +9196,7 @@ function isRateLimitError(errMsg) {
9193
9196
  }
9194
9197
  function isExtraUsageRequiredError(errMsg) {
9195
9198
  const lower = errMsg.toLowerCase();
9196
- return lower.includes("extra usage") && lower.includes("1m");
9199
+ return lower.includes("extra usage") && lower.includes("1m") || lower.includes("out of extra usage");
9197
9200
  }
9198
9201
  var STDERR_TAIL_MAX = 500;
9199
9202
  var RAW_TAIL_MAX = 300;
@@ -9479,6 +9482,10 @@ ${historyBlock}` : historyBlock;
9479
9482
  result.temperature = body.temperature;
9480
9483
  if (body.top_p !== undefined)
9481
9484
  result.top_p = body.top_p;
9485
+ if (body.reasoning_effort !== undefined)
9486
+ result.reasoning_effort = body.reasoning_effort;
9487
+ if (body.output_config?.effort !== undefined)
9488
+ result.output_config = { effort: body.output_config.effort };
9482
9489
  return result;
9483
9490
  }
9484
9491
  function toFinishReason(stopReason) {
@@ -9653,6 +9660,14 @@ function buildModelList(isMaxSubscription, now = Math.floor(Date.now() / 1000))
9653
9660
  display_name: "Claude Opus 4.7",
9654
9661
  context_window: isMaxSubscription ? 1e6 : 200000
9655
9662
  },
9663
+ {
9664
+ id: "claude-opus-4-8",
9665
+ object: "model",
9666
+ created: now,
9667
+ owned_by: "anthropic",
9668
+ display_name: "Claude Opus 4.8",
9669
+ context_window: isMaxSubscription ? 1e6 : 200000
9670
+ },
9656
9671
  {
9657
9672
  id: "claude-haiku-4-5",
9658
9673
  object: "model",
@@ -10732,6 +10747,12 @@ var claudeCodeAdapter = {
10732
10747
  }
10733
10748
  };
10734
10749
 
10750
+ // src/proxy/adapters/openai.ts
10751
+ var openAiAdapter = {
10752
+ ...openCodeAdapter,
10753
+ name: "openai"
10754
+ };
10755
+
10735
10756
  // src/proxy/adapters/detect.ts
10736
10757
  var ADAPTER_MAP = {
10737
10758
  opencode: openCodeAdapter,
@@ -10741,7 +10762,8 @@ var ADAPTER_MAP = {
10741
10762
  pi: piAdapter,
10742
10763
  forgecode: forgeCodeAdapter,
10743
10764
  "claude-code": claudeCodeAdapter,
10744
- claudecode: claudeCodeAdapter
10765
+ claudecode: claudeCodeAdapter,
10766
+ openai: openAiAdapter
10745
10767
  };
10746
10768
  var envDefault = process.env.MERIDIAN_DEFAULT_AGENT || "";
10747
10769
  if (envDefault && !ADAPTER_MAP[envDefault]) {
@@ -16597,7 +16619,8 @@ function buildQueryOptions(ctx) {
16597
16619
  ...sharedMemory ? stripConfigDir(cleanEnv) : cleanEnv,
16598
16620
  ENABLE_TOOL_SEARCH: hasDeferredTools ? "true" : "false",
16599
16621
  ...passthrough ? { ENABLE_CLAUDEAI_MCP_SERVERS: "false" } : {},
16600
- ...process.getuid?.() === 0 ? { IS_SANDBOX: "1" } : {}
16622
+ ...process.getuid?.() === 0 ? { IS_SANDBOX: "1" } : {},
16623
+ ...ctx.envOverrides
16601
16624
  },
16602
16625
  ...Object.keys(sdkAgents).length > 0 ? { agents: sdkAgents } : {},
16603
16626
  ...resumeSessionId ? { resume: resumeSessionId } : {},
@@ -16616,6 +16639,12 @@ function buildQueryOptions(ctx) {
16616
16639
  };
16617
16640
  }
16618
16641
 
16642
+ // src/proxy/effort.ts
16643
+ var VALID_EFFORTS = ["low", "medium", "high", "xhigh", "max"];
16644
+ function normalizeEffort(value) {
16645
+ return typeof value === "string" && VALID_EFFORTS.includes(value) ? value : undefined;
16646
+ }
16647
+
16619
16648
  // src/proxy/transforms/registry.ts
16620
16649
  var ADAPTER_TRANSFORMS = {
16621
16650
  opencode: openCodeTransforms,
@@ -16623,7 +16652,8 @@ var ADAPTER_TRANSFORMS = {
16623
16652
  droid: droidTransforms,
16624
16653
  pi: piTransforms,
16625
16654
  forgecode: forgeCodeTransforms,
16626
- passthrough: passthroughTransforms
16655
+ passthrough: passthroughTransforms,
16656
+ openai: openCodeTransforms
16627
16657
  };
16628
16658
  function getAdapterTransforms(adapterName) {
16629
16659
  return ADAPTER_TRANSFORMS[adapterName] ?? [];
@@ -17495,6 +17525,22 @@ function storeSession(sessionId, messages, claudeSessionId, workingDirectory, sd
17495
17525
  // src/proxy/server.ts
17496
17526
  var exec2 = promisify2(execCallback);
17497
17527
  var claudeExecutable = "";
17528
+ function credentialStoreForProfile(profile) {
17529
+ if (profile.type !== "claude-max")
17530
+ return;
17531
+ return createPlatformCredentialStore(profile.env.CLAUDE_CONFIG_DIR ? { claudeConfigDir: profile.env.CLAUDE_CONFIG_DIR } : undefined);
17532
+ }
17533
+ async function ensureFreshTokenForProfiles(config) {
17534
+ const profiles = getEffectiveProfiles(config.profiles);
17535
+ if (profiles.length === 0)
17536
+ return;
17537
+ for (const profile of profiles) {
17538
+ const resolved = resolveProfile(config.profiles, config.defaultProfile, profile.id);
17539
+ const store = credentialStoreForProfile(resolved);
17540
+ if (store)
17541
+ await ensureFreshToken(store).catch(() => {});
17542
+ }
17543
+ }
17498
17544
  var MULTIMODAL_TYPES = new Set(["image", "document", "file"]);
17499
17545
  function hasMultimodalContent(content) {
17500
17546
  if (!Array.isArray(content))
@@ -17618,8 +17664,13 @@ function buildFreshPrompt(messages, sanitizeOpts = {}) {
17618
17664
 
17619
17665
  `) || "";
17620
17666
  }
17667
+ var proxyLogSilent = false;
17668
+ function plog(message) {
17669
+ if (!proxyLogSilent)
17670
+ console.error(message);
17671
+ }
17621
17672
  function logUsage(requestId, usage) {
17622
- console.error(`[PROXY] ${requestId} usage: ${formatUsageSummary(usage)}`);
17673
+ plog(`[PROXY] ${requestId} usage: ${formatUsageSummary(usage)}`);
17623
17674
  }
17624
17675
  function checkTokenHealth(requestId, sdkSessionId, usage, turnNumber, isResume, isPassthrough) {
17625
17676
  if (!usage || !sdkSessionId)
@@ -17652,7 +17703,7 @@ function checkTokenHealth(requestId, sdkSessionId, usage, turnNumber, isResume,
17652
17703
  if (anomalies.length > 0) {
17653
17704
  const alerts = formatAnomalyAlerts(requestId, anomalies);
17654
17705
  for (const line of alerts) {
17655
- console.error(line);
17706
+ plog(line);
17656
17707
  }
17657
17708
  for (const a of anomalies) {
17658
17709
  diagnosticLog2.log({
@@ -17666,6 +17717,7 @@ function checkTokenHealth(requestId, sdkSessionId, usage, turnNumber, isResume,
17666
17717
  }
17667
17718
  function createProxyServer(config = {}) {
17668
17719
  const finalConfig = { ...DEFAULT_PROXY_CONFIG, ...config };
17720
+ proxyLogSilent = finalConfig.silent;
17669
17721
  const serverVersion = finalConfig.version ?? "unknown";
17670
17722
  restoreActiveProfile(finalConfig.profiles);
17671
17723
  const sessionDiscoveredTools = new Map;
@@ -17747,7 +17799,9 @@ function createProxyServer(config = {}) {
17747
17799
  const authStatus = await getClaudeAuthStatusAsync(profile.id !== "default" ? profile.id : undefined, Object.keys(profile.env).length > 0 ? profile.env : undefined);
17748
17800
  const agentMode = c.req.header("x-opencode-agent-mode") ?? null;
17749
17801
  const requestSource = c.req.header("x-meridian-source")?.slice(0, 64) || undefined;
17750
- let model = mapModelToClaudeModel(body.model || "sonnet", authStatus?.subscriptionType, agentMode);
17802
+ const requestedModel = typeof body.model === "string" ? body.model : "sonnet";
17803
+ let model = mapModelToClaudeModel(requestedModel, authStatus?.subscriptionType, agentMode);
17804
+ const envOverrides = requestedModel.startsWith("claude-opus-") ? { ANTHROPIC_DEFAULT_OPUS_MODEL: requestedModel } : undefined;
17751
17805
  const cwdResolution = resolveSdkWorkingDirectory({
17752
17806
  envOverride: process.env.MERIDIAN_WORKDIR ?? process.env.CLAUDE_PROXY_WORKDIR,
17753
17807
  adapterCwd: adapter.extractWorkingDirectory(body),
@@ -17771,6 +17825,7 @@ function createProxyServer(config = {}) {
17771
17825
  } = process.env;
17772
17826
  const sdkModelDefaults = resolveSdkModelDefaults();
17773
17827
  const profileEnv = { ...sdkModelDefaults, ...cleanEnv, ...profile.env };
17828
+ const profileCredentialStore = credentialStoreForProfile(profile);
17774
17829
  let systemContext = "";
17775
17830
  if (body.system) {
17776
17831
  if (typeof body.system === "string") {
@@ -17800,15 +17855,15 @@ function createProxyServer(config = {}) {
17800
17855
  const rawBetaHeader = c.req.header("anthropic-beta");
17801
17856
  const betaFilter = filterBetasForProfile(rawBetaHeader, profile.type, getBetaPolicyFromEnv());
17802
17857
  if (betaFilter.stripped.length > 0) {
17803
- console.error(`[PROXY] ${requestMeta.requestId} stripped anthropic-beta(s) for Max profile: ${betaFilter.stripped.join(", ")}`);
17858
+ plog(`[PROXY] ${requestMeta.requestId} stripped anthropic-beta(s) for Max profile: ${betaFilter.stripped.join(", ")}`);
17804
17859
  }
17805
- const effort = effortHeader || body.effort || undefined;
17860
+ const effort = normalizeEffort(effortHeader || body.effort || body.reasoning_effort || body.output_config?.effort);
17806
17861
  let thinking = body.thinking || undefined;
17807
17862
  if (thinkingHeader !== undefined) {
17808
17863
  try {
17809
17864
  thinking = JSON.parse(thinkingHeader);
17810
17865
  } catch (e) {
17811
- console.error(`[PROXY] ${requestMeta.requestId} ignoring malformed x-opencode-thinking header: ${e instanceof Error ? e.message : String(e)}`);
17866
+ plog(`[PROXY] ${requestMeta.requestId} ignoring malformed x-opencode-thinking header: ${e instanceof Error ? e.message : String(e)}`);
17812
17867
  }
17813
17868
  }
17814
17869
  const { getFeaturesForAdapter: getFeaturesForAdapter2 } = (init_sdkFeatures(), __toCommonJS(exports_sdkFeatures));
@@ -17823,7 +17878,7 @@ function createProxyServer(config = {}) {
17823
17878
  if (thinkingBetaStripped) {
17824
17879
  thinking = { type: "disabled" };
17825
17880
  if (betaFilter.stripped.length > 0) {
17826
- console.error(`[PROXY] ${requestMeta.requestId} thinking disabled (thinking beta stripped by ${getBetaPolicyFromEnv()} policy)`);
17881
+ plog(`[PROXY] ${requestMeta.requestId} thinking disabled (thinking beta stripped by ${getBetaPolicyFromEnv()} policy)`);
17827
17882
  }
17828
17883
  }
17829
17884
  const parsedBudget = taskBudgetHeader ? Number.parseInt(taskBudgetHeader, 10) : NaN;
@@ -17850,14 +17905,14 @@ function createProxyServer(config = {}) {
17850
17905
  const msgCount = Array.isArray(body.messages) ? body.messages.length : 0;
17851
17906
  const toolCount = body.tools?.length ?? 0;
17852
17907
  const requestLogLine = `${requestMeta.requestId} adapter=${adapter.name}${requestSource ? ` source=${requestSource}` : ""} model=${model} stream=${stream2} tools=${toolCount} lineage=${lineageType} session=${resumeSessionId?.slice(0, 8) || "new"}${isUndo && undoRollbackUuid ? ` rollback=${undoRollbackUuid.slice(0, 8)}` : ""}${agentMode ? ` agent=${agentMode}` : ""} active=${activeSessions}/${MAX_CONCURRENT_SESSIONS} msgCount=${msgCount}`;
17853
- console.error(`[PROXY] ${requestLogLine} msgs=${msgSummary}`);
17908
+ plog(`[PROXY] ${requestLogLine} msgs=${msgSummary}`);
17854
17909
  diagnosticLog2.session(`${requestLogLine}`, requestMeta.requestId);
17855
17910
  if (lineageResult.type === "diverged" && profileSessionId && !isIndependentSession) {
17856
17911
  const recovery = lookupSessionRecovery(profileSessionId);
17857
17912
  if (recovery) {
17858
17913
  const prevId = recovery.previousClaudeSessionId || recovery.claudeSessionId;
17859
17914
  const recoveryMsg = `${requestMeta.requestId} SESSION RECOVERY: previous conversation available. Run: claude --resume ${prevId}`;
17860
- console.error(`[PROXY] ${recoveryMsg}`);
17915
+ plog(`[PROXY] ${recoveryMsg}`);
17861
17916
  diagnosticLog2.session(recoveryMsg, requestMeta.requestId);
17862
17917
  }
17863
17918
  }
@@ -17953,7 +18008,7 @@ function createProxyServer(config = {}) {
17953
18008
  const cached = sessionToolCache.get(profileSessionId);
17954
18009
  if (cached && cached.length > 0) {
17955
18010
  requestTools = cached;
17956
- console.error(`[PROXY] ${requestMeta.requestId} tools_restored: client sent 0 tools but session had ${cached.length} — reusing cached tools to preserve prompt cache`);
18011
+ plog(`[PROXY] ${requestMeta.requestId} tools_restored: client sent 0 tools but session had ${cached.length} — reusing cached tools to preserve prompt cache`);
17957
18012
  }
17958
18013
  }
17959
18014
  if (passthrough && requestTools.length > 0) {
@@ -17966,7 +18021,7 @@ function createProxyServer(config = {}) {
17966
18021
  if (profileSessionId) {
17967
18022
  sessionMcpCache.set(profileSessionId, { key: toolSetKey, mcp: passthroughMcp });
17968
18023
  if (cachedMcp) {
17969
- console.error(`[PROXY] ${requestMeta.requestId} tools_changed: MCP server recreated (prompt cache likely invalidates)`);
18024
+ plog(`[PROXY] ${requestMeta.requestId} tools_changed: MCP server recreated (prompt cache likely invalidates)`);
17970
18025
  }
17971
18026
  }
17972
18027
  }
@@ -17978,7 +18033,7 @@ function createProxyServer(config = {}) {
17978
18033
  const coreSet = coreNames ? new Set(coreNames.map((n) => n.toLowerCase())) : undefined;
17979
18034
  const deferredToolCount = hasDeferredTools && requestTools.length > 0 ? requestTools.filter((t) => t.defer_loading === true || coreSet && !coreSet.has(String(t.name).toLowerCase())).length : 0;
17980
18035
  if (hasDeferredTools) {
17981
- console.error(`[PROXY] ${requestMeta.requestId} deferred=${deferredToolCount}/${toolCount} tools (core: ${coreNames?.join(",") ?? "none"})`);
18036
+ plog(`[PROXY] ${requestMeta.requestId} deferred=${deferredToolCount}/${toolCount} tools (core: ${coreNames?.join(",") ?? "none"})`);
17982
18037
  }
17983
18038
  const mcpPrefix = `mcp__${adapter.getMcpServerName()}__`;
17984
18039
  const trackFileChanges = !(process.env.MERIDIAN_NO_FILE_CHANGES ?? process.env.CLAUDE_PROXY_NO_FILE_CHANGES) && pipelineCtx.shouldTrackFileChanges;
@@ -18039,8 +18094,11 @@ function createProxyServer(config = {}) {
18039
18094
  const RATE_LIMIT_BASE_DELAY_MS = 1000;
18040
18095
  const response = async function* () {
18041
18096
  let rateLimitRetries = 0;
18042
- await ensureFreshToken().catch(() => {});
18097
+ if (profileCredentialStore) {
18098
+ await ensureFreshToken(profileCredentialStore).catch(() => {});
18099
+ }
18043
18100
  let tokenRefreshed = false;
18101
+ let didFreshBaseRetry = false;
18044
18102
  while (true) {
18045
18103
  let didYieldContent = false;
18046
18104
  try {
@@ -18056,6 +18114,7 @@ function createProxyServer(config = {}) {
18056
18114
  sdkAgents,
18057
18115
  passthroughMcp,
18058
18116
  cleanEnv: profileEnv,
18117
+ envOverrides,
18059
18118
  hasDeferredTools,
18060
18119
  resumeSessionId,
18061
18120
  isUndo,
@@ -18101,7 +18160,7 @@ function createProxyServer(config = {}) {
18101
18160
  rollbackUuid: undoRollbackUuid,
18102
18161
  resumeSessionId
18103
18162
  });
18104
- console.error(`[PROXY] Stale session UUID, evicting and retrying as fresh session`);
18163
+ plog(`[PROXY] Stale session UUID, evicting and retrying as fresh session`);
18105
18164
  evictSession(profileSessionId, profileScopedCwd, allMessages);
18106
18165
  sdkUuidMap.length = 0;
18107
18166
  for (let i = 0;i < allMessages.length; i++)
@@ -18118,6 +18177,7 @@ function createProxyServer(config = {}) {
18118
18177
  sdkAgents,
18119
18178
  passthroughMcp,
18120
18179
  cleanEnv: profileEnv,
18180
+ envOverrides,
18121
18181
  hasDeferredTools,
18122
18182
  resumeSessionId: undefined,
18123
18183
  isUndo: false,
@@ -18156,15 +18216,68 @@ function createProxyServer(config = {}) {
18156
18216
  to: model,
18157
18217
  reason: "extra_usage_required"
18158
18218
  });
18159
- console.error(`[PROXY] ${requestMeta.requestId} extra usage required for [1m], falling back to ${model} (skipping [1m] for 1h)`);
18219
+ plog(`[PROXY] ${requestMeta.requestId} extra usage required for [1m], falling back to ${model} (skipping [1m] for 1h)`);
18160
18220
  continue;
18161
18221
  }
18222
+ if (isExtraUsageRequiredError(errMsg) && resumeSessionId && !didFreshBaseRetry) {
18223
+ didFreshBaseRetry = true;
18224
+ claudeLog("upstream.session_fallback", {
18225
+ mode: "non_stream",
18226
+ model,
18227
+ reason: "extra_usage_required_resume"
18228
+ });
18229
+ plog(`[PROXY] ${requestMeta.requestId} extra usage persisted on resumed ${model}, retrying as fresh session`);
18230
+ evictSession(profileSessionId, profileScopedCwd, allMessages);
18231
+ sdkUuidMap.length = 0;
18232
+ for (let i = 0;i < allMessages.length; i++)
18233
+ sdkUuidMap.push(null);
18234
+ yield* query(buildQueryOptions({
18235
+ prompt: buildFreshPrompt(allMessages, sanitizeOpts),
18236
+ model,
18237
+ workingDirectory,
18238
+ clientWorkingDirectory,
18239
+ systemContext,
18240
+ claudeExecutable,
18241
+ passthrough,
18242
+ stream: false,
18243
+ sdkAgents,
18244
+ passthroughMcp,
18245
+ cleanEnv: profileEnv,
18246
+ envOverrides,
18247
+ hasDeferredTools,
18248
+ resumeSessionId: undefined,
18249
+ isUndo: false,
18250
+ undoRollbackUuid: undefined,
18251
+ sdkHooks,
18252
+ blockedTools: pipelineCtx.blockedTools,
18253
+ incompatibleTools: pipelineCtx.incompatibleTools,
18254
+ mcpServerName: adapter.getMcpServerName(),
18255
+ allowedMcpTools: pipelineCtx.allowedMcpTools,
18256
+ onStderr,
18257
+ effort,
18258
+ thinking,
18259
+ taskBudget,
18260
+ betas,
18261
+ settingSources,
18262
+ codeSystemPrompt: sdkFeatures.codeSystemPrompt,
18263
+ clientSystemPrompt: sdkFeatures.clientSystemPrompt === false ? false : undefined,
18264
+ memory: sdkFeatures.memory,
18265
+ dreaming: sdkFeatures.dreaming,
18266
+ sharedMemory: sdkFeatures.sharedMemory,
18267
+ maxBudgetUsd: sdkFeatures.maxBudgetUsd,
18268
+ fallbackModel: sdkFeatures.fallbackModel,
18269
+ sdkDebug: sdkFeatures.sdkDebug,
18270
+ additionalDirectories: sdkFeatures.additionalDirectories ? sdkFeatures.additionalDirectories.split(",").map((d) => d.trim()).filter(Boolean) : undefined,
18271
+ advisorModel
18272
+ }));
18273
+ return;
18274
+ }
18162
18275
  if (isExpiredTokenError(errMsg) && !tokenRefreshed) {
18163
18276
  tokenRefreshed = true;
18164
- const refreshed = await refreshOAuthToken();
18277
+ const refreshed = profileCredentialStore ? await refreshOAuthToken(profileCredentialStore) : false;
18165
18278
  if (refreshed) {
18166
18279
  claudeLog("token_refresh.retrying", { mode: "non_stream" });
18167
- console.error(`[PROXY] ${requestMeta.requestId} OAuth token expired — refreshed, retrying`);
18280
+ plog(`[PROXY] ${requestMeta.requestId} OAuth token expired — refreshed, retrying`);
18168
18281
  continue;
18169
18282
  }
18170
18283
  }
@@ -18178,7 +18291,7 @@ function createProxyServer(config = {}) {
18178
18291
  to: model,
18179
18292
  reason: "rate_limit"
18180
18293
  });
18181
- console.error(`[PROXY] ${requestMeta.requestId} rate-limited on [1m], retrying with ${model}`);
18294
+ plog(`[PROXY] ${requestMeta.requestId} rate-limited on [1m], retrying with ${model}`);
18182
18295
  continue;
18183
18296
  }
18184
18297
  if (rateLimitRetries < MAX_RATE_LIMIT_RETRIES) {
@@ -18191,7 +18304,7 @@ function createProxyServer(config = {}) {
18191
18304
  maxAttempts: MAX_RATE_LIMIT_RETRIES,
18192
18305
  delayMs: delay
18193
18306
  });
18194
- console.error(`[PROXY] ${requestMeta.requestId} rate-limited on ${model}, retry ${rateLimitRetries}/${MAX_RATE_LIMIT_RETRIES} in ${delay}ms`);
18307
+ plog(`[PROXY] ${requestMeta.requestId} rate-limited on ${model}, retry ${rateLimitRetries}/${MAX_RATE_LIMIT_RETRIES} in ${delay}ms`);
18195
18308
  await new Promise((r) => setTimeout(r, delay));
18196
18309
  continue;
18197
18310
  }
@@ -18267,7 +18380,7 @@ function createProxyServer(config = {}) {
18267
18380
  sessionDiscoveredTools.get(sessId).add(t);
18268
18381
  const newNames = [...discoveredTools].join(", ");
18269
18382
  const allNames = [...sessionDiscoveredTools.get(sessId)];
18270
- console.error(`[PROXY] ${requestMeta.requestId} discovered=${discoveredTools.size} (${newNames}) session_total=${allNames.length}`);
18383
+ plog(`[PROXY] ${requestMeta.requestId} discovered=${discoveredTools.size} (${newNames}) session_total=${allNames.length}`);
18271
18384
  }
18272
18385
  } catch (error) {
18273
18386
  const stderrOutput = stderrLines.join(`
@@ -18441,8 +18554,11 @@ Subprocess stderr: ${stderrOutput}`;
18441
18554
  const RATE_LIMIT_BASE_DELAY_MS = 1000;
18442
18555
  const response = async function* () {
18443
18556
  let rateLimitRetries = 0;
18444
- await ensureFreshToken().catch(() => {});
18557
+ if (profileCredentialStore) {
18558
+ await ensureFreshToken(profileCredentialStore).catch(() => {});
18559
+ }
18445
18560
  let tokenRefreshed = false;
18561
+ let didFreshBaseRetry = false;
18446
18562
  while (true) {
18447
18563
  let didYieldClientEvent = false;
18448
18564
  try {
@@ -18458,6 +18574,7 @@ Subprocess stderr: ${stderrOutput}`;
18458
18574
  sdkAgents,
18459
18575
  passthroughMcp,
18460
18576
  cleanEnv: profileEnv,
18577
+ envOverrides,
18461
18578
  hasDeferredTools,
18462
18579
  resumeSessionId,
18463
18580
  isUndo,
@@ -18503,7 +18620,7 @@ Subprocess stderr: ${stderrOutput}`;
18503
18620
  rollbackUuid: undoRollbackUuid,
18504
18621
  resumeSessionId
18505
18622
  });
18506
- console.error(`[PROXY] Stale session UUID, evicting and retrying as fresh session`);
18623
+ plog(`[PROXY] Stale session UUID, evicting and retrying as fresh session`);
18507
18624
  evictSession(profileSessionId, profileScopedCwd, allMessages);
18508
18625
  sdkUuidMap.length = 0;
18509
18626
  for (let i = 0;i < allMessages.length; i++)
@@ -18520,6 +18637,7 @@ Subprocess stderr: ${stderrOutput}`;
18520
18637
  sdkAgents,
18521
18638
  passthroughMcp,
18522
18639
  cleanEnv: profileEnv,
18640
+ envOverrides,
18523
18641
  hasDeferredTools,
18524
18642
  resumeSessionId: undefined,
18525
18643
  isUndo: false,
@@ -18558,15 +18676,68 @@ Subprocess stderr: ${stderrOutput}`;
18558
18676
  to: model,
18559
18677
  reason: "extra_usage_required"
18560
18678
  });
18561
- console.error(`[PROXY] ${requestMeta.requestId} extra usage required for [1m], falling back to ${model} (skipping [1m] for 1h)`);
18679
+ plog(`[PROXY] ${requestMeta.requestId} extra usage required for [1m], falling back to ${model} (skipping [1m] for 1h)`);
18562
18680
  continue;
18563
18681
  }
18682
+ if (isExtraUsageRequiredError(errMsg) && resumeSessionId && !didFreshBaseRetry) {
18683
+ didFreshBaseRetry = true;
18684
+ claudeLog("upstream.session_fallback", {
18685
+ mode: "stream",
18686
+ model,
18687
+ reason: "extra_usage_required_resume"
18688
+ });
18689
+ plog(`[PROXY] ${requestMeta.requestId} extra usage persisted on resumed ${model}, retrying as fresh session`);
18690
+ evictSession(profileSessionId, profileScopedCwd, allMessages);
18691
+ sdkUuidMap.length = 0;
18692
+ for (let i = 0;i < allMessages.length; i++)
18693
+ sdkUuidMap.push(null);
18694
+ yield* query(buildQueryOptions({
18695
+ prompt: buildFreshPrompt(allMessages, sanitizeOpts),
18696
+ model,
18697
+ workingDirectory,
18698
+ clientWorkingDirectory,
18699
+ systemContext,
18700
+ claudeExecutable,
18701
+ passthrough,
18702
+ stream: true,
18703
+ sdkAgents,
18704
+ passthroughMcp,
18705
+ cleanEnv: profileEnv,
18706
+ envOverrides,
18707
+ hasDeferredTools,
18708
+ resumeSessionId: undefined,
18709
+ isUndo: false,
18710
+ undoRollbackUuid: undefined,
18711
+ sdkHooks,
18712
+ blockedTools: pipelineCtx.blockedTools,
18713
+ incompatibleTools: pipelineCtx.incompatibleTools,
18714
+ mcpServerName: adapter.getMcpServerName(),
18715
+ allowedMcpTools: pipelineCtx.allowedMcpTools,
18716
+ onStderr,
18717
+ effort,
18718
+ thinking,
18719
+ taskBudget,
18720
+ betas,
18721
+ settingSources,
18722
+ codeSystemPrompt: sdkFeatures.codeSystemPrompt,
18723
+ clientSystemPrompt: sdkFeatures.clientSystemPrompt === false ? false : undefined,
18724
+ memory: sdkFeatures.memory,
18725
+ dreaming: sdkFeatures.dreaming,
18726
+ sharedMemory: sdkFeatures.sharedMemory,
18727
+ maxBudgetUsd: sdkFeatures.maxBudgetUsd,
18728
+ fallbackModel: sdkFeatures.fallbackModel,
18729
+ sdkDebug: sdkFeatures.sdkDebug,
18730
+ additionalDirectories: sdkFeatures.additionalDirectories ? sdkFeatures.additionalDirectories.split(",").map((d) => d.trim()).filter(Boolean) : undefined,
18731
+ advisorModel
18732
+ }));
18733
+ return;
18734
+ }
18564
18735
  if (isExpiredTokenError(errMsg) && !tokenRefreshed) {
18565
18736
  tokenRefreshed = true;
18566
- const refreshed = await refreshOAuthToken();
18737
+ const refreshed = profileCredentialStore ? await refreshOAuthToken(profileCredentialStore) : false;
18567
18738
  if (refreshed) {
18568
18739
  claudeLog("token_refresh.retrying", { mode: "stream" });
18569
- console.error(`[PROXY] ${requestMeta.requestId} OAuth token expired — refreshed, retrying`);
18740
+ plog(`[PROXY] ${requestMeta.requestId} OAuth token expired — refreshed, retrying`);
18570
18741
  continue;
18571
18742
  }
18572
18743
  }
@@ -18580,7 +18751,7 @@ Subprocess stderr: ${stderrOutput}`;
18580
18751
  to: model,
18581
18752
  reason: "rate_limit"
18582
18753
  });
18583
- console.error(`[PROXY] ${requestMeta.requestId} rate-limited on [1m], retrying with ${model}`);
18754
+ plog(`[PROXY] ${requestMeta.requestId} rate-limited on [1m], retrying with ${model}`);
18584
18755
  continue;
18585
18756
  }
18586
18757
  if (rateLimitRetries < MAX_RATE_LIMIT_RETRIES) {
@@ -18593,7 +18764,7 @@ Subprocess stderr: ${stderrOutput}`;
18593
18764
  maxAttempts: MAX_RATE_LIMIT_RETRIES,
18594
18765
  delayMs: delay
18595
18766
  });
18596
- console.error(`[PROXY] ${requestMeta.requestId} rate-limited on ${model}, retry ${rateLimitRetries}/${MAX_RATE_LIMIT_RETRIES} in ${delay}ms`);
18767
+ plog(`[PROXY] ${requestMeta.requestId} rate-limited on ${model}, retry ${rateLimitRetries}/${MAX_RATE_LIMIT_RETRIES} in ${delay}ms`);
18597
18768
  await new Promise((r) => setTimeout(r, delay));
18598
18769
  continue;
18599
18770
  }
@@ -18807,7 +18978,7 @@ data: ${JSON.stringify({ type: "message_stop" })}
18807
18978
  sessionDiscoveredTools.get(sessId).add(t);
18808
18979
  const newNames = [...discoveredTools].join(", ");
18809
18980
  const allNames = [...sessionDiscoveredTools.get(sessId)];
18810
- console.error(`[PROXY] ${requestMeta.requestId} discovered=${discoveredTools.size} (${newNames}) session_total=${allNames.length}`);
18981
+ plog(`[PROXY] ${requestMeta.requestId} discovered=${discoveredTools.size} (${newNames}) session_total=${allNames.length}`);
18811
18982
  }
18812
18983
  if (currentSessionId && !isIndependentSession) {
18813
18984
  storeSession(profileSessionId, body.messages || [], currentSessionId, profileScopedCwd, sdkUuidMap, lastUsage);
@@ -19326,7 +19497,7 @@ data: ${JSON.stringify({
19326
19497
  setActiveProfile(body.profile);
19327
19498
  clearSessionCache();
19328
19499
  rateLimitStore.clear();
19329
- console.error(`[PROXY] Active profile switched to: ${body.profile} (session + rate-limit caches cleared)`);
19500
+ plog(`[PROXY] Active profile switched to: ${body.profile} (session + rate-limit caches cleared)`);
19330
19501
  return c.json({ success: true, activeProfile: body.profile });
19331
19502
  });
19332
19503
  app.get("/plugins/list", async (c) => {
@@ -19350,7 +19521,7 @@ data: ${JSON.stringify({
19350
19521
  loadedPlugins = await loadPlugins(pluginDir, pluginConfigPath);
19351
19522
  pluginTransforms = getActiveTransforms(loadedPlugins);
19352
19523
  const active = loadedPlugins.filter((p) => p.status === "active").length;
19353
- console.error(`[PROXY] Plugins reloaded: ${active} active`);
19524
+ plog(`[PROXY] Plugins reloaded: ${active} active`);
19354
19525
  return c.json({
19355
19526
  success: true,
19356
19527
  plugins: loadedPlugins.map((p) => ({
@@ -19369,10 +19540,12 @@ data: ${JSON.stringify({
19369
19540
  return c.html(pluginPageHtml);
19370
19541
  });
19371
19542
  app.post("/auth/refresh", async (c) => {
19372
- const success = await refreshOAuthToken();
19543
+ const profile = resolveProfile(finalConfig.profiles, finalConfig.defaultProfile, c.req.header("x-meridian-profile") || undefined);
19544
+ const store = credentialStoreForProfile(profile);
19545
+ const success = store ? await refreshOAuthToken(store) : false;
19373
19546
  if (success) {
19374
19547
  rateLimitStore.clear();
19375
- return c.json({ success: true, message: "OAuth token refreshed successfully" });
19548
+ return c.json({ success: true, message: "OAuth token refreshed successfully", profile: profile.id });
19376
19549
  }
19377
19550
  return c.json({ success: false, message: "Token refresh failed. If the problem persists, run 'claude login'." }, 500);
19378
19551
  });
@@ -19382,7 +19555,10 @@ data: ${JSON.stringify({
19382
19555
  if (!anthropicBody) {
19383
19556
  return c.json({ type: "error", error: { type: "invalid_request_error", message: "messages: Field required" } }, 400);
19384
19557
  }
19385
- const internalHeaders = { "Content-Type": "application/json" };
19558
+ const internalHeaders = {
19559
+ "Content-Type": "application/json",
19560
+ "x-meridian-agent": "openai"
19561
+ };
19386
19562
  const xApiKey = c.req.header("x-api-key");
19387
19563
  if (xApiKey)
19388
19564
  internalHeaders["x-api-key"] = xApiKey;
@@ -19403,8 +19579,7 @@ data: ${JSON.stringify({
19403
19579
  const created = Math.floor(Date.now() / 1000);
19404
19580
  const model = typeof rawBody.model === "string" && rawBody.model ? rawBody.model : "claude-sonnet-4-6";
19405
19581
  const { getFeaturesForAdapter: getFeaturesForAdapter2 } = (init_sdkFeatures(), __toCommonJS(exports_sdkFeatures));
19406
- const adapter = detectAdapter(c);
19407
- const sdkFeatures = getFeaturesForAdapter2(adapter.name);
19582
+ const sdkFeatures = getFeaturesForAdapter2("openai");
19408
19583
  if (!anthropicBody.stream) {
19409
19584
  const anthropicRes = await internalRes.json();
19410
19585
  return c.json(translateAnthropicToOpenAi(anthropicRes, completionId, model, created, {
@@ -19635,7 +19810,7 @@ data: ${JSON.stringify({
19635
19810
  });
19636
19811
  });
19637
19812
  app.all("*", (c) => {
19638
- console.error(`[PROXY] UNHANDLED ${c.req.method} ${c.req.url}`);
19813
+ plog(`[PROXY] UNHANDLED ${c.req.method} ${c.req.url}`);
19639
19814
  return c.json({ error: { type: "not_found", message: `Endpoint not supported: ${c.req.method} ${new URL(c.req.url).pathname}` } }, 404);
19640
19815
  });
19641
19816
  async function initPluginsAsync() {
@@ -19646,19 +19821,34 @@ data: ${JSON.stringify({
19646
19821
  const active = loadedPlugins.filter((p) => p.status === "active").length;
19647
19822
  const disabled = loadedPlugins.filter((p) => p.status === "disabled").length;
19648
19823
  const errored = loadedPlugins.filter((p) => p.status === "error").length;
19649
- console.error(`[PROXY] Plugins loaded: ${active} active, ${disabled} disabled, ${errored} errors`);
19824
+ plog(`[PROXY] Plugins loaded: ${active} active, ${disabled} disabled, ${errored} errors`);
19650
19825
  }
19651
19826
  } catch (err) {
19652
- console.error(`[PROXY] Plugin loading failed: ${err instanceof Error ? err.message : String(err)}`);
19827
+ plog(`[PROXY] Plugin loading failed: ${err instanceof Error ? err.message : String(err)}`);
19653
19828
  }
19654
19829
  }
19655
19830
  return { app, config: finalConfig, initPlugins: initPluginsAsync };
19656
19831
  }
19832
+ var processErrorHandlersInstalled = false;
19833
+ function installProxyProcessErrorHandlers() {
19834
+ if (processErrorHandlersInstalled)
19835
+ return;
19836
+ processErrorHandlersInstalled = true;
19837
+ process.on("uncaughtException", (err) => {
19838
+ console.error(`[PROXY] Uncaught exception (recovered): ${err.message}`);
19839
+ });
19840
+ process.on("unhandledRejection", (reason) => {
19841
+ console.error(`[PROXY] Unhandled rejection (recovered): ${reason instanceof Error ? reason.message : reason}`);
19842
+ });
19843
+ }
19657
19844
  async function startProxyServer(config = {}) {
19658
19845
  claudeExecutable = await resolveClaudeExecutableAsync();
19659
19846
  const { app, config: finalConfig, initPlugins } = createProxyServer(config);
19660
19847
  if (initPlugins)
19661
19848
  await initPlugins();
19849
+ if (finalConfig.installProcessErrorHandlers) {
19850
+ installProxyProcessErrorHandlers();
19851
+ }
19662
19852
  const server = serve({
19663
19853
  fetch: app.fetch,
19664
19854
  port: finalConfig.port,
@@ -19696,6 +19886,13 @@ Or use a different port:`);
19696
19886
  }
19697
19887
  });
19698
19888
  startBackgroundRefresh();
19889
+ const PROFILE_TOKEN_REFRESH_MS = 45000;
19890
+ ensureFreshTokenForProfiles(finalConfig);
19891
+ const profileTokenRefreshInterval = setInterval(() => {
19892
+ ensureFreshTokenForProfiles(finalConfig);
19893
+ }, PROFILE_TOKEN_REFRESH_MS);
19894
+ if (profileTokenRefreshInterval.unref)
19895
+ profileTokenRefreshInterval.unref();
19699
19896
  let authKeepaliveInterval;
19700
19897
  const effectiveProfiles = getEffectiveProfiles(finalConfig.profiles);
19701
19898
  if (effectiveProfiles.length > 0) {
@@ -19717,6 +19914,7 @@ Or use a different port:`);
19717
19914
  server,
19718
19915
  config: finalConfig,
19719
19916
  async close() {
19917
+ clearInterval(profileTokenRefreshInterval);
19720
19918
  if (authKeepaliveInterval)
19721
19919
  clearInterval(authKeepaliveInterval);
19722
19920
  stopBackgroundRefresh();
@@ -19727,4 +19925,4 @@ Or use a different port:`);
19727
19925
  };
19728
19926
  }
19729
19927
 
19730
- export { runTransformHook, runObserveHook, buildPipeline, createRequestContext, computeLineageHash, hashMessage, computeMessageHashes, getMaxSessionsLimit, clearSessionCache, createProxyServer, startProxyServer };
19928
+ export { runTransformHook, runObserveHook, buildPipeline, createRequestContext, computeLineageHash, hashMessage, computeMessageHashes, getMaxSessionsLimit, clearSessionCache, createProxyServer, installProxyProcessErrorHandlers, startProxyServer };