@inferencesh/sdk 0.5.6 → 0.5.8

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.
@@ -4,7 +4,7 @@
4
4
  * Action creators that handle side effects (API calls, streaming).
5
5
  * These are created once per provider instance with access to dispatch.
6
6
  */
7
- import { ToolInvocationStatusAwaitingInput, ToolTypeClient, } from '../types';
7
+ import { ToolInvocationStatusAwaitingInput, ToolTypeClient, ChatStatusBusy, } from '../types';
8
8
  import { StreamManager } from '../http/stream';
9
9
  import { PollManager } from '../http/poll';
10
10
  import { isAdHocConfig, extractClientToolHandlers } from './types';
@@ -24,7 +24,7 @@ export function createActions(ctx) {
24
24
  const setChat = (chat) => {
25
25
  dispatch({ type: 'SET_CHAT', payload: chat });
26
26
  if (chat) {
27
- const status = chat.status === 'busy' ? 'streaming' : 'idle';
27
+ const status = chat.status === ChatStatusBusy ? 'streaming' : 'idle';
28
28
  callbacks.onStatusChange?.(status);
29
29
  }
30
30
  };
@@ -32,6 +32,10 @@ export interface SendMessageOptions {
32
32
  /** Polling interval in ms when stream is false. Overrides client default. */
33
33
  pollIntervalMs?: number;
34
34
  }
35
+ export interface AgentRunOptions extends Omit<SendMessageOptions, 'stream'> {
36
+ /** Polling interval in ms (default: 2000) */
37
+ pollIntervalMs?: number;
38
+ }
35
39
  /**
36
40
  * Agent for chat interactions
37
41
  *
@@ -71,6 +75,14 @@ export declare class Agent {
71
75
  }): Promise<void>;
72
76
  /** Stop streaming/polling and cleanup */
73
77
  disconnect(): void;
78
+ /**
79
+ * Run the agent and return structured output.
80
+ *
81
+ * Sends a message, waits for completion (always polls, no SSE), then returns
82
+ * `chat.output` — the parsed finish tool result. Returns `null` if the agent
83
+ * finished without calling the finish tool.
84
+ */
85
+ run(text: string, options?: AgentRunOptions): Promise<any>;
74
86
  /** Reset the agent (start fresh chat) */
75
87
  reset(): void;
76
88
  /**
@@ -1,6 +1,6 @@
1
1
  import { StreamManager } from '../http/stream';
2
2
  import { PollManager } from '../http/poll';
3
- import { ToolTypeClient, ToolInvocationStatusAwaitingInput, } from '../types';
3
+ import { ToolTypeClient, ToolInvocationStatusAwaitingInput, ChatStatusBusy, } from '../types';
4
4
  /**
5
5
  * Agent for chat interactions
6
6
  *
@@ -62,12 +62,13 @@ export class Agent {
62
62
  input: { text, images: imageUris, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 },
63
63
  };
64
64
  const useStream = options.stream ?? this.http.getStreamDefault();
65
- const waitFn = useStream
66
- ? (opts) => this.streamUntilIdle(opts)
67
- : (opts) => this.pollUntilIdle(opts);
68
- // For existing chats with callbacks: Start waiting BEFORE POST so we don't miss updates
65
+ const shouldWait = useStream === false || hasCallbacks;
66
+ const waitFn = useStream === false
67
+ ? (opts) => this.pollUntilIdle(opts)
68
+ : (opts) => this.streamUntilIdle(opts);
69
+ // For existing chats: Start waiting BEFORE POST so we don't miss updates
69
70
  let waitPromise = null;
70
- if (this.chatId && hasCallbacks) {
71
+ if (this.chatId && shouldWait) {
71
72
  waitPromise = waitFn(options);
72
73
  }
73
74
  // Make the POST request
@@ -76,7 +77,7 @@ export class Agent {
76
77
  const isNewChat = !this.chatId && response.assistant_message.chat_id;
77
78
  if (isNewChat) {
78
79
  this.chatId = response.assistant_message.chat_id;
79
- if (hasCallbacks) {
80
+ if (shouldWait) {
80
81
  waitPromise = waitFn(options);
81
82
  }
82
83
  }
@@ -113,6 +114,18 @@ export class Agent {
113
114
  this.poller?.stop();
114
115
  this.poller = null;
115
116
  }
117
+ /**
118
+ * Run the agent and return structured output.
119
+ *
120
+ * Sends a message, waits for completion (always polls, no SSE), then returns
121
+ * `chat.output` — the parsed finish tool result. Returns `null` if the agent
122
+ * finished without calling the finish tool.
123
+ */
124
+ async run(text, options = {}) {
125
+ await this.sendMessage(text, { ...options, stream: false });
126
+ const chat = await this.getChat();
127
+ return chat?.output ?? null;
128
+ }
116
129
  /** Reset the agent (start fresh chat) */
117
130
  reset() {
118
131
  this.disconnect();
@@ -139,7 +152,7 @@ export class Agent {
139
152
  });
140
153
  this.stream.addEventListener('chats', (chat) => {
141
154
  options.onChat?.(chat);
142
- if (chat.status === 'idle') {
155
+ if (chat.status !== ChatStatusBusy) {
143
156
  resolve();
144
157
  }
145
158
  });
@@ -217,7 +230,7 @@ export class Agent {
217
230
  }
218
231
  }
219
232
  }
220
- if (chat.status === 'idle') {
233
+ if (chat.status !== ChatStatusBusy) {
221
234
  this.poller?.stop();
222
235
  this.poller = null;
223
236
  resolve();
@@ -1,4 +1,4 @@
1
1
  export { TasksAPI, createTasksAPI, RunOptions } from './tasks';
2
2
  export { FilesAPI, createFilesAPI, UploadFileOptions } from './files';
3
- export { AgentsAPI, createAgentsAPI, Agent, AgentOptions, SendMessageOptions } from './agents';
3
+ export { AgentsAPI, createAgentsAPI, Agent, AgentOptions, SendMessageOptions, AgentRunOptions } from './agents';
4
4
  export { SessionsAPI, createSessionsAPI } from './sessions';
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ export { PollManager, PollManagerOptions } from './http/poll';
4
4
  export { InferenceError, RequirementsNotMetException, SessionError, SessionNotFoundError, SessionExpiredError, SessionEndedError, WorkerLostError, } from './http/errors';
5
5
  export { TasksAPI, RunOptions } from './api/tasks';
6
6
  export { FilesAPI, UploadFileOptions } from './api/files';
7
- export { AgentsAPI, Agent, AgentOptions, SendMessageOptions } from './api/agents';
7
+ export { AgentsAPI, Agent, AgentOptions, SendMessageOptions, AgentRunOptions } from './api/agents';
8
8
  export { SessionsAPI } from './api/sessions';
9
9
  export { AppsAPI } from './api/apps';
10
10
  export { ChatsAPI } from './api/chats';
@@ -76,6 +76,17 @@ describeIfApiKey('Integration Tests', () => {
76
76
  expect(result.id).toBeDefined();
77
77
  }, 30000);
78
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
+ });
79
90
  describe('Error Handling', () => {
80
91
  it('should throw an error for non-existent app', async () => {
81
92
  await expect(client.run({
package/dist/types.d.ts CHANGED
@@ -349,6 +349,11 @@ export interface ApiAppRunRequest {
349
349
  * If true, returns SSE stream instead of JSON response
350
350
  */
351
351
  stream?: boolean;
352
+ /**
353
+ * If true, holds the connection open until the task reaches a terminal state and returns the final result.
354
+ * Mutually exclusive with Stream.
355
+ */
356
+ wait?: boolean;
352
357
  /**
353
358
  * Function to call on multi-function apps (defaults to "run" or app's default_function)
354
359
  */
@@ -436,6 +441,14 @@ export interface CreateAgentMessageResponse {
436
441
  export interface ToolResultRequest {
437
442
  result: string;
438
443
  }
444
+ /**
445
+ * WebhookEvent is the envelope for task webhook deliveries.
446
+ */
447
+ export interface WebhookEvent<T extends any> {
448
+ event: string;
449
+ timestamp: string;
450
+ data: T;
451
+ }
439
452
  /**
440
453
  * HookPayload represents the request body sent to a webhook when a hook tool is invoked
441
454
  */
@@ -720,6 +733,16 @@ export interface EngineConfig {
720
733
  network_name: string;
721
734
  cache_path: string;
722
735
  gpus: string[];
736
+ /**
737
+ * CallbackBasePort overrides the base port for engine↔worker callback APIs.
738
+ * If 0, derived from EnginePort: 5000 + (enginePort - 8163) * 100.
739
+ */
740
+ callback_base_port: number;
741
+ /**
742
+ * EngineInternalAPIURL is the URL workers use to reach the engine's main API.
743
+ * If empty, derived as http://host.docker.internal:{EnginePort}.
744
+ */
745
+ engine_internal_api_url: string;
723
746
  }
724
747
  export type AppCategory = string;
725
748
  export declare const AppCategoryImage: AppCategory;
@@ -1188,6 +1211,7 @@ export declare const DeviceAuthStatusLoading: DeviceAuthStatus;
1188
1211
  export type EngineStatus = string;
1189
1212
  export declare const EngineStatusRunning: EngineStatus;
1190
1213
  export declare const EngineStatusPending: EngineStatus;
1214
+ export declare const EngineStatusDraining: EngineStatus;
1191
1215
  export declare const EngineStatusStopping: EngineStatus;
1192
1216
  export declare const EngineStatusStopped: EngineStatus;
1193
1217
  export interface EngineState extends BaseModel, PermissionModel {
@@ -1979,7 +2003,7 @@ export interface Task extends BaseModel, PermissionModel {
1979
2003
  setup?: any;
1980
2004
  input: any;
1981
2005
  output: any;
1982
- error: string;
2006
+ error?: string;
1983
2007
  rating: ContentRating;
1984
2008
  /**
1985
2009
  * Relationships
@@ -2054,7 +2078,7 @@ export interface TaskDTO extends BaseModel, PermissionModelDTO {
2054
2078
  setup?: any;
2055
2079
  input: any;
2056
2080
  output: any;
2057
- error: string;
2081
+ error?: string;
2058
2082
  rating: ContentRating;
2059
2083
  events: TaskEvent[];
2060
2084
  logs: TaskLog[];
package/dist/types.js CHANGED
@@ -80,6 +80,7 @@ export const DeviceAuthStatusInvalid = "invalid";
80
80
  export const DeviceAuthStatusLoading = "loading";
81
81
  export const EngineStatusRunning = "running";
82
82
  export const EngineStatusPending = "pending";
83
+ export const EngineStatusDraining = "draining";
83
84
  export const EngineStatusStopping = "stopping";
84
85
  export const EngineStatusStopped = "stopped";
85
86
  export const FlowRunStatusUnknown = 0; // 0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inferencesh/sdk",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "description": "Official JavaScript/TypeScript SDK for inference.sh - Run AI models with a simple API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",