@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,510 +0,0 @@
1
- /**
2
- * Unit tests for streamable HTTP client
3
- */
4
- import { streamable, streamableRaw, StreamableManager } from './streamable';
5
- // Mock fetch for unit tests
6
- const mockFetch = (chunks) => {
7
- let chunkIndex = 0;
8
- const mockReader = {
9
- read: jest.fn().mockImplementation(async () => {
10
- if (chunkIndex >= chunks.length) {
11
- return { done: true, value: undefined };
12
- }
13
- const chunk = chunks[chunkIndex++];
14
- return { done: false, value: new TextEncoder().encode(chunk) };
15
- }),
16
- releaseLock: jest.fn(),
17
- };
18
- return jest.fn().mockResolvedValue({
19
- ok: true,
20
- status: 200,
21
- body: {
22
- getReader: () => mockReader,
23
- },
24
- });
25
- };
26
- describe('streamable', () => {
27
- const originalFetch = global.fetch;
28
- afterEach(() => {
29
- global.fetch = originalFetch;
30
- });
31
- it('should parse NDJSON lines', async () => {
32
- global.fetch = mockFetch([
33
- '{"id":1,"name":"first"}\n',
34
- '{"id":2,"name":"second"}\n',
35
- ]);
36
- const results = [];
37
- for await (const item of streamable('http://test.com/stream')) {
38
- results.push(item);
39
- }
40
- expect(results).toHaveLength(2);
41
- expect(results[0]).toEqual({ id: 1, name: 'first' });
42
- expect(results[1]).toEqual({ id: 2, name: 'second' });
43
- });
44
- it('should skip heartbeats by default', async () => {
45
- global.fetch = mockFetch([
46
- '{"id":1}\n',
47
- '{"type":"heartbeat"}\n',
48
- '{"id":2}\n',
49
- ]);
50
- const results = [];
51
- for await (const item of streamable('http://test.com/stream')) {
52
- results.push(item);
53
- }
54
- expect(results).toHaveLength(2);
55
- expect(results[0]).toEqual({ id: 1 });
56
- expect(results[1]).toEqual({ id: 2 });
57
- });
58
- it('should include heartbeats when skipHeartbeats is false', async () => {
59
- global.fetch = mockFetch([
60
- '{"id":1}\n',
61
- '{"type":"heartbeat"}\n',
62
- '{"id":2}\n',
63
- ]);
64
- const results = [];
65
- for await (const item of streamable('http://test.com/stream', { skipHeartbeats: false })) {
66
- results.push(item);
67
- }
68
- expect(results).toHaveLength(3);
69
- });
70
- it('should unwrap data from wrapped messages', async () => {
71
- global.fetch = mockFetch([
72
- '{"data":{"id":1},"fields":["id"]}\n',
73
- '{"event":"update","data":{"id":2}}\n',
74
- ]);
75
- const results = [];
76
- for await (const item of streamable('http://test.com/stream')) {
77
- results.push(item);
78
- }
79
- expect(results).toHaveLength(2);
80
- expect(results[0]).toEqual({ id: 1 });
81
- expect(results[1]).toEqual({ id: 2 });
82
- });
83
- it('should handle chunked data across multiple reads', async () => {
84
- global.fetch = mockFetch([
85
- '{"id":1}\n{"id":', // First chunk ends mid-JSON
86
- '2}\n', // Second chunk completes it
87
- ]);
88
- const results = [];
89
- for await (const item of streamable('http://test.com/stream')) {
90
- results.push(item);
91
- }
92
- expect(results).toHaveLength(2);
93
- expect(results[0]).toEqual({ id: 1 });
94
- expect(results[1]).toEqual({ id: 2 });
95
- });
96
- it('should handle empty lines', async () => {
97
- global.fetch = mockFetch([
98
- '{"id":1}\n',
99
- '\n',
100
- '{"id":2}\n',
101
- '\n\n',
102
- ]);
103
- const results = [];
104
- for await (const item of streamable('http://test.com/stream')) {
105
- results.push(item);
106
- }
107
- expect(results).toHaveLength(2);
108
- });
109
- it('should set correct headers', async () => {
110
- const mockFetchFn = mockFetch(['{"ok":true}\n']);
111
- global.fetch = mockFetchFn;
112
- const results = [];
113
- for await (const item of streamable('http://test.com/stream', {
114
- headers: { 'Authorization': 'Bearer token' },
115
- })) {
116
- results.push(item);
117
- }
118
- expect(mockFetchFn).toHaveBeenCalledWith('http://test.com/stream', expect.objectContaining({
119
- method: 'GET',
120
- headers: expect.objectContaining({
121
- 'Accept': 'application/x-ndjson',
122
- 'Authorization': 'Bearer token',
123
- }),
124
- }));
125
- });
126
- it('should use POST when body is provided', async () => {
127
- const mockFetchFn = mockFetch(['{"ok":true}\n']);
128
- global.fetch = mockFetchFn;
129
- const results = [];
130
- for await (const item of streamable('http://test.com/stream', {
131
- body: { query: 'test' },
132
- })) {
133
- results.push(item);
134
- }
135
- expect(mockFetchFn).toHaveBeenCalledWith('http://test.com/stream', expect.objectContaining({
136
- method: 'POST',
137
- headers: expect.objectContaining({
138
- 'Content-Type': 'application/json',
139
- }),
140
- body: JSON.stringify({ query: 'test' }),
141
- }));
142
- });
143
- it('should throw on HTTP error', async () => {
144
- global.fetch = jest.fn().mockResolvedValue({
145
- ok: false,
146
- status: 401,
147
- text: async () => 'Unauthorized',
148
- });
149
- await expect(async () => {
150
- for await (const _ of streamable('http://test.com/stream')) {
151
- // consume
152
- }
153
- }).rejects.toThrow('HTTP 401: Unauthorized');
154
- });
155
- it('should throw when the response has no body', async () => {
156
- global.fetch = jest.fn().mockResolvedValue({
157
- ok: true,
158
- status: 200,
159
- body: null,
160
- });
161
- await expect(async () => {
162
- for await (const _ of streamable('http://test.com/stream')) {
163
- // consume
164
- }
165
- }).rejects.toThrow('No response body');
166
- });
167
- // Edge cases for chunking/buffering
168
- describe('chunking edge cases', () => {
169
- it('should handle message split across many chunks', async () => {
170
- // Split a single JSON object into 5 tiny chunks
171
- global.fetch = mockFetch([
172
- '{"id":',
173
- '123,',
174
- '"name"',
175
- ':"test',
176
- '"}\n',
177
- ]);
178
- const results = [];
179
- for await (const item of streamable('http://test.com/stream')) {
180
- results.push(item);
181
- }
182
- expect(results).toHaveLength(1);
183
- expect(results[0]).toEqual({ id: 123, name: 'test' });
184
- });
185
- it('should handle single-byte chunks', async () => {
186
- const json = '{"id":1}\n';
187
- const chunks = json.split('').map(c => c); // One char per chunk
188
- global.fetch = mockFetch(chunks);
189
- const results = [];
190
- for await (const item of streamable('http://test.com/stream')) {
191
- results.push(item);
192
- }
193
- expect(results).toHaveLength(1);
194
- expect(results[0]).toEqual({ id: 1 });
195
- });
196
- it('should handle newline exactly at chunk boundary', async () => {
197
- global.fetch = mockFetch([
198
- '{"id":1}',
199
- '\n',
200
- '{"id":2}\n',
201
- ]);
202
- const results = [];
203
- for await (const item of streamable('http://test.com/stream')) {
204
- results.push(item);
205
- }
206
- expect(results).toHaveLength(2);
207
- });
208
- it('should handle multiple messages in single chunk', async () => {
209
- global.fetch = mockFetch([
210
- '{"id":1}\n{"id":2}\n{"id":3}\n',
211
- ]);
212
- const results = [];
213
- for await (const item of streamable('http://test.com/stream')) {
214
- results.push(item);
215
- }
216
- expect(results).toHaveLength(3);
217
- });
218
- it('should handle empty chunks', async () => {
219
- global.fetch = mockFetch([
220
- '{"id":1}\n',
221
- '',
222
- '',
223
- '{"id":2}\n',
224
- ]);
225
- const results = [];
226
- for await (const item of streamable('http://test.com/stream')) {
227
- results.push(item);
228
- }
229
- expect(results).toHaveLength(2);
230
- });
231
- it('should handle trailing data without final newline', async () => {
232
- global.fetch = mockFetch([
233
- '{"id":1}\n',
234
- '{"id":2}', // No trailing newline
235
- ]);
236
- const results = [];
237
- for await (const item of streamable('http://test.com/stream')) {
238
- results.push(item);
239
- }
240
- expect(results).toHaveLength(2);
241
- });
242
- });
243
- describe('unicode handling', () => {
244
- it('should handle unicode in messages', async () => {
245
- global.fetch = mockFetch([
246
- '{"text":"Hello 世界 🎉"}\n',
247
- ]);
248
- const results = [];
249
- for await (const item of streamable('http://test.com/stream')) {
250
- results.push(item);
251
- }
252
- expect(results[0]).toEqual({ text: 'Hello 世界 🎉' });
253
- });
254
- it('should handle unicode split across chunks', async () => {
255
- // 世 is 3 bytes in UTF-8: E4 B8 96
256
- // Split it across chunks
257
- const encoder = new TextEncoder();
258
- const fullText = '{"text":"世"}\n';
259
- const bytes = encoder.encode(fullText);
260
- // Create mock that returns raw bytes split mid-character
261
- let chunkIndex = 0;
262
- const chunks = [
263
- bytes.slice(0, 10), // '{"text":"' + first byte of 世
264
- bytes.slice(10), // rest of 世 + '"}\n'
265
- ];
266
- const mockReader = {
267
- read: jest.fn().mockImplementation(async () => {
268
- if (chunkIndex >= chunks.length) {
269
- return { done: true, value: undefined };
270
- }
271
- return { done: false, value: chunks[chunkIndex++] };
272
- }),
273
- releaseLock: jest.fn(),
274
- };
275
- global.fetch = jest.fn().mockResolvedValue({
276
- ok: true,
277
- body: { getReader: () => mockReader },
278
- });
279
- const results = [];
280
- for await (const item of streamable('http://test.com/stream')) {
281
- results.push(item);
282
- }
283
- expect(results[0]).toEqual({ text: '世' });
284
- });
285
- });
286
- describe('error handling', () => {
287
- it('should handle invalid JSON gracefully', async () => {
288
- global.fetch = mockFetch([
289
- '{"id":1}\n',
290
- 'not valid json\n',
291
- '{"id":2}\n',
292
- ]);
293
- const results = [];
294
- await expect(async () => {
295
- for await (const item of streamable('http://test.com/stream')) {
296
- results.push(item);
297
- }
298
- }).rejects.toThrow(); // Should throw on invalid JSON
299
- // First valid message should have been processed
300
- expect(results).toHaveLength(1);
301
- });
302
- it('should handle network error mid-stream', async () => {
303
- let readCount = 0;
304
- const mockReader = {
305
- read: jest.fn().mockImplementation(async () => {
306
- readCount++;
307
- if (readCount === 1) {
308
- return { done: false, value: new TextEncoder().encode('{"id":1}\n') };
309
- }
310
- throw new Error('Network error');
311
- }),
312
- releaseLock: jest.fn(),
313
- };
314
- global.fetch = jest.fn().mockResolvedValue({
315
- ok: true,
316
- body: { getReader: () => mockReader },
317
- });
318
- const results = [];
319
- await expect(async () => {
320
- for await (const item of streamable('http://test.com/stream')) {
321
- results.push(item);
322
- }
323
- }).rejects.toThrow('Network error');
324
- expect(results).toHaveLength(1);
325
- });
326
- });
327
- });
328
- describe('streamableRaw', () => {
329
- const originalFetch = global.fetch;
330
- afterEach(() => {
331
- global.fetch = originalFetch;
332
- });
333
- it('should preserve event and fields in raw mode', async () => {
334
- global.fetch = mockFetch([
335
- '{"event":"update","data":{"id":1},"fields":["id"]}\n',
336
- ]);
337
- const results = [];
338
- for await (const item of streamableRaw('http://test.com/stream')) {
339
- results.push(item);
340
- }
341
- expect(results).toHaveLength(1);
342
- expect(results[0]).toEqual({
343
- event: 'update',
344
- data: { id: 1 },
345
- fields: ['id'],
346
- });
347
- });
348
- });
349
- describe('StreamableManager', () => {
350
- const originalFetch = global.fetch;
351
- afterEach(() => {
352
- global.fetch = originalFetch;
353
- });
354
- it('should call onData for each message', async () => {
355
- global.fetch = mockFetch([
356
- '{"id":1}\n',
357
- '{"id":2}\n',
358
- ]);
359
- const messages = [];
360
- const manager = new StreamableManager({
361
- url: 'http://test.com/stream',
362
- onData: (data) => messages.push(data),
363
- });
364
- await manager.start();
365
- expect(messages).toHaveLength(2);
366
- expect(messages[0]).toEqual({ id: 1 });
367
- expect(messages[1]).toEqual({ id: 2 });
368
- });
369
- it('should call onPartialData for partial updates', async () => {
370
- global.fetch = mockFetch([
371
- '{"data":{"id":1},"fields":["id"]}\n',
372
- ]);
373
- const partials = [];
374
- const manager = new StreamableManager({
375
- url: 'http://test.com/stream',
376
- onPartialData: (data, fields) => partials.push({ data, fields }),
377
- });
378
- await manager.start();
379
- expect(partials).toHaveLength(1);
380
- expect(partials[0]).toEqual({ data: { id: 1 }, fields: ['id'] });
381
- });
382
- it('should call lifecycle callbacks', async () => {
383
- global.fetch = mockFetch(['{"ok":true}\n']);
384
- const events = [];
385
- const manager = new StreamableManager({
386
- url: 'http://test.com/stream',
387
- onStart: () => events.push('start'),
388
- onEnd: () => events.push('end'),
389
- onData: () => events.push('data'),
390
- });
391
- await manager.start();
392
- expect(events).toEqual(['start', 'data', 'end']);
393
- });
394
- it('should dispatch typed events to addEventListener subscribers', async () => {
395
- global.fetch = mockFetch([
396
- '{"event":"chats","data":{"id":"chat-1","status":"busy"}}\n',
397
- '{"event":"chat_messages","data":{"id":"msg-1","content":"hi"}}\n',
398
- ]);
399
- const onChat = jest.fn();
400
- const onMessage = jest.fn();
401
- const manager = new StreamableManager({
402
- url: 'http://test.com/stream',
403
- onData: jest.fn(),
404
- });
405
- manager.addEventListener('chats', onChat);
406
- manager.addEventListener('chat_messages', onMessage);
407
- await manager.start();
408
- expect(onChat).toHaveBeenCalledWith({ id: 'chat-1', status: 'busy' });
409
- expect(onMessage).toHaveBeenCalledWith({ id: 'msg-1', content: 'hi' });
410
- });
411
- it('should stop dispatching to an unsubscribed listener', async () => {
412
- global.fetch = mockFetch([
413
- '{"event":"chats","data":{"id":"chat-1"}}\n',
414
- ]);
415
- const removedListener = jest.fn();
416
- const activeListener = jest.fn();
417
- const manager = new StreamableManager({
418
- url: 'http://test.com/stream',
419
- });
420
- const unsubscribe = manager.addEventListener('chats', removedListener);
421
- manager.addEventListener('chats', activeListener);
422
- unsubscribe();
423
- await manager.start();
424
- expect(removedListener).not.toHaveBeenCalled();
425
- expect(activeListener).toHaveBeenCalledWith({ id: 'chat-1' });
426
- });
427
- it('should ignore start() when a stream is already running', async () => {
428
- let readCount = 0;
429
- const mockReader = {
430
- read: jest.fn().mockImplementation(async () => {
431
- readCount++;
432
- if (readCount > 3) {
433
- return { done: true, value: undefined };
434
- }
435
- await new Promise((resolve) => setTimeout(resolve, 20));
436
- return { done: false, value: new TextEncoder().encode('{"id":1}\n') };
437
- }),
438
- releaseLock: jest.fn(),
439
- };
440
- global.fetch = jest.fn().mockResolvedValue({
441
- ok: true,
442
- body: { getReader: () => mockReader },
443
- });
444
- const onStart = jest.fn();
445
- const manager = new StreamableManager({
446
- url: 'http://test.com/stream',
447
- onStart,
448
- onData: () => { },
449
- });
450
- const firstStart = manager.start();
451
- await manager.start();
452
- await firstStart;
453
- expect(onStart).toHaveBeenCalledTimes(1);
454
- expect(global.fetch).toHaveBeenCalledTimes(1);
455
- });
456
- it('should handle stop()', async () => {
457
- let readCount = 0;
458
- const mockReader = {
459
- read: jest.fn().mockImplementation(async () => {
460
- readCount++;
461
- if (readCount > 10) {
462
- return { done: true, value: undefined };
463
- }
464
- await new Promise(resolve => setTimeout(resolve, 10));
465
- return { done: false, value: new TextEncoder().encode('{"id":1}\n') };
466
- }),
467
- releaseLock: jest.fn(),
468
- };
469
- global.fetch = jest.fn().mockResolvedValue({
470
- ok: true,
471
- body: { getReader: () => mockReader },
472
- });
473
- const manager = new StreamableManager({
474
- url: 'http://test.com/stream',
475
- onData: () => { },
476
- });
477
- // Start and immediately stop
478
- const startPromise = manager.start();
479
- setTimeout(() => manager.stop(), 25);
480
- await startPromise;
481
- // Should have stopped before reading all 10
482
- expect(readCount).toBeLessThan(10);
483
- });
484
- it('should call onError when the stream request fails', async () => {
485
- global.fetch = jest.fn().mockResolvedValue({
486
- ok: false,
487
- status: 503,
488
- text: async () => 'Service unavailable',
489
- });
490
- const onError = jest.fn();
491
- const manager = new StreamableManager({
492
- url: 'http://test.com/stream',
493
- onError,
494
- });
495
- await manager.start();
496
- expect(onError).toHaveBeenCalledWith(expect.objectContaining({ message: 'HTTP 503: Service unavailable' }));
497
- });
498
- it('should route partial updates to onData when onPartialData is not provided', async () => {
499
- global.fetch = mockFetch([
500
- '{"data":{"id":1,"status":"busy"},"fields":["status"]}\n',
501
- ]);
502
- const onData = jest.fn();
503
- const manager = new StreamableManager({
504
- url: 'http://test.com/stream',
505
- onData,
506
- });
507
- await manager.start();
508
- expect(onData).toHaveBeenCalledWith({ id: 1, status: 'busy' });
509
- });
510
- });
@@ -1,9 +0,0 @@
1
- /**
2
- * Integration tests for @inferencesh/sdk
3
- *
4
- * These tests hit the real API and require INFERENCE_API_KEY to be set.
5
- * Run with: npm run test:integration
6
- *
7
- * @jest-environment node
8
- */
9
- export {};
@@ -1,107 +0,0 @@
1
- /**
2
- * Integration tests for @inferencesh/sdk
3
- *
4
- * These tests hit the real API and require INFERENCE_API_KEY to be set.
5
- * Run with: npm run test:integration
6
- *
7
- * @jest-environment node
8
- */
9
- import { Inference, inference } from './index';
10
- import { TaskStatusCompleted, TaskStatusFailed } from './types';
11
- // Skip all tests if no API key is set
12
- const API_KEY = process.env.INFERENCE_API_KEY;
13
- const BASE_URL = process.env.INFERENCE_BASE_URL || 'https://api.inference.sh';
14
- // Use a pinned app version that's known to work
15
- const TEST_APP = 'infsh/text-templating@53bk0yzk';
16
- const describeIfApiKey = API_KEY ? describe : describe.skip;
17
- describeIfApiKey('Integration Tests', () => {
18
- let client;
19
- beforeAll(() => {
20
- client = new Inference({
21
- apiKey: API_KEY,
22
- baseUrl: BASE_URL,
23
- });
24
- });
25
- describe('Basic Run', () => {
26
- it('should run a simple task and wait for completion', async () => {
27
- const result = await client.run({
28
- app: TEST_APP,
29
- input: { template: 'Hello {1}!', strings: ['Jest'] },
30
- });
31
- expect(result).toBeDefined();
32
- expect(result.id).toBeDefined();
33
- expect(result.status).toBe(TaskStatusCompleted);
34
- expect(result.output).toBeDefined();
35
- }, 60000); // 60 second timeout for API call
36
- });
37
- describe('Run with Updates', () => {
38
- it('should receive status updates during task execution', async () => {
39
- const updates = [];
40
- const result = await client.run({
41
- app: TEST_APP,
42
- input: { template: 'Testing {1}', strings: ['SDK'] },
43
- }, {
44
- onUpdate: (update) => {
45
- updates.push(update.status);
46
- },
47
- });
48
- expect(result.status).toBe(TaskStatusCompleted);
49
- expect(updates.length).toBeGreaterThan(0);
50
- }, 60000);
51
- });
52
- describe('Fire and Forget', () => {
53
- it('should submit a task without waiting for completion', async () => {
54
- const result = await client.run({
55
- app: TEST_APP,
56
- input: { template: '{1}', strings: ['Fire and forget'] },
57
- }, { wait: false });
58
- expect(result).toBeDefined();
59
- expect(result.id).toBeDefined();
60
- // Status should NOT be completed yet (task was just submitted)
61
- expect(result.status).not.toBe(TaskStatusCompleted);
62
- expect(result.status).not.toBe(TaskStatusFailed);
63
- }, 30000);
64
- });
65
- describe('Factory Function', () => {
66
- it('should work with lowercase inference() factory', async () => {
67
- const factoryClient = inference({
68
- apiKey: API_KEY,
69
- baseUrl: BASE_URL,
70
- });
71
- const result = await factoryClient.run({
72
- app: TEST_APP,
73
- input: { template: '{1}', strings: ['Factory test'] },
74
- }, { wait: false });
75
- expect(result).toBeDefined();
76
- expect(result.id).toBeDefined();
77
- }, 30000);
78
- });
79
- describe('Webhook', () => {
80
- it('should deliver webhook on task completion', async () => {
81
- const result = await client.run({
82
- app: TEST_APP,
83
- input: { template: 'Webhook test {1}', strings: ['hello'] },
84
- webhook: 'https://webhook.site/bbe9ba01-3ab2-4056-a1b1-1cf6969987d5',
85
- });
86
- expect(result.status).toBe(TaskStatusCompleted);
87
- expect(result.output).toBeDefined();
88
- }, 60000);
89
- });
90
- describe('Error Handling', () => {
91
- it('should throw an error for non-existent app', async () => {
92
- await expect(client.run({
93
- app: 'non-existent/app-that-does-not-exist@xyz123',
94
- input: {},
95
- }, { wait: false })).rejects.toThrow();
96
- }, 30000);
97
- });
98
- });
99
- // Add a simple test that always runs to ensure Jest doesn't complain about no tests
100
- describe('Integration Test Setup', () => {
101
- it('should have API key check', () => {
102
- if (!API_KEY) {
103
- console.log('⚠️ Skipping integration tests - INFERENCE_API_KEY not set');
104
- }
105
- expect(true).toBe(true);
106
- });
107
- });
@@ -1 +0,0 @@
1
- export {};