Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/platform/networking/common/fetch.ts
13401 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { EncryptedThinkingDelta, ThinkingData, ThinkingDelta } from '../../thinking/common/thinking';
7
import { AnthropicMessagesTool, ContextManagementResponse } from './anthropic';
8
import { IHeaders } from './fetcherService';
9
import { ChoiceLogProbs, FilterReason, openAIContextManagementCompactionType, OpenAIContextManagementResponse } from './openai';
10
11
12
// Request helpers
13
14
export interface RequestId {
15
headerRequestId: string;
16
gitHubRequestId: string;
17
completionId: string;
18
created: number;
19
serverExperiments: string;
20
deploymentId: string;
21
}
22
23
export function getRequestId(headers: IHeaders, json?: any): RequestId {
24
const serverExperiments = headers.get('X-Copilot-Experiment') || '';
25
const capiExpAssignmentContext = headers.get('x-copilot-api-exp-assignment-context') || '';
26
return {
27
headerRequestId: headers.get('x-request-id') || '',
28
gitHubRequestId: headers.get('x-github-request-id') || '',
29
completionId: json && json.id ? json.id : '',
30
created: json && json.created ? json.created : 0,
31
serverExperiments: serverExperiments && capiExpAssignmentContext
32
? `${serverExperiments};${capiExpAssignmentContext}`
33
: serverExperiments || capiExpAssignmentContext,
34
deploymentId: headers.get('azureml-model-deployment') || '',
35
};
36
}
37
38
// Request methods
39
40
export interface ICodeVulnerabilityAnnotation {
41
details: {
42
type: string;
43
description: string;
44
};
45
}
46
47
export interface IIPCodeCitation {
48
citations: {
49
url: string;
50
license: string;
51
snippet: string;
52
};
53
}
54
55
export function isCopilotAnnotation(thing: unknown): thing is ICodeVulnerabilityAnnotation {
56
if (typeof thing !== 'object' || thing === null || !('details' in thing)) {
57
return false;
58
}
59
60
const { details } = thing as ICodeVulnerabilityAnnotation;
61
return typeof details === 'object' && details !== null &&
62
'type' in details && 'description' in details && typeof details.type === 'string' && typeof details.description === 'string';
63
}
64
65
export function isCodeCitationAnnotation(thing: unknown): thing is IIPCodeCitation {
66
if (typeof thing !== 'object' || thing === null || !('citations' in thing)) {
67
return false;
68
}
69
70
const { citations } = thing as IIPCodeCitation;
71
return typeof citations === 'object' && citations !== null &&
72
'url' in citations && 'license' in citations && typeof citations.url === 'string' && typeof citations.license === 'string';
73
}
74
75
export interface ICopilotReference {
76
type: string;
77
id: string;
78
data: Record<string, unknown>;
79
metadata?: {
80
display_name: string;
81
display_icon?: string;
82
display_url?: string;
83
};
84
}
85
86
export interface ICopilotToolCall {
87
name: string;
88
arguments: string;
89
id: string;
90
}
91
92
export interface ICopilotToolCallStreamUpdate {
93
name: string;
94
arguments: string;
95
id?: string;
96
}
97
98
export interface ICopilotBeginToolCall {
99
name: string;
100
id?: string;
101
}
102
103
/**
104
* @deprecated
105
*/
106
export interface ICopilotFunctionCall {
107
name: string;
108
arguments: string;
109
}
110
111
export interface ICopilotError {
112
type: string;
113
code: string;
114
message: string;
115
agent: string;
116
identifier?: string;
117
}
118
119
export function isCopilotWebReference(reference: unknown) {
120
return typeof reference === 'object' && !!reference && 'title' in reference && 'excerpt' in reference && 'url' in reference;
121
}
122
123
export interface ICopilotWebReference {
124
title: string;
125
excerpt: string;
126
url: string;
127
}
128
129
export interface ICopilotConfirmation {
130
title: string;
131
message: string;
132
confirmation: any;
133
}
134
135
export interface IResponseDelta {
136
text: string;
137
logprobs?: ChoiceLogProbs;
138
codeVulnAnnotations?: ICodeVulnerabilityAnnotation[];
139
ipCitations?: IIPCodeCitation[];
140
copilotReferences?: ICopilotReference[];
141
copilotErrors?: ICopilotError[];
142
copilotToolCalls?: ICopilotToolCall[];
143
copilotToolCallStreamUpdates?: ICopilotToolCallStreamUpdate[];
144
beginToolCalls?: ICopilotBeginToolCall[];
145
_deprecatedCopilotFunctionCalls?: ICopilotFunctionCall[];
146
copilotConfirmation?: ICopilotConfirmation;
147
thinking?: ThinkingDelta | EncryptedThinkingDelta;
148
phase?: string;
149
retryReason?: FilterReason | 'network_error' | 'server_error';
150
/** Marker for the current response, which should be presented in `IMakeChatRequestOptions` on the next call */
151
statefulMarker?: string;
152
/** Context management information from Anthropic Messages API */
153
contextManagement?: ContextManagementResponse | OpenAIContextManagementResponse;
154
}
155
156
export function isOpenAIContextManagementResponse(value: ContextManagementResponse | OpenAIContextManagementResponse): value is OpenAIContextManagementResponse {
157
return 'type' in value && value.type === openAIContextManagementCompactionType;
158
}
159
160
export function isAnthropicContextManagementResponse(value: ContextManagementResponse | OpenAIContextManagementResponse): value is ContextManagementResponse {
161
return 'applied_edits' in value;
162
}
163
164
export const enum ResponsePartKind {
165
ContentDelta,
166
Content,
167
ToolCallDelta,
168
ToolCall,
169
Annotation,
170
Confirmation,
171
Error,
172
Thinking,
173
ThinkingDelta,
174
}
175
176
/** Part that contains incremental data added to the output */
177
export interface IContentDeltaResponsePart {
178
kind: ResponsePartKind.ContentDelta;
179
/** Part ID corresponds to the later IContentResponsePart */
180
partId: string;
181
/** Incremental content chunk */
182
delta: string;
183
}
184
185
/** Part that is emitted once the content is finished */
186
export interface IContentResponsePart {
187
kind: ResponsePartKind.Content;
188
/** Part ID of the IContentDeltaResponsePart */
189
partId: string;
190
/** Finalized content */
191
content: string;
192
/** Log probabilities, if requested */
193
logProbs?: ChoiceLogProbs;
194
}
195
196
/** Part that contains incremental data for a tool call that's being generated */
197
export interface IToolCallDeltaResponsePart {
198
kind: ResponsePartKind.ToolCallDelta;
199
/** Part ID corresponds to the later IToolCallResponsePart */
200
partId: string;
201
/** Name of the function being called */
202
name: string;
203
/** Arguments delta */
204
delta: string;
205
}
206
207
/** Part that is emitted once a tool call is ready. */
208
export interface IToolCallResponsePart extends ICopilotToolCall {
209
kind: ResponsePartKind.ToolCall;
210
/** Part ID of the IToolCallDeltaResponsePart */
211
partId: string;
212
}
213
214
/** Part that is emitted when the model wants to ask the user for confirmation. */
215
export interface IConfirmationResponsePart extends ICopilotConfirmation {
216
kind: ResponsePartKind.Confirmation;
217
}
218
219
/** Part that is emitted when the model want to add annotations to a response. */
220
export interface IAnnotationResponsePart {
221
kind: ResponsePartKind.Annotation;
222
codeVulnAnnotations?: ICodeVulnerabilityAnnotation[];
223
ipCitations?: IIPCodeCitation[];
224
copilotReferences?: ICopilotReference[];
225
}
226
227
/** Part that is emitted when the model begins thinking. */
228
export interface IThinkingResponseDeltaPart {
229
kind: ResponsePartKind.ThinkingDelta;
230
/** Part ID of the IThinkingResponsePart */
231
partId: string;
232
/** Delta of the thinking process */
233
delta: ThinkingDelta;
234
}
235
236
/**
237
* Part that is emitted when the model finishes thinking.
238
* WARN: currently CAPI never signals the end of thinking.
239
*/
240
export interface IThinkingResponsePart {
241
kind: ResponsePartKind.Thinking;
242
/** Part ID of IThinkingResponseDeltaPart */
243
partId: string;
244
/** Summary text shown to the user. */
245
data: ThinkingData;
246
}
247
248
/** Part that is emitted when the model encounters an error. */
249
export interface IErrorResponsePart {
250
kind: ResponsePartKind.Error;
251
error: ICopilotError;
252
}
253
254
export type ResponsePart =
255
| IContentDeltaResponsePart
256
| IContentResponsePart
257
| IToolCallDeltaResponsePart
258
| IToolCallResponsePart
259
| IAnnotationResponsePart
260
| IThinkingResponseDeltaPart
261
| IThinkingResponsePart
262
| IConfirmationResponsePart
263
| IErrorResponsePart;
264
265
266
export interface FinishedCallback {
267
/**
268
* @param text The full concatenated text of the response
269
* @param index The index of the choice to which the completion chunk belongs
270
* @param delta A delta for the latest chunk
271
* @returns A number to stop reading data from the server, `undefined` to continue
272
*/
273
(text: string, index: number, delta: IResponseDelta): Promise<number | undefined>;
274
}
275
276
export interface OpenAiFunctionDef {
277
name: string;
278
description: string;
279
parameters?: object;
280
}
281
282
export interface OpenAiFunctionTool {
283
function: OpenAiFunctionDef;
284
type: 'function';
285
}
286
287
export interface OpenAiResponsesFunctionTool extends OpenAiFunctionDef {
288
type: 'function';
289
}
290
291
/** OpenAI Responses API client-executed tool_search tool declaration. See https://developers.openai.com/api/docs/guides/tools-tool-search */
292
export interface OpenAiToolSearchTool {
293
type: 'tool_search';
294
execution: 'client';
295
/** Description for client-executed tool search. */
296
description?: string;
297
/** Parameters schema for client-executed tool search. */
298
parameters?: Record<string, unknown>;
299
}
300
301
export function isOpenAiFunctionTool(tool: OpenAiResponsesFunctionTool | OpenAiFunctionTool | AnthropicMessagesTool | OpenAiToolSearchTool): tool is OpenAiFunctionTool {
302
return (tool as OpenAiFunctionTool).function !== undefined;
303
}
304
305
/**
306
* Options for streaming response. Only set this when you set stream: true.
307
*
308
* @remarks Proxy has `include_usage` hard-coded to true.
309
*/
310
export type StreamOptions = {
311
/**
312
* If set, an additional chunk will be streamed before the data: [DONE] message. The usage field on this chunk shows the token usage statistics for the entire request, and the choices field will always be an empty array.
313
*
314
* All other chunks will also include a usage field, but with a null value. NOTE: If the stream is interrupted, you may not receive the final usage chunk which contains the total token usage for the request.
315
*/
316
include_usage?: boolean;
317
};
318
319
export type Prediction = {
320
type: 'content';
321
content: string | { type: string; text: string }[];
322
};
323
324
/** based on https://platform.openai.com/docs/api-reference/chat/create
325
*
326
* 'stream' param is not respected because we don't yet support non-streamed responses
327
*/
328
export interface OptionalChatRequestParams {
329
330
/** Non-negative temperature sampling parameter (default 1). */
331
temperature?: number;
332
333
/** Non-negative temperature sampling parameter (default 1). */
334
top_p?: number;
335
336
/** How many parallel completions the model should generate (default 1). */
337
n?: number;
338
339
/** Whether to stream back a response in SSE format. */
340
stream?: boolean;
341
342
/** Options for streaming response. Only set this when you set stream: true. */
343
stream_options?: StreamOptions;
344
345
/** Strings that will cause the model to stop generating text. */
346
stop?: string[];
347
348
/** The maximum number of tokens to return for a completion request */
349
max_tokens?: number;
350
351
/** Likelihood of specified tokens appearing in the completion. */
352
logit_bias?: number;
353
354
// TODO@ulugbekna: not sure params below are supported by Copilot proxy
355
presence_penalty?: number;
356
frequency_penalty?: number;
357
358
secretKey?: string;
359
360
/** For github remote agents */
361
copilot_thread_id?: string;
362
copilot_skills?: string[];
363
364
functions?: OpenAiFunctionDef[];
365
function_call?: { name: string };
366
tools?: OpenAiFunctionTool[];
367
/**
368
* Note: 'required' is not supported
369
*/
370
tool_choice?: 'none' | 'auto' | { type: 'function'; function: { name: string } };
371
372
prediction?: Prediction;
373
logprobs?: boolean;
374
375
/** Responses API */
376
previous_response_id?: string;
377
}
378
379