@inferencesh/sdk 0.10.1 → 0.11.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.
@@ -4,8 +4,8 @@
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 { AgentRunStateWorking, AgentRunStateSubmitted, AgentRunStateInputRequired, ToolInvocationStatusAwaitingInput, ToolInvocationStatusInProgress, ToolTypeClient, ChatMessageStatusReady, ChatMessageStatusFailed, ChatMessageStatusCancelled, } from '../types';
8
- import { isChatBusy } from '../utils';
7
+ import { ToolInvocationStatusAwaitingInput, ToolInvocationStatusInProgress, ToolTypeClient, } from '../types';
8
+ import { isChatBusy, isMessageTerminal, isRunInterrupted, isRunWorking } from '../utils';
9
9
  import { StreamableManager } from '../http/streamable';
10
10
  import { PollManager } from '../http/poll';
11
11
  import { createLLMDeltaAccumulator } from '../delta';
@@ -148,9 +148,7 @@ export function createActions(ctx) {
148
148
  // A message that has reached a terminal state will receive no further
149
149
  // deltas, so its accumulator is done. This bounds the map by the number
150
150
  // of messages streaming at once rather than by chat length.
151
- if (message.status === ChatMessageStatusReady
152
- || message.status === ChatMessageStatusFailed
153
- || message.status === ChatMessageStatusCancelled) {
151
+ if (isMessageTerminal(message.status)) {
154
152
  deltaAccums.delete(message.id);
155
153
  }
156
154
  updateMessage(message, fields);
@@ -158,8 +156,7 @@ export function createActions(ctx) {
158
156
  // Listen for AgentRun updates (state transitions, output)
159
157
  manager.addEventListener('agent_runs', (run) => {
160
158
  dispatch({ type: 'UPDATE_ACTIVE_RUN', payload: run });
161
- const isRunActive = run.state === AgentRunStateWorking || run.state === AgentRunStateSubmitted || run.state === AgentRunStateInputRequired;
162
- callbacks.onStatusChange?.(isRunActive ? 'streaming' : 'idle');
159
+ callbacks.onStatusChange?.(isRunWorking(run.state) || isRunInterrupted(run.state) ? 'streaming' : 'idle');
163
160
  const currentChat = getState().chat;
164
161
  if (currentChat)
165
162
  checkTurnEnd({ ...currentChat, active_run: run });
@@ -3,13 +3,14 @@
3
3
  *
4
4
  * Pure reducer for managing agent chat state.
5
5
  */
6
- import { ChatStatusBusy, ChatStatusAwaitingInput, ChatStatusIdle, AgentRunStateWorking, AgentRunStateSubmitted } from '../types';
6
+ import { ChatStatusBusy, ChatStatusAwaitingInput, ChatStatusIdle } from '../types';
7
+ import { isRunInterrupted, isRunWorking } from '../utils';
7
8
  function deriveChatStatus(run) {
8
9
  if (!run)
9
10
  return ChatStatusIdle;
10
- if (run.state === AgentRunStateWorking || run.state === AgentRunStateSubmitted)
11
+ if (isRunWorking(run.state))
11
12
  return ChatStatusBusy;
12
- if (run.state === 'input_required' || run.state === 'auth_required')
13
+ if (isRunInterrupted(run.state))
13
14
  return ChatStatusAwaitingInput;
14
15
  return ChatStatusIdle;
15
16
  }
@@ -1,9 +1,8 @@
1
1
  import { StreamableManager } from '../http/streamable';
2
2
  import { PollManager } from '../http/poll';
3
3
  import { createLLMDeltaAccumulator } from '../delta';
4
- import { ChatMessageStatusCancelled, ChatMessageStatusFailed, ChatMessageStatusReady, ToolTypeClient, ToolInvocationStatusAwaitingInput, ToolInvocationStatusInProgress, } from '../types';
5
- import { isChatBusy } from '../utils';
6
- const terminalMessageStatuses = new Set([ChatMessageStatusReady, ChatMessageStatusFailed, ChatMessageStatusCancelled]);
4
+ import { ToolTypeClient, ToolInvocationStatusAwaitingInput, ToolInvocationStatusInProgress, } from '../types';
5
+ import { isChatBusy, isMessageTerminal } from '../utils';
7
6
  /**
8
7
  * Decides when one sendMessage() turn is over.
9
8
  *
@@ -25,7 +24,7 @@ class TurnGate {
25
24
  this.sawBusy = true;
26
25
  }
27
26
  observeMessage(message) {
28
- if (message.id === this.assistantMessageId && terminalMessageStatuses.has(message.status)) {
27
+ if (message.id === this.assistantMessageId && isMessageTerminal(message.status)) {
29
28
  this.assistantDone = true;
30
29
  }
31
30
  }
@@ -86,23 +85,19 @@ export class Agent {
86
85
  if (others.length > 0)
87
86
  fileUris = others.map((f) => f.uri);
88
87
  }
89
- const body = isTemplate
90
- ? {
91
- chat_id: this.chatId,
92
- agent: this.config,
93
- context: this.context,
94
- input: { text, images: imageUris, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 },
95
- }
96
- : {
97
- chat_id: this.chatId,
98
- agent_config: this.config,
99
- agent_name: this.agentName ?? this.config.name,
100
- context: this.context,
101
- input: { text, images: imageUris, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 },
102
- };
103
- if (options.channel_context !== undefined) {
104
- body.channel_context = options.channel_context;
105
- }
88
+ const input = { text, images: imageUris, files: fileUris, role: 'user', context: [], system_prompt: '', context_size: 0 };
89
+ const body = {
90
+ chat_id: this.chatId ?? undefined,
91
+ context: this.context,
92
+ input,
93
+ channel_context: options.channel_context,
94
+ ...(isTemplate
95
+ ? { agent: this.config }
96
+ : {
97
+ agent_config: this.config,
98
+ agent_name: this.agentName ?? this.config.name,
99
+ }),
100
+ };
106
101
  const useStream = options.stream ?? this.http.getStreamDefault();
107
102
  const shouldWait = useStream === false || hasCallbacks;
108
103
  const gate = new TurnGate(!!this.chatId);
@@ -270,7 +265,7 @@ export class Agent {
270
265
  });
271
266
  this.stream.addEventListener('chat_messages', (message) => {
272
267
  // A terminal message receives no further deltas.
273
- if (terminalMessageStatuses.has(message.status))
268
+ if (isMessageTerminal(message.status))
274
269
  deltaAccums.delete(message.id);
275
270
  gate.observeMessage(message);
276
271
  options.onMessage?.(message);
package/dist/index.d.ts CHANGED
@@ -26,14 +26,15 @@ export { ProjectsAPI } from './api/projects';
26
26
  export { MCPServersAPI } from './api/mcp-servers';
27
27
  export { LiveSession, accessUrl } from './live/session';
28
28
  export type { LiveState, LiveEnd, LiveHandlers, LiveSessionOptions, LiveUpdate, WebSocketLike, WebSocketConstructor } from './live/session';
29
- export { STREAM_FORMAT, CLEAR_KEY, ERROR_KEY, isLiveField, parseMediaType, pcmFormat, splitLiveSchema, binaryLiveField, alternativeLabel, alternativeTag, } from './live/schema';
29
+ export { STREAM_FORMAT, CLEAR_KEY, ERROR_KEY, REDIAL_CODES } from './live/protocol';
30
+ export { isLiveField, parseMediaType, pcmFormat, splitLiveSchema, binaryLiveField, alternativeLabel, alternativeTag, } from './live/schema';
30
31
  export type { JsonSchema, MediaType, PCMFormat, LiveField } from './live/schema';
31
32
  export { tool, appTool, agentTool, webhookTool, httpTool, callTool, mcpTool, internalTools, string, number, integer, boolean, enumOf, object, array, optional, } from './tool-builder';
32
33
  export type { ClientTool, ClientToolHandler } from './tool-builder';
33
34
  export { lifecycleHook } from './hook-builder';
34
35
  export type { LifecycleHookBuilder } from './hook-builder';
35
36
  export { DeltaAccumulator, createLLMDeltaAccumulator, type DeltaEvent, type FieldTags, type FieldTagsRegistry } from './delta';
36
- export { parseStatus, isTerminalStatus, isChatBusy, pendingApprovals } from './utils';
37
+ export { parseStatus, isTerminalStatus, isChatBusy, isAwaitingHuman, isRunTerminal, isRunInterrupted, isRunSettled, isRunWorking, isMessageTerminal, pendingApprovals, } from './utils';
37
38
  export type { PendingApproval } from './utils';
38
39
  export * from './types';
39
40
  export type { TaskDTO as Task } from './types';
package/dist/index.js CHANGED
@@ -28,7 +28,8 @@ export { ProjectsAPI } from './api/projects';
28
28
  export { MCPServersAPI } from './api/mcp-servers';
29
29
  // Live: the socket of a stream task and the live fields of its schemas
30
30
  export { LiveSession, accessUrl } from './live/session';
31
- export { STREAM_FORMAT, CLEAR_KEY, ERROR_KEY, isLiveField, parseMediaType, pcmFormat, splitLiveSchema, binaryLiveField, alternativeLabel, alternativeTag, } from './live/schema';
31
+ export { STREAM_FORMAT, CLEAR_KEY, ERROR_KEY, REDIAL_CODES } from './live/protocol';
32
+ export { isLiveField, parseMediaType, pcmFormat, splitLiveSchema, binaryLiveField, alternativeLabel, alternativeTag, } from './live/schema';
32
33
  // Tool Builder (fluent API)
33
34
  export { tool, appTool, agentTool, webhookTool, httpTool, callTool, mcpTool, internalTools, string, number, integer, boolean, enumOf, object, array, optional, } from './tool-builder';
34
35
  // Hook Builder (fluent API)
@@ -36,7 +37,7 @@ export { lifecycleHook } from './hook-builder';
36
37
  // Delta accumulator for streaming responses
37
38
  export { DeltaAccumulator, createLLMDeltaAccumulator } from './delta';
38
39
  // Status utilities (handle both int and string status values)
39
- export { parseStatus, isTerminalStatus, isChatBusy, pendingApprovals } from './utils';
40
+ export { parseStatus, isTerminalStatus, isChatBusy, isAwaitingHuman, isRunTerminal, isRunInterrupted, isRunSettled, isRunWorking, isMessageTerminal, pendingApprovals, } from './utils';
40
41
  // Types - includes TaskStatus constants and all DTOs
41
42
  export * from './types';
42
43
  // =============================================================================
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The live socket's wire protocol. sdk-py (inferencesh/models/stream.py)
3
+ * mirrors all of it and sdk-js-app (src/stream.ts) mirrors CLEAR_KEY and
4
+ * ERROR_KEY; change the copies together.
5
+ */
6
+ export declare const STREAM_FORMAT = "stream";
7
+ /** `{"$clear": "audio"}`: drop what has been buffered of a live output field. */
8
+ export declare const CLEAR_KEY = "$clear";
9
+ /**
10
+ * `{"$error": {"field": ..., "message": ...}}`: a refused frame, or anything
11
+ * else the caller should be told went wrong. The stream goes on.
12
+ */
13
+ export declare const ERROR_KEY = "$error";
14
+ /**
15
+ * Relay close codes that mean "dial again". 1012: the relay is restarting and
16
+ * closed an end that still waited for its peer. 1013: the peer did not come in
17
+ * time. Neither means anything once frames have flowed.
18
+ */
19
+ export declare const REDIAL_CODES: ReadonlySet<number>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The live socket's wire protocol. sdk-py (inferencesh/models/stream.py)
3
+ * mirrors all of it and sdk-js-app (src/stream.ts) mirrors CLEAR_KEY and
4
+ * ERROR_KEY; change the copies together.
5
+ */
6
+ export const STREAM_FORMAT = 'stream';
7
+ // Control frames. Reserved keys start with `$`, which no field name can, so a
8
+ // control frame is never mistaken for an output field.
9
+ /** `{"$clear": "audio"}`: drop what has been buffered of a live output field. */
10
+ export const CLEAR_KEY = '$clear';
11
+ /**
12
+ * `{"$error": {"field": ..., "message": ...}}`: a refused frame, or anything
13
+ * else the caller should be told went wrong. The stream goes on.
14
+ */
15
+ export const ERROR_KEY = '$error';
16
+ /**
17
+ * Relay close codes that mean "dial again". 1012: the relay is restarting and
18
+ * closed an end that still waited for its peer. 1013: the peer did not come in
19
+ * time. Neither means anything once frames have flowed.
20
+ */
21
+ export const REDIAL_CODES = new Set([1012, 1013]);
@@ -16,14 +16,6 @@
16
16
  * The helpers are generic over the schema type so a caller with a richer
17
17
  * JSON Schema type keeps it.
18
18
  */
19
- export declare const STREAM_FORMAT = "stream";
20
- /** `{"$clear": "audio"}`: drop what has been buffered of a live output field. */
21
- export declare const CLEAR_KEY = "$clear";
22
- /**
23
- * `{"$error": {"field": ..., "message": ...}}`: a refused frame, or anything
24
- * else the caller should be told went wrong. The stream goes on.
25
- */
26
- export declare const ERROR_KEY = "$error";
27
19
  /** The part of JSON Schema these helpers read. */
28
20
  export interface JsonSchema {
29
21
  $ref?: string;
@@ -16,16 +16,7 @@
16
16
  * The helpers are generic over the schema type so a caller with a richer
17
17
  * JSON Schema type keeps it.
18
18
  */
19
- export const STREAM_FORMAT = 'stream';
20
- // Control frames. Reserved keys start with `$`, which no field name can, so a
21
- // control frame is never mistaken for an output field.
22
- /** `{"$clear": "audio"}`: drop what has been buffered of a live output field. */
23
- export const CLEAR_KEY = '$clear';
24
- /**
25
- * `{"$error": {"field": ..., "message": ...}}`: a refused frame, or anything
26
- * else the caller should be told went wrong. The stream goes on.
27
- */
28
- export const ERROR_KEY = '$error';
19
+ import { STREAM_FORMAT } from './protocol';
29
20
  export function isLiveField(schema) {
30
21
  return !!schema && schema.format === STREAM_FORMAT;
31
22
  }
@@ -1,9 +1,6 @@
1
- import { binaryLiveField, CLEAR_KEY, ERROR_KEY, splitLiveSchema } from './schema';
1
+ import { CLEAR_KEY, ERROR_KEY, REDIAL_CODES } from './protocol';
2
+ import { binaryLiveField, splitLiveSchema } from './schema';
2
3
  const WS_OPEN = 1;
3
- // 1012: the relay is restarting and closed an end that still waited for its
4
- // peer. 1013: the peer did not come in time. Both mean "dial again" while the
5
- // task is alive, and neither means anything once frames have flowed.
6
- const REDIAL_CODES = new Set([1012, 1013]);
7
4
  const MAX_REDIALS = 5;
8
5
  function globalWebSocket() {
9
6
  const ctor = globalThis.WebSocket;