@inferencesh/sdk 0.6.15 → 0.6.20

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 (86) hide show
  1. package/dist/agent/provider.d.ts +2 -1
  2. package/dist/api/apps.d.ts +4 -0
  3. package/dist/api/apps.js +6 -0
  4. package/dist/api/index.d.ts +3 -3
  5. package/dist/http/index.d.ts +3 -3
  6. package/dist/index.d.ts +9 -9
  7. package/dist/proxy/index.js +11 -3
  8. package/dist/types.d.ts +30 -4
  9. package/dist/types.js +4 -0
  10. package/package.json +8 -5
  11. package/dist/agent/actions.test.d.ts +0 -1
  12. package/dist/agent/actions.test.js +0 -820
  13. package/dist/agent/api.test.d.ts +0 -1
  14. package/dist/agent/api.test.js +0 -246
  15. package/dist/agent/reducer.test.d.ts +0 -1
  16. package/dist/agent/reducer.test.js +0 -131
  17. package/dist/agent/types.test.d.ts +0 -1
  18. package/dist/agent/types.test.js +0 -75
  19. package/dist/api/agents.test.d.ts +0 -1
  20. package/dist/api/agents.test.js +0 -1014
  21. package/dist/api/api-keys.test.d.ts +0 -1
  22. package/dist/api/api-keys.test.js +0 -44
  23. package/dist/api/apps.test.d.ts +0 -1
  24. package/dist/api/apps.test.js +0 -135
  25. package/dist/api/chats.test.d.ts +0 -1
  26. package/dist/api/chats.test.js +0 -85
  27. package/dist/api/engines.test.d.ts +0 -1
  28. package/dist/api/engines.test.js +0 -133
  29. package/dist/api/files.test.d.ts +0 -1
  30. package/dist/api/files.test.js +0 -256
  31. package/dist/api/flow-runs.test.d.ts +0 -1
  32. package/dist/api/flow-runs.test.js +0 -97
  33. package/dist/api/flows.test.d.ts +0 -1
  34. package/dist/api/flows.test.js +0 -118
  35. package/dist/api/integrations.test.d.ts +0 -1
  36. package/dist/api/integrations.test.js +0 -109
  37. package/dist/api/knowledge.test.d.ts +0 -1
  38. package/dist/api/knowledge.test.js +0 -238
  39. package/dist/api/mcp-servers.test.d.ts +0 -1
  40. package/dist/api/mcp-servers.test.js +0 -98
  41. package/dist/api/projects.test.d.ts +0 -1
  42. package/dist/api/projects.test.js +0 -61
  43. package/dist/api/search.test.d.ts +0 -1
  44. package/dist/api/search.test.js +0 -50
  45. package/dist/api/secrets.test.d.ts +0 -1
  46. package/dist/api/secrets.test.js +0 -61
  47. package/dist/api/sessions.test.d.ts +0 -1
  48. package/dist/api/sessions.test.js +0 -61
  49. package/dist/api/tasks.test.d.ts +0 -1
  50. package/dist/api/tasks.test.js +0 -381
  51. package/dist/api/teams.test.d.ts +0 -1
  52. package/dist/api/teams.test.js +0 -139
  53. package/dist/client.test.d.ts +0 -1
  54. package/dist/client.test.js +0 -446
  55. package/dist/http/client.test.d.ts +0 -1
  56. package/dist/http/client.test.js +0 -435
  57. package/dist/http/errors.test.d.ts +0 -1
  58. package/dist/http/errors.test.js +0 -66
  59. package/dist/http/poll.test.d.ts +0 -1
  60. package/dist/http/poll.test.js +0 -146
  61. package/dist/http/streamable.test.d.ts +0 -4
  62. package/dist/http/streamable.test.js +0 -510
  63. package/dist/integration.test.d.ts +0 -9
  64. package/dist/integration.test.js +0 -107
  65. package/dist/proxy/express.test.d.ts +0 -1
  66. package/dist/proxy/express.test.js +0 -106
  67. package/dist/proxy/hono.test.d.ts +0 -1
  68. package/dist/proxy/hono.test.js +0 -90
  69. package/dist/proxy/index.test.d.ts +0 -1
  70. package/dist/proxy/index.test.js +0 -173
  71. package/dist/proxy/nextjs.test.d.ts +0 -1
  72. package/dist/proxy/nextjs.test.js +0 -125
  73. package/dist/proxy/remix.test.d.ts +0 -1
  74. package/dist/proxy/remix.test.js +0 -66
  75. package/dist/proxy/svelte.test.d.ts +0 -1
  76. package/dist/proxy/svelte.test.js +0 -69
  77. package/dist/sessions.integration.test.d.ts +0 -13
  78. package/dist/sessions.integration.test.js +0 -310
  79. package/dist/stream.test.d.ts +0 -1
  80. package/dist/stream.test.js +0 -363
  81. package/dist/streamable.integration.test.d.ts +0 -11
  82. package/dist/streamable.integration.test.js +0 -150
  83. package/dist/tool-builder.test.d.ts +0 -1
  84. package/dist/tool-builder.test.js +0 -407
  85. package/dist/utils.test.d.ts +0 -1
  86. package/dist/utils.test.js +0 -43
@@ -1,446 +0,0 @@
1
- import { Inference, inference, createClient } from './index';
2
- import { RequirementsNotMetException } from './http/errors';
3
- import { HttpClient } from './http/client';
4
- import { ChatStatusBusy, ChatStatusIdle } from './types';
5
- // Mock fetch globally
6
- const mockFetch = jest.fn();
7
- global.fetch = mockFetch;
8
- describe('Inference', () => {
9
- beforeEach(() => {
10
- jest.clearAllMocks();
11
- });
12
- describe('constructor', () => {
13
- it('should create an instance with valid config', () => {
14
- const client = new Inference({ apiKey: 'test-api-key' });
15
- expect(client).toBeInstanceOf(Inference);
16
- });
17
- it('should throw error when neither apiKey nor proxyUrl is provided', () => {
18
- expect(() => new Inference({ apiKey: '' })).toThrow('Either apiKey, getToken, or proxyUrl is required');
19
- expect(() => new Inference({})).toThrow('Either apiKey, getToken, or proxyUrl is required');
20
- });
21
- it('should use default baseUrl when not provided', () => {
22
- const client = new Inference({ apiKey: 'test-api-key' });
23
- expect(client).toBeDefined();
24
- });
25
- it('should accept custom baseUrl', () => {
26
- const client = new Inference({
27
- apiKey: 'test-api-key',
28
- baseUrl: 'https://custom-api.example.com',
29
- });
30
- expect(client).toBeDefined();
31
- });
32
- });
33
- describe('run', () => {
34
- it('should make a POST request to /run', async () => {
35
- const mockTask = {
36
- id: 'task-123',
37
- status: 9, // TaskStatusCompleted
38
- created_at: new Date().toISOString(),
39
- updated_at: new Date().toISOString(),
40
- input: { message: 'hello world' },
41
- output: { result: 'success' },
42
- };
43
- const responseData = mockTask;
44
- mockFetch.mockResolvedValueOnce({
45
- ok: true,
46
- status: 200,
47
- text: () => Promise.resolve(JSON.stringify(responseData)),
48
- json: () => Promise.resolve(responseData),
49
- });
50
- const client = new Inference({ apiKey: 'test-api-key' });
51
- // Use input that won't trigger base64 detection (contains spaces/special chars)
52
- const result = await client.run({ app: 'test-app', input: { message: 'hello world!' } }, { wait: false });
53
- expect(result.id).toBe('task-123');
54
- expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/run'), expect.objectContaining({
55
- method: 'POST',
56
- headers: expect.objectContaining({
57
- Authorization: 'Bearer test-api-key',
58
- 'Content-Type': 'application/json',
59
- }),
60
- }));
61
- });
62
- it('should throw error on API failure', async () => {
63
- const responseData = { message: 'Invalid app' };
64
- mockFetch.mockResolvedValueOnce({
65
- ok: false,
66
- status: 400,
67
- text: () => Promise.resolve(JSON.stringify(responseData)),
68
- json: () => Promise.resolve(responseData),
69
- });
70
- const client = new Inference({ apiKey: 'test-api-key' });
71
- await expect(client.run({ app: 'invalid-app', input: { message: 'test!' } }, { wait: false })).rejects.toThrow('Invalid app');
72
- });
73
- it('should throw RequirementsNotMetException on 412 with errors', async () => {
74
- const requirementErrors = [
75
- {
76
- type: 'secret',
77
- key: 'OPENAI_API_KEY',
78
- message: 'Missing secret: OPENAI_API_KEY',
79
- action: { type: 'add_secret', secret_key: 'OPENAI_API_KEY' },
80
- },
81
- {
82
- type: 'integration',
83
- key: 'google',
84
- message: 'Integration not connected: google',
85
- action: { type: 'connect', provider: 'google' },
86
- },
87
- ];
88
- const responseData = { errors: requirementErrors };
89
- mockFetch.mockResolvedValueOnce({
90
- ok: false,
91
- status: 412,
92
- text: () => Promise.resolve(JSON.stringify(responseData)),
93
- json: () => Promise.resolve(responseData),
94
- });
95
- const client = new Inference({ apiKey: 'test-api-key' });
96
- try {
97
- await client.run({ app: 'test-app', input: { message: 'test!' } }, { wait: false });
98
- fail('Expected RequirementsNotMetException to be thrown');
99
- }
100
- catch (e) {
101
- expect(e).toBeInstanceOf(RequirementsNotMetException);
102
- const exception = e;
103
- expect(exception.errors).toHaveLength(2);
104
- expect(exception.errors[0].type).toBe('secret');
105
- expect(exception.errors[0].key).toBe('OPENAI_API_KEY');
106
- expect(exception.errors[1].type).toBe('integration');
107
- expect(exception.statusCode).toBe(412);
108
- expect(exception.message).toBe('Missing secret: OPENAI_API_KEY');
109
- }
110
- });
111
- it('should include action details in RequirementsNotMetException', async () => {
112
- const requirementErrors = [
113
- {
114
- type: 'scope',
115
- key: 'calendar.readonly',
116
- message: 'Missing scope: calendar.readonly',
117
- action: {
118
- type: 'add_scopes',
119
- provider: 'google',
120
- scopes: ['calendar.readonly', 'calendar.events'],
121
- },
122
- },
123
- ];
124
- const responseData = { errors: requirementErrors };
125
- mockFetch.mockResolvedValueOnce({
126
- ok: false,
127
- status: 412,
128
- text: () => Promise.resolve(JSON.stringify(responseData)),
129
- json: () => Promise.resolve(responseData),
130
- });
131
- const client = new Inference({ apiKey: 'test-api-key' });
132
- try {
133
- await client.run({ app: 'test-app', input: {} }, { wait: false });
134
- fail('Expected RequirementsNotMetException to be thrown');
135
- }
136
- catch (e) {
137
- expect(e).toBeInstanceOf(RequirementsNotMetException);
138
- const exception = e;
139
- expect(exception.errors[0].action?.type).toBe('add_scopes');
140
- expect(exception.errors[0].action?.scopes).toEqual(['calendar.readonly', 'calendar.events']);
141
- }
142
- });
143
- it('should process Blob inputs via processInput before calling /apps/run', async () => {
144
- const fileRecord = {
145
- id: 'file-blob',
146
- uri: 'inf://files/blob',
147
- upload_url: 'https://upload.example.com/put',
148
- content_type: 'image/png',
149
- };
150
- const mockTask = {
151
- id: 'task-456',
152
- status: 9,
153
- created_at: new Date().toISOString(),
154
- updated_at: new Date().toISOString(),
155
- input: {},
156
- output: { result: 'done' },
157
- };
158
- mockFetch
159
- .mockResolvedValueOnce({
160
- ok: true,
161
- status: 200,
162
- text: () => Promise.resolve(JSON.stringify([fileRecord])),
163
- json: () => Promise.resolve([fileRecord]),
164
- })
165
- .mockResolvedValueOnce({ ok: true, status: 200 })
166
- .mockResolvedValueOnce({
167
- ok: true,
168
- status: 200,
169
- text: () => Promise.resolve(JSON.stringify(mockTask)),
170
- json: () => Promise.resolve(mockTask),
171
- });
172
- const client = new Inference({ apiKey: 'test-api-key' });
173
- const blob = new Blob(['png-bytes'], { type: 'image/png' });
174
- const result = await client.run({ app: 'test-app', input: { image: blob } }, { wait: false });
175
- expect(result.id).toBe('task-456');
176
- expect(mockFetch).toHaveBeenCalledTimes(3);
177
- const runCall = mockFetch.mock.calls.find((call) => String(call[0]).includes('/apps/run'));
178
- expect(runCall).toBeDefined();
179
- const runBody = JSON.parse(runCall[1].body);
180
- expect(runBody.input.image).toBe('inf://files/blob');
181
- });
182
- });
183
- describe('cancel', () => {
184
- it('should make a POST request to cancel endpoint', async () => {
185
- const responseData = null;
186
- mockFetch.mockResolvedValueOnce({
187
- ok: true,
188
- status: 200,
189
- text: () => Promise.resolve(JSON.stringify(responseData)),
190
- json: () => Promise.resolve(responseData),
191
- });
192
- const client = new Inference({ apiKey: 'test-api-key' });
193
- await client.cancel('task-123');
194
- expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/tasks/task-123/cancel'), expect.objectContaining({ method: 'POST' }));
195
- });
196
- });
197
- describe('legacy task helpers', () => {
198
- it('should delegate getTask() to tasks.get', async () => {
199
- const mockTask = { id: 'task-legacy', status: 9 };
200
- mockFetch.mockResolvedValueOnce({
201
- ok: true,
202
- status: 200,
203
- text: () => Promise.resolve(JSON.stringify(mockTask)),
204
- json: () => Promise.resolve(mockTask),
205
- });
206
- const client = new Inference({ apiKey: 'test-api-key' });
207
- const result = await client.getTask('task-legacy');
208
- expect(result.id).toBe('task-legacy');
209
- expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/tasks/task-legacy'), expect.objectContaining({ method: 'GET' }));
210
- });
211
- it('should delegate streamTask() to tasks.stream', async () => {
212
- const client = new Inference({ apiKey: 'test-api-key' });
213
- const createEventSource = jest
214
- .spyOn(HttpClient.prototype, 'createEventSource')
215
- .mockResolvedValue(null);
216
- await client.streamTask('task-stream');
217
- expect(createEventSource).toHaveBeenCalledWith('/tasks/task-stream/stream');
218
- createEventSource.mockRestore();
219
- });
220
- });
221
- describe('agent()', () => {
222
- it('should return an Agent whose sendMessage hits POST /agents/run', async () => {
223
- mockFetch
224
- .mockResolvedValueOnce({
225
- ok: true,
226
- status: 200,
227
- text: () => Promise.resolve(JSON.stringify({
228
- user_message: { id: 'user-1', chat_id: 'chat-1', role: 'user', content: 'hi' },
229
- assistant_message: { id: 'asst-1', chat_id: 'chat-1', role: 'assistant', content: 'hello' },
230
- })),
231
- })
232
- .mockResolvedValueOnce({
233
- ok: true,
234
- status: 200,
235
- text: () => Promise.resolve(JSON.stringify({ status: ChatStatusBusy })),
236
- })
237
- .mockResolvedValueOnce({
238
- ok: true,
239
- status: 200,
240
- text: () => Promise.resolve(JSON.stringify({ id: 'chat-1', status: ChatStatusBusy, chat_messages: [] })),
241
- })
242
- .mockResolvedValueOnce({
243
- ok: true,
244
- status: 200,
245
- text: () => Promise.resolve(JSON.stringify({ status: ChatStatusIdle })),
246
- })
247
- .mockResolvedValueOnce({
248
- ok: true,
249
- status: 200,
250
- text: () => Promise.resolve(JSON.stringify({ id: 'chat-1', status: ChatStatusIdle, chat_messages: [] })),
251
- });
252
- const client = new Inference({ apiKey: 'test-api-key', stream: false, pollIntervalMs: 20 });
253
- const agentInstance = client.agent('my-agent');
254
- await agentInstance.sendMessage('hi', { stream: false });
255
- const runCall = mockFetch.mock.calls.find(([url]) => String(url).includes('/agents/run'));
256
- expect(runCall).toBeDefined();
257
- const body = JSON.parse(runCall[1].body);
258
- expect(body.agent).toBe('my-agent');
259
- });
260
- });
261
- describe('createClient', () => {
262
- it('should create an Inference instance with extended HttpClient config', () => {
263
- const client = createClient({ apiKey: 'extended-key', baseUrl: 'https://api.example.com' });
264
- expect(client).toBeInstanceOf(Inference);
265
- });
266
- });
267
- describe('lowercase factory', () => {
268
- it('should export lowercase inference factory', () => {
269
- expect(typeof inference).toBe('function');
270
- });
271
- it('should work with lowercase inference factory', () => {
272
- const client = inference({ apiKey: 'test-api-key' });
273
- expect(client).toBeInstanceOf(Inference);
274
- });
275
- });
276
- });
277
- describe('namespaced APIs', () => {
278
- beforeEach(() => {
279
- jest.clearAllMocks();
280
- });
281
- describe('client.tasks', () => {
282
- it('should have tasks namespace', () => {
283
- const client = new Inference({ apiKey: 'test-api-key' });
284
- expect(client.tasks).toBeDefined();
285
- expect(typeof client.tasks.run).toBe('function');
286
- expect(typeof client.tasks.get).toBe('function');
287
- expect(typeof client.tasks.cancel).toBe('function');
288
- expect(typeof client.tasks.list).toBe('function');
289
- expect(typeof client.tasks.create).toBe('function');
290
- });
291
- it('should create task via tasks.create()', async () => {
292
- const mockTask = {
293
- id: 'task-123',
294
- status: 1,
295
- created_at: new Date().toISOString(),
296
- updated_at: new Date().toISOString(),
297
- input: { message: 'hello world' },
298
- };
299
- const responseData = mockTask;
300
- mockFetch.mockResolvedValueOnce({
301
- ok: true,
302
- status: 200,
303
- text: () => Promise.resolve(JSON.stringify(responseData)),
304
- json: () => Promise.resolve(responseData),
305
- });
306
- const client = new Inference({ apiKey: 'test-api-key' });
307
- const result = await client.tasks.create({
308
- app: 'test-org/test-app@v1',
309
- input: { message: 'hello world!' },
310
- });
311
- expect(result.id).toBe('task-123');
312
- expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/apps/run'), expect.objectContaining({ method: 'POST' }));
313
- });
314
- it('should get task via tasks.get()', async () => {
315
- const mockTask = { id: 'task-123', status: 7 };
316
- const responseData = mockTask;
317
- mockFetch.mockResolvedValueOnce({
318
- ok: true,
319
- status: 200,
320
- text: () => Promise.resolve(JSON.stringify(responseData)),
321
- json: () => Promise.resolve(responseData),
322
- });
323
- const client = new Inference({ apiKey: 'test-api-key' });
324
- const result = await client.tasks.get('task-123');
325
- expect(result.id).toBe('task-123');
326
- expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/tasks/task-123'), expect.objectContaining({ method: 'GET' }));
327
- });
328
- it('should cancel task via tasks.cancel()', async () => {
329
- const responseData = null;
330
- mockFetch.mockResolvedValueOnce({
331
- ok: true,
332
- status: 200,
333
- text: () => Promise.resolve(JSON.stringify(responseData)),
334
- json: () => Promise.resolve(responseData),
335
- });
336
- const client = new Inference({ apiKey: 'test-api-key' });
337
- await client.tasks.cancel('task-123');
338
- expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/tasks/task-123/cancel'), expect.objectContaining({ method: 'POST' }));
339
- });
340
- });
341
- describe('client.files', () => {
342
- it('should have files namespace', () => {
343
- const client = new Inference({ apiKey: 'test-api-key' });
344
- expect(client.files).toBeDefined();
345
- expect(typeof client.files.upload).toBe('function');
346
- expect(typeof client.files.list).toBe('function');
347
- expect(typeof client.files.get).toBe('function');
348
- expect(typeof client.files.delete).toBe('function');
349
- });
350
- });
351
- describe('client.agents', () => {
352
- it('should have agents namespace', () => {
353
- const client = new Inference({ apiKey: 'test-api-key' });
354
- expect(client.agents).toBeDefined();
355
- expect(typeof client.agents.list).toBe('function');
356
- expect(typeof client.agents.get).toBe('function');
357
- expect(typeof client.agents.create).toBe('function');
358
- });
359
- });
360
- describe('client.apps', () => {
361
- it('should have apps namespace', () => {
362
- const client = new Inference({ apiKey: 'test-api-key' });
363
- expect(client.apps).toBeDefined();
364
- expect(typeof client.apps.list).toBe('function');
365
- expect(typeof client.apps.get).toBe('function');
366
- expect(typeof client.apps.getByName).toBe('function');
367
- });
368
- });
369
- describe('client.chats', () => {
370
- it('should have chats namespace', () => {
371
- const client = new Inference({ apiKey: 'test-api-key' });
372
- expect(client.chats).toBeDefined();
373
- expect(typeof client.chats.list).toBe('function');
374
- expect(typeof client.chats.get).toBe('function');
375
- });
376
- });
377
- describe('client.flows', () => {
378
- it('should have flows namespace', () => {
379
- const client = new Inference({ apiKey: 'test-api-key' });
380
- expect(client.flows).toBeDefined();
381
- expect(typeof client.flows.list).toBe('function');
382
- expect(typeof client.flows.get).toBe('function');
383
- });
384
- });
385
- describe('client.flowRuns', () => {
386
- it('should have flowRuns namespace', () => {
387
- const client = new Inference({ apiKey: 'test-api-key' });
388
- expect(client.flowRuns).toBeDefined();
389
- expect(typeof client.flowRuns.list).toBe('function');
390
- expect(typeof client.flowRuns.get).toBe('function');
391
- });
392
- });
393
- describe('client.engines', () => {
394
- it('should have engines namespace', () => {
395
- const client = new Inference({ apiKey: 'test-api-key' });
396
- expect(client.engines).toBeDefined();
397
- expect(typeof client.engines.list).toBe('function');
398
- expect(typeof client.engines.get).toBe('function');
399
- });
400
- });
401
- });
402
- describe('uploadFile', () => {
403
- beforeEach(() => {
404
- jest.clearAllMocks();
405
- });
406
- it('should upload a base64 string', async () => {
407
- const mockFile = {
408
- id: 'file-123',
409
- uri: 'https://example.com/file.png',
410
- upload_url: 'https://upload.example.com/signed-url',
411
- };
412
- const responseData = [mockFile];
413
- mockFetch
414
- .mockResolvedValueOnce({
415
- ok: true,
416
- status: 200,
417
- text: () => Promise.resolve(JSON.stringify(responseData)),
418
- json: () => Promise.resolve(responseData),
419
- })
420
- .mockResolvedValueOnce({ ok: true });
421
- const client = new Inference({ apiKey: 'test-api-key' });
422
- // Use valid base64 that won't be mistaken for regular text
423
- const result = await client.uploadFile('SGVsbG8gV29ybGQh', {
424
- filename: 'test.txt',
425
- contentType: 'text/plain',
426
- });
427
- expect(result.uri).toBe('https://example.com/file.png');
428
- expect(mockFetch).toHaveBeenCalledTimes(2);
429
- });
430
- it('should throw error when no upload URL provided', async () => {
431
- const mockFile = {
432
- id: 'file-123',
433
- uri: 'https://example.com/file.png',
434
- // Missing upload_url
435
- };
436
- const responseData = [mockFile];
437
- mockFetch.mockResolvedValueOnce({
438
- ok: true,
439
- status: 200,
440
- text: () => Promise.resolve(JSON.stringify(responseData)),
441
- json: () => Promise.resolve(responseData),
442
- });
443
- const client = new Inference({ apiKey: 'test-api-key' });
444
- await expect(client.uploadFile('SGVsbG8gV29ybGQh', { filename: 'test.txt' })).rejects.toThrow('No upload URL provided by the server');
445
- });
446
- });
@@ -1 +0,0 @@
1
- export {};