@inferencesh/sdk 0.6.14 → 0.6.19

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 (89) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/actions.js +10 -0
  3. package/dist/agent/provider.d.ts +2 -1
  4. package/dist/agent/provider.js +5 -5
  5. package/dist/agent/types.d.ts +3 -0
  6. package/dist/api/apps.d.ts +4 -0
  7. package/dist/api/apps.js +6 -0
  8. package/dist/api/index.d.ts +3 -3
  9. package/dist/http/index.d.ts +3 -3
  10. package/dist/index.d.ts +9 -9
  11. package/dist/types.d.ts +131 -19
  12. package/dist/types.js +26 -9
  13. package/package.json +8 -5
  14. package/dist/agent/actions.test.d.ts +0 -1
  15. package/dist/agent/actions.test.js +0 -820
  16. package/dist/agent/api.test.d.ts +0 -1
  17. package/dist/agent/api.test.js +0 -246
  18. package/dist/agent/reducer.test.d.ts +0 -1
  19. package/dist/agent/reducer.test.js +0 -131
  20. package/dist/agent/types.test.d.ts +0 -1
  21. package/dist/agent/types.test.js +0 -75
  22. package/dist/api/agents.test.d.ts +0 -1
  23. package/dist/api/agents.test.js +0 -1014
  24. package/dist/api/api-keys.test.d.ts +0 -1
  25. package/dist/api/api-keys.test.js +0 -44
  26. package/dist/api/apps.test.d.ts +0 -1
  27. package/dist/api/apps.test.js +0 -135
  28. package/dist/api/chats.test.d.ts +0 -1
  29. package/dist/api/chats.test.js +0 -85
  30. package/dist/api/engines.test.d.ts +0 -1
  31. package/dist/api/engines.test.js +0 -133
  32. package/dist/api/files.test.d.ts +0 -1
  33. package/dist/api/files.test.js +0 -256
  34. package/dist/api/flow-runs.test.d.ts +0 -1
  35. package/dist/api/flow-runs.test.js +0 -97
  36. package/dist/api/flows.test.d.ts +0 -1
  37. package/dist/api/flows.test.js +0 -118
  38. package/dist/api/integrations.test.d.ts +0 -1
  39. package/dist/api/integrations.test.js +0 -109
  40. package/dist/api/knowledge.test.d.ts +0 -1
  41. package/dist/api/knowledge.test.js +0 -238
  42. package/dist/api/mcp-servers.test.d.ts +0 -1
  43. package/dist/api/mcp-servers.test.js +0 -98
  44. package/dist/api/projects.test.d.ts +0 -1
  45. package/dist/api/projects.test.js +0 -61
  46. package/dist/api/search.test.d.ts +0 -1
  47. package/dist/api/search.test.js +0 -50
  48. package/dist/api/secrets.test.d.ts +0 -1
  49. package/dist/api/secrets.test.js +0 -61
  50. package/dist/api/sessions.test.d.ts +0 -1
  51. package/dist/api/sessions.test.js +0 -61
  52. package/dist/api/tasks.test.d.ts +0 -1
  53. package/dist/api/tasks.test.js +0 -381
  54. package/dist/api/teams.test.d.ts +0 -1
  55. package/dist/api/teams.test.js +0 -139
  56. package/dist/client.test.d.ts +0 -1
  57. package/dist/client.test.js +0 -446
  58. package/dist/http/client.test.d.ts +0 -1
  59. package/dist/http/client.test.js +0 -435
  60. package/dist/http/errors.test.d.ts +0 -1
  61. package/dist/http/errors.test.js +0 -66
  62. package/dist/http/poll.test.d.ts +0 -1
  63. package/dist/http/poll.test.js +0 -146
  64. package/dist/http/streamable.test.d.ts +0 -4
  65. package/dist/http/streamable.test.js +0 -510
  66. package/dist/integration.test.d.ts +0 -9
  67. package/dist/integration.test.js +0 -107
  68. package/dist/proxy/express.test.d.ts +0 -1
  69. package/dist/proxy/express.test.js +0 -106
  70. package/dist/proxy/hono.test.d.ts +0 -1
  71. package/dist/proxy/hono.test.js +0 -90
  72. package/dist/proxy/index.test.d.ts +0 -1
  73. package/dist/proxy/index.test.js +0 -173
  74. package/dist/proxy/nextjs.test.d.ts +0 -1
  75. package/dist/proxy/nextjs.test.js +0 -125
  76. package/dist/proxy/remix.test.d.ts +0 -1
  77. package/dist/proxy/remix.test.js +0 -66
  78. package/dist/proxy/svelte.test.d.ts +0 -1
  79. package/dist/proxy/svelte.test.js +0 -69
  80. package/dist/sessions.integration.test.d.ts +0 -13
  81. package/dist/sessions.integration.test.js +0 -310
  82. package/dist/stream.test.d.ts +0 -1
  83. package/dist/stream.test.js +0 -363
  84. package/dist/streamable.integration.test.d.ts +0 -11
  85. package/dist/streamable.integration.test.js +0 -150
  86. package/dist/tool-builder.test.d.ts +0 -1
  87. package/dist/tool-builder.test.js +0 -407
  88. package/dist/utils.test.d.ts +0 -1
  89. 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 {};