@inferencesh/sdk 0.5.1 → 0.5.3

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.
@@ -48,7 +48,8 @@ export function createActions(ctx) {
48
48
  if (!handler) {
49
49
  console.warn(`[AgentSDK] No handler for client tool: ${functionName}`);
50
50
  api.submitToolResult(client, invocation.id, JSON.stringify({
51
- error: `No handler registered for tool: ${functionName}`
51
+ status: 'not_available',
52
+ message: `Client tool "${functionName}" is not available in this environment`,
52
53
  }));
53
54
  continue;
54
55
  }
@@ -77,10 +78,19 @@ export function createActions(ctx) {
77
78
  setStreamManager(undefined);
78
79
  dispatch({ type: 'SET_STATUS', payload: 'connecting' });
79
80
  callbacks.onStatusChange?.('connecting');
80
- // Fetch initial chat
81
- const chat = await api.fetchChat(client, id);
82
- if (chat) {
83
- setChat(chat);
81
+ try {
82
+ // Fetch initial chat
83
+ const chat = await api.fetchChat(client, id);
84
+ if (chat) {
85
+ setChat(chat);
86
+ }
87
+ }
88
+ catch (error) {
89
+ console.error('[AgentSDK] Failed to fetch chat:', error);
90
+ dispatch({ type: 'SET_STATUS', payload: 'idle' });
91
+ dispatch({ type: 'SET_IS_GENERATING', payload: false });
92
+ callbacks.onStatusChange?.('idle');
93
+ return;
84
94
  }
85
95
  // Single unified stream with TypedEvents (both Chat and ChatMessage events)
86
96
  const manager = new StreamManager({
@@ -96,6 +106,17 @@ export function createActions(ctx) {
96
106
  dispatch({ type: 'SET_STATUS', payload: 'streaming' });
97
107
  callbacks.onStatusChange?.('streaming');
98
108
  },
109
+ onStop: () => {
110
+ // Only reset if this is an unexpected stop (stream died, max reconnects exhausted).
111
+ // If stopStream() was called intentionally, it clears the manager ref first,
112
+ // so getStreamManager() will be undefined and we skip the duplicate dispatch.
113
+ if (getStreamManager()) {
114
+ setStreamManager(undefined);
115
+ dispatch({ type: 'SET_STATUS', payload: 'idle' });
116
+ dispatch({ type: 'SET_IS_GENERATING', payload: false });
117
+ callbacks.onStatusChange?.('idle');
118
+ }
119
+ },
99
120
  });
100
121
  // Listen for Chat object updates (status changes)
101
122
  manager.addEventListener('chats', (chatData) => {
@@ -110,10 +131,11 @@ export function createActions(ctx) {
110
131
  };
111
132
  const stopStream = () => {
112
133
  const manager = getStreamManager();
134
+ // Clear ref first so onStop callback (from manager.stop) is a no-op
135
+ setStreamManager(undefined);
113
136
  if (manager) {
114
137
  manager.stop();
115
138
  }
116
- setStreamManager(undefined);
117
139
  dispatch({ type: 'SET_STATUS', payload: 'idle' });
118
140
  dispatch({ type: 'SET_IS_GENERATING', payload: false });
119
141
  callbacks.onStatusChange?.('idle');
@@ -150,6 +172,12 @@ export function createActions(ctx) {
150
172
  streamChat(newChatId);
151
173
  }
152
174
  }
175
+ else {
176
+ // API returned no result — reset status so we don't get stuck
177
+ dispatch({ type: 'SET_STATUS', payload: 'idle' });
178
+ dispatch({ type: 'SET_IS_GENERATING', payload: false });
179
+ callbacks.onStatusChange?.('idle');
180
+ }
153
181
  }
154
182
  catch (error) {
155
183
  console.error('[AgentSDK] Failed to send message:', error);
package/dist/agent/api.js CHANGED
@@ -24,6 +24,7 @@ export async function sendAdHocMessage(client, config, chatId, text, imageUris,
24
24
  system_prompt: config.system_prompt ?? '',
25
25
  tools: toolSchemas
26
26
  },
27
+ agent_name: config.name,
27
28
  input: {
28
29
  text,
29
30
  images: imageUris,
@@ -27,7 +27,7 @@ import type { AgentChatProviderProps } from './types';
27
27
  * }
28
28
  * ```
29
29
  */
30
- export declare function AgentChatProvider({ client, agentConfig, chatId, onChatCreated, onStatusChange, onError, children, }: AgentChatProviderProps): import("react/jsx-runtime").JSX.Element;
30
+ export declare function AgentChatProvider({ client, agentConfig, chatId, clientToolHandlers: extraHandlers, onChatCreated, onStatusChange, onError, children, }: AgentChatProviderProps): import("react/jsx-runtime").JSX.Element;
31
31
  export declare namespace AgentChatProvider {
32
32
  var displayName: string;
33
33
  }
@@ -9,6 +9,14 @@ import { useReducer, useRef, useEffect, useMemo } from 'react';
9
9
  import { AgentChatContext } from './context';
10
10
  import { chatReducer, initialState } from './reducer';
11
11
  import { createActions, getClientToolHandlers } from './actions';
12
+ function mergeHandlers(base, extra) {
13
+ if (!extra || extra.size === 0)
14
+ return base;
15
+ const merged = new Map(base);
16
+ for (const [k, v] of extra)
17
+ merged.set(k, v);
18
+ return merged;
19
+ }
12
20
  /**
13
21
  * AgentChatProvider - Provides chat state and actions to children
14
22
  *
@@ -31,20 +39,20 @@ import { createActions, getClientToolHandlers } from './actions';
31
39
  * }
32
40
  * ```
33
41
  */
34
- export function AgentChatProvider({ client, agentConfig, chatId, onChatCreated, onStatusChange, onError, children, }) {
42
+ export function AgentChatProvider({ client, agentConfig, chatId, clientToolHandlers: extraHandlers, onChatCreated, onStatusChange, onError, children, }) {
35
43
  // Core state via useReducer
36
44
  const [state, dispatch] = useReducer(chatReducer, initialState);
37
45
  // Refs for mutable values that actions need access to
38
46
  const configRef = useRef(agentConfig);
39
47
  const chatIdRef = useRef(chatId ?? null);
40
48
  const streamManagerRef = useRef(undefined);
41
- const clientToolHandlersRef = useRef(getClientToolHandlers(agentConfig));
49
+ const clientToolHandlersRef = useRef(mergeHandlers(getClientToolHandlers(agentConfig), extraHandlers));
42
50
  const callbacksRef = useRef({ onChatCreated, onStatusChange, onError });
43
51
  // Keep refs in sync with props
44
52
  useEffect(() => {
45
53
  configRef.current = agentConfig;
46
- clientToolHandlersRef.current = getClientToolHandlers(agentConfig);
47
- }, [agentConfig]);
54
+ clientToolHandlersRef.current = mergeHandlers(getClientToolHandlers(agentConfig), extraHandlers);
55
+ }, [agentConfig, extraHandlers]);
48
56
  useEffect(() => {
49
57
  callbacksRef.current = { onChatCreated, onStatusChange, onError };
50
58
  }, [onChatCreated, onStatusChange, onError]);
@@ -134,6 +134,8 @@ export interface AgentChatProviderProps {
134
134
  agentConfig: AgentOptions;
135
135
  /** Optional existing chat ID to continue */
136
136
  chatId?: string;
137
+ /** Extra client tool handlers, merged with any from agentConfig. Use with TemplateAgentConfig to handle tools defined server-side. */
138
+ clientToolHandlers?: Map<string, ClientToolHandlerFn>;
137
139
  /** Callback when a new chat is created */
138
140
  onChatCreated?: (chatId: string) => void;
139
141
  /** Callback when chat status changes */
@@ -56,7 +56,7 @@ export class Agent {
56
56
  : {
57
57
  chat_id: this.chatId,
58
58
  agent_config: this.config,
59
- agent_name: this.agentName,
59
+ agent_name: this.agentName ?? this.config.name,
60
60
  input: { text, images: imageUris, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 },
61
61
  };
62
62
  // For existing chats with callbacks: Start streaming BEFORE POST so we don't miss updates
@@ -39,7 +39,6 @@ describeIfApiKey('Sessions Integration Tests', () => {
39
39
  expect(result.status).toBe(TaskStatusCompleted);
40
40
  expect(result.session_id).toBeDefined();
41
41
  expect(result.session_id).not.toBe('new');
42
- expect(result.session_id).toMatch(/^sess_/);
43
42
  }, 60000);
44
43
  it('should return correct output data', async () => {
45
44
  const result = await client.run({
@@ -69,7 +68,6 @@ describeIfApiKey('Sessions Integration Tests', () => {
69
68
  });
70
69
  expect(result1.status).toBe(TaskStatusCompleted);
71
70
  const sessionId = result1.session_id;
72
- expect(sessionId).toMatch(/^sess_/);
73
71
  // Retrieve value from same session
74
72
  const result2 = await client.run({
75
73
  app: SESSION_TEST_APP,
package/dist/types.d.ts CHANGED
@@ -7,6 +7,7 @@ export interface InternalToolsConfig {
7
7
  widget?: boolean;
8
8
  finish?: boolean;
9
9
  skills?: boolean;
10
+ host_context?: boolean;
10
11
  }
11
12
  /**
12
13
  * ToolType represents the type of tool (used in both AgentTool definition and ToolInvocation)
@@ -170,7 +171,7 @@ export interface ClientToolConfigDTO {
170
171
  */
171
172
  export interface CoreAppConfig {
172
173
  id?: string;
173
- version?: string;
174
+ version_id?: string;
174
175
  /**
175
176
  * CoreAppRef is the user-facing ref (namespace/name@shortid) - used in ad-hoc configs, resolved at creation
176
177
  */
@@ -235,6 +236,11 @@ export interface SkillConfig {
235
236
  * Using Go embedding flattens these fields in JSON serialization.
236
237
  */
237
238
  export interface AgentConfig {
239
+ /**
240
+ * Optional name for the agent (used for adhoc agent deduplication — reuses existing agent by name).
241
+ * Not persisted as a DB column; only used in API requests.
242
+ */
243
+ name?: string;
238
244
  description?: string;
239
245
  system_prompt?: string;
240
246
  example_prompts?: string[];
@@ -268,7 +274,7 @@ export interface AgentVersion extends BaseModel, PermissionModel {
268
274
  }
269
275
  export interface CoreAppConfigDTO {
270
276
  id?: string;
271
- version?: string;
277
+ version_id?: string;
272
278
  ref?: string;
273
279
  app?: AppDTO;
274
280
  /**
@@ -330,7 +336,7 @@ export interface ApiAppRunRequest {
330
336
  */
331
337
  app?: string;
332
338
  /**
333
- * Alternative: specify app by ID (for internal use)
339
+ * Deprecated: use App ref instead. Direct ID bypasses ref routing.
334
340
  */
335
341
  app_id?: string;
336
342
  version_id?: string;
@@ -391,6 +397,16 @@ export interface ApiAgentRunRequest {
391
397
  */
392
398
  stream?: boolean;
393
399
  }
400
+ /**
401
+ * EmbedAgentRunRequest is the embed variant of ApiAgentRunRequest.
402
+ * Only template agents are supported (no ad-hoc configs).
403
+ */
404
+ export interface EmbedAgentRunRequest {
405
+ chat_id?: string;
406
+ agent: string;
407
+ input: ChatTaskInput;
408
+ stream?: boolean;
409
+ }
394
410
  export interface CreateAgentMessageRequest {
395
411
  chat_id?: string;
396
412
  agent_id?: string;
@@ -503,6 +519,26 @@ export interface CreateAgentRequest {
503
519
  */
504
520
  export interface SDKTypes {
505
521
  }
522
+ export interface SkillPublishRequest {
523
+ name: string;
524
+ description: string;
525
+ category: string;
526
+ repo_url: string;
527
+ license: string;
528
+ allowed_tools: string;
529
+ compatibility: string;
530
+ instructions: string;
531
+ files: SkillFile[];
532
+ metadata?: {
533
+ [key: string]: string;
534
+ };
535
+ /**
536
+ * Spec fields for roundtrip fidelity
537
+ */
538
+ disable_model_invocation: boolean;
539
+ user_invocable?: boolean;
540
+ context: string;
541
+ }
506
542
  export interface CheckoutCreateRequest {
507
543
  amount: number;
508
544
  success_url: string;
@@ -1253,6 +1289,19 @@ export interface WorkerStateSummary {
1253
1289
  cpus: WorkerCPU[];
1254
1290
  rams: WorkerRAM[];
1255
1291
  }
1292
+ /**
1293
+ * FileMetadata holds probed media metadata cached on File records.
1294
+ */
1295
+ export interface FileMetadata {
1296
+ type?: string;
1297
+ width?: number;
1298
+ height?: number;
1299
+ duration?: number;
1300
+ fps?: number;
1301
+ sample_rate?: number;
1302
+ channels?: number;
1303
+ codec?: string;
1304
+ }
1256
1305
  export interface File extends BaseModel, PermissionModel {
1257
1306
  path: string;
1258
1307
  remote_path: string;
@@ -1262,6 +1311,7 @@ export interface File extends BaseModel, PermissionModel {
1262
1311
  size: number;
1263
1312
  filename: string;
1264
1313
  rating: ContentRating;
1314
+ metadata?: FileMetadata;
1265
1315
  }
1266
1316
  export interface FileDTO extends BaseModel, PermissionModelDTO {
1267
1317
  path: string;
@@ -1272,6 +1322,7 @@ export interface FileDTO extends BaseModel, PermissionModelDTO {
1272
1322
  size: number;
1273
1323
  filename: string;
1274
1324
  rating: ContentRating;
1325
+ metadata?: FileMetadata;
1275
1326
  }
1276
1327
  export interface FlowVersion extends BaseModel {
1277
1328
  /**
@@ -1725,6 +1776,16 @@ export interface InstanceEnvVar {
1725
1776
  name: string;
1726
1777
  value: string;
1727
1778
  }
1779
+ /**
1780
+ * SkillFile represents a file in the skill directory (stored as JSONB in skill_versions)
1781
+ */
1782
+ export interface SkillFile {
1783
+ path: string;
1784
+ uri?: string;
1785
+ size: number;
1786
+ hash: string;
1787
+ content?: string;
1788
+ }
1728
1789
  /**
1729
1790
  * Hardware/System related types
1730
1791
  */
@@ -2072,6 +2133,7 @@ export interface ToolInvocationDTO extends BaseModel, PermissionModelDTO {
2072
2133
  chat_message_id: string;
2073
2134
  tool_invocation_id: string;
2074
2135
  type: ToolType;
2136
+ display_name?: string;
2075
2137
  execution_id?: string;
2076
2138
  function: ToolInvocationFunction;
2077
2139
  status: ToolInvocationStatus;
@@ -2130,6 +2192,12 @@ export interface Transaction extends BaseModel {
2130
2192
  metadata: {
2131
2193
  [key: string]: any;
2132
2194
  };
2195
+ /**
2196
+ * SideEffectsProcessed tracks whether side effects (notifications, auto-recharge,
2197
+ * billing status changes) have been processed for this transaction.
2198
+ * Set to true via WithSkipTxSideEffects context to skip side effects (e.g. migrations).
2199
+ */
2200
+ side_effects_processed: boolean;
2133
2201
  }
2134
2202
  /**
2135
2203
  * PaymentRecordStatus represents the status of a payment
@@ -2152,6 +2220,7 @@ export interface PaymentRecord extends BaseModel, PermissionModel {
2152
2220
  type: PaymentRecordType;
2153
2221
  status: PaymentRecordStatus;
2154
2222
  amount: number;
2223
+ service_fee: number;
2155
2224
  stripe_customer_id: string;
2156
2225
  payment_intent_id: string;
2157
2226
  receipt_url: string;
@@ -2239,6 +2308,13 @@ export interface UsageEvent extends BaseModel, PermissionModel {
2239
2308
  quantity: number;
2240
2309
  unit: string;
2241
2310
  }
2311
+ /**
2312
+ * DiscountItem represents a single discount applied to a billing record
2313
+ */
2314
+ export interface DiscountItem {
2315
+ reason: string;
2316
+ amount: number;
2317
+ }
2242
2318
  export interface UsageBillingRecord extends BaseModel, PermissionModel {
2243
2319
  /**
2244
2320
  * Fee breakdown (all in microcents)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inferencesh/sdk",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
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",