@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.
@@ -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 };