@inferencesh/sdk 0.29.0 → 0.30.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.30.0] - 2026-10-18
11
+
12
+ ### Removed
13
+ - `credentialId` on `httpTool().auth()` and `mcpTool()`, and the positional `mcpTool(name, credentialId, toolName)`: a tool no longer pins a connection. Credential-auth HTTP tools and MCP tools always sign in with the caller's own login to the provider at run time; `mcpTool(name, { server, toolName })` requires `server` (INF-1012). Generated types: `ToolAuthConfig`, `MCPToolConfig` and `MCPToolConfigDTO` lose `credential_id`.
14
+
10
15
  ## [0.29.0] - 2026-10-17
11
16
 
12
17
  ### Removed
package/README.md CHANGED
@@ -377,7 +377,7 @@ Use the fluent builders to define `AgentTool` schemas. Client tools (`tool`) run
377
377
  | `agentTool(name, agentRef)` | Server | Delegate to a sub-agent |
378
378
  | `httpTool(name, url)` / `callTool(name, url)` | Server | HTTP request with credential injection (preferred over `webhookTool`) |
379
379
  | `webhookTool(name, url)` | Server | Unsigned webhook (legacy; use `httpTool` for new tools) |
380
- | `mcpTool(name, { server, toolName, credentialId? })` | Server | Call a tool on an MCP server (by slug), signed in through the server's provider; `credentialId` pins one connection. `mcpTool(name, credentialId, toolName)` still works and is saved with the connection's server |
380
+ | `mcpTool(name, { server, toolName })` | Server | Call a tool on an MCP server (by slug), signed in with the runner's own connection to the server's provider |
381
381
  | `internalTools()` | Server | Built-in tools: plan, memory, widget, finish, skills, meta, remote, knowledge, artifact, agent |
382
382
 
383
383
  ```typescript
@@ -401,7 +401,7 @@ const clientTool = tool('get_weather')
401
401
  const gmailSend = httpTool('gmail_send', 'https://gmail.googleapis.com/gmail/v1/users/me/messages/send')
402
402
  .describe('Send an email via Gmail')
403
403
  .method('POST')
404
- .auth({ credential: CredentialProviderGoogle, credentialId: 'your-credential-id' })
404
+ .auth({ credential: CredentialProviderGoogle })
405
405
  .build();
406
406
 
407
407
  // API key or bearer auth
@@ -575,6 +575,7 @@ export function createActions(ctx) {
575
575
  throw error;
576
576
  }
577
577
  },
578
+ listRunInterrupts: (runId) => api.listRunInterrupts(client, runId),
578
579
  loadOlderMessages: async () => {
579
580
  const chatId = getChatId();
580
581
  const cursor = getState().messageCursor;
@@ -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 { AgentRunDTO, AgentVersionDTO, AlwaysAllowOptionsDTO, AlwaysAllowResultDTO, ToolExplanationDTO, ChatAgentDTO, ChatDTO, ChatMessageDTO, ChatSettingsDTO, ChatSettingsRequest, AgentTool, AgentConfigInput as GeneratedAgentConfig, CoreAppConfigInput as CoreAppConfig, FileRef, ElicitResult } from '../types.js';
7
+ import type { AgentRunDTO, AgentVersionDTO, AlwaysAllowOptionsDTO, AlwaysAllowResultDTO, ToolExplanationDTO, ChatAgentDTO, ChatDTO, ChatMessageDTO, ChatSettingsDTO, ChatSettingsRequest, AgentTool, AgentConfigInput as GeneratedAgentConfig, CoreAppConfigInput as CoreAppConfig, FileRef, ElicitResult, InterruptDTO } from '../types.js';
8
8
  import type { HttpClient } from '../http/client.js';
9
9
  import type { ClientToolResult } from '../tool-builder.js';
10
10
  import type { StreamableManager } from '../http/streamable.js';
@@ -190,6 +190,8 @@ export interface AgentChatActions {
190
190
  * `requires_sign_in` (ErrorCodeRequiresSignIn).
191
191
  */
192
192
  resolveInterrupt: (interruptId: string, decision: 'allow' | 'deny') => Promise<void>;
193
+ /** A run's pending interrupts (`heldTurn` finds a held turn among them). */
194
+ listRunInterrupts: (runId: string) => Promise<InterruptDTO[]>;
193
195
  /** Load older messages (scroll-up pagination). Returns true if more exist. */
194
196
  loadOlderMessages: () => Promise<boolean>;
195
197
  /** Whether there are older messages to load */
package/dist/api/tasks.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { streamUntilTerminal } from '../http/stream-until-terminal.js';
2
2
  import { PollManager } from '../http/poll.js';
3
- import { TaskStatusCompleted, TaskStatusFailed, TaskStatusCancelled, } from '../types.js';
3
+ import { TaskStatusCompleted, TaskStatusFailed, TaskStatusCancelled, TaskStatusRejected, } from '../types.js';
4
4
  import { parseStatus } from '../utils.js';
5
5
  //TODO: This is ugly...
6
6
  function stripTask(task) {
@@ -28,6 +28,9 @@ function settleTerminal(data, stripped, settle) {
28
28
  case TaskStatusCancelled:
29
29
  settle.reject(new Error('task cancelled'));
30
30
  break;
31
+ case TaskStatusRejected:
32
+ settle.reject(new Error(data.error || 'task rejected'));
33
+ break;
31
34
  }
32
35
  }
33
36
  /**
package/dist/index.d.ts CHANGED
@@ -36,8 +36,8 @@ export type { ClientTool, ClientToolHandler, ClientToolResult } from './tool-bui
36
36
  export { lifecycleHook, learningHooks } from './hook-builder.js';
37
37
  export type { LifecycleHookBuilder } from './hook-builder.js';
38
38
  export { DeltaAccumulator, createLLMDeltaAccumulator, type DeltaEvent, type FieldTags, type FieldTagsRegistry } from './delta.js';
39
- export { parseStatus, isTerminalStatus, isChatBusy, isAwaitingHuman, isRunTerminal, isRunInterrupted, isRunSettled, isRunWorking, isMessageTerminal, pendingApprovals, } from './utils.js';
40
- export type { PendingApproval } from './utils.js';
39
+ export { parseStatus, isTerminalStatus, isChatBusy, isAwaitingHuman, isRunTerminal, isRunInterrupted, isRunSettled, isRunWorking, isMessageTerminal, pendingApprovals, heldTurn, } from './utils.js';
40
+ export type { PendingApproval, HeldTurn } from './utils.js';
41
41
  export * from './types.js';
42
42
  export type { TaskDTO as Task } from './types.js';
43
43
  import { HttpClient, type HttpClientConfig } from './http/client.js';
package/dist/index.js CHANGED
@@ -38,7 +38,7 @@ export { lifecycleHook, learningHooks } from './hook-builder.js';
38
38
  // Delta accumulator for streaming responses
39
39
  export { DeltaAccumulator, createLLMDeltaAccumulator } from './delta.js';
40
40
  // Status utilities (handle both int and string status values)
41
- export { parseStatus, isTerminalStatus, isChatBusy, isAwaitingHuman, isRunTerminal, isRunInterrupted, isRunSettled, isRunWorking, isMessageTerminal, pendingApprovals, } from './utils.js';
41
+ export { parseStatus, isTerminalStatus, isChatBusy, isAwaitingHuman, isRunTerminal, isRunInterrupted, isRunSettled, isRunWorking, isMessageTerminal, pendingApprovals, heldTurn, } from './utils.js';
42
42
  // Types - includes TaskStatus constants and all DTOs
43
43
  export * from './types.js';
44
44
  // =============================================================================
@@ -100,13 +100,12 @@ declare class HTTPToolBuilder extends ToolBuilder {
100
100
  constructor(name: string, url: string);
101
101
  method(m: string): this;
102
102
  /**
103
- * How the tool authenticates: `credential` sends a connected account's
104
- * access token (pick the account with `credentialId`), `apiKey` / `bearer`
105
- * send a vault secret.
103
+ * How the tool authenticates: `credential` sends the access token of the
104
+ * runner's own connection to that provider, `apiKey` / `bearer` send a
105
+ * vault secret.
106
106
  */
107
107
  auth(config: {
108
108
  credential?: string;
109
- credentialId?: string;
110
109
  apiKey?: string;
111
110
  bearer?: string;
112
111
  header?: string;
@@ -131,24 +130,15 @@ export interface MCPToolTarget {
131
130
  /** The MCP server's slug (a workspace registration or a directory entry). */
132
131
  server: string;
133
132
  toolName: string;
134
- /** Pins one connection to the server's provider; by default the runner's own is used. */
135
- credentialId?: string;
136
133
  }
137
134
  /**
138
135
  * Create an MCP tool: `toolName` on the MCP server `target.server` (its slug).
139
- * The call signs in with the runner's connection to the server's provider;
140
- * `credentialId` pins one connection instead.
141
- *
142
- * The older form `mcpTool(name, credentialId, toolName)` (a string second
143
- * argument) still works: a tool naming only a connection is saved with the
144
- * server that connection's provider is declared by.
136
+ * The call signs in with the runner's own connection to the server's provider.
145
137
  */
146
- export declare function mcpTool(name: string, target: MCPToolTarget | string, toolName?: string): MCPToolBuilder;
138
+ export declare function mcpTool(name: string, target: MCPToolTarget): MCPToolBuilder;
147
139
  declare class MCPToolBuilder extends ToolBuilder {
148
140
  private target;
149
- constructor(name: string, target: Partial<MCPToolTarget> & {
150
- toolName: string;
151
- });
141
+ constructor(name: string, target: MCPToolTarget);
152
142
  build(): AgentTool;
153
143
  }
154
144
  declare class InternalToolsBuilder {
@@ -184,13 +184,13 @@ class HTTPToolBuilder extends ToolBuilder {
184
184
  return this;
185
185
  }
186
186
  /**
187
- * How the tool authenticates: `credential` sends a connected account's
188
- * access token (pick the account with `credentialId`), `apiKey` / `bearer`
189
- * send a vault secret.
187
+ * How the tool authenticates: `credential` sends the access token of the
188
+ * runner's own connection to that provider, `apiKey` / `bearer` send a
189
+ * vault secret.
190
190
  */
191
191
  auth(config) {
192
192
  if (config.credential) {
193
- this.authConfig = { type: ToolAuthTypeCredential, provider: config.credential, credential_id: config.credentialId };
193
+ this.authConfig = { type: ToolAuthTypeCredential, provider: config.credential };
194
194
  }
195
195
  else if (config.apiKey) {
196
196
  this.authConfig = { type: ToolAuthTypeAPIKey, secret: config.apiKey, header: config.header || 'X-API-Key' };
@@ -238,17 +238,9 @@ export const httpTool = (name, url) => new HTTPToolBuilder(name, url);
238
238
  export const callTool = (name, url) => new HTTPToolBuilder(name, url);
239
239
  /**
240
240
  * Create an MCP tool: `toolName` on the MCP server `target.server` (its slug).
241
- * The call signs in with the runner's connection to the server's provider;
242
- * `credentialId` pins one connection instead.
243
- *
244
- * The older form `mcpTool(name, credentialId, toolName)` (a string second
245
- * argument) still works: a tool naming only a connection is saved with the
246
- * server that connection's provider is declared by.
241
+ * The call signs in with the runner's own connection to the server's provider.
247
242
  */
248
- export function mcpTool(name, target, toolName) {
249
- if (typeof target === 'string') {
250
- return new MCPToolBuilder(name, { toolName: toolName ?? '', credentialId: target });
251
- }
243
+ export function mcpTool(name, target) {
252
244
  return new MCPToolBuilder(name, target);
253
245
  }
254
246
  class MCPToolBuilder extends ToolBuilder {
@@ -264,9 +256,8 @@ class MCPToolBuilder extends ToolBuilder {
264
256
  type: ToolTypeMCP,
265
257
  require_approval: this.approval || undefined,
266
258
  mcp: {
259
+ server: this.target.server,
267
260
  tool_name: this.target.toolName,
268
- ...(this.target.server ? { server: this.target.server } : {}),
269
- ...(this.target.credentialId ? { credential_id: this.target.credentialId } : {}),
270
261
  },
271
262
  };
272
263
  }
package/dist/types.d.ts CHANGED
@@ -172,7 +172,6 @@ export declare const ToolAuthTypeBearer: ToolAuthType;
172
172
  export interface ToolAuthConfig {
173
173
  type: ToolAuthType;
174
174
  provider?: string;
175
- credential_id?: string;
176
175
  secret?: string;
177
176
  header?: string;
178
177
  }
@@ -203,15 +202,12 @@ export interface HTTPToolConfig {
203
202
  /**
204
203
  * MCPToolConfig is a tool of an MCP server: the server by its slug (the
205
204
  * agent's team's registration, its org's or the directory's) and the tool
206
- * to call. CredentialID pins the connection the call signs in with; without
207
- * it the runner's connection to the server's provider is used. A tool
208
- * written with only a connection is saved with the server that
209
- * connection's provider is declared by.
205
+ * to call. Each call signs in with the runner's connection to the
206
+ * server's provider (Credential.ToolConnection).
210
207
  */
211
208
  export interface MCPToolConfig {
212
209
  server?: string;
213
210
  tool_name: string;
214
- credential_id?: string;
215
211
  }
216
212
  export interface AppToolConfigDTO {
217
213
  ref: string;
@@ -264,7 +260,6 @@ export interface HTTPToolConfigDTO {
264
260
  export interface MCPToolConfigDTO {
265
261
  server: string;
266
262
  tool_name: string;
267
- credential_id?: string;
268
263
  }
269
264
  /**
270
265
  * CoreAppConfigDTO references an app used as the agent's core
@@ -1489,6 +1484,34 @@ export interface CredentialRequirement {
1489
1484
  * Auth is the credential's auth provider, for a slug no row defines yet.
1490
1485
  */
1491
1486
  auth?: AuthMethod;
1487
+ /**
1488
+ * The rest describe the platform api_key scheme a platform app's deploy
1489
+ * catalogues for the slug: set on the scheme it creates, and filled into
1490
+ * an existing one only where that is still empty (an admin's edit
1491
+ * stands). Any other deploy ignores them.
1492
+ * DisplayName is the scheme's name ("Claude Code"); at most
1493
+ * MaxCredentialDisplayName characters.
1494
+ */
1495
+ display_name?: string;
1496
+ /**
1497
+ * ConnectionScope is who a connection belongs to: team (empty) or user.
1498
+ */
1499
+ connection_scope?: CredentialScope;
1500
+ /**
1501
+ * Instructions tell a person how to get the key (markdown, at most
1502
+ * MaxAuthProviderInstructions characters).
1503
+ */
1504
+ instructions?: string;
1505
+ /**
1506
+ * DocsURL is the scheme's documentation link.
1507
+ */
1508
+ docs_url?: string;
1509
+ /**
1510
+ * ExpiresAfterDays is how long a saved key lasts: it counts as expired
1511
+ * this many days after it is saved. 0 is never; at most
1512
+ * MaxExpiresAfterDays.
1513
+ */
1514
+ expires_after_days?: number;
1492
1515
  }
1493
1516
  /**
1494
1517
  * CompanySeed is a provider (the company behind a credential) as an app
@@ -2652,9 +2675,20 @@ export interface CredentialConfigDTO {
2652
2675
  description: string;
2653
2676
  icon_url?: string;
2654
2677
  how_it_works?: string[];
2678
+ /**
2679
+ * Instructions tell a person how to get what this credential asks for
2680
+ * (markdown, links allowed): the auth scheme's.
2681
+ */
2682
+ instructions?: string;
2655
2683
  docs_url?: string;
2656
2684
  secret_fields?: SecretFieldConfig[];
2657
2685
  allows_byok: boolean;
2686
+ /**
2687
+ * ExpiresAfterDays is how long a saved key lasts, in days: a key counts
2688
+ * as expired that long after it is saved (its credential's expires_at).
2689
+ * 0 is never.
2690
+ */
2691
+ expires_after_days?: number;
2658
2692
  available: boolean;
2659
2693
  has_managed: boolean;
2660
2694
  /**
@@ -2702,6 +2736,10 @@ export interface SecretFieldConfig {
2702
2736
  placeholder: string;
2703
2737
  sensitive: boolean;
2704
2738
  optional: boolean;
2739
+ /**
2740
+ * Pattern is the scheme field's pattern (shared.SecretField.Pattern).
2741
+ */
2742
+ pattern?: string;
2705
2743
  }
2706
2744
  /**
2707
2745
  * SearchRequest represents a search request.
@@ -3017,7 +3055,7 @@ export interface DecideEntitlementRequestRequest {
3017
3055
  * and APIError.Code on the legacy envelope. Clients branch on these, so a
3018
3056
  * code is a named const here, where it generates into models and the SDKs.
3019
3057
  */
3020
- export type ErrorCode = "invalid_request" | "validation_error" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "name_conflict" | "already_exists" | "not_configured" | "method_not_allowed" | "rate_limited" | "internal_error" | "team_role_required" | "blocked_by_usage_policy" | "last_owner" | "account_deactivated" | "account_banned" | "person_required" | "otp_required" | "requires_sign_in" | "insufficient_scope" | "invalid_scope" | "impersonation_reason_required" | "mcp_auth_expired" | "admin_session_required" | "admin_scopes_not_approved" | "cli_session_required" | "admin_required" | "same_admin_required" | "browser_session_required" | "invalid_ttl" | "admin_authenticator_required" | "limit_exceeded" | "feature_not_available" | "entitlement_unavailable" | "payment_required" | "payment_method_required" | "form_closed" | "already_submitted" | "already_claimed" | "already_entitled" | "request_open" | "invalid_code" | "already_processed" | "expired" | "code_confirmation_required" | "app_retired" | "app_maintenance" | "invalid_transition" | "SESSION_NOT_FOUND" | "SESSION_EXPIRED" | "SESSION_ENDED" | "WORKER_LEASED" | "APP_MISMATCH" | "VERSION_MISMATCH" | "agents_disabled" | "remote_offline" | "remote_timeout" | "harness_not_drivable" | "harness_too_old";
3058
+ export type ErrorCode = "invalid_request" | "validation_error" | "unauthorized" | "forbidden" | "not_found" | "conflict" | "name_conflict" | "already_exists" | "not_configured" | "method_not_allowed" | "rate_limited" | "internal_error" | "requirements_not_met" | "team_role_required" | "blocked_by_usage_policy" | "last_owner" | "account_deactivated" | "account_banned" | "person_required" | "otp_required" | "requires_sign_in" | "insufficient_scope" | "invalid_scope" | "impersonation_reason_required" | "mcp_auth_expired" | "admin_session_required" | "admin_scopes_not_approved" | "cli_session_required" | "admin_required" | "same_admin_required" | "browser_session_required" | "invalid_ttl" | "admin_authenticator_required" | "limit_exceeded" | "feature_not_available" | "entitlement_unavailable" | "payment_required" | "payment_method_required" | "form_closed" | "already_submitted" | "already_claimed" | "already_entitled" | "request_open" | "invalid_code" | "already_processed" | "expired" | "code_confirmation_required" | "app_retired" | "app_maintenance" | "invalid_transition" | "SESSION_NOT_FOUND" | "SESSION_EXPIRED" | "SESSION_ENDED" | "WORKER_LEASED" | "APP_MISMATCH" | "VERSION_MISMATCH" | "agents_disabled" | "remote_offline" | "remote_timeout" | "harness_not_drivable" | "harness_too_old";
3021
3059
  export declare const ErrorCodeInvalidRequest: ErrorCode;
3022
3060
  export declare const ErrorCodeValidationError: ErrorCode;
3023
3061
  export declare const ErrorCodeUnauthorized: ErrorCode;
@@ -3030,6 +3068,12 @@ export declare const ErrorCodeNotConfigured: ErrorCode;
3030
3068
  export declare const ErrorCodeMethodNotAllowed: ErrorCode;
3031
3069
  export declare const ErrorCodeRateLimited: ErrorCode;
3032
3070
  export declare const ErrorCodeInternalError: ErrorCode;
3071
+ /**
3072
+ * ErrorCodeRequirementsNotMet (412): the run needs a secret or a
3073
+ * credential the caller has not set up. Meta "errors" lists each
3074
+ * RequirementError, its action saying how to set it up.
3075
+ */
3076
+ export declare const ErrorCodeRequirementsNotMet: ErrorCode;
3033
3077
  /**
3034
3078
  * ErrorCodeTeamRoleRequired: the caller's team role or org-admin status
3035
3079
  * does not allow the action. Meta is TeamRoleRequiredMeta when a
@@ -4723,6 +4767,11 @@ export interface SetupAction {
4723
4767
  * list comes from; sent back when the keys are saved.
4724
4768
  */
4725
4769
  provider_website?: string;
4770
+ /**
4771
+ * Instructions tell a person how to get what the provider's scheme
4772
+ * asks for (markdown, links allowed).
4773
+ */
4774
+ instructions?: string;
4726
4775
  }
4727
4776
  /**
4728
4777
  * CheckRequirementsRequest is the request body for checking requirements
@@ -5759,6 +5808,12 @@ export interface SecretField {
5759
5808
  placeholder?: string;
5760
5809
  sensitive?: boolean;
5761
5810
  optional?: boolean;
5811
+ /**
5812
+ * Pattern, when set, is a regular expression (RE2) a saved value must
5813
+ * match, so a pasted login link or the wrong key is refused on save
5814
+ * instead of failing the first run ("^sk-ant-oat01-").
5815
+ */
5816
+ pattern?: string;
5762
5817
  }
5763
5818
  /**
5764
5819
  * AuthMethodClientAuth is how client_id/client_secret reach the token
@@ -6650,6 +6705,12 @@ export declare const GraphEdgeTypeReferences: GraphEdgeType;
6650
6705
  export declare const GraphEdgeTypeSupersedes: GraphEdgeType;
6651
6706
  export declare const GraphEdgeTypeInput: GraphEdgeType;
6652
6707
  export declare const GraphEdgeTypeOutput: GraphEdgeType;
6708
+ /**
6709
+ * InterruptResourceTurn is an interrupt that holds a run's next turn before
6710
+ * its model call, with nothing in flight; its ResourceID is the run's. An
6711
+ * allow starts the turn, a deny ends the run.
6712
+ */
6713
+ export declare const InterruptResourceTurn: InterruptResourceType;
6653
6714
  /**
6654
6715
  * MergeStrategy defines how a delta field should be merged by consumers.
6655
6716
  */
@@ -7456,6 +7517,12 @@ export declare const TaskStatusUploading: TaskStatus;
7456
7517
  export declare const TaskStatusCompleted: TaskStatus;
7457
7518
  export declare const TaskStatusFailed: TaskStatus;
7458
7519
  export declare const TaskStatusCancelled: TaskStatus;
7520
+ /**
7521
+ * TaskStatusRejected is a run admission refused (no balance, no payment
7522
+ * method). The task is written already ended, keeping what was asked
7523
+ * for; it never ran and no status leads to it.
7524
+ */
7525
+ export declare const TaskStatusRejected: TaskStatus;
7459
7526
  /**
7460
7527
  * Infra defines where a task should run.
7461
7528
  */
@@ -7801,7 +7868,7 @@ export declare const InterruptResolutionDeny: InterruptResolution;
7801
7868
  /**
7802
7869
  * InterruptResourceType identifies the kind of resource an interrupt gates.
7803
7870
  */
7804
- export type InterruptResourceType = "tool_invocation" | "hook_event";
7871
+ export type InterruptResourceType = "turn" | "tool_invocation" | "hook_event";
7805
7872
  export declare const InterruptResourceToolInvocation: InterruptResourceType;
7806
7873
  export declare const InterruptResourceHookEvent: InterruptResourceType;
7807
7874
  /**
package/dist/types.js CHANGED
@@ -389,6 +389,12 @@ export const ErrorCodeNotConfigured = "not_configured";
389
389
  export const ErrorCodeMethodNotAllowed = "method_not_allowed";
390
390
  export const ErrorCodeRateLimited = "rate_limited";
391
391
  export const ErrorCodeInternalError = "internal_error";
392
+ /**
393
+ * ErrorCodeRequirementsNotMet (412): the run needs a secret or a
394
+ * credential the caller has not set up. Meta "errors" lists each
395
+ * RequirementError, its action saying how to set it up.
396
+ */
397
+ export const ErrorCodeRequirementsNotMet = "requirements_not_met";
392
398
  /**
393
399
  * ErrorCodeTeamRoleRequired: the caller's team role or org-admin status
394
400
  * does not allow the action. Meta is TeamRoleRequiredMeta when a
@@ -980,6 +986,12 @@ export const GraphEdgeTypeReferences = "references";
980
986
  export const GraphEdgeTypeSupersedes = "supersedes";
981
987
  export const GraphEdgeTypeInput = "input";
982
988
  export const GraphEdgeTypeOutput = "output";
989
+ /**
990
+ * InterruptResourceTurn is an interrupt that holds a run's next turn before
991
+ * its model call, with nothing in flight; its ResourceID is the run's. An
992
+ * allow starts the turn, a deny ends the run.
993
+ */
994
+ export const InterruptResourceTurn = "turn";
983
995
  export const MergeStrategyConcat = "concat";
984
996
  export const MergeStrategyReplace = "replace";
985
997
  export const MergeStrategyIndexed = "indexed";
@@ -1455,6 +1467,12 @@ export const TaskStatusUploading = 9;
1455
1467
  export const TaskStatusCompleted = 10;
1456
1468
  export const TaskStatusFailed = 11;
1457
1469
  export const TaskStatusCancelled = 12;
1470
+ /**
1471
+ * TaskStatusRejected is a run admission refused (no balance, no payment
1472
+ * method). The task is written already ended, keeping what was asked
1473
+ * for; it never ran and no status leads to it.
1474
+ */
1475
+ export const TaskStatusRejected = 13;
1458
1476
  export const InfraPrivate = "private";
1459
1477
  export const InfraCloud = "cloud";
1460
1478
  export const InfraPrivateFirst = "private_first";
package/dist/utils.d.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  * Status utilities for handling both int and string-based status values.
3
3
  * Provides future compatibility when API migrates from int to string status.
4
4
  */
5
+ import type { InterruptDTO } from './types.js';
5
6
  import { TaskStatus } from './types.js';
6
7
  import type { AgentRunState, ChatDTO, ChatMessageStatus } from './types.js';
7
8
  /**
@@ -10,7 +11,7 @@ import type { AgentRunState, ChatDTO, ChatMessageStatus } from './types.js';
10
11
  */
11
12
  export declare function parseStatus(status: number | string | undefined | null): TaskStatus;
12
13
  /**
13
- * Check if a task status is terminal (completed, failed, or cancelled).
14
+ * Check if a task status is terminal (completed, failed, cancelled, or rejected).
14
15
  * Handles both int and string status values.
15
16
  */
16
17
  export declare function isTerminalStatus(status: number | string | undefined | null): boolean;
@@ -39,3 +40,12 @@ export type PendingApproval = {
39
40
  * which the API projects onto the chat, so no message scan is needed.
40
41
  */
41
42
  export declare function pendingApprovals(chat: ChatDTO | null | undefined): PendingApproval[];
43
+ /** A run's next turn held for the person (InterruptResourceTurn): after a long stretch without them, it waits for "keep going" (allow) or "stop" (deny). */
44
+ export type HeldTurn = {
45
+ interruptId: string;
46
+ runId: string;
47
+ /** Steps the run took without the person, when the api says. */
48
+ steps: number | null;
49
+ };
50
+ /** The held turn among a run's pending interrupts, if one is held. */
51
+ export declare function heldTurn(interrupts: InterruptDTO[] | null | undefined): HeldTurn | null;
package/dist/utils.js CHANGED
@@ -2,8 +2,8 @@
2
2
  * Status utilities for handling both int and string-based status values.
3
3
  * Provides future compatibility when API migrates from int to string status.
4
4
  */
5
- import { InterruptReasonToolApproval, InterruptStatusPending } from './types.js';
6
- import { TaskStatusUnknown, TaskStatusReceived, TaskStatusQueued, TaskStatusDispatched, TaskStatusPreparing, TaskStatusServing, TaskStatusSettingUp, TaskStatusRunning, TaskStatusCancelling, TaskStatusUploading, TaskStatusCompleted, TaskStatusFailed, TaskStatusCancelled, AgentRunStateWorking, AgentRunStateSubmitted, AgentRunStateInputRequired, AgentRunStateAuthRequired, AgentRunStateCompleted, AgentRunStateFailed, AgentRunStateCanceled, AgentRunStateRejected, ChatMessageStatusReady, ChatMessageStatusFailed, ChatMessageStatusCancelled, ChatStatusBusy, ChatStatusAwaitingInput, } from './types.js';
5
+ import { InterruptReasonToolApproval, InterruptResourceTurn, InterruptStatusPending } from './types.js';
6
+ import { TaskStatusUnknown, TaskStatusReceived, TaskStatusQueued, TaskStatusDispatched, TaskStatusPreparing, TaskStatusServing, TaskStatusSettingUp, TaskStatusRunning, TaskStatusCancelling, TaskStatusUploading, TaskStatusCompleted, TaskStatusFailed, TaskStatusCancelled, TaskStatusRejected, AgentRunStateWorking, AgentRunStateSubmitted, AgentRunStateInputRequired, AgentRunStateAuthRequired, AgentRunStateCompleted, AgentRunStateFailed, AgentRunStateCanceled, AgentRunStateRejected, ChatMessageStatusReady, ChatMessageStatusFailed, ChatMessageStatusCancelled, ChatStatusBusy, ChatStatusAwaitingInput, } from './types.js';
7
7
  /** Map string status names to TaskStatus values (for future string-based API) */
8
8
  const STATUS_STRING_MAP = {
9
9
  unknown: TaskStatusUnknown,
@@ -19,6 +19,7 @@ const STATUS_STRING_MAP = {
19
19
  completed: TaskStatusCompleted,
20
20
  failed: TaskStatusFailed,
21
21
  cancelled: TaskStatusCancelled,
22
+ rejected: TaskStatusRejected,
22
23
  };
23
24
  /**
24
25
  * Parse task status from int or string to TaskStatus number.
@@ -37,12 +38,12 @@ export function parseStatus(status) {
37
38
  return TaskStatusUnknown;
38
39
  }
39
40
  /**
40
- * Check if a task status is terminal (completed, failed, or cancelled).
41
+ * Check if a task status is terminal (completed, failed, cancelled, or rejected).
41
42
  * Handles both int and string status values.
42
43
  */
43
44
  export function isTerminalStatus(status) {
44
45
  const parsed = parseStatus(status);
45
- return parsed === TaskStatusCompleted || parsed === TaskStatusFailed || parsed === TaskStatusCancelled;
46
+ return parsed === TaskStatusCompleted || parsed === TaskStatusFailed || parsed === TaskStatusCancelled || parsed === TaskStatusRejected;
46
47
  }
47
48
  // Run and message state predicates. Ports of the Go methods AgentRunState.IsTerminal/
48
49
  // IsInterrupted/IsSettled and ChatMessageStatus.IsTerminal; every consumer uses these.
@@ -79,7 +80,8 @@ export function isAwaitingHuman(chat) {
79
80
  return isRunInterrupted(run.state);
80
81
  return chat?.status === ChatStatusAwaitingInput;
81
82
  }
82
- function parseApprovalMeta(interrupt) {
83
+ /** An interrupt's meta, which arrives as an object or a JSON string. */
84
+ function parseMeta(interrupt) {
83
85
  const meta = interrupt.meta;
84
86
  if (!meta)
85
87
  return {};
@@ -104,7 +106,7 @@ export function pendingApprovals(chat) {
104
106
  if (interrupt.reason !== InterruptReasonToolApproval || interrupt.status !== InterruptStatusPending) {
105
107
  continue;
106
108
  }
107
- const meta = parseApprovalMeta(interrupt);
109
+ const meta = parseMeta(interrupt);
108
110
  out.push({
109
111
  interruptId: interrupt.id,
110
112
  toolInvocationId: interrupt.resource_id ?? meta.tool_invocation_id ?? '',
@@ -115,3 +117,11 @@ export function pendingApprovals(chat) {
115
117
  }
116
118
  return out;
117
119
  }
120
+ /** The held turn among a run's pending interrupts, if one is held. */
121
+ export function heldTurn(interrupts) {
122
+ const interrupt = interrupts?.find(i => i.resource_type === InterruptResourceTurn && i.status === InterruptStatusPending);
123
+ if (!interrupt)
124
+ return null;
125
+ const { steps } = parseMeta(interrupt);
126
+ return { interruptId: interrupt.id, runId: interrupt.run_id, steps: typeof steps === 'number' ? steps : null };
127
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inferencesh/sdk",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
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",