@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.
Files changed (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -383
  3. package/dist/agent/conversation.d.ts +97 -0
  4. package/dist/agent/conversation.d.ts.map +1 -0
  5. package/dist/agent/conversation.js +328 -0
  6. package/dist/agent/conversation.js.map +1 -0
  7. package/dist/agent/runner.d.ts +37 -0
  8. package/dist/agent/runner.d.ts.map +1 -0
  9. package/dist/agent/runner.js +169 -0
  10. package/dist/agent/runner.js.map +1 -0
  11. package/dist/agent/tools/calculate.d.ts +15 -0
  12. package/dist/agent/tools/calculate.d.ts.map +1 -0
  13. package/dist/agent/tools/calculate.js +23 -0
  14. package/dist/agent/tools/calculate.js.map +1 -0
  15. package/dist/agent/tools/get-current-time.d.ts +15 -0
  16. package/dist/agent/tools/get-current-time.d.ts.map +1 -0
  17. package/dist/agent/tools/get-current-time.js +38 -0
  18. package/dist/agent/tools/get-current-time.js.map +1 -0
  19. package/dist/agent/tools/index.d.ts +3 -0
  20. package/dist/agent/tools/index.d.ts.map +1 -0
  21. package/dist/agent/tools/index.js +3 -0
  22. package/dist/agent/tools/index.js.map +1 -0
  23. package/dist/agent/types.d.ts +53 -31
  24. package/dist/agent/types.d.ts.map +1 -1
  25. package/dist/agent/types.js +1 -2
  26. package/dist/agent/utils.d.ts +14 -0
  27. package/dist/agent/utils.d.ts.map +1 -0
  28. package/dist/agent/utils.js +59 -0
  29. package/dist/agent/utils.js.map +1 -0
  30. package/dist/index.d.ts +16 -9
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +16 -28
  33. package/dist/index.js.map +1 -1
  34. package/dist/llm.d.ts +15 -0
  35. package/dist/llm.d.ts.map +1 -0
  36. package/dist/llm.js +92 -0
  37. package/dist/llm.js.map +1 -0
  38. package/dist/models.d.ts +8 -1
  39. package/dist/models.d.ts.map +1 -1
  40. package/dist/models.generated.d.ts +25 -112
  41. package/dist/models.generated.d.ts.map +1 -1
  42. package/dist/models.generated.js +72 -227
  43. package/dist/models.generated.js.map +1 -1
  44. package/dist/models.js +30 -32
  45. package/dist/models.js.map +1 -1
  46. package/dist/providers/google/complete.d.ts +3 -0
  47. package/dist/providers/google/complete.d.ts.map +1 -0
  48. package/dist/providers/google/complete.js +53 -0
  49. package/dist/providers/google/complete.js.map +1 -0
  50. package/dist/providers/google/index.d.ts +6 -0
  51. package/dist/providers/google/index.d.ts.map +1 -0
  52. package/dist/providers/google/index.js +6 -0
  53. package/dist/providers/google/index.js.map +1 -0
  54. package/dist/providers/google/stream.d.ts +3 -0
  55. package/dist/providers/google/stream.d.ts.map +1 -0
  56. package/dist/providers/{google.js → google/stream.js} +67 -231
  57. package/dist/providers/google/stream.js.map +1 -0
  58. package/dist/providers/google/types.d.ts +8 -0
  59. package/dist/providers/google/types.d.ts.map +1 -0
  60. package/dist/providers/google/types.js +2 -0
  61. package/dist/providers/google/types.js.map +1 -0
  62. package/dist/providers/google/utils.d.ts +30 -0
  63. package/dist/providers/google/utils.d.ts.map +1 -0
  64. package/dist/providers/google/utils.js +354 -0
  65. package/dist/providers/google/utils.js.map +1 -0
  66. package/dist/providers/openai/complete.d.ts +3 -0
  67. package/dist/providers/openai/complete.d.ts.map +1 -0
  68. package/dist/providers/openai/complete.js +57 -0
  69. package/dist/providers/openai/complete.js.map +1 -0
  70. package/dist/providers/openai/index.d.ts +4 -0
  71. package/dist/providers/openai/index.d.ts.map +1 -0
  72. package/dist/providers/openai/index.js +4 -0
  73. package/dist/providers/openai/index.js.map +1 -0
  74. package/dist/providers/openai/stream.d.ts +3 -0
  75. package/dist/providers/openai/stream.d.ts.map +1 -0
  76. package/dist/providers/{openai.js → openai/stream.js} +74 -152
  77. package/dist/providers/openai/stream.js.map +1 -0
  78. package/dist/providers/openai/types.d.ts +8 -0
  79. package/dist/providers/openai/types.d.ts.map +1 -0
  80. package/dist/providers/openai/types.js +2 -0
  81. package/dist/providers/openai/types.js.map +1 -0
  82. package/dist/providers/openai/utils.d.ts +13 -0
  83. package/dist/providers/openai/utils.d.ts.map +1 -0
  84. package/dist/providers/openai/utils.js +285 -0
  85. package/dist/providers/openai/utils.js.map +1 -0
  86. package/dist/types.d.ts +95 -87
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js +1 -9
  89. package/dist/types.js.map +1 -1
  90. package/dist/utils/event-stream.d.ts +2 -2
  91. package/dist/utils/event-stream.d.ts.map +1 -1
  92. package/dist/utils/event-stream.js +2 -7
  93. package/dist/utils/event-stream.js.map +1 -1
  94. package/dist/utils/json-parse.js +3 -6
  95. package/dist/utils/json-parse.js.map +1 -1
  96. package/dist/utils/overflow.d.ts +51 -0
  97. package/dist/utils/overflow.d.ts.map +1 -0
  98. package/dist/utils/overflow.js +106 -0
  99. package/dist/utils/overflow.js.map +1 -0
  100. package/dist/utils/sanitize-unicode.js +1 -4
  101. package/dist/utils/sanitize-unicode.js.map +1 -1
  102. package/dist/utils/uuid.d.ts +6 -0
  103. package/dist/utils/uuid.d.ts.map +1 -0
  104. package/dist/utils/uuid.js +9 -0
  105. package/dist/utils/uuid.js.map +1 -0
  106. package/dist/utils/validation.d.ts +10 -3
  107. package/dist/utils/validation.d.ts.map +1 -1
  108. package/dist/utils/validation.js +20 -12
  109. package/dist/utils/validation.js.map +1 -1
  110. package/package.json +45 -8
  111. package/biome.json +0 -43
  112. package/dist/agent/agent-loop.d.ts +0 -5
  113. package/dist/agent/agent-loop.d.ts.map +0 -1
  114. package/dist/agent/agent-loop.js +0 -219
  115. package/dist/agent/agent-loop.js.map +0 -1
  116. package/dist/providers/convert.d.ts +0 -6
  117. package/dist/providers/convert.d.ts.map +0 -1
  118. package/dist/providers/convert.js +0 -207
  119. package/dist/providers/convert.js.map +0 -1
  120. package/dist/providers/google.d.ts +0 -26
  121. package/dist/providers/google.d.ts.map +0 -1
  122. package/dist/providers/google.js.map +0 -1
  123. package/dist/providers/openai.d.ts +0 -17
  124. package/dist/providers/openai.d.ts.map +0 -1
  125. package/dist/providers/openai.js.map +0 -1
  126. package/dist/stream.d.ts +0 -4
  127. package/dist/stream.d.ts.map +0 -1
  128. package/dist/stream.js +0 -40
  129. package/dist/stream.js.map +0 -1
  130. package/dist/test-google-agent-loop.d.ts +0 -2
  131. package/dist/test-google-agent-loop.d.ts.map +0 -1
  132. package/dist/test-google-agent-loop.js +0 -186
  133. package/dist/test-google-agent-loop.js.map +0 -1
  134. package/dist/test-google.d.ts +0 -2
  135. package/dist/test-google.d.ts.map +0 -1
  136. package/dist/test-google.js +0 -41
  137. package/dist/test-google.js.map +0 -1
  138. package/src/agent/agent-loop.ts +0 -275
  139. package/src/agent/types.ts +0 -80
  140. package/src/index.ts +0 -72
  141. package/src/models.generated.ts +0 -314
  142. package/src/models.ts +0 -45
  143. package/src/providers/convert.ts +0 -222
  144. package/src/providers/google.ts +0 -496
  145. package/src/providers/openai.ts +0 -437
  146. package/src/stream.ts +0 -60
  147. package/src/types.ts +0 -198
  148. package/src/utils/event-stream.ts +0 -60
  149. package/src/utils/json-parse.ts +0 -28
  150. package/src/utils/sanitize-unicode.ts +0 -25
  151. package/src/utils/validation.ts +0 -69
  152. package/test/core/agent-loop.test.ts +0 -958
  153. package/test/core/stream.test.ts +0 -409
  154. package/test/data/red-circle.png +0 -0
  155. package/test/data/superintelligentwill.pdf +0 -0
  156. package/test/edge-cases/general.test.ts +0 -565
  157. package/test/integration/e2e.test.ts +0 -530
  158. package/test/models/cost.test.ts +0 -499
  159. package/test/models/registry.test.ts +0 -298
  160. package/test/providers/convert.test.ts +0 -846
  161. package/test/providers/google-schema.test.ts +0 -666
  162. package/test/providers/google-stream.test.ts +0 -369
  163. package/test/providers/openai-stream.test.ts +0 -251
  164. package/test/utils/event-stream.test.ts +0 -289
  165. package/test/utils/json-parse.test.ts +0 -344
  166. package/test/utils/sanitize-unicode.test.ts +0 -329
  167. package/test/utils/validation.test.ts +0 -614
  168. package/tsconfig.json +0 -21
  169. package/vitest.config.ts +0 -9
@@ -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
- });
Binary file
Binary file