@inferencesh/sdk 0.4.26 → 0.5.1

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/README.md CHANGED
@@ -1,11 +1,13 @@
1
- # @inferencesh/sdk
1
+ # @inferencesh/sdk — ai inference api for javascript & typescript
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@inferencesh/sdk.svg)](https://www.npmjs.com/package/@inferencesh/sdk)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/@inferencesh/sdk.svg)](https://www.npmjs.com/package/@inferencesh/sdk)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
7
7
 
8
- Official JavaScript/TypeScript SDK for [inference.sh](https://inference.sh) — Run AI models with a simple API.
8
+ official javascript/typescript sdk for [inference.sh](https://inference.sh) — the ai agent runtime for serverless ai inference.
9
+
10
+ run ai models, build ai agents, and deploy generative ai applications with a simple api. access 150+ models including flux, stable diffusion, llms (claude, gpt, gemini), video generation (veo, seedance), and more.
9
11
 
10
12
  ## Installation
11
13
 
@@ -149,6 +151,53 @@ const task = await client.tasks.run(
149
151
  await client.tasks.cancel(task.id);
150
152
  ```
151
153
 
154
+ ### Sessions (Stateful Execution)
155
+
156
+ Sessions allow you to maintain state across multiple task invocations. The worker stays warm between calls, preserving loaded models and in-memory state.
157
+
158
+ ```typescript
159
+ // Start a new session
160
+ const result = await client.tasks.run({
161
+ app: 'my-stateful-app',
162
+ input: { prompt: 'hello' },
163
+ session: 'new'
164
+ });
165
+
166
+ const sessionId = result.session_id;
167
+ console.log('Session ID:', sessionId);
168
+
169
+ // Continue the session with another call
170
+ const result2 = await client.tasks.run({
171
+ app: 'my-stateful-app',
172
+ input: { prompt: 'remember what I said?' },
173
+ session: sessionId
174
+ });
175
+ ```
176
+
177
+ #### Custom Session Timeout
178
+
179
+ By default, sessions expire after 60 seconds of inactivity. You can customize this with `session_timeout` (1-3600 seconds):
180
+
181
+ ```typescript
182
+ // Create a session with 5-minute idle timeout
183
+ const result = await client.tasks.run({
184
+ app: 'my-stateful-app',
185
+ input: { prompt: 'hello' },
186
+ session: 'new',
187
+ session_timeout: 300 // 5 minutes
188
+ });
189
+
190
+ // Session stays alive for 5 minutes after each call
191
+ ```
192
+
193
+ **Notes:**
194
+ - `session_timeout` is only valid when `session: 'new'`
195
+ - Minimum timeout: 1 second
196
+ - Maximum timeout: 3600 seconds (1 hour)
197
+ - Each successful call resets the idle timer
198
+
199
+ For complete session documentation including error handling, best practices, and advanced patterns, see the [Sessions Developer Guide](https://inference.sh/docs/extend/sessions).
200
+
152
201
  ## Agent Chat
153
202
 
154
203
  Chat with AI agents using `client.agents.create()`.
@@ -252,6 +301,8 @@ Runs a task on inference.sh.
252
301
  | `params.setup` | `object` | No | Setup parameters (affects worker warmth/scheduling) |
253
302
  | `params.infra` | `string` | No | Infrastructure: `'cloud'` or `'private'` |
254
303
  | `params.variant` | `string` | No | App variant to use |
304
+ | `params.session` | `string` | No | Session ID or `'new'` to start a new session |
305
+ | `params.session_timeout` | `number` | No | Session timeout in seconds (1-3600, only with `session: 'new'`) |
255
306
 
256
307
  **Options:**
257
308
 
@@ -331,6 +382,14 @@ import type { Task, ApiTaskRequest, RunOptions } from '@inferencesh/sdk';
331
382
  - Node.js 18.0.0 or higher
332
383
  - Modern browsers with `fetch` support
333
384
 
334
- ## License
385
+ ## resources
386
+
387
+ - [documentation](https://inference.sh/docs) — getting started guides and api reference
388
+ - [blog](https://inference.sh/blog) — tutorials on ai agents, image generation, and more
389
+ - [app store](https://app.inference.sh) — browse 150+ ai models
390
+ - [discord](https://discord.gg/RM77SWSbyT) — community support
391
+ - [github](https://github.com/inference-sh) — open source projects
392
+
393
+ ## license
335
394
 
336
395
  MIT © [inference.sh](https://inference.sh)
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * React hooks for accessing chat state and actions.
5
5
  */
6
- import type { AgentChatState, AgentChatActions, ChatMessageDTO, AgentClient } from './types';
6
+ import type { AgentChatState, AgentChatActions, AgentClient } from './types';
7
+ import type { ChatMessageDTO } from '../types';
7
8
  /**
8
9
  * Hook to access chat state
9
10
  *
@@ -45,5 +45,5 @@
45
45
  export { AgentChatProvider } from './provider';
46
46
  export { useAgentChat, useAgentActions, useAgentClient, useAgentChatContext, useMessage, } from './hooks';
47
47
  export { AgentChatContext, type AgentChatContextValue } from './context';
48
- export type { AgentClient, UploadedFile, AdHocAgentConfig, TemplateAgentConfig, AgentOptions, AgentChatState, AgentChatActions, ChatStatus, AgentChatProviderProps, ClientTool, ClientToolHandlerFn, ChatMessageDTO, ChatDTO, ToolInvocationDTO, ChatMessageContent, ChatMessageRole, } from './types';
48
+ export type { AgentClient, UploadedFile, AdHocAgentConfig, TemplateAgentConfig, AgentOptions, AgentChatState, AgentChatActions, ChatStatus, AgentChatProviderProps, ClientTool, ClientToolHandlerFn, } from './types';
49
49
  export { isAdHocConfig, isTemplateConfig, isClientTool, extractToolSchemas, extractClientToolHandlers, } from './types';
@@ -4,7 +4,7 @@
4
4
  * Public types for the Agent chat module.
5
5
  */
6
6
  import type { Dispatch } from 'react';
7
- import type { ChatDTO, ChatMessageDTO, ToolInvocationDTO, ChatMessageContent, ChatMessageRole, TaskStatus, AgentTool, AgentConfig as GeneratedAgentConfig, CoreAppConfig } from '../types';
7
+ import type { ChatDTO, ChatMessageDTO, AgentTool, AgentConfig as GeneratedAgentConfig, CoreAppConfig } from '../types';
8
8
  import type { HttpClient } from '../http/client';
9
9
  import type { StreamManager } from '../http/stream';
10
10
  /**
@@ -26,10 +26,29 @@ export interface AgentClient {
26
26
  upload: (data: string | Blob | globalThis.File) => Promise<UploadedFile>;
27
27
  };
28
28
  }
29
- export type { ChatMessageDTO, ChatDTO, ToolInvocationDTO, ChatMessageContent, ChatMessageRole, TaskStatus, };
30
29
  /**
31
30
  * Configuration for an ad-hoc agent - extends generated AgentConfig
32
31
  * Adds support for ClientTool (browser-side tool handlers)
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const config: AdHocAgentConfig = {
36
+ * core_app: { ref: 'openrouter/claude-sonnet-4@abc123' },
37
+ * system_prompt: 'You are a helpful assistant.',
38
+ * skills: [
39
+ * {
40
+ * name: 'code-review',
41
+ * description: 'Guidelines for reviewing code',
42
+ * content: '# Code Review\n\nWhen reviewing code...'
43
+ * },
44
+ * {
45
+ * name: 'api-docs',
46
+ * description: 'API documentation',
47
+ * url: 'https://example.com/skills/api-docs.md'
48
+ * }
49
+ * ]
50
+ * }
51
+ * ```
33
52
  */
34
53
  export type AdHocAgentConfig = Omit<Partial<GeneratedAgentConfig>, 'tools' | 'core_app'> & {
35
54
  /** Core LLM app configuration (required for ad-hoc agents) */
@@ -1,14 +1,5 @@
1
1
  import { HttpClient } from '../http/client';
2
- import { AppDTO as App, AppVersionDTO, CursorListRequest, CursorListResponse } from '../types';
3
- interface LicenseRecord {
4
- id: string;
5
- created_at: string;
6
- updated_at: string;
7
- deleted_at?: string;
8
- user_id: string;
9
- app_id: string;
10
- license: string;
11
- }
2
+ import { AppDTO as App, AppVersionDTO, CursorListRequest, CursorListResponse, LicenseRecord } from '../types';
12
3
  /**
13
4
  * Apps API
14
5
  */
@@ -69,4 +60,3 @@ export declare class AppsAPI {
69
60
  saveLicense(appId: string, license: string): Promise<LicenseRecord>;
70
61
  }
71
62
  export declare function createAppsAPI(http: HttpClient): AppsAPI;
72
- export {};
package/dist/api/files.js CHANGED
@@ -111,11 +111,22 @@ export class FilesAPI {
111
111
  return processed;
112
112
  }
113
113
  // Handle base64 strings or data URIs
114
- if (typeof input === 'string' &&
115
- (input.startsWith('data:') ||
116
- /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$/.test(input))) {
117
- const file = await this.upload(input);
118
- return file.uri;
114
+ // Only treat as base64 if it's a data URI OR if it looks like base64 AND is reasonably long
115
+ // Short strings like "key1" or "test" shouldn't be treated as base64
116
+ if (typeof input === 'string') {
117
+ if (input.startsWith('data:')) {
118
+ // Data URIs are always treated as files
119
+ const file = await this.upload(input);
120
+ return file.uri;
121
+ }
122
+ // For raw base64, require minimum length (64 chars ~= 48 bytes of data)
123
+ // and must match base64 pattern with proper padding
124
+ if (input.length >= 64 &&
125
+ /^[A-Za-z0-9+/]+={0,2}$/.test(input) &&
126
+ input.length % 4 === 0) {
127
+ const file = await this.upload(input);
128
+ return file.uri;
129
+ }
119
130
  }
120
131
  return input;
121
132
  }
@@ -1,3 +1,4 @@
1
1
  export { TasksAPI, createTasksAPI, RunOptions } from './tasks';
2
2
  export { FilesAPI, createFilesAPI, UploadFileOptions } from './files';
3
3
  export { AgentsAPI, createAgentsAPI, Agent, AgentOptions, SendMessageOptions } from './agents';
4
+ export { SessionsAPI, createSessionsAPI } from './sessions';
package/dist/api/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { TasksAPI, createTasksAPI } from './tasks';
2
2
  export { FilesAPI, createFilesAPI } from './files';
3
3
  export { AgentsAPI, createAgentsAPI, Agent } from './agents';
4
+ export { SessionsAPI, createSessionsAPI } from './sessions';
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Sessions API - namespaced session operations.
3
+ */
4
+ import { HttpClient } from '../http/client';
5
+ import { AppSession } from '../types';
6
+ /**
7
+ * Sessions API for managing stateful worker leases.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const client = new Inference({ apiKey: '...' });
12
+ *
13
+ * // Get session info
14
+ * const info = await client.sessions.get('sess_abc123');
15
+ * console.log(info.status);
16
+ *
17
+ * // List sessions
18
+ * const sessions = await client.sessions.list();
19
+ *
20
+ * // Keep session alive
21
+ * await client.sessions.keepalive('sess_abc123');
22
+ *
23
+ * // End session
24
+ * await client.sessions.end('sess_abc123');
25
+ * ```
26
+ */
27
+ export declare class SessionsAPI {
28
+ private readonly http;
29
+ constructor(http: HttpClient);
30
+ /**
31
+ * Get information about a session.
32
+ *
33
+ * @param sessionId - The session ID
34
+ * @returns Session information
35
+ * @throws SessionNotFoundError if session doesn't exist
36
+ */
37
+ get(sessionId: string): Promise<AppSession>;
38
+ /**
39
+ * List all sessions for the current user/team.
40
+ *
41
+ * @returns List of session information
42
+ */
43
+ list(): Promise<AppSession[]>;
44
+ /**
45
+ * Extend session expiration time.
46
+ *
47
+ * Each call resets the expiration timer (sliding window).
48
+ *
49
+ * @param sessionId - The session ID
50
+ * @returns Updated session information
51
+ * @throws SessionNotFoundError if session doesn't exist
52
+ * @throws SessionExpiredError if session has expired
53
+ * @throws SessionEndedError if session was ended
54
+ */
55
+ keepalive(sessionId: string): Promise<AppSession>;
56
+ /**
57
+ * End a session and release the worker.
58
+ *
59
+ * @param sessionId - The session ID
60
+ * @throws SessionNotFoundError if session doesn't exist
61
+ */
62
+ end(sessionId: string): Promise<void>;
63
+ }
64
+ /**
65
+ * Create a new SessionsAPI instance.
66
+ */
67
+ export declare function createSessionsAPI(http: HttpClient): SessionsAPI;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Sessions API - namespaced session operations.
3
+ */
4
+ /**
5
+ * Sessions API for managing stateful worker leases.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const client = new Inference({ apiKey: '...' });
10
+ *
11
+ * // Get session info
12
+ * const info = await client.sessions.get('sess_abc123');
13
+ * console.log(info.status);
14
+ *
15
+ * // List sessions
16
+ * const sessions = await client.sessions.list();
17
+ *
18
+ * // Keep session alive
19
+ * await client.sessions.keepalive('sess_abc123');
20
+ *
21
+ * // End session
22
+ * await client.sessions.end('sess_abc123');
23
+ * ```
24
+ */
25
+ export class SessionsAPI {
26
+ constructor(http) {
27
+ this.http = http;
28
+ }
29
+ /**
30
+ * Get information about a session.
31
+ *
32
+ * @param sessionId - The session ID
33
+ * @returns Session information
34
+ * @throws SessionNotFoundError if session doesn't exist
35
+ */
36
+ async get(sessionId) {
37
+ return this.http.request('get', `/sessions/${sessionId}`);
38
+ }
39
+ /**
40
+ * List all sessions for the current user/team.
41
+ *
42
+ * @returns List of session information
43
+ */
44
+ async list() {
45
+ const data = await this.http.request('get', '/sessions');
46
+ return data || [];
47
+ }
48
+ /**
49
+ * Extend session expiration time.
50
+ *
51
+ * Each call resets the expiration timer (sliding window).
52
+ *
53
+ * @param sessionId - The session ID
54
+ * @returns Updated session information
55
+ * @throws SessionNotFoundError if session doesn't exist
56
+ * @throws SessionExpiredError if session has expired
57
+ * @throws SessionEndedError if session was ended
58
+ */
59
+ async keepalive(sessionId) {
60
+ return this.http.request('post', `/sessions/${sessionId}/keepalive`);
61
+ }
62
+ /**
63
+ * End a session and release the worker.
64
+ *
65
+ * @param sessionId - The session ID
66
+ * @throws SessionNotFoundError if session doesn't exist
67
+ */
68
+ async end(sessionId) {
69
+ await this.http.request('delete', `/sessions/${sessionId}`);
70
+ }
71
+ }
72
+ /**
73
+ * Create a new SessionsAPI instance.
74
+ */
75
+ export function createSessionsAPI(http) {
76
+ return new SessionsAPI(http);
77
+ }
package/dist/api/tasks.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { StreamManager } from '../http/stream';
2
2
  import { TaskStatusCompleted, TaskStatusFailed, TaskStatusCancelled, } from '../types';
3
+ //TODO: This is ugly...
3
4
  function stripTask(task) {
4
5
  return {
5
6
  ...task,
@@ -10,6 +11,7 @@ function stripTask(task) {
10
11
  output: task.output,
11
12
  logs: task.logs,
12
13
  status: task.status,
14
+ session_id: task.session_id,
13
15
  };
14
16
  }
15
17
  /**
@@ -77,6 +79,8 @@ export class TasksAPI {
77
79
  return stripTask(task);
78
80
  }
79
81
  // Wait for completion with optional updates
82
+ // Accumulate state across partial updates to preserve fields like session_id
83
+ let accumulatedTask = { ...task };
80
84
  return new Promise((resolve, reject) => {
81
85
  const streamManager = new StreamManager({
82
86
  createEventSource: async () => this.http.createEventSource(`/tasks/${task.id}/stream`),
@@ -84,7 +88,9 @@ export class TasksAPI {
84
88
  maxReconnects,
85
89
  reconnectDelayMs,
86
90
  onData: (data) => {
87
- const stripped = stripTask(data);
91
+ // Merge new data, preserving existing fields if not in update
92
+ accumulatedTask = { ...accumulatedTask, ...data };
93
+ const stripped = stripTask(accumulatedTask);
88
94
  onUpdate?.(stripped);
89
95
  if (data.status === TaskStatusCompleted) {
90
96
  streamManager.stop();
@@ -100,7 +106,9 @@ export class TasksAPI {
100
106
  }
101
107
  },
102
108
  onPartialData: (data, fields) => {
103
- const stripped = stripTask(data);
109
+ // Merge partial update, preserving fields not in this update
110
+ accumulatedTask = { ...accumulatedTask, ...data };
111
+ const stripped = stripTask(accumulatedTask);
104
112
  onPartialUpdate?.(stripped, fields);
105
113
  if (data.status === TaskStatusCompleted) {
106
114
  streamManager.stop();
@@ -135,6 +135,10 @@ export class HttpClient {
135
135
  }
136
136
  throw new InferenceError(response.status, errorDetail || 'Request failed', responseText);
137
137
  }
138
+ // Handle 204 No Content (e.g., DELETE requests)
139
+ if (response.status === 204) {
140
+ return undefined;
141
+ }
138
142
  const apiResponse = data;
139
143
  if (!apiResponse?.success) {
140
144
  let errorMessage = apiResponse?.error?.message;
@@ -48,3 +48,85 @@ export declare class RequirementsNotMetException extends Error {
48
48
  errors?: RequirementError[];
49
49
  }, statusCode?: number): RequirementsNotMetException;
50
50
  }
51
+ /**
52
+ * Base class for session-related errors.
53
+ */
54
+ export declare class SessionError extends InferenceError {
55
+ readonly sessionId: string;
56
+ constructor(sessionId: string, statusCode: number, message: string, responseBody?: string);
57
+ }
58
+ /**
59
+ * Error thrown when a session doesn't exist (404 SESSION_NOT_FOUND).
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * try {
64
+ * await client.sessions.get('sess_invalid');
65
+ * } catch (e) {
66
+ * if (e instanceof SessionNotFoundError) {
67
+ * console.log('Session not found');
68
+ * }
69
+ * }
70
+ * ```
71
+ */
72
+ export declare class SessionNotFoundError extends SessionError {
73
+ constructor(sessionId: string, responseBody?: string);
74
+ }
75
+ /**
76
+ * Error thrown when a session has expired (410 SESSION_EXPIRED).
77
+ *
78
+ * Sessions expire after an idle timeout (default: 5 minutes).
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * try {
83
+ * const result = await client.run({ ..., session: sessionId });
84
+ * } catch (e) {
85
+ * if (e instanceof SessionExpiredError) {
86
+ * // Create new session
87
+ * const result = await client.run({ ..., session: 'new' });
88
+ * }
89
+ * }
90
+ * ```
91
+ */
92
+ export declare class SessionExpiredError extends SessionError {
93
+ constructor(sessionId: string, responseBody?: string);
94
+ }
95
+ /**
96
+ * Error thrown when a session was explicitly ended (410 SESSION_ENDED).
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * try {
101
+ * const result = await client.run({ ..., session: sessionId });
102
+ * } catch (e) {
103
+ * if (e instanceof SessionEndedError) {
104
+ * // Create new session
105
+ * const result = await client.run({ ..., session: 'new' });
106
+ * }
107
+ * }
108
+ * ```
109
+ */
110
+ export declare class SessionEndedError extends SessionError {
111
+ constructor(sessionId: string, responseBody?: string);
112
+ }
113
+ /**
114
+ * Error thrown when the worker assigned to a session is lost.
115
+ *
116
+ * This can happen if the worker crashes or is terminated unexpectedly.
117
+ *
118
+ * @example
119
+ * ```typescript
120
+ * try {
121
+ * const result = await client.run({ ..., session: sessionId });
122
+ * } catch (e) {
123
+ * if (e instanceof WorkerLostError) {
124
+ * // Worker crashed, create new session
125
+ * const result = await client.run({ ..., session: 'new' });
126
+ * }
127
+ * }
128
+ * ```
129
+ */
130
+ export declare class WorkerLostError extends SessionError {
131
+ constructor(sessionId: string, responseBody?: string);
132
+ }
@@ -54,3 +54,101 @@ export class RequirementsNotMetException extends Error {
54
54
  return new RequirementsNotMetException(data.errors || [], statusCode);
55
55
  }
56
56
  }
57
+ // Session-specific errors
58
+ /**
59
+ * Base class for session-related errors.
60
+ */
61
+ export class SessionError extends InferenceError {
62
+ constructor(sessionId, statusCode, message, responseBody) {
63
+ super(statusCode, message, responseBody);
64
+ this.name = 'SessionError';
65
+ this.sessionId = sessionId;
66
+ }
67
+ }
68
+ /**
69
+ * Error thrown when a session doesn't exist (404 SESSION_NOT_FOUND).
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * try {
74
+ * await client.sessions.get('sess_invalid');
75
+ * } catch (e) {
76
+ * if (e instanceof SessionNotFoundError) {
77
+ * console.log('Session not found');
78
+ * }
79
+ * }
80
+ * ```
81
+ */
82
+ export class SessionNotFoundError extends SessionError {
83
+ constructor(sessionId, responseBody) {
84
+ super(sessionId, 404, `Session not found: ${sessionId}`, responseBody);
85
+ this.name = 'SessionNotFoundError';
86
+ }
87
+ }
88
+ /**
89
+ * Error thrown when a session has expired (410 SESSION_EXPIRED).
90
+ *
91
+ * Sessions expire after an idle timeout (default: 5 minutes).
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * try {
96
+ * const result = await client.run({ ..., session: sessionId });
97
+ * } catch (e) {
98
+ * if (e instanceof SessionExpiredError) {
99
+ * // Create new session
100
+ * const result = await client.run({ ..., session: 'new' });
101
+ * }
102
+ * }
103
+ * ```
104
+ */
105
+ export class SessionExpiredError extends SessionError {
106
+ constructor(sessionId, responseBody) {
107
+ super(sessionId, 410, `Session expired: ${sessionId}`, responseBody);
108
+ this.name = 'SessionExpiredError';
109
+ }
110
+ }
111
+ /**
112
+ * Error thrown when a session was explicitly ended (410 SESSION_ENDED).
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * try {
117
+ * const result = await client.run({ ..., session: sessionId });
118
+ * } catch (e) {
119
+ * if (e instanceof SessionEndedError) {
120
+ * // Create new session
121
+ * const result = await client.run({ ..., session: 'new' });
122
+ * }
123
+ * }
124
+ * ```
125
+ */
126
+ export class SessionEndedError extends SessionError {
127
+ constructor(sessionId, responseBody) {
128
+ super(sessionId, 410, `Session ended: ${sessionId}`, responseBody);
129
+ this.name = 'SessionEndedError';
130
+ }
131
+ }
132
+ /**
133
+ * Error thrown when the worker assigned to a session is lost.
134
+ *
135
+ * This can happen if the worker crashes or is terminated unexpectedly.
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * try {
140
+ * const result = await client.run({ ..., session: sessionId });
141
+ * } catch (e) {
142
+ * if (e instanceof WorkerLostError) {
143
+ * // Worker crashed, create new session
144
+ * const result = await client.run({ ..., session: 'new' });
145
+ * }
146
+ * }
147
+ * ```
148
+ */
149
+ export class WorkerLostError extends SessionError {
150
+ constructor(sessionId, responseBody) {
151
+ super(sessionId, 500, `Worker lost for session: ${sessionId}`, responseBody);
152
+ this.name = 'WorkerLostError';
153
+ }
154
+ }
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  export { HttpClient, HttpClientConfig, ErrorHandler, createHttpClient } from './http/client';
2
2
  export { StreamManager, StreamManagerOptions, PartialDataWrapper } from './http/stream';
3
- export { InferenceError, RequirementsNotMetException } from './http/errors';
3
+ export { InferenceError, RequirementsNotMetException, SessionError, SessionNotFoundError, SessionExpiredError, SessionEndedError, WorkerLostError, } from './http/errors';
4
4
  export { TasksAPI, RunOptions } from './api/tasks';
5
5
  export { FilesAPI, UploadFileOptions } from './api/files';
6
6
  export { AgentsAPI, Agent, AgentOptions, SendMessageOptions } from './api/agents';
7
+ export { SessionsAPI } from './api/sessions';
7
8
  export { AppsAPI } from './api/apps';
8
9
  export { ChatsAPI } from './api/chats';
9
10
  export { FlowsAPI } from './api/flows';
@@ -17,6 +18,7 @@ import { HttpClient, HttpClientConfig } from './http/client';
17
18
  import { TasksAPI, RunOptions } from './api/tasks';
18
19
  import { FilesAPI, UploadFileOptions } from './api/files';
19
20
  import { AgentsAPI, Agent, AgentOptions } from './api/agents';
21
+ import { SessionsAPI } from './api/sessions';
20
22
  import { AppsAPI } from './api/apps';
21
23
  import { ChatsAPI } from './api/chats';
22
24
  import { FlowsAPI } from './api/flows';
@@ -48,6 +50,7 @@ export declare class Inference {
48
50
  readonly tasks: TasksAPI;
49
51
  readonly files: FilesAPI;
50
52
  readonly agents: AgentsAPI;
53
+ readonly sessions: SessionsAPI;
51
54
  readonly apps: AppsAPI;
52
55
  readonly chats: ChatsAPI;
53
56
  readonly flows: FlowsAPI;
package/dist/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  // HTTP utilities
2
2
  export { HttpClient, createHttpClient } from './http/client';
3
3
  export { StreamManager } from './http/stream';
4
- export { InferenceError, RequirementsNotMetException } from './http/errors';
4
+ export { InferenceError, RequirementsNotMetException, SessionError, SessionNotFoundError, SessionExpiredError, SessionEndedError, WorkerLostError, } from './http/errors';
5
5
  // API modules
6
6
  export { TasksAPI } from './api/tasks';
7
7
  export { FilesAPI } from './api/files';
8
8
  export { AgentsAPI, Agent } from './api/agents';
9
+ export { SessionsAPI } from './api/sessions';
9
10
  export { AppsAPI } from './api/apps';
10
11
  export { ChatsAPI } from './api/chats';
11
12
  export { FlowsAPI } from './api/flows';
@@ -22,6 +23,7 @@ import { HttpClient } from './http/client';
22
23
  import { TasksAPI } from './api/tasks';
23
24
  import { FilesAPI } from './api/files';
24
25
  import { AgentsAPI } from './api/agents';
26
+ import { SessionsAPI } from './api/sessions';
25
27
  import { AppsAPI } from './api/apps';
26
28
  import { ChatsAPI } from './api/chats';
27
29
  import { FlowsAPI } from './api/flows';
@@ -51,6 +53,7 @@ export class Inference {
51
53
  this.files = new FilesAPI(this.http);
52
54
  this.tasks = new TasksAPI(this.http);
53
55
  this.agents = new AgentsAPI(this.http, this.files);
56
+ this.sessions = new SessionsAPI(this.http);
54
57
  this.apps = new AppsAPI(this.http);
55
58
  this.chats = new ChatsAPI(this.http);
56
59
  this.flows = new FlowsAPI(this.http);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Sessions 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
+ * Prerequisites:
8
+ * - API and scheduler must be running
9
+ * - Test app deployed: infsh/session-test
10
+ *
11
+ * @jest-environment node
12
+ */
13
+ export {};