@inferencesh/sdk 0.1.1 → 0.2.0

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/dist/client.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.inference = exports.Inference = void 0;
3
+ exports.Agent = exports.Inference = void 0;
4
+ exports.inference = inference;
4
5
  const types_1 = require("./types");
5
6
  const stream_1 = require("./stream");
6
7
  const eventsource_1 = require("eventsource");
8
+ const errors_1 = require("./errors");
7
9
  /**
8
10
  * Inference.sh SDK Client
9
11
  *
@@ -21,7 +23,8 @@ class Inference {
21
23
  this.apiKey = config.apiKey;
22
24
  this.baseUrl = config.baseUrl || "https://api.inference.sh";
23
25
  }
24
- async request(method, endpoint, options = {}) {
26
+ /** @internal */
27
+ async _request(method, endpoint, options = {}) {
25
28
  const url = new URL(`${this.baseUrl}${endpoint}`);
26
29
  if (options.params) {
27
30
  Object.entries(options.params).forEach(([key, value]) => {
@@ -43,13 +46,48 @@ class Inference {
43
46
  fetchOptions.body = JSON.stringify(options.data);
44
47
  }
45
48
  const response = await fetch(url.toString(), fetchOptions);
46
- const data = await response.json();
47
- if (!data.success) {
48
- throw new Error(data.error?.message || "Request failed");
49
+ const responseText = await response.text();
50
+ // Try to parse as JSON
51
+ let data = null;
52
+ try {
53
+ data = JSON.parse(responseText);
49
54
  }
50
- return data.data;
55
+ catch {
56
+ // Not JSON
57
+ }
58
+ // Check for HTTP errors
59
+ if (!response.ok) {
60
+ // Check for RequirementsNotMetException (412 with errors array)
61
+ if (response.status === 412 && data && 'errors' in data && Array.isArray(data.errors)) {
62
+ throw errors_1.RequirementsNotMetException.fromResponse(data, response.status);
63
+ }
64
+ // General error handling
65
+ let errorDetail;
66
+ if (data && typeof data === 'object') {
67
+ const apiData = data;
68
+ if (apiData.error) {
69
+ errorDetail = typeof apiData.error === 'object' ? apiData.error.message : String(apiData.error);
70
+ }
71
+ else if ('message' in data) {
72
+ errorDetail = String(data.message);
73
+ }
74
+ else {
75
+ errorDetail = JSON.stringify(data);
76
+ }
77
+ }
78
+ else if (responseText) {
79
+ errorDetail = responseText.slice(0, 500);
80
+ }
81
+ throw new errors_1.InferenceError(response.status, errorDetail || 'Request failed', responseText);
82
+ }
83
+ const apiResponse = data;
84
+ if (!apiResponse?.success) {
85
+ throw new errors_1.InferenceError(response.status, apiResponse?.error?.message || 'Request failed', responseText);
86
+ }
87
+ return apiResponse.data;
51
88
  }
52
- createEventSource(endpoint) {
89
+ /** @internal */
90
+ _createEventSource(endpoint) {
53
91
  const url = new URL(`${this.baseUrl}${endpoint}`);
54
92
  return new eventsource_1.EventSource(url.toString(), {
55
93
  fetch: (input, init) => fetch(input, {
@@ -112,26 +150,37 @@ class Inference {
112
150
  * @param options - Run options for waiting, updates, and reconnection
113
151
  * @returns The completed task result
114
152
  *
153
+ * App reference format: `namespace/name@shortid` (version is required)
154
+ *
155
+ * The short ID ensures your code always runs the same version,
156
+ * protecting against breaking changes from app updates.
157
+ *
115
158
  * @example
116
159
  * ```typescript
117
- * // Simple usage - wait for result
118
- * const result = await client.run({ app: 'my-app', input: { prompt: 'hello' } });
160
+ * // Run a specific version (required)
161
+ * const result = await client.run({
162
+ * app: 'okaris/flux@abc1', // version @abc1 is pinned
163
+ * input: { prompt: 'hello' }
164
+ * });
119
165
  *
120
166
  * // With status updates
121
167
  * const result = await client.run(
122
- * { app: 'my-app', input: { prompt: 'hello' } },
168
+ * { app: 'okaris/flux@abc1', input: { prompt: 'hello' } },
123
169
  * { onUpdate: (update) => console.log(update.status) }
124
170
  * );
125
171
  *
126
172
  * // Fire and forget
127
- * const task = await client.run({ app: 'my-app', input: {} }, { wait: false });
173
+ * const task = await client.run(
174
+ * { app: 'okaris/flux@abc1', input: {} },
175
+ * { wait: false }
176
+ * );
128
177
  * ```
129
178
  */
130
179
  async run(params, options = {}) {
131
180
  const { onUpdate, onPartialUpdate, wait = true, autoReconnect = true, maxReconnects = 5, reconnectDelayMs = 1000, } = options;
132
181
  // Process input data and upload any files
133
182
  const processedInput = await this.processInputData(params.input);
134
- const task = await this.request("post", "/run", {
183
+ const task = await this._request("post", "/apps/run", {
135
184
  data: {
136
185
  ...params,
137
186
  input: processedInput
@@ -144,7 +193,7 @@ class Inference {
144
193
  // Wait for completion with optional updates
145
194
  return new Promise((resolve, reject) => {
146
195
  const streamManager = new stream_1.StreamManager({
147
- createEventSource: async () => this.createEventSource(`/tasks/${task.id}/stream`),
196
+ createEventSource: async () => this._createEventSource(`/tasks/${task.id}/stream`),
148
197
  autoReconnect,
149
198
  maxReconnects,
150
199
  reconnectDelayMs,
@@ -189,7 +238,7 @@ class Inference {
189
238
  path: options.path,
190
239
  size: data instanceof Blob ? data.size : undefined,
191
240
  };
192
- const response = await this.request("post", "/files", {
241
+ const response = await this._request("post", "/files", {
193
242
  data: {
194
243
  files: [fileRequest]
195
244
  }
@@ -246,11 +295,159 @@ class Inference {
246
295
  * @param taskId - The ID of the task to cancel
247
296
  */
248
297
  async cancel(taskId) {
249
- return this.request("post", `/tasks/${taskId}/cancel`);
298
+ return this._request("post", `/tasks/${taskId}/cancel`);
299
+ }
300
+ /**
301
+ * Create an agent for chat interactions
302
+ *
303
+ * @param config - Either a template reference string (namespace/name@version) or ad-hoc config
304
+ * @returns An Agent instance for chat operations
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * // Template agent
309
+ * const agent = client.agent('okaris/assistant@abc123')
310
+ *
311
+ * // Ad-hoc agent
312
+ * const agent = client.agent({
313
+ * coreApp: 'infsh/claude-sonnet-4@xyz789',
314
+ * systemPrompt: 'You are a helpful assistant',
315
+ * tools: [...]
316
+ * })
317
+ *
318
+ * // Send messages
319
+ * const response = await agent.sendMessage('Hello!')
320
+ * ```
321
+ */
322
+ agent(config) {
323
+ return new Agent(this, config);
250
324
  }
251
325
  }
252
326
  exports.Inference = Inference;
327
+ // =============================================================================
328
+ // Agent Class
329
+ // =============================================================================
253
330
  /**
254
- * @deprecated Use `Inference` instead. Will be removed in v1.0.0
331
+ * Agent for chat interactions
332
+ *
333
+ * Created via `client.agent()` - do not instantiate directly.
255
334
  */
256
- exports.inference = Inference;
335
+ class Agent {
336
+ /** @internal */
337
+ constructor(client, config) {
338
+ this.chatId = null;
339
+ this.stream = null;
340
+ this.client = client;
341
+ this.config = config;
342
+ }
343
+ /** Get current chat ID */
344
+ get currentChatId() {
345
+ return this.chatId;
346
+ }
347
+ /** Send a message to the agent */
348
+ async sendMessage(text, options = {}) {
349
+ const isTemplate = typeof this.config === 'string';
350
+ // Upload files if provided
351
+ let imageUri;
352
+ let fileUris;
353
+ if (options.files && options.files.length > 0) {
354
+ const uploadedFiles = await Promise.all(options.files.map(f => this.client.uploadFile(f)));
355
+ const images = uploadedFiles.filter(f => f.content_type?.startsWith('image/'));
356
+ const others = uploadedFiles.filter(f => !f.content_type?.startsWith('image/'));
357
+ if (images.length > 0)
358
+ imageUri = images[0].uri;
359
+ if (others.length > 0)
360
+ fileUris = others.map(f => f.uri);
361
+ }
362
+ const body = isTemplate
363
+ ? {
364
+ chat_id: this.chatId,
365
+ agent: this.config,
366
+ input: { text, image: imageUri, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 },
367
+ }
368
+ : {
369
+ chat_id: this.chatId,
370
+ core_app: this.config.coreApp,
371
+ core_app_input: this.config.coreAppInput,
372
+ name: this.config.name,
373
+ system_prompt: this.config.systemPrompt,
374
+ tools: this.config.tools,
375
+ internal_tools: this.config.internalTools,
376
+ input: { text, image: imageUri, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 },
377
+ };
378
+ const response = await this.client._request('post', '/agents/run', { data: body });
379
+ if (!this.chatId && response.assistant_message.chat_id) {
380
+ this.chatId = response.assistant_message.chat_id;
381
+ this.startStreaming(options);
382
+ }
383
+ return response.assistant_message;
384
+ }
385
+ /** Get chat by ID */
386
+ async getChat(chatId) {
387
+ const id = chatId || this.chatId;
388
+ if (!id)
389
+ return null;
390
+ return this.client._request('get', `/chats/${id}`);
391
+ }
392
+ /** Stop the current chat generation */
393
+ async stopChat() {
394
+ if (!this.chatId)
395
+ return;
396
+ await this.client._request('post', `/chats/${this.chatId}/stop`);
397
+ }
398
+ /** Submit a tool result */
399
+ async submitToolResult(toolInvocationId, result) {
400
+ if (!this.chatId)
401
+ throw new Error('No active chat');
402
+ await this.client._request('post', `/chats/${this.chatId}/tool-result`, {
403
+ data: { tool_invocation_id: toolInvocationId, result },
404
+ });
405
+ }
406
+ /** Stop streaming and cleanup */
407
+ disconnect() {
408
+ this.stream?.stop();
409
+ this.stream = null;
410
+ }
411
+ /** Reset the agent (start fresh chat) */
412
+ reset() {
413
+ this.disconnect();
414
+ this.chatId = null;
415
+ }
416
+ startStreaming(options) {
417
+ if (!this.chatId)
418
+ return;
419
+ this.stream = new stream_1.StreamManager({
420
+ createEventSource: async () => this.client._createEventSource(`/chats/${this.chatId}/stream`),
421
+ autoReconnect: true,
422
+ });
423
+ this.stream.addEventListener('chats', (chat) => {
424
+ options.onChat?.(chat);
425
+ });
426
+ this.stream.addEventListener('chat_messages', (message) => {
427
+ options.onMessage?.(message);
428
+ if (message.tool_invocations && options.onToolCall) {
429
+ for (const inv of message.tool_invocations) {
430
+ if (inv.type === types_1.ToolTypeClient && inv.status === types_1.ToolInvocationStatusAwaitingInput) {
431
+ options.onToolCall({
432
+ id: inv.id,
433
+ name: inv.function?.name || '',
434
+ args: inv.function?.arguments || {},
435
+ });
436
+ }
437
+ }
438
+ }
439
+ });
440
+ this.stream.connect();
441
+ }
442
+ }
443
+ exports.Agent = Agent;
444
+ /**
445
+ * Factory function for creating an Inference client (lowercase for branding)
446
+ * @example
447
+ * ```typescript
448
+ * const client = inference({ apiKey: 'your-api-key' });
449
+ * ```
450
+ */
451
+ function inference(config) {
452
+ return new Inference(config);
453
+ }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const client_1 = require("./client");
4
+ const errors_1 = require("./errors");
4
5
  // Mock fetch globally
5
6
  const mockFetch = jest.fn();
6
7
  global.fetch = mockFetch;
@@ -39,8 +40,12 @@ describe('Inference', () => {
39
40
  input: { message: 'hello world' },
40
41
  output: { result: 'success' },
41
42
  };
43
+ const responseData = { success: true, data: mockTask };
42
44
  mockFetch.mockResolvedValueOnce({
43
- json: () => Promise.resolve({ success: true, data: mockTask }),
45
+ ok: true,
46
+ status: 200,
47
+ text: () => Promise.resolve(JSON.stringify(responseData)),
48
+ json: () => Promise.resolve(responseData),
44
49
  });
45
50
  const client = new client_1.Inference({ apiKey: 'test-api-key' });
46
51
  // Use input that won't trigger base64 detection (contains spaces/special chars)
@@ -55,29 +60,107 @@ describe('Inference', () => {
55
60
  }));
56
61
  });
57
62
  it('should throw error on API failure', async () => {
63
+ const responseData = { success: false, error: { message: 'Invalid app' } };
58
64
  mockFetch.mockResolvedValueOnce({
59
- json: () => Promise.resolve({ success: false, error: { message: 'Invalid app' } }),
65
+ ok: false,
66
+ status: 400,
67
+ text: () => Promise.resolve(JSON.stringify(responseData)),
68
+ json: () => Promise.resolve(responseData),
60
69
  });
61
70
  const client = new client_1.Inference({ apiKey: 'test-api-key' });
62
71
  await expect(client.run({ app: 'invalid-app', input: { message: 'test!' } }, { wait: false })).rejects.toThrow('Invalid app');
63
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 client_1.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(errors_1.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 client_1.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(errors_1.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
+ });
64
143
  });
65
144
  describe('cancel', () => {
66
145
  it('should make a POST request to cancel endpoint', async () => {
146
+ const responseData = { success: true, data: null };
67
147
  mockFetch.mockResolvedValueOnce({
68
- json: () => Promise.resolve({ success: true, data: null }),
148
+ ok: true,
149
+ status: 200,
150
+ text: () => Promise.resolve(JSON.stringify(responseData)),
151
+ json: () => Promise.resolve(responseData),
69
152
  });
70
153
  const client = new client_1.Inference({ apiKey: 'test-api-key' });
71
154
  await client.cancel('task-123');
72
155
  expect(mockFetch).toHaveBeenCalledWith(expect.stringContaining('/tasks/task-123/cancel'), expect.objectContaining({ method: 'POST' }));
73
156
  });
74
157
  });
75
- describe('backward compatibility', () => {
76
- it('should export lowercase inference as alias', () => {
77
- expect(client_1.inference).toBe(client_1.Inference);
158
+ describe('lowercase factory', () => {
159
+ it('should export lowercase inference factory', () => {
160
+ expect(typeof client_1.inference).toBe('function');
78
161
  });
79
- it('should work with lowercase inference', () => {
80
- const client = new client_1.inference({ apiKey: 'test-api-key' });
162
+ it('should work with lowercase inference factory', () => {
163
+ const client = (0, client_1.inference)({ apiKey: 'test-api-key' });
81
164
  expect(client).toBeInstanceOf(client_1.Inference);
82
165
  });
83
166
  });
@@ -92,9 +175,13 @@ describe('uploadFile', () => {
92
175
  uri: 'https://example.com/file.png',
93
176
  upload_url: 'https://upload.example.com/signed-url',
94
177
  };
178
+ const responseData = { success: true, data: [mockFile] };
95
179
  mockFetch
96
180
  .mockResolvedValueOnce({
97
- json: () => Promise.resolve({ success: true, data: [mockFile] }),
181
+ ok: true,
182
+ status: 200,
183
+ text: () => Promise.resolve(JSON.stringify(responseData)),
184
+ json: () => Promise.resolve(responseData),
98
185
  })
99
186
  .mockResolvedValueOnce({ ok: true });
100
187
  const client = new client_1.Inference({ apiKey: 'test-api-key' });
@@ -112,8 +199,12 @@ describe('uploadFile', () => {
112
199
  uri: 'https://example.com/file.png',
113
200
  // Missing upload_url
114
201
  };
202
+ const responseData = { success: true, data: [mockFile] };
115
203
  mockFetch.mockResolvedValueOnce({
116
- json: () => Promise.resolve({ success: true, data: [mockFile] }),
204
+ ok: true,
205
+ status: 200,
206
+ text: () => Promise.resolve(JSON.stringify(responseData)),
207
+ json: () => Promise.resolve(responseData),
117
208
  });
118
209
  const client = new client_1.Inference({ apiKey: 'test-api-key' });
119
210
  await expect(client.uploadFile('SGVsbG8gV29ybGQh', { filename: 'test.txt' })).rejects.toThrow('No upload URL provided by the server');
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Error classes for the inference.sh SDK.
3
+ *
4
+ * Note: types.ts contains interfaces (APIError, RequirementsNotMetError) that describe
5
+ * the API response data shapes. These classes are throwable Error subclasses for SDK use.
6
+ */
7
+ import type { RequirementError } from './types';
8
+ /**
9
+ * General HTTP/API error thrown by the SDK.
10
+ *
11
+ * Note: This is distinct from the `APIError` interface in types.ts which describes
12
+ * the error payload shape in API responses.
13
+ */
14
+ export declare class InferenceError extends Error {
15
+ readonly statusCode: number;
16
+ readonly responseBody?: string;
17
+ constructor(statusCode: number, message: string, responseBody?: string);
18
+ }
19
+ /**
20
+ * Error thrown when app requirements (secrets, integrations, scopes) are not met.
21
+ *
22
+ * Thrown for HTTP 412 responses that contain structured requirement errors.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * try {
27
+ * const task = await client.run(params);
28
+ * } catch (e) {
29
+ * if (e instanceof RequirementsNotMetException) {
30
+ * for (const err of e.errors) {
31
+ * console.log(`Missing ${err.type}: ${err.key}`);
32
+ * if (err.action) {
33
+ * console.log(` Fix: ${err.action.type}`);
34
+ * }
35
+ * }
36
+ * }
37
+ * }
38
+ * ```
39
+ */
40
+ export declare class RequirementsNotMetException extends Error {
41
+ readonly errors: RequirementError[];
42
+ readonly statusCode: number;
43
+ constructor(errors: RequirementError[], statusCode?: number);
44
+ /**
45
+ * Create from API response data.
46
+ */
47
+ static fromResponse(data: {
48
+ errors?: RequirementError[];
49
+ }, statusCode?: number): RequirementsNotMetException;
50
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ /**
3
+ * Error classes for the inference.sh SDK.
4
+ *
5
+ * Note: types.ts contains interfaces (APIError, RequirementsNotMetError) that describe
6
+ * the API response data shapes. These classes are throwable Error subclasses for SDK use.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.RequirementsNotMetException = exports.InferenceError = void 0;
10
+ /**
11
+ * General HTTP/API error thrown by the SDK.
12
+ *
13
+ * Note: This is distinct from the `APIError` interface in types.ts which describes
14
+ * the error payload shape in API responses.
15
+ */
16
+ class InferenceError extends Error {
17
+ constructor(statusCode, message, responseBody) {
18
+ super(`HTTP ${statusCode}: ${message}`);
19
+ this.name = 'InferenceError';
20
+ this.statusCode = statusCode;
21
+ this.responseBody = responseBody;
22
+ }
23
+ }
24
+ exports.InferenceError = InferenceError;
25
+ /**
26
+ * Error thrown when app requirements (secrets, integrations, scopes) are not met.
27
+ *
28
+ * Thrown for HTTP 412 responses that contain structured requirement errors.
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * try {
33
+ * const task = await client.run(params);
34
+ * } catch (e) {
35
+ * if (e instanceof RequirementsNotMetException) {
36
+ * for (const err of e.errors) {
37
+ * console.log(`Missing ${err.type}: ${err.key}`);
38
+ * if (err.action) {
39
+ * console.log(` Fix: ${err.action.type}`);
40
+ * }
41
+ * }
42
+ * }
43
+ * }
44
+ * ```
45
+ */
46
+ class RequirementsNotMetException extends Error {
47
+ constructor(errors, statusCode = 412) {
48
+ const message = errors.length > 0 ? errors[0].message : 'requirements not met';
49
+ super(message);
50
+ this.name = 'RequirementsNotMetException';
51
+ this.errors = errors;
52
+ this.statusCode = statusCode;
53
+ }
54
+ /**
55
+ * Create from API response data.
56
+ */
57
+ static fromResponse(data, statusCode = 412) {
58
+ return new RequirementsNotMetException(data.errors || [], statusCode);
59
+ }
60
+ }
61
+ exports.RequirementsNotMetException = RequirementsNotMetException;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
- export { Inference, inference, InferenceConfig, RunOptions, UploadFileOptions } from './client';
1
+ export { Inference, inference, InferenceConfig, RunOptions, UploadFileOptions, Agent, AdHocAgentConfig, SendMessageOptions, } from './client';
2
+ export { AgentConfig, AdHocAgentOptions, TemplateAgentOptions, AgentOptions, } from './agent';
3
+ export { tool, appTool, agentTool, webhookTool, internalTools, string, number, integer, boolean, enumOf, object, array, optional } from './tool-builder';
2
4
  export { StreamManager, PartialDataWrapper } from './stream';
5
+ export { InferenceError, RequirementsNotMetException } from './errors';
3
6
  export * from './types';
4
7
  export type { TaskDTO as Task } from './types';
package/dist/index.js CHANGED
@@ -14,13 +14,33 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.StreamManager = exports.inference = exports.Inference = void 0;
18
- // Main client export
17
+ exports.RequirementsNotMetException = exports.InferenceError = exports.StreamManager = exports.optional = exports.array = exports.object = exports.enumOf = exports.boolean = exports.integer = exports.number = exports.string = exports.internalTools = exports.webhookTool = exports.agentTool = exports.appTool = exports.tool = exports.Agent = exports.inference = exports.Inference = void 0;
18
+ // Main client export (includes Agent)
19
19
  var client_1 = require("./client");
20
20
  Object.defineProperty(exports, "Inference", { enumerable: true, get: function () { return client_1.Inference; } });
21
21
  Object.defineProperty(exports, "inference", { enumerable: true, get: function () { return client_1.inference; } });
22
+ Object.defineProperty(exports, "Agent", { enumerable: true, get: function () { return client_1.Agent; } });
23
+ // Tool Builder (fluent API)
24
+ var tool_builder_1 = require("./tool-builder");
25
+ Object.defineProperty(exports, "tool", { enumerable: true, get: function () { return tool_builder_1.tool; } });
26
+ Object.defineProperty(exports, "appTool", { enumerable: true, get: function () { return tool_builder_1.appTool; } });
27
+ Object.defineProperty(exports, "agentTool", { enumerable: true, get: function () { return tool_builder_1.agentTool; } });
28
+ Object.defineProperty(exports, "webhookTool", { enumerable: true, get: function () { return tool_builder_1.webhookTool; } });
29
+ Object.defineProperty(exports, "internalTools", { enumerable: true, get: function () { return tool_builder_1.internalTools; } });
30
+ Object.defineProperty(exports, "string", { enumerable: true, get: function () { return tool_builder_1.string; } });
31
+ Object.defineProperty(exports, "number", { enumerable: true, get: function () { return tool_builder_1.number; } });
32
+ Object.defineProperty(exports, "integer", { enumerable: true, get: function () { return tool_builder_1.integer; } });
33
+ Object.defineProperty(exports, "boolean", { enumerable: true, get: function () { return tool_builder_1.boolean; } });
34
+ Object.defineProperty(exports, "enumOf", { enumerable: true, get: function () { return tool_builder_1.enumOf; } });
35
+ Object.defineProperty(exports, "object", { enumerable: true, get: function () { return tool_builder_1.object; } });
36
+ Object.defineProperty(exports, "array", { enumerable: true, get: function () { return tool_builder_1.array; } });
37
+ Object.defineProperty(exports, "optional", { enumerable: true, get: function () { return tool_builder_1.optional; } });
22
38
  // Stream utilities
23
39
  var stream_1 = require("./stream");
24
40
  Object.defineProperty(exports, "StreamManager", { enumerable: true, get: function () { return stream_1.StreamManager; } });
41
+ // Error classes (throwable)
42
+ var errors_1 = require("./errors");
43
+ Object.defineProperty(exports, "InferenceError", { enumerable: true, get: function () { return errors_1.InferenceError; } });
44
+ Object.defineProperty(exports, "RequirementsNotMetException", { enumerable: true, get: function () { return errors_1.RequirementsNotMetException; } });
25
45
  // Types - includes TaskStatus constants and all DTOs
26
46
  __exportStar(require("./types"), exports);
package/dist/stream.d.ts CHANGED
@@ -24,7 +24,15 @@ export declare class StreamManager<T> {
24
24
  private initialConnectionAttempts;
25
25
  private isConnected;
26
26
  private isStopped;
27
+ private eventListeners;
27
28
  constructor(options: StreamManagerOptions<T>);
29
+ /**
30
+ * Add a listener for typed SSE events (e.g., 'chats', 'chat_messages')
31
+ * Used when server sends events with `event: eventName` header
32
+ */
33
+ addEventListener<E = unknown>(eventName: string, callback: (data: E) => void): () => void;
34
+ private setupEventListener;
35
+ private setupAllEventListeners;
28
36
  private clearTimeouts;
29
37
  private closeEventSource;
30
38
  private cleanup;