@inferencesh/sdk 0.31.0 → 0.32.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 +10 -0
- package/dist/agent/actions.js +20 -3
- package/dist/agent/api.d.ts +4 -20
- package/dist/agent/api.js +5 -25
- package/dist/agent/types.d.ts +4 -2
- package/dist/api/agents.d.ts +4 -2
- package/dist/api/agents.js +5 -3
- package/dist/types.d.ts +12 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
### Changed
|
|
11
|
+
- `approveTool` and `rejectTool` resolve the call's interrupt (`POST /interrupts/{id}/resolve`), the same answer as every other pause (a wait, a hook gate, a held turn); they no longer post to `/tools/{id}/invoke|reject`. A call that is not awaiting approval rejects with "Tool call … is not awaiting approval".
|
|
12
|
+
- `resolveInterrupt` (agent actions and `AgentsAPI`) takes an optional `reason`, sent with a deny as `data.reason`.
|
|
13
|
+
|
|
14
|
+
## [0.31.0] - 2026-10-19
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- `pendingWait(interrupts)` and `PendingWait`: the wait a run is paused on by its agent's wait tool (`InterruptReasonWait`), with when it ends and the agent's note.
|
|
18
|
+
- Generated types: `InternalToolsConfig.wait`, `AgentTool.approval_timeout` (seconds a call waits for approval before it is refused), `InterruptReasonWait`.
|
|
19
|
+
|
|
10
20
|
## [0.30.0] - 2026-10-18
|
|
11
21
|
|
|
12
22
|
### Removed
|
package/dist/agent/actions.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* These are created once per provider instance with access to dispatch.
|
|
6
6
|
*/
|
|
7
7
|
import { ToolInvocationStatusAwaitingInput, ToolInvocationStatusInProgress, ToolTypeClient, } from '../types.js';
|
|
8
|
-
import { isChatBusy, isMessageTerminal, isRunInterrupted, isRunWorking } from '../utils.js';
|
|
8
|
+
import { approvalInterrupt, isChatBusy, isMessageTerminal, isRunInterrupted, isRunWorking } from '../utils.js';
|
|
9
9
|
import { StreamableManager } from '../http/streamable.js';
|
|
10
10
|
import { PollManager } from '../http/poll.js';
|
|
11
11
|
import { createLLMDeltaAccumulator } from '../delta.js';
|
|
@@ -29,6 +29,23 @@ function isTransient(err) {
|
|
|
29
29
|
export function createActions(ctx) {
|
|
30
30
|
const dispatchedToolInvocations = new Set();
|
|
31
31
|
const { client, dispatch, getState, getConfig, getChatId, getClientToolHandlers, getStreamManager, setStreamManager, getStreamEnabled, getPollIntervalMs, callbacks } = ctx;
|
|
32
|
+
/**
|
|
33
|
+
* The interrupt a call awaiting approval waits on: approving or rejecting
|
|
34
|
+
* the call resolves it, like every other pause. The chat's pending
|
|
35
|
+
* interrupts carry it; when they have not caught up with the call yet, the
|
|
36
|
+
* run's are read from the api.
|
|
37
|
+
*/
|
|
38
|
+
const approvalInterruptId = async (toolInvocationId) => {
|
|
39
|
+
const chat = getState().chat;
|
|
40
|
+
let interrupt = approvalInterrupt(chat?.pending_interrupts, toolInvocationId);
|
|
41
|
+
const runId = chat?.active_run?.id;
|
|
42
|
+
if (!interrupt && runId) {
|
|
43
|
+
interrupt = approvalInterrupt(await api.listRunInterrupts(client, runId), toolInvocationId);
|
|
44
|
+
}
|
|
45
|
+
if (!interrupt)
|
|
46
|
+
throw new Error(`Tool call ${toolInvocationId} is not awaiting approval`);
|
|
47
|
+
return interrupt.id;
|
|
48
|
+
};
|
|
32
49
|
let prevChatWasBusy = false;
|
|
33
50
|
// Bumped by every streamChat() and stopStream(). A stream whose generation
|
|
34
51
|
// is no longer current (stopped, reset, switched to another chat) leaves
|
|
@@ -453,7 +470,7 @@ export function createActions(ctx) {
|
|
|
453
470
|
},
|
|
454
471
|
approveTool: async (toolInvocationId) => {
|
|
455
472
|
try {
|
|
456
|
-
await api.
|
|
473
|
+
await api.resolveInterrupt(client, await approvalInterruptId(toolInvocationId), 'allow');
|
|
457
474
|
}
|
|
458
475
|
catch (error) {
|
|
459
476
|
console.error('[AgentSDK] Failed to approve tool:', error);
|
|
@@ -466,7 +483,7 @@ export function createActions(ctx) {
|
|
|
466
483
|
},
|
|
467
484
|
rejectTool: async (toolInvocationId, reason) => {
|
|
468
485
|
try {
|
|
469
|
-
await api.
|
|
486
|
+
await api.resolveInterrupt(client, await approvalInterruptId(toolInvocationId), 'deny', reason);
|
|
470
487
|
}
|
|
471
488
|
catch (error) {
|
|
472
489
|
console.error('[AgentSDK] Failed to reject tool:', error);
|
package/dist/agent/api.d.ts
CHANGED
|
@@ -46,24 +46,6 @@ export declare function submitToolResult(client: AgentClient, toolInvocationId:
|
|
|
46
46
|
};
|
|
47
47
|
form_data?: Record<string, unknown>;
|
|
48
48
|
}, attachments?: FileRef[]): Promise<void>;
|
|
49
|
-
/**
|
|
50
|
-
* Approve a call awaiting approval; the api then runs it.
|
|
51
|
-
*
|
|
52
|
-
* Needs approvals:write, which only the account holder's own sign-in holds
|
|
53
|
-
* (the web app, or a `belt login` session). An API key, an app's OAuth token
|
|
54
|
-
* or the server proxy is refused with 403 `requires_sign_in`
|
|
55
|
-
* (ErrorCodeRequiresSignIn); the error's message says what to do.
|
|
56
|
-
*/
|
|
57
|
-
export declare function approveTool(client: AgentClient, toolInvocationId: string): Promise<void>;
|
|
58
|
-
/**
|
|
59
|
-
* Reject a call awaiting approval, with an optional reason the agent sees.
|
|
60
|
-
*
|
|
61
|
-
* Needs approvals:write, which only the account holder's own sign-in holds
|
|
62
|
-
* (the web app, or a `belt login` session). An API key, an app's OAuth token
|
|
63
|
-
* or the server proxy is refused with 403 `requires_sign_in`
|
|
64
|
-
* (ErrorCodeRequiresSignIn); the error's message says what to do.
|
|
65
|
-
*/
|
|
66
|
-
export declare function rejectTool(client: AgentClient, toolInvocationId: string, reason?: string): Promise<void>;
|
|
67
49
|
/**
|
|
68
50
|
* What "always allow" can save for a call awaiting approval, narrowest first.
|
|
69
51
|
* The api computes the options from the call; each one, saved, answers it again.
|
|
@@ -94,14 +76,16 @@ export declare function explainTool(client: AgentClient, chatId: string, toolInv
|
|
|
94
76
|
*/
|
|
95
77
|
export declare function updateChatSettings(client: AgentClient, chatId: string, settings: ChatSettingsRequest): Promise<ChatSettingsDTO>;
|
|
96
78
|
/**
|
|
97
|
-
* Allow or deny an interrupt
|
|
79
|
+
* Allow or deny an interrupt on an agent run: a tool call waiting for
|
|
80
|
+
* approval, a wait, a hook gate or a held turn, all the same way. `reason`,
|
|
81
|
+
* with deny, goes back to the agent with the refused call.
|
|
98
82
|
*
|
|
99
83
|
* Needs approvals:write, which only the account holder's own sign-in holds
|
|
100
84
|
* (the web app, or a `belt login` session). An API key, an app's OAuth token
|
|
101
85
|
* or the server proxy is refused with 403 `requires_sign_in`
|
|
102
86
|
* (ErrorCodeRequiresSignIn); the error's message says what to do.
|
|
103
87
|
*/
|
|
104
|
-
export declare function resolveInterrupt(client: AgentClient, interruptId: string, decision: 'allow' | 'deny'): Promise<InterruptDTO>;
|
|
88
|
+
export declare function resolveInterrupt(client: AgentClient, interruptId: string, decision: 'allow' | 'deny', reason?: string): Promise<InterruptDTO>;
|
|
105
89
|
export declare function listRunInterrupts(client: AgentClient, runId: string): Promise<InterruptDTO[]>;
|
|
106
90
|
export declare function uploadFile(client: AgentClient, file: globalThis.File): Promise<FileRef>;
|
|
107
91
|
export declare function chatStreamRequest(client: AgentClient, chatId: string): StreamRequest;
|
package/dist/agent/api.js
CHANGED
|
@@ -151,28 +151,6 @@ export async function submitToolResult(client, toolInvocationId, resultOrAction,
|
|
|
151
151
|
}
|
|
152
152
|
await client.http.request('post', `/tools/${toolInvocationId}`, { data });
|
|
153
153
|
}
|
|
154
|
-
/**
|
|
155
|
-
* Approve a call awaiting approval; the api then runs it.
|
|
156
|
-
*
|
|
157
|
-
* Needs approvals:write, which only the account holder's own sign-in holds
|
|
158
|
-
* (the web app, or a `belt login` session). An API key, an app's OAuth token
|
|
159
|
-
* or the server proxy is refused with 403 `requires_sign_in`
|
|
160
|
-
* (ErrorCodeRequiresSignIn); the error's message says what to do.
|
|
161
|
-
*/
|
|
162
|
-
export async function approveTool(client, toolInvocationId) {
|
|
163
|
-
await client.http.request('post', `/tools/${toolInvocationId}/invoke`);
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Reject a call awaiting approval, with an optional reason the agent sees.
|
|
167
|
-
*
|
|
168
|
-
* Needs approvals:write, which only the account holder's own sign-in holds
|
|
169
|
-
* (the web app, or a `belt login` session). An API key, an app's OAuth token
|
|
170
|
-
* or the server proxy is refused with 403 `requires_sign_in`
|
|
171
|
-
* (ErrorCodeRequiresSignIn); the error's message says what to do.
|
|
172
|
-
*/
|
|
173
|
-
export async function rejectTool(client, toolInvocationId, reason) {
|
|
174
|
-
await client.http.request('post', `/tools/${toolInvocationId}/reject`, { data: { reason } });
|
|
175
|
-
}
|
|
176
154
|
/**
|
|
177
155
|
* What "always allow" can save for a call awaiting approval, narrowest first.
|
|
178
156
|
* The api computes the options from the call; each one, saved, answers it again.
|
|
@@ -219,16 +197,18 @@ export async function updateChatSettings(client, chatId, settings) {
|
|
|
219
197
|
// Interrupt operations
|
|
220
198
|
// =========================================================================
|
|
221
199
|
/**
|
|
222
|
-
* Allow or deny an interrupt
|
|
200
|
+
* Allow or deny an interrupt on an agent run: a tool call waiting for
|
|
201
|
+
* approval, a wait, a hook gate or a held turn, all the same way. `reason`,
|
|
202
|
+
* with deny, goes back to the agent with the refused call.
|
|
223
203
|
*
|
|
224
204
|
* Needs approvals:write, which only the account holder's own sign-in holds
|
|
225
205
|
* (the web app, or a `belt login` session). An API key, an app's OAuth token
|
|
226
206
|
* or the server proxy is refused with 403 `requires_sign_in`
|
|
227
207
|
* (ErrorCodeRequiresSignIn); the error's message says what to do.
|
|
228
208
|
*/
|
|
229
|
-
export async function resolveInterrupt(client, interruptId, decision) {
|
|
209
|
+
export async function resolveInterrupt(client, interruptId, decision, reason) {
|
|
230
210
|
const resp = await client.http.request('post', `/interrupts/${interruptId}/resolve`, {
|
|
231
|
-
data: { decision }
|
|
211
|
+
data: reason ? { decision, data: { reason } } : { decision }
|
|
232
212
|
});
|
|
233
213
|
return resp.data;
|
|
234
214
|
}
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -134,7 +134,8 @@ export interface AgentChatActions {
|
|
|
134
134
|
/** Answer an MCP tool call's input requests (AwaitingInput status with MCPInputState data) */
|
|
135
135
|
submitMCPInput: (toolInvocationId: string, responses: Record<string, ElicitResult>) => Promise<void>;
|
|
136
136
|
/**
|
|
137
|
-
* Approve a tool (for HIL approval - AwaitingApproval status)
|
|
137
|
+
* Approve a tool (for HIL approval - AwaitingApproval status). Resolves the
|
|
138
|
+
* call's interrupt with allow, as resolveInterrupt does for every pause.
|
|
138
139
|
*
|
|
139
140
|
* Needs the account holder's own sign-in (approvals:write): with an API
|
|
140
141
|
* key, an app's token or the server proxy it rejects with 403
|
|
@@ -142,7 +143,8 @@ export interface AgentChatActions {
|
|
|
142
143
|
*/
|
|
143
144
|
approveTool: (toolInvocationId: string) => Promise<void>;
|
|
144
145
|
/**
|
|
145
|
-
* Reject a tool (for HIL approval - AwaitingApproval status)
|
|
146
|
+
* Reject a tool (for HIL approval - AwaitingApproval status). Resolves the
|
|
147
|
+
* call's interrupt with deny; `reason` goes back to the agent.
|
|
146
148
|
*
|
|
147
149
|
* Needs the account holder's own sign-in (approvals:write): with an API
|
|
148
150
|
* key, an app's token or the server proxy it rejects with 403
|
package/dist/api/agents.d.ts
CHANGED
|
@@ -219,13 +219,15 @@ export declare class AgentsAPI {
|
|
|
219
219
|
form_data?: Record<string, unknown>;
|
|
220
220
|
}, attachments?: FileRef[]): Promise<void>;
|
|
221
221
|
/**
|
|
222
|
-
* Resolve an interrupt
|
|
222
|
+
* Resolve an interrupt on an agent run: a tool call waiting for approval, a
|
|
223
|
+
* wait, a hook gate or a held turn, all the same way. `reason`, with deny,
|
|
224
|
+
* goes back to the agent with the refused call.
|
|
223
225
|
*
|
|
224
226
|
* Needs approvals:write, which only the account holder's own sign-in holds:
|
|
225
227
|
* with an API key, an app's OAuth token or the server proxy it rejects with
|
|
226
228
|
* 403 `requires_sign_in` (ErrorCodeRequiresSignIn).
|
|
227
229
|
*/
|
|
228
|
-
resolveInterrupt(interruptId: string, decision: 'allow' | 'deny'): Promise<Response<InterruptDTO>>;
|
|
230
|
+
resolveInterrupt(interruptId: string, decision: 'allow' | 'deny', reason?: string): Promise<Response<InterruptDTO>>;
|
|
229
231
|
/**
|
|
230
232
|
* List pending interrupts for an agent run
|
|
231
233
|
*/
|
package/dist/api/agents.js
CHANGED
|
@@ -522,15 +522,17 @@ export class AgentsAPI {
|
|
|
522
522
|
await this.http.request('post', `/tools/${toolInvocationId}`, { data });
|
|
523
523
|
}
|
|
524
524
|
/**
|
|
525
|
-
* Resolve an interrupt
|
|
525
|
+
* Resolve an interrupt on an agent run: a tool call waiting for approval, a
|
|
526
|
+
* wait, a hook gate or a held turn, all the same way. `reason`, with deny,
|
|
527
|
+
* goes back to the agent with the refused call.
|
|
526
528
|
*
|
|
527
529
|
* Needs approvals:write, which only the account holder's own sign-in holds:
|
|
528
530
|
* with an API key, an app's OAuth token or the server proxy it rejects with
|
|
529
531
|
* 403 `requires_sign_in` (ErrorCodeRequiresSignIn).
|
|
530
532
|
*/
|
|
531
|
-
async resolveInterrupt(interruptId, decision) {
|
|
533
|
+
async resolveInterrupt(interruptId, decision, reason) {
|
|
532
534
|
return this.http.request('post', `/interrupts/${interruptId}/resolve`, {
|
|
533
|
-
data: { decision }
|
|
535
|
+
data: reason ? { decision, data: { reason } } : { decision }
|
|
534
536
|
});
|
|
535
537
|
}
|
|
536
538
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -5087,7 +5087,13 @@ export interface TaskLog {
|
|
|
5087
5087
|
}
|
|
5088
5088
|
/**
|
|
5089
5089
|
* TaskDTO is the full API response for a task.
|
|
5090
|
+
* TaskEgress is what a task's sandbox sent to and received from the
|
|
5091
|
+
* internet through the engine's egress gateway, in bytes.
|
|
5090
5092
|
*/
|
|
5093
|
+
export interface TaskEgress {
|
|
5094
|
+
bytes_out: number;
|
|
5095
|
+
bytes_in: number;
|
|
5096
|
+
}
|
|
5091
5097
|
export interface TaskDTO extends BaseModelDTO, PermissionModelDTO {
|
|
5092
5098
|
graph_id?: string;
|
|
5093
5099
|
user_public_key: string;
|
|
@@ -5121,6 +5127,12 @@ export interface TaskDTO extends BaseModelDTO, PermissionModelDTO {
|
|
|
5121
5127
|
events: TaskEvent[];
|
|
5122
5128
|
logs: TaskLog[];
|
|
5123
5129
|
usage_events: (UsageEventDTO | undefined)[];
|
|
5130
|
+
/**
|
|
5131
|
+
* Egress is what the task's sandbox moved through the engine's egress
|
|
5132
|
+
* gateway, reported by the engine when the task ended. Absent for a
|
|
5133
|
+
* task that ran without the gateway.
|
|
5134
|
+
*/
|
|
5135
|
+
egress?: TaskEgress;
|
|
5124
5136
|
session_id?: string;
|
|
5125
5137
|
session_timeout?: number;
|
|
5126
5138
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export type HeldTurn = {
|
|
|
49
49
|
};
|
|
50
50
|
/** The held turn among a run's pending interrupts, if one is held. */
|
|
51
51
|
export declare function heldTurn(interrupts: InterruptDTO[] | null | undefined): HeldTurn | null;
|
|
52
|
+
/** The interrupt a tool call awaiting approval waits on, among a chat's or a run's pending interrupts. */
|
|
53
|
+
export declare function approvalInterrupt(interrupts: InterruptDTO[] | null | undefined, toolInvocationId: string): InterruptDTO | undefined;
|
|
52
54
|
/** A run paused by its agent's wait tool (InterruptReasonWait): it continues at `until`, or sooner when the person ends the wait ("continue now", allow) or cancels it (deny). */
|
|
53
55
|
export type PendingWait = {
|
|
54
56
|
interruptId: string;
|
package/dist/utils.js
CHANGED
|
@@ -129,6 +129,10 @@ export function heldTurn(interrupts) {
|
|
|
129
129
|
const { steps } = parseMeta(interrupt);
|
|
130
130
|
return { interruptId: interrupt.id, runId: interrupt.run_id, steps: typeof steps === 'number' ? steps : null };
|
|
131
131
|
}
|
|
132
|
+
/** The interrupt a tool call awaiting approval waits on, among a chat's or a run's pending interrupts. */
|
|
133
|
+
export function approvalInterrupt(interrupts, toolInvocationId) {
|
|
134
|
+
return pendingInterrupt(interrupts, i => i.reason === InterruptReasonToolApproval && (i.resource_id || parseMeta(i).tool_invocation_id) === toolInvocationId);
|
|
135
|
+
}
|
|
132
136
|
/** The wait among a run's pending interrupts, if the run is waiting. */
|
|
133
137
|
export function pendingWait(interrupts) {
|
|
134
138
|
const interrupt = pendingInterrupt(interrupts, i => i.reason === InterruptReasonWait);
|