@yushaw/sanqian-sdk 0.2.12 → 0.2.14

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.
@@ -137,7 +137,7 @@ interface ChatResponse {
137
137
  };
138
138
  }
139
139
  interface ChatStreamEvent {
140
- type: "text" | "thinking" | "tool_call" | "tool_result" | "done" | "error";
140
+ type: "text" | "thinking" | "tool_call" | "tool_result" | "done" | "error" | "interrupt";
141
141
  /** Text content (for "text" and "thinking" events) */
142
142
  content?: string;
143
143
  /** Tool call info (for "tool_call" event) */
@@ -154,6 +154,58 @@ interface ChatStreamEvent {
154
154
  title?: string;
155
155
  /** Error message (for "error" event or failed "tool_result") */
156
156
  error?: string;
157
+ /** Interrupt type (for "interrupt" event) - HITL */
158
+ interrupt_type?: HitlInterruptType;
159
+ /** Interrupt payload (for "interrupt" event) - HITL */
160
+ interrupt_payload?: HitlInterruptPayload;
161
+ /** Run ID (for "interrupt" event) - needed to send HITL response */
162
+ run_id?: string;
163
+ }
164
+ /** HITL interrupt types */
165
+ type HitlInterruptType = "approval_request" | "user_input_request";
166
+ /** HITL risk levels for approval requests */
167
+ type HitlRiskLevel = "low" | "medium" | "high";
168
+ /** HITL interrupt payload - sent from backend when HITL is triggered */
169
+ interface HitlInterruptPayload {
170
+ /** Interrupt type (redundant but useful) */
171
+ type?: HitlInterruptType;
172
+ /** Tool name requiring approval */
173
+ tool?: string;
174
+ /** Tool arguments */
175
+ args?: Record<string, unknown>;
176
+ /** Reason for approval request */
177
+ reason?: string;
178
+ /** Risk level */
179
+ risk_level?: HitlRiskLevel;
180
+ /** Question to ask the user */
181
+ question?: string;
182
+ /** Additional context */
183
+ context?: string;
184
+ /** Predefined options (for single/multi-select) */
185
+ options?: string[];
186
+ /** Allow multiple selections */
187
+ multi_select?: boolean;
188
+ /** Default value */
189
+ default?: string;
190
+ /** Whether input is required */
191
+ required?: boolean;
192
+ /** Timeout in seconds */
193
+ timeout?: number;
194
+ }
195
+ /** HITL response - sent from client to backend */
196
+ interface HitlResponse {
197
+ /** For approval_request: true = approved, false = rejected */
198
+ approved?: boolean;
199
+ /** Remember this choice for future similar requests */
200
+ remember?: boolean;
201
+ /** For user_input_request: the user's answer */
202
+ answer?: string;
203
+ /** For multi-select: selected option indices */
204
+ selected_indices?: number[];
205
+ /** User cancelled the request */
206
+ cancelled?: boolean;
207
+ /** Request timed out */
208
+ timed_out?: boolean;
157
209
  }
158
210
  /** Agent configuration for create/update */
159
211
  interface AgentConfig {
@@ -343,6 +395,15 @@ declare class SanqianSDK {
343
395
  conversationId?: string;
344
396
  remoteTools?: RemoteToolDefinition[];
345
397
  }): AsyncGenerator<ChatStreamEvent>;
398
+ /**
399
+ * Send HITL (Human-in-the-Loop) response to resume after interrupt
400
+ *
401
+ * Call this after receiving an "interrupt" event in chatStream.
402
+ *
403
+ * @param runId - The run_id from the interrupt event
404
+ * @param response - User's response (approval, input, etc.)
405
+ */
406
+ sendHitlResponse(runId: string, response: HitlResponse): void;
346
407
  startConversation(agentId: string): Conversation;
347
408
  on<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this;
348
409
  off<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this;
@@ -442,4 +503,4 @@ declare class SanqianSDKError extends Error {
442
503
  */
443
504
  declare function createSDKError(code: SDKErrorCode, details?: string): SanqianSDKError;
444
505
 
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 };
506
+ 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 HitlInterruptPayload, type HitlInterruptType, type HitlResponse, type HitlRiskLevel, type JSONSchema, type JSONSchemaProperty, type RemoteToolDefinition, SANQIAN_WEBSITE, type SDKConfig, SDKErrorCode, type SDKEventName, type SDKEvents, SanqianSDK, SanqianSDKError, type ToolCall, type ToolDefinition, createSDKError };
@@ -431,6 +431,14 @@ var SanqianSDK = class _SanqianSDK {
431
431
  case "error":
432
432
  handler.onError(new Error(error || "Unknown stream error"));
433
433
  break;
434
+ case "interrupt":
435
+ handler.onEvent({
436
+ type: "interrupt",
437
+ interrupt_type: message.interrupt_type,
438
+ interrupt_payload: message.interrupt_payload,
439
+ run_id: message.run_id
440
+ });
441
+ break;
434
442
  }
435
443
  }
436
444
  async handleToolCall(message) {
@@ -935,6 +943,26 @@ var SanqianSDK = class _SanqianSDK {
935
943
  this.streamHandlers.delete(msgId);
936
944
  }
937
945
  }
946
+ /**
947
+ * Send HITL (Human-in-the-Loop) response to resume after interrupt
948
+ *
949
+ * Call this after receiving an "interrupt" event in chatStream.
950
+ *
951
+ * @param runId - The run_id from the interrupt event
952
+ * @param response - User's response (approval, input, etc.)
953
+ */
954
+ sendHitlResponse(runId, response) {
955
+ if (!this.state.connected) {
956
+ throw createSDKError("DISCONNECTED" /* DISCONNECTED */, "Not connected to Sanqian");
957
+ }
958
+ const message = {
959
+ type: "hitl_response",
960
+ run_id: runId,
961
+ response
962
+ };
963
+ this.send(message);
964
+ this.log(`Sent HITL response for run ${runId}`);
965
+ }
938
966
  startConversation(agentId) {
939
967
  return new Conversation(this, agentId);
940
968
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/isomorphic-ws/browser.js","../src/errors.ts","../src/client.browser.ts"],"sourcesContent":["// https://github.com/maxogden/websocket-stream/blob/48dc3ddf943e5ada668c31ccd94e9186f02fafbd/ws-fallback.js\n\nvar ws = null\n\nif (typeof WebSocket !== 'undefined') {\n ws = WebSocket\n} else if (typeof MozWebSocket !== 'undefined') {\n ws = MozWebSocket\n} else if (typeof global !== 'undefined') {\n ws = global.WebSocket || global.MozWebSocket\n} else if (typeof window !== 'undefined') {\n ws = window.WebSocket || window.MozWebSocket\n} else if (typeof self !== 'undefined') {\n ws = self.WebSocket || self.MozWebSocket\n}\n\nexport default ws\n","/**\n * SDK Error Messages\n *\n * User-friendly error messages in English and Chinese.\n * All errors guide users to sanqian.io for installation.\n */\n\nexport const SANQIAN_WEBSITE = \"https://sanqian.io\";\n\n/**\n * Error codes for SDK errors\n */\nexport enum SDKErrorCode {\n NOT_INSTALLED = \"NOT_INSTALLED\",\n NOT_RUNNING = \"NOT_RUNNING\",\n CONNECTION_TIMEOUT = \"CONNECTION_TIMEOUT\",\n STARTUP_TIMEOUT = \"STARTUP_TIMEOUT\",\n REGISTRATION_FAILED = \"REGISTRATION_FAILED\",\n REQUEST_TIMEOUT = \"REQUEST_TIMEOUT\",\n REQUEST_FAILED = \"REQUEST_FAILED\",\n DISCONNECTED = \"DISCONNECTED\",\n WEBSOCKET_ERROR = \"WEBSOCKET_ERROR\",\n AGENT_NOT_FOUND = \"AGENT_NOT_FOUND\",\n CONVERSATION_NOT_FOUND = \"CONVERSATION_NOT_FOUND\",\n TOOL_NOT_FOUND = \"TOOL_NOT_FOUND\",\n TOOL_EXECUTION_TIMEOUT = \"TOOL_EXECUTION_TIMEOUT\",\n}\n\n/**\n * Bilingual error messages\n */\nexport const ErrorMessages: Record<\n SDKErrorCode,\n { en: string; zh: string; hint?: { en: string; zh: string } }\n> = {\n [SDKErrorCode.NOT_INSTALLED]: {\n en: `Sanqian is not installed on this computer.`,\n zh: `Sanqian 尚未安装在此电脑上。`,\n hint: {\n en: `Please download and install Sanqian from ${SANQIAN_WEBSITE}`,\n zh: `请访问 ${SANQIAN_WEBSITE} 下载安装 Sanqian`,\n },\n },\n [SDKErrorCode.NOT_RUNNING]: {\n en: `Sanqian is not running.`,\n zh: `Sanqian 未在运行。`,\n hint: {\n en: `Please start Sanqian first, or enable autoLaunchSanqian option in SDK config.`,\n zh: `请先启动 Sanqian,或在 SDK 配置中启用 autoLaunchSanqian 选项。`,\n },\n },\n [SDKErrorCode.CONNECTION_TIMEOUT]: {\n en: `Failed to connect to Sanqian (connection timeout).`,\n zh: `连接 Sanqian 失败(连接超时)。`,\n hint: {\n en: `Please check if Sanqian is running properly. If the problem persists, try restarting Sanqian.`,\n zh: `请检查 Sanqian 是否正常运行。如问题持续,请尝试重启 Sanqian。`,\n },\n },\n [SDKErrorCode.STARTUP_TIMEOUT]: {\n en: `Sanqian failed to start within 2 minutes.`,\n zh: `Sanqian 在 2 分钟内未能启动。`,\n hint: {\n en: `Please try starting Sanqian manually. If it fails to start, reinstall from ${SANQIAN_WEBSITE}`,\n zh: `请尝试手动启动 Sanqian。如仍无法启动,请从 ${SANQIAN_WEBSITE} 重新安装。`,\n },\n },\n [SDKErrorCode.REGISTRATION_FAILED]: {\n en: `Failed to register with Sanqian.`,\n zh: `向 Sanqian 注册失败。`,\n hint: {\n en: `Please check your SDK configuration (appName, tools). If the problem persists, try restarting Sanqian.`,\n zh: `请检查 SDK 配置(appName、tools)。如问题持续,请尝试重启 Sanqian。`,\n },\n },\n [SDKErrorCode.REQUEST_TIMEOUT]: {\n en: `Request timed out.`,\n zh: `请求超时。`,\n hint: {\n en: `The operation took too long. Please try again.`,\n zh: `操作耗时过长,请重试。`,\n },\n },\n [SDKErrorCode.REQUEST_FAILED]: {\n en: `Request failed.`,\n zh: `请求失败。`,\n hint: {\n en: `Please check the error details and try again.`,\n zh: `请检查错误详情后重试。`,\n },\n },\n [SDKErrorCode.DISCONNECTED]: {\n en: `Disconnected from Sanqian.`,\n zh: `与 Sanqian 的连接已断开。`,\n hint: {\n en: `The SDK will automatically reconnect. If problems persist, check if Sanqian is still running.`,\n zh: `SDK 会自动重连。如问题持续,请检查 Sanqian 是否仍在运行。`,\n },\n },\n [SDKErrorCode.WEBSOCKET_ERROR]: {\n en: `WebSocket connection error.`,\n zh: `WebSocket 连接错误。`,\n hint: {\n en: `Please check your network and firewall settings. Sanqian uses local WebSocket on port shown in settings.`,\n zh: `请检查网络和防火墙设置。Sanqian 使用本地 WebSocket,端口可在设置中查看。`,\n },\n },\n [SDKErrorCode.AGENT_NOT_FOUND]: {\n en: `Agent not found.`,\n zh: `找不到该 Agent。`,\n hint: {\n en: `Please check the agent ID. Use listAgents() to see available agents.`,\n zh: `请检查 Agent ID。使用 listAgents() 查看可用的 Agent。`,\n },\n },\n [SDKErrorCode.CONVERSATION_NOT_FOUND]: {\n en: `Conversation not found.`,\n zh: `找不到该对话。`,\n hint: {\n en: `The conversation may have been deleted. Start a new conversation with startConversation().`,\n zh: `该对话可能已被删除。使用 startConversation() 开始新对话。`,\n },\n },\n [SDKErrorCode.TOOL_NOT_FOUND]: {\n en: `Tool not found.`,\n zh: `找不到该工具。`,\n hint: {\n en: `Please check that the tool is registered in your SDK config.`,\n zh: `请检查该工具是否已在 SDK 配置中注册。`,\n },\n },\n [SDKErrorCode.TOOL_EXECUTION_TIMEOUT]: {\n en: `Tool execution timed out.`,\n zh: `工具执行超时。`,\n hint: {\n en: `The tool took too long to execute. Consider increasing toolExecutionTimeout in SDK config.`,\n zh: `工具执行时间过长。可在 SDK 配置中增加 toolExecutionTimeout。`,\n },\n },\n};\n\n/**\n * Custom SDK Error with code and bilingual message\n */\nexport class SanqianSDKError extends Error {\n code: SDKErrorCode;\n messageZh: string;\n hint?: string;\n hintZh?: string;\n\n constructor(code: SDKErrorCode, details?: string) {\n const msg = ErrorMessages[code];\n const fullMessage = details ? `${msg.en} ${details}` : msg.en;\n\n super(fullMessage);\n this.name = \"SanqianSDKError\";\n this.code = code;\n this.messageZh = details ? `${msg.zh} ${details}` : msg.zh;\n this.hint = msg.hint?.en;\n this.hintZh = msg.hint?.zh;\n }\n\n /**\n * Get full error message with hint (English)\n */\n getFullMessage(): string {\n return this.hint ? `${this.message}\\n${this.hint}` : this.message;\n }\n\n /**\n * Get full error message with hint (Chinese)\n */\n getFullMessageZh(): string {\n return this.hintZh ? `${this.messageZh}\\n${this.hintZh}` : this.messageZh;\n }\n\n /**\n * Get bilingual error message\n */\n getBilingualMessage(): string {\n return `${this.getFullMessage()}\\n\\n${this.getFullMessageZh()}`;\n }\n}\n\n/**\n * Create a user-friendly SDK error\n */\nexport function createSDKError(\n code: SDKErrorCode,\n details?: string\n): SanqianSDKError {\n return new SanqianSDKError(code, details);\n}\n","/**\n * Sanqian SDK Client - Browser Build\n *\n * This is a browser-optimized version of the SDK client that does NOT include\n * DiscoveryManager or any Node.js APIs (fs, path, child_process, os).\n *\n * IMPORTANT: When using this build, you MUST provide connectionInfo in config.\n * Auto-discovery and auto-launch features are not available in browser environments.\n *\n * TODO: Consider refactoring to share code with client.ts using composition or\n * inheritance pattern to reduce duplication (~900 lines shared). Currently kept\n * separate for simplicity and to avoid complex build configurations.\n * See: https://github.com/anthropics/claude-code/issues/xxx (if tracked)\n */\n\nimport WebSocket from \"isomorphic-ws\";\nimport type {\n SDKConfig,\n ConnectionInfo,\n ConnectionState,\n ToolDefinition,\n RegisterMessage,\n RegisterAckMessage,\n ToolCallMessage,\n ToolResultMessage,\n HeartbeatMessage,\n SDKEvents,\n SDKEventName,\n AgentConfig,\n AgentInfo,\n AgentUpdateConfig,\n ConversationInfo,\n ConversationDetail,\n CreateAgentMessage,\n CreateAgentAckMessage,\n UpdateAgentMessage,\n UpdateAgentAckMessage,\n ListAgentsMessage,\n ListAgentsAckMessage,\n DeleteAgentMessage,\n DeleteAgentAckMessage,\n ListConversationsMessage,\n ListConversationsAckMessage,\n GetConversationMessage,\n GetConversationAckMessage,\n DeleteConversationMessage,\n DeleteConversationAckMessage,\n ChatMessage,\n ChatResponse,\n ChatRequestMessage,\n ChatResponseMessage,\n ChatStreamMessage,\n ChatStreamEvent,\n RemoteToolDefinition,\n} from \"./types\";\nimport { SanqianSDKError, SDKErrorCode, createSDKError } from \"./errors\";\n\ntype EventListener<T extends SDKEventName> = SDKEvents[T];\n\nexport class SanqianSDK {\n private config: SDKConfig;\n private ws: WebSocket | null = null;\n private connectionInfo: ConnectionInfo | null = null;\n\n private state: ConnectionState = {\n connected: false,\n registering: false,\n registered: false,\n reconnectAttempts: 0,\n };\n\n // Tool handlers by name\n private toolHandlers: Map<string, (args: unknown) => Promise<unknown>> =\n new Map();\n\n // Pending request futures\n private pendingRequests: Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n }\n > = new Map();\n\n // Timers\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private heartbeatAckPending: boolean = false;\n private missedHeartbeats: number = 0;\n private static readonly MAX_MISSED_HEARTBEATS = 2;\n\n // Connection promise for deduplication\n private connectingPromise: Promise<void> | null = null;\n\n // Reconnect reference count\n private reconnectRefCount: number = 0;\n\n // Event listeners\n private eventListeners: Map<SDKEventName, Set<EventListener<SDKEventName>>> =\n new Map();\n\n // ============================================\n // Debug Logging\n // ============================================\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log(\"[SDK]\", ...args);\n }\n }\n\n private warn(...args: unknown[]): void {\n if (this.config.debug) {\n console.warn(\"[SDK]\", ...args);\n }\n }\n\n constructor(config: SDKConfig) {\n // Browser build REQUIRES connectionInfo\n if (!config.connectionInfo) {\n throw new SanqianSDKError(\n SDKErrorCode.NOT_RUNNING,\n \"Browser build requires connectionInfo in config. \" +\n \"Use the Node.js build for auto-discovery, or provide connectionInfo manually.\"\n );\n }\n\n this.config = {\n reconnectInterval: 5000,\n heartbeatInterval: 30000,\n toolExecutionTimeout: 30000,\n debug: false,\n autoLaunchSanqian: false, // Not supported in browser\n ...config,\n };\n\n // Register tool handlers\n for (const tool of config.tools) {\n this.toolHandlers.set(tool.name, tool.handler);\n }\n }\n\n /**\n * Build WebSocket URL from connection info\n */\n private buildWebSocketUrl(info: ConnectionInfo): string {\n const wsPath = info.ws_path || \"/ws/apps\";\n return `ws://127.0.0.1:${info.port}${wsPath}?token=${info.token}`;\n }\n\n // ============================================\n // Lifecycle\n // ============================================\n\n async connect(): Promise<void> {\n return this.ensureReady();\n }\n\n private async connectWithInfo(info: ConnectionInfo): Promise<void> {\n this.connectionInfo = info;\n const url = this.buildWebSocketUrl(info);\n\n return new Promise((resolve, reject) => {\n this.log(`Connecting to ${url}`);\n\n this.ws = new WebSocket(url);\n\n const connectTimeout = setTimeout(() => {\n reject(createSDKError(SDKErrorCode.CONNECTION_TIMEOUT));\n this.ws?.close();\n }, 10000);\n\n this.ws.onopen = async () => {\n clearTimeout(connectTimeout);\n this.log(\"WebSocket connected\");\n this.state.connected = true;\n this.state.reconnectAttempts = 0;\n this.emit(\"connected\");\n\n try {\n await this.register();\n resolve();\n } catch (e) {\n reject(e);\n }\n };\n\n this.ws.onclose = (event: WebSocket.CloseEvent) => {\n const reasonRaw = event.reason as string | Buffer | undefined;\n const reason =\n typeof reasonRaw === \"string\"\n ? reasonRaw\n : reasonRaw?.toString() || \"\";\n this.log(`WebSocket closed: ${event.code} ${reason}`);\n this.handleDisconnect(reason);\n };\n\n this.ws.onerror = (event: WebSocket.ErrorEvent) => {\n const error =\n (event as { error?: Error }).error || new Error(\"WebSocket error\");\n console.error(\"[SDK] WebSocket error:\", error);\n this.state.lastError = error;\n this.emit(\"error\", error);\n };\n\n this.ws.onmessage = (event: WebSocket.MessageEvent) => {\n try {\n const data =\n typeof event.data === \"string\"\n ? event.data\n : event.data.toString();\n const message = JSON.parse(data);\n this.handleMessage(message);\n } catch (e) {\n this.warn(\"Failed to parse message:\", e);\n }\n };\n });\n }\n\n async disconnect(): Promise<void> {\n this.stopHeartbeat();\n this.stopReconnect();\n\n if (this.ws) {\n this.ws.close(1000, \"Client disconnect\");\n this.ws = null;\n }\n\n this.state = {\n connected: false,\n registering: false,\n registered: false,\n reconnectAttempts: 0,\n };\n }\n\n // ============================================\n // Registration\n // ============================================\n\n private async register(): Promise<void> {\n this.state.registering = true;\n\n const msgId = this.generateId();\n\n const message: RegisterMessage = {\n id: msgId,\n type: \"register\",\n app: {\n name: this.config.appName,\n version: this.config.appVersion,\n display_name: this.config.displayName,\n launch_command: this.config.launchCommand,\n },\n tools: this.config.tools.map((t) => ({\n name: `${this.config.appName}:${t.name}`,\n description: t.description,\n parameters: t.parameters,\n searchable: t.searchable ?? true,\n })),\n };\n\n try {\n const response = await this.sendAndWait<RegisterAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success) {\n throw createSDKError(SDKErrorCode.REGISTRATION_FAILED, response.error);\n }\n\n this.state.registering = false;\n this.state.registered = true;\n this.startHeartbeat();\n this.emit(\"registered\");\n\n this.log(`Registered as '${this.config.appName}'`);\n } catch (e) {\n this.state.registering = false;\n throw e;\n }\n }\n\n // ============================================\n // Message Handling\n // ============================================\n\n private handleMessage(message: {\n id?: string;\n type: string;\n [key: string]: unknown;\n }): void {\n const { id, type } = message;\n\n if (id && this.pendingRequests.has(id)) {\n const pending = this.pendingRequests.get(id)!;\n this.pendingRequests.delete(id);\n pending.resolve(message);\n return;\n }\n\n switch (type) {\n case \"tool_call\":\n this.handleToolCall(message as unknown as ToolCallMessage);\n break;\n\n case \"heartbeat_ack\":\n this.heartbeatAckPending = false;\n this.missedHeartbeats = 0;\n break;\n\n case \"chat_stream\":\n this.handleChatStream(message as unknown as ChatStreamMessage);\n break;\n\n default:\n this.warn(`Unknown message type: ${type}`);\n }\n }\n\n private handleChatStream(message: ChatStreamMessage): void {\n const {\n id,\n event,\n content,\n tool_call,\n tool_result,\n conversation_id,\n title,\n usage,\n error,\n } = message;\n\n if (!id) return;\n\n const handler = this.streamHandlers.get(id);\n if (!handler) {\n this.warn(`No stream handler for message ${id}`);\n return;\n }\n\n switch (event) {\n case \"text\":\n handler.onEvent({ type: \"text\", content });\n break;\n\n case \"thinking\":\n // Reasoning content from thinking models (DeepSeek R1, o3, etc.)\n handler.onEvent({ type: \"thinking\", content });\n break;\n\n case \"tool_call\":\n handler.onEvent({ type: \"tool_call\", tool_call });\n break;\n\n case \"tool_result\":\n // Forward tool_result as proper event (not disguised as tool_call)\n if (tool_result) {\n handler.onEvent({\n type: \"tool_result\",\n tool_call_id: tool_result.call_id,\n result: tool_result.result,\n success: tool_result.success,\n error: tool_result.error,\n });\n } else {\n this.log(\"Received tool_result event without tool_result data\");\n }\n break;\n\n case \"done\":\n handler.onDone({\n message: message.message || { role: \"assistant\", content: \"\" },\n conversationId: conversation_id || \"\",\n title,\n usage,\n });\n break;\n\n case \"error\":\n handler.onError(new Error(error || \"Unknown stream error\"));\n break;\n }\n }\n\n private async handleToolCall(message: ToolCallMessage): Promise<void> {\n this.log(`handleToolCall received:`, JSON.stringify(message));\n const { id, call_id, name, arguments: args } = message;\n const msgId = id || call_id;\n\n const toolName = name.includes(\":\") ? name.split(\":\")[1] : name;\n this.log(\n `Looking for handler: '${toolName}', available handlers:`,\n Array.from(this.toolHandlers.keys())\n );\n const handler = this.toolHandlers.get(toolName);\n\n this.emit(\"tool_call\", { name: toolName, arguments: args });\n\n if (!handler) {\n await this.sendToolResult(\n msgId,\n call_id,\n false,\n undefined,\n `Tool '${toolName}' not found`\n );\n return;\n }\n\n try {\n this.log(`Executing tool '${toolName}' with args:`, args);\n const result = await Promise.race([\n handler(args),\n this.createTimeout(this.config.toolExecutionTimeout!),\n ]);\n\n this.log(`Tool '${toolName}' completed successfully`);\n await this.sendToolResult(msgId, call_id, true, result);\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n const errorStack = e instanceof Error ? e.stack : undefined;\n this.log(`Tool '${toolName}' failed:`, errorMessage);\n if (errorStack) {\n this.log(`Tool error stack:`, errorStack);\n }\n await this.sendToolResult(msgId, call_id, false, undefined, errorMessage);\n }\n }\n\n private async sendToolResult(\n id: string,\n callId: string,\n success: boolean,\n result?: unknown,\n error?: string\n ): Promise<void> {\n const message: ToolResultMessage = {\n id,\n type: \"tool_result\",\n call_id: callId,\n success,\n result,\n error,\n };\n\n this.log(\n `Sending tool_result for ${callId}:`,\n success ? \"success\" : `error: ${error}`\n );\n this.send(message);\n }\n\n // ============================================\n // Connection Management\n // ============================================\n\n private handleDisconnect(reason: string): void {\n this.stopHeartbeat();\n this.state.connected = false;\n this.state.registered = false;\n this.emit(\"disconnected\", reason);\n\n for (const [, pending] of this.pendingRequests) {\n pending.reject(createSDKError(SDKErrorCode.DISCONNECTED));\n }\n this.pendingRequests.clear();\n\n if (reason === \"Client disconnect\") {\n this.log(\"Client disconnected intentionally, skipping auto-reconnect\");\n return;\n }\n\n if (reason === \"Replaced by new connection\") {\n this.log(\"Connection replaced by newer one, skipping auto-reconnect\");\n return;\n }\n\n if (this.connectingPromise) {\n this.log(\n \"Connection attempt already in progress, skipping auto-reconnect\"\n );\n return;\n }\n\n if (!this.shouldAutoReconnect()) {\n this.log(\n \"No components require reconnection (refCount=0), skipping auto-reconnect\"\n );\n return;\n }\n\n this.scheduleReconnect();\n }\n\n private shouldAutoReconnect(): boolean {\n return this.reconnectRefCount > 0;\n }\n\n acquireReconnect(): void {\n this.reconnectRefCount++;\n this.log(`acquireReconnect: refCount=${this.reconnectRefCount}`);\n }\n\n releaseReconnect(): void {\n this.reconnectRefCount = Math.max(0, this.reconnectRefCount - 1);\n this.log(`releaseReconnect: refCount=${this.reconnectRefCount}`);\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return;\n\n const baseDelay = Math.min(\n 500 * Math.pow(2, this.state.reconnectAttempts),\n 5000\n );\n const jitter = Math.random() * 500;\n const delay = baseDelay + jitter;\n\n this.log(\n `Scheduling reconnect in ${Math.round(delay)}ms (attempt ${this.state.reconnectAttempts + 1})`\n );\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = null;\n this.state.reconnectAttempts++;\n\n try {\n await this.ensureReady();\n } catch (e) {\n console.error(\"[SDK] Reconnect failed:\", e);\n if (!this.isConnected()) {\n this.scheduleReconnect();\n }\n }\n }, delay);\n }\n\n private stopReconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n\n // ============================================\n // Heartbeat\n // ============================================\n\n private startHeartbeat(): void {\n this.stopHeartbeat();\n this.missedHeartbeats = 0;\n this.heartbeatAckPending = false;\n\n this.heartbeatTimer = setInterval(() => {\n if (this.heartbeatAckPending) {\n this.missedHeartbeats++;\n this.warn(\n `Missed heartbeat ack (${this.missedHeartbeats}/${SanqianSDK.MAX_MISSED_HEARTBEATS})`\n );\n\n if (this.missedHeartbeats >= SanqianSDK.MAX_MISSED_HEARTBEATS) {\n this.warn(\"Too many missed heartbeat acks, connection may be dead\");\n this.ws?.close(4000, \"Heartbeat timeout\");\n return;\n }\n }\n\n const message: HeartbeatMessage = {\n type: \"heartbeat\",\n timestamp: new Date().toISOString(),\n };\n this.heartbeatAckPending = true;\n try {\n this.send(message);\n } catch (e) {\n console.error(\"[SDK] Heartbeat send failed:\", e);\n this.ws?.close(4000, \"Heartbeat send failed\");\n }\n }, this.config.heartbeatInterval);\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n // ============================================\n // Communication\n // ============================================\n\n private send(message: object): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n const error = new Error(\n `WebSocket not open (state: ${this.ws?.readyState ?? \"null\"}), cannot send message`\n );\n console.error(`[SDK] ${error.message}:`, message);\n throw error;\n }\n\n const data = JSON.stringify(message);\n this.log(`WebSocket send:`, data.substring(0, 200));\n this.ws.send(data);\n }\n\n private sendAndWait<T>(\n message: object,\n id: string,\n timeout: number\n ): Promise<T> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(createSDKError(SDKErrorCode.REQUEST_TIMEOUT));\n }, timeout);\n\n this.pendingRequests.set(id, {\n resolve: (value) => {\n clearTimeout(timer);\n resolve(value as T);\n },\n reject: (error) => {\n clearTimeout(timer);\n reject(error);\n },\n });\n\n try {\n this.send(message);\n } catch (e) {\n clearTimeout(timer);\n this.pendingRequests.delete(id);\n reject(e);\n }\n });\n }\n\n // ============================================\n // Public API\n // ============================================\n\n getState(): ConnectionState {\n return { ...this.state };\n }\n\n isConnected(): boolean {\n return this.state.connected && this.state.registered;\n }\n\n async ensureReady(): Promise<void> {\n if (this.isConnected()) {\n return;\n }\n\n if (this.connectingPromise) {\n this.log(\"Connection already in progress, waiting...\");\n return this.connectingPromise;\n }\n\n this.connectingPromise = this.doFullConnect();\n\n try {\n await this.connectingPromise;\n } finally {\n this.connectingPromise = null;\n }\n }\n\n private async doFullConnect(): Promise<void> {\n this.log(\"Starting connection (browser mode)...\");\n\n // Browser mode: always use pre-configured connectionInfo\n const info = this.config.connectionInfo!;\n await this.connectWithInfo(info);\n }\n\n async updateTools(tools: ToolDefinition[]): Promise<void> {\n this.toolHandlers.clear();\n for (const tool of tools) {\n this.toolHandlers.set(tool.name, tool.handler);\n }\n\n if (this.isConnected()) {\n const msgId = this.generateId();\n const message = {\n id: msgId,\n type: \"tools_update\",\n tools: tools.map((t) => ({\n name: `${this.config.appName}:${t.name}`,\n description: t.description,\n parameters: t.parameters,\n searchable: t.searchable ?? true,\n })),\n };\n\n await this.sendAndWait(message, msgId, 5000);\n }\n }\n\n // ============================================\n // Private Agent API\n // ============================================\n\n async createAgent(config: AgentConfig): Promise<AgentInfo> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: CreateAgentMessage = {\n id: msgId,\n type: \"create_agent\",\n agent: config,\n };\n\n const response = await this.sendAndWait<CreateAgentAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success) {\n throw createSDKError(SDKErrorCode.AGENT_NOT_FOUND, response.error);\n }\n\n if (response.agent) {\n return response.agent;\n }\n\n return {\n agent_id: response.agent_id!,\n name: config.name,\n description: config.description,\n tools: config.tools || [],\n };\n }\n\n async listAgents(): Promise<AgentInfo[]> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: ListAgentsMessage = {\n id: msgId,\n type: \"list_agents\",\n };\n\n const response = await this.sendAndWait<ListAgentsAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (response.error) {\n throw new Error(response.error);\n }\n\n return response.agents;\n }\n\n async deleteAgent(agentId: string): Promise<void> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: DeleteAgentMessage = {\n id: msgId,\n type: \"delete_agent\",\n agent_id: agentId,\n };\n\n const response = await this.sendAndWait<DeleteAgentAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success) {\n throw createSDKError(SDKErrorCode.AGENT_NOT_FOUND, response.error);\n }\n }\n\n async updateAgent(\n agentId: string,\n updates: Omit<AgentUpdateConfig, \"agent_id\">\n ): Promise<AgentInfo> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: UpdateAgentMessage = {\n id: msgId,\n type: \"update_agent\",\n agent_id: agentId,\n updates,\n };\n\n const response = await this.sendAndWait<UpdateAgentAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success || !response.agent) {\n throw createSDKError(SDKErrorCode.AGENT_NOT_FOUND, response.error);\n }\n\n return response.agent;\n }\n\n // ============================================\n // Conversation API\n // ============================================\n\n async listConversations(options?: {\n agentId?: string;\n limit?: number;\n offset?: number;\n }): Promise<{ conversations: ConversationInfo[]; total: number }> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: ListConversationsMessage = {\n id: msgId,\n type: \"list_conversations\",\n agent_id: options?.agentId,\n limit: options?.limit,\n offset: options?.offset,\n };\n\n const response = await this.sendAndWait<ListConversationsAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (response.error) {\n throw new Error(response.error);\n }\n\n return {\n conversations: response.conversations,\n total: response.total,\n };\n }\n\n async getConversation(\n conversationId: string,\n options?: {\n includeMessages?: boolean;\n messageLimit?: number;\n messageOffset?: number;\n }\n ): Promise<ConversationDetail> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: GetConversationMessage = {\n id: msgId,\n type: \"get_conversation\",\n conversation_id: conversationId,\n include_messages: options?.includeMessages ?? true,\n message_limit: options?.messageLimit,\n message_offset: options?.messageOffset,\n };\n\n const response = await this.sendAndWait<GetConversationAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success || !response.conversation) {\n throw createSDKError(SDKErrorCode.CONVERSATION_NOT_FOUND, response.error);\n }\n\n return response.conversation;\n }\n\n async deleteConversation(conversationId: string): Promise<void> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: DeleteConversationMessage = {\n id: msgId,\n type: \"delete_conversation\",\n conversation_id: conversationId,\n };\n\n const response = await this.sendAndWait<DeleteConversationAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success) {\n throw createSDKError(SDKErrorCode.CONVERSATION_NOT_FOUND, response.error);\n }\n }\n\n // ============================================\n // Chat API\n // ============================================\n\n private streamHandlers: Map<\n string,\n {\n onEvent: (event: ChatStreamEvent) => void;\n onDone: (response: ChatResponse) => void;\n onError: (error: Error) => void;\n }\n > = new Map();\n\n async chat(\n agentId: string,\n messages: ChatMessage[],\n options?: {\n conversationId?: string;\n remoteTools?: RemoteToolDefinition[];\n }\n ): Promise<ChatResponse> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: ChatRequestMessage = {\n id: msgId,\n type: \"chat\",\n agent_id: agentId,\n messages,\n conversation_id: options?.conversationId,\n stream: false,\n remote_tools: options?.remoteTools?.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n };\n\n const response = await this.sendAndWait<ChatResponseMessage>(\n message,\n msgId,\n 600000\n );\n\n if (!response.success) {\n const errorLower = (response.error || \"\").toLowerCase();\n if (errorLower.includes(\"agent\") && errorLower.includes(\"not found\")) {\n throw createSDKError(SDKErrorCode.AGENT_NOT_FOUND, response.error);\n }\n throw createSDKError(SDKErrorCode.REQUEST_FAILED, response.error);\n }\n\n return {\n message: response.message!,\n conversationId: response.conversation_id!,\n title: response.title,\n usage: response.usage,\n };\n }\n\n async *chatStream(\n agentId: string,\n messages: ChatMessage[],\n options?: {\n conversationId?: string;\n remoteTools?: RemoteToolDefinition[];\n }\n ): AsyncGenerator<ChatStreamEvent> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: ChatRequestMessage = {\n id: msgId,\n type: \"chat\",\n agent_id: agentId,\n messages,\n conversation_id: options?.conversationId,\n stream: true,\n remote_tools: options?.remoteTools?.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n };\n\n const eventQueue: ChatStreamEvent[] = [];\n let done = false;\n let error: Error | null = null;\n let resolveNext: (() => void) | null = null;\n\n this.streamHandlers.set(msgId, {\n onEvent: (event) => {\n eventQueue.push(event);\n resolveNext?.();\n },\n onDone: (response) => {\n eventQueue.push({\n type: \"done\",\n conversationId: response.conversationId,\n title: response.title,\n });\n done = true;\n resolveNext?.();\n },\n onError: (e) => {\n error = e;\n resolveNext?.();\n },\n });\n\n try {\n this.send(message);\n\n while (!done && !error) {\n if (eventQueue.length > 0) {\n yield eventQueue.shift()!;\n } else {\n await new Promise<void>((resolve) => {\n resolveNext = resolve;\n });\n resolveNext = null;\n }\n }\n\n while (eventQueue.length > 0) {\n yield eventQueue.shift()!;\n }\n\n if (error) {\n throw error;\n }\n } finally {\n this.streamHandlers.delete(msgId);\n }\n }\n\n startConversation(agentId: string): Conversation {\n return new Conversation(this, agentId);\n }\n\n // ============================================\n // Events\n // ============================================\n\n on<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(listener as EventListener<SDKEventName>);\n return this;\n }\n\n off<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this {\n this.eventListeners\n .get(event)\n ?.delete(listener as EventListener<SDKEventName>);\n return this;\n }\n\n once<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this {\n const onceWrapper = ((...args: Parameters<SDKEvents[T]>) => {\n this.off(event, onceWrapper as SDKEvents[T]);\n (listener as (...args: unknown[]) => void)(...args);\n }) as SDKEvents[T];\n return this.on(event, onceWrapper);\n }\n\n /**\n * Remove all event listeners\n *\n * Call this to prevent memory leaks when disposing the SDK instance.\n * If event is specified, only removes listeners for that event.\n */\n removeAllListeners(event?: SDKEventName): this {\n if (event) {\n this.eventListeners.delete(event);\n } else {\n this.eventListeners.clear();\n }\n return this;\n }\n\n private emit<T extends SDKEventName>(\n event: T,\n ...args: Parameters<SDKEvents[T]>\n ): void {\n const listeners = this.eventListeners.get(event);\n if (listeners) {\n for (const listener of listeners) {\n try {\n (listener as (...args: unknown[]) => void)(...args);\n } catch (e) {\n console.error(`[SDK] Event listener error for '${event}':`, e);\n }\n }\n }\n }\n\n // ============================================\n // Utilities\n // ============================================\n\n private generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n }\n\n private createTimeout(ms: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(\n () => reject(createSDKError(SDKErrorCode.TOOL_EXECUTION_TIMEOUT)),\n ms\n );\n });\n }\n}\n\n/**\n * Conversation helper for multi-turn chat\n */\nexport class Conversation {\n private sdk: SanqianSDK;\n private agentId: string;\n private _conversationId: string | null = null;\n\n constructor(sdk: SanqianSDK, agentId: string, conversationId?: string) {\n this.sdk = sdk;\n this.agentId = agentId;\n this._conversationId = conversationId || null;\n }\n\n get id(): string | null {\n return this._conversationId;\n }\n\n async send(\n content: string,\n options?: { remoteTools?: RemoteToolDefinition[] }\n ): Promise<ChatResponse> {\n const response = await this.sdk.chat(\n this.agentId,\n [{ role: \"user\", content }],\n {\n conversationId: this._conversationId || undefined,\n remoteTools: options?.remoteTools,\n }\n );\n\n if (response.conversationId && !this._conversationId) {\n this._conversationId = response.conversationId;\n }\n\n return response;\n }\n\n async *sendStream(\n content: string,\n options?: { remoteTools?: RemoteToolDefinition[] }\n ): AsyncGenerator<ChatStreamEvent> {\n const stream = this.sdk.chatStream(\n this.agentId,\n [{ role: \"user\", content }],\n {\n conversationId: this._conversationId || undefined,\n remoteTools: options?.remoteTools,\n }\n );\n\n for await (const event of stream) {\n if (\n event.type === \"done\" &&\n event.conversationId &&\n !this._conversationId\n ) {\n this._conversationId = event.conversationId;\n }\n yield event;\n }\n }\n\n async delete(): Promise<void> {\n if (!this._conversationId) {\n throw new Error(\"No conversation to delete\");\n }\n await this.sdk.deleteConversation(this._conversationId);\n this._conversationId = null;\n }\n\n async getDetails(options?: {\n messageLimit?: number;\n }): Promise<ConversationDetail> {\n if (!this._conversationId) {\n throw new Error(\"No conversation to get details for\");\n }\n return this.sdk.getConversation(this._conversationId, {\n includeMessages: true,\n messageLimit: options?.messageLimit,\n });\n }\n}\n"],"mappings":"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","names":["SDKErrorCode"]}
1
+ {"version":3,"sources":["../node_modules/isomorphic-ws/browser.js","../src/errors.ts","../src/client.browser.ts"],"sourcesContent":["// https://github.com/maxogden/websocket-stream/blob/48dc3ddf943e5ada668c31ccd94e9186f02fafbd/ws-fallback.js\n\nvar ws = null\n\nif (typeof WebSocket !== 'undefined') {\n ws = WebSocket\n} else if (typeof MozWebSocket !== 'undefined') {\n ws = MozWebSocket\n} else if (typeof global !== 'undefined') {\n ws = global.WebSocket || global.MozWebSocket\n} else if (typeof window !== 'undefined') {\n ws = window.WebSocket || window.MozWebSocket\n} else if (typeof self !== 'undefined') {\n ws = self.WebSocket || self.MozWebSocket\n}\n\nexport default ws\n","/**\n * SDK Error Messages\n *\n * User-friendly error messages in English and Chinese.\n * All errors guide users to sanqian.io for installation.\n */\n\nexport const SANQIAN_WEBSITE = \"https://sanqian.io\";\n\n/**\n * Error codes for SDK errors\n */\nexport enum SDKErrorCode {\n NOT_INSTALLED = \"NOT_INSTALLED\",\n NOT_RUNNING = \"NOT_RUNNING\",\n CONNECTION_TIMEOUT = \"CONNECTION_TIMEOUT\",\n STARTUP_TIMEOUT = \"STARTUP_TIMEOUT\",\n REGISTRATION_FAILED = \"REGISTRATION_FAILED\",\n REQUEST_TIMEOUT = \"REQUEST_TIMEOUT\",\n REQUEST_FAILED = \"REQUEST_FAILED\",\n DISCONNECTED = \"DISCONNECTED\",\n WEBSOCKET_ERROR = \"WEBSOCKET_ERROR\",\n AGENT_NOT_FOUND = \"AGENT_NOT_FOUND\",\n CONVERSATION_NOT_FOUND = \"CONVERSATION_NOT_FOUND\",\n TOOL_NOT_FOUND = \"TOOL_NOT_FOUND\",\n TOOL_EXECUTION_TIMEOUT = \"TOOL_EXECUTION_TIMEOUT\",\n}\n\n/**\n * Bilingual error messages\n */\nexport const ErrorMessages: Record<\n SDKErrorCode,\n { en: string; zh: string; hint?: { en: string; zh: string } }\n> = {\n [SDKErrorCode.NOT_INSTALLED]: {\n en: `Sanqian is not installed on this computer.`,\n zh: `Sanqian 尚未安装在此电脑上。`,\n hint: {\n en: `Please download and install Sanqian from ${SANQIAN_WEBSITE}`,\n zh: `请访问 ${SANQIAN_WEBSITE} 下载安装 Sanqian`,\n },\n },\n [SDKErrorCode.NOT_RUNNING]: {\n en: `Sanqian is not running.`,\n zh: `Sanqian 未在运行。`,\n hint: {\n en: `Please start Sanqian first, or enable autoLaunchSanqian option in SDK config.`,\n zh: `请先启动 Sanqian,或在 SDK 配置中启用 autoLaunchSanqian 选项。`,\n },\n },\n [SDKErrorCode.CONNECTION_TIMEOUT]: {\n en: `Failed to connect to Sanqian (connection timeout).`,\n zh: `连接 Sanqian 失败(连接超时)。`,\n hint: {\n en: `Please check if Sanqian is running properly. If the problem persists, try restarting Sanqian.`,\n zh: `请检查 Sanqian 是否正常运行。如问题持续,请尝试重启 Sanqian。`,\n },\n },\n [SDKErrorCode.STARTUP_TIMEOUT]: {\n en: `Sanqian failed to start within 2 minutes.`,\n zh: `Sanqian 在 2 分钟内未能启动。`,\n hint: {\n en: `Please try starting Sanqian manually. If it fails to start, reinstall from ${SANQIAN_WEBSITE}`,\n zh: `请尝试手动启动 Sanqian。如仍无法启动,请从 ${SANQIAN_WEBSITE} 重新安装。`,\n },\n },\n [SDKErrorCode.REGISTRATION_FAILED]: {\n en: `Failed to register with Sanqian.`,\n zh: `向 Sanqian 注册失败。`,\n hint: {\n en: `Please check your SDK configuration (appName, tools). If the problem persists, try restarting Sanqian.`,\n zh: `请检查 SDK 配置(appName、tools)。如问题持续,请尝试重启 Sanqian。`,\n },\n },\n [SDKErrorCode.REQUEST_TIMEOUT]: {\n en: `Request timed out.`,\n zh: `请求超时。`,\n hint: {\n en: `The operation took too long. Please try again.`,\n zh: `操作耗时过长,请重试。`,\n },\n },\n [SDKErrorCode.REQUEST_FAILED]: {\n en: `Request failed.`,\n zh: `请求失败。`,\n hint: {\n en: `Please check the error details and try again.`,\n zh: `请检查错误详情后重试。`,\n },\n },\n [SDKErrorCode.DISCONNECTED]: {\n en: `Disconnected from Sanqian.`,\n zh: `与 Sanqian 的连接已断开。`,\n hint: {\n en: `The SDK will automatically reconnect. If problems persist, check if Sanqian is still running.`,\n zh: `SDK 会自动重连。如问题持续,请检查 Sanqian 是否仍在运行。`,\n },\n },\n [SDKErrorCode.WEBSOCKET_ERROR]: {\n en: `WebSocket connection error.`,\n zh: `WebSocket 连接错误。`,\n hint: {\n en: `Please check your network and firewall settings. Sanqian uses local WebSocket on port shown in settings.`,\n zh: `请检查网络和防火墙设置。Sanqian 使用本地 WebSocket,端口可在设置中查看。`,\n },\n },\n [SDKErrorCode.AGENT_NOT_FOUND]: {\n en: `Agent not found.`,\n zh: `找不到该 Agent。`,\n hint: {\n en: `Please check the agent ID. Use listAgents() to see available agents.`,\n zh: `请检查 Agent ID。使用 listAgents() 查看可用的 Agent。`,\n },\n },\n [SDKErrorCode.CONVERSATION_NOT_FOUND]: {\n en: `Conversation not found.`,\n zh: `找不到该对话。`,\n hint: {\n en: `The conversation may have been deleted. Start a new conversation with startConversation().`,\n zh: `该对话可能已被删除。使用 startConversation() 开始新对话。`,\n },\n },\n [SDKErrorCode.TOOL_NOT_FOUND]: {\n en: `Tool not found.`,\n zh: `找不到该工具。`,\n hint: {\n en: `Please check that the tool is registered in your SDK config.`,\n zh: `请检查该工具是否已在 SDK 配置中注册。`,\n },\n },\n [SDKErrorCode.TOOL_EXECUTION_TIMEOUT]: {\n en: `Tool execution timed out.`,\n zh: `工具执行超时。`,\n hint: {\n en: `The tool took too long to execute. Consider increasing toolExecutionTimeout in SDK config.`,\n zh: `工具执行时间过长。可在 SDK 配置中增加 toolExecutionTimeout。`,\n },\n },\n};\n\n/**\n * Custom SDK Error with code and bilingual message\n */\nexport class SanqianSDKError extends Error {\n code: SDKErrorCode;\n messageZh: string;\n hint?: string;\n hintZh?: string;\n\n constructor(code: SDKErrorCode, details?: string) {\n const msg = ErrorMessages[code];\n const fullMessage = details ? `${msg.en} ${details}` : msg.en;\n\n super(fullMessage);\n this.name = \"SanqianSDKError\";\n this.code = code;\n this.messageZh = details ? `${msg.zh} ${details}` : msg.zh;\n this.hint = msg.hint?.en;\n this.hintZh = msg.hint?.zh;\n }\n\n /**\n * Get full error message with hint (English)\n */\n getFullMessage(): string {\n return this.hint ? `${this.message}\\n${this.hint}` : this.message;\n }\n\n /**\n * Get full error message with hint (Chinese)\n */\n getFullMessageZh(): string {\n return this.hintZh ? `${this.messageZh}\\n${this.hintZh}` : this.messageZh;\n }\n\n /**\n * Get bilingual error message\n */\n getBilingualMessage(): string {\n return `${this.getFullMessage()}\\n\\n${this.getFullMessageZh()}`;\n }\n}\n\n/**\n * Create a user-friendly SDK error\n */\nexport function createSDKError(\n code: SDKErrorCode,\n details?: string\n): SanqianSDKError {\n return new SanqianSDKError(code, details);\n}\n","/**\n * Sanqian SDK Client - Browser Build\n *\n * This is a browser-optimized version of the SDK client that does NOT include\n * DiscoveryManager or any Node.js APIs (fs, path, child_process, os).\n *\n * IMPORTANT: When using this build, you MUST provide connectionInfo in config.\n * Auto-discovery and auto-launch features are not available in browser environments.\n *\n * TODO: Consider refactoring to share code with client.ts using composition or\n * inheritance pattern to reduce duplication (~900 lines shared). Currently kept\n * separate for simplicity and to avoid complex build configurations.\n * See: https://github.com/anthropics/claude-code/issues/xxx (if tracked)\n */\n\nimport WebSocket from \"isomorphic-ws\";\nimport type {\n SDKConfig,\n ConnectionInfo,\n ConnectionState,\n ToolDefinition,\n RegisterMessage,\n RegisterAckMessage,\n ToolCallMessage,\n ToolResultMessage,\n HeartbeatMessage,\n SDKEvents,\n SDKEventName,\n AgentConfig,\n AgentInfo,\n AgentUpdateConfig,\n ConversationInfo,\n ConversationDetail,\n CreateAgentMessage,\n CreateAgentAckMessage,\n UpdateAgentMessage,\n UpdateAgentAckMessage,\n ListAgentsMessage,\n ListAgentsAckMessage,\n DeleteAgentMessage,\n DeleteAgentAckMessage,\n ListConversationsMessage,\n ListConversationsAckMessage,\n GetConversationMessage,\n GetConversationAckMessage,\n DeleteConversationMessage,\n DeleteConversationAckMessage,\n ChatMessage,\n ChatResponse,\n ChatRequestMessage,\n ChatResponseMessage,\n ChatStreamMessage,\n ChatStreamEvent,\n RemoteToolDefinition,\n HitlResponse,\n HitlResponseMessage,\n} from \"./types\";\nimport { SanqianSDKError, SDKErrorCode, createSDKError } from \"./errors\";\n\ntype EventListener<T extends SDKEventName> = SDKEvents[T];\n\nexport class SanqianSDK {\n private config: SDKConfig;\n private ws: WebSocket | null = null;\n private connectionInfo: ConnectionInfo | null = null;\n\n private state: ConnectionState = {\n connected: false,\n registering: false,\n registered: false,\n reconnectAttempts: 0,\n };\n\n // Tool handlers by name\n private toolHandlers: Map<string, (args: unknown) => Promise<unknown>> =\n new Map();\n\n // Pending request futures\n private pendingRequests: Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n }\n > = new Map();\n\n // Timers\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private heartbeatAckPending: boolean = false;\n private missedHeartbeats: number = 0;\n private static readonly MAX_MISSED_HEARTBEATS = 2;\n\n // Connection promise for deduplication\n private connectingPromise: Promise<void> | null = null;\n\n // Reconnect reference count\n private reconnectRefCount: number = 0;\n\n // Event listeners\n private eventListeners: Map<SDKEventName, Set<EventListener<SDKEventName>>> =\n new Map();\n\n // ============================================\n // Debug Logging\n // ============================================\n\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log(\"[SDK]\", ...args);\n }\n }\n\n private warn(...args: unknown[]): void {\n if (this.config.debug) {\n console.warn(\"[SDK]\", ...args);\n }\n }\n\n constructor(config: SDKConfig) {\n // Browser build REQUIRES connectionInfo\n if (!config.connectionInfo) {\n throw new SanqianSDKError(\n SDKErrorCode.NOT_RUNNING,\n \"Browser build requires connectionInfo in config. \" +\n \"Use the Node.js build for auto-discovery, or provide connectionInfo manually.\"\n );\n }\n\n this.config = {\n reconnectInterval: 5000,\n heartbeatInterval: 30000,\n toolExecutionTimeout: 30000,\n debug: false,\n autoLaunchSanqian: false, // Not supported in browser\n ...config,\n };\n\n // Register tool handlers\n for (const tool of config.tools) {\n this.toolHandlers.set(tool.name, tool.handler);\n }\n }\n\n /**\n * Build WebSocket URL from connection info\n */\n private buildWebSocketUrl(info: ConnectionInfo): string {\n const wsPath = info.ws_path || \"/ws/apps\";\n return `ws://127.0.0.1:${info.port}${wsPath}?token=${info.token}`;\n }\n\n // ============================================\n // Lifecycle\n // ============================================\n\n async connect(): Promise<void> {\n return this.ensureReady();\n }\n\n private async connectWithInfo(info: ConnectionInfo): Promise<void> {\n this.connectionInfo = info;\n const url = this.buildWebSocketUrl(info);\n\n return new Promise((resolve, reject) => {\n this.log(`Connecting to ${url}`);\n\n this.ws = new WebSocket(url);\n\n const connectTimeout = setTimeout(() => {\n reject(createSDKError(SDKErrorCode.CONNECTION_TIMEOUT));\n this.ws?.close();\n }, 10000);\n\n this.ws.onopen = async () => {\n clearTimeout(connectTimeout);\n this.log(\"WebSocket connected\");\n this.state.connected = true;\n this.state.reconnectAttempts = 0;\n this.emit(\"connected\");\n\n try {\n await this.register();\n resolve();\n } catch (e) {\n reject(e);\n }\n };\n\n this.ws.onclose = (event: WebSocket.CloseEvent) => {\n const reasonRaw = event.reason as string | Buffer | undefined;\n const reason =\n typeof reasonRaw === \"string\"\n ? reasonRaw\n : reasonRaw?.toString() || \"\";\n this.log(`WebSocket closed: ${event.code} ${reason}`);\n this.handleDisconnect(reason);\n };\n\n this.ws.onerror = (event: WebSocket.ErrorEvent) => {\n const error =\n (event as { error?: Error }).error || new Error(\"WebSocket error\");\n console.error(\"[SDK] WebSocket error:\", error);\n this.state.lastError = error;\n this.emit(\"error\", error);\n };\n\n this.ws.onmessage = (event: WebSocket.MessageEvent) => {\n try {\n const data =\n typeof event.data === \"string\"\n ? event.data\n : event.data.toString();\n const message = JSON.parse(data);\n this.handleMessage(message);\n } catch (e) {\n this.warn(\"Failed to parse message:\", e);\n }\n };\n });\n }\n\n async disconnect(): Promise<void> {\n this.stopHeartbeat();\n this.stopReconnect();\n\n if (this.ws) {\n this.ws.close(1000, \"Client disconnect\");\n this.ws = null;\n }\n\n this.state = {\n connected: false,\n registering: false,\n registered: false,\n reconnectAttempts: 0,\n };\n }\n\n // ============================================\n // Registration\n // ============================================\n\n private async register(): Promise<void> {\n this.state.registering = true;\n\n const msgId = this.generateId();\n\n const message: RegisterMessage = {\n id: msgId,\n type: \"register\",\n app: {\n name: this.config.appName,\n version: this.config.appVersion,\n display_name: this.config.displayName,\n launch_command: this.config.launchCommand,\n },\n tools: this.config.tools.map((t) => ({\n name: `${this.config.appName}:${t.name}`,\n description: t.description,\n parameters: t.parameters,\n searchable: t.searchable ?? true,\n })),\n };\n\n try {\n const response = await this.sendAndWait<RegisterAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success) {\n throw createSDKError(SDKErrorCode.REGISTRATION_FAILED, response.error);\n }\n\n this.state.registering = false;\n this.state.registered = true;\n this.startHeartbeat();\n this.emit(\"registered\");\n\n this.log(`Registered as '${this.config.appName}'`);\n } catch (e) {\n this.state.registering = false;\n throw e;\n }\n }\n\n // ============================================\n // Message Handling\n // ============================================\n\n private handleMessage(message: {\n id?: string;\n type: string;\n [key: string]: unknown;\n }): void {\n const { id, type } = message;\n\n if (id && this.pendingRequests.has(id)) {\n const pending = this.pendingRequests.get(id)!;\n this.pendingRequests.delete(id);\n pending.resolve(message);\n return;\n }\n\n switch (type) {\n case \"tool_call\":\n this.handleToolCall(message as unknown as ToolCallMessage);\n break;\n\n case \"heartbeat_ack\":\n this.heartbeatAckPending = false;\n this.missedHeartbeats = 0;\n break;\n\n case \"chat_stream\":\n this.handleChatStream(message as unknown as ChatStreamMessage);\n break;\n\n default:\n this.warn(`Unknown message type: ${type}`);\n }\n }\n\n private handleChatStream(message: ChatStreamMessage): void {\n const {\n id,\n event,\n content,\n tool_call,\n tool_result,\n conversation_id,\n title,\n usage,\n error,\n } = message;\n\n if (!id) return;\n\n const handler = this.streamHandlers.get(id);\n if (!handler) {\n this.warn(`No stream handler for message ${id}`);\n return;\n }\n\n switch (event) {\n case \"text\":\n handler.onEvent({ type: \"text\", content });\n break;\n\n case \"thinking\":\n // Reasoning content from thinking models (DeepSeek R1, o3, etc.)\n handler.onEvent({ type: \"thinking\", content });\n break;\n\n case \"tool_call\":\n handler.onEvent({ type: \"tool_call\", tool_call });\n break;\n\n case \"tool_result\":\n // Forward tool_result as proper event (not disguised as tool_call)\n if (tool_result) {\n handler.onEvent({\n type: \"tool_result\",\n tool_call_id: tool_result.call_id,\n result: tool_result.result,\n success: tool_result.success,\n error: tool_result.error,\n });\n } else {\n this.log(\"Received tool_result event without tool_result data\");\n }\n break;\n\n case \"done\":\n handler.onDone({\n message: message.message || { role: \"assistant\", content: \"\" },\n conversationId: conversation_id || \"\",\n title,\n usage,\n });\n break;\n\n case \"error\":\n handler.onError(new Error(error || \"Unknown stream error\"));\n break;\n\n case \"interrupt\":\n // HITL interrupt - user input required to continue\n handler.onEvent({\n type: \"interrupt\",\n interrupt_type: message.interrupt_type,\n interrupt_payload: message.interrupt_payload,\n run_id: message.run_id,\n });\n break;\n }\n }\n\n private async handleToolCall(message: ToolCallMessage): Promise<void> {\n this.log(`handleToolCall received:`, JSON.stringify(message));\n const { id, call_id, name, arguments: args } = message;\n const msgId = id || call_id;\n\n const toolName = name.includes(\":\") ? name.split(\":\")[1] : name;\n this.log(\n `Looking for handler: '${toolName}', available handlers:`,\n Array.from(this.toolHandlers.keys())\n );\n const handler = this.toolHandlers.get(toolName);\n\n this.emit(\"tool_call\", { name: toolName, arguments: args });\n\n if (!handler) {\n await this.sendToolResult(\n msgId,\n call_id,\n false,\n undefined,\n `Tool '${toolName}' not found`\n );\n return;\n }\n\n try {\n this.log(`Executing tool '${toolName}' with args:`, args);\n const result = await Promise.race([\n handler(args),\n this.createTimeout(this.config.toolExecutionTimeout!),\n ]);\n\n this.log(`Tool '${toolName}' completed successfully`);\n await this.sendToolResult(msgId, call_id, true, result);\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n const errorStack = e instanceof Error ? e.stack : undefined;\n this.log(`Tool '${toolName}' failed:`, errorMessage);\n if (errorStack) {\n this.log(`Tool error stack:`, errorStack);\n }\n await this.sendToolResult(msgId, call_id, false, undefined, errorMessage);\n }\n }\n\n private async sendToolResult(\n id: string,\n callId: string,\n success: boolean,\n result?: unknown,\n error?: string\n ): Promise<void> {\n const message: ToolResultMessage = {\n id,\n type: \"tool_result\",\n call_id: callId,\n success,\n result,\n error,\n };\n\n this.log(\n `Sending tool_result for ${callId}:`,\n success ? \"success\" : `error: ${error}`\n );\n this.send(message);\n }\n\n // ============================================\n // Connection Management\n // ============================================\n\n private handleDisconnect(reason: string): void {\n this.stopHeartbeat();\n this.state.connected = false;\n this.state.registered = false;\n this.emit(\"disconnected\", reason);\n\n for (const [, pending] of this.pendingRequests) {\n pending.reject(createSDKError(SDKErrorCode.DISCONNECTED));\n }\n this.pendingRequests.clear();\n\n if (reason === \"Client disconnect\") {\n this.log(\"Client disconnected intentionally, skipping auto-reconnect\");\n return;\n }\n\n if (reason === \"Replaced by new connection\") {\n this.log(\"Connection replaced by newer one, skipping auto-reconnect\");\n return;\n }\n\n if (this.connectingPromise) {\n this.log(\n \"Connection attempt already in progress, skipping auto-reconnect\"\n );\n return;\n }\n\n if (!this.shouldAutoReconnect()) {\n this.log(\n \"No components require reconnection (refCount=0), skipping auto-reconnect\"\n );\n return;\n }\n\n this.scheduleReconnect();\n }\n\n private shouldAutoReconnect(): boolean {\n return this.reconnectRefCount > 0;\n }\n\n acquireReconnect(): void {\n this.reconnectRefCount++;\n this.log(`acquireReconnect: refCount=${this.reconnectRefCount}`);\n }\n\n releaseReconnect(): void {\n this.reconnectRefCount = Math.max(0, this.reconnectRefCount - 1);\n this.log(`releaseReconnect: refCount=${this.reconnectRefCount}`);\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return;\n\n const baseDelay = Math.min(\n 500 * Math.pow(2, this.state.reconnectAttempts),\n 5000\n );\n const jitter = Math.random() * 500;\n const delay = baseDelay + jitter;\n\n this.log(\n `Scheduling reconnect in ${Math.round(delay)}ms (attempt ${this.state.reconnectAttempts + 1})`\n );\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnectTimer = null;\n this.state.reconnectAttempts++;\n\n try {\n await this.ensureReady();\n } catch (e) {\n console.error(\"[SDK] Reconnect failed:\", e);\n if (!this.isConnected()) {\n this.scheduleReconnect();\n }\n }\n }, delay);\n }\n\n private stopReconnect(): void {\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n }\n\n // ============================================\n // Heartbeat\n // ============================================\n\n private startHeartbeat(): void {\n this.stopHeartbeat();\n this.missedHeartbeats = 0;\n this.heartbeatAckPending = false;\n\n this.heartbeatTimer = setInterval(() => {\n if (this.heartbeatAckPending) {\n this.missedHeartbeats++;\n this.warn(\n `Missed heartbeat ack (${this.missedHeartbeats}/${SanqianSDK.MAX_MISSED_HEARTBEATS})`\n );\n\n if (this.missedHeartbeats >= SanqianSDK.MAX_MISSED_HEARTBEATS) {\n this.warn(\"Too many missed heartbeat acks, connection may be dead\");\n this.ws?.close(4000, \"Heartbeat timeout\");\n return;\n }\n }\n\n const message: HeartbeatMessage = {\n type: \"heartbeat\",\n timestamp: new Date().toISOString(),\n };\n this.heartbeatAckPending = true;\n try {\n this.send(message);\n } catch (e) {\n console.error(\"[SDK] Heartbeat send failed:\", e);\n this.ws?.close(4000, \"Heartbeat send failed\");\n }\n }, this.config.heartbeatInterval);\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n }\n\n // ============================================\n // Communication\n // ============================================\n\n private send(message: object): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n const error = new Error(\n `WebSocket not open (state: ${this.ws?.readyState ?? \"null\"}), cannot send message`\n );\n console.error(`[SDK] ${error.message}:`, message);\n throw error;\n }\n\n const data = JSON.stringify(message);\n this.log(`WebSocket send:`, data.substring(0, 200));\n this.ws.send(data);\n }\n\n private sendAndWait<T>(\n message: object,\n id: string,\n timeout: number\n ): Promise<T> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(createSDKError(SDKErrorCode.REQUEST_TIMEOUT));\n }, timeout);\n\n this.pendingRequests.set(id, {\n resolve: (value) => {\n clearTimeout(timer);\n resolve(value as T);\n },\n reject: (error) => {\n clearTimeout(timer);\n reject(error);\n },\n });\n\n try {\n this.send(message);\n } catch (e) {\n clearTimeout(timer);\n this.pendingRequests.delete(id);\n reject(e);\n }\n });\n }\n\n // ============================================\n // Public API\n // ============================================\n\n getState(): ConnectionState {\n return { ...this.state };\n }\n\n isConnected(): boolean {\n return this.state.connected && this.state.registered;\n }\n\n async ensureReady(): Promise<void> {\n if (this.isConnected()) {\n return;\n }\n\n if (this.connectingPromise) {\n this.log(\"Connection already in progress, waiting...\");\n return this.connectingPromise;\n }\n\n this.connectingPromise = this.doFullConnect();\n\n try {\n await this.connectingPromise;\n } finally {\n this.connectingPromise = null;\n }\n }\n\n private async doFullConnect(): Promise<void> {\n this.log(\"Starting connection (browser mode)...\");\n\n // Browser mode: always use pre-configured connectionInfo\n const info = this.config.connectionInfo!;\n await this.connectWithInfo(info);\n }\n\n async updateTools(tools: ToolDefinition[]): Promise<void> {\n this.toolHandlers.clear();\n for (const tool of tools) {\n this.toolHandlers.set(tool.name, tool.handler);\n }\n\n if (this.isConnected()) {\n const msgId = this.generateId();\n const message = {\n id: msgId,\n type: \"tools_update\",\n tools: tools.map((t) => ({\n name: `${this.config.appName}:${t.name}`,\n description: t.description,\n parameters: t.parameters,\n searchable: t.searchable ?? true,\n })),\n };\n\n await this.sendAndWait(message, msgId, 5000);\n }\n }\n\n // ============================================\n // Private Agent API\n // ============================================\n\n async createAgent(config: AgentConfig): Promise<AgentInfo> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: CreateAgentMessage = {\n id: msgId,\n type: \"create_agent\",\n agent: config,\n };\n\n const response = await this.sendAndWait<CreateAgentAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success) {\n throw createSDKError(SDKErrorCode.AGENT_NOT_FOUND, response.error);\n }\n\n if (response.agent) {\n return response.agent;\n }\n\n return {\n agent_id: response.agent_id!,\n name: config.name,\n description: config.description,\n tools: config.tools || [],\n };\n }\n\n async listAgents(): Promise<AgentInfo[]> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: ListAgentsMessage = {\n id: msgId,\n type: \"list_agents\",\n };\n\n const response = await this.sendAndWait<ListAgentsAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (response.error) {\n throw new Error(response.error);\n }\n\n return response.agents;\n }\n\n async deleteAgent(agentId: string): Promise<void> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: DeleteAgentMessage = {\n id: msgId,\n type: \"delete_agent\",\n agent_id: agentId,\n };\n\n const response = await this.sendAndWait<DeleteAgentAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success) {\n throw createSDKError(SDKErrorCode.AGENT_NOT_FOUND, response.error);\n }\n }\n\n async updateAgent(\n agentId: string,\n updates: Omit<AgentUpdateConfig, \"agent_id\">\n ): Promise<AgentInfo> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: UpdateAgentMessage = {\n id: msgId,\n type: \"update_agent\",\n agent_id: agentId,\n updates,\n };\n\n const response = await this.sendAndWait<UpdateAgentAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success || !response.agent) {\n throw createSDKError(SDKErrorCode.AGENT_NOT_FOUND, response.error);\n }\n\n return response.agent;\n }\n\n // ============================================\n // Conversation API\n // ============================================\n\n async listConversations(options?: {\n agentId?: string;\n limit?: number;\n offset?: number;\n }): Promise<{ conversations: ConversationInfo[]; total: number }> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: ListConversationsMessage = {\n id: msgId,\n type: \"list_conversations\",\n agent_id: options?.agentId,\n limit: options?.limit,\n offset: options?.offset,\n };\n\n const response = await this.sendAndWait<ListConversationsAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (response.error) {\n throw new Error(response.error);\n }\n\n return {\n conversations: response.conversations,\n total: response.total,\n };\n }\n\n async getConversation(\n conversationId: string,\n options?: {\n includeMessages?: boolean;\n messageLimit?: number;\n messageOffset?: number;\n }\n ): Promise<ConversationDetail> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: GetConversationMessage = {\n id: msgId,\n type: \"get_conversation\",\n conversation_id: conversationId,\n include_messages: options?.includeMessages ?? true,\n message_limit: options?.messageLimit,\n message_offset: options?.messageOffset,\n };\n\n const response = await this.sendAndWait<GetConversationAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success || !response.conversation) {\n throw createSDKError(SDKErrorCode.CONVERSATION_NOT_FOUND, response.error);\n }\n\n return response.conversation;\n }\n\n async deleteConversation(conversationId: string): Promise<void> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: DeleteConversationMessage = {\n id: msgId,\n type: \"delete_conversation\",\n conversation_id: conversationId,\n };\n\n const response = await this.sendAndWait<DeleteConversationAckMessage>(\n message,\n msgId,\n 10000\n );\n\n if (!response.success) {\n throw createSDKError(SDKErrorCode.CONVERSATION_NOT_FOUND, response.error);\n }\n }\n\n // ============================================\n // Chat API\n // ============================================\n\n private streamHandlers: Map<\n string,\n {\n onEvent: (event: ChatStreamEvent) => void;\n onDone: (response: ChatResponse) => void;\n onError: (error: Error) => void;\n }\n > = new Map();\n\n async chat(\n agentId: string,\n messages: ChatMessage[],\n options?: {\n conversationId?: string;\n remoteTools?: RemoteToolDefinition[];\n }\n ): Promise<ChatResponse> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: ChatRequestMessage = {\n id: msgId,\n type: \"chat\",\n agent_id: agentId,\n messages,\n conversation_id: options?.conversationId,\n stream: false,\n remote_tools: options?.remoteTools?.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n };\n\n const response = await this.sendAndWait<ChatResponseMessage>(\n message,\n msgId,\n 600000\n );\n\n if (!response.success) {\n const errorLower = (response.error || \"\").toLowerCase();\n if (errorLower.includes(\"agent\") && errorLower.includes(\"not found\")) {\n throw createSDKError(SDKErrorCode.AGENT_NOT_FOUND, response.error);\n }\n throw createSDKError(SDKErrorCode.REQUEST_FAILED, response.error);\n }\n\n return {\n message: response.message!,\n conversationId: response.conversation_id!,\n title: response.title,\n usage: response.usage,\n };\n }\n\n async *chatStream(\n agentId: string,\n messages: ChatMessage[],\n options?: {\n conversationId?: string;\n remoteTools?: RemoteToolDefinition[];\n }\n ): AsyncGenerator<ChatStreamEvent> {\n await this.ensureReady();\n\n const msgId = this.generateId();\n const message: ChatRequestMessage = {\n id: msgId,\n type: \"chat\",\n agent_id: agentId,\n messages,\n conversation_id: options?.conversationId,\n stream: true,\n remote_tools: options?.remoteTools?.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n };\n\n const eventQueue: ChatStreamEvent[] = [];\n let done = false;\n let error: Error | null = null;\n let resolveNext: (() => void) | null = null;\n\n this.streamHandlers.set(msgId, {\n onEvent: (event) => {\n eventQueue.push(event);\n resolveNext?.();\n },\n onDone: (response) => {\n eventQueue.push({\n type: \"done\",\n conversationId: response.conversationId,\n title: response.title,\n });\n done = true;\n resolveNext?.();\n },\n onError: (e) => {\n error = e;\n resolveNext?.();\n },\n });\n\n try {\n this.send(message);\n\n while (!done && !error) {\n if (eventQueue.length > 0) {\n yield eventQueue.shift()!;\n } else {\n await new Promise<void>((resolve) => {\n resolveNext = resolve;\n });\n resolveNext = null;\n }\n }\n\n while (eventQueue.length > 0) {\n yield eventQueue.shift()!;\n }\n\n if (error) {\n throw error;\n }\n } finally {\n this.streamHandlers.delete(msgId);\n }\n }\n\n /**\n * Send HITL (Human-in-the-Loop) response to resume after interrupt\n *\n * Call this after receiving an \"interrupt\" event in chatStream.\n *\n * @param runId - The run_id from the interrupt event\n * @param response - User's response (approval, input, etc.)\n */\n sendHitlResponse(runId: string, response: HitlResponse): void {\n if (!this.state.connected) {\n throw createSDKError(SDKErrorCode.DISCONNECTED, \"Not connected to Sanqian\");\n }\n\n const message: HitlResponseMessage = {\n type: \"hitl_response\",\n run_id: runId,\n response,\n };\n\n this.send(message);\n this.log(`Sent HITL response for run ${runId}`);\n }\n\n startConversation(agentId: string): Conversation {\n return new Conversation(this, agentId);\n }\n\n // ============================================\n // Events\n // ============================================\n\n on<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(listener as EventListener<SDKEventName>);\n return this;\n }\n\n off<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this {\n this.eventListeners\n .get(event)\n ?.delete(listener as EventListener<SDKEventName>);\n return this;\n }\n\n once<T extends SDKEventName>(event: T, listener: SDKEvents[T]): this {\n const onceWrapper = ((...args: Parameters<SDKEvents[T]>) => {\n this.off(event, onceWrapper as SDKEvents[T]);\n (listener as (...args: unknown[]) => void)(...args);\n }) as SDKEvents[T];\n return this.on(event, onceWrapper);\n }\n\n /**\n * Remove all event listeners\n *\n * Call this to prevent memory leaks when disposing the SDK instance.\n * If event is specified, only removes listeners for that event.\n */\n removeAllListeners(event?: SDKEventName): this {\n if (event) {\n this.eventListeners.delete(event);\n } else {\n this.eventListeners.clear();\n }\n return this;\n }\n\n private emit<T extends SDKEventName>(\n event: T,\n ...args: Parameters<SDKEvents[T]>\n ): void {\n const listeners = this.eventListeners.get(event);\n if (listeners) {\n for (const listener of listeners) {\n try {\n (listener as (...args: unknown[]) => void)(...args);\n } catch (e) {\n console.error(`[SDK] Event listener error for '${event}':`, e);\n }\n }\n }\n }\n\n // ============================================\n // Utilities\n // ============================================\n\n private generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n }\n\n private createTimeout(ms: number): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(\n () => reject(createSDKError(SDKErrorCode.TOOL_EXECUTION_TIMEOUT)),\n ms\n );\n });\n }\n}\n\n/**\n * Conversation helper for multi-turn chat\n */\nexport class Conversation {\n private sdk: SanqianSDK;\n private agentId: string;\n private _conversationId: string | null = null;\n\n constructor(sdk: SanqianSDK, agentId: string, conversationId?: string) {\n this.sdk = sdk;\n this.agentId = agentId;\n this._conversationId = conversationId || null;\n }\n\n get id(): string | null {\n return this._conversationId;\n }\n\n async send(\n content: string,\n options?: { remoteTools?: RemoteToolDefinition[] }\n ): Promise<ChatResponse> {\n const response = await this.sdk.chat(\n this.agentId,\n [{ role: \"user\", content }],\n {\n conversationId: this._conversationId || undefined,\n remoteTools: options?.remoteTools,\n }\n );\n\n if (response.conversationId && !this._conversationId) {\n this._conversationId = response.conversationId;\n }\n\n return response;\n }\n\n async *sendStream(\n content: string,\n options?: { remoteTools?: RemoteToolDefinition[] }\n ): AsyncGenerator<ChatStreamEvent> {\n const stream = this.sdk.chatStream(\n this.agentId,\n [{ role: \"user\", content }],\n {\n conversationId: this._conversationId || undefined,\n remoteTools: options?.remoteTools,\n }\n );\n\n for await (const event of stream) {\n if (\n event.type === \"done\" &&\n event.conversationId &&\n !this._conversationId\n ) {\n this._conversationId = event.conversationId;\n }\n yield event;\n }\n }\n\n async delete(): Promise<void> {\n if (!this._conversationId) {\n throw new Error(\"No conversation to delete\");\n }\n await this.sdk.deleteConversation(this._conversationId);\n this._conversationId = null;\n }\n\n async getDetails(options?: {\n messageLimit?: number;\n }): Promise<ConversationDetail> {\n if (!this._conversationId) {\n throw new Error(\"No conversation to get details for\");\n }\n return this.sdk.getConversation(this._conversationId, {\n includeMessages: true,\n messageLimit: options?.messageLimit,\n });\n }\n}\n"],"mappings":"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","names":["SDKErrorCode"]}
package/dist/index.d.mts CHANGED
@@ -137,7 +137,7 @@ interface ChatResponse {
137
137
  };
138
138
  }
139
139
  interface ChatStreamEvent {
140
- type: "text" | "thinking" | "tool_call" | "tool_result" | "done" | "error";
140
+ type: "text" | "thinking" | "tool_call" | "tool_result" | "done" | "error" | "interrupt";
141
141
  /** Text content (for "text" and "thinking" events) */
142
142
  content?: string;
143
143
  /** Tool call info (for "tool_call" event) */
@@ -154,6 +154,58 @@ interface ChatStreamEvent {
154
154
  title?: string;
155
155
  /** Error message (for "error" event or failed "tool_result") */
156
156
  error?: string;
157
+ /** Interrupt type (for "interrupt" event) - HITL */
158
+ interrupt_type?: HitlInterruptType;
159
+ /** Interrupt payload (for "interrupt" event) - HITL */
160
+ interrupt_payload?: HitlInterruptPayload;
161
+ /** Run ID (for "interrupt" event) - needed to send HITL response */
162
+ run_id?: string;
163
+ }
164
+ /** HITL interrupt types */
165
+ type HitlInterruptType = "approval_request" | "user_input_request";
166
+ /** HITL risk levels for approval requests */
167
+ type HitlRiskLevel = "low" | "medium" | "high";
168
+ /** HITL interrupt payload - sent from backend when HITL is triggered */
169
+ interface HitlInterruptPayload {
170
+ /** Interrupt type (redundant but useful) */
171
+ type?: HitlInterruptType;
172
+ /** Tool name requiring approval */
173
+ tool?: string;
174
+ /** Tool arguments */
175
+ args?: Record<string, unknown>;
176
+ /** Reason for approval request */
177
+ reason?: string;
178
+ /** Risk level */
179
+ risk_level?: HitlRiskLevel;
180
+ /** Question to ask the user */
181
+ question?: string;
182
+ /** Additional context */
183
+ context?: string;
184
+ /** Predefined options (for single/multi-select) */
185
+ options?: string[];
186
+ /** Allow multiple selections */
187
+ multi_select?: boolean;
188
+ /** Default value */
189
+ default?: string;
190
+ /** Whether input is required */
191
+ required?: boolean;
192
+ /** Timeout in seconds */
193
+ timeout?: number;
194
+ }
195
+ /** HITL response - sent from client to backend */
196
+ interface HitlResponse {
197
+ /** For approval_request: true = approved, false = rejected */
198
+ approved?: boolean;
199
+ /** Remember this choice for future similar requests */
200
+ remember?: boolean;
201
+ /** For user_input_request: the user's answer */
202
+ answer?: string;
203
+ /** For multi-select: selected option indices */
204
+ selected_indices?: number[];
205
+ /** User cancelled the request */
206
+ cancelled?: boolean;
207
+ /** Request timed out */
208
+ timed_out?: boolean;
157
209
  }
158
210
  /** Agent configuration for create/update */
159
211
  interface AgentConfig {
@@ -469,6 +521,26 @@ declare class SanqianSDK {
469
521
  conversationId?: string;
470
522
  remoteTools?: RemoteToolDefinition[];
471
523
  }): AsyncGenerator<ChatStreamEvent>;
524
+ /**
525
+ * Send HITL (Human-in-the-Loop) response to resume after interrupt
526
+ *
527
+ * Call this after receiving an "interrupt" event in chatStream.
528
+ *
529
+ * @example
530
+ * ```typescript
531
+ * for await (const event of sdk.chatStream('assistant', messages)) {
532
+ * if (event.type === 'interrupt') {
533
+ * // Show UI for user approval/input
534
+ * const userApproved = await showApprovalDialog(event.interrupt_payload);
535
+ * sdk.sendHitlResponse(event.run_id!, { approved: userApproved });
536
+ * }
537
+ * }
538
+ * ```
539
+ *
540
+ * @param runId - The run_id from the interrupt event
541
+ * @param response - User's response (approval, input, etc.)
542
+ */
543
+ sendHitlResponse(runId: string, response: HitlResponse): void;
472
544
  /**
473
545
  * Start a new conversation with an agent
474
546
  *
@@ -691,4 +763,4 @@ declare class SanqianSDKError extends Error {
691
763
  */
692
764
  declare function createSDKError(code: SDKErrorCode, details?: string): SanqianSDKError;
693
765
 
694
- 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, DiscoveryManager, ErrorMessages, type JSONSchema, type JSONSchemaProperty, type RemoteToolDefinition, SANQIAN_WEBSITE, type SDKConfig, SDKErrorCode, type SDKEventName, type SDKEvents, SanqianSDK, SanqianSDKError, type ToolCall, type ToolDefinition, createSDKError };
766
+ 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, DiscoveryManager, ErrorMessages, type HitlInterruptPayload, type HitlInterruptType, type HitlResponse, type HitlRiskLevel, type JSONSchema, type JSONSchemaProperty, type RemoteToolDefinition, SANQIAN_WEBSITE, type SDKConfig, SDKErrorCode, type SDKEventName, type SDKEvents, SanqianSDK, SanqianSDKError, type ToolCall, type ToolDefinition, createSDKError };
package/dist/index.d.ts CHANGED
@@ -137,7 +137,7 @@ interface ChatResponse {
137
137
  };
138
138
  }
139
139
  interface ChatStreamEvent {
140
- type: "text" | "thinking" | "tool_call" | "tool_result" | "done" | "error";
140
+ type: "text" | "thinking" | "tool_call" | "tool_result" | "done" | "error" | "interrupt";
141
141
  /** Text content (for "text" and "thinking" events) */
142
142
  content?: string;
143
143
  /** Tool call info (for "tool_call" event) */
@@ -154,6 +154,58 @@ interface ChatStreamEvent {
154
154
  title?: string;
155
155
  /** Error message (for "error" event or failed "tool_result") */
156
156
  error?: string;
157
+ /** Interrupt type (for "interrupt" event) - HITL */
158
+ interrupt_type?: HitlInterruptType;
159
+ /** Interrupt payload (for "interrupt" event) - HITL */
160
+ interrupt_payload?: HitlInterruptPayload;
161
+ /** Run ID (for "interrupt" event) - needed to send HITL response */
162
+ run_id?: string;
163
+ }
164
+ /** HITL interrupt types */
165
+ type HitlInterruptType = "approval_request" | "user_input_request";
166
+ /** HITL risk levels for approval requests */
167
+ type HitlRiskLevel = "low" | "medium" | "high";
168
+ /** HITL interrupt payload - sent from backend when HITL is triggered */
169
+ interface HitlInterruptPayload {
170
+ /** Interrupt type (redundant but useful) */
171
+ type?: HitlInterruptType;
172
+ /** Tool name requiring approval */
173
+ tool?: string;
174
+ /** Tool arguments */
175
+ args?: Record<string, unknown>;
176
+ /** Reason for approval request */
177
+ reason?: string;
178
+ /** Risk level */
179
+ risk_level?: HitlRiskLevel;
180
+ /** Question to ask the user */
181
+ question?: string;
182
+ /** Additional context */
183
+ context?: string;
184
+ /** Predefined options (for single/multi-select) */
185
+ options?: string[];
186
+ /** Allow multiple selections */
187
+ multi_select?: boolean;
188
+ /** Default value */
189
+ default?: string;
190
+ /** Whether input is required */
191
+ required?: boolean;
192
+ /** Timeout in seconds */
193
+ timeout?: number;
194
+ }
195
+ /** HITL response - sent from client to backend */
196
+ interface HitlResponse {
197
+ /** For approval_request: true = approved, false = rejected */
198
+ approved?: boolean;
199
+ /** Remember this choice for future similar requests */
200
+ remember?: boolean;
201
+ /** For user_input_request: the user's answer */
202
+ answer?: string;
203
+ /** For multi-select: selected option indices */
204
+ selected_indices?: number[];
205
+ /** User cancelled the request */
206
+ cancelled?: boolean;
207
+ /** Request timed out */
208
+ timed_out?: boolean;
157
209
  }
158
210
  /** Agent configuration for create/update */
159
211
  interface AgentConfig {
@@ -469,6 +521,26 @@ declare class SanqianSDK {
469
521
  conversationId?: string;
470
522
  remoteTools?: RemoteToolDefinition[];
471
523
  }): AsyncGenerator<ChatStreamEvent>;
524
+ /**
525
+ * Send HITL (Human-in-the-Loop) response to resume after interrupt
526
+ *
527
+ * Call this after receiving an "interrupt" event in chatStream.
528
+ *
529
+ * @example
530
+ * ```typescript
531
+ * for await (const event of sdk.chatStream('assistant', messages)) {
532
+ * if (event.type === 'interrupt') {
533
+ * // Show UI for user approval/input
534
+ * const userApproved = await showApprovalDialog(event.interrupt_payload);
535
+ * sdk.sendHitlResponse(event.run_id!, { approved: userApproved });
536
+ * }
537
+ * }
538
+ * ```
539
+ *
540
+ * @param runId - The run_id from the interrupt event
541
+ * @param response - User's response (approval, input, etc.)
542
+ */
543
+ sendHitlResponse(runId: string, response: HitlResponse): void;
472
544
  /**
473
545
  * Start a new conversation with an agent
474
546
  *
@@ -691,4 +763,4 @@ declare class SanqianSDKError extends Error {
691
763
  */
692
764
  declare function createSDKError(code: SDKErrorCode, details?: string): SanqianSDKError;
693
765
 
694
- 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, DiscoveryManager, ErrorMessages, type JSONSchema, type JSONSchemaProperty, type RemoteToolDefinition, SANQIAN_WEBSITE, type SDKConfig, SDKErrorCode, type SDKEventName, type SDKEvents, SanqianSDK, SanqianSDKError, type ToolCall, type ToolDefinition, createSDKError };
766
+ 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, DiscoveryManager, ErrorMessages, type HitlInterruptPayload, type HitlInterruptType, type HitlResponse, type HitlRiskLevel, type JSONSchema, type JSONSchemaProperty, type RemoteToolDefinition, SANQIAN_WEBSITE, type SDKConfig, SDKErrorCode, type SDKEventName, type SDKEvents, SanqianSDK, SanqianSDKError, type ToolCall, type ToolDefinition, createSDKError };