@inferencesh/sdk 0.15.0 → 0.17.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 +27 -0
- package/dist/agent/actions.js +26 -7
- package/dist/agent/api.d.ts +22 -4
- package/dist/agent/api.js +28 -4
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/reducer.js +37 -0
- package/dist/agent/types.d.ts +31 -3
- package/dist/api/agents.js +7 -5
- package/dist/types.d.ts +220 -1
- package/dist/types.js +37 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.17.0] - 2026-10-02
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- `updateChatSettings` and `switchAgent` merge what the api now answers with into the chat they hold: `ChatSettingsDTO` (`chat_id`, `name`, `visibility`, `allow_all_tools`, `disable_hooks`, `memory`) from `POST /chats/{id}/settings` and `ChatAgentDTO` (`chat_id`, `agent_id`, `agent`, `agent_version_id`, `agent_version`) from `POST /chats/{id}/agent`. The reducer has `MERGE_CHAT_SETTINGS` and `MERGE_CHAT_AGENT` for them; a response for a chat other than the one on screen is ignored. The low-level `updateChatSettings` and `setAgent` in the agent api return those types. Needs an api that answers with them.
|
|
15
|
+
- `ChatDTO.chat_messages` is optional: the api leaves it out when it did not load the messages, which it never does on the chat endpoints. Read messages from `GET /chats/{id}/messages`.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Polling `sendMessage` handled a fetched chat with an unchanged status only when it carried `chat_messages`. It now skips only the poll's own "nothing changed" answer.
|
|
20
|
+
|
|
21
|
+
## [0.16.0] - 2026-10-02
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- `useAgentActions().getAlwaysAllowOptions(toolInvocationId)`: what "always allow" can save for a call awaiting approval, narrowest first, computed by the api (`GET /chats/{id}/tools/{toolId}/always-allow/options`). Each option has a `key`, a `scope` (`exact`, `prefix`, `folder`, `remote`, `tool`), a `label` such as "npm run commands on laptop", and the chat `rules` it saves; `default` is the narrowest that answers the call again, and `unavailable` says why there are none.
|
|
26
|
+
- `useAgentActions().explainTool(toolInvocationId)`: a plain-words explanation of a call awaiting approval, `{ risk_level: 'low' | 'medium' | 'high', explanation, reasoning, risk }` (`POST /chats/{id}/tools/{toolId}/explain`). A model writes it the first time it is asked for and the api keeps it for the call; call it only when the person asks.
|
|
27
|
+
- Types: `ToolExplanationDTO`, `ToolRiskLevel`, `AlwaysAllowOptionsDTO`, `AlwaysAllowOptionDTO`, `AlwaysAllowScope`, `AlwaysAllowRequest`, `AlwaysAllowResultDTO`, `PolicyRuleDTO` (with `label`), `AlwaysAllowChoice`.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- `useAgentActions().alwaysAllowTool(toolInvocationId, { option })` saves the chosen option and resolves to the saved rules. The second argument used to be the tool name; a string is still accepted and means the api's default. A 409 (stale option) or 400 rejects without putting the chat in the error state.
|
|
32
|
+
|
|
33
|
+
### Security
|
|
34
|
+
|
|
35
|
+
- `proxy-addr` 2.0.8 in the lockfile (CVE-2026-90711).
|
|
36
|
+
|
|
10
37
|
## [0.15.0] - 2026-10-02
|
|
11
38
|
|
|
12
39
|
### Added
|
package/dist/agent/actions.js
CHANGED
|
@@ -368,16 +368,37 @@ export function createActions(ctx) {
|
|
|
368
368
|
throw error;
|
|
369
369
|
}
|
|
370
370
|
},
|
|
371
|
-
|
|
371
|
+
getAlwaysAllowOptions: async (toolInvocationId) => {
|
|
372
|
+
const chatId = getChatId();
|
|
373
|
+
if (!chatId)
|
|
374
|
+
return null;
|
|
375
|
+
return api.getAlwaysAllowOptions(client, chatId, toolInvocationId);
|
|
376
|
+
},
|
|
377
|
+
explainTool: async (toolInvocationId) => {
|
|
378
|
+
const chatId = getChatId();
|
|
379
|
+
if (!chatId)
|
|
380
|
+
throw new Error('Cannot explain a tool call without a chat');
|
|
381
|
+
return api.explainTool(client, chatId, toolInvocationId);
|
|
382
|
+
},
|
|
383
|
+
alwaysAllowTool: async (toolInvocationId, choice) => {
|
|
372
384
|
const chatId = getChatId();
|
|
373
385
|
if (!chatId) {
|
|
374
386
|
console.error('[AgentSDK] Cannot always-allow tool without a chatId');
|
|
375
|
-
return;
|
|
387
|
+
return undefined;
|
|
376
388
|
}
|
|
389
|
+
// A string is the tool name older callers passed; the api reads the
|
|
390
|
+
// tool from the call, so it only means "the default option".
|
|
391
|
+
const option = typeof choice === 'string' ? undefined : choice?.option;
|
|
377
392
|
try {
|
|
378
|
-
await api.alwaysAllowTool(client, chatId, toolInvocationId,
|
|
393
|
+
return await api.alwaysAllowTool(client, chatId, toolInvocationId, option);
|
|
379
394
|
}
|
|
380
395
|
catch (error) {
|
|
396
|
+
// 409: the option is stale (the rules changed since it was read);
|
|
397
|
+
// 400: nothing can be always-allowed here. The call is still
|
|
398
|
+
// waiting and the connection is fine: the caller reads the options
|
|
399
|
+
// again or shows why.
|
|
400
|
+
if (isInferenceError(error) && (error.statusCode === 409 || error.statusCode === 400))
|
|
401
|
+
throw error;
|
|
381
402
|
console.error('[AgentSDK] Failed to always-allow tool:', error);
|
|
382
403
|
const err = error instanceof Error ? error : new Error('Failed to always-allow tool');
|
|
383
404
|
dispatch({ type: 'SET_CONNECTION_STATUS', payload: 'error' });
|
|
@@ -393,9 +414,7 @@ export function createActions(ctx) {
|
|
|
393
414
|
return;
|
|
394
415
|
}
|
|
395
416
|
try {
|
|
396
|
-
|
|
397
|
-
// chat and keep the conversation on screen.
|
|
398
|
-
dispatch({ type: 'UPDATE_CHAT', payload: await api.updateChatSettings(client, chatId, settings) });
|
|
417
|
+
dispatch({ type: 'MERGE_CHAT_SETTINGS', payload: await api.updateChatSettings(client, chatId, settings) });
|
|
399
418
|
}
|
|
400
419
|
catch (error) {
|
|
401
420
|
console.error('[AgentSDK] Failed to change chat settings:', error);
|
|
@@ -412,7 +431,7 @@ export function createActions(ctx) {
|
|
|
412
431
|
return;
|
|
413
432
|
}
|
|
414
433
|
try {
|
|
415
|
-
dispatch({ type: '
|
|
434
|
+
dispatch({ type: 'MERGE_CHAT_AGENT', payload: await api.setAgent(client, chatId, agentRef) });
|
|
416
435
|
}
|
|
417
436
|
catch (error) {
|
|
418
437
|
console.error('[AgentSDK] Failed to switch the agent:', error);
|
package/dist/agent/api.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* /agents/run stays for A2A/programmatic use.
|
|
9
9
|
*/
|
|
10
|
-
import type { ChatDTO, ChatMessageDTO, ChatSettingsRequest, InterruptDTO } from '../types';
|
|
10
|
+
import type { AlwaysAllowOptionsDTO, AlwaysAllowResultDTO, ChatAgentDTO, ChatDTO, ChatMessageDTO, ChatSettingsDTO, ChatSettingsRequest, InterruptDTO, ToolExplanationDTO } from '../types';
|
|
11
11
|
import type { AgentOptions, AgentClient, AgentInfo, FileRef } from './types';
|
|
12
12
|
export interface SendResult {
|
|
13
13
|
chatId: string;
|
|
@@ -36,7 +36,8 @@ export declare function fetchMessagesPage(client: AgentClient, chatId: string, o
|
|
|
36
36
|
export declare function fetchChat(client: AgentClient, chatId: string): Promise<ChatDTO | null>;
|
|
37
37
|
export declare function stopChat(client: AgentClient, chatId: string): Promise<void>;
|
|
38
38
|
export declare function cancelMessage(client: AgentClient, messageId: string): Promise<void>;
|
|
39
|
-
|
|
39
|
+
/** Hand the chat to another agent. Answers with the agent the chat now runs on. */
|
|
40
|
+
export declare function setAgent(client: AgentClient, chatId: string, agentRef: string): Promise<ChatAgentDTO>;
|
|
40
41
|
export declare function submitToolResult(client: AgentClient, toolInvocationId: string, resultOrAction: string | {
|
|
41
42
|
action: {
|
|
42
43
|
type: string;
|
|
@@ -46,8 +47,25 @@ export declare function submitToolResult(client: AgentClient, toolInvocationId:
|
|
|
46
47
|
}): Promise<void>;
|
|
47
48
|
export declare function approveTool(client: AgentClient, toolInvocationId: string): Promise<void>;
|
|
48
49
|
export declare function rejectTool(client: AgentClient, toolInvocationId: string, reason?: string): Promise<void>;
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
/**
|
|
51
|
+
* What "always allow" can save for a call awaiting approval, narrowest first.
|
|
52
|
+
* The api computes the options from the call; each one, saved, answers it again.
|
|
53
|
+
*/
|
|
54
|
+
export declare function getAlwaysAllowOptions(client: AgentClient, chatId: string, toolInvocationId: string): Promise<AlwaysAllowOptionsDTO>;
|
|
55
|
+
/**
|
|
56
|
+
* Save an "always allow" option (a key from getAlwaysAllowOptions) as chat
|
|
57
|
+
* rules and approve the call once. Without an option the api saves its old
|
|
58
|
+
* default: the command exactly for remote_exec, the whole tool otherwise.
|
|
59
|
+
*/
|
|
60
|
+
export declare function alwaysAllowTool(client: AgentClient, chatId: string, toolInvocationId: string, option?: string): Promise<AlwaysAllowResultDTO>;
|
|
61
|
+
/**
|
|
62
|
+
* Explain a call awaiting approval in plain words: what it does, why the agent
|
|
63
|
+
* appears to make it, and its risk. Generated by a model the first time and kept
|
|
64
|
+
* for the call, so asking again is free.
|
|
65
|
+
*/
|
|
66
|
+
export declare function explainTool(client: AgentClient, chatId: string, toolInvocationId: string): Promise<ToolExplanationDTO>;
|
|
67
|
+
/** Change the chat's settings. Answers with the settings as they now are. */
|
|
68
|
+
export declare function updateChatSettings(client: AgentClient, chatId: string, settings: ChatSettingsRequest): Promise<ChatSettingsDTO>;
|
|
51
69
|
export declare function resolveInterrupt(client: AgentClient, interruptId: string, decision: 'allow' | 'deny'): Promise<InterruptDTO>;
|
|
52
70
|
export declare function listRunInterrupts(client: AgentClient, runId: string): Promise<InterruptDTO[]>;
|
|
53
71
|
export declare function uploadFile(client: AgentClient, file: globalThis.File): Promise<FileRef>;
|
package/dist/agent/api.js
CHANGED
|
@@ -132,6 +132,7 @@ export async function stopChat(client, chatId) {
|
|
|
132
132
|
export async function cancelMessage(client, messageId) {
|
|
133
133
|
await client.http.request('post', `/chats/messages/${messageId}/cancel`);
|
|
134
134
|
}
|
|
135
|
+
/** Hand the chat to another agent. Answers with the agent the chat now runs on. */
|
|
135
136
|
export async function setAgent(client, chatId, agentRef) {
|
|
136
137
|
const resp = await client.http.request('post', `/chats/${chatId}/agent`, {
|
|
137
138
|
data: { agent: agentRef },
|
|
@@ -151,11 +152,34 @@ export async function approveTool(client, toolInvocationId) {
|
|
|
151
152
|
export async function rejectTool(client, toolInvocationId, reason) {
|
|
152
153
|
await client.http.request('post', `/tools/${toolInvocationId}/reject`, { data: { reason } });
|
|
153
154
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
/**
|
|
156
|
+
* What "always allow" can save for a call awaiting approval, narrowest first.
|
|
157
|
+
* The api computes the options from the call; each one, saved, answers it again.
|
|
158
|
+
*/
|
|
159
|
+
export async function getAlwaysAllowOptions(client, chatId, toolInvocationId) {
|
|
160
|
+
const resp = await client.http.request('get', `/chats/${chatId}/tools/${toolInvocationId}/always-allow/options`);
|
|
161
|
+
return resp.data;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Save an "always allow" option (a key from getAlwaysAllowOptions) as chat
|
|
165
|
+
* rules and approve the call once. Without an option the api saves its old
|
|
166
|
+
* default: the command exactly for remote_exec, the whole tool otherwise.
|
|
167
|
+
*/
|
|
168
|
+
export async function alwaysAllowTool(client, chatId, toolInvocationId, option) {
|
|
169
|
+
const data = option ? { option } : {};
|
|
170
|
+
const resp = await client.http.request('post', `/chats/${chatId}/tools/${toolInvocationId}/always-allow`, { data });
|
|
171
|
+
return resp.data;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Explain a call awaiting approval in plain words: what it does, why the agent
|
|
175
|
+
* appears to make it, and its risk. Generated by a model the first time and kept
|
|
176
|
+
* for the call, so asking again is free.
|
|
177
|
+
*/
|
|
178
|
+
export async function explainTool(client, chatId, toolInvocationId) {
|
|
179
|
+
const resp = await client.http.request('post', `/chats/${chatId}/tools/${toolInvocationId}/explain`);
|
|
180
|
+
return resp.data;
|
|
158
181
|
}
|
|
182
|
+
/** Change the chat's settings. Answers with the settings as they now are. */
|
|
159
183
|
export async function updateChatSettings(client, chatId, settings) {
|
|
160
184
|
const resp = await client.http.request('post', `/chats/${chatId}/settings`, { data: settings });
|
|
161
185
|
return resp.data;
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -46,6 +46,6 @@
|
|
|
46
46
|
export { AgentChatProvider } from './provider';
|
|
47
47
|
export { useAgentChat, useAgentActions, useAgentClient, useAgentChatContext, useMessage, } from './hooks';
|
|
48
48
|
export { AgentChatContext, type AgentChatContextValue } from './context';
|
|
49
|
-
export type { AgentClient, FileRef, AdHocAgentConfig, TemplateAgentConfig, AgentOptions, AgentChatState, AgentChatActions, ChatStatus, AgentChatProviderProps, ClientTool, ClientToolHandlerFn, } from './types';
|
|
49
|
+
export type { AgentClient, FileRef, AdHocAgentConfig, TemplateAgentConfig, AgentOptions, AgentChatState, AgentChatActions, AlwaysAllowChoice, ChatStatus, AgentChatProviderProps, ClientTool, ClientToolHandlerFn, } from './types';
|
|
50
50
|
export { isAdHocConfig, isTemplateConfig, isClientTool, extractToolSchemas, extractClientToolHandlers, } from './types';
|
|
51
51
|
export { MCPMethodElicitationCreate, parseMCPInputState, elicitParams, isURLElicitation, buildMCPInputResult, type MCPInputState, type ElicitRequestParams, type ElicitRequestedSchema, type ElicitPropertySchema, } from './mcp-input';
|
package/dist/agent/reducer.js
CHANGED
|
@@ -50,6 +50,43 @@ export function chatReducer(state, action) {
|
|
|
50
50
|
return state;
|
|
51
51
|
return { ...state, chat };
|
|
52
52
|
}
|
|
53
|
+
// The settings and set-agent endpoints answer with only what they wrote.
|
|
54
|
+
// Merge it into the chat it belongs to; a chat switched away from in the
|
|
55
|
+
// meantime is left alone.
|
|
56
|
+
case 'MERGE_CHAT_SETTINGS': {
|
|
57
|
+
const settings = action.payload;
|
|
58
|
+
if (!state.chat || state.chat.id !== settings.chat_id)
|
|
59
|
+
return state;
|
|
60
|
+
return {
|
|
61
|
+
...state,
|
|
62
|
+
chat: {
|
|
63
|
+
...state.chat,
|
|
64
|
+
name: settings.name,
|
|
65
|
+
visibility: settings.visibility,
|
|
66
|
+
agent_data: {
|
|
67
|
+
...state.chat.agent_data,
|
|
68
|
+
allow_all_tools: settings.allow_all_tools,
|
|
69
|
+
disable_hooks: settings.disable_hooks,
|
|
70
|
+
memory: settings.memory,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
case 'MERGE_CHAT_AGENT': {
|
|
76
|
+
const agent = action.payload;
|
|
77
|
+
if (!state.chat || state.chat.id !== agent.chat_id)
|
|
78
|
+
return state;
|
|
79
|
+
return {
|
|
80
|
+
...state,
|
|
81
|
+
chat: {
|
|
82
|
+
...state.chat,
|
|
83
|
+
agent_id: agent.agent_id,
|
|
84
|
+
agent: agent.agent,
|
|
85
|
+
agent_version_id: agent.agent_version_id,
|
|
86
|
+
agent_version: agent.agent_version,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
53
90
|
case 'UPDATE_ACTIVE_RUN': {
|
|
54
91
|
if (!state.chat)
|
|
55
92
|
return state;
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
* Public types for the Agent chat module.
|
|
5
5
|
*/
|
|
6
6
|
import type { Dispatch } from 'react';
|
|
7
|
-
import type { AgentRunDTO, AgentVersionDTO, ChatDTO, ChatMessageDTO, ChatSettingsRequest, AgentTool, AgentConfigInput as GeneratedAgentConfig, CoreAppConfigInput as CoreAppConfig, FileRef, ElicitResult } from '../types';
|
|
7
|
+
import type { AgentRunDTO, AgentVersionDTO, AlwaysAllowOptionsDTO, AlwaysAllowResultDTO, ToolExplanationDTO, ChatAgentDTO, ChatDTO, ChatMessageDTO, ChatSettingsDTO, ChatSettingsRequest, AgentTool, AgentConfigInput as GeneratedAgentConfig, CoreAppConfigInput as CoreAppConfig, FileRef, ElicitResult } from '../types';
|
|
8
8
|
import type { HttpClient } from '../http/client';
|
|
9
9
|
import type { StreamableManager } from '../http/streamable';
|
|
10
10
|
import type { PollManager } from '../http/poll';
|
|
11
11
|
export type { FileRef } from '../types';
|
|
12
|
+
/** The "always allow" option to save: a key from getAlwaysAllowOptions. */
|
|
13
|
+
export interface AlwaysAllowChoice {
|
|
14
|
+
option?: string;
|
|
15
|
+
}
|
|
12
16
|
/**
|
|
13
17
|
* Minimal client interface required by the agent module.
|
|
14
18
|
* This allows extended clients (like the app client) to be used.
|
|
@@ -132,8 +136,26 @@ export interface AgentChatActions {
|
|
|
132
136
|
approveTool: (toolInvocationId: string) => Promise<void>;
|
|
133
137
|
/** Reject a tool (for HIL approval - AwaitingApproval status) */
|
|
134
138
|
rejectTool: (toolInvocationId: string, reason?: string) => Promise<void>;
|
|
135
|
-
/**
|
|
136
|
-
|
|
139
|
+
/**
|
|
140
|
+
* What "always allow" can save for a call awaiting approval, narrowest
|
|
141
|
+
* first, as computed by the api (null without a chat). Show the options'
|
|
142
|
+
* labels in order; `default` is the narrowest that answers the call again.
|
|
143
|
+
*/
|
|
144
|
+
getAlwaysAllowOptions: (toolInvocationId: string) => Promise<AlwaysAllowOptionsDTO | null>;
|
|
145
|
+
/**
|
|
146
|
+
* Explain a call awaiting approval (risk level, what it does, why, what could
|
|
147
|
+
* go wrong). A model generates it the first time it is asked for; later calls
|
|
148
|
+
* return the kept answer. Call it only when the person asks.
|
|
149
|
+
*/
|
|
150
|
+
explainTool: (toolInvocationId: string) => Promise<ToolExplanationDTO>;
|
|
151
|
+
/**
|
|
152
|
+
* Always allow a call: save the chosen option's chat rules (`{ option: key }`
|
|
153
|
+
* from getAlwaysAllowOptions) and approve the call once. Without an option the
|
|
154
|
+
* api saves its default. A string is accepted from older callers (it was the
|
|
155
|
+
* tool name) and means the default. Rejects with a 409 when the option is
|
|
156
|
+
* stale: read the options again.
|
|
157
|
+
*/
|
|
158
|
+
alwaysAllowTool: (toolInvocationId: string, choice?: AlwaysAllowChoice | string) => Promise<AlwaysAllowResultDTO | undefined>;
|
|
137
159
|
/** Change this chat's settings, e.g. allow_all_tools (switching it on approves the calls waiting) */
|
|
138
160
|
updateChatSettings: (settings: ChatSettingsRequest) => Promise<void>;
|
|
139
161
|
/** Hand this chat to another agent (namespace/name); the next message goes to it. Agents our loop runs only. */
|
|
@@ -211,6 +233,12 @@ export type ChatAction = {
|
|
|
211
233
|
} | {
|
|
212
234
|
type: 'UPDATE_CHAT';
|
|
213
235
|
payload: ChatDTO | null;
|
|
236
|
+
} | {
|
|
237
|
+
type: 'MERGE_CHAT_SETTINGS';
|
|
238
|
+
payload: ChatSettingsDTO;
|
|
239
|
+
} | {
|
|
240
|
+
type: 'MERGE_CHAT_AGENT';
|
|
241
|
+
payload: ChatAgentDTO;
|
|
214
242
|
} | {
|
|
215
243
|
type: 'UPDATE_ACTIVE_RUN';
|
|
216
244
|
payload: AgentRunDTO;
|
package/dist/api/agents.js
CHANGED
|
@@ -296,6 +296,10 @@ export class Agent {
|
|
|
296
296
|
const intervalMs = options.pollIntervalMs ?? this.http.getPollIntervalMs();
|
|
297
297
|
let prevStatus = null;
|
|
298
298
|
let knownMessageIds = new Set();
|
|
299
|
+
// Returned by the poll when nothing changed. Compared by identity: a
|
|
300
|
+
// fetched chat never carries chat_messages, so their absence cannot tell
|
|
301
|
+
// the two apart.
|
|
302
|
+
const unchanged = {};
|
|
299
303
|
return new Promise((resolve) => {
|
|
300
304
|
this.poller?.stop();
|
|
301
305
|
this.poller = new PollManager({
|
|
@@ -305,17 +309,15 @@ export class Agent {
|
|
|
305
309
|
const status = statusResp.data;
|
|
306
310
|
// Unchanged status is skipped — unless the turn is still ungated: a run
|
|
307
311
|
// that started and finished between two polls only shows in the messages.
|
|
308
|
-
if (status.status === prevStatus && gate.settled)
|
|
309
|
-
|
|
310
|
-
return { status: status.status };
|
|
311
|
-
}
|
|
312
|
+
if (status.status === prevStatus && gate.settled)
|
|
313
|
+
return unchanged;
|
|
312
314
|
// Status changed — fetch full chat
|
|
313
315
|
const chatResp = await this.http.request('get', `/chats/${this.chatId}`);
|
|
314
316
|
return chatResp.data;
|
|
315
317
|
},
|
|
316
318
|
intervalMs,
|
|
317
319
|
onData: (chat) => {
|
|
318
|
-
if (chat
|
|
320
|
+
if (chat === unchanged)
|
|
319
321
|
return;
|
|
320
322
|
prevStatus = chat.status;
|
|
321
323
|
options.onChat?.(chat);
|
package/dist/types.d.ts
CHANGED
|
@@ -1777,6 +1777,37 @@ export interface ChatSettingsRequest {
|
|
|
1777
1777
|
*/
|
|
1778
1778
|
forget_memory?: string[];
|
|
1779
1779
|
}
|
|
1780
|
+
/**
|
|
1781
|
+
* ChatSettingsDTO is what POST /chats/{id}/settings answers with: the chat's
|
|
1782
|
+
* settings after the change, every field the endpoint writes and nothing
|
|
1783
|
+
* else. A client merges it into the chat it holds.
|
|
1784
|
+
*/
|
|
1785
|
+
export interface ChatSettingsDTO {
|
|
1786
|
+
chat_id: string;
|
|
1787
|
+
name: string;
|
|
1788
|
+
visibility: Visibility;
|
|
1789
|
+
/**
|
|
1790
|
+
* AllowAllTools and DisableHooks are agent_data.allow_all_tools and
|
|
1791
|
+
* agent_data.disable_hooks on the chat.
|
|
1792
|
+
*/
|
|
1793
|
+
allow_all_tools: boolean;
|
|
1794
|
+
disable_hooks: boolean;
|
|
1795
|
+
/**
|
|
1796
|
+
* Memory is agent_data.memory after forget_memory removed its keys.
|
|
1797
|
+
*/
|
|
1798
|
+
memory: StringEncodedMap;
|
|
1799
|
+
}
|
|
1800
|
+
/**
|
|
1801
|
+
* ChatAgentDTO is what POST /chats/{id}/agent answers with: the agent the
|
|
1802
|
+
* chat now runs on. A client merges it into the chat it holds.
|
|
1803
|
+
*/
|
|
1804
|
+
export interface ChatAgentDTO {
|
|
1805
|
+
chat_id: string;
|
|
1806
|
+
agent_id: string;
|
|
1807
|
+
agent?: AgentDTO;
|
|
1808
|
+
agent_version_id: string;
|
|
1809
|
+
agent_version?: AgentVersionDTO;
|
|
1810
|
+
}
|
|
1780
1811
|
/**
|
|
1781
1812
|
* ChatDTO for API responses
|
|
1782
1813
|
*/
|
|
@@ -1800,7 +1831,12 @@ export interface ChatDTO extends BaseModelDTO, PermissionModelDTO {
|
|
|
1800
1831
|
agent_version?: AgentVersionDTO;
|
|
1801
1832
|
name: string;
|
|
1802
1833
|
description: string;
|
|
1803
|
-
|
|
1834
|
+
/**
|
|
1835
|
+
* ChatMessages is left out when the messages were not loaded. The chat
|
|
1836
|
+
* endpoints do not load them; read them from GET /chats/{id}/messages.
|
|
1837
|
+
* An absent field says nothing about whether the chat has messages.
|
|
1838
|
+
*/
|
|
1839
|
+
chat_messages?: ChatMessageDTO[];
|
|
1804
1840
|
agent_data: ChatData;
|
|
1805
1841
|
active_run?: AgentRunDTO;
|
|
1806
1842
|
pending_interrupts?: InterruptDTO[];
|
|
@@ -1834,6 +1870,189 @@ export interface ChatMessageDTO extends BaseModelDTO, PermissionModelDTO {
|
|
|
1834
1870
|
tool_call_id?: string;
|
|
1835
1871
|
tool_invocations?: ToolInvocationDTO[];
|
|
1836
1872
|
}
|
|
1873
|
+
/**
|
|
1874
|
+
* PolicyEffect is a rule's outcome: allow, ask or deny.
|
|
1875
|
+
*/
|
|
1876
|
+
export type PolicyEffect = "allow" | "ask" | "deny";
|
|
1877
|
+
export declare const PolicyEffectAllow: PolicyEffect;
|
|
1878
|
+
export declare const PolicyEffectAsk: PolicyEffect;
|
|
1879
|
+
export declare const PolicyEffectDeny: PolicyEffect;
|
|
1880
|
+
/**
|
|
1881
|
+
* PolicyRuleDTO is one rule, typed form Kind[selector](specifier).
|
|
1882
|
+
*/
|
|
1883
|
+
export interface PolicyRuleDTO {
|
|
1884
|
+
id: string;
|
|
1885
|
+
effect: PolicyEffect;
|
|
1886
|
+
/**
|
|
1887
|
+
* Kind: RemoteExec, Workspace, Harness, Tool (and, from phase 3, App,
|
|
1888
|
+
* Agent, Knowledge, Mcp, Flow, WebFetch).
|
|
1889
|
+
*/
|
|
1890
|
+
kind: string;
|
|
1891
|
+
/**
|
|
1892
|
+
* Selector narrows the rule to one remote (its id) or a tag (tag:<name>);
|
|
1893
|
+
* empty applies everywhere.
|
|
1894
|
+
*/
|
|
1895
|
+
selector: string;
|
|
1896
|
+
/**
|
|
1897
|
+
* Specifier is the kind's pattern: a command (`npm test`, `git push:*`),
|
|
1898
|
+
* a folder (`~/proj/**`), a harness tool with its pattern
|
|
1899
|
+
* (`Bash(git status:*)`, `Edit`), or a loop tool's name. Empty is the
|
|
1900
|
+
* whole kind.
|
|
1901
|
+
*/
|
|
1902
|
+
specifier: string;
|
|
1903
|
+
/**
|
|
1904
|
+
* Label is the rule in words, e.g. "git commit commands on Laptop", the
|
|
1905
|
+
* same words an approval prompt's "always allow" options use.
|
|
1906
|
+
*/
|
|
1907
|
+
label: string;
|
|
1908
|
+
/**
|
|
1909
|
+
* CreatedAt is null for a rule that is not a stored row yet: an entry of
|
|
1910
|
+
* the chat's always-allow list from before rules existed, or the chat's
|
|
1911
|
+
* "allow every tool" setting.
|
|
1912
|
+
*/
|
|
1913
|
+
created_at?: string;
|
|
1914
|
+
/**
|
|
1915
|
+
* CreatedBy is the user who wrote the rule; empty for those above.
|
|
1916
|
+
*/
|
|
1917
|
+
created_by: string;
|
|
1918
|
+
}
|
|
1919
|
+
/**
|
|
1920
|
+
* AlwaysAllowScope is how far an "always allow" option reaches, narrowest
|
|
1921
|
+
* first.
|
|
1922
|
+
*/
|
|
1923
|
+
export type AlwaysAllowScope = "exact" | "prefix" | "folder" | "remote" | "tool";
|
|
1924
|
+
/**
|
|
1925
|
+
* AlwaysAllowScopeExact: this call exactly (each piece of the command,
|
|
1926
|
+
* the file, the domain).
|
|
1927
|
+
*/
|
|
1928
|
+
export declare const AlwaysAllowScopeExact: AlwaysAllowScope;
|
|
1929
|
+
/**
|
|
1930
|
+
* AlwaysAllowScopePrefix: commands that start the same way, per piece
|
|
1931
|
+
* (git commit:*, npm run:*).
|
|
1932
|
+
*/
|
|
1933
|
+
export declare const AlwaysAllowScopePrefix: AlwaysAllowScope;
|
|
1934
|
+
/**
|
|
1935
|
+
* AlwaysAllowScopeFolder: files in the same folder.
|
|
1936
|
+
*/
|
|
1937
|
+
export declare const AlwaysAllowScopeFolder: AlwaysAllowScope;
|
|
1938
|
+
/**
|
|
1939
|
+
* AlwaysAllowScopeRemote: every command on the machine.
|
|
1940
|
+
*/
|
|
1941
|
+
export declare const AlwaysAllowScopeRemote: AlwaysAllowScope;
|
|
1942
|
+
/**
|
|
1943
|
+
* AlwaysAllowScopeTool: every call of the tool.
|
|
1944
|
+
*/
|
|
1945
|
+
export declare const AlwaysAllowScopeTool: AlwaysAllowScope;
|
|
1946
|
+
/**
|
|
1947
|
+
* AlwaysAllowOptionDTO is one "always allow" choice on an approval prompt:
|
|
1948
|
+
* the chat rules it saves.
|
|
1949
|
+
*/
|
|
1950
|
+
export interface AlwaysAllowOptionDTO {
|
|
1951
|
+
/**
|
|
1952
|
+
* Key names the option in POST .../always-allow. It changes when the
|
|
1953
|
+
* rules it stands for change.
|
|
1954
|
+
*/
|
|
1955
|
+
key: string;
|
|
1956
|
+
scope: AlwaysAllowScope;
|
|
1957
|
+
/**
|
|
1958
|
+
* Label is the option in words, e.g. "git clone commands on Laptop".
|
|
1959
|
+
*/
|
|
1960
|
+
label: string;
|
|
1961
|
+
/**
|
|
1962
|
+
* Description adds why a broad option is the narrowest offered, e.g.
|
|
1963
|
+
* the command uses shell syntax no narrower rule can match.
|
|
1964
|
+
*/
|
|
1965
|
+
description?: string;
|
|
1966
|
+
/**
|
|
1967
|
+
* Rules are the chat rules the option saves (not stored yet: no id).
|
|
1968
|
+
*/
|
|
1969
|
+
rules: PolicyRuleDTO[];
|
|
1970
|
+
}
|
|
1971
|
+
/**
|
|
1972
|
+
* AlwaysAllowOptionsDTO is GET /chats/{id}/tools/{toolId}/always-allow/options:
|
|
1973
|
+
* the options for a call awaiting approval, narrowest first. Each one,
|
|
1974
|
+
* saved, answers this call again. Computed by the api from the call; the
|
|
1975
|
+
* client never builds rules.
|
|
1976
|
+
*/
|
|
1977
|
+
export interface AlwaysAllowOptionsDTO {
|
|
1978
|
+
options: AlwaysAllowOptionDTO[];
|
|
1979
|
+
/**
|
|
1980
|
+
* Default is the key of the narrowest option, "" when there is none.
|
|
1981
|
+
*/
|
|
1982
|
+
default?: string;
|
|
1983
|
+
/**
|
|
1984
|
+
* Unavailable says why there are no options: a policy allows only its
|
|
1985
|
+
* own rules, or no chat rule could allow this call.
|
|
1986
|
+
*/
|
|
1987
|
+
unavailable?: string;
|
|
1988
|
+
}
|
|
1989
|
+
/**
|
|
1990
|
+
* AlwaysAllowRequest is POST /chats/{id}/tools/{toolId}/always-allow. The
|
|
1991
|
+
* api saves the option's rules to the chat and approves the call once.
|
|
1992
|
+
*/
|
|
1993
|
+
export interface AlwaysAllowRequest {
|
|
1994
|
+
/**
|
|
1995
|
+
* Option is an option key from the options endpoint. A key that no
|
|
1996
|
+
* longer names a current option is refused (409). Without one, the
|
|
1997
|
+
* call saves what "always allow" saved before options existed: the
|
|
1998
|
+
* command's pieces exactly for remote_exec, the whole tool otherwise.
|
|
1999
|
+
*/
|
|
2000
|
+
option?: string;
|
|
2001
|
+
/**
|
|
2002
|
+
* ToolName is accepted from older clients and ignored: the call names
|
|
2003
|
+
* its own tool.
|
|
2004
|
+
*/
|
|
2005
|
+
tool_name?: string;
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* AlwaysAllowResultDTO is what an always-allow saved.
|
|
2009
|
+
*/
|
|
2010
|
+
export interface AlwaysAllowResultDTO {
|
|
2011
|
+
/**
|
|
2012
|
+
* Option is the option chosen; null for a call without one.
|
|
2013
|
+
*/
|
|
2014
|
+
option?: AlwaysAllowOptionDTO;
|
|
2015
|
+
/**
|
|
2016
|
+
* Rules are the chat rules now in place for it.
|
|
2017
|
+
*/
|
|
2018
|
+
rules: PolicyRuleDTO[];
|
|
2019
|
+
}
|
|
2020
|
+
/**
|
|
2021
|
+
* ToolRiskLevel is how risky an explained call is.
|
|
2022
|
+
*/
|
|
2023
|
+
export type ToolRiskLevel = "low" | "medium" | "high";
|
|
2024
|
+
/**
|
|
2025
|
+
* ToolRiskLow: safe development workflows (reads, builds, tests).
|
|
2026
|
+
*/
|
|
2027
|
+
export declare const ToolRiskLow: ToolRiskLevel;
|
|
2028
|
+
/**
|
|
2029
|
+
* ToolRiskMedium: changes that can be undone.
|
|
2030
|
+
*/
|
|
2031
|
+
export declare const ToolRiskMedium: ToolRiskLevel;
|
|
2032
|
+
/**
|
|
2033
|
+
* ToolRiskHigh: dangerous or irreversible changes.
|
|
2034
|
+
*/
|
|
2035
|
+
export declare const ToolRiskHigh: ToolRiskLevel;
|
|
2036
|
+
/**
|
|
2037
|
+
* ToolExplanationDTO is POST /chats/{id}/tools/{toolId}/explain: a model's
|
|
2038
|
+
* plain-words reading of a call awaiting approval (Claude Code's permission
|
|
2039
|
+
* explainer). Generated once, when the person asks, and kept for the call.
|
|
2040
|
+
*/
|
|
2041
|
+
export interface ToolExplanationDTO {
|
|
2042
|
+
risk_level: ToolRiskLevel;
|
|
2043
|
+
/**
|
|
2044
|
+
* Explanation is what the call does, in one or two sentences.
|
|
2045
|
+
*/
|
|
2046
|
+
explanation: string;
|
|
2047
|
+
/**
|
|
2048
|
+
* Reasoning is why the agent appears to be making it.
|
|
2049
|
+
*/
|
|
2050
|
+
reasoning: string;
|
|
2051
|
+
/**
|
|
2052
|
+
* Risk is what could go wrong, in a few words.
|
|
2053
|
+
*/
|
|
2054
|
+
risk: string;
|
|
2055
|
+
}
|
|
1837
2056
|
/**
|
|
1838
2057
|
* CredentialDTO is the API response for a credential (never exposes secrets).
|
|
1839
2058
|
*/
|
package/dist/types.js
CHANGED
|
@@ -302,6 +302,43 @@ export const ScopeGroupKnowledge = "knowledge";
|
|
|
302
302
|
export const ScopeGroupArtifacts = "artifacts";
|
|
303
303
|
export const ScopeGroupUser = "user";
|
|
304
304
|
export const ScopeGroupSettings = "settings";
|
|
305
|
+
export const PolicyEffectAllow = "allow";
|
|
306
|
+
export const PolicyEffectAsk = "ask";
|
|
307
|
+
export const PolicyEffectDeny = "deny";
|
|
308
|
+
/**
|
|
309
|
+
* AlwaysAllowScopeExact: this call exactly (each piece of the command,
|
|
310
|
+
* the file, the domain).
|
|
311
|
+
*/
|
|
312
|
+
export const AlwaysAllowScopeExact = "exact";
|
|
313
|
+
/**
|
|
314
|
+
* AlwaysAllowScopePrefix: commands that start the same way, per piece
|
|
315
|
+
* (git commit:*, npm run:*).
|
|
316
|
+
*/
|
|
317
|
+
export const AlwaysAllowScopePrefix = "prefix";
|
|
318
|
+
/**
|
|
319
|
+
* AlwaysAllowScopeFolder: files in the same folder.
|
|
320
|
+
*/
|
|
321
|
+
export const AlwaysAllowScopeFolder = "folder";
|
|
322
|
+
/**
|
|
323
|
+
* AlwaysAllowScopeRemote: every command on the machine.
|
|
324
|
+
*/
|
|
325
|
+
export const AlwaysAllowScopeRemote = "remote";
|
|
326
|
+
/**
|
|
327
|
+
* AlwaysAllowScopeTool: every call of the tool.
|
|
328
|
+
*/
|
|
329
|
+
export const AlwaysAllowScopeTool = "tool";
|
|
330
|
+
/**
|
|
331
|
+
* ToolRiskLow: safe development workflows (reads, builds, tests).
|
|
332
|
+
*/
|
|
333
|
+
export const ToolRiskLow = "low";
|
|
334
|
+
/**
|
|
335
|
+
* ToolRiskMedium: changes that can be undone.
|
|
336
|
+
*/
|
|
337
|
+
export const ToolRiskMedium = "medium";
|
|
338
|
+
/**
|
|
339
|
+
* ToolRiskHigh: dangerous or irreversible changes.
|
|
340
|
+
*/
|
|
341
|
+
export const ToolRiskHigh = "high";
|
|
305
342
|
export const ErrorCodeInvalidRequest = "invalid_request";
|
|
306
343
|
export const ErrorCodeValidationError = "validation_error";
|
|
307
344
|
export const ErrorCodeUnauthorized = "unauthorized";
|