@inferencesh/sdk 0.31.0 → 0.33.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 +26 -0
- package/dist/agent/actions.js +27 -9
- package/dist/agent/api.d.ts +4 -20
- package/dist/agent/api.js +7 -25
- package/dist/agent/reducer.js +54 -29
- package/dist/agent/types.d.ts +11 -3
- package/dist/api/agents.d.ts +4 -2
- package/dist/api/agents.js +5 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/proxy/endpoints.json +0 -1
- package/dist/types.d.ts +149 -13
- package/dist/types.js +71 -2
- package/dist/utils.d.ts +6 -2
- package/dist/utils.js +12 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.33.0] - 2026-10-24
|
|
11
|
+
|
|
12
|
+
### Breaking
|
|
13
|
+
- `AuthResponse.otp_method` is gone: read `otp_methods`, the ordered `SecondFactor[]` (`totp`, `passkey`, `recovery`, `email`) a sign-in may be finished with.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- The agent reducer applies streamed reasoning as it arrives; before, only text streamed.
|
|
17
|
+
- `AgentInfo.model_capabilities`: what the agent's model takes besides text (`image`, `file`, ...), from its core app version.
|
|
18
|
+
- `isRunWaiting(run)`. A chat whose run waits on the agent's own wait call (`ChatStatusWaiting`) counts as an open turn, not as one needing a person.
|
|
19
|
+
- Generated types: `ChatStatusWaiting`, `ToolInvocationStatusWaiting`, `ChatEventTypeRunFailed`, `ChatEventTypeRunEnded`, `ChatRunEvent`, `RunEndReason`, `SecondFactor`, `InfraRemote`, `ScopeContentWrite`, `ErrorCodeLastAuthenticator`, `InstancePriceHistoryPointDTO`, app capability and remote llm direct mode types.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Proxy endpoints: cancelling a queued message needs `conversations:write` only.
|
|
23
|
+
|
|
24
|
+
## [0.32.0] - 2026-10-20
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- `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".
|
|
28
|
+
- `resolveInterrupt` (agent actions and `AgentsAPI`) takes an optional `reason`, sent with a deny as `data.reason`.
|
|
29
|
+
|
|
30
|
+
## [0.31.0] - 2026-10-19
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- `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.
|
|
34
|
+
- Generated types: `InternalToolsConfig.wait`, `AgentTool.approval_timeout` (seconds a call waits for approval before it is refused), `InterruptReasonWait`.
|
|
35
|
+
|
|
10
36
|
## [0.30.0] - 2026-10-18
|
|
11
37
|
|
|
12
38
|
### 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
|
|
@@ -375,13 +392,14 @@ export function createActions(ctx) {
|
|
|
375
392
|
const result = await api.sendMessage(client, agentConfig, chatId, trimmedText, files);
|
|
376
393
|
if (result) {
|
|
377
394
|
const { chatId: newChatId, userMessage } = result;
|
|
378
|
-
//
|
|
379
|
-
|
|
395
|
+
// An open SSE stream owns the message: it may already have moved it
|
|
396
|
+
// on (a message that ends a wait is taken up before this response
|
|
397
|
+
// returns). Polling refetches only when the chat's status changes,
|
|
398
|
+
// so it shows the response, as does a chat with no stream yet.
|
|
399
|
+
const manager = getStreamManager();
|
|
400
|
+
if (userMessage && !(manager instanceof StreamableManager))
|
|
380
401
|
dispatch({ type: 'UPDATE_MESSAGE', payload: userMessage });
|
|
381
|
-
|
|
382
|
-
const streamManager = getStreamManager();
|
|
383
|
-
if (newChatId && !streamManager) {
|
|
384
|
-
// Either new chat or stream was stopped - restart streaming
|
|
402
|
+
if (newChatId && !manager) {
|
|
385
403
|
if (!chatId) {
|
|
386
404
|
dispatch({ type: 'SET_CHAT_ID', payload: newChatId });
|
|
387
405
|
callbacks.onChatCreated?.(newChatId);
|
|
@@ -453,7 +471,7 @@ export function createActions(ctx) {
|
|
|
453
471
|
},
|
|
454
472
|
approveTool: async (toolInvocationId) => {
|
|
455
473
|
try {
|
|
456
|
-
await api.
|
|
474
|
+
await api.resolveInterrupt(client, await approvalInterruptId(toolInvocationId), 'allow');
|
|
457
475
|
}
|
|
458
476
|
catch (error) {
|
|
459
477
|
console.error('[AgentSDK] Failed to approve tool:', error);
|
|
@@ -466,7 +484,7 @@ export function createActions(ctx) {
|
|
|
466
484
|
},
|
|
467
485
|
rejectTool: async (toolInvocationId, reason) => {
|
|
468
486
|
try {
|
|
469
|
-
await api.
|
|
487
|
+
await api.resolveInterrupt(client, await approvalInterruptId(toolInvocationId), 'deny', reason);
|
|
470
488
|
}
|
|
471
489
|
catch (error) {
|
|
472
490
|
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
|
@@ -76,9 +76,11 @@ export async function fetchAgentInfo(client, agentRef) {
|
|
|
76
76
|
try {
|
|
77
77
|
const resp = await client.http.request('get', `/agents/${agentRef}`);
|
|
78
78
|
const version = resp.data?.version;
|
|
79
|
+
const capabilities = version?.core_app?.app?.version?.metadata?.capabilities;
|
|
79
80
|
return {
|
|
80
81
|
description: version?.description,
|
|
81
82
|
example_prompts: version?.example_prompts,
|
|
83
|
+
model_capabilities: Array.isArray(capabilities) ? capabilities : undefined,
|
|
82
84
|
};
|
|
83
85
|
}
|
|
84
86
|
catch {
|
|
@@ -151,28 +153,6 @@ export async function submitToolResult(client, toolInvocationId, resultOrAction,
|
|
|
151
153
|
}
|
|
152
154
|
await client.http.request('post', `/tools/${toolInvocationId}`, { data });
|
|
153
155
|
}
|
|
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
156
|
/**
|
|
177
157
|
* What "always allow" can save for a call awaiting approval, narrowest first.
|
|
178
158
|
* The api computes the options from the call; each one, saved, answers it again.
|
|
@@ -219,16 +199,18 @@ export async function updateChatSettings(client, chatId, settings) {
|
|
|
219
199
|
// Interrupt operations
|
|
220
200
|
// =========================================================================
|
|
221
201
|
/**
|
|
222
|
-
* Allow or deny an interrupt
|
|
202
|
+
* Allow or deny an interrupt on an agent run: a tool call waiting for
|
|
203
|
+
* approval, a wait, a hook gate or a held turn, all the same way. `reason`,
|
|
204
|
+
* with deny, goes back to the agent with the refused call.
|
|
223
205
|
*
|
|
224
206
|
* Needs approvals:write, which only the account holder's own sign-in holds
|
|
225
207
|
* (the web app, or a `belt login` session). An API key, an app's OAuth token
|
|
226
208
|
* or the server proxy is refused with 403 `requires_sign_in`
|
|
227
209
|
* (ErrorCodeRequiresSignIn); the error's message says what to do.
|
|
228
210
|
*/
|
|
229
|
-
export async function resolveInterrupt(client, interruptId, decision) {
|
|
211
|
+
export async function resolveInterrupt(client, interruptId, decision, reason) {
|
|
230
212
|
const resp = await client.http.request('post', `/interrupts/${interruptId}/resolve`, {
|
|
231
|
-
data: { decision }
|
|
213
|
+
data: reason ? { decision, data: { reason } } : { decision }
|
|
232
214
|
});
|
|
233
215
|
return resp.data;
|
|
234
216
|
}
|
package/dist/agent/reducer.js
CHANGED
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Pure reducer for managing agent chat state.
|
|
5
5
|
*/
|
|
6
|
-
import { ChatStatusBusy, ChatStatusAwaitingInput, ChatStatusIdle } from '../types.js';
|
|
7
|
-
import { isMessageTerminal, isRunInterrupted, isRunWorking } from '../utils.js';
|
|
6
|
+
import { ChatMessageContentTypeReasoning, ChatMessageContentTypeText, ChatStatusBusy, ChatStatusAwaitingInput, ChatStatusIdle, ChatStatusWaiting, } from '../types.js';
|
|
7
|
+
import { isMessageTerminal, isRunInterrupted, isRunWaiting, isRunWorking } from '../utils.js';
|
|
8
8
|
function deriveChatStatus(run) {
|
|
9
9
|
if (!run)
|
|
10
10
|
return ChatStatusIdle;
|
|
11
11
|
if (isRunWorking(run.state))
|
|
12
12
|
return ChatStatusBusy;
|
|
13
|
+
if (isRunWaiting(run))
|
|
14
|
+
return ChatStatusWaiting;
|
|
13
15
|
if (isRunInterrupted(run.state))
|
|
14
16
|
return ChatStatusAwaitingInput;
|
|
15
17
|
return ChatStatusIdle;
|
|
@@ -60,26 +62,55 @@ function normalizeMessage(message, existing) {
|
|
|
60
62
|
return { ...message, content: existing?.content ?? [] };
|
|
61
63
|
}
|
|
62
64
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* lag behind them (often still empty). Taking that copy as-is blanks the text
|
|
66
|
-
* until the next delta, so while the message is still generating, a text
|
|
67
|
-
* that is an earlier version of what is shown keeps what is shown. Once the
|
|
68
|
-
* message is terminal the server's copy is final and wins.
|
|
65
|
+
* The content blocks deltas stream, and the delta field each is built from.
|
|
66
|
+
* An optional block gets no block until something streams into it.
|
|
69
67
|
*/
|
|
70
|
-
|
|
68
|
+
const streamedBlocks = [
|
|
69
|
+
{ type: ChatMessageContentTypeText, field: 'response', optional: false },
|
|
70
|
+
{ type: ChatMessageContentTypeReasoning, field: 'reasoning', optional: true },
|
|
71
|
+
];
|
|
72
|
+
/** content with the block of type set to text, added in front when missing. */
|
|
73
|
+
function withBlockText(content, type, text) {
|
|
74
|
+
return content.some((c) => c.type === type)
|
|
75
|
+
? content.map((c) => (c.type === type ? { ...c, text } : c))
|
|
76
|
+
: [{ type, text }, ...content];
|
|
77
|
+
}
|
|
78
|
+
const blockText = (message, type) => message.content.find((c) => c.type === type)?.text;
|
|
79
|
+
/** copy is an earlier version of shown: shown already has all of it and more. */
|
|
80
|
+
const isBehind = (copy, shown) => !!shown && shown.startsWith(copy ?? '');
|
|
81
|
+
/**
|
|
82
|
+
* Streamed text and reasoning only grow until the message is done. Deltas
|
|
83
|
+
* build them locally, while a message update carries the server's saved
|
|
84
|
+
* copy, which can lag behind them (often still empty). While the message is
|
|
85
|
+
* generating, a server copy behind what is shown keeps what is shown. Once
|
|
86
|
+
* the message is terminal the server's copy is final and wins.
|
|
87
|
+
*/
|
|
88
|
+
function keepStreamedBlocks(updated, existing) {
|
|
71
89
|
if (isMessageTerminal(updated.status))
|
|
72
90
|
return updated;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
91
|
+
let content = updated.content;
|
|
92
|
+
for (const { type } of streamedBlocks) {
|
|
93
|
+
const shown = blockText(existing, type);
|
|
94
|
+
if (isBehind(blockText(updated, type), shown))
|
|
95
|
+
content = withBlockText(content, type, shown);
|
|
96
|
+
}
|
|
97
|
+
return content === updated.content ? updated : { ...updated, content };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The message with what the deltas have built so far. Deltas from a stream
|
|
101
|
+
* joined mid-message start partway, behind what the message already shows,
|
|
102
|
+
* so the message keeps its copy until they catch up.
|
|
103
|
+
*/
|
|
104
|
+
function applyStreamedOutput(message, output) {
|
|
105
|
+
let content = message.content;
|
|
106
|
+
for (const { type, field, optional } of streamedBlocks) {
|
|
107
|
+
const streamed = output[field];
|
|
108
|
+
if (optional && !streamed)
|
|
109
|
+
continue;
|
|
110
|
+
if (!isBehind(streamed, blockText(message, type)))
|
|
111
|
+
content = withBlockText(content, type, streamed);
|
|
112
|
+
}
|
|
113
|
+
return content === message.content ? message : { ...message, content };
|
|
83
114
|
}
|
|
84
115
|
const normalizeMessages = (messages) => messages.map((m) => normalizeMessage(m));
|
|
85
116
|
// =============================================================================
|
|
@@ -182,7 +213,7 @@ export function chatReducer(state, action) {
|
|
|
182
213
|
const existingIndex = state.messages.findIndex((m) => m.id === message.id);
|
|
183
214
|
if (existingIndex !== -1) {
|
|
184
215
|
const existing = state.messages[existingIndex];
|
|
185
|
-
const updated =
|
|
216
|
+
const updated = keepStreamedBlocks(action.partial ? normalizeMessage({ ...existing, ...message }, existing) : normalizeMessage(message), existing);
|
|
186
217
|
if (existing === updated)
|
|
187
218
|
return state;
|
|
188
219
|
const newMessages = [...state.messages];
|
|
@@ -207,16 +238,10 @@ export function chatReducer(state, action) {
|
|
|
207
238
|
const target = msgs.find(m => m.id === messageId);
|
|
208
239
|
if (!target)
|
|
209
240
|
return state;
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
// update already showed more, so keep it until they catch up.
|
|
213
|
-
if (textBlock?.text && textBlock.text.startsWith(output.response ?? ''))
|
|
241
|
+
const next = applyStreamedOutput(target, output);
|
|
242
|
+
if (next === target)
|
|
214
243
|
return state;
|
|
215
|
-
|
|
216
|
-
? target.content.map(c => c.type === 'text' ? { ...c, text: output.response } : c)
|
|
217
|
-
: [{ type: 'text', text: output.response }, ...target.content];
|
|
218
|
-
const newMessages = msgs.map(m => m.id === target.id ? { ...target, content: newContent } : m);
|
|
219
|
-
return { ...state, messages: newMessages };
|
|
244
|
+
return { ...state, messages: msgs.map(m => (m.id === target.id ? next : m)) };
|
|
220
245
|
}
|
|
221
246
|
case 'SET_CONNECTION_STATUS':
|
|
222
247
|
return { ...state, connectionStatus: action.payload };
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -89,7 +89,13 @@ export declare function isTemplateConfig(config: AgentOptions): config is Templa
|
|
|
89
89
|
/**
|
|
90
90
|
* Agent metadata fetched from the backend for template configs
|
|
91
91
|
*/
|
|
92
|
-
export type AgentInfo = Partial<Pick<AgentVersionDTO, 'description' | 'example_prompts'
|
|
92
|
+
export type AgentInfo = Partial<Pick<AgentVersionDTO, 'description' | 'example_prompts'>> & {
|
|
93
|
+
/**
|
|
94
|
+
* What the agent's model takes besides text ("image", "file", ...), from
|
|
95
|
+
* its app version. Undefined when unknown; then assume everything.
|
|
96
|
+
*/
|
|
97
|
+
model_capabilities?: string[];
|
|
98
|
+
};
|
|
93
99
|
/**
|
|
94
100
|
* Status of the chat
|
|
95
101
|
*/
|
|
@@ -134,7 +140,8 @@ export interface AgentChatActions {
|
|
|
134
140
|
/** Answer an MCP tool call's input requests (AwaitingInput status with MCPInputState data) */
|
|
135
141
|
submitMCPInput: (toolInvocationId: string, responses: Record<string, ElicitResult>) => Promise<void>;
|
|
136
142
|
/**
|
|
137
|
-
* Approve a tool (for HIL approval - AwaitingApproval status)
|
|
143
|
+
* Approve a tool (for HIL approval - AwaitingApproval status). Resolves the
|
|
144
|
+
* call's interrupt with allow, as resolveInterrupt does for every pause.
|
|
138
145
|
*
|
|
139
146
|
* Needs the account holder's own sign-in (approvals:write): with an API
|
|
140
147
|
* key, an app's token or the server proxy it rejects with 403
|
|
@@ -142,7 +149,8 @@ export interface AgentChatActions {
|
|
|
142
149
|
*/
|
|
143
150
|
approveTool: (toolInvocationId: string) => Promise<void>;
|
|
144
151
|
/**
|
|
145
|
-
* Reject a tool (for HIL approval - AwaitingApproval status)
|
|
152
|
+
* Reject a tool (for HIL approval - AwaitingApproval status). Resolves the
|
|
153
|
+
* call's interrupt with deny; `reason` goes back to the agent.
|
|
146
154
|
*
|
|
147
155
|
* Needs the account holder's own sign-in (approvals:write): with an API
|
|
148
156
|
* 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/index.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ 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, heldTurn, pendingWait, } from './utils.js';
|
|
39
|
+
export { parseStatus, isTerminalStatus, isChatBusy, isAwaitingHuman, isRunTerminal, isRunInterrupted, isRunWaiting, isRunSettled, isRunWorking, isMessageTerminal, pendingApprovals, heldTurn, pendingWait, } from './utils.js';
|
|
40
40
|
export type { PendingApproval, HeldTurn, PendingWait } from './utils.js';
|
|
41
41
|
export * from './types.js';
|
|
42
42
|
export type { TaskDTO as Task } from './types.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, heldTurn, pendingWait, } from './utils.js';
|
|
41
|
+
export { parseStatus, isTerminalStatus, isChatBusy, isAwaitingHuman, isRunTerminal, isRunInterrupted, isRunWaiting, isRunSettled, isRunWorking, isMessageTerminal, pendingApprovals, heldTurn, pendingWait, } from './utils.js';
|
|
42
42
|
// Types - includes TaskStatus constants and all DTOs
|
|
43
43
|
export * from './types.js';
|
|
44
44
|
// =============================================================================
|
package/dist/types.d.ts
CHANGED
|
@@ -608,7 +608,11 @@ export interface AuthResponse {
|
|
|
608
608
|
session_id: string;
|
|
609
609
|
is_new?: boolean;
|
|
610
610
|
otp_required?: boolean;
|
|
611
|
-
|
|
611
|
+
/**
|
|
612
|
+
* OTPMethods are the second factors the sign-in may be finished with,
|
|
613
|
+
* the default first (POST /auth/otp/verify with method).
|
|
614
|
+
*/
|
|
615
|
+
otp_methods?: SecondFactor[];
|
|
612
616
|
challenge_token?: string;
|
|
613
617
|
redirect_to?: string;
|
|
614
618
|
provider?: string;
|
|
@@ -911,7 +915,7 @@ export interface EstimateCostResponse {
|
|
|
911
915
|
/**
|
|
912
916
|
* Scope represents an API key permission scope string.
|
|
913
917
|
*/
|
|
914
|
-
export type Scope = "*" | "agents" | "apps" | "conversations" | "files" | "datastores" | "templates" | "flows" | "projects" | "teams" | "billing" | "artifacts" | "agents:read" | "agents:write" | "agents:execute" | "apps:read" | "apps:write" | "apps:execute" | "conversations:read" | "conversations:write" | "files:read" | "files:write" | "datastores:read" | "datastores:write" | "flows:read" | "flows:write" | "flows:execute" | "projects:read" | "projects:write" | "teams:read" | "teams:write" | "billing:read" | "billing:write" | "secrets:read" | "secrets:write" | "secrets:reveal" | "credentials:read" | "credentials:write" | "engines:read" | "engines:write" | "remotes:read" | "remotes:write" | "apikeys:read" | "apikeys:write" | "knowledge:read" | "knowledge:write" | "artifacts:read" | "artifacts:write" | "user:read" | "user:write" | "settings:read" | "settings:write" | "approvals:write" | "admin:read" | "admin:write" | "store:pricing" | "store:submit";
|
|
918
|
+
export type Scope = "*" | "agents" | "apps" | "conversations" | "files" | "datastores" | "templates" | "flows" | "projects" | "teams" | "billing" | "artifacts" | "agents:read" | "agents:write" | "agents:execute" | "apps:read" | "apps:write" | "apps:execute" | "conversations:read" | "conversations:write" | "files:read" | "files:write" | "datastores:read" | "datastores:write" | "flows:read" | "flows:write" | "flows:execute" | "projects:read" | "projects:write" | "teams:read" | "teams:write" | "billing:read" | "billing:write" | "secrets:read" | "secrets:write" | "secrets:reveal" | "credentials:read" | "credentials:write" | "engines:read" | "engines:write" | "remotes:read" | "remotes:write" | "apikeys:read" | "apikeys:write" | "knowledge:read" | "knowledge:write" | "artifacts:read" | "artifacts:write" | "user:read" | "user:write" | "settings:read" | "settings:write" | "approvals:write" | "admin:read" | "admin:write" | "store:pricing" | "store:submit" | "content:write";
|
|
915
919
|
/**
|
|
916
920
|
* API Key Scopes - hierarchical permission system.
|
|
917
921
|
* Resource-level scopes (e.g., "agents") imply all action-level scopes (e.g., "agents:read").
|
|
@@ -1218,10 +1222,18 @@ export declare const ScopeStorePricing: Scope;
|
|
|
1218
1222
|
* publisher's behalf. Held like ScopeStorePricing.
|
|
1219
1223
|
*/
|
|
1220
1224
|
export declare const ScopeStoreSubmit: Scope;
|
|
1225
|
+
/**
|
|
1226
|
+
* ScopeContentWrite writes the site's content (/content): blog and docs
|
|
1227
|
+
* pages, menus and the platform media library. Held like
|
|
1228
|
+
* ScopeStorePricing: only in the platform's workspace, by its members,
|
|
1229
|
+
* their keys and runs, and its own keys. Reads of published content take
|
|
1230
|
+
* no scope.
|
|
1231
|
+
*/
|
|
1232
|
+
export declare const ScopeContentWrite: Scope;
|
|
1221
1233
|
/**
|
|
1222
1234
|
* ScopeGroup identifies a category of scopes for UI grouping
|
|
1223
1235
|
*/
|
|
1224
|
-
export type ScopeGroup = "agents" | "apps" | "conversations" | "files" | "datastores" | "flows" | "projects" | "teams" | "billing" | "secrets" | "credentials" | "engines" | "remotes" | "apikeys" | "knowledge" | "artifacts" | "user" | "settings" | "approvals" | "admin" | "store";
|
|
1236
|
+
export type ScopeGroup = "agents" | "apps" | "conversations" | "files" | "datastores" | "flows" | "projects" | "teams" | "billing" | "secrets" | "credentials" | "engines" | "remotes" | "apikeys" | "knowledge" | "artifacts" | "user" | "settings" | "approvals" | "admin" | "store" | "content";
|
|
1225
1237
|
export declare const ScopeGroupAgents: ScopeGroup;
|
|
1226
1238
|
export declare const ScopeGroupApps: ScopeGroup;
|
|
1227
1239
|
export declare const ScopeGroupConversations: ScopeGroup;
|
|
@@ -1243,6 +1255,7 @@ export declare const ScopeGroupSettings: ScopeGroup;
|
|
|
1243
1255
|
export declare const ScopeGroupApprovals: ScopeGroup;
|
|
1244
1256
|
export declare const ScopeGroupAdmin: ScopeGroup;
|
|
1245
1257
|
export declare const ScopeGroupStore: ScopeGroup;
|
|
1258
|
+
export declare const ScopeGroupContent: ScopeGroup;
|
|
1246
1259
|
/**
|
|
1247
1260
|
* ScopeDefinition describes a single scope for UI rendering
|
|
1248
1261
|
*/
|
|
@@ -1398,9 +1411,6 @@ export interface AppPricing {
|
|
|
1398
1411
|
description: string;
|
|
1399
1412
|
description_rendered?: string;
|
|
1400
1413
|
}
|
|
1401
|
-
/**
|
|
1402
|
-
* AppFunction represents a callable entry point within an app version.
|
|
1403
|
-
*/
|
|
1404
1414
|
export interface AppFunction {
|
|
1405
1415
|
name: string;
|
|
1406
1416
|
description?: string;
|
|
@@ -3062,7 +3072,7 @@ export interface DecideEntitlementRequestRequest {
|
|
|
3062
3072
|
* and APIError.Code on the legacy envelope. Clients branch on these, so a
|
|
3063
3073
|
* code is a named const here, where it generates into models and the SDKs.
|
|
3064
3074
|
*/
|
|
3065
|
-
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";
|
|
3075
|
+
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" | "last_authenticator" | "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";
|
|
3066
3076
|
export declare const ErrorCodeInvalidRequest: ErrorCode;
|
|
3067
3077
|
export declare const ErrorCodeValidationError: ErrorCode;
|
|
3068
3078
|
export declare const ErrorCodeUnauthorized: ErrorCode;
|
|
@@ -3171,6 +3181,13 @@ export declare const ErrorCodeInvalidTTL: ErrorCode;
|
|
|
3171
3181
|
* has not proved it gets otp_required instead: re-authenticate with it.
|
|
3172
3182
|
*/
|
|
3173
3183
|
export declare const ErrorCodeAdminAuthenticatorRequired: ErrorCode;
|
|
3184
|
+
/**
|
|
3185
|
+
* ErrorCodeLastAuthenticator (409): the change would leave two-step
|
|
3186
|
+
* verification on with no method to prove it (removing the last
|
|
3187
|
+
* authenticator app or passkey), or turn it on with none enrolled.
|
|
3188
|
+
* Turn two-step verification off first, or enroll a method.
|
|
3189
|
+
*/
|
|
3190
|
+
export declare const ErrorCodeLastAuthenticator: ErrorCode;
|
|
3174
3191
|
/**
|
|
3175
3192
|
* Entitlements. LimitExceeded (402) and FeatureNotAvailable (403) carry
|
|
3176
3193
|
* EntitlementErrorMeta. EntitlementUnavailable (500) means the plan could
|
|
@@ -3846,6 +3863,29 @@ export interface InstanceTypeBootTime {
|
|
|
3846
3863
|
updated_at: string;
|
|
3847
3864
|
sample_size: number;
|
|
3848
3865
|
}
|
|
3866
|
+
/**
|
|
3867
|
+
* InstancePriceHistoryPointDTO is one day's cheapest hourly prices, in cents,
|
|
3868
|
+
* for a GPU type. List prices rarely move; the in-stock price does, as stock
|
|
3869
|
+
* comes and goes. A price with no listing (or no stock) that day is omitted.
|
|
3870
|
+
*/
|
|
3871
|
+
export interface InstancePriceHistoryPointDTO {
|
|
3872
|
+
day: string;
|
|
3873
|
+
/**
|
|
3874
|
+
* OnDemand and Spot are the cheapest listed prices, in stock or not.
|
|
3875
|
+
*/
|
|
3876
|
+
on_demand?: number;
|
|
3877
|
+
spot?: number;
|
|
3878
|
+
/**
|
|
3879
|
+
* OnDemandInStock and SpotInStock are the cheapest prices that had stock.
|
|
3880
|
+
*/
|
|
3881
|
+
on_demand_in_stock?: number;
|
|
3882
|
+
spot_in_stock?: number;
|
|
3883
|
+
providers: number;
|
|
3884
|
+
/**
|
|
3885
|
+
* Regions is the number of provider regions with on-demand stock.
|
|
3886
|
+
*/
|
|
3887
|
+
regions: number;
|
|
3888
|
+
}
|
|
3849
3889
|
export interface InterruptDTO extends BaseModelDTO, PermissionModelDTO {
|
|
3850
3890
|
run_id: string;
|
|
3851
3891
|
chat_id: string;
|
|
@@ -5087,7 +5127,13 @@ export interface TaskLog {
|
|
|
5087
5127
|
}
|
|
5088
5128
|
/**
|
|
5089
5129
|
* TaskDTO is the full API response for a task.
|
|
5130
|
+
* TaskEgress is what a task's sandbox sent to and received from the
|
|
5131
|
+
* internet through the engine's egress gateway, in bytes.
|
|
5090
5132
|
*/
|
|
5133
|
+
export interface TaskEgress {
|
|
5134
|
+
bytes_out: number;
|
|
5135
|
+
bytes_in: number;
|
|
5136
|
+
}
|
|
5091
5137
|
export interface TaskDTO extends BaseModelDTO, PermissionModelDTO {
|
|
5092
5138
|
graph_id?: string;
|
|
5093
5139
|
user_public_key: string;
|
|
@@ -5121,6 +5167,12 @@ export interface TaskDTO extends BaseModelDTO, PermissionModelDTO {
|
|
|
5121
5167
|
events: TaskEvent[];
|
|
5122
5168
|
logs: TaskLog[];
|
|
5123
5169
|
usage_events: (UsageEventDTO | undefined)[];
|
|
5170
|
+
/**
|
|
5171
|
+
* Egress is what the task's sandbox moved through the engine's egress
|
|
5172
|
+
* gateway, reported by the engine when the task ended. Absent for a
|
|
5173
|
+
* task that ran without the gateway.
|
|
5174
|
+
*/
|
|
5175
|
+
egress?: TaskEgress;
|
|
5124
5176
|
session_id?: string;
|
|
5125
5177
|
session_timeout?: number;
|
|
5126
5178
|
}
|
|
@@ -5442,7 +5494,17 @@ export interface UserDTO extends BaseModelDTO {
|
|
|
5442
5494
|
avatar_url: string;
|
|
5443
5495
|
banned_at?: string;
|
|
5444
5496
|
ban_note?: string;
|
|
5497
|
+
/**
|
|
5498
|
+
* TOTPEnabled mirrors TwoFactorEnabled for clients built before it
|
|
5499
|
+
* (the Swift SDK decodes it as required).
|
|
5500
|
+
* Deprecated: read TwoFactorEnabled. Kept until no Swift app build older
|
|
5501
|
+
* than sdk-swift 0.23.0 is in use, since those fail to decode /me without it.
|
|
5502
|
+
*/
|
|
5445
5503
|
totp_enabled: boolean;
|
|
5504
|
+
/**
|
|
5505
|
+
* TwoFactorEnabled is the account's two-step verification switch.
|
|
5506
|
+
*/
|
|
5507
|
+
two_factor_enabled: boolean;
|
|
5446
5508
|
metadata?: UserMetadataDTO;
|
|
5447
5509
|
}
|
|
5448
5510
|
/**
|
|
@@ -6236,10 +6298,15 @@ export declare const EntitlementRequestOpen: EntitlementRequestState;
|
|
|
6236
6298
|
export declare const EntitlementRequestAccepted: EntitlementRequestState;
|
|
6237
6299
|
export declare const EntitlementRequestDeclined: EntitlementRequestState;
|
|
6238
6300
|
export declare const EntitlementRequestWithdrawn: EntitlementRequestState;
|
|
6239
|
-
export type ChatStatus = "busy" | "idle" | "awaiting_input" | "completed";
|
|
6301
|
+
export type ChatStatus = "busy" | "idle" | "awaiting_input" | "waiting" | "completed";
|
|
6240
6302
|
export declare const ChatStatusBusy: ChatStatus;
|
|
6241
6303
|
export declare const ChatStatusIdle: ChatStatus;
|
|
6242
6304
|
export declare const ChatStatusAwaitingInput: ChatStatus;
|
|
6305
|
+
/**
|
|
6306
|
+
* ChatStatusWaiting: the run is paused on the agent's own wait call. A
|
|
6307
|
+
* message ends the wait early; nobody has to act on it.
|
|
6308
|
+
*/
|
|
6309
|
+
export declare const ChatStatusWaiting: ChatStatus;
|
|
6243
6310
|
export declare const ChatStatusCompleted: ChatStatus;
|
|
6244
6311
|
export type PlanStepStatus = "pending" | "in_progress" | "completed" | "cancelled";
|
|
6245
6312
|
export declare const PlanStepStatusPending: PlanStepStatus;
|
|
@@ -6321,8 +6388,41 @@ export interface ChatMessageContent {
|
|
|
6321
6388
|
tool_calls?: ToolCall[];
|
|
6322
6389
|
event?: ChatEvent;
|
|
6323
6390
|
}
|
|
6324
|
-
export type ChatEventType = "hook";
|
|
6391
|
+
export type ChatEventType = "hook" | "run_failed" | "run_ended";
|
|
6325
6392
|
export declare const ChatEventTypeHook: ChatEventType;
|
|
6393
|
+
/**
|
|
6394
|
+
* ChatEventTypeRunFailed marks the point a run ended in failure; the
|
|
6395
|
+
* content's text is the run's error.
|
|
6396
|
+
*/
|
|
6397
|
+
export declare const ChatEventTypeRunFailed: ChatEventType;
|
|
6398
|
+
/**
|
|
6399
|
+
* ChatEventTypeRunEnded marks the point a run completed or was stopped;
|
|
6400
|
+
* the event's run says how, and the content's text, when set, why.
|
|
6401
|
+
*/
|
|
6402
|
+
export declare const ChatEventTypeRunEnded: ChatEventType;
|
|
6403
|
+
/**
|
|
6404
|
+
* RunEndReason is why a run that completed ended the way it did, when its
|
|
6405
|
+
* last turn did not end with a reply.
|
|
6406
|
+
*/
|
|
6407
|
+
export type RunEndReason = "output_limit" | "no_reply";
|
|
6408
|
+
/**
|
|
6409
|
+
* RunEndReasonOutputLimit: the model's last turn hit its output limit
|
|
6410
|
+
* (max_tokens) before it replied or called a tool.
|
|
6411
|
+
*/
|
|
6412
|
+
export declare const RunEndReasonOutputLimit: RunEndReason;
|
|
6413
|
+
/**
|
|
6414
|
+
* RunEndReasonNoReply: the model ended its last turn with no reply and
|
|
6415
|
+
* no tool call.
|
|
6416
|
+
*/
|
|
6417
|
+
export declare const RunEndReasonNoReply: RunEndReason;
|
|
6418
|
+
/**
|
|
6419
|
+
* ChatRunEvent is how a run ended, on a run_ended event.
|
|
6420
|
+
*/
|
|
6421
|
+
export interface ChatRunEvent {
|
|
6422
|
+
run_id: string;
|
|
6423
|
+
state: AgentRunState;
|
|
6424
|
+
reason?: RunEndReason;
|
|
6425
|
+
}
|
|
6326
6426
|
/**
|
|
6327
6427
|
* ChatEvent is the payload of an event-role message: system info shown in the
|
|
6328
6428
|
* chat but never sent to the model.
|
|
@@ -6330,6 +6430,7 @@ export declare const ChatEventTypeHook: ChatEventType;
|
|
|
6330
6430
|
export interface ChatEvent {
|
|
6331
6431
|
type: ChatEventType;
|
|
6332
6432
|
hook?: ChatHookEvent;
|
|
6433
|
+
run?: ChatRunEvent;
|
|
6333
6434
|
}
|
|
6334
6435
|
/**
|
|
6335
6436
|
* ChatHookEvent records one lifecycle hook handler run.
|
|
@@ -6720,8 +6821,8 @@ export declare const GraphEdgeTypeOutput: GraphEdgeType;
|
|
|
6720
6821
|
export declare const InterruptResourceTurn: InterruptResourceType;
|
|
6721
6822
|
/**
|
|
6722
6823
|
* InterruptReasonWait is a tool call the agent made to wait: the run is
|
|
6723
|
-
* paused until the interrupt's deadline, when
|
|
6724
|
-
*
|
|
6824
|
+
* paused until the interrupt's deadline, when the expiry sweep settles it
|
|
6825
|
+
* (allow), or until a person ends the wait sooner. Its resource is the
|
|
6725
6826
|
* wait call (InterruptResourceToolInvocation).
|
|
6726
6827
|
*/
|
|
6727
6828
|
export declare const InterruptReasonWait: InterruptReason;
|
|
@@ -7046,6 +7147,33 @@ export type MCPServerAuthType = "oauth" | "api_key" | "none";
|
|
|
7046
7147
|
export declare const MCPServerAuthOAuth: MCPServerAuthType;
|
|
7047
7148
|
export declare const MCPServerAuthAPIKey: MCPServerAuthType;
|
|
7048
7149
|
export declare const MCPServerAuthNone: MCPServerAuthType;
|
|
7150
|
+
/**
|
|
7151
|
+
* SecondFactor is one way a person proves their second factor. It names
|
|
7152
|
+
* what a session proved (AuthSession.SecondFactor), what a login challenge
|
|
7153
|
+
* offers, the method a verify request picks, and the kind of an enrolled
|
|
7154
|
+
* method (SecondFactorMethod.Kind: the enrollable ones).
|
|
7155
|
+
*/
|
|
7156
|
+
export type SecondFactor = "totp" | "passkey" | "recovery" | "email";
|
|
7157
|
+
/**
|
|
7158
|
+
* SecondFactorTOTP: a code from an enrolled authenticator app.
|
|
7159
|
+
*/
|
|
7160
|
+
export declare const SecondFactorTOTP: SecondFactor;
|
|
7161
|
+
/**
|
|
7162
|
+
* SecondFactorPasskey: a WebAuthn assertion from an enrolled passkey.
|
|
7163
|
+
*/
|
|
7164
|
+
export declare const SecondFactorPasskey: SecondFactor;
|
|
7165
|
+
/**
|
|
7166
|
+
* SecondFactorRecovery: one of the account's single-use recovery codes.
|
|
7167
|
+
* Not enrolled on its own: issued once an authenticator exists.
|
|
7168
|
+
*/
|
|
7169
|
+
export declare const SecondFactorRecovery: SecondFactor;
|
|
7170
|
+
/**
|
|
7171
|
+
* SecondFactorEmail: a code emailed to the account. The weakest: the
|
|
7172
|
+
* same mailbox a magic link lands in, so it is offered only to an
|
|
7173
|
+
* account with two-step verification off (a platform admin's first
|
|
7174
|
+
* sign-in, re-auth before they enroll).
|
|
7175
|
+
*/
|
|
7176
|
+
export declare const SecondFactorEmail: SecondFactor;
|
|
7049
7177
|
/**
|
|
7050
7178
|
* TeamInviteStatus represents the status of a team invitation
|
|
7051
7179
|
*/
|
|
@@ -7540,10 +7668,17 @@ export declare const TaskStatusRejected: TaskStatus;
|
|
|
7540
7668
|
/**
|
|
7541
7669
|
* Infra defines where a task should run.
|
|
7542
7670
|
*/
|
|
7543
|
-
export type Infra = "private" | "cloud" | "private_first";
|
|
7671
|
+
export type Infra = "private" | "cloud" | "private_first" | "remote";
|
|
7544
7672
|
export declare const InfraPrivate: Infra;
|
|
7545
7673
|
export declare const InfraCloud: Infra;
|
|
7546
7674
|
export declare const InfraPrivateFirst: Infra;
|
|
7675
|
+
/**
|
|
7676
|
+
* InfraRemote is a model call a harness on the caller's own remote
|
|
7677
|
+
* answers (an agent whose model app is a harness model app). The
|
|
7678
|
+
* scheduler never takes it: the remote model service sends it to the
|
|
7679
|
+
* remote's daemon, whose frames end it.
|
|
7680
|
+
*/
|
|
7681
|
+
export declare const InfraRemote: Infra;
|
|
7547
7682
|
/**
|
|
7548
7683
|
* TaskLogType defines the type of task log.
|
|
7549
7684
|
*/
|
|
@@ -8058,11 +8193,12 @@ export declare const AgentEventSubagentCompleted: AgentEventType;
|
|
|
8058
8193
|
/**
|
|
8059
8194
|
* ToolInvocationStatus represents the execution status of a tool invocation
|
|
8060
8195
|
*/
|
|
8061
|
-
export type ToolInvocationStatus = "pending" | "in_progress" | "awaiting_input" | "awaiting_approval" | "completed" | "failed" | "cancelled";
|
|
8196
|
+
export type ToolInvocationStatus = "pending" | "in_progress" | "awaiting_input" | "awaiting_approval" | "waiting" | "completed" | "failed" | "cancelled";
|
|
8062
8197
|
export declare const ToolInvocationStatusPending: ToolInvocationStatus;
|
|
8063
8198
|
export declare const ToolInvocationStatusInProgress: ToolInvocationStatus;
|
|
8064
8199
|
export declare const ToolInvocationStatusAwaitingInput: ToolInvocationStatus;
|
|
8065
8200
|
export declare const ToolInvocationStatusAwaitingApproval: ToolInvocationStatus;
|
|
8201
|
+
export declare const ToolInvocationStatusWaiting: ToolInvocationStatus;
|
|
8066
8202
|
export declare const ToolInvocationStatusCompleted: ToolInvocationStatus;
|
|
8067
8203
|
export declare const ToolInvocationStatusFailed: ToolInvocationStatus;
|
|
8068
8204
|
export declare const ToolInvocationStatusCancelled: ToolInvocationStatus;
|
package/dist/types.js
CHANGED
|
@@ -321,6 +321,14 @@ export const ScopeStorePricing = "store:pricing";
|
|
|
321
321
|
* publisher's behalf. Held like ScopeStorePricing.
|
|
322
322
|
*/
|
|
323
323
|
export const ScopeStoreSubmit = "store:submit";
|
|
324
|
+
/**
|
|
325
|
+
* ScopeContentWrite writes the site's content (/content): blog and docs
|
|
326
|
+
* pages, menus and the platform media library. Held like
|
|
327
|
+
* ScopeStorePricing: only in the platform's workspace, by its members,
|
|
328
|
+
* their keys and runs, and its own keys. Reads of published content take
|
|
329
|
+
* no scope.
|
|
330
|
+
*/
|
|
331
|
+
export const ScopeContentWrite = "content:write";
|
|
324
332
|
export const ScopeGroupAgents = "agents";
|
|
325
333
|
export const ScopeGroupApps = "apps";
|
|
326
334
|
export const ScopeGroupConversations = "conversations";
|
|
@@ -342,6 +350,7 @@ export const ScopeGroupSettings = "settings";
|
|
|
342
350
|
export const ScopeGroupApprovals = "approvals";
|
|
343
351
|
export const ScopeGroupAdmin = "admin";
|
|
344
352
|
export const ScopeGroupStore = "store";
|
|
353
|
+
export const ScopeGroupContent = "content";
|
|
345
354
|
/**
|
|
346
355
|
* AlwaysAllowScopeExact: this call exactly (each piece of the command,
|
|
347
356
|
* the file, the domain).
|
|
@@ -485,6 +494,13 @@ export const ErrorCodeInvalidTTL = "invalid_ttl";
|
|
|
485
494
|
* has not proved it gets otp_required instead: re-authenticate with it.
|
|
486
495
|
*/
|
|
487
496
|
export const ErrorCodeAdminAuthenticatorRequired = "admin_authenticator_required";
|
|
497
|
+
/**
|
|
498
|
+
* ErrorCodeLastAuthenticator (409): the change would leave two-step
|
|
499
|
+
* verification on with no method to prove it (removing the last
|
|
500
|
+
* authenticator app or passkey), or turn it on with none enrolled.
|
|
501
|
+
* Turn two-step verification off first, or enroll a method.
|
|
502
|
+
*/
|
|
503
|
+
export const ErrorCodeLastAuthenticator = "last_authenticator";
|
|
488
504
|
/**
|
|
489
505
|
* Entitlements. LimitExceeded (402) and FeatureNotAvailable (403) carry
|
|
490
506
|
* EntitlementErrorMeta. EntitlementUnavailable (500) means the plan could
|
|
@@ -870,6 +886,11 @@ export const EntitlementRequestWithdrawn = "withdrawn";
|
|
|
870
886
|
export const ChatStatusBusy = "busy";
|
|
871
887
|
export const ChatStatusIdle = "idle";
|
|
872
888
|
export const ChatStatusAwaitingInput = "awaiting_input";
|
|
889
|
+
/**
|
|
890
|
+
* ChatStatusWaiting: the run is paused on the agent's own wait call. A
|
|
891
|
+
* message ends the wait early; nobody has to act on it.
|
|
892
|
+
*/
|
|
893
|
+
export const ChatStatusWaiting = "waiting";
|
|
873
894
|
export const ChatStatusCompleted = "completed";
|
|
874
895
|
export const PlanStepStatusPending = "pending";
|
|
875
896
|
export const PlanStepStatusInProgress = "in_progress";
|
|
@@ -907,6 +928,26 @@ export const ChannelTypeDiscord = "discord";
|
|
|
907
928
|
export const ChannelTypeTeams = "teams";
|
|
908
929
|
export const ChannelTypeTelegram = "telegram";
|
|
909
930
|
export const ChatEventTypeHook = "hook";
|
|
931
|
+
/**
|
|
932
|
+
* ChatEventTypeRunFailed marks the point a run ended in failure; the
|
|
933
|
+
* content's text is the run's error.
|
|
934
|
+
*/
|
|
935
|
+
export const ChatEventTypeRunFailed = "run_failed";
|
|
936
|
+
/**
|
|
937
|
+
* ChatEventTypeRunEnded marks the point a run completed or was stopped;
|
|
938
|
+
* the event's run says how, and the content's text, when set, why.
|
|
939
|
+
*/
|
|
940
|
+
export const ChatEventTypeRunEnded = "run_ended";
|
|
941
|
+
/**
|
|
942
|
+
* RunEndReasonOutputLimit: the model's last turn hit its output limit
|
|
943
|
+
* (max_tokens) before it replied or called a tool.
|
|
944
|
+
*/
|
|
945
|
+
export const RunEndReasonOutputLimit = "output_limit";
|
|
946
|
+
/**
|
|
947
|
+
* RunEndReasonNoReply: the model ended its last turn with no reply and
|
|
948
|
+
* no tool call.
|
|
949
|
+
*/
|
|
950
|
+
export const RunEndReasonNoReply = "no_reply";
|
|
910
951
|
/**
|
|
911
952
|
* DescriptionLimitListing bounds the description of an app, agent, flow,
|
|
912
953
|
* MCP server or knowledge entry. A description is shown in listings and
|
|
@@ -994,8 +1035,8 @@ export const GraphEdgeTypeOutput = "output";
|
|
|
994
1035
|
export const InterruptResourceTurn = "turn";
|
|
995
1036
|
/**
|
|
996
1037
|
* InterruptReasonWait is a tool call the agent made to wait: the run is
|
|
997
|
-
* paused until the interrupt's deadline, when
|
|
998
|
-
*
|
|
1038
|
+
* paused until the interrupt's deadline, when the expiry sweep settles it
|
|
1039
|
+
* (allow), or until a person ends the wait sooner. Its resource is the
|
|
999
1040
|
* wait call (InterruptResourceToolInvocation).
|
|
1000
1041
|
*/
|
|
1001
1042
|
export const InterruptReasonWait = "wait";
|
|
@@ -1111,6 +1152,26 @@ export const VideoRes4K = "4k";
|
|
|
1111
1152
|
export const MCPServerAuthOAuth = "oauth";
|
|
1112
1153
|
export const MCPServerAuthAPIKey = "api_key";
|
|
1113
1154
|
export const MCPServerAuthNone = "none";
|
|
1155
|
+
/**
|
|
1156
|
+
* SecondFactorTOTP: a code from an enrolled authenticator app.
|
|
1157
|
+
*/
|
|
1158
|
+
export const SecondFactorTOTP = "totp";
|
|
1159
|
+
/**
|
|
1160
|
+
* SecondFactorPasskey: a WebAuthn assertion from an enrolled passkey.
|
|
1161
|
+
*/
|
|
1162
|
+
export const SecondFactorPasskey = "passkey";
|
|
1163
|
+
/**
|
|
1164
|
+
* SecondFactorRecovery: one of the account's single-use recovery codes.
|
|
1165
|
+
* Not enrolled on its own: issued once an authenticator exists.
|
|
1166
|
+
*/
|
|
1167
|
+
export const SecondFactorRecovery = "recovery";
|
|
1168
|
+
/**
|
|
1169
|
+
* SecondFactorEmail: a code emailed to the account. The weakest: the
|
|
1170
|
+
* same mailbox a magic link lands in, so it is offered only to an
|
|
1171
|
+
* account with two-step verification off (a platform admin's first
|
|
1172
|
+
* sign-in, re-auth before they enroll).
|
|
1173
|
+
*/
|
|
1174
|
+
export const SecondFactorEmail = "email";
|
|
1114
1175
|
export const TeamInviteStatusPending = "pending";
|
|
1115
1176
|
export const TeamInviteStatusAccepted = "accepted";
|
|
1116
1177
|
export const TeamInviteStatusDeclined = "declined";
|
|
@@ -1483,6 +1544,13 @@ export const TaskStatusRejected = 13;
|
|
|
1483
1544
|
export const InfraPrivate = "private";
|
|
1484
1545
|
export const InfraCloud = "cloud";
|
|
1485
1546
|
export const InfraPrivateFirst = "private_first";
|
|
1547
|
+
/**
|
|
1548
|
+
* InfraRemote is a model call a harness on the caller's own remote
|
|
1549
|
+
* answers (an agent whose model app is a harness model app). The
|
|
1550
|
+
* scheduler never takes it: the remote model service sends it to the
|
|
1551
|
+
* remote's daemon, whose frames end it.
|
|
1552
|
+
*/
|
|
1553
|
+
export const InfraRemote = "remote";
|
|
1486
1554
|
export const TaskLogTypeBuild = 0;
|
|
1487
1555
|
export const TaskLogTypeRun = 1;
|
|
1488
1556
|
export const TaskLogTypeServe = 2;
|
|
@@ -1672,6 +1740,7 @@ export const ToolInvocationStatusPending = "pending";
|
|
|
1672
1740
|
export const ToolInvocationStatusInProgress = "in_progress";
|
|
1673
1741
|
export const ToolInvocationStatusAwaitingInput = "awaiting_input";
|
|
1674
1742
|
export const ToolInvocationStatusAwaitingApproval = "awaiting_approval";
|
|
1743
|
+
export const ToolInvocationStatusWaiting = "waiting";
|
|
1675
1744
|
export const ToolInvocationStatusCompleted = "completed";
|
|
1676
1745
|
export const ToolInvocationStatusFailed = "failed";
|
|
1677
1746
|
export const ToolInvocationStatusCancelled = "cancelled";
|
package/dist/utils.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { InterruptDTO } from './types.js';
|
|
6
6
|
import { TaskStatus } from './types.js';
|
|
7
|
-
import type { AgentRunState, ChatDTO, ChatMessageStatus } from './types.js';
|
|
7
|
+
import type { AgentRunDTO, AgentRunState, ChatDTO, ChatMessageStatus } from './types.js';
|
|
8
8
|
/**
|
|
9
9
|
* Parse task status from int or string to TaskStatus number.
|
|
10
10
|
* Handles both current int-based API and future string-based API.
|
|
@@ -18,12 +18,14 @@ export declare function isTerminalStatus(status: number | string | undefined | n
|
|
|
18
18
|
export declare function isRunTerminal(state: AgentRunState | null | undefined): boolean;
|
|
19
19
|
/** Parked on a human: a tool approval or input (input_required) or an authorization (auth_required). */
|
|
20
20
|
export declare function isRunInterrupted(state: AgentRunState | null | undefined): boolean;
|
|
21
|
+
/** Paused on the agent's own wait call: it resumes at its deadline or on a message, so nobody has to act. */
|
|
22
|
+
export declare function isRunWaiting(run: Pick<AgentRunDTO, 'state' | 'interrupt_reason'> | null | undefined): boolean;
|
|
21
23
|
/** The run produces no further events this turn: terminal or interrupted. */
|
|
22
24
|
export declare function isRunSettled(state: AgentRunState | null | undefined): boolean;
|
|
23
25
|
/** The run is executing: submitted or working. */
|
|
24
26
|
export declare function isRunWorking(state: AgentRunState | null | undefined): boolean;
|
|
25
27
|
export declare function isMessageTerminal(status: ChatMessageStatus | null | undefined): boolean;
|
|
26
|
-
/** The turn is still open: the run is working or parked on a human (approval, input, authorization). */
|
|
28
|
+
/** The turn is still open: the run is working, waiting, or parked on a human (approval, input, authorization). */
|
|
27
29
|
export declare function isChatBusy(chat: ChatDTO | null | undefined): boolean;
|
|
28
30
|
/** The chat is blocked on a human: nothing more arrives until someone approves, answers or authorizes. */
|
|
29
31
|
export declare function isAwaitingHuman(chat: ChatDTO | null | undefined): boolean;
|
|
@@ -49,6 +51,8 @@ export type HeldTurn = {
|
|
|
49
51
|
};
|
|
50
52
|
/** The held turn among a run's pending interrupts, if one is held. */
|
|
51
53
|
export declare function heldTurn(interrupts: InterruptDTO[] | null | undefined): HeldTurn | null;
|
|
54
|
+
/** The interrupt a tool call awaiting approval waits on, among a chat's or a run's pending interrupts. */
|
|
55
|
+
export declare function approvalInterrupt(interrupts: InterruptDTO[] | null | undefined, toolInvocationId: string): InterruptDTO | undefined;
|
|
52
56
|
/** 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
57
|
export type PendingWait = {
|
|
54
58
|
interruptId: string;
|
package/dist/utils.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Provides future compatibility when API migrates from int to string status.
|
|
4
4
|
*/
|
|
5
5
|
import { InterruptReasonToolApproval, InterruptReasonWait, 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';
|
|
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, ChatStatusWaiting, } 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,
|
|
@@ -54,6 +54,10 @@ export function isRunTerminal(state) {
|
|
|
54
54
|
export function isRunInterrupted(state) {
|
|
55
55
|
return state === AgentRunStateInputRequired || state === AgentRunStateAuthRequired;
|
|
56
56
|
}
|
|
57
|
+
/** Paused on the agent's own wait call: it resumes at its deadline or on a message, so nobody has to act. */
|
|
58
|
+
export function isRunWaiting(run) {
|
|
59
|
+
return !!run && isRunInterrupted(run.state) && run.interrupt_reason === InterruptReasonWait;
|
|
60
|
+
}
|
|
57
61
|
/** The run produces no further events this turn: terminal or interrupted. */
|
|
58
62
|
export function isRunSettled(state) {
|
|
59
63
|
return isRunTerminal(state) || isRunInterrupted(state);
|
|
@@ -65,19 +69,19 @@ export function isRunWorking(state) {
|
|
|
65
69
|
export function isMessageTerminal(status) {
|
|
66
70
|
return status === ChatMessageStatusReady || status === ChatMessageStatusFailed || status === ChatMessageStatusCancelled;
|
|
67
71
|
}
|
|
68
|
-
/** The turn is still open: the run is working or parked on a human (approval, input, authorization). */
|
|
72
|
+
/** The turn is still open: the run is working, waiting, or parked on a human (approval, input, authorization). */
|
|
69
73
|
export function isChatBusy(chat) {
|
|
70
74
|
const run = chat?.active_run;
|
|
71
75
|
if (run) {
|
|
72
76
|
return isRunWorking(run.state) || isRunInterrupted(run.state);
|
|
73
77
|
}
|
|
74
|
-
return chat?.status === ChatStatusBusy || chat?.status === ChatStatusAwaitingInput;
|
|
78
|
+
return chat?.status === ChatStatusBusy || chat?.status === ChatStatusAwaitingInput || chat?.status === ChatStatusWaiting;
|
|
75
79
|
}
|
|
76
80
|
/** The chat is blocked on a human: nothing more arrives until someone approves, answers or authorizes. */
|
|
77
81
|
export function isAwaitingHuman(chat) {
|
|
78
82
|
const run = chat?.active_run;
|
|
79
83
|
if (run)
|
|
80
|
-
return isRunInterrupted(run.state);
|
|
84
|
+
return isRunInterrupted(run.state) && !isRunWaiting(run);
|
|
81
85
|
return chat?.status === ChatStatusAwaitingInput;
|
|
82
86
|
}
|
|
83
87
|
/** An interrupt's meta, which arrives as an object or a JSON string. */
|
|
@@ -129,6 +133,10 @@ export function heldTurn(interrupts) {
|
|
|
129
133
|
const { steps } = parseMeta(interrupt);
|
|
130
134
|
return { interruptId: interrupt.id, runId: interrupt.run_id, steps: typeof steps === 'number' ? steps : null };
|
|
131
135
|
}
|
|
136
|
+
/** The interrupt a tool call awaiting approval waits on, among a chat's or a run's pending interrupts. */
|
|
137
|
+
export function approvalInterrupt(interrupts, toolInvocationId) {
|
|
138
|
+
return pendingInterrupt(interrupts, i => i.reason === InterruptReasonToolApproval && (i.resource_id || parseMeta(i).tool_invocation_id) === toolInvocationId);
|
|
139
|
+
}
|
|
132
140
|
/** The wait among a run's pending interrupts, if the run is waiting. */
|
|
133
141
|
export function pendingWait(interrupts) {
|
|
134
142
|
const interrupt = pendingInterrupt(interrupts, i => i.reason === InterruptReasonWait);
|