@inferencesh/sdk 0.6.6 → 0.6.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.
- package/CHANGELOG.md +26 -1
- package/README.md +236 -36
- package/dist/agent/actions.test.d.ts +1 -0
- package/dist/agent/actions.test.js +404 -0
- package/dist/agent/api.test.d.ts +1 -0
- package/dist/agent/api.test.js +130 -0
- package/dist/agent/reducer.test.js +4 -0
- package/dist/agent/types.test.d.ts +1 -0
- package/dist/agent/types.test.js +75 -0
- package/dist/api/agents.test.js +258 -0
- package/dist/api/sessions.d.ts +2 -1
- package/dist/api/sessions.js +2 -1
- package/dist/api/sessions.test.d.ts +1 -0
- package/dist/api/sessions.test.js +49 -0
- package/dist/api/tasks.test.js +14 -0
- package/dist/stream.test.js +139 -0
- package/dist/tool-builder.test.js +69 -2
- package/dist/types.d.ts +48 -12
- package/dist/types.js +32 -8
- package/package.json +11 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Typed SDK constants for integrations: `IntegrationProvider*`, `IntegrationAuthType*`, `IntegrationStatus*`
|
|
13
|
+
- `IntegrationDTO` fields (`provider`, `type`, `auth`, `status`) now use those typed aliases
|
|
14
|
+
- Additional `InstanceStatus*` constants (`creating`, `pending_provider`, `error`, `deleting`)
|
|
15
|
+
- `ToolParamType*` constants for JSON Schema tool parameter types (distinct from `ToolCallType`)
|
|
16
|
+
|
|
17
|
+
## [0.6.7] - 2026-05-19
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- `client.sessions` API: `get`, `list`, `keepalive`, and `end` for session lifecycle management
|
|
22
|
+
- Session error types: `SessionNotFoundError`, `SessionExpiredError`, `SessionEndedError`
|
|
23
|
+
- Agent chat: `sendMessage` file attachments (upload `Blob` or reuse uploaded file `uri`)
|
|
24
|
+
- Agent lifecycle: `stopChat()`, `reset()`, and `agent.run()` for structured output via polling
|
|
25
|
+
- Task streaming: `onPartialUpdate` callback for partial NDJSON stream payloads
|
|
26
|
+
- Client config: `stream` and `pollIntervalMs` for global streaming vs status polling
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- README documents ad-hoc agent field names (`core_app`, `system_prompt`) and tool builder API
|
|
31
|
+
- Polling mode: `run()` rejects if full task fetch fails after a status transition
|
|
32
|
+
|
|
10
33
|
## [0.1.1] - 2024-11-30
|
|
11
34
|
|
|
12
35
|
### Added
|
|
@@ -42,6 +65,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
42
65
|
- Configurable reconnection behavior
|
|
43
66
|
- Comprehensive error handling
|
|
44
67
|
|
|
45
|
-
[Unreleased]: https://github.com/inference-sh/sdk-js/compare/v0.
|
|
68
|
+
[Unreleased]: https://github.com/inference-sh/sdk-js/compare/v0.6.7...HEAD
|
|
69
|
+
[0.6.7]: https://github.com/inference-sh/sdk-js/compare/v0.6.6...v0.6.7
|
|
70
|
+
[0.1.1]: https://github.com/inference-sh/sdk-js/compare/v0.1.0...v0.1.1
|
|
46
71
|
[0.1.0]: https://github.com/inference-sh/sdk-js/releases/tag/v0.1.0
|
|
47
72
|
|
package/README.md
CHANGED
|
@@ -90,18 +90,43 @@ console.log('Status:', task.status);
|
|
|
90
90
|
|
|
91
91
|
### Real-time Status Updates
|
|
92
92
|
|
|
93
|
+
By default, the client streams task progress over NDJSON (`/tasks/{id}/stream`) and invokes `onUpdate` as the task changes. Use `onPartialUpdate` when you only need specific fields from a partial stream payload:
|
|
94
|
+
|
|
93
95
|
```typescript
|
|
94
|
-
const result = await client.
|
|
96
|
+
const result = await client.run(
|
|
95
97
|
{ app: 'my-app', input: { prompt: 'hello' } },
|
|
96
98
|
{
|
|
97
99
|
onUpdate: (update) => {
|
|
98
100
|
console.log('Status:', update.status);
|
|
99
101
|
console.log('Progress:', update.logs);
|
|
100
|
-
}
|
|
102
|
+
},
|
|
103
|
+
onPartialUpdate: (update, fields) => {
|
|
104
|
+
console.log('Changed fields:', fields, update.status);
|
|
105
|
+
},
|
|
101
106
|
}
|
|
102
107
|
);
|
|
103
108
|
```
|
|
104
109
|
|
|
110
|
+
### Streaming vs Polling
|
|
111
|
+
|
|
112
|
+
SSE/NDJSON streaming is the default. For edge runtimes that cannot keep long-lived connections open (Convex actions, Cloudflare Workers, etc.), disable streaming and use lightweight status polling instead:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const client = inference({
|
|
116
|
+
apiKey: 'your-api-key',
|
|
117
|
+
stream: false, // poll /tasks/{id}/status instead of streaming
|
|
118
|
+
pollIntervalMs: 2000, // default: 2000
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Per-call override
|
|
122
|
+
const result = await client.run(
|
|
123
|
+
{ app: 'my-app', input: { prompt: 'hello' } },
|
|
124
|
+
{ stream: false, onUpdate: (u) => console.log(u.status) }
|
|
125
|
+
);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
In polling mode, the SDK checks `/tasks/{id}/status` and fetches the full task when the status changes. If that fetch fails after a status transition, `run()` rejects with the underlying error.
|
|
129
|
+
|
|
105
130
|
### Batch Processing
|
|
106
131
|
|
|
107
132
|
```typescript
|
|
@@ -196,6 +221,58 @@ const result = await client.tasks.run({
|
|
|
196
221
|
- Maximum timeout: 3600 seconds (1 hour)
|
|
197
222
|
- Each successful call resets the idle timer
|
|
198
223
|
|
|
224
|
+
#### Session management API
|
|
225
|
+
|
|
226
|
+
Manage sessions directly without running a task:
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// Inspect a session
|
|
230
|
+
const info = await client.sessions.get(sessionId);
|
|
231
|
+
console.log(info.status, info.expires_at, info.call_count);
|
|
232
|
+
|
|
233
|
+
// List active sessions
|
|
234
|
+
const sessions = await client.sessions.list();
|
|
235
|
+
|
|
236
|
+
// Extend idle timeout without a task call (sliding window)
|
|
237
|
+
await client.sessions.keepalive(sessionId);
|
|
238
|
+
|
|
239
|
+
// Release the worker immediately
|
|
240
|
+
await client.sessions.end(sessionId);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### Session errors
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import {
|
|
247
|
+
SessionNotFoundError,
|
|
248
|
+
SessionExpiredError,
|
|
249
|
+
SessionEndedError,
|
|
250
|
+
} from '@inferencesh/sdk';
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
await client.tasks.run({
|
|
254
|
+
app: 'my-stateful-app',
|
|
255
|
+
input: { prompt: 'hello' },
|
|
256
|
+
session: sessionId,
|
|
257
|
+
});
|
|
258
|
+
} catch (error) {
|
|
259
|
+
if (
|
|
260
|
+
error instanceof SessionNotFoundError ||
|
|
261
|
+
error instanceof SessionExpiredError ||
|
|
262
|
+
error instanceof SessionEndedError
|
|
263
|
+
) {
|
|
264
|
+
// Start a new session and retry
|
|
265
|
+
const result = await client.tasks.run({
|
|
266
|
+
app: 'my-stateful-app',
|
|
267
|
+
input: { prompt: 'hello' },
|
|
268
|
+
session: 'new',
|
|
269
|
+
});
|
|
270
|
+
} else {
|
|
271
|
+
throw error;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
199
276
|
For complete session documentation including error handling, best practices, and advanced patterns, see the [Sessions Developer Guide](https://inference.sh/docs/extend/sessions).
|
|
200
277
|
|
|
201
278
|
## Agent Chat
|
|
@@ -240,27 +317,42 @@ import { inference, tool, string } from '@inferencesh/sdk';
|
|
|
240
317
|
|
|
241
318
|
const client = inference({ apiKey: 'your-api-key' });
|
|
242
319
|
|
|
243
|
-
// Create ad-hoc agent
|
|
320
|
+
// Create ad-hoc agent (config uses API field names: core_app, system_prompt)
|
|
321
|
+
const weatherTool = tool('get_weather')
|
|
322
|
+
.describe('Get current weather')
|
|
323
|
+
.param('city', string('City name'))
|
|
324
|
+
.build();
|
|
325
|
+
|
|
244
326
|
const agent = client.agents.create({
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
tools: [
|
|
248
|
-
tool('get_weather')
|
|
249
|
-
.description('Get current weather')
|
|
250
|
-
.params({ city: string('City name') })
|
|
251
|
-
.handler(async (args) => {
|
|
252
|
-
// Your tool logic here
|
|
253
|
-
return JSON.stringify({ temp: 72, conditions: 'sunny' });
|
|
254
|
-
})
|
|
255
|
-
.build()
|
|
256
|
-
]
|
|
327
|
+
core_app: { ref: 'infsh/claude-sonnet-4@abc123' },
|
|
328
|
+
system_prompt: 'You are a helpful assistant.',
|
|
329
|
+
tools: [weatherTool], // only schemas are sent to the API; handlers stay client-side
|
|
257
330
|
});
|
|
258
331
|
|
|
259
332
|
await agent.sendMessage('What is the weather in Paris?', {
|
|
260
333
|
onMessage: (msg) => console.log(msg),
|
|
261
334
|
onToolCall: async (call) => {
|
|
262
|
-
|
|
263
|
-
|
|
335
|
+
const result = await runMyClientTool(call.name, call.args);
|
|
336
|
+
await agent.submitToolResult(call.id, result);
|
|
337
|
+
},
|
|
338
|
+
});
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
For multi-turn chats, the SDK opens the chat stream before sending the next message so updates are not missed. Use `stopChat()` to cancel in-flight generation (`POST /chats/{id}/stop`), and `reset()` to clear the current chat and start fresh.
|
|
342
|
+
|
|
343
|
+
### File attachments
|
|
344
|
+
|
|
345
|
+
Pass files in `sendMessage` options. `Blob` values are uploaded first; objects with a `uri` (already uploaded via `client.files.upload`) are attached as-is:
|
|
346
|
+
|
|
347
|
+
```typescript
|
|
348
|
+
const uploaded = await client.files.upload(imageBlob, {
|
|
349
|
+
filename: 'photo.png',
|
|
350
|
+
contentType: 'image/png',
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
await agent.sendMessage('Describe this image', {
|
|
354
|
+
files: [imageBlob, uploaded], // Blob uploads; FileDTO reuses uri
|
|
355
|
+
onMessage: (msg) => console.log(msg),
|
|
264
356
|
});
|
|
265
357
|
```
|
|
266
358
|
|
|
@@ -283,21 +375,23 @@ const agent = client.agents.create({
|
|
|
283
375
|
internal_tools: { finish: true },
|
|
284
376
|
});
|
|
285
377
|
|
|
286
|
-
const
|
|
378
|
+
const output = await agent.run('Analyze: Great product!');
|
|
287
379
|
```
|
|
288
380
|
|
|
381
|
+
`agent.run()` sends a message with polling (no SSE), waits until the chat is idle, and returns `chat.output` (parsed finish-tool result, or `null` if none).
|
|
382
|
+
|
|
289
383
|
### Agent Methods
|
|
290
384
|
|
|
291
385
|
| Method | Description |
|
|
292
386
|
|--------|-------------|
|
|
293
|
-
| `sendMessage(text, options?)` | Send a message
|
|
294
|
-
| `
|
|
295
|
-
| `
|
|
296
|
-
| `
|
|
297
|
-
| `
|
|
298
|
-
| `
|
|
299
|
-
| `disconnect()` |
|
|
300
|
-
| `reset()` |
|
|
387
|
+
| `sendMessage(text, options?)` | Send a message; streams or polls until idle when callbacks or `stream: false` |
|
|
388
|
+
| `run(text, options?)` | Send and return structured `chat.output` (always uses polling) |
|
|
389
|
+
| `getChat(chatId?)` | Get the current or specified chat (`chat_messages` on the returned chat) |
|
|
390
|
+
| `stopChat()` | Stop generation for the current chat (no-op if no active chat) |
|
|
391
|
+
| `submitToolResult(toolId, resultOrAction)` | Submit result for a client tool (string or `{action, form_data}`) |
|
|
392
|
+
| `startStreaming(options?)` | Manually attach to `/chats/{id}/stream` for the current chat |
|
|
393
|
+
| `disconnect()` | Stop active stream/poll connections |
|
|
394
|
+
| `reset()` | Disconnect and clear chat state so the next message starts a new chat |
|
|
301
395
|
|
|
302
396
|
## API Reference
|
|
303
397
|
|
|
@@ -309,6 +403,9 @@ Creates a new inference client.
|
|
|
309
403
|
|-----------|------|----------|-------------|
|
|
310
404
|
| `config.apiKey` | `string` | Yes | Your inference.sh API key |
|
|
311
405
|
| `config.baseUrl` | `string` | No | Custom API URL (default: `https://api.inference.sh`) |
|
|
406
|
+
| `config.stream` | `boolean` | No | Use NDJSON streaming (`true`, default) or status polling (`false`) |
|
|
407
|
+
| `config.pollIntervalMs` | `number` | No | Poll interval when `stream: false` (default: `2000`) |
|
|
408
|
+
| `config.proxyUrl` | `string` | No | Proxy base URL for frontend apps (keeps API keys server-side) |
|
|
312
409
|
|
|
313
410
|
### `client.tasks.run(params, options?)`
|
|
314
411
|
|
|
@@ -331,10 +428,11 @@ Runs a task on inference.sh.
|
|
|
331
428
|
| Option | Type | Default | Description |
|
|
332
429
|
|--------|------|---------|-------------|
|
|
333
430
|
| `wait` | `boolean` | `true` | Wait for task completion |
|
|
334
|
-
| `
|
|
335
|
-
| `
|
|
336
|
-
| `
|
|
337
|
-
| `
|
|
431
|
+
| `stream` | `boolean` | client default | Use NDJSON streaming or status polling |
|
|
432
|
+
| `pollIntervalMs` | `number` | client default | Poll interval when `stream: false` |
|
|
433
|
+
| `onUpdate` | `function` | - | Callback for task updates (full fetch on status change when polling) |
|
|
434
|
+
| `onPartialUpdate` | `function` | - | Callback for partial NDJSON stream updates `(task, fields)` |
|
|
435
|
+
| `maxReconnects` | `number` | `5` | Max poll retries when `stream: false` |
|
|
338
436
|
|
|
339
437
|
### `client.tasks.get(taskId)`
|
|
340
438
|
|
|
@@ -357,9 +455,11 @@ Uploads a file to inference.sh.
|
|
|
357
455
|
| `options.contentType` | `string` | MIME type |
|
|
358
456
|
| `options.public` | `boolean` | Make file publicly accessible |
|
|
359
457
|
|
|
360
|
-
### `client.agents.create(templateOrConfig)`
|
|
458
|
+
### `client.agents.create(templateOrConfig)` / `client.agent(...)`
|
|
459
|
+
|
|
460
|
+
Creates an agent instance from a template or ad-hoc configuration. `client.agent(...)` is an alias for `client.agents.create(...)`.
|
|
361
461
|
|
|
362
|
-
|
|
462
|
+
**`sendMessage` options:** `onMessage`, `onChat`, `onToolCall`, `files`, `stream`, `pollIntervalMs`. Client tools with status `awaiting_input` are dispatched once per invocation ID via `onToolCall`.
|
|
363
463
|
|
|
364
464
|
**Template mode:**
|
|
365
465
|
```typescript
|
|
@@ -369,12 +469,21 @@ const agent = client.agents.create('namespace/name@version');
|
|
|
369
469
|
**Ad-hoc mode:**
|
|
370
470
|
```typescript
|
|
371
471
|
const agent = client.agents.create({
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
tools: [...]
|
|
472
|
+
core_app: { ref: 'infsh/claude-sonnet-4@abc123' },
|
|
473
|
+
system_prompt: 'You are helpful.',
|
|
474
|
+
tools: [...],
|
|
375
475
|
});
|
|
376
476
|
```
|
|
377
477
|
|
|
478
|
+
### `client.sessions`
|
|
479
|
+
|
|
480
|
+
| Method | HTTP | Description |
|
|
481
|
+
|--------|------|-------------|
|
|
482
|
+
| `get(sessionId)` | `GET /sessions/{id}` | Session metadata (`status`, `expires_at`, `call_count`, …) |
|
|
483
|
+
| `list()` | `GET /sessions` | All sessions (empty array if none) |
|
|
484
|
+
| `keepalive(sessionId)` | `POST /sessions/{id}/keepalive` | Reset idle expiration |
|
|
485
|
+
| `end(sessionId)` | `DELETE /sessions/{id}` | End session and release worker |
|
|
486
|
+
|
|
378
487
|
## Task Status Constants
|
|
379
488
|
|
|
380
489
|
```typescript
|
|
@@ -391,12 +500,103 @@ if (task.status === TaskStatusCompleted) {
|
|
|
391
500
|
}
|
|
392
501
|
```
|
|
393
502
|
|
|
503
|
+
## Integration Constants
|
|
504
|
+
|
|
505
|
+
`IntegrationDTO` fields (`provider`, `type`, `auth`, `status`) use typed string unions exported as constants:
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
import type { IntegrationDTO } from '@inferencesh/sdk';
|
|
509
|
+
import {
|
|
510
|
+
IntegrationProviderGoogle,
|
|
511
|
+
IntegrationAuthTypeOAuth,
|
|
512
|
+
IntegrationStatusConnected,
|
|
513
|
+
IntegrationStatusDisconnected,
|
|
514
|
+
IntegrationStatusExpired,
|
|
515
|
+
IntegrationStatusError,
|
|
516
|
+
isRequirementsNotMetException,
|
|
517
|
+
} from '@inferencesh/sdk';
|
|
518
|
+
|
|
519
|
+
function isGoogleConnected(integration: IntegrationDTO): boolean {
|
|
520
|
+
return (
|
|
521
|
+
integration.provider === IntegrationProviderGoogle &&
|
|
522
|
+
integration.status === IntegrationStatusConnected
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// HTTP 412 when an app requires a missing secret, integration, or scope
|
|
527
|
+
try {
|
|
528
|
+
await client.run({ app: 'my-app', input: {} });
|
|
529
|
+
} catch (error) {
|
|
530
|
+
if (isRequirementsNotMetException(error)) {
|
|
531
|
+
for (const req of error.errors) {
|
|
532
|
+
if (req.type === 'integration' && req.action?.provider === IntegrationProviderGoogle) {
|
|
533
|
+
// User must connect Google — see https://inference.sh/docs/extend/integrations
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
| Constant group | Values |
|
|
541
|
+
|----------------|--------|
|
|
542
|
+
| `IntegrationProvider*` | `google`, `slack`, `notion`, `github`, `x`, `microsoft`, `salesforce`, `discord`, `gcp`, `mcp`, `reddit` |
|
|
543
|
+
| `IntegrationAuthType*` | `service_account`, `oauth`, `api_key`, `wif`, `mcp` |
|
|
544
|
+
| `IntegrationStatus*` | `connected`, `disconnected`, `expired`, `error` |
|
|
545
|
+
|
|
546
|
+
## Instance Status Constants
|
|
547
|
+
|
|
548
|
+
Use when working with engine instance APIs (`InstanceDTO.status`):
|
|
549
|
+
|
|
550
|
+
```typescript
|
|
551
|
+
import {
|
|
552
|
+
InstanceStatusCreating,
|
|
553
|
+
InstanceStatusPendingProvider,
|
|
554
|
+
InstanceStatusPending,
|
|
555
|
+
InstanceStatusActive,
|
|
556
|
+
InstanceStatusError,
|
|
557
|
+
InstanceStatusDeleting,
|
|
558
|
+
InstanceStatusDeleted,
|
|
559
|
+
} from '@inferencesh/sdk';
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
## Tool Parameter Types
|
|
563
|
+
|
|
564
|
+
When building `AgentTool` schemas manually (outside the tool builder), use `ToolParamType*` for JSON Schema `type` fields:
|
|
565
|
+
|
|
566
|
+
```typescript
|
|
567
|
+
import {
|
|
568
|
+
ToolParamTypeObject,
|
|
569
|
+
ToolParamTypeString,
|
|
570
|
+
ToolParamTypeInteger,
|
|
571
|
+
ToolParamTypeNumber,
|
|
572
|
+
ToolParamTypeBoolean,
|
|
573
|
+
ToolParamTypeArray,
|
|
574
|
+
ToolParamTypeNull,
|
|
575
|
+
} from '@inferencesh/sdk';
|
|
576
|
+
|
|
577
|
+
const schema = {
|
|
578
|
+
type: ToolParamTypeObject,
|
|
579
|
+
properties: {
|
|
580
|
+
city: { type: ToolParamTypeString, description: 'City name' },
|
|
581
|
+
},
|
|
582
|
+
required: ['city'],
|
|
583
|
+
};
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
The fluent tool builder (`string()`, `number()`, `object()`, …) infers these types automatically.
|
|
587
|
+
|
|
394
588
|
## TypeScript Support
|
|
395
589
|
|
|
396
590
|
This SDK is written in TypeScript and includes full type definitions. All types are exported:
|
|
397
591
|
|
|
398
592
|
```typescript
|
|
399
|
-
import type {
|
|
593
|
+
import type {
|
|
594
|
+
Task,
|
|
595
|
+
ApiAppRunRequest,
|
|
596
|
+
RunOptions,
|
|
597
|
+
IntegrationDTO,
|
|
598
|
+
AgentTool,
|
|
599
|
+
} from '@inferencesh/sdk';
|
|
400
600
|
```
|
|
401
601
|
|
|
402
602
|
## Requirements
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|