Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/agents/node/test/openaiAdapter.spec.ts
13405 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 * as http from 'http';
7
import { describe, expect, it } from 'vitest';
8
import { OpenAIAdapterFactoryForSTests } from '../adapters/openaiAdapterForSTests';
9
import { Raw } from '@vscode/prompt-tsx';
10
11
describe('OpenAIAdapterFactory', () => {
12
it('should create an OpenAI adapter instance', () => {
13
const factory = new OpenAIAdapterFactoryForSTests();
14
const adapter = factory.createAdapter();
15
16
// Verify the adapter has the correct name
17
expect(adapter.name).toBe('openai');
18
});
19
20
it('should parse a basic OpenAI request', () => {
21
const factory = new OpenAIAdapterFactoryForSTests();
22
const adapter = factory.createAdapter();
23
24
const requestBody = {
25
model: 'gpt-4o',
26
messages: [
27
{ role: 'user', content: 'Hello' }
28
],
29
temperature: 0.7
30
};
31
32
const parsedRequest = adapter.parseRequest(JSON.stringify(requestBody));
33
34
expect(parsedRequest.model).toBe('gpt-4o');
35
expect(parsedRequest.messages).toHaveLength(1);
36
expect(parsedRequest.messages[0]).toEqual({ role: Raw.ChatRole.User, content: [{ text: 'Hello', type: Raw.ChatCompletionContentPartKind.Text }] } satisfies Raw.UserChatMessage);
37
expect(parsedRequest.options?.temperature).toBe(0.7);
38
});
39
40
it('should parse an OpenAI request with tools', () => {
41
const factory = new OpenAIAdapterFactoryForSTests();
42
const adapter = factory.createAdapter();
43
44
const requestBody = {
45
model: 'gpt-4o',
46
messages: [
47
{ role: 'user', content: 'What is the weather?' }
48
],
49
tools: [
50
{
51
type: 'function',
52
function: {
53
name: 'get_weather',
54
description: 'Get the current weather',
55
parameters: {
56
type: 'object',
57
properties: {
58
location: { type: 'string' }
59
}
60
}
61
}
62
}
63
]
64
};
65
66
const parsedRequest = adapter.parseRequest(JSON.stringify(requestBody));
67
68
expect(parsedRequest.model).toBe('gpt-4o');
69
expect(parsedRequest.messages).toHaveLength(1);
70
expect(parsedRequest.options?.tools).toBeDefined();
71
expect(parsedRequest.options?.tools).toHaveLength(1);
72
});
73
74
it('should extract auth key from headers', () => {
75
const factory = new OpenAIAdapterFactoryForSTests();
76
const adapter = factory.createAdapter();
77
78
const headers: http.IncomingHttpHeaders = {
79
'authorization': 'Bearer test-key-123'
80
};
81
82
const authKey = adapter.extractAuthKey(headers);
83
84
expect(authKey).toBe('test-key-123');
85
});
86
87
it('should format text stream response', () => {
88
const factory = new OpenAIAdapterFactoryForSTests();
89
const adapter = factory.createAdapter();
90
91
const context = {
92
requestId: 'test-request-id',
93
endpoint: {
94
modelId: 'gpt-4o',
95
modelMaxPromptTokens: 128000
96
}
97
};
98
99
const streamData = {
100
type: 'text' as const,
101
content: 'Hello, world!'
102
};
103
104
let events = adapter.formatStreamResponse(streamData, context);
105
106
expect(events).toHaveLength(0);
107
108
events = adapter.generateFinalEvents(context);
109
expect(events).toHaveLength(2);
110
expect(events[0].event).toBe('message');
111
expect(events[0].data).toContain('Hello, world!');
112
113
expect(events[1].event).toBe('message');
114
expect(JSON.parse(events[1].data).choices).toEqual([{ 'index': 0, 'delta': { 'content': null }, 'finish_reason': 'stop' }]);
115
});
116
117
it('should format tool call stream response', () => {
118
const factory = new OpenAIAdapterFactoryForSTests();
119
const adapter = factory.createAdapter();
120
121
const context = {
122
requestId: 'test-request-id',
123
endpoint: {
124
modelId: 'gpt-4o',
125
modelMaxPromptTokens: 128000
126
}
127
};
128
129
const streamData = {
130
type: 'tool_call' as const,
131
callId: 'call_123',
132
name: 'get_weather',
133
input: { location: 'Boston' }
134
};
135
136
const events = adapter.formatStreamResponse(streamData, context);
137
138
expect(events).toHaveLength(1);
139
expect(events[0].event).toBe('message');
140
expect(events[0].data).toContain('get_weather');
141
expect(events[0].data).toContain('Boston');
142
});
143
144
it('should generate final events with usage', () => {
145
const factory = new OpenAIAdapterFactoryForSTests();
146
const adapter = factory.createAdapter();
147
148
const context = {
149
requestId: 'test-request-id',
150
endpoint: {
151
modelId: 'gpt-4o',
152
modelMaxPromptTokens: 128000
153
}
154
};
155
156
const usage = {
157
prompt_tokens: 10,
158
completion_tokens: 20,
159
total_tokens: 30
160
};
161
162
const events = adapter.generateFinalEvents(context, usage);
163
164
expect(events).toHaveLength(1);
165
expect(events[0].event).toBe('message');
166
expect(events[0].data).toContain('"prompt_tokens":10');
167
expect(events[0].data).toContain('"completion_tokens":20');
168
});
169
});
170