@ank1015/providers 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +93 -383
- package/dist/agent/conversation.d.ts +97 -0
- package/dist/agent/conversation.d.ts.map +1 -0
- package/dist/agent/conversation.js +328 -0
- package/dist/agent/conversation.js.map +1 -0
- package/dist/agent/runner.d.ts +37 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +169 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/tools/calculate.d.ts +15 -0
- package/dist/agent/tools/calculate.d.ts.map +1 -0
- package/dist/agent/tools/calculate.js +23 -0
- package/dist/agent/tools/calculate.js.map +1 -0
- package/dist/agent/tools/get-current-time.d.ts +15 -0
- package/dist/agent/tools/get-current-time.d.ts.map +1 -0
- package/dist/agent/tools/get-current-time.js +38 -0
- package/dist/agent/tools/get-current-time.js.map +1 -0
- package/dist/agent/tools/index.d.ts +3 -0
- package/dist/agent/tools/index.d.ts.map +1 -0
- package/dist/agent/tools/index.js +3 -0
- package/dist/agent/tools/index.js.map +1 -0
- package/dist/agent/types.d.ts +53 -31
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +1 -2
- package/dist/agent/utils.d.ts +14 -0
- package/dist/agent/utils.d.ts.map +1 -0
- package/dist/agent/utils.js +59 -0
- package/dist/agent/utils.js.map +1 -0
- package/dist/index.d.ts +16 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -28
- package/dist/index.js.map +1 -1
- package/dist/llm.d.ts +15 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +92 -0
- package/dist/llm.js.map +1 -0
- package/dist/models.d.ts +8 -1
- package/dist/models.d.ts.map +1 -1
- package/dist/models.generated.d.ts +25 -112
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +72 -227
- package/dist/models.generated.js.map +1 -1
- package/dist/models.js +30 -32
- package/dist/models.js.map +1 -1
- package/dist/providers/google/complete.d.ts +3 -0
- package/dist/providers/google/complete.d.ts.map +1 -0
- package/dist/providers/google/complete.js +53 -0
- package/dist/providers/google/complete.js.map +1 -0
- package/dist/providers/google/index.d.ts +6 -0
- package/dist/providers/google/index.d.ts.map +1 -0
- package/dist/providers/google/index.js +6 -0
- package/dist/providers/google/index.js.map +1 -0
- package/dist/providers/google/stream.d.ts +3 -0
- package/dist/providers/google/stream.d.ts.map +1 -0
- package/dist/providers/{google.js → google/stream.js} +67 -231
- package/dist/providers/google/stream.js.map +1 -0
- package/dist/providers/google/types.d.ts +8 -0
- package/dist/providers/google/types.d.ts.map +1 -0
- package/dist/providers/google/types.js +2 -0
- package/dist/providers/google/types.js.map +1 -0
- package/dist/providers/google/utils.d.ts +30 -0
- package/dist/providers/google/utils.d.ts.map +1 -0
- package/dist/providers/google/utils.js +354 -0
- package/dist/providers/google/utils.js.map +1 -0
- package/dist/providers/openai/complete.d.ts +3 -0
- package/dist/providers/openai/complete.d.ts.map +1 -0
- package/dist/providers/openai/complete.js +57 -0
- package/dist/providers/openai/complete.js.map +1 -0
- package/dist/providers/openai/index.d.ts +4 -0
- package/dist/providers/openai/index.d.ts.map +1 -0
- package/dist/providers/openai/index.js +4 -0
- package/dist/providers/openai/index.js.map +1 -0
- package/dist/providers/openai/stream.d.ts +3 -0
- package/dist/providers/openai/stream.d.ts.map +1 -0
- package/dist/providers/{openai.js → openai/stream.js} +74 -152
- package/dist/providers/openai/stream.js.map +1 -0
- package/dist/providers/openai/types.d.ts +8 -0
- package/dist/providers/openai/types.d.ts.map +1 -0
- package/dist/providers/openai/types.js +2 -0
- package/dist/providers/openai/types.js.map +1 -0
- package/dist/providers/openai/utils.d.ts +13 -0
- package/dist/providers/openai/utils.d.ts.map +1 -0
- package/dist/providers/openai/utils.js +285 -0
- package/dist/providers/openai/utils.js.map +1 -0
- package/dist/types.d.ts +95 -87
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -9
- package/dist/types.js.map +1 -1
- package/dist/utils/event-stream.d.ts +2 -2
- package/dist/utils/event-stream.d.ts.map +1 -1
- package/dist/utils/event-stream.js +2 -7
- package/dist/utils/event-stream.js.map +1 -1
- package/dist/utils/json-parse.js +3 -6
- package/dist/utils/json-parse.js.map +1 -1
- package/dist/utils/overflow.d.ts +51 -0
- package/dist/utils/overflow.d.ts.map +1 -0
- package/dist/utils/overflow.js +106 -0
- package/dist/utils/overflow.js.map +1 -0
- package/dist/utils/sanitize-unicode.js +1 -4
- package/dist/utils/sanitize-unicode.js.map +1 -1
- package/dist/utils/uuid.d.ts +6 -0
- package/dist/utils/uuid.d.ts.map +1 -0
- package/dist/utils/uuid.js +9 -0
- package/dist/utils/uuid.js.map +1 -0
- package/dist/utils/validation.d.ts +10 -3
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +20 -12
- package/dist/utils/validation.js.map +1 -1
- package/package.json +45 -8
- package/biome.json +0 -43
- package/dist/agent/agent-loop.d.ts +0 -5
- package/dist/agent/agent-loop.d.ts.map +0 -1
- package/dist/agent/agent-loop.js +0 -219
- package/dist/agent/agent-loop.js.map +0 -1
- package/dist/providers/convert.d.ts +0 -6
- package/dist/providers/convert.d.ts.map +0 -1
- package/dist/providers/convert.js +0 -207
- package/dist/providers/convert.js.map +0 -1
- package/dist/providers/google.d.ts +0 -26
- package/dist/providers/google.d.ts.map +0 -1
- package/dist/providers/google.js.map +0 -1
- package/dist/providers/openai.d.ts +0 -17
- package/dist/providers/openai.d.ts.map +0 -1
- package/dist/providers/openai.js.map +0 -1
- package/dist/stream.d.ts +0 -4
- package/dist/stream.d.ts.map +0 -1
- package/dist/stream.js +0 -40
- package/dist/stream.js.map +0 -1
- package/dist/test-google-agent-loop.d.ts +0 -2
- package/dist/test-google-agent-loop.d.ts.map +0 -1
- package/dist/test-google-agent-loop.js +0 -186
- package/dist/test-google-agent-loop.js.map +0 -1
- package/dist/test-google.d.ts +0 -2
- package/dist/test-google.d.ts.map +0 -1
- package/dist/test-google.js +0 -41
- package/dist/test-google.js.map +0 -1
- package/src/agent/agent-loop.ts +0 -275
- package/src/agent/types.ts +0 -80
- package/src/index.ts +0 -72
- package/src/models.generated.ts +0 -314
- package/src/models.ts +0 -45
- package/src/providers/convert.ts +0 -222
- package/src/providers/google.ts +0 -496
- package/src/providers/openai.ts +0 -437
- package/src/stream.ts +0 -60
- package/src/types.ts +0 -198
- package/src/utils/event-stream.ts +0 -60
- package/src/utils/json-parse.ts +0 -28
- package/src/utils/sanitize-unicode.ts +0 -25
- package/src/utils/validation.ts +0 -69
- package/test/core/agent-loop.test.ts +0 -958
- package/test/core/stream.test.ts +0 -409
- package/test/data/red-circle.png +0 -0
- package/test/data/superintelligentwill.pdf +0 -0
- package/test/edge-cases/general.test.ts +0 -565
- package/test/integration/e2e.test.ts +0 -530
- package/test/models/cost.test.ts +0 -499
- package/test/models/registry.test.ts +0 -298
- package/test/providers/convert.test.ts +0 -846
- package/test/providers/google-schema.test.ts +0 -666
- package/test/providers/google-stream.test.ts +0 -369
- package/test/providers/openai-stream.test.ts +0 -251
- package/test/utils/event-stream.test.ts +0 -289
- package/test/utils/json-parse.test.ts +0 -344
- package/test/utils/sanitize-unicode.test.ts +0 -329
- package/test/utils/validation.test.ts +0 -614
- package/tsconfig.json +0 -21
- package/vitest.config.ts +0 -9
package/test/core/stream.test.ts
DELETED
|
@@ -1,409 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { stream } from '../../src/stream';
|
|
3
|
-
import { Model, Context } from '../../src/types';
|
|
4
|
-
import * as openaiProvider from '../../src/providers/openai';
|
|
5
|
-
import * as googleProvider from '../../src/providers/google';
|
|
6
|
-
import { ThinkingLevel } from '@google/genai';
|
|
7
|
-
|
|
8
|
-
// Mock the provider modules
|
|
9
|
-
vi.mock('../src/providers/openai');
|
|
10
|
-
vi.mock('../src/providers/google');
|
|
11
|
-
|
|
12
|
-
const mockOpenAIModel: Model<'openai'> = {
|
|
13
|
-
id: 'test-openai',
|
|
14
|
-
name: 'Test OpenAI',
|
|
15
|
-
api: 'openai',
|
|
16
|
-
baseUrl: 'https://api.openai.com',
|
|
17
|
-
reasoning: false,
|
|
18
|
-
input: ['text'],
|
|
19
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
20
|
-
contextWindow: 128000,
|
|
21
|
-
maxTokens: 4096,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const mockGoogleModel: Model<'google'> = {
|
|
25
|
-
id: 'test-google',
|
|
26
|
-
name: 'Test Google',
|
|
27
|
-
api: 'google',
|
|
28
|
-
baseUrl: 'https://generativelanguage.googleapis.com',
|
|
29
|
-
reasoning: false,
|
|
30
|
-
input: ['text'],
|
|
31
|
-
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
32
|
-
contextWindow: 128000,
|
|
33
|
-
maxTokens: 8192,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
describe('stream', () => {
|
|
37
|
-
let originalEnv: NodeJS.ProcessEnv;
|
|
38
|
-
|
|
39
|
-
beforeEach(() => {
|
|
40
|
-
// Save original env
|
|
41
|
-
originalEnv = { ...process.env };
|
|
42
|
-
// Clear mocks
|
|
43
|
-
vi.clearAllMocks();
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
afterEach(() => {
|
|
47
|
-
// Restore original env
|
|
48
|
-
process.env = originalEnv;
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe('Provider routing', () => {
|
|
52
|
-
it('should route to OpenAI provider for openai api', () => {
|
|
53
|
-
process.env.OPENAI_API_KEY = 'test-key';
|
|
54
|
-
|
|
55
|
-
const context: Context = {
|
|
56
|
-
messages: [],
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const mockStream = {} as any;
|
|
60
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
61
|
-
|
|
62
|
-
const result = stream(mockOpenAIModel, context);
|
|
63
|
-
|
|
64
|
-
expect(openaiProvider.streamOpenAI).toHaveBeenCalledWith(
|
|
65
|
-
mockOpenAIModel,
|
|
66
|
-
context,
|
|
67
|
-
expect.objectContaining({ apiKey: 'test-key' })
|
|
68
|
-
);
|
|
69
|
-
expect(result).toBe(mockStream);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should route to Google provider for google api', () => {
|
|
73
|
-
process.env.GEMINI_API_KEY = 'test-gemini-key';
|
|
74
|
-
|
|
75
|
-
const context: Context = {
|
|
76
|
-
messages: [],
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const mockStream = {} as any;
|
|
80
|
-
vi.spyOn(googleProvider, 'streamGoogle').mockReturnValue(mockStream);
|
|
81
|
-
|
|
82
|
-
const result = stream(mockGoogleModel, context);
|
|
83
|
-
|
|
84
|
-
expect(googleProvider.streamGoogle).toHaveBeenCalledWith(
|
|
85
|
-
mockGoogleModel,
|
|
86
|
-
context,
|
|
87
|
-
expect.objectContaining({ apiKey: 'test-gemini-key' })
|
|
88
|
-
);
|
|
89
|
-
expect(result).toBe(mockStream);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
describe('API key handling', () => {
|
|
94
|
-
it('should use API key from OPENAI_API_KEY environment variable', () => {
|
|
95
|
-
process.env.OPENAI_API_KEY = 'env-openai-key';
|
|
96
|
-
|
|
97
|
-
const context: Context = { messages: [] };
|
|
98
|
-
const mockStream = {} as any;
|
|
99
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
100
|
-
|
|
101
|
-
stream(mockOpenAIModel, context);
|
|
102
|
-
|
|
103
|
-
expect(openaiProvider.streamOpenAI).toHaveBeenCalledWith(
|
|
104
|
-
expect.anything(),
|
|
105
|
-
expect.anything(),
|
|
106
|
-
expect.objectContaining({ apiKey: 'env-openai-key' })
|
|
107
|
-
);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should use API key from GEMINI_API_KEY environment variable', () => {
|
|
111
|
-
process.env.GEMINI_API_KEY = 'env-gemini-key';
|
|
112
|
-
|
|
113
|
-
const context: Context = { messages: [] };
|
|
114
|
-
const mockStream = {} as any;
|
|
115
|
-
vi.spyOn(googleProvider, 'streamGoogle').mockReturnValue(mockStream);
|
|
116
|
-
|
|
117
|
-
stream(mockGoogleModel, context);
|
|
118
|
-
|
|
119
|
-
expect(googleProvider.streamGoogle).toHaveBeenCalledWith(
|
|
120
|
-
expect.anything(),
|
|
121
|
-
expect.anything(),
|
|
122
|
-
expect.objectContaining({ apiKey: 'env-gemini-key' })
|
|
123
|
-
);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('should use API key from options (overrides env)', () => {
|
|
127
|
-
process.env.OPENAI_API_KEY = 'env-key';
|
|
128
|
-
|
|
129
|
-
const context: Context = { messages: [] };
|
|
130
|
-
const mockStream = {} as any;
|
|
131
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
132
|
-
|
|
133
|
-
stream(mockOpenAIModel, context, { apiKey: 'options-key' });
|
|
134
|
-
|
|
135
|
-
expect(openaiProvider.streamOpenAI).toHaveBeenCalledWith(
|
|
136
|
-
expect.anything(),
|
|
137
|
-
expect.anything(),
|
|
138
|
-
expect.objectContaining({ apiKey: 'options-key' })
|
|
139
|
-
);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('should throw error when API key is missing for OpenAI', () => {
|
|
143
|
-
delete process.env.OPENAI_API_KEY;
|
|
144
|
-
|
|
145
|
-
const context: Context = { messages: [] };
|
|
146
|
-
|
|
147
|
-
expect(() => stream(mockOpenAIModel, context)).toThrow(
|
|
148
|
-
/No API key for provider: openai/
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it('should throw error when API key is missing for Google', () => {
|
|
153
|
-
delete process.env.GEMINI_API_KEY;
|
|
154
|
-
|
|
155
|
-
const context: Context = { messages: [] };
|
|
156
|
-
|
|
157
|
-
expect(() => stream(mockGoogleModel, context)).toThrow(
|
|
158
|
-
/No API key for provider: google/
|
|
159
|
-
);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe('Options pass-through', () => {
|
|
164
|
-
it('should pass OpenAI options to provider', () => {
|
|
165
|
-
process.env.OPENAI_API_KEY = 'test-key';
|
|
166
|
-
|
|
167
|
-
const context: Context = { messages: [] };
|
|
168
|
-
const mockStream = {} as any;
|
|
169
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
170
|
-
|
|
171
|
-
const options = {
|
|
172
|
-
apiKey: 'custom-key',
|
|
173
|
-
temperature: 0.7,
|
|
174
|
-
maxOutputTokens: 2000,
|
|
175
|
-
reasoning: {
|
|
176
|
-
effort: 'medium' as const,
|
|
177
|
-
summaryStyle: 'concise' as const,
|
|
178
|
-
},
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
stream(mockOpenAIModel, context, options);
|
|
182
|
-
|
|
183
|
-
expect(openaiProvider.streamOpenAI).toHaveBeenCalledWith(
|
|
184
|
-
mockOpenAIModel,
|
|
185
|
-
context,
|
|
186
|
-
expect.objectContaining({
|
|
187
|
-
apiKey: 'custom-key',
|
|
188
|
-
temperature: 0.7,
|
|
189
|
-
maxOutputTokens: 2000,
|
|
190
|
-
reasoning: {
|
|
191
|
-
effort: 'medium',
|
|
192
|
-
summaryStyle: 'concise',
|
|
193
|
-
},
|
|
194
|
-
})
|
|
195
|
-
);
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
it('should pass Google options to provider', () => {
|
|
199
|
-
process.env.GEMINI_API_KEY = 'test-key';
|
|
200
|
-
|
|
201
|
-
const context: Context = { messages: [] };
|
|
202
|
-
const mockStream = {} as any;
|
|
203
|
-
vi.spyOn(googleProvider, 'streamGoogle').mockReturnValue(mockStream);
|
|
204
|
-
|
|
205
|
-
const options = {
|
|
206
|
-
apiKey: 'custom-key',
|
|
207
|
-
temperature: 0.8,
|
|
208
|
-
maxOutputTokens: 4000,
|
|
209
|
-
thinkingConfig: {
|
|
210
|
-
thinkingLevel: ThinkingLevel.HIGH,
|
|
211
|
-
},
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
stream(mockGoogleModel, context, options);
|
|
215
|
-
|
|
216
|
-
expect(googleProvider.streamGoogle).toHaveBeenCalledWith(
|
|
217
|
-
mockGoogleModel,
|
|
218
|
-
context,
|
|
219
|
-
expect.objectContaining({
|
|
220
|
-
apiKey: 'custom-key',
|
|
221
|
-
temperature: 0.8,
|
|
222
|
-
maxOutputTokens: 4000,
|
|
223
|
-
thinkingConfig: {
|
|
224
|
-
thinkingLevel: "HIGH"
|
|
225
|
-
},
|
|
226
|
-
})
|
|
227
|
-
);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it('should pass undefined options when none provided', () => {
|
|
231
|
-
process.env.OPENAI_API_KEY = 'test-key';
|
|
232
|
-
|
|
233
|
-
const context: Context = { messages: [] };
|
|
234
|
-
const mockStream = {} as any;
|
|
235
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
236
|
-
|
|
237
|
-
stream(mockOpenAIModel, context);
|
|
238
|
-
|
|
239
|
-
expect(openaiProvider.streamOpenAI).toHaveBeenCalledWith(
|
|
240
|
-
mockOpenAIModel,
|
|
241
|
-
context,
|
|
242
|
-
expect.objectContaining({ apiKey: 'test-key' })
|
|
243
|
-
);
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
describe('Context pass-through', () => {
|
|
248
|
-
it('should pass context with messages to provider', () => {
|
|
249
|
-
process.env.OPENAI_API_KEY = 'test-key';
|
|
250
|
-
|
|
251
|
-
const context: Context = {
|
|
252
|
-
systemPrompt: 'You are helpful',
|
|
253
|
-
messages: [
|
|
254
|
-
{
|
|
255
|
-
role: 'user',
|
|
256
|
-
content: [{ type: 'text', content: 'Hello' }],
|
|
257
|
-
timestamp: Date.now(),
|
|
258
|
-
},
|
|
259
|
-
],
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
const mockStream = {} as any;
|
|
263
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
264
|
-
|
|
265
|
-
stream(mockOpenAIModel, context);
|
|
266
|
-
|
|
267
|
-
expect(openaiProvider.streamOpenAI).toHaveBeenCalledWith(
|
|
268
|
-
expect.anything(),
|
|
269
|
-
context,
|
|
270
|
-
expect.anything()
|
|
271
|
-
);
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
it('should pass context with tools to provider', () => {
|
|
275
|
-
process.env.OPENAI_API_KEY = 'test-key';
|
|
276
|
-
|
|
277
|
-
const context: Context = {
|
|
278
|
-
messages: [],
|
|
279
|
-
tools: [
|
|
280
|
-
{
|
|
281
|
-
name: 'test_tool',
|
|
282
|
-
description: 'A test tool',
|
|
283
|
-
parameters: {} as any,
|
|
284
|
-
},
|
|
285
|
-
],
|
|
286
|
-
};
|
|
287
|
-
|
|
288
|
-
const mockStream = {} as any;
|
|
289
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
290
|
-
|
|
291
|
-
stream(mockOpenAIModel, context);
|
|
292
|
-
|
|
293
|
-
expect(openaiProvider.streamOpenAI).toHaveBeenCalledWith(
|
|
294
|
-
expect.anything(),
|
|
295
|
-
expect.objectContaining({
|
|
296
|
-
tools: expect.arrayContaining([
|
|
297
|
-
expect.objectContaining({ name: 'test_tool' }),
|
|
298
|
-
]),
|
|
299
|
-
}),
|
|
300
|
-
expect.anything()
|
|
301
|
-
);
|
|
302
|
-
});
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
describe('Model pass-through', () => {
|
|
306
|
-
it('should pass model to OpenAI provider', () => {
|
|
307
|
-
process.env.OPENAI_API_KEY = 'test-key';
|
|
308
|
-
|
|
309
|
-
const context: Context = { messages: [] };
|
|
310
|
-
const mockStream = {} as any;
|
|
311
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
312
|
-
|
|
313
|
-
stream(mockOpenAIModel, context);
|
|
314
|
-
|
|
315
|
-
expect(openaiProvider.streamOpenAI).toHaveBeenCalledWith(
|
|
316
|
-
mockOpenAIModel,
|
|
317
|
-
expect.anything(),
|
|
318
|
-
expect.anything()
|
|
319
|
-
);
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
it('should pass model to Google provider', () => {
|
|
323
|
-
process.env.GEMINI_API_KEY = 'test-key';
|
|
324
|
-
|
|
325
|
-
const context: Context = { messages: [] };
|
|
326
|
-
const mockStream = {} as any;
|
|
327
|
-
vi.spyOn(googleProvider, 'streamGoogle').mockReturnValue(mockStream);
|
|
328
|
-
|
|
329
|
-
stream(mockGoogleModel, context);
|
|
330
|
-
|
|
331
|
-
expect(googleProvider.streamGoogle).toHaveBeenCalledWith(
|
|
332
|
-
mockGoogleModel,
|
|
333
|
-
expect.anything(),
|
|
334
|
-
expect.anything()
|
|
335
|
-
);
|
|
336
|
-
});
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
describe('Return value', () => {
|
|
340
|
-
it('should return AssistantMessageEventStream from OpenAI provider', () => {
|
|
341
|
-
process.env.OPENAI_API_KEY = 'test-key';
|
|
342
|
-
|
|
343
|
-
const context: Context = { messages: [] };
|
|
344
|
-
const mockStream = { [Symbol.asyncIterator]: () => ({}) } as any;
|
|
345
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
346
|
-
|
|
347
|
-
const result = stream(mockOpenAIModel, context);
|
|
348
|
-
|
|
349
|
-
expect(result).toBe(mockStream);
|
|
350
|
-
expect(result[Symbol.asyncIterator]).toBeDefined();
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it('should return AssistantMessageEventStream from Google provider', () => {
|
|
354
|
-
process.env.GEMINI_API_KEY = 'test-key';
|
|
355
|
-
|
|
356
|
-
const context: Context = { messages: [] };
|
|
357
|
-
const mockStream = { [Symbol.asyncIterator]: () => ({}) } as any;
|
|
358
|
-
vi.spyOn(googleProvider, 'streamGoogle').mockReturnValue(mockStream);
|
|
359
|
-
|
|
360
|
-
const result = stream(mockGoogleModel, context);
|
|
361
|
-
|
|
362
|
-
expect(result).toBe(mockStream);
|
|
363
|
-
expect(result[Symbol.asyncIterator]).toBeDefined();
|
|
364
|
-
});
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
describe('Edge cases', () => {
|
|
368
|
-
it('should handle empty context', () => {
|
|
369
|
-
process.env.OPENAI_API_KEY = 'test-key';
|
|
370
|
-
|
|
371
|
-
const context: Context = { messages: [] };
|
|
372
|
-
const mockStream = {} as any;
|
|
373
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
374
|
-
|
|
375
|
-
expect(() => stream(mockOpenAIModel, context)).not.toThrow();
|
|
376
|
-
});
|
|
377
|
-
|
|
378
|
-
it('should handle context with only system prompt', () => {
|
|
379
|
-
process.env.OPENAI_API_KEY = 'test-key';
|
|
380
|
-
|
|
381
|
-
const context: Context = {
|
|
382
|
-
systemPrompt: 'System instructions',
|
|
383
|
-
messages: [],
|
|
384
|
-
};
|
|
385
|
-
const mockStream = {} as any;
|
|
386
|
-
vi.spyOn(openaiProvider, 'streamOpenAI').mockReturnValue(mockStream);
|
|
387
|
-
|
|
388
|
-
expect(() => stream(mockOpenAIModel, context)).not.toThrow();
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
it('should handle empty string API key from environment', () => {
|
|
392
|
-
process.env.OPENAI_API_KEY = '';
|
|
393
|
-
|
|
394
|
-
const context: Context = { messages: [] };
|
|
395
|
-
|
|
396
|
-
expect(() => stream(mockOpenAIModel, context)).toThrow(
|
|
397
|
-
/No API key for provider/
|
|
398
|
-
);
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
it('should handle empty string API key from options', () => {
|
|
402
|
-
const context: Context = { messages: [] };
|
|
403
|
-
|
|
404
|
-
expect(() => stream(mockOpenAIModel, context, { apiKey: '' })).toThrow(
|
|
405
|
-
/No API key for provider/
|
|
406
|
-
);
|
|
407
|
-
});
|
|
408
|
-
});
|
|
409
|
-
});
|
package/test/data/red-circle.png
DELETED
|
Binary file
|
|
Binary file
|