@yushaw/sanqian-sdk 0.2.10 → 0.2.12
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/dist/index.browser.d.mts +445 -0
- package/dist/index.browser.mjs +1071 -0
- package/dist/index.browser.mjs.map +1 -0
- package/dist/index.d.mts +29 -2
- package/dist/index.d.ts +29 -2
- package/dist/index.js +345 -281
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +363 -266
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -2
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanqian SDK Type Definitions
|
|
3
|
+
*/
|
|
4
|
+
interface SDKConfig {
|
|
5
|
+
/** Unique app identifier (e.g., "sanqian-todolist") */
|
|
6
|
+
appName: string;
|
|
7
|
+
/** App version string */
|
|
8
|
+
appVersion: string;
|
|
9
|
+
/** Display name shown in Sanqian UI */
|
|
10
|
+
displayName?: string;
|
|
11
|
+
/** Command to launch this app (for auto-start) */
|
|
12
|
+
launchCommand?: string;
|
|
13
|
+
/** Tools provided by this app */
|
|
14
|
+
tools: ToolDefinition[];
|
|
15
|
+
/** Reconnect interval in ms (default: 5000) */
|
|
16
|
+
reconnectInterval?: number;
|
|
17
|
+
/** Heartbeat interval in ms (default: 30000) */
|
|
18
|
+
heartbeatInterval?: number;
|
|
19
|
+
/** Tool execution timeout in ms (default: 30000) */
|
|
20
|
+
toolExecutionTimeout?: number;
|
|
21
|
+
/**
|
|
22
|
+
* Auto-launch Sanqian if not running (default: false)
|
|
23
|
+
* When enabled, SDK will try to start Sanqian in hidden/tray mode
|
|
24
|
+
*/
|
|
25
|
+
autoLaunchSanqian?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Custom path to Sanqian executable (optional)
|
|
28
|
+
* If not provided, SDK will search in standard installation locations
|
|
29
|
+
*/
|
|
30
|
+
sanqianPath?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Enable debug logging (default: false)
|
|
33
|
+
* When enabled, SDK will output detailed logs to console
|
|
34
|
+
*/
|
|
35
|
+
debug?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Pre-configured connection info (for browser environments)
|
|
38
|
+
* When provided, SDK skips file-based discovery and connects directly.
|
|
39
|
+
* This is useful for browser extensions that discover Sanqian via other means
|
|
40
|
+
* (e.g., native messaging or HTTP API).
|
|
41
|
+
*/
|
|
42
|
+
connectionInfo?: ConnectionInfo;
|
|
43
|
+
}
|
|
44
|
+
interface ToolDefinition {
|
|
45
|
+
/** Tool name (without app prefix) */
|
|
46
|
+
name: string;
|
|
47
|
+
/** Tool description for LLM */
|
|
48
|
+
description: string;
|
|
49
|
+
/** JSON Schema for parameters */
|
|
50
|
+
parameters: JSONSchema;
|
|
51
|
+
/** Handler function */
|
|
52
|
+
handler: (args: any) => Promise<any>;
|
|
53
|
+
/**
|
|
54
|
+
* Whether this tool can be discovered via search_capability (default: true)
|
|
55
|
+
* Set to false for internal tools that should be available but not searchable
|
|
56
|
+
*/
|
|
57
|
+
searchable?: boolean;
|
|
58
|
+
}
|
|
59
|
+
interface JSONSchema {
|
|
60
|
+
type: "object" | "array" | "string" | "number" | "boolean";
|
|
61
|
+
properties?: Record<string, JSONSchemaProperty>;
|
|
62
|
+
required?: string[];
|
|
63
|
+
items?: JSONSchemaProperty;
|
|
64
|
+
description?: string;
|
|
65
|
+
}
|
|
66
|
+
interface JSONSchemaProperty {
|
|
67
|
+
type: "string" | "number" | "boolean" | "array" | "object";
|
|
68
|
+
description?: string;
|
|
69
|
+
enum?: (string | number)[];
|
|
70
|
+
default?: unknown;
|
|
71
|
+
items?: JSONSchemaProperty;
|
|
72
|
+
properties?: Record<string, JSONSchemaProperty>;
|
|
73
|
+
required?: string[];
|
|
74
|
+
format?: string;
|
|
75
|
+
}
|
|
76
|
+
interface ConnectionInfo {
|
|
77
|
+
version: number;
|
|
78
|
+
port: number;
|
|
79
|
+
ws_path: string;
|
|
80
|
+
token: string;
|
|
81
|
+
pid: number;
|
|
82
|
+
started_at: string;
|
|
83
|
+
/** Path to Sanqian executable (for SDK auto-launch) */
|
|
84
|
+
executable?: string;
|
|
85
|
+
}
|
|
86
|
+
interface ConnectionState {
|
|
87
|
+
connected: boolean;
|
|
88
|
+
registering: boolean;
|
|
89
|
+
registered: boolean;
|
|
90
|
+
lastError?: Error;
|
|
91
|
+
reconnectAttempts: number;
|
|
92
|
+
}
|
|
93
|
+
/** Remote tool definition for dynamic tool injection */
|
|
94
|
+
interface RemoteToolDefinition {
|
|
95
|
+
/** Tool name */
|
|
96
|
+
name: string;
|
|
97
|
+
/** Tool description for LLM */
|
|
98
|
+
description: string;
|
|
99
|
+
/** JSON Schema for parameters */
|
|
100
|
+
parameters: JSONSchema;
|
|
101
|
+
}
|
|
102
|
+
interface ChatRequest {
|
|
103
|
+
/** Agent ID (can be short name, SDK auto-adds app prefix) */
|
|
104
|
+
agentId: string;
|
|
105
|
+
/** Messages to send */
|
|
106
|
+
messages: ChatMessage[];
|
|
107
|
+
/** Conversation ID for stateful mode (server stores messages) */
|
|
108
|
+
conversationId?: string;
|
|
109
|
+
/** Enable streaming (default: true) */
|
|
110
|
+
stream?: boolean;
|
|
111
|
+
/** Dynamic tools to inject at call time */
|
|
112
|
+
remoteTools?: RemoteToolDefinition[];
|
|
113
|
+
}
|
|
114
|
+
interface ChatMessage {
|
|
115
|
+
role: "user" | "assistant" | "system" | "tool";
|
|
116
|
+
content: string;
|
|
117
|
+
tool_calls?: ToolCall[];
|
|
118
|
+
tool_call_id?: string;
|
|
119
|
+
}
|
|
120
|
+
interface ToolCall {
|
|
121
|
+
id: string;
|
|
122
|
+
type: "function";
|
|
123
|
+
function: {
|
|
124
|
+
name: string;
|
|
125
|
+
arguments: string;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
interface ChatResponse {
|
|
129
|
+
message: ChatMessage;
|
|
130
|
+
conversationId: string;
|
|
131
|
+
/** Conversation title (truncated from first user message, or LLM-generated after 3rd round) */
|
|
132
|
+
title?: string;
|
|
133
|
+
usage?: {
|
|
134
|
+
prompt_tokens: number;
|
|
135
|
+
completion_tokens: number;
|
|
136
|
+
total_tokens: number;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
interface ChatStreamEvent {
|
|
140
|
+
type: "text" | "thinking" | "tool_call" | "tool_result" | "done" | "error";
|
|
141
|
+
/** Text content (for "text" and "thinking" events) */
|
|
142
|
+
content?: string;
|
|
143
|
+
/** Tool call info (for "tool_call" event) */
|
|
144
|
+
tool_call?: ToolCall;
|
|
145
|
+
/** Tool call ID (for "tool_result" event) */
|
|
146
|
+
tool_call_id?: string;
|
|
147
|
+
/** Tool execution result (for "tool_result" event) */
|
|
148
|
+
result?: unknown;
|
|
149
|
+
/** Whether tool execution succeeded (for "tool_result" event) */
|
|
150
|
+
success?: boolean;
|
|
151
|
+
/** Conversation ID (for "done" event) */
|
|
152
|
+
conversationId?: string;
|
|
153
|
+
/** Conversation title (for "done" event) */
|
|
154
|
+
title?: string;
|
|
155
|
+
/** Error message (for "error" event or failed "tool_result") */
|
|
156
|
+
error?: string;
|
|
157
|
+
}
|
|
158
|
+
/** Agent configuration for create/update */
|
|
159
|
+
interface AgentConfig {
|
|
160
|
+
/** Unique agent ID within this app (e.g., "assistant") */
|
|
161
|
+
agent_id: string;
|
|
162
|
+
/** Display name */
|
|
163
|
+
name: string;
|
|
164
|
+
/** Description */
|
|
165
|
+
description?: string;
|
|
166
|
+
/** System prompt */
|
|
167
|
+
system_prompt?: string;
|
|
168
|
+
/** Tool names from this app to enable (without prefix) */
|
|
169
|
+
tools?: string[];
|
|
170
|
+
/**
|
|
171
|
+
* Sub-agents this agent can call via task tool.
|
|
172
|
+
* - undefined/null: Cannot use task tool (default)
|
|
173
|
+
* - []: Cannot use task tool (explicit)
|
|
174
|
+
* - ["*"]: Can call all available agents
|
|
175
|
+
* - ["agent1", "agent2"]: Can only call specified agents
|
|
176
|
+
*/
|
|
177
|
+
subagents?: string[];
|
|
178
|
+
/**
|
|
179
|
+
* Whether this agent can be discovered via search_capability (default: true)
|
|
180
|
+
* Set to false if you want the agent to be usable but not discoverable by other agents
|
|
181
|
+
*/
|
|
182
|
+
searchable?: boolean;
|
|
183
|
+
}
|
|
184
|
+
/** Agent info returned from list */
|
|
185
|
+
interface AgentInfo {
|
|
186
|
+
/** Full agent ID (app_name:agent_id) */
|
|
187
|
+
agent_id: string;
|
|
188
|
+
name: string;
|
|
189
|
+
description?: string;
|
|
190
|
+
/** Tool names with sdk_ prefix */
|
|
191
|
+
tools: string[];
|
|
192
|
+
/** Sub-agents this agent can call via task tool */
|
|
193
|
+
subagents?: string[] | null;
|
|
194
|
+
/** Whether this agent can be discovered via search_capability */
|
|
195
|
+
searchable?: boolean;
|
|
196
|
+
created_at?: string;
|
|
197
|
+
}
|
|
198
|
+
/** Conversation info */
|
|
199
|
+
interface ConversationInfo {
|
|
200
|
+
conversation_id: string;
|
|
201
|
+
agent_id: string;
|
|
202
|
+
title?: string;
|
|
203
|
+
message_count: number;
|
|
204
|
+
created_at?: string;
|
|
205
|
+
updated_at?: string;
|
|
206
|
+
}
|
|
207
|
+
/** Message in a conversation */
|
|
208
|
+
interface ConversationMessage {
|
|
209
|
+
id: string;
|
|
210
|
+
role: "user" | "assistant" | "system" | "tool";
|
|
211
|
+
content: string;
|
|
212
|
+
tool_calls?: ToolCall[] | null;
|
|
213
|
+
tool_call_id?: string | null;
|
|
214
|
+
created_at?: string;
|
|
215
|
+
}
|
|
216
|
+
/** Full conversation with messages */
|
|
217
|
+
interface ConversationDetail extends ConversationInfo {
|
|
218
|
+
messages?: ConversationMessage[];
|
|
219
|
+
}
|
|
220
|
+
/** Agent update configuration (all fields optional except agent_id) */
|
|
221
|
+
interface AgentUpdateConfig {
|
|
222
|
+
/** Agent ID to update */
|
|
223
|
+
agent_id: string;
|
|
224
|
+
/** New display name */
|
|
225
|
+
name?: string;
|
|
226
|
+
/** New description */
|
|
227
|
+
description?: string;
|
|
228
|
+
/** New system prompt */
|
|
229
|
+
system_prompt?: string;
|
|
230
|
+
/** New tool names from this app to enable (without prefix) */
|
|
231
|
+
tools?: string[];
|
|
232
|
+
/**
|
|
233
|
+
* Sub-agents this agent can call via task tool.
|
|
234
|
+
* - undefined: Keep existing value
|
|
235
|
+
* - null/[]: Cannot use task tool
|
|
236
|
+
* - ["*"]: Can call all available agents
|
|
237
|
+
* - ["agent1", "agent2"]: Can only call specified agents
|
|
238
|
+
*/
|
|
239
|
+
subagents?: string[] | null;
|
|
240
|
+
/**
|
|
241
|
+
* Whether this agent can be discovered via search_capability
|
|
242
|
+
* - undefined: Keep existing value
|
|
243
|
+
* - true/false: Set explicitly
|
|
244
|
+
*/
|
|
245
|
+
searchable?: boolean;
|
|
246
|
+
}
|
|
247
|
+
interface SDKEvents {
|
|
248
|
+
connected: () => void;
|
|
249
|
+
disconnected: (reason: string) => void;
|
|
250
|
+
registered: () => void;
|
|
251
|
+
error: (error: Error) => void;
|
|
252
|
+
tool_call: (call: {
|
|
253
|
+
name: string;
|
|
254
|
+
arguments: Record<string, unknown>;
|
|
255
|
+
}) => void;
|
|
256
|
+
}
|
|
257
|
+
type SDKEventName = keyof SDKEvents;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Sanqian SDK Client - Browser Build
|
|
261
|
+
*
|
|
262
|
+
* This is a browser-optimized version of the SDK client that does NOT include
|
|
263
|
+
* DiscoveryManager or any Node.js APIs (fs, path, child_process, os).
|
|
264
|
+
*
|
|
265
|
+
* IMPORTANT: When using this build, you MUST provide connectionInfo in config.
|
|
266
|
+
* Auto-discovery and auto-launch features are not available in browser environments.
|
|
267
|
+
*
|
|
268
|
+
* TODO: Consider refactoring to share code with client.ts using composition or
|
|
269
|
+
* inheritance pattern to reduce duplication (~900 lines shared). Currently kept
|
|
270
|
+
* separate for simplicity and to avoid complex build configurations.
|
|
271
|
+
* See: https://github.com/anthropics/claude-code/issues/xxx (if tracked)
|
|
272
|
+
*/
|
|
273
|
+
|
|
274
|
+
declare class SanqianSDK {
|
|
275
|
+
private config;
|
|
276
|
+
private ws;
|
|
277
|
+
private connectionInfo;
|
|
278
|
+
private state;
|
|
279
|
+
private toolHandlers;
|
|
280
|
+
private pendingRequests;
|
|
281
|
+
private heartbeatTimer;
|
|
282
|
+
private reconnectTimer;
|
|
283
|
+
private heartbeatAckPending;
|
|
284
|
+
private missedHeartbeats;
|
|
285
|
+
private static readonly MAX_MISSED_HEARTBEATS;
|
|
286
|
+
private connectingPromise;
|
|
287
|
+
private reconnectRefCount;
|
|
288
|
+
private eventListeners;
|
|
289
|
+
private log;
|
|
290
|
+
private warn;
|
|
291
|
+
constructor(config: SDKConfig);
|
|
292
|
+
/**
|
|
293
|
+
* Build WebSocket URL from connection info
|
|
294
|
+
*/
|
|
295
|
+
private buildWebSocketUrl;
|
|
296
|
+
connect(): Promise<void>;
|
|
297
|
+
private connectWithInfo;
|
|
298
|
+
disconnect(): Promise<void>;
|
|
299
|
+
private register;
|
|
300
|
+
private handleMessage;
|
|
301
|
+
private handleChatStream;
|
|
302
|
+
private handleToolCall;
|
|
303
|
+
private sendToolResult;
|
|
304
|
+
private handleDisconnect;
|
|
305
|
+
private shouldAutoReconnect;
|
|
306
|
+
acquireReconnect(): void;
|
|
307
|
+
releaseReconnect(): void;
|
|
308
|
+
private scheduleReconnect;
|
|
309
|
+
private stopReconnect;
|
|
310
|
+
private startHeartbeat;
|
|
311
|
+
private stopHeartbeat;
|
|
312
|
+
private send;
|
|
313
|
+
private sendAndWait;
|
|
314
|
+
getState(): ConnectionState;
|
|
315
|
+
isConnected(): boolean;
|
|
316
|
+
ensureReady(): Promise<void>;
|
|
317
|
+
private doFullConnect;
|
|
318
|
+
updateTools(tools: ToolDefinition[]): Promise<void>;
|
|
319
|
+
createAgent(config: AgentConfig): Promise<AgentInfo>;
|
|
320
|
+
listAgents(): Promise<AgentInfo[]>;
|
|
321
|
+
deleteAgent(agentId: string): Promise<void>;
|
|
322
|
+
updateAgent(agentId: string, updates: Omit<AgentUpdateConfig, "agent_id">): Promise<AgentInfo>;
|
|
323
|
+
listConversations(options?: {
|
|
324
|
+
agentId?: string;
|
|
325
|
+
limit?: number;
|
|
326
|
+
offset?: number;
|
|
327
|
+
}): Promise<{
|
|
328
|
+
conversations: ConversationInfo[];
|
|
329
|
+
total: number;
|
|
330
|
+
}>;
|
|
331
|
+
getConversation(conversationId: string, options?: {
|
|
332
|
+
includeMessages?: boolean;
|
|
333
|
+
messageLimit?: number;
|
|
334
|
+
messageOffset?: number;
|
|
335
|
+
}): Promise<ConversationDetail>;
|
|
336
|
+
deleteConversation(conversationId: string): Promise<void>;
|
|
337
|
+
private streamHandlers;
|
|
338
|
+
chat(agentId: string, messages: ChatMessage[], options?: {
|
|
339
|
+
conversationId?: string;
|
|
340
|
+
remoteTools?: RemoteToolDefinition[];
|
|
341
|
+
}): Promise<ChatResponse>;
|
|
342
|
+
chatStream(agentId: string, messages: ChatMessage[], options?: {
|
|
343
|
+
conversationId?: string;
|
|
344
|
+
remoteTools?: RemoteToolDefinition[];
|
|
345
|
+
}): AsyncGenerator<ChatStreamEvent>;
|
|
346
|
+
startConversation(agentId: string): Conversation;
|
|
347
|
+
on<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this;
|
|
348
|
+
off<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this;
|
|
349
|
+
once<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this;
|
|
350
|
+
/**
|
|
351
|
+
* Remove all event listeners
|
|
352
|
+
*
|
|
353
|
+
* Call this to prevent memory leaks when disposing the SDK instance.
|
|
354
|
+
* If event is specified, only removes listeners for that event.
|
|
355
|
+
*/
|
|
356
|
+
removeAllListeners(event?: SDKEventName): this;
|
|
357
|
+
private emit;
|
|
358
|
+
private generateId;
|
|
359
|
+
private createTimeout;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Conversation helper for multi-turn chat
|
|
363
|
+
*/
|
|
364
|
+
declare class Conversation {
|
|
365
|
+
private sdk;
|
|
366
|
+
private agentId;
|
|
367
|
+
private _conversationId;
|
|
368
|
+
constructor(sdk: SanqianSDK, agentId: string, conversationId?: string);
|
|
369
|
+
get id(): string | null;
|
|
370
|
+
send(content: string, options?: {
|
|
371
|
+
remoteTools?: RemoteToolDefinition[];
|
|
372
|
+
}): Promise<ChatResponse>;
|
|
373
|
+
sendStream(content: string, options?: {
|
|
374
|
+
remoteTools?: RemoteToolDefinition[];
|
|
375
|
+
}): AsyncGenerator<ChatStreamEvent>;
|
|
376
|
+
delete(): Promise<void>;
|
|
377
|
+
getDetails(options?: {
|
|
378
|
+
messageLimit?: number;
|
|
379
|
+
}): Promise<ConversationDetail>;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* SDK Error Messages
|
|
384
|
+
*
|
|
385
|
+
* User-friendly error messages in English and Chinese.
|
|
386
|
+
* All errors guide users to sanqian.io for installation.
|
|
387
|
+
*/
|
|
388
|
+
declare const SANQIAN_WEBSITE = "https://sanqian.io";
|
|
389
|
+
/**
|
|
390
|
+
* Error codes for SDK errors
|
|
391
|
+
*/
|
|
392
|
+
declare enum SDKErrorCode {
|
|
393
|
+
NOT_INSTALLED = "NOT_INSTALLED",
|
|
394
|
+
NOT_RUNNING = "NOT_RUNNING",
|
|
395
|
+
CONNECTION_TIMEOUT = "CONNECTION_TIMEOUT",
|
|
396
|
+
STARTUP_TIMEOUT = "STARTUP_TIMEOUT",
|
|
397
|
+
REGISTRATION_FAILED = "REGISTRATION_FAILED",
|
|
398
|
+
REQUEST_TIMEOUT = "REQUEST_TIMEOUT",
|
|
399
|
+
REQUEST_FAILED = "REQUEST_FAILED",
|
|
400
|
+
DISCONNECTED = "DISCONNECTED",
|
|
401
|
+
WEBSOCKET_ERROR = "WEBSOCKET_ERROR",
|
|
402
|
+
AGENT_NOT_FOUND = "AGENT_NOT_FOUND",
|
|
403
|
+
CONVERSATION_NOT_FOUND = "CONVERSATION_NOT_FOUND",
|
|
404
|
+
TOOL_NOT_FOUND = "TOOL_NOT_FOUND",
|
|
405
|
+
TOOL_EXECUTION_TIMEOUT = "TOOL_EXECUTION_TIMEOUT"
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Bilingual error messages
|
|
409
|
+
*/
|
|
410
|
+
declare const ErrorMessages: Record<SDKErrorCode, {
|
|
411
|
+
en: string;
|
|
412
|
+
zh: string;
|
|
413
|
+
hint?: {
|
|
414
|
+
en: string;
|
|
415
|
+
zh: string;
|
|
416
|
+
};
|
|
417
|
+
}>;
|
|
418
|
+
/**
|
|
419
|
+
* Custom SDK Error with code and bilingual message
|
|
420
|
+
*/
|
|
421
|
+
declare class SanqianSDKError extends Error {
|
|
422
|
+
code: SDKErrorCode;
|
|
423
|
+
messageZh: string;
|
|
424
|
+
hint?: string;
|
|
425
|
+
hintZh?: string;
|
|
426
|
+
constructor(code: SDKErrorCode, details?: string);
|
|
427
|
+
/**
|
|
428
|
+
* Get full error message with hint (English)
|
|
429
|
+
*/
|
|
430
|
+
getFullMessage(): string;
|
|
431
|
+
/**
|
|
432
|
+
* Get full error message with hint (Chinese)
|
|
433
|
+
*/
|
|
434
|
+
getFullMessageZh(): string;
|
|
435
|
+
/**
|
|
436
|
+
* Get bilingual error message
|
|
437
|
+
*/
|
|
438
|
+
getBilingualMessage(): string;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Create a user-friendly SDK error
|
|
442
|
+
*/
|
|
443
|
+
declare function createSDKError(code: SDKErrorCode, details?: string): SanqianSDKError;
|
|
444
|
+
|
|
445
|
+
export { type AgentConfig, type AgentInfo, type AgentUpdateConfig, type ChatMessage, type ChatRequest, type ChatResponse, type ChatStreamEvent, type ConnectionInfo, type ConnectionState, Conversation, type ConversationDetail, type ConversationInfo, type ConversationMessage, ErrorMessages, type JSONSchema, type JSONSchemaProperty, type RemoteToolDefinition, SANQIAN_WEBSITE, type SDKConfig, SDKErrorCode, type SDKEventName, type SDKEvents, SanqianSDK, SanqianSDKError, type ToolCall, type ToolDefinition, createSDKError };
|