mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-07 07:16:41 +01:00
Filter out unsupported codex tool type (#1748)
This commit is contained in:
Generated
+5
-5
@@ -104,7 +104,7 @@
|
||||
"monaco-editor": "0.44.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"open": "^10.1.2",
|
||||
"openai": "^5.11.0",
|
||||
"openai": "^6.7.0",
|
||||
"outdent": "^0.8.0",
|
||||
"picomatch": "^4.0.2",
|
||||
"playwright": "^1.56.1",
|
||||
@@ -14526,9 +14526,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/openai": {
|
||||
"version": "5.11.0",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-5.11.0.tgz",
|
||||
"integrity": "sha512-+AuTc5pVjlnTuA9zvn8rA/k+1RluPIx9AD4eDcnutv6JNwHHZxIhkFy+tmMKCvmMFDQzfA/r1ujvPWB19DQkYg==",
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/openai/-/openai-6.7.0.tgz",
|
||||
"integrity": "sha512-mgSQXa3O/UXTbA8qFzoa7aydbXBJR5dbLQXCRapAOtoNT+v69sLdKMZzgiakpqhclRnhPggPAXoniVGn2kMY2A==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
@@ -14536,7 +14536,7 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"ws": "^8.18.0",
|
||||
"zod": "^3.23.8"
|
||||
"zod": "^3.25 || ^4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"ws": {
|
||||
|
||||
@@ -4478,7 +4478,7 @@
|
||||
"monaco-editor": "0.44.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"open": "^10.1.2",
|
||||
"openai": "^5.11.0",
|
||||
"openai": "^6.7.0",
|
||||
"outdent": "^0.8.0",
|
||||
"picomatch": "^4.0.2",
|
||||
"playwright": "^1.56.1",
|
||||
|
||||
@@ -7,7 +7,7 @@ import { RequestMetadata } from '@vscode/copilot-api';
|
||||
import { Raw } from '@vscode/prompt-tsx';
|
||||
import * as http from 'http';
|
||||
import { ClientHttp2Stream } from 'http2';
|
||||
import OpenAI from 'openai';
|
||||
import type OpenAI from 'openai';
|
||||
import { IChatMLFetcher, Source } from '../../../platform/chat/common/chatMLFetcher';
|
||||
import { ChatLocation, ChatResponse } from '../../../platform/chat/common/commonTypes';
|
||||
import { CustomModel, EndpointEditToolName, IEndpointProvider } from '../../../platform/endpoint/common/endpointProvider';
|
||||
@@ -132,6 +132,16 @@ export class OpenAILanguageModelServer extends Disposable {
|
||||
|
||||
try {
|
||||
const requestBody: OpenAI.Responses.ResponseCreateParams = JSON.parse(bodyString);
|
||||
if (Array.isArray(requestBody.tools)) {
|
||||
requestBody.tools = requestBody.tools.filter(tool => {
|
||||
if (typeof tool?.type === 'string' && tool.type.startsWith('web_search')) {
|
||||
this.warn(`Filtering out unsupported tool type: ${JSON.stringify(tool)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
const lastMessage = requestBody.input?.at(-1);
|
||||
const isUserInitiatedMessage = typeof lastMessage === 'string' ||
|
||||
lastMessage?.type === 'message' && lastMessage.role === 'user';
|
||||
@@ -274,6 +284,11 @@ export class OpenAILanguageModelServer extends Disposable {
|
||||
const messageWithClassName = `[OpenAILanguageModelServer] ${message}`;
|
||||
this.logService.trace(messageWithClassName);
|
||||
}
|
||||
|
||||
private warn(message: string): void {
|
||||
const messageWithClassName = `[OpenAILanguageModelServer] ${message}`;
|
||||
this.logService.warn(messageWithClassName);
|
||||
}
|
||||
}
|
||||
|
||||
class StreamingPassThroughEndpoint implements IChatEndpoint {
|
||||
|
||||
@@ -251,14 +251,18 @@ export function responseApiInputToRawMessagesForLogging(body: OpenAI.Responses.R
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'function_call_output':
|
||||
case 'function_call_output': {
|
||||
flushPendingFunctionCalls();
|
||||
messages.push({
|
||||
role: Raw.ChatRole.Tool,
|
||||
content: [{ type: Raw.ChatCompletionContentPartKind.Text, text: item.output }],
|
||||
toolCallId: item.call_id
|
||||
});
|
||||
if (isResponseFunctionCallOutputItem(item)) {
|
||||
const content = responseFunctionOutputToRawContents(item.output);
|
||||
messages.push({
|
||||
role: Raw.ChatRole.Tool,
|
||||
content,
|
||||
toolCallId: item.call_id
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'reasoning':
|
||||
// We can't perfectly reconstruct the original thinking data
|
||||
// but we can add a placeholder for logging
|
||||
@@ -295,6 +299,10 @@ function isResponseInputItemMessage(item: OpenAI.Responses.ResponseInputItem): i
|
||||
return 'role' in item && item.role === 'assistant' && (!('type' in item) || item.type !== 'message');
|
||||
}
|
||||
|
||||
function isResponseFunctionCallOutputItem(item: OpenAI.Responses.ResponseInputItem): item is OpenAI.Responses.ResponseInputItem.FunctionCallOutput {
|
||||
return 'type' in item && item.type === 'function_call_output';
|
||||
}
|
||||
|
||||
function ensureContentArray(content: string | OpenAI.Responses.ResponseInputMessageContentList): OpenAI.Responses.ResponseInputMessageContentList {
|
||||
if (typeof content === 'string') {
|
||||
return [{ type: 'input_text', text: content }];
|
||||
@@ -329,6 +337,36 @@ function responseOutputToRawContent(part: OpenAI.Responses.ResponseOutputText |
|
||||
}
|
||||
}
|
||||
|
||||
function responseFunctionOutputItemToRawContent(part: OpenAI.Responses.ResponseFunctionCallOutputItem): Raw.ChatCompletionContentPart | undefined {
|
||||
if (part.type === 'input_text') {
|
||||
return { type: Raw.ChatCompletionContentPartKind.Text, text: part.text };
|
||||
}
|
||||
if (part.type === 'input_image') {
|
||||
const detail = part.detail && part.detail !== 'auto' ? part.detail : undefined;
|
||||
return {
|
||||
type: Raw.ChatCompletionContentPartKind.Image,
|
||||
imageUrl: {
|
||||
url: part.image_url || '',
|
||||
detail
|
||||
}
|
||||
};
|
||||
}
|
||||
if (part.type === 'input_file') {
|
||||
return {
|
||||
type: Raw.ChatCompletionContentPartKind.Opaque,
|
||||
value: `[File Output - Filename: ${part.filename || 'unknown'}]`
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function responseFunctionOutputToRawContents(output: string | OpenAI.Responses.ResponseFunctionCallOutputItemList): Raw.ChatCompletionContentPart[] {
|
||||
if (typeof output === 'string') {
|
||||
return [{ type: Raw.ChatCompletionContentPartKind.Text, text: output }];
|
||||
}
|
||||
return coalesce(output.map(responseFunctionOutputItemToRawContent));
|
||||
}
|
||||
|
||||
export async function processResponseFromChatEndpoint(instantiationService: IInstantiationService, telemetryService: ITelemetryService, logService: ILogService, response: Response, expectedNumChoices: number, finishCallback: FinishedCallback, telemetryData: TelemetryData): Promise<AsyncIterableObject<ChatCompletion>> {
|
||||
const body = (await response.body()) as ClientHttp2Stream;
|
||||
return new AsyncIterableObject<ChatCompletion>(async feed => {
|
||||
|
||||
Reference in New Issue
Block a user