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]