@kenkaiiii/gg-ai 5.82.0 → 5.83.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.
package/dist/index.cjs CHANGED
@@ -40,6 +40,7 @@ __export(index_exports, {
40
40
  clampProviderContextImages: () => clampProviderContextImages,
41
41
  classifyProviderError: () => classifyProviderError,
42
42
  continuesTurn: () => continuesTurn,
43
+ describeFastModeRejection: () => describeFastModeRejection,
43
44
  dropInvalidToolCalls: () => dropInvalidToolCalls,
44
45
  embed: () => embed,
45
46
  environmentSecrets: () => environmentSecrets,
@@ -58,6 +59,7 @@ __export(index_exports, {
58
59
  palsuText: () => palsuText,
59
60
  palsuThinking: () => palsuThinking,
60
61
  palsuToolCall: () => palsuToolCall,
62
+ parseFastModeRejection: () => parseFastModeRejection,
61
63
  prewarmAnthropicCache: () => prewarmAnthropicCache,
62
64
  providerRegistry: () => providerRegistry,
63
65
  redactText: () => redactText,
@@ -79,6 +81,96 @@ __export(index_exports, {
79
81
  });
80
82
  module.exports = __toCommonJS(index_exports);
81
83
 
84
+ // src/fast-mode.ts
85
+ var FAST_MODE_SUFFIX = "-fast";
86
+ var FAST_MODE_BASE_MODELS = {
87
+ anthropic: ["claude-opus-5-5"],
88
+ openai: ["gpt-6-astra", "gpt-6.1-sol", "gpt-6-luna"]
89
+ };
90
+ function resolveFastModeModel(provider, model) {
91
+ if (!model.endsWith(FAST_MODE_SUFFIX)) return { model, fast: false };
92
+ const base = model.slice(0, -FAST_MODE_SUFFIX.length);
93
+ return FAST_MODE_BASE_MODELS[provider]?.includes(base) ? { model: base, fast: true } : { model, fast: false };
94
+ }
95
+ var FAST_MODE_REJECTION_HEADER = "anthropic-ratelimit-unified-overage-disabled-reason";
96
+ var FAST_MODE_REJECTION_PREFIX = "Fast mode unavailable";
97
+ var USAGE_PAGE = "claude.ai/settings/usage";
98
+ var STANDARD_SPEED_FALLBACK = "or switch to Claude Opus 5.5 (standard speed), which uses your plan";
99
+ function describeFastModeRejection(reason) {
100
+ const code = reason?.trim() || "unknown";
101
+ const of = (headline, guidance, kind) => ({ reason: code, headline, guidance, kind });
102
+ switch (code) {
103
+ case "overage_not_provisioned":
104
+ case "no_limits_configured":
105
+ return of(
106
+ "Claude usage credits are turned off",
107
+ `Fast mode bills your Claude usage credits, never your plan. Turn usage credits on at ${USAGE_PAGE}, ${STANDARD_SPEED_FALLBACK}.`,
108
+ "access"
109
+ );
110
+ case "out_of_credits":
111
+ return of(
112
+ "Your Claude usage credits have run out",
113
+ `Fast mode bills your Claude usage credits, never your plan, and the balance is empty. Add funds or turn on auto-reload at ${USAGE_PAGE}, ${STANDARD_SPEED_FALLBACK}.`,
114
+ "billing"
115
+ );
116
+ case "org_level_disabled_until":
117
+ case "org_spend_cap_reached":
118
+ return of(
119
+ "Claude usage credit limit reached",
120
+ `Fast mode bills your Claude usage credits and this period's spend limit is used up. Raise the limit at ${USAGE_PAGE}, ${STANDARD_SPEED_FALLBACK}.`,
121
+ "billing"
122
+ );
123
+ case "org_level_disabled":
124
+ case "org_service_level_disabled":
125
+ return of(
126
+ "Your organization turned Claude usage credits off",
127
+ `Fast mode needs usage credits. Ask an admin to turn them on, ${STANDARD_SPEED_FALLBACK}.`,
128
+ "access"
129
+ );
130
+ case "member_level_disabled":
131
+ return of(
132
+ "Claude usage credits are off for your account",
133
+ `Fast mode needs usage credits. Ask your organization's admin to turn them on for you, ${STANDARD_SPEED_FALLBACK}.`,
134
+ "access"
135
+ );
136
+ case "seat_tier_level_disabled":
137
+ case "seat_tier_zero_credit_limit":
138
+ case "member_zero_credit_limit":
139
+ case "group_zero_credit_limit":
140
+ return of(
141
+ "Claude usage credits aren't available on your plan",
142
+ `Fast mode needs usage credits, which your seat doesn't include. Ask your admin about access, ${STANDARD_SPEED_FALLBACK}.`,
143
+ "access"
144
+ );
145
+ case "fast_mode_org_disabled":
146
+ return of(
147
+ "Your organization turned fast mode off",
148
+ `An Owner can enable fast mode for the organization, ${STANDARD_SPEED_FALLBACK}.`,
149
+ "access"
150
+ );
151
+ default:
152
+ return of(
153
+ "Fast mode needs Claude usage credits",
154
+ `Fast mode bills your Claude usage credits, never your plan, and Anthropic couldn't charge them. Check usage credits at ${USAGE_PAGE}, ${STANDARD_SPEED_FALLBACK}.`,
155
+ "billing"
156
+ );
157
+ }
158
+ }
159
+ function fastModeRejectionMessage(rejection) {
160
+ return `${FAST_MODE_REJECTION_PREFIX} (${rejection.reason}): ${rejection.headline}.`;
161
+ }
162
+ function parseFastModeRejection(message) {
163
+ const canonical = /fast mode unavailable \(([a-z_]+)\)/i.exec(message);
164
+ if (canonical) return describeFastModeRejection(canonical[1]);
165
+ if (/usage credits are required for fast mode/i.test(message)) {
166
+ return describeFastModeRejection(void 0);
167
+ }
168
+ if (/fast mode (?:has been |is )?disabled by your organization/i.test(message)) {
169
+ return describeFastModeRejection("fast_mode_org_disabled");
170
+ }
171
+ return void 0;
172
+ }
173
+
82
174
  // src/errors.ts
83
175
  function readHeader(headers, ...names) {
84
176
  if (!headers) return void 0;
@@ -158,8 +250,8 @@ function isUsageLimitError(err) {
158
250
  }
159
251
  function isHardBillingMessage(message) {
160
252
  const lower = message.toLowerCase();
161
- return lower.includes("insufficient balance") || lower.includes("insufficient credits") || lower.includes("more credits") || lower.includes("insufficient_quota") || lower.includes("exceeded your current quota") || lower.includes("quota exceeded") || lower.includes("no resource package") || lower.includes("recharge") || lower.includes("balance is too low") || lower.includes("out of credits") || // Anthropic fast mode on a subscription without usage credits turned on.
162
- lower.includes("usage credits are required") || lower.includes("arrears") || lower.includes("arrearage") || lower.includes("token quota") || lower.includes("exceeded_current_quota_error") || lower.includes("check your account balance") || lower.includes("does not yet include access") || lower.includes("subscription plan") || lower.includes("billing");
253
+ return lower.includes("insufficient balance") || lower.includes("insufficient credits") || lower.includes("more credits") || lower.includes("insufficient_quota") || lower.includes("exceeded your current quota") || lower.includes("quota exceeded") || lower.includes("no resource package") || lower.includes("recharge") || lower.includes("balance is too low") || lower.includes("out of credits") || // Anthropic fast mode when usage credits can't pay (see fast-mode.ts).
254
+ lower.includes("usage credits are required") || lower.includes("fast mode unavailable") || lower.includes("arrears") || lower.includes("arrearage") || lower.includes("token quota") || lower.includes("exceeded_current_quota_error") || lower.includes("check your account balance") || lower.includes("does not yet include access") || lower.includes("subscription plan") || lower.includes("billing");
163
255
  }
164
256
  function formatResetTime(resetsAt) {
165
257
  const when = new Date(resetsAt * 1e3);
@@ -212,6 +304,18 @@ function formatError(err) {
212
304
  guidance: "Request access via your Anthropic account team (see platform.claude.com/docs/en/about-claude/models/overview), or switch to Claude Fable 5.1 via the model selector \u2014 same underlying model, generally available."
213
305
  };
214
306
  }
307
+ const fastRejection = err.provider === "anthropic" ? parseFastModeRejection(err.message) : void 0;
308
+ if (fastRejection) {
309
+ return {
310
+ headline: `${fastRejection.headline}.`,
311
+ source: "provider",
312
+ message: cleanMessage,
313
+ provider: err.provider,
314
+ statusCode: err.statusCode,
315
+ ...err.requestId ? { requestId: err.requestId } : {},
316
+ guidance: fastRejection.guidance
317
+ };
318
+ }
215
319
  if (isUsageLimitError(err)) {
216
320
  const resetClause = err.resetsAt ? ` It resets at ${formatResetTime(err.resetsAt)}.` : "";
217
321
  return {
@@ -1388,7 +1492,7 @@ function isAdaptiveThinkingModel(model) {
1388
1492
  function toAnthropicThinking(level, maxTokens, model) {
1389
1493
  if (isAdaptiveThinkingModel(model)) {
1390
1494
  let effort = level;
1391
- if (effort === "xhigh" && !/opus-5|opus-4-8|opus-4-7|sonnet-5[-.]5|haiku-5[-.]5/.test(model)) {
1495
+ if (effort === "xhigh" && !/fable-5|mythos-5|opus-5|opus-4-8|opus-4-7|sonnet-5[-.]5|haiku-5[-.]5/.test(model)) {
1392
1496
  effort = "high";
1393
1497
  }
1394
1498
  return {
@@ -1928,7 +2032,7 @@ async function* runStream(options) {
1928
2032
  yield* synthesizeEventsFromMessage(message);
1929
2033
  return messageToResponse(message);
1930
2034
  } catch (err) {
1931
- throw toError(err);
2035
+ throw toError(err, { fastMode: useFastMode });
1932
2036
  }
1933
2037
  }
1934
2038
  const contentParts = [];
@@ -2145,7 +2249,7 @@ async function* runStream(options) {
2145
2249
  }
2146
2250
  }
2147
2251
  } catch (err) {
2148
- throw toError(err);
2252
+ throw toError(err, { fastMode: useFastMode });
2149
2253
  }
2150
2254
  if (!receivedAnyEvent) {
2151
2255
  throw new ProviderError("anthropic", "Stream ended without producing any events.", {
@@ -2275,8 +2379,12 @@ function messageToResponse(message) {
2275
2379
  }
2276
2380
  };
2277
2381
  }
2278
- function isFastModeCreditsMessage(message) {
2279
- return /usage credits are required for fast mode/i.test(message);
2382
+ function readFastModeRejection(err, message, fastMode) {
2383
+ const reason = readHeader(err.headers, FAST_MODE_REJECTION_HEADER);
2384
+ if (fastMode && err.status === 429 && reason) return describeFastModeRejection(reason);
2385
+ const fromBody = parseFastModeRejection(message);
2386
+ if (!fromBody) return void 0;
2387
+ return reason ? describeFastModeRejection(reason) : fromBody;
2280
2388
  }
2281
2389
  function readUnifiedRateLimit(headers) {
2282
2390
  const status = readHeader(headers, "anthropic-ratelimit-unified-status");
@@ -2290,7 +2398,7 @@ function readUnifiedRateLimit(headers) {
2290
2398
  const resetsAt = Number.isFinite(resetNum) && resetNum > 0 ? resetNum : void 0;
2291
2399
  return { rejected: status === "rejected", ...resetsAt ? { resetsAt } : {} };
2292
2400
  }
2293
- function toError(err) {
2401
+ function toError(err, context) {
2294
2402
  if (err instanceof ProviderError) return err;
2295
2403
  if (err instanceof import_sdk.default.APIError) {
2296
2404
  const errorBody = err.error;
@@ -2301,11 +2409,12 @@ function toError(err) {
2301
2409
  const fallbackMessage = isRawJsonErrorEcho(err.message) ? emptyProviderErrorMessage(err.status) : err.message;
2302
2410
  const messageCandidate = bodyMessage ?? err.message;
2303
2411
  const message = isRawHtmlErrorEcho(messageCandidate) ? providerHtmlErrorMessage(err.status) : bodyType && bodyMessage ? `${bodyType}: ${bodyMessage}` : bodyMessage ?? fallbackMessage;
2304
- if (isFastModeCreditsMessage(message)) {
2305
- return new ProviderError("anthropic", message, {
2412
+ const fastRejection = readFastModeRejection(err, message, context?.fastMode === true);
2413
+ if (fastRejection) {
2414
+ return new ProviderError("anthropic", fastModeRejectionMessage(fastRejection), {
2306
2415
  statusCode: err.status,
2307
2416
  ...requestId ? { requestId } : {},
2308
- hint: "Fast mode bills Claude usage credits, not your plan. Turn them on at claude.ai/settings/usage, or switch to Claude Opus 5.5 (standard speed) in the model selector.",
2417
+ hint: fastRejection.guidance,
2309
2418
  cause: err
2310
2419
  });
2311
2420
  }
@@ -2604,10 +2713,16 @@ async function* runStream2(options) {
2604
2713
  `
2605
2714
  );
2606
2715
  }
2716
+ const requestHeaders = options.provider === "xai" ? {
2717
+ headers: {
2718
+ "x-grok-conv-id": normalizePromptCacheKey(options.promptCacheKey ?? "ggcoder")
2719
+ }
2720
+ } : {};
2607
2721
  if (!useStreaming) {
2608
2722
  try {
2609
2723
  const completion = await client.chat.completions.create(requestParams, {
2610
- signal: options.signal ?? void 0
2724
+ signal: options.signal ?? void 0,
2725
+ ...requestHeaders
2611
2726
  });
2612
2727
  yield* synthesizeEventsFromCompletion(completion, !!options.thinking, endpointKey);
2613
2728
  return completionToResponse(completion, endpointKey);
@@ -2618,7 +2733,8 @@ async function* runStream2(options) {
2618
2733
  let stream2;
2619
2734
  try {
2620
2735
  stream2 = await client.chat.completions.create(requestParams, {
2621
- signal: options.signal ?? void 0
2736
+ signal: options.signal ?? void 0,
2737
+ ...requestHeaders
2622
2738
  });
2623
2739
  } catch (err) {
2624
2740
  throw toError2(err, providerName);
@@ -3661,6 +3777,9 @@ var CODE_ASSIST_SUPPORTED_MODELS = /* @__PURE__ */ new Set([
3661
3777
  "gemma-4-31b-it",
3662
3778
  "gemma-4-26b-a4b-it"
3663
3779
  ]);
3780
+ function isGeminiApiKeyRoute(options) {
3781
+ return options.baseUrl?.includes("generativelanguage.googleapis.com") === true;
3782
+ }
3664
3783
  function getGoogleProject(options) {
3665
3784
  const env = getEnvironment();
3666
3785
  return options.projectId ?? env?.GOOGLE_CLOUD_PROJECT ?? env?.GOOGLE_CLOUD_PROJECT_ID;
@@ -3693,8 +3812,28 @@ function accountGatedHint(model) {
3693
3812
  if (model === "gemini-3.8-flash" || model === "gemini-3.5-flash-lite") {
3694
3813
  return "Use /model to select Gemini 3.1 Flash Lite, or retry once Google enables this model through Code Assist for your account.";
3695
3814
  }
3696
- return `Newer Gemini models (3.7 Flash, 3.5 Flash, 3.1 Pro Preview) are available only to Code Assist Standard/Enterprise accounts with preview/GA access enabled by a cloud admin \u2014 free/personal accounts usually can't call them. Switch to Gemini 3.1 Flash Lite (it works on this account) with /model, or sign in with a Code Assist Standard/Enterprise account that has preview access.`;
3815
+ return `Newer Gemini models (3.5 Flash, 3.1 Pro Preview) are available only to Code Assist Standard/Enterprise accounts with preview/GA access enabled by a cloud admin. Try Gemini 3.1 Flash Lite with /model, or sign in with a Code Assist Standard/Enterprise account that has preview access.`;
3697
3816
  }
3817
+ function isCodeAssistLicenseRequired(status, body) {
3818
+ if (status !== 403) return false;
3819
+ try {
3820
+ const parsed = JSON.parse(body);
3821
+ const details = typeof parsed === "object" && parsed !== null && "error" in parsed ? parsed.error?.details : void 0;
3822
+ return Array.isArray(details) && details.some(
3823
+ (detail) => typeof detail === "object" && detail !== null && detail.reason === "SUBSCRIPTION_REQUIRED"
3824
+ );
3825
+ } catch {
3826
+ return false;
3827
+ }
3828
+ }
3829
+ function isInvalidGeminiApiKey(status, body) {
3830
+ if (status !== 400 && status !== 401 && status !== 403) return false;
3831
+ return /"reason"\s*:\s*"API_KEY_INVALID"/.test(body) || /API key not valid/i.test(body);
3832
+ }
3833
+ var INVALID_API_KEY_MESSAGE = "Google rejected the Gemini API key: it is not valid.";
3834
+ var INVALID_API_KEY_HINT = "Create a key at aistudio.google.com/apikey and add it again under Gemini in Providers (or `ggcoder login`).";
3835
+ var LICENSE_REQUIRED_MESSAGE = "This Google account has no Gemini Code Assist licence. Google stopped serving Gemini through Code Assist to personal accounts (Google AI Pro/Ultra and the free individual tier) on June 18, 2026, so every Gemini model is refused, not just this one.";
3836
+ var LICENSE_REQUIRED_HINT = "Sign in to Gemini with a Google account that has a Gemini Code Assist Standard or Enterprise licence, or pick a model from another provider with /model.";
3698
3837
  function formatErrorMessage(status, body, model) {
3699
3838
  if (status === 404 && !CODE_ASSIST_SUPPORTED_MODELS.has(model)) {
3700
3839
  return `Gemini API error (404): ${body}
@@ -3918,7 +4057,29 @@ function buildCodeAssistRequest(options, request, projectId) {
3918
4057
  request
3919
4058
  };
3920
4059
  }
4060
+ var API_KEY_MODEL_IDS = {
4061
+ "gemini-3-flash": "gemini-3.5-flash"
4062
+ };
4063
+ function buildApiKeyRequestPlan(options, method) {
4064
+ const { session_id: _sessionId, ...request } = mergeProviderOptions(
4065
+ buildGenerateRequest(options),
4066
+ options.providerOptions
4067
+ );
4068
+ const base = (options.baseUrl ?? "").replace(/\/+$/, "");
4069
+ return {
4070
+ url: new URL(
4071
+ `${base}/models/${encodeURIComponent(API_KEY_MODEL_IDS[options.model] ?? options.model)}:${method}`
4072
+ ),
4073
+ headers: {
4074
+ "Content-Type": "application/json",
4075
+ "x-goog-api-key": options.apiKey ?? ""
4076
+ },
4077
+ body: request,
4078
+ route: "api-key"
4079
+ };
4080
+ }
3921
4081
  function buildRequestPlan(options, method) {
4082
+ if (isGeminiApiKeyRoute(options)) return buildApiKeyRequestPlan(options, method);
3922
4083
  if (!CODE_ASSIST_SUPPORTED_MODELS.has(options.model)) {
3923
4084
  throw new ProviderError("gemini", formatUnsupportedModelMessage(options.model));
3924
4085
  }
@@ -3932,7 +4093,8 @@ function buildRequestPlan(options, method) {
3932
4093
  "User-Agent": GEMINI_CLI_USER_AGENT,
3933
4094
  "X-Goog-Api-Client": GEMINI_CLI_API_CLIENT
3934
4095
  },
3935
- body: buildCodeAssistRequest(options, request, projectId)
4096
+ body: buildCodeAssistRequest(options, request, projectId),
4097
+ route: "code-assist"
3936
4098
  };
3937
4099
  }
3938
4100
  function normalizeGeminiStopReason(reason) {
@@ -4018,8 +4180,11 @@ async function fetchCodeAssist(plan, options) {
4018
4180
  if (!response.ok) {
4019
4181
  const text = await response.text().catch(() => "");
4020
4182
  const quota = parseGeminiQuota(response.status, text);
4021
- const accountGated = response.status === 404 && ACCOUNT_GATED_MODELS.has(options.model);
4022
- let message = accountGated ? accountGatedMessage(options.model) : formatErrorMessage(response.status, text, options.model);
4183
+ const codeAssist = plan.route === "code-assist";
4184
+ const accountGated = codeAssist && response.status === 404 && ACCOUNT_GATED_MODELS.has(options.model);
4185
+ const licenseRequired = codeAssist && isCodeAssistLicenseRequired(response.status, text);
4186
+ const invalidKey = !codeAssist && isInvalidGeminiApiKey(response.status, text);
4187
+ let message = invalidKey ? INVALID_API_KEY_MESSAGE : licenseRequired ? LICENSE_REQUIRED_MESSAGE : accountGated ? accountGatedMessage(options.model) : formatErrorMessage(response.status, text, options.model);
4023
4188
  let resetsAt;
4024
4189
  if (quota?.exhausted) {
4025
4190
  message = `Gemini quota exhausted \u2014 usage limit reached. ${message}`;
@@ -4029,7 +4194,7 @@ async function fetchCodeAssist(plan, options) {
4029
4194
  throw new ProviderError("gemini", message, {
4030
4195
  statusCode: response.status,
4031
4196
  ...resetsAt !== void 0 ? { resetsAt } : {},
4032
- ...accountGated ? { hint: accountGatedHint(options.model) } : {}
4197
+ ...invalidKey ? { hint: INVALID_API_KEY_HINT, source: "auth" } : licenseRequired ? { hint: LICENSE_REQUIRED_HINT, source: "auth" } : accountGated ? { hint: accountGatedHint(options.model) } : {}
4033
4198
  });
4034
4199
  }
4035
4200
  return response;
@@ -4814,18 +4979,6 @@ function observePreparedContext(before, after, tools) {
4814
4979
  };
4815
4980
  }
4816
4981
 
4817
- // src/fast-mode.ts
4818
- var FAST_MODE_SUFFIX = "-fast";
4819
- var FAST_MODE_BASE_MODELS = {
4820
- anthropic: ["claude-opus-5-5"],
4821
- openai: ["gpt-6-astra", "gpt-6.1-sol", "gpt-6-luna"]
4822
- };
4823
- function resolveFastModeModel(provider, model) {
4824
- if (!model.endsWith(FAST_MODE_SUFFIX)) return { model, fast: false };
4825
- const base = model.slice(0, -FAST_MODE_SUFFIX.length);
4826
- return FAST_MODE_BASE_MODELS[provider]?.includes(base) ? { model: base, fast: true } : { model, fast: false };
4827
- }
4828
-
4829
4982
  // src/stream.ts
4830
4983
  var OPENAI_EMBED_BATCH_SIZE = 2048;
4831
4984
  var OPENROUTER_EMBED_BATCH_SIZE = 64;
@@ -4928,7 +5081,7 @@ providerRegistry.register("sakana", {
4928
5081
  providerRegistry.register("xai", {
4929
5082
  // xAI's public API (console.x.ai key) is OpenAI-compatible — ride the Chat
4930
5083
  // Completions transport like Moonshot/DeepSeek. Grok reasoning models take
4931
- // top-level `reasoning_effort` (low/medium/high), which the shared thinking
5084
+ // top-level `reasoning_effort` (low/medium/high/xhigh), which the shared thinking
4932
5085
  // path already sends.
4933
5086
  //
4934
5087
  // Subscription OAuth (SuperGrok / X Premium) routes to the Grok CLI chat proxy
@@ -5217,6 +5370,14 @@ function formatChatError(error) {
5217
5370
  "Update the app, or choose another model."
5218
5371
  );
5219
5372
  }
5373
+ const fastRejection = base.provider === "anthropic" ? parseFastModeRejection(raw) : void 0;
5374
+ if (fastRejection) {
5375
+ return present(
5376
+ fastRejection.kind === "billing" ? "billing" : "model_access",
5377
+ fastRejection.headline,
5378
+ fastRejection.guidance
5379
+ );
5380
+ }
5220
5381
  if (/insufficient.*(?:balance|credits?)|(?:balance|credits?).*(?:insufficient|exhausted|depleted)|credit balance is too low|payment_required/.test(
5221
5382
  text
5222
5383
  )) {
@@ -5643,6 +5804,7 @@ function palsuRerankScore(query, document) {
5643
5804
  clampProviderContextImages,
5644
5805
  classifyProviderError,
5645
5806
  continuesTurn,
5807
+ describeFastModeRejection,
5646
5808
  dropInvalidToolCalls,
5647
5809
  embed,
5648
5810
  environmentSecrets,
@@ -5661,6 +5823,7 @@ function palsuRerankScore(query, document) {
5661
5823
  palsuText,
5662
5824
  palsuThinking,
5663
5825
  palsuToolCall,
5826
+ parseFastModeRejection,
5664
5827
  prewarmAnthropicCache,
5665
5828
  providerRegistry,
5666
5829
  redactText,