@code-yeongyu/senpi-ai 2026.8.14 → 2026.8.17

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.
Files changed (164) hide show
  1. package/README.md +3 -0
  2. package/dist/api/anthropic-messages.d.ts.map +1 -1
  3. package/dist/api/anthropic-messages.js +40 -14
  4. package/dist/api/anthropic-messages.js.map +1 -1
  5. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  6. package/dist/api/bedrock-converse-stream.js +16 -4
  7. package/dist/api/bedrock-converse-stream.js.map +1 -1
  8. package/dist/api/cloudflare-gateway-binding.d.ts +69 -0
  9. package/dist/api/cloudflare-gateway-binding.d.ts.map +1 -0
  10. package/dist/api/cloudflare-gateway-binding.js +159 -0
  11. package/dist/api/cloudflare-gateway-binding.js.map +1 -0
  12. package/dist/api/constrained-sampling.d.ts +3 -0
  13. package/dist/api/constrained-sampling.d.ts.map +1 -1
  14. package/dist/api/constrained-sampling.js +125 -5
  15. package/dist/api/constrained-sampling.js.map +1 -1
  16. package/dist/api/cursor-agent/deterministic-id.d.ts +17 -0
  17. package/dist/api/cursor-agent/deterministic-id.d.ts.map +1 -0
  18. package/dist/api/cursor-agent/deterministic-id.js +14 -0
  19. package/dist/api/cursor-agent/deterministic-id.js.map +1 -0
  20. package/dist/api/cursor-agent/exec-lifecycle.d.ts +13 -0
  21. package/dist/api/cursor-agent/exec-lifecycle.d.ts.map +1 -0
  22. package/dist/api/cursor-agent/exec-lifecycle.js +33 -0
  23. package/dist/api/cursor-agent/exec-lifecycle.js.map +1 -0
  24. package/dist/api/cursor-agent/exec-modern.d.ts +79 -0
  25. package/dist/api/cursor-agent/exec-modern.d.ts.map +1 -0
  26. package/dist/api/cursor-agent/exec-modern.js +360 -0
  27. package/dist/api/cursor-agent/exec-modern.js.map +1 -0
  28. package/dist/api/cursor-agent/gen/agent_pb.d.ts +16797 -0
  29. package/dist/api/cursor-agent/gen/agent_pb.d.ts.map +1 -0
  30. package/dist/api/cursor-agent/gen/agent_pb.js +3828 -0
  31. package/dist/api/cursor-agent/gen/agent_pb.js.map +1 -0
  32. package/dist/api/cursor-agent/pi-args.d.ts +55 -0
  33. package/dist/api/cursor-agent/pi-args.d.ts.map +1 -0
  34. package/dist/api/cursor-agent/pi-args.js +76 -0
  35. package/dist/api/cursor-agent/pi-args.js.map +1 -0
  36. package/dist/api/cursor-agent/types.d.ts +116 -0
  37. package/dist/api/cursor-agent/types.d.ts.map +1 -0
  38. package/dist/api/cursor-agent/types.js +16 -0
  39. package/dist/api/cursor-agent/types.js.map +1 -0
  40. package/dist/api/cursor-agent.d.ts +191 -0
  41. package/dist/api/cursor-agent.d.ts.map +1 -0
  42. package/dist/api/cursor-agent.js +3316 -0
  43. package/dist/api/cursor-agent.js.map +1 -0
  44. package/dist/api/cursor-agent.lazy.d.ts +29 -0
  45. package/dist/api/cursor-agent.lazy.d.ts.map +1 -0
  46. package/dist/api/cursor-agent.lazy.js +33 -0
  47. package/dist/api/cursor-agent.lazy.js.map +1 -0
  48. package/dist/api/google-generative-ai.js +7 -3
  49. package/dist/api/google-generative-ai.js.map +1 -1
  50. package/dist/api/google-shared.d.ts +1 -1
  51. package/dist/api/google-shared.d.ts.map +1 -1
  52. package/dist/api/google-shared.js +13 -9
  53. package/dist/api/google-shared.js.map +1 -1
  54. package/dist/api/google-vertex.js +7 -3
  55. package/dist/api/google-vertex.js.map +1 -1
  56. package/dist/api/mistral-conversations.d.ts +1 -1
  57. package/dist/api/mistral-conversations.d.ts.map +1 -1
  58. package/dist/api/mistral-conversations.js +208 -42
  59. package/dist/api/mistral-conversations.js.map +1 -1
  60. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  61. package/dist/api/openai-codex-responses.js +13 -4
  62. package/dist/api/openai-codex-responses.js.map +1 -1
  63. package/dist/api/openai-completions.d.ts.map +1 -1
  64. package/dist/api/openai-completions.js +10 -7
  65. package/dist/api/openai-completions.js.map +1 -1
  66. package/dist/api/openai-responses-shared.d.ts +1 -0
  67. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  68. package/dist/api/openai-responses-shared.js +31 -7
  69. package/dist/api/openai-responses-shared.js.map +1 -1
  70. package/dist/api/openai-responses.d.ts.map +1 -1
  71. package/dist/api/openai-responses.js +8 -1
  72. package/dist/api/openai-responses.js.map +1 -1
  73. package/dist/auth/oauth/cursor.d.ts +16 -0
  74. package/dist/auth/oauth/cursor.d.ts.map +1 -0
  75. package/dist/auth/oauth/cursor.js +234 -0
  76. package/dist/auth/oauth/cursor.js.map +1 -0
  77. package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  78. package/dist/auth/oauth/github-copilot.js +6 -3
  79. package/dist/auth/oauth/github-copilot.js.map +1 -1
  80. package/dist/auth/oauth/load.d.ts +2 -0
  81. package/dist/auth/oauth/load.d.ts.map +1 -1
  82. package/dist/auth/oauth/load.js +5 -0
  83. package/dist/auth/oauth/load.js.map +1 -1
  84. package/dist/auth/resolve.js +44 -9
  85. package/dist/auth/resolve.js.map +1 -1
  86. package/dist/auth/types.d.ts +2 -0
  87. package/dist/auth/types.d.ts.map +1 -1
  88. package/dist/auth/types.js.map +1 -1
  89. package/dist/bun-oauth.d.ts.map +1 -1
  90. package/dist/bun-oauth.js +2 -0
  91. package/dist/bun-oauth.js.map +1 -1
  92. package/dist/compat.d.ts +1 -0
  93. package/dist/compat.d.ts.map +1 -1
  94. package/dist/compat.js +3 -0
  95. package/dist/compat.js.map +1 -1
  96. package/dist/cursor-agent-provider.d.ts +11 -0
  97. package/dist/cursor-agent-provider.d.ts.map +1 -0
  98. package/dist/cursor-agent-provider.js +11 -0
  99. package/dist/cursor-agent-provider.js.map +1 -0
  100. package/dist/index.d.ts +3 -0
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +2 -0
  103. package/dist/index.js.map +1 -1
  104. package/dist/model.d.ts +6 -1
  105. package/dist/model.d.ts.map +1 -1
  106. package/dist/model.js.map +1 -1
  107. package/dist/providers/all.d.ts.map +1 -1
  108. package/dist/providers/all.js +2 -0
  109. package/dist/providers/all.js.map +1 -1
  110. package/dist/providers/cursor.d.ts +12 -0
  111. package/dist/providers/cursor.d.ts.map +1 -0
  112. package/dist/providers/cursor.js +65 -0
  113. package/dist/providers/cursor.js.map +1 -0
  114. package/dist/providers/data/.manifest.json +1 -1
  115. package/dist/providers/data/alibaba-token-plan.json +1 -1
  116. package/dist/providers/data/amazon-bedrock.json +1 -1
  117. package/dist/providers/data/baseten.json +1 -1
  118. package/dist/providers/data/cerebras.json +1 -1
  119. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  120. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  121. package/dist/providers/data/deepseek.json +1 -1
  122. package/dist/providers/data/fireworks.json +1 -1
  123. package/dist/providers/data/github-copilot.json +1 -1
  124. package/dist/providers/data/huggingface.json +1 -1
  125. package/dist/providers/data/kimi-coding.json +1 -1
  126. package/dist/providers/data/nvidia.json +1 -1
  127. package/dist/providers/data/openai-codex.json +1 -1
  128. package/dist/providers/data/openai.json +1 -1
  129. package/dist/providers/data/opencode-go.json +1 -1
  130. package/dist/providers/data/openrouter.json +1 -1
  131. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  132. package/dist/providers/data/qwen-token-plan.json +1 -1
  133. package/dist/providers/data/together.json +1 -1
  134. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  135. package/dist/providers/data/zai-coding-cn.json +1 -1
  136. package/dist/providers/data/zai.json +1 -1
  137. package/dist/types.d.ts +17 -4
  138. package/dist/types.d.ts.map +1 -1
  139. package/dist/types.js.map +1 -1
  140. package/dist/utils/block-symbols.d.ts +57 -0
  141. package/dist/utils/block-symbols.d.ts.map +1 -0
  142. package/dist/utils/block-symbols.js +57 -0
  143. package/dist/utils/block-symbols.js.map +1 -0
  144. package/dist/utils/event-stream.d.ts +10 -0
  145. package/dist/utils/event-stream.d.ts.map +1 -1
  146. package/dist/utils/event-stream.js +22 -0
  147. package/dist/utils/event-stream.js.map +1 -1
  148. package/dist/utils/overflow.d.ts.map +1 -1
  149. package/dist/utils/overflow.js +2 -0
  150. package/dist/utils/overflow.js.map +1 -1
  151. package/dist/utils/pi-user-agent.d.ts +2 -0
  152. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  153. package/dist/utils/pi-user-agent.js +12 -0
  154. package/dist/utils/pi-user-agent.js.map +1 -0
  155. package/dist/utils/prompt-cache-ttl.d.ts.map +1 -1
  156. package/dist/utils/prompt-cache-ttl.js +3 -2
  157. package/dist/utils/prompt-cache-ttl.js.map +1 -1
  158. package/dist/utils/retry.d.ts.map +1 -1
  159. package/dist/utils/retry.js +1 -0
  160. package/dist/utils/retry.js.map +1 -1
  161. package/dist/utils/validation.d.ts.map +1 -1
  162. package/dist/utils/validation.js +34 -0
  163. package/dist/utils/validation.js.map +1 -1
  164. package/package.json +3 -2
package/README.md CHANGED
@@ -90,6 +90,7 @@ Unified LLM API with provider collections, automatic auth resolution, token and
90
90
  - **Qwen Token Plan** (separate Individual and existing catalogs, with a separate China provider)
91
91
  - **Xiaomi MiMo** (defaults to API billing endpoint, with separate Token Plan providers for `cn`/`ams`/`sgp` regions)
92
92
  - **Alibaba Token Plan** (Alibaba Cloud Model Studio prepaid Token Plan, OpenAI-compatible `ap-southeast-1` endpoint)
93
+ - **Cursor** (Pro/Ultra/Teams subscription; native `cursor-agent` protocol with full chat + server-driven tool calling, per-account dynamic catalog, requires OAuth, see below)
93
94
  - **Any other OpenAI-compatible API**: local Ollama, vLLM, LM Studio, etc.
94
95
 
95
96
  ## Installation
@@ -1161,6 +1162,7 @@ Built-in API implementations live under `./api/<api-id>`:
1161
1162
  | `openai-completions` | `OpenAICompletionsOptions` |
1162
1163
  | `openai-responses` | `OpenAIResponsesOptions` |
1163
1164
  | `openai-codex-responses` | `OpenAICodexResponsesOptions` |
1165
+ | `cursor-agent` | `CursorAgentOptions` |
1164
1166
  | `azure-openai-responses` | `AzureOpenAIResponsesOptions` |
1165
1167
  | `google-generative-ai` | `GoogleOptions` |
1166
1168
  | `google-vertex` | `GoogleVertexOptions` |
@@ -1483,6 +1485,7 @@ Several providers support OAuth authentication instead of static API keys:
1483
1485
  - **OpenAI Codex** (ChatGPT Plus/Pro subscription, access to GPT-5.x Codex models)
1484
1486
  - **GitHub Copilot** (Copilot subscription)
1485
1487
  - **OpenRouter** (OAuth PKCE that mints a user-controlled API key)
1488
+ - **Cursor** (Pro/Ultra/Teams subscription; browser deep-link + poll flow. After login, the per-account model catalog is discovered through `GetUsableModels` and chat streams over the native `cursor-agent` protocol with in-band tool execution — hosts supply `CursorAgentOptions.execHandlers` to bridge Cursor's server-driven tool calls onto local tools)
1486
1489
 
1487
1490
  Each of these providers carries an `OAuthAuth` on `provider.auth.oauth` with three operations: `login(interaction)` uses the provider-neutral `AuthInteraction.prompt()`/`notify()` protocol and returns a credential, `refresh(credential, signal)` refreshes expiring credentials when applicable, and `toAuth(credential)` derives request auth (GitHub Copilot's per-account base URL comes from here). Provider login interactions and refresh calls always carry a concrete abort signal. Refresh is automatic: `models.getAuth(providerId)` and request paths refresh expired tokens under a credential-store lock, so concurrent requests and processes cannot double-refresh. OpenRouter's OAuth flow instead returns a permanent API key, so its refresh operation is a no-op.
1488
1491
 
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAGX,+BAA+B,EAK/B,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAKX,OAAO,EAGP,KAAK,EAGL,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;AAkCrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AA6JlE,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AAoEhE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AA4zBD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CA6ZzE,CAAC;AA0FF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CA2ClF,CAAC;AAsIF,wBAAgB,mCAAmC,CAClD,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,EAClC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,gBAAgB,GACxB,+BAA+B,CAkBjC"}
1
+ {"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAGX,+BAA+B,EAK/B,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAKX,OAAO,EAGP,KAAK,EAGL,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;AAmCrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AA6JlE,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AAoEhE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AA+1BD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CA2ZzE,CAAC;AA0FF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAyClF,CAAC;AAyIF,wBAAgB,mCAAmC,CAClD,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,EAClC,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,gBAAgB,GACxB,+BAA+B,CAkBjC"}
@@ -6,6 +6,7 @@ import { splitDeferredTools } from "../utils/deferred-tools.js";
6
6
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
7
7
  import { headersToRecord, providerHeadersToRecord } from "../utils/headers.js";
8
8
  import { parseJsonWithRepair, parseStreamingJson } from "../utils/json-parse.js";
9
+ import { getPiUserAgent } from "../utils/pi-user-agent.js";
9
10
  import { getAnthropicCompat, isAnthropicApiBaseUrl } from "../utils/prompt-cache-ttl.js";
10
11
  import { getProviderEnvValue } from "../utils/provider-env.js";
11
12
  import { retryProviderRequest } from "../utils/provider-retry.js";
@@ -18,7 +19,7 @@ import { resolveRootObjectSchema } from "../utils/tool-schema-compat.js";
18
19
  import { demotedToolCallText, demotedToolResultText } from "../utils/unavailable-tool-text.js";
19
20
  import { sanitizeAnthropicToolPairs } from "./anthropic-tool-pairs.js";
20
21
  import { resolveCloudflareBaseUrl } from "./cloudflare.js";
21
- import { resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
22
+ import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
22
23
  import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
23
24
  import { ANTHROPIC_RESERVED_BODY_KEYS, adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext, } from "./simple-options.js";
24
25
  import { transformMessages } from "./transform-messages.js";
@@ -197,8 +198,36 @@ function mergeHeaders(...headerSources) {
197
198
  }
198
199
  return merged;
199
200
  }
200
- function hasAuthorizationHeader(headers) {
201
- return Object.keys(headers ?? {}).some((name) => name.toLowerCase() === "authorization");
201
+ function mergeClientHeaders(model, ...headerSources) {
202
+ const merged = mergeHeaders(...headerSources);
203
+ if (model.provider === "kimi-coding") {
204
+ for (const name of Object.keys(merged)) {
205
+ if (name.toLowerCase() === "user-agent")
206
+ delete merged[name];
207
+ }
208
+ merged["User-Agent"] = getPiUserAgent();
209
+ }
210
+ return merged;
211
+ }
212
+ function hasHeader(headers, name) {
213
+ if (!headers)
214
+ return false;
215
+ const expected = name.toLowerCase();
216
+ for (const [key, value] of Object.entries(headers)) {
217
+ if (key.toLowerCase() === expected && value !== null && value.trim().length > 0)
218
+ return true;
219
+ }
220
+ return false;
221
+ }
222
+ function assertRequestAuth(provider, apiKey, headers) {
223
+ if (apiKey)
224
+ return;
225
+ if (hasHeader(headers, "authorization") ||
226
+ hasHeader(headers, "x-api-key") ||
227
+ hasHeader(headers, "cf-aig-authorization")) {
228
+ return;
229
+ }
230
+ throw new Error(`No API key for provider: ${provider}`);
202
231
  }
203
232
  function isRecord(value) {
204
233
  return typeof value === "object" && value !== null;
@@ -901,9 +930,7 @@ export const stream = (model, context, options) => {
901
930
  else {
902
931
  const apiKey = options?.apiKey;
903
932
  const optionsHeaders = providerHeadersToRecord(options?.headers);
904
- if (!apiKey && !hasAuthorizationHeader(optionsHeaders)) {
905
- throw new Error(`No API key for provider: ${model.provider}`);
906
- }
933
+ assertRequestAuth(model.provider, apiKey, optionsHeaders);
907
934
  let copilotDynamicHeaders;
908
935
  if (model.provider === "github-copilot") {
909
936
  const hasImages = hasCopilotVisionInput(context.messages);
@@ -1329,9 +1356,7 @@ function mapThinkingLevelToEffort(model, level) {
1329
1356
  }
1330
1357
  export const streamSimple = (model, context, options) => {
1331
1358
  const apiKey = options?.apiKey;
1332
- if (!apiKey && !hasAuthorizationHeader(providerHeadersToRecord(options?.headers))) {
1333
- throw new Error(`No API key for provider: ${model.provider}`);
1334
- }
1359
+ assertRequestAuth(model.provider, apiKey, providerHeadersToRecord(options?.headers));
1335
1360
  const base = buildBaseOptions(model, context, options, options?.apiKey);
1336
1361
  if (!options?.reasoning) {
1337
1362
  return stream(model, context, { ...base, thinkingEnabled: false });
@@ -1396,7 +1421,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
1396
1421
  baseURL: model.baseUrl,
1397
1422
  dangerouslyAllowBrowser: true,
1398
1423
  fetch,
1399
- defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeHeaders({
1424
+ defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeClientHeaders(model, {
1400
1425
  accept: "application/json",
1401
1426
  "anthropic-dangerous-direct-browser-access": "true",
1402
1427
  ...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
@@ -1412,7 +1437,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
1412
1437
  baseURL: model.baseUrl,
1413
1438
  dangerouslyAllowBrowser: true,
1414
1439
  fetch,
1415
- defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeHeaders({
1440
+ defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeClientHeaders(model, {
1416
1441
  accept: "application/json",
1417
1442
  "anthropic-dangerous-direct-browser-access": "true",
1418
1443
  "anthropic-beta": ["claude-code-20250219", "oauth-2025-04-20", ...betaFeatures].join(","),
@@ -1430,7 +1455,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
1430
1455
  baseURL: model.baseUrl,
1431
1456
  dangerouslyAllowBrowser: true,
1432
1457
  fetch,
1433
- defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeHeaders({
1458
+ defaultHeaders: sanitizeAdaptiveThinkingHeaders(model, mergeClientHeaders(model, {
1434
1459
  accept: "application/json",
1435
1460
  "anthropic-dangerous-direct-browser-access": "true",
1436
1461
  ...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
@@ -1845,9 +1870,10 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
1845
1870
  return [];
1846
1871
  return tools.map((tool, index) => {
1847
1872
  const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools);
1873
+ const parameters = getJsonSchemaToolParameters(tool, strict);
1848
1874
  // A root union carries no top-level properties, so reading them directly
1849
1875
  // would advertise the tool to the model as taking no arguments at all.
1850
- const schema = resolveRootObjectSchema(tool.parameters);
1876
+ const schema = resolveRootObjectSchema(parameters);
1851
1877
  const legacyInputSchema = {
1852
1878
  type: "object",
1853
1879
  properties: schema.properties ?? {},
@@ -1855,7 +1881,7 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
1855
1881
  };
1856
1882
  const inputSchema = strict === true
1857
1883
  ? {
1858
- ...tool.parameters,
1884
+ ...parameters,
1859
1885
  ...legacyInputSchema,
1860
1886
  }
1861
1887
  : legacyInputSchema;