diff --git a/.vscode/extensions/vscode-selfhost-test-provider/src/streamSplitter.ts b/.vscode/extensions/vscode-selfhost-test-provider/src/streamSplitter.ts
index bb5bc5f2..7dc085e1 100644
--- a/.vscode/extensions/vscode-selfhost-test-provider/src/streamSplitter.ts
+++ b/.vscode/extensions/vscode-selfhost-test-provider/src/streamSplitter.ts
@@ -36,7 +36,7 @@ export class StreamSplitter extends Transform {
if (!this.buffer) {
this.buffer = chunk;
} else {
- this.buffer = Buffer.concat([this.buffer, chunk]);
+ this.buffer = Buffer.concat([this.buffer, chunk] as readonly Uint8Array[]);
}
let offset = 0;
diff --git a/extensions/extension-editing/tsconfig.json b/extensions/extension-editing/tsconfig.json
index 3714bd09..e49c3992 100644
--- a/extensions/extension-editing/tsconfig.json
+++ b/extensions/extension-editing/tsconfig.json
@@ -3,7 +3,8 @@
"compilerOptions": {
"outDir": "./out",
"typeRoots": [
- "node_modules/@types"
+ "../../node_modules/@types",
+ "./node_modules/@types"
]
},
"include": [
diff --git a/extensions/git-base/tsconfig.json b/extensions/git-base/tsconfig.json
index d7aed183..34c250d2 100644
--- a/extensions/git-base/tsconfig.json
+++ b/extensions/git-base/tsconfig.json
@@ -4,6 +4,7 @@
"outDir": "./out",
"experimentalDecorators": true,
"typeRoots": [
+ "../../../node_modules/@types",
"./node_modules/@types"
]
},
diff --git a/extensions/git/tsconfig.json b/extensions/git/tsconfig.json
index fc72bd70..a3b475a6 100644
--- a/extensions/git/tsconfig.json
+++ b/extensions/git/tsconfig.json
@@ -4,6 +4,7 @@
"outDir": "./out",
"experimentalDecorators": true,
"typeRoots": [
+ "../../../node_modules/@types",
"./node_modules/@types"
]
},
diff --git a/extensions/github-authentication/tsconfig.json b/extensions/github-authentication/tsconfig.json
index 5e4713e9..cb1f89c4 100644
--- a/extensions/github-authentication/tsconfig.json
+++ b/extensions/github-authentication/tsconfig.json
@@ -4,6 +4,7 @@
"outDir": "./out",
"experimentalDecorators": true,
"typeRoots": [
+ "../../../node_modules/@types",
"./node_modules/@types"
],
"lib": [
diff --git a/extensions/github/tsconfig.json b/extensions/github/tsconfig.json
index 8435c0d0..7481e249 100644
--- a/extensions/github/tsconfig.json
+++ b/extensions/github/tsconfig.json
@@ -4,6 +4,7 @@
"outDir": "./out",
"experimentalDecorators": true,
"typeRoots": [
+ "../../../node_modules/@types",
"./node_modules/@types"
]
},
diff --git a/extensions/microsoft-authentication/src/AADHelper.ts b/extensions/microsoft-authentication/src/AADHelper.ts
index 9722145d..c25dda45 100644
--- a/extensions/microsoft-authentication/src/AADHelper.ts
+++ b/extensions/microsoft-authentication/src/AADHelper.ts
@@ -551,7 +551,7 @@ export class AzureActiveDirectoryService {
throw e;
}
- const id = `${claims.tid}/${(claims.oid ?? (claims.altsecid ?? '' + claims.ipd ?? ''))}`;
+ const id = `${claims.tid}/${(claims.oid ?? claims.altsecid ?? claims.ipd ?? '')}`;
const sessionId = existingId || `${id}/${randomUUID()}`;
this._logger.trace(`[${scopeData.scopeStr}] '${sessionId}' Token response parsed successfully.`);
return {
diff --git a/extensions/package-lock.json b/extensions/package-lock.json
index e3e87e1f..e20e14a0 100644
--- a/extensions/package-lock.json
+++ b/extensions/package-lock.json
@@ -10,7 +10,7 @@
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
- "typescript": "^5.8.2"
+ "typescript": "5.6.3"
},
"devDependencies": {
"@parcel/watcher": "2.5.1",
@@ -940,9 +940,9 @@
}
},
"node_modules/typescript": {
- "version": "5.8.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
- "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
+ "version": "5.6.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
+ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
diff --git a/extensions/package.json b/extensions/package.json
index d24575b1..d94f99d4 100644
--- a/extensions/package.json
+++ b/extensions/package.json
@@ -4,7 +4,7 @@
"license": "MIT",
"description": "Dependencies shared by all extensions",
"dependencies": {
- "typescript": "^5.8.2"
+ "typescript": "5.6.3"
},
"scripts": {
"postinstall": "node ./postinstall.mjs"
diff --git a/extensions/tsconfig.base.json b/extensions/tsconfig.base.json
index 8aa0dbff..0ec81d72 100644
--- a/extensions/tsconfig.base.json
+++ b/extensions/tsconfig.base.json
@@ -36,6 +36,7 @@
"noImplicitOverride": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
- "forceConsistentCasingInFileNames": true
+ "forceConsistentCasingInFileNames": true,
+ "skipLibCheck": true
}
}
diff --git a/extensions/tunnel-forwarding/src/split.ts b/extensions/tunnel-forwarding/src/split.ts
index 33ad055a..d2895a13 100644
--- a/extensions/tunnel-forwarding/src/split.ts
+++ b/extensions/tunnel-forwarding/src/split.ts
@@ -23,7 +23,7 @@ export class StreamSplitter extends Transform {
if (!this.buffer) {
this.buffer = chunk;
} else {
- this.buffer = Buffer.concat([this.buffer, chunk]);
+ this.buffer = Buffer.concat([this.buffer, chunk] as readonly Uint8Array[]);
}
let offset = 0;
diff --git a/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts b/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts
index 747e7c22..1e4f9cc3 100644
--- a/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts
+++ b/extensions/typescript-language-features/src/tsServer/protocol/protocol.d.ts
@@ -19,5 +19,13 @@ declare module '../../../../node_modules/typescript/lib/typescript' {
interface Response {
readonly _serverType?: ServerType;
}
+
+ /** Missing from typescript@5.6 lib; required at runtime when the bundled server supports preparePasteEdits (API ≥ 5.7). */
+ interface PreparePasteEditsRequestArgs extends FileRequestArgs {
+ copiedTextSpan: TextSpan[];
+ }
+ interface PreparePasteEditsResponse extends Response {
+ body: boolean;
+ }
}
}
diff --git a/package-lock.json b/package-lock.json
index 8666d0ef..30aedda1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -88,7 +88,7 @@
"@types/kerberos": "^1.1.2",
"@types/minimist": "^1.2.1",
"@types/mocha": "^9.1.1",
- "@types/node": "20.x",
+ "@types/node": "20.17.14",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@types/sinon": "^10.0.2",
@@ -184,7 +184,7 @@
"tsec": "0.2.7",
"tslib": "^2.6.3",
"tsup": "^8.4.0",
- "typescript": "^5.8.0-dev.20250207",
+ "typescript": "5.6.3",
"typescript-eslint": "^8.8.0",
"util": "^0.12.4",
"webpack": "^5.94.0",
@@ -225,21 +225,6 @@
"node-fetch": "^2.6.7"
}
},
- "node_modules/@anthropic-ai/sdk/node_modules/@types/node": {
- "version": "18.19.130",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz",
- "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==",
- "license": "MIT",
- "dependencies": {
- "undici-types": "~5.26.4"
- }
- },
- "node_modules/@anthropic-ai/sdk/node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "license": "MIT"
- },
"node_modules/@azure-rest/ai-translation-text": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@azure-rest/ai-translation-text/-/ai-translation-text-1.0.1.tgz",
@@ -4255,12 +4240,12 @@
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "20.19.39",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz",
- "integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==",
+ "version": "20.17.14",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.14.tgz",
+ "integrity": "sha512-w6qdYetNL5KRBiSClK/KWai+2IMEJuAj+EujKCumalFOwXtvOXaEan9AuwcRID2IcOIAWSIfR495hBtgKlx2zg==",
"license": "MIT",
"dependencies": {
- "undici-types": "~6.21.0"
+ "undici-types": "~6.19.2"
}
},
"node_modules/@types/node-fetch": {
@@ -12404,21 +12389,6 @@
"node-fetch": "^2.6.7"
}
},
- "node_modules/groq-sdk/node_modules/@types/node": {
- "version": "18.19.130",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz",
- "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==",
- "license": "MIT",
- "dependencies": {
- "undici-types": "~5.26.4"
- }
- },
- "node_modules/groq-sdk/node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "license": "MIT"
- },
"node_modules/gtoken": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
@@ -18920,21 +18890,6 @@
}
}
},
- "node_modules/openai/node_modules/@types/node": {
- "version": "18.19.130",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz",
- "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==",
- "license": "MIT",
- "dependencies": {
- "undici-types": "~5.26.4"
- }
- },
- "node_modules/openai/node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "license": "MIT"
- },
"node_modules/opentype.js": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-0.8.0.tgz",
@@ -25093,9 +25048,9 @@
"license": "MIT"
},
"node_modules/typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "version": "5.6.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
+ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -25238,9 +25193,9 @@
}
},
"node_modules/undici-types": {
- "version": "6.21.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
- "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "version": "6.19.8",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
+ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"license": "MIT"
},
"node_modules/union-value": {
diff --git a/package.json b/package.json
index 0fd249b0..84b044a8 100644
--- a/package.json
+++ b/package.json
@@ -150,7 +150,7 @@
"@types/kerberos": "^1.1.2",
"@types/minimist": "^1.2.1",
"@types/mocha": "^9.1.1",
- "@types/node": "20.x",
+ "@types/node": "20.17.14",
"@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2",
"@types/sinon": "^10.0.2",
@@ -246,7 +246,7 @@
"tsec": "0.2.7",
"tslib": "^2.6.3",
"tsup": "^8.4.0",
- "typescript": "^5.8.0-dev.20250207",
+ "typescript": "5.6.3",
"typescript-eslint": "^8.8.0",
"util": "^0.12.4",
"webpack": "^5.94.0",
@@ -256,6 +256,7 @@
"yaserver": "^0.4.0"
},
"overrides": {
+ "@types/node": "20.17.14",
"node-gyp-build": "4.8.1",
"kerberos@2.1.1": {
"node-addon-api": "7.1.0"
diff --git a/src/vs/base/node/nodeStreams.ts b/src/vs/base/node/nodeStreams.ts
index 0dba130a..b650cc2f 100644
--- a/src/vs/base/node/nodeStreams.ts
+++ b/src/vs/base/node/nodeStreams.ts
@@ -32,7 +32,7 @@ export class StreamSplitter extends Transform {
if (!this.buffer) {
this.buffer = chunk;
} else {
- this.buffer = Buffer.concat([this.buffer, chunk]);
+ this.buffer = Buffer.concat([this.buffer, chunk] as readonly Uint8Array[]);
}
let offset = 0;
diff --git a/src/vs/platform/webContentExtractor/node/sharedWebContentExtractorService.ts b/src/vs/platform/webContentExtractor/node/sharedWebContentExtractorService.ts
index 61ae28d1..41ffc9e9 100644
--- a/src/vs/platform/webContentExtractor/node/sharedWebContentExtractorService.ts
+++ b/src/vs/platform/webContentExtractor/node/sharedWebContentExtractorService.ts
@@ -28,7 +28,8 @@ export class SharedWebContentExtractorService implements ISharedWebContentExtrac
return undefined;
}
- const content = VSBuffer.wrap(await response.bytes());
+ const body = await response.arrayBuffer();
+ const content = VSBuffer.wrap(new Uint8Array(body));
return content;
} catch (err) {
console.log(err);
diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
index b835c0b5..0ae8d0b5 100644
--- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
+++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
@@ -221,9 +221,6 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach
cursorWidth: config.cursorWidth,
macOptionIsMeta: config.macOptionIsMeta,
macOptionClickForcesSelection: config.macOptionClickForcesSelection,
- rightClickSelectsWord: config.rightClickBehavior === 'selectWord',
- fastScrollModifier: 'alt',
- fastScrollSensitivity: config.fastScrollSensitivity,
scrollSensitivity: config.mouseWheelScrollSensitivity,
wordSeparator: config.wordSeparators,
overviewRuler: {
diff --git a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts
index 94545c0d..3d0c29bd 100644
--- a/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts
+++ b/src/vs/workbench/contrib/void/browser/convertToLLMMessageService.ts
@@ -77,7 +77,15 @@ const prepareMessages_openai_tools = (messages: SimpleLLMMessage[]): AnthropicOr
const currMsg = messages[i]
if (currMsg.role !== 'tool') {
- newMessages.push(currMsg)
+ // Omit anthropic-only fields: JSON.stringify would send them and strict APIs (e.g. Mistral) return 422 Extra inputs.
+ if (currMsg.role === 'assistant') {
+ newMessages.push({
+ role: 'assistant',
+ content: currMsg.content,
+ })
+ } else {
+ newMessages.push(currMsg)
+ }
continue
}
diff --git a/src/vs/workbench/contrib/void/common/modelCapabilities.ts b/src/vs/workbench/contrib/void/common/modelCapabilities.ts
index d7d3e7d8..56b7f659 100644
--- a/src/vs/workbench/contrib/void/common/modelCapabilities.ts
+++ b/src/vs/workbench/contrib/void/common/modelCapabilities.ts
@@ -717,24 +717,8 @@ const openAICompatIncludeInPayloadReasoning = (reasoningInfo: SendableReasoningI
}
-// Mistral Adjustable Reasoning — only "none" | "high" (not OpenAI-style low/medium/high)
-// https://docs.mistral.ai/capabilities/reasoning/adjustable
-const mistralIncludeInPayloadReasoning = (reasoningInfo: SendableReasoningInfo) => {
- if (!reasoningInfo?.isReasoningEnabled) return null
- if (reasoningInfo.type !== 'effort_slider_value') return null
- const raw = reasoningInfo.reasoningEffort
- let reasoning_effort: 'high' | 'none'
- if (raw === 'none') {
- reasoning_effort = 'none'
- } else if (raw === 'high') {
- reasoning_effort = 'high'
- } else if (raw === 'low') {
- reasoning_effort = 'none'
- } else {
- reasoning_effort = 'high'
- }
- return { reasoning_effort }
-}
+// Mistral via OpenAI SDK: omit `reasoning_effort` (422 "Extra inputs are not permitted"); public OpenAPI ≠ strict gateway here. Use Mistral-native SDK upstream if needed.
+const mistralIncludeInPayloadReasoning = (_reasoningInfo: SendableReasoningInfo): null => null
const openAISettings: VoidStaticProviderInfo = {
modelOptions: openAIModelOptions,
@@ -999,7 +983,8 @@ const mistralModelOptions = { // https://docs.mistral.ai/getting-started/models/
specialToolFormat: 'openai-style',
downloadable: { sizeGb: 'not-known' },
supportsSystemMessage: 'system-role',
- reasoningCapabilities: { supportsReasoning: true, canIOReasoning: true, canTurnOffReasoning: true, reasoningSlider: { type: 'effort_slider', values: ['none', 'high'], default: 'high' }, openSourceThinkTags: ['', ''] },
+ // No `reasoning_effort` payload (see mistralIncludeInPayloadReasoning). Surface thinking tags from stream text when present (same shape as Magistral).
+ reasoningCapabilities: { supportsReasoning: true, canIOReasoning: true, canTurnOffReasoning: false, openSourceThinkTags: ['', ''] },
},
'mistral-small-latest': { // Mistral Small 4 — https://docs.mistral.ai/models/model-cards/mistral-small-4-0-26-03
contextWindow: 256_000,
@@ -1009,7 +994,7 @@ const mistralModelOptions = { // https://docs.mistral.ai/getting-started/models/
specialToolFormat: 'openai-style',
downloadable: { sizeGb: 'not-known' },
supportsSystemMessage: 'system-role',
- reasoningCapabilities: { supportsReasoning: true, canIOReasoning: true, canTurnOffReasoning: true, reasoningSlider: { type: 'effort_slider', values: ['none', 'high'], default: 'high' }, openSourceThinkTags: ['', ''] },
+ reasoningCapabilities: { supportsReasoning: true, canIOReasoning: true, canTurnOffReasoning: false, openSourceThinkTags: ['', ''] },
},
'codestral-latest': { // Codestral 25.08 — https://docs.mistral.ai/models/model-cards/codestral-25-08
contextWindow: 128_000,
@@ -1098,6 +1083,7 @@ const mistralSettings: VoidStaticProviderInfo = {
modelOptionsFallback: (modelName) => { return null },
providerReasoningIOSettings: {
input: { includeInPayload: mistralIncludeInPayloadReasoning },
+ output: { needsManualParse: true },
},
}
diff --git a/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts b/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts
index e0953635..0402dbd6 100644
--- a/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts
+++ b/src/vs/workbench/contrib/void/electron-main/llmMessage/sendLLMMessage.impl.ts
@@ -56,6 +56,45 @@ export type ListParams_Internal = ModelListParams
const invalidApiKeyMessage = (providerName: ProviderName) => `Invalid ${displayInfoOfProviderName(providerName).title} API key.`
+/** The OpenAI SDK only reads JSON `error.message`; Mistral often returns FastAPI-shaped `detail`/`message`. Without this remap: "422 status code (no body)". */
+const openAICompatibleErrorMessageFromParsedBody = (parsed: unknown, rawText: string, status: number): string => {
+ if (parsed !== undefined && parsed !== null && typeof parsed === 'object') {
+ const o = parsed as Record
+ const nested = typeof o.error === 'object' && o.error !== null ? (o.error as { message?: unknown }).message : undefined
+ if (typeof nested === 'string') return nested
+ if (typeof o.message === 'string') return o.message
+ if (typeof o.detail === 'string') return o.detail
+ if (Array.isArray(o.detail)) {
+ return o.detail.map((item: unknown) => {
+ if (item && typeof item === 'object' && typeof (item as { msg?: unknown }).msg === 'string') return (item as { msg: string }).msg
+ try { return JSON.stringify(item) } catch { return String(item) }
+ }).join('; ')
+ }
+ }
+ const t = (rawText || '').trim()
+ if (t.length) return t.length > 4000 ? t.slice(0, 3997) + '...' : t
+ return `HTTP ${status}`
+}
+
+const openAITolerantFetch: typeof fetch = async (input, init) => {
+ const res = await globalThis.fetch(input, init as RequestInit)
+ if (res.ok)
+ return res
+ const rawText = await res.text().catch(() => '')
+ let parsed: unknown
+ try {
+ parsed = rawText ? JSON.parse(rawText) : undefined
+ } catch {
+ parsed = undefined
+ }
+ const message = openAICompatibleErrorMessageFromParsedBody(parsed, rawText, res.status)
+ return new Response(JSON.stringify({ error: { message } }), {
+ status: res.status,
+ statusText: res.statusText,
+ headers: res.headers,
+ })
+}
+
// ------------ OPENAI-COMPATIBLE (HELPERS) ------------
@@ -72,6 +111,7 @@ const parseHeadersJSON = (s: string | undefined): Record {
const commonPayloadOpts: ClientOptions = {
dangerouslyAllowBrowser: true,
+ fetch: openAITolerantFetch,
}
if (providerName === 'openAI') {
const thisConfig = settingsOfProvider[providerName]