@chucky.cloud/sdk 0.2.7 → 0.3.1

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.
Files changed (94) hide show
  1. package/dist/browser.cjs +1371 -0
  2. package/dist/browser.cjs.map +1 -0
  3. package/dist/browser.d.cts +1 -0
  4. package/dist/browser.d.ts +1 -8
  5. package/dist/browser.js +1288 -11
  6. package/dist/browser.js.map +1 -1
  7. package/dist/index.cjs +1371 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.d.cts +1991 -0
  10. package/dist/index.d.ts +1971 -48
  11. package/dist/index.js +1288 -72
  12. package/dist/index.js.map +1 -1
  13. package/dist/node.cjs +1371 -0
  14. package/dist/node.cjs.map +1 -0
  15. package/dist/node.d.cts +1 -0
  16. package/dist/node.d.ts +1 -8
  17. package/dist/node.js +1288 -10
  18. package/dist/node.js.map +1 -1
  19. package/package.json +13 -7
  20. package/dist/browser.d.ts.map +0 -1
  21. package/dist/client/ChuckyClient.d.ts +0 -141
  22. package/dist/client/ChuckyClient.d.ts.map +0 -1
  23. package/dist/client/ChuckyClient.js +0 -209
  24. package/dist/client/ChuckyClient.js.map +0 -1
  25. package/dist/client/Session.d.ts +0 -167
  26. package/dist/client/Session.d.ts.map +0 -1
  27. package/dist/client/Session.js +0 -392
  28. package/dist/client/Session.js.map +0 -1
  29. package/dist/client/index.d.ts +0 -10
  30. package/dist/client/index.d.ts.map +0 -1
  31. package/dist/client/index.js +0 -9
  32. package/dist/client/index.js.map +0 -1
  33. package/dist/index.d.ts.map +0 -1
  34. package/dist/node.d.ts.map +0 -1
  35. package/dist/tools/McpServer.d.ts +0 -117
  36. package/dist/tools/McpServer.d.ts.map +0 -1
  37. package/dist/tools/McpServer.js +0 -142
  38. package/dist/tools/McpServer.js.map +0 -1
  39. package/dist/tools/index.d.ts +0 -9
  40. package/dist/tools/index.d.ts.map +0 -1
  41. package/dist/tools/index.js +0 -8
  42. package/dist/tools/index.js.map +0 -1
  43. package/dist/tools/tool.d.ts +0 -146
  44. package/dist/tools/tool.d.ts.map +0 -1
  45. package/dist/tools/tool.js +0 -232
  46. package/dist/tools/tool.js.map +0 -1
  47. package/dist/transport/Transport.d.ts +0 -82
  48. package/dist/transport/Transport.d.ts.map +0 -1
  49. package/dist/transport/Transport.js +0 -47
  50. package/dist/transport/Transport.js.map +0 -1
  51. package/dist/transport/WebSocketTransport.d.ts +0 -78
  52. package/dist/transport/WebSocketTransport.d.ts.map +0 -1
  53. package/dist/transport/WebSocketTransport.js +0 -258
  54. package/dist/transport/WebSocketTransport.js.map +0 -1
  55. package/dist/transport/index.d.ts +0 -10
  56. package/dist/transport/index.d.ts.map +0 -1
  57. package/dist/transport/index.js +0 -8
  58. package/dist/transport/index.js.map +0 -1
  59. package/dist/types/index.d.ts +0 -12
  60. package/dist/types/index.d.ts.map +0 -1
  61. package/dist/types/index.js +0 -8
  62. package/dist/types/index.js.map +0 -1
  63. package/dist/types/messages.d.ts +0 -327
  64. package/dist/types/messages.d.ts.map +0 -1
  65. package/dist/types/messages.js +0 -133
  66. package/dist/types/messages.js.map +0 -1
  67. package/dist/types/options.d.ts +0 -212
  68. package/dist/types/options.d.ts.map +0 -1
  69. package/dist/types/options.js +0 -8
  70. package/dist/types/options.js.map +0 -1
  71. package/dist/types/results.d.ts +0 -186
  72. package/dist/types/results.d.ts.map +0 -1
  73. package/dist/types/results.js +0 -7
  74. package/dist/types/results.js.map +0 -1
  75. package/dist/types/token.d.ts +0 -124
  76. package/dist/types/token.d.ts.map +0 -1
  77. package/dist/types/token.js +0 -7
  78. package/dist/types/token.js.map +0 -1
  79. package/dist/types/tools.d.ts +0 -234
  80. package/dist/types/tools.d.ts.map +0 -1
  81. package/dist/types/tools.js +0 -31
  82. package/dist/types/tools.js.map +0 -1
  83. package/dist/utils/errors.d.ts +0 -80
  84. package/dist/utils/errors.d.ts.map +0 -1
  85. package/dist/utils/errors.js +0 -158
  86. package/dist/utils/errors.js.map +0 -1
  87. package/dist/utils/index.d.ts +0 -8
  88. package/dist/utils/index.d.ts.map +0 -1
  89. package/dist/utils/index.js +0 -8
  90. package/dist/utils/index.js.map +0 -1
  91. package/dist/utils/token.d.ts +0 -104
  92. package/dist/utils/token.d.ts.map +0 -1
  93. package/dist/utils/token.js +0 -209
  94. package/dist/utils/token.js.map +0 -1
package/dist/browser.js CHANGED
@@ -1,12 +1,1289 @@
1
- /**
2
- * Browser Entry Point
3
- *
4
- * Optimized exports for browser environments.
5
- * Excludes Node.js-specific functionality like token creation.
6
- */
7
- // Re-export everything from main index
8
- export * from './index.js';
9
- // Browser-specific note: Token creation uses Web Crypto API
10
- // which is available in modern browsers. For older browsers,
11
- // you may need a polyfill.
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/types/messages.ts
6
+ function createInitMessage(payload) {
7
+ return { type: "init", payload };
8
+ }
9
+ function createUserMessage(content, sessionId, options = {}) {
10
+ const messageContent = typeof content === "string" ? content : content;
11
+ return {
12
+ type: "user",
13
+ uuid: options.uuid,
14
+ session_id: sessionId,
15
+ message: {
16
+ role: "user",
17
+ content: messageContent
18
+ },
19
+ parent_tool_use_id: options.parentToolUseId ?? null
20
+ };
21
+ }
22
+ function createControlMessage(action, data) {
23
+ return { type: "control", payload: { action, data } };
24
+ }
25
+ function createPingMessage() {
26
+ return { type: "ping", payload: { timestamp: Date.now() } };
27
+ }
28
+ function createToolResultMessage(callId, result) {
29
+ return { type: "tool_result", payload: { callId, result } };
30
+ }
31
+ function isUserMessage(message) {
32
+ return message.type === "user";
33
+ }
34
+ function isAssistantMessage(message) {
35
+ return message.type === "assistant";
36
+ }
37
+ function isResultMessage(message) {
38
+ return message.type === "result";
39
+ }
40
+ function isSuccessResult(message) {
41
+ return message.type === "result" && message.subtype === "success";
42
+ }
43
+ function isErrorResult(message) {
44
+ return message.type === "result" && message.subtype !== "success";
45
+ }
46
+ function isSystemMessage(message) {
47
+ return message.type === "system";
48
+ }
49
+ function isStreamEvent(message) {
50
+ return message.type === "stream_event";
51
+ }
52
+ function isToolCallMessage(message) {
53
+ return message.type === "tool_call";
54
+ }
55
+ function isControlMessage(message) {
56
+ return message.type === "control";
57
+ }
58
+ function isErrorMessage(message) {
59
+ return message.type === "error";
60
+ }
61
+
62
+ // src/transport/Transport.ts
63
+ var BaseTransport = class {
64
+ constructor(config) {
65
+ __publicField(this, "_status", "disconnected");
66
+ __publicField(this, "handlers", {});
67
+ __publicField(this, "config");
68
+ const cleanConfig = Object.fromEntries(
69
+ Object.entries(config).filter(([_, v]) => v !== void 0)
70
+ );
71
+ this.config = {
72
+ timeout: 6e4,
73
+ // 60s - container startup can take time
74
+ keepAliveInterval: 3e5,
75
+ // 5 minutes
76
+ autoReconnect: false,
77
+ // Disabled - server doesn't support reconnect
78
+ maxReconnectAttempts: 0,
79
+ debug: false,
80
+ ...cleanConfig
81
+ };
82
+ }
83
+ get status() {
84
+ return this._status;
85
+ }
86
+ setStatus(status) {
87
+ if (this._status !== status) {
88
+ this._status = status;
89
+ this.handlers.onStatusChange?.(status);
90
+ }
91
+ }
92
+ log(...args) {
93
+ if (this.config.debug) {
94
+ console.log("[ChuckySDK]", ...args);
95
+ }
96
+ }
97
+ logError(...args) {
98
+ console.error("[ChuckySDK]", ...args);
99
+ }
100
+ setEventHandlers(handlers) {
101
+ this.handlers = { ...this.handlers, ...handlers };
102
+ }
103
+ };
104
+
105
+ // src/transport/WebSocketTransport.ts
106
+ async function getWebSocket() {
107
+ if (typeof WebSocket !== "undefined") {
108
+ return WebSocket;
109
+ }
110
+ const ws = await import("ws");
111
+ return ws.default;
112
+ }
113
+ var WebSocketTransport = class extends BaseTransport {
114
+ constructor(config) {
115
+ super(config);
116
+ __publicField(this, "ws", null);
117
+ __publicField(this, "keepAliveTimer", null);
118
+ __publicField(this, "reconnectAttempts", 0);
119
+ __publicField(this, "reconnectTimer", null);
120
+ __publicField(this, "readyPromise", null);
121
+ __publicField(this, "readyResolve", null);
122
+ __publicField(this, "readyReject", null);
123
+ __publicField(this, "messageQueue", []);
124
+ }
125
+ /**
126
+ * Build the WebSocket URL with token
127
+ */
128
+ buildUrl() {
129
+ const url = new URL(this.config.url);
130
+ url.searchParams.set("token", this.config.token);
131
+ return url.toString();
132
+ }
133
+ /**
134
+ * Connect to the WebSocket server
135
+ */
136
+ async connect() {
137
+ if (this._status === "connected" || this._status === "connecting") {
138
+ return this.waitForReady();
139
+ }
140
+ this.setStatus("connecting");
141
+ this.log("Connecting to", this.config.url);
142
+ this.readyPromise = new Promise((resolve, reject) => {
143
+ this.readyResolve = resolve;
144
+ this.readyReject = reject;
145
+ });
146
+ try {
147
+ const WS = await getWebSocket();
148
+ const wsUrl = this.buildUrl();
149
+ this.ws = new WS(wsUrl);
150
+ const timeoutId = setTimeout(() => {
151
+ if (this._status === "connecting") {
152
+ this.ws?.close();
153
+ const error = new Error("Connection timeout");
154
+ this.readyReject?.(error);
155
+ this.handlers.onError?.(error);
156
+ this.setStatus("error");
157
+ }
158
+ }, this.config.timeout);
159
+ this.ws.onopen = () => {
160
+ clearTimeout(timeoutId);
161
+ this.log("Connected");
162
+ this.setStatus("connected");
163
+ this.reconnectAttempts = 0;
164
+ this.startKeepAlive();
165
+ this.readyResolve?.();
166
+ this.flushMessageQueue();
167
+ };
168
+ this.ws.onclose = (event) => {
169
+ clearTimeout(timeoutId);
170
+ this.log("Disconnected:", event.code, event.reason);
171
+ this.stopKeepAlive();
172
+ if (this._status === "connecting") {
173
+ const error = new Error(`Connection failed: ${event.reason || "Unknown"}`);
174
+ this.readyReject?.(error);
175
+ }
176
+ this.setStatus("disconnected");
177
+ this.handlers.onClose?.(event.code, event.reason);
178
+ if (this.config.autoReconnect && this.reconnectAttempts < (this.config.maxReconnectAttempts || 5)) {
179
+ this.scheduleReconnect();
180
+ }
181
+ };
182
+ this.ws.onerror = (event) => {
183
+ clearTimeout(timeoutId);
184
+ const error = new Error("WebSocket error");
185
+ this.logError("WebSocket error:", event);
186
+ this.handlers.onError?.(error);
187
+ if (this._status === "connecting") {
188
+ this.readyReject?.(error);
189
+ }
190
+ this.setStatus("error");
191
+ };
192
+ this.ws.onmessage = (event) => {
193
+ this.handleMessage(event.data);
194
+ };
195
+ return this.readyPromise;
196
+ } catch (error) {
197
+ this.setStatus("error");
198
+ this.readyReject?.(error);
199
+ throw error;
200
+ }
201
+ }
202
+ /**
203
+ * Disconnect from the server
204
+ */
205
+ async disconnect() {
206
+ this.log("Disconnecting");
207
+ this.stopKeepAlive();
208
+ this.clearReconnectTimer();
209
+ if (this.ws) {
210
+ this.ws.close(1e3, "Client disconnect");
211
+ this.ws = null;
212
+ }
213
+ this.setStatus("disconnected");
214
+ }
215
+ /**
216
+ * Send a message to the server
217
+ */
218
+ async send(message) {
219
+ if (this._status === "disconnected" && !this.config.autoReconnect) {
220
+ this.log("Message dropped (disconnected):", message.type);
221
+ return;
222
+ }
223
+ if (this._status !== "connected") {
224
+ this.messageQueue.push(message);
225
+ this.log("Message queued (not connected):", message.type);
226
+ if (this._status === "disconnected" && this.config.autoReconnect) {
227
+ await this.connect();
228
+ }
229
+ return;
230
+ }
231
+ this.sendImmediate(message);
232
+ }
233
+ /**
234
+ * Send a message immediately
235
+ */
236
+ sendImmediate(message) {
237
+ if (!this.ws || this.ws.readyState !== 1) {
238
+ this.logError("Cannot send: WebSocket not ready");
239
+ return;
240
+ }
241
+ const data = JSON.stringify(message);
242
+ this.handlers.onRawMessage?.("out", message);
243
+ this.ws.send(data);
244
+ this.log("Sent:", message.type);
245
+ }
246
+ /**
247
+ * Wait for the connection to be ready
248
+ */
249
+ async waitForReady() {
250
+ if (this._status === "connected") {
251
+ return;
252
+ }
253
+ if (this.readyPromise) {
254
+ return this.readyPromise;
255
+ }
256
+ return this.connect();
257
+ }
258
+ /**
259
+ * Handle incoming message
260
+ */
261
+ handleMessage(data) {
262
+ try {
263
+ const text = typeof data === "string" ? data : new TextDecoder().decode(data);
264
+ const message = JSON.parse(text);
265
+ this.handlers.onRawMessage?.("in", message);
266
+ this.log("Received:", message.type);
267
+ if (message.type === "pong") {
268
+ return;
269
+ }
270
+ if (isErrorMessage(message)) {
271
+ const error = new Error(message.payload.message);
272
+ this.handlers.onError?.(error);
273
+ }
274
+ this.handlers.onMessage?.(message);
275
+ } catch (error) {
276
+ this.logError("Failed to parse message:", error);
277
+ }
278
+ }
279
+ /**
280
+ * Start keep-alive ping
281
+ */
282
+ startKeepAlive() {
283
+ this.stopKeepAlive();
284
+ if (this.config.keepAliveInterval && this.config.keepAliveInterval > 0) {
285
+ this.keepAliveTimer = setInterval(() => {
286
+ if (this._status === "connected" && this.ws?.readyState === 1) {
287
+ this.sendImmediate(createPingMessage());
288
+ }
289
+ }, this.config.keepAliveInterval);
290
+ }
291
+ }
292
+ /**
293
+ * Stop keep-alive ping
294
+ */
295
+ stopKeepAlive() {
296
+ if (this.keepAliveTimer) {
297
+ clearInterval(this.keepAliveTimer);
298
+ this.keepAliveTimer = null;
299
+ }
300
+ }
301
+ /**
302
+ * Schedule a reconnection attempt
303
+ */
304
+ scheduleReconnect() {
305
+ this.clearReconnectTimer();
306
+ this.reconnectAttempts++;
307
+ const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts - 1), 16e3);
308
+ this.log(`Scheduling reconnect in ${delay}ms (attempt ${this.reconnectAttempts})`);
309
+ this.setStatus("reconnecting");
310
+ this.reconnectTimer = setTimeout(() => {
311
+ this.connect().catch((error) => {
312
+ this.logError("Reconnect failed:", error);
313
+ });
314
+ }, delay);
315
+ }
316
+ /**
317
+ * Clear reconnect timer
318
+ */
319
+ clearReconnectTimer() {
320
+ if (this.reconnectTimer) {
321
+ clearTimeout(this.reconnectTimer);
322
+ this.reconnectTimer = null;
323
+ }
324
+ }
325
+ /**
326
+ * Flush queued messages
327
+ */
328
+ flushMessageQueue() {
329
+ while (this.messageQueue.length > 0) {
330
+ const message = this.messageQueue.shift();
331
+ this.sendImmediate(message);
332
+ }
333
+ }
334
+ };
335
+
336
+ // src/client/Session.ts
337
+ function generateUUID() {
338
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
339
+ const r = Math.random() * 16 | 0;
340
+ const v = c === "x" ? r : r & 3 | 8;
341
+ return v.toString(16);
342
+ });
343
+ }
344
+ var Session = class {
345
+ constructor(transport, options, config = {}) {
346
+ __publicField(this, "transport");
347
+ __publicField(this, "options");
348
+ __publicField(this, "config");
349
+ __publicField(this, "eventHandlers", {});
350
+ __publicField(this, "toolHandlers", /* @__PURE__ */ new Map());
351
+ __publicField(this, "messageBuffer", []);
352
+ __publicField(this, "_state", "idle");
353
+ __publicField(this, "_sessionId");
354
+ __publicField(this, "messageResolvers", []);
355
+ __publicField(this, "connected", false);
356
+ __publicField(this, "connectPromise", null);
357
+ this.transport = transport;
358
+ this.options = options;
359
+ this.config = config;
360
+ this._sessionId = options.sessionId || generateUUID();
361
+ if (options.mcpServers) {
362
+ for (const server of options.mcpServers) {
363
+ if ("tools" in server) {
364
+ for (const tool2 of server.tools) {
365
+ if (tool2.handler) {
366
+ this.toolHandlers.set(tool2.name, tool2.handler);
367
+ }
368
+ }
369
+ }
370
+ }
371
+ }
372
+ this.transport.setEventHandlers({
373
+ onMessage: (message) => this.handleMessage(message),
374
+ onError: (error) => this.eventHandlers.onError?.(error),
375
+ onStatusChange: (status) => {
376
+ if (status === "disconnected" && this._state !== "completed") {
377
+ this._state = "error";
378
+ }
379
+ }
380
+ });
381
+ }
382
+ /**
383
+ * Get the session ID
384
+ */
385
+ get sessionId() {
386
+ return this._sessionId;
387
+ }
388
+ /**
389
+ * Set event handlers
390
+ */
391
+ on(handlers) {
392
+ this.eventHandlers = { ...this.eventHandlers, ...handlers };
393
+ return this;
394
+ }
395
+ /**
396
+ * Connect and initialize the session (called automatically on first send)
397
+ */
398
+ async ensureConnected() {
399
+ if (this.connected) return;
400
+ if (this.connectPromise) {
401
+ return this.connectPromise;
402
+ }
403
+ this.connectPromise = this.connect();
404
+ await this.connectPromise;
405
+ }
406
+ async connect() {
407
+ this._state = "initializing";
408
+ await this.transport.connect();
409
+ const initPayload = this.buildInitPayload();
410
+ await this.transport.send(createInitMessage(initPayload));
411
+ await this.waitForReady();
412
+ this._state = "ready";
413
+ this.connected = true;
414
+ }
415
+ /**
416
+ * Send a message to the session
417
+ *
418
+ * Matches V2 SDK: send() returns Promise<void>
419
+ * Use stream() to get the response.
420
+ *
421
+ * Supports both text-only messages and multimodal content (text + images).
422
+ *
423
+ * @example
424
+ * ```typescript
425
+ * // Text-only message
426
+ * await session.send('Hello!');
427
+ *
428
+ * // Multimodal message with image
429
+ * await session.send([
430
+ * { type: 'text', text: 'What is in this image?' },
431
+ * { type: 'image', source: { type: 'base64', media_type: 'image/png', data: '...' } }
432
+ * ]);
433
+ *
434
+ * for await (const msg of session.stream()) {
435
+ * // Handle messages
436
+ * }
437
+ * ```
438
+ */
439
+ async send(message) {
440
+ await this.ensureConnected();
441
+ if (this._state !== "ready") {
442
+ throw new Error(`Cannot send: session state is ${this._state}`);
443
+ }
444
+ this._state = "processing";
445
+ const userMessage = createUserMessage(message, this._sessionId);
446
+ await this.transport.send(userMessage);
447
+ }
448
+ /**
449
+ * Stream the response after sending a message
450
+ *
451
+ * Matches V2 SDK: Returns AsyncGenerator<SDKMessage>
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * await session.send('Hello!');
456
+ * for await (const msg of session.stream()) {
457
+ * if (msg.type === 'assistant') {
458
+ * const text = msg.message.content
459
+ * .filter(b => b.type === 'text')
460
+ * .map(b => b.text)
461
+ * .join('');
462
+ * console.log(text);
463
+ * }
464
+ * if (msg.type === 'result') {
465
+ * console.log('Done:', msg.result);
466
+ * }
467
+ * }
468
+ * ```
469
+ */
470
+ async *stream() {
471
+ while (this._state === "processing" || this._state === "waiting_tool") {
472
+ const msg = await this.waitForNextMessage();
473
+ if (isToolCallMessage(msg)) {
474
+ this._state = "waiting_tool";
475
+ await this.handleToolCall(msg.payload);
476
+ this._state = "processing";
477
+ continue;
478
+ }
479
+ if (isAssistantMessage(msg) || isResultMessage(msg) || isSystemMessage(msg) || isStreamEvent(msg)) {
480
+ yield msg;
481
+ }
482
+ if (isResultMessage(msg)) {
483
+ this._state = "ready";
484
+ break;
485
+ }
486
+ if (isErrorMessage(msg)) {
487
+ this._state = "ready";
488
+ throw new Error(msg.payload.message);
489
+ }
490
+ }
491
+ }
492
+ /**
493
+ * Receive messages (alias for stream for V2 compatibility)
494
+ */
495
+ receive() {
496
+ return this.stream();
497
+ }
498
+ /**
499
+ * Close the session
500
+ */
501
+ close() {
502
+ this.transport.send(createControlMessage("close")).catch(() => {
503
+ });
504
+ this.transport.disconnect().catch(() => {
505
+ });
506
+ this._state = "completed";
507
+ }
508
+ /**
509
+ * Support for `await using` (TypeScript 5.2+)
510
+ */
511
+ async [Symbol.asyncDispose]() {
512
+ this.close();
513
+ }
514
+ /**
515
+ * Build init payload from options
516
+ */
517
+ buildInitPayload() {
518
+ const { mcpServers, ...rest } = this.options;
519
+ const serializedMcpServers = mcpServers?.map((server) => {
520
+ if ("tools" in server) {
521
+ return {
522
+ name: server.name,
523
+ version: server.version,
524
+ tools: server.tools.map((tool2) => ({
525
+ name: tool2.name,
526
+ description: tool2.description,
527
+ inputSchema: tool2.inputSchema,
528
+ // If tool has a handler, it executes on the client (SDK) side
529
+ executeIn: tool2.handler ? "client" : tool2.executeIn
530
+ }))
531
+ };
532
+ }
533
+ return server;
534
+ });
535
+ return {
536
+ ...rest,
537
+ // tools is passed through as-is (string[] or preset for allowlisting)
538
+ mcpServers: serializedMcpServers
539
+ };
540
+ }
541
+ /**
542
+ * Handle incoming message
543
+ */
544
+ handleMessage(message) {
545
+ this.log("Received:", message.type);
546
+ if (isControlMessage(message)) {
547
+ if (message.payload.action === "session_info") {
548
+ const info = message.payload.data;
549
+ this._sessionId = info.sessionId || this._sessionId;
550
+ this.eventHandlers.onSessionInfo?.(info);
551
+ }
552
+ }
553
+ if (isSystemMessage(message) && message.subtype === "init") {
554
+ this._sessionId = message.session_id || this._sessionId;
555
+ this.eventHandlers.onSessionInfo?.({
556
+ sessionId: message.session_id,
557
+ model: message.model,
558
+ tools: message.tools
559
+ });
560
+ }
561
+ if (isErrorMessage(message)) {
562
+ const error = new Error(message.payload.message);
563
+ this.eventHandlers.onError?.(error);
564
+ }
565
+ const resolver = this.messageResolvers.shift();
566
+ if (resolver) {
567
+ resolver(message);
568
+ } else {
569
+ this.messageBuffer.push(message);
570
+ }
571
+ }
572
+ /**
573
+ * Wait for session to be ready
574
+ */
575
+ async waitForReady() {
576
+ return new Promise((resolve, reject) => {
577
+ const timeout = setTimeout(() => {
578
+ reject(new Error("Session initialization timeout"));
579
+ }, 3e4);
580
+ const checkReady = (message) => {
581
+ if (isControlMessage(message)) {
582
+ if (message.payload.action === "ready" || message.payload.action === "session_info") {
583
+ clearTimeout(timeout);
584
+ resolve();
585
+ return true;
586
+ }
587
+ }
588
+ if (isSystemMessage(message) && message.subtype === "init") {
589
+ clearTimeout(timeout);
590
+ resolve();
591
+ return true;
592
+ }
593
+ if (isErrorMessage(message)) {
594
+ clearTimeout(timeout);
595
+ reject(new Error(message.payload.message));
596
+ return true;
597
+ }
598
+ return false;
599
+ };
600
+ for (let i = 0; i < this.messageBuffer.length; i++) {
601
+ if (checkReady(this.messageBuffer[i])) {
602
+ this.messageBuffer.splice(i, 1);
603
+ return;
604
+ }
605
+ }
606
+ this.messageResolvers.push((msg) => {
607
+ checkReady(msg);
608
+ });
609
+ });
610
+ }
611
+ /**
612
+ * Wait for next message
613
+ */
614
+ async waitForNextMessage() {
615
+ if (this.messageBuffer.length > 0) {
616
+ return this.messageBuffer.shift();
617
+ }
618
+ return new Promise((resolve) => {
619
+ this.messageResolvers.push(resolve);
620
+ });
621
+ }
622
+ /**
623
+ * Handle a tool call
624
+ */
625
+ async handleToolCall(toolCall) {
626
+ const handler = this.toolHandlers.get(toolCall.toolName);
627
+ if (!handler) {
628
+ this.log("No local handler for tool:", toolCall.toolName);
629
+ return;
630
+ }
631
+ this.log("Executing tool:", toolCall.toolName);
632
+ try {
633
+ const result = await handler(toolCall.input);
634
+ await this.transport.send(createToolResultMessage(toolCall.callId, result));
635
+ } catch (error) {
636
+ const errorResult2 = {
637
+ content: [{ type: "text", text: error.message }],
638
+ isError: true
639
+ };
640
+ await this.transport.send(createToolResultMessage(toolCall.callId, errorResult2));
641
+ }
642
+ }
643
+ /**
644
+ * Log debug messages
645
+ */
646
+ log(...args) {
647
+ if (this.config.debug) {
648
+ console.log("[Session]", ...args);
649
+ }
650
+ }
651
+ };
652
+ function getAssistantText(msg) {
653
+ if (msg.type !== "assistant") return null;
654
+ return msg.message.content.filter((block) => block.type === "text").map((block) => block.text).join("");
655
+ }
656
+ function getResultText(msg) {
657
+ if (msg.type !== "result") return null;
658
+ const resultMsg = msg;
659
+ if (resultMsg.subtype === "success") {
660
+ return resultMsg.result;
661
+ }
662
+ return null;
663
+ }
664
+
665
+ // src/client/ChuckyClient.ts
666
+ var DEFAULT_BASE_URL = "wss://conjure.chucky.cloud/ws";
667
+ var ChuckyClient = class {
668
+ /**
669
+ * Create a new Chucky client
670
+ */
671
+ constructor(options) {
672
+ __publicField(this, "options");
673
+ __publicField(this, "eventHandlers", {});
674
+ __publicField(this, "activeSessions", /* @__PURE__ */ new Map());
675
+ this.options = {
676
+ baseUrl: DEFAULT_BASE_URL,
677
+ debug: false,
678
+ ...options
679
+ };
680
+ }
681
+ /**
682
+ * Set event handlers
683
+ */
684
+ on(handlers) {
685
+ this.eventHandlers = { ...this.eventHandlers, ...handlers };
686
+ return this;
687
+ }
688
+ /**
689
+ * Create a new session
690
+ *
691
+ * Matches V2 SDK: createSession() returns a Session immediately.
692
+ * Connection happens automatically on first send().
693
+ *
694
+ * @param options - Session configuration options
695
+ * @returns A new session instance
696
+ *
697
+ * @example
698
+ * ```typescript
699
+ * const session = client.createSession({
700
+ * model: 'claude-sonnet-4-5-20250929',
701
+ * systemPrompt: 'You are a helpful coding assistant.',
702
+ * });
703
+ *
704
+ * await session.send('Hello!');
705
+ * for await (const msg of session.stream()) {
706
+ * // Handle messages
707
+ * }
708
+ * ```
709
+ */
710
+ createSession(options = {}) {
711
+ const transport = this.createTransport();
712
+ const session = new Session(transport, options, {
713
+ debug: this.options.debug
714
+ });
715
+ session.on({
716
+ onSessionInfo: (info) => {
717
+ if (info.sessionId) {
718
+ this.activeSessions.set(info.sessionId, session);
719
+ }
720
+ }
721
+ });
722
+ return session;
723
+ }
724
+ /**
725
+ * Resume an existing session
726
+ *
727
+ * @param sessionId - The session ID to resume
728
+ * @param options - Additional session options
729
+ * @returns The resumed session
730
+ *
731
+ * @example
732
+ * ```typescript
733
+ * const session = client.resumeSession('session-123');
734
+ * await session.send('Continue our conversation');
735
+ * ```
736
+ */
737
+ resumeSession(sessionId, options = {}) {
738
+ return this.createSession({
739
+ ...options,
740
+ sessionId
741
+ });
742
+ }
743
+ /**
744
+ * Execute a one-shot prompt (stateless)
745
+ *
746
+ * Supports two call signatures:
747
+ * - `prompt('message', { model: '...' })` - positional style
748
+ * - `prompt({ message: '...', model: '...' })` - object style
749
+ *
750
+ * @param messageOrOptions - The message string OR an options object with message
751
+ * @param options - Prompt configuration (only used with positional style)
752
+ * @returns The result message
753
+ *
754
+ * @example
755
+ * ```typescript
756
+ * // Positional style
757
+ * const result = await client.prompt(
758
+ * 'Explain quantum computing in simple terms',
759
+ * { model: 'claude-sonnet-4-5-20250929' }
760
+ * );
761
+ *
762
+ * // Object style
763
+ * const result = await client.prompt({
764
+ * message: 'Explain quantum computing in simple terms',
765
+ * model: 'claude-sonnet-4-5-20250929',
766
+ * });
767
+ *
768
+ * if (result.subtype === 'success') {
769
+ * console.log(result.result);
770
+ * }
771
+ * ```
772
+ */
773
+ async prompt(messageOrOptions, options = {}) {
774
+ let message;
775
+ let sessionOptions;
776
+ if (typeof messageOrOptions === "object") {
777
+ const { message: msg, ...rest } = messageOrOptions;
778
+ message = msg;
779
+ sessionOptions = rest;
780
+ } else {
781
+ message = messageOrOptions;
782
+ sessionOptions = options;
783
+ }
784
+ const session = this.createSession(sessionOptions);
785
+ try {
786
+ await session.send(message);
787
+ let result = null;
788
+ for await (const msg of session.stream()) {
789
+ if (msg.type === "result") {
790
+ result = msg;
791
+ break;
792
+ }
793
+ }
794
+ if (!result) {
795
+ throw new Error("No result message received");
796
+ }
797
+ return result;
798
+ } finally {
799
+ session.close();
800
+ }
801
+ }
802
+ /**
803
+ * Close all active sessions and disconnect
804
+ */
805
+ close() {
806
+ for (const session of this.activeSessions.values()) {
807
+ session.close();
808
+ }
809
+ this.activeSessions.clear();
810
+ }
811
+ /**
812
+ * Create a new transport instance
813
+ */
814
+ createTransport() {
815
+ return new WebSocketTransport({
816
+ url: this.options.baseUrl,
817
+ token: this.options.token,
818
+ timeout: this.options.timeout,
819
+ keepAliveInterval: this.options.keepAliveInterval,
820
+ autoReconnect: this.options.autoReconnect,
821
+ maxReconnectAttempts: this.options.maxReconnectAttempts,
822
+ debug: this.options.debug
823
+ });
824
+ }
825
+ };
826
+ function createClient(options) {
827
+ return new ChuckyClient(options);
828
+ }
829
+
830
+ // src/tools/tool.ts
831
+ function isZodSchema(schema) {
832
+ return typeof schema === "object" && schema !== null && ("_def" in schema || "shape" in schema);
833
+ }
834
+ function zodToJsonSchema(zodSchema) {
835
+ const def = zodSchema._def;
836
+ if (!def) {
837
+ return {
838
+ type: "object",
839
+ properties: {}
840
+ };
841
+ }
842
+ const typeName = def.typeName;
843
+ if (typeName === "ZodObject") {
844
+ const shape = def.shape?.() || {};
845
+ const properties = {};
846
+ const required = [];
847
+ for (const [key, value] of Object.entries(shape)) {
848
+ const valueDef = value._def;
849
+ if (valueDef) {
850
+ const prop = zodDefToJsonSchema(valueDef);
851
+ if (prop) {
852
+ properties[key] = prop;
853
+ if (valueDef.typeName !== "ZodOptional") {
854
+ required.push(key);
855
+ }
856
+ }
857
+ }
858
+ }
859
+ return {
860
+ type: "object",
861
+ properties,
862
+ required: required.length > 0 ? required : void 0
863
+ };
864
+ }
865
+ return {
866
+ type: "object",
867
+ properties: {}
868
+ };
869
+ }
870
+ function zodDefToJsonSchema(def) {
871
+ const typeName = def.typeName;
872
+ switch (typeName) {
873
+ case "ZodString":
874
+ return { type: "string", description: def.description };
875
+ case "ZodNumber":
876
+ return { type: "number", description: def.description };
877
+ case "ZodBoolean":
878
+ return { type: "boolean", description: def.description };
879
+ case "ZodArray":
880
+ const innerDef = def.innerType?._def;
881
+ return {
882
+ type: "array",
883
+ description: def.description,
884
+ items: innerDef ? zodDefToJsonSchema(innerDef) || { type: "string" } : { type: "string" }
885
+ };
886
+ case "ZodEnum":
887
+ return {
888
+ type: "string",
889
+ description: def.description,
890
+ enum: def.values
891
+ };
892
+ case "ZodOptional":
893
+ const innerOptDef = def.innerType?._def;
894
+ return innerOptDef ? zodDefToJsonSchema(innerOptDef) : null;
895
+ default:
896
+ return { type: "string" };
897
+ }
898
+ }
899
+ function createTool(options) {
900
+ let inputSchema;
901
+ if (isZodSchema(options.inputSchema)) {
902
+ inputSchema = zodToJsonSchema(options.inputSchema);
903
+ } else {
904
+ inputSchema = options.inputSchema;
905
+ }
906
+ return {
907
+ name: options.name,
908
+ description: options.description,
909
+ inputSchema,
910
+ executeIn: options.executeIn ?? "server",
911
+ handler: options.handler
912
+ };
913
+ }
914
+ function tool(name, description, inputSchema, handler) {
915
+ return createTool({ name, description, inputSchema, handler });
916
+ }
917
+ function browserTool(options) {
918
+ return createTool({ ...options, executeIn: "browser" });
919
+ }
920
+ function serverTool(options) {
921
+ return createTool({ ...options, executeIn: "server" });
922
+ }
923
+ function textResult(text) {
924
+ return {
925
+ content: [{ type: "text", text }]
926
+ };
927
+ }
928
+ function errorResult(message) {
929
+ return {
930
+ content: [{ type: "text", text: message }],
931
+ isError: true
932
+ };
933
+ }
934
+ function imageResult(data, mimeType) {
935
+ return {
936
+ content: [{ type: "image", data, mimeType }]
937
+ };
938
+ }
939
+
940
+ // src/tools/McpServer.ts
941
+ var McpServerBuilder = class {
942
+ /**
943
+ * Create a new MCP server builder
944
+ *
945
+ * @param name - Server name
946
+ * @param version - Server version (default: '1.0.0')
947
+ */
948
+ constructor(name, version = "1.0.0") {
949
+ __publicField(this, "name");
950
+ __publicField(this, "version");
951
+ __publicField(this, "tools", []);
952
+ this.name = name;
953
+ this.version = version;
954
+ }
955
+ /**
956
+ * Add a tool to the server
957
+ *
958
+ * @param options - Tool configuration
959
+ * @returns This builder for chaining
960
+ */
961
+ addTool(options) {
962
+ this.tools.push(createTool(options));
963
+ return this;
964
+ }
965
+ /**
966
+ * Add an existing tool definition
967
+ *
968
+ * @param tool - Tool definition
969
+ * @returns This builder for chaining
970
+ */
971
+ add(tool2) {
972
+ this.tools.push(tool2);
973
+ return this;
974
+ }
975
+ /**
976
+ * Add multiple tools at once
977
+ *
978
+ * @param tools - Array of tool definitions
979
+ * @returns This builder for chaining
980
+ */
981
+ addTools(tools) {
982
+ this.tools.push(...tools);
983
+ return this;
984
+ }
985
+ /**
986
+ * Build the MCP server definition
987
+ *
988
+ * @returns Complete MCP server definition
989
+ */
990
+ build() {
991
+ return {
992
+ name: this.name,
993
+ version: this.version,
994
+ tools: this.tools
995
+ };
996
+ }
997
+ };
998
+ function createMcpServer(name, tools, version = "1.0.0") {
999
+ return {
1000
+ name,
1001
+ version,
1002
+ tools
1003
+ };
1004
+ }
1005
+ function mcpServer(name, version) {
1006
+ return new McpServerBuilder(name, version);
1007
+ }
1008
+
1009
+ // src/utils/token.ts
1010
+ function base64UrlEncode(data) {
1011
+ let base64;
1012
+ if (typeof data === "string") {
1013
+ const bytes = new TextEncoder().encode(data);
1014
+ base64 = btoa(String.fromCharCode(...bytes));
1015
+ } else {
1016
+ base64 = btoa(String.fromCharCode(...data));
1017
+ }
1018
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
1019
+ }
1020
+ function base64UrlDecode(str) {
1021
+ const base64 = str.replace(/-/g, "+").replace(/_/g, "/");
1022
+ const padding = "=".repeat((4 - base64.length % 4) % 4);
1023
+ const bytes = atob(base64 + padding);
1024
+ return bytes;
1025
+ }
1026
+ async function getCrypto() {
1027
+ if (typeof crypto !== "undefined" && crypto.subtle) {
1028
+ return crypto;
1029
+ }
1030
+ const nodeCrypto = await import("crypto");
1031
+ return nodeCrypto.webcrypto;
1032
+ }
1033
+ async function createHmacSignature(secret, data) {
1034
+ const { subtle } = await getCrypto();
1035
+ const keyData = new TextEncoder().encode(secret);
1036
+ const key = await subtle.importKey(
1037
+ "raw",
1038
+ keyData,
1039
+ { name: "HMAC", hash: "SHA-256" },
1040
+ false,
1041
+ ["sign"]
1042
+ );
1043
+ const signature = await subtle.sign("HMAC", key, new TextEncoder().encode(data));
1044
+ return base64UrlEncode(new Uint8Array(signature));
1045
+ }
1046
+ async function verifyHmacSignature(secret, data, signature) {
1047
+ const expectedSignature = await createHmacSignature(secret, data);
1048
+ return signature === expectedSignature;
1049
+ }
1050
+ async function createToken(options) {
1051
+ const {
1052
+ userId,
1053
+ projectId,
1054
+ secret,
1055
+ expiresIn = 3600,
1056
+ budget,
1057
+ permissions,
1058
+ sdkConfig
1059
+ } = options;
1060
+ const now = Math.floor(Date.now() / 1e3);
1061
+ const payload = {
1062
+ sub: userId,
1063
+ iss: projectId,
1064
+ iat: now,
1065
+ exp: now + expiresIn,
1066
+ budget,
1067
+ ...permissions && { permissions },
1068
+ ...sdkConfig && { sdkConfig }
1069
+ };
1070
+ const header = {
1071
+ alg: "HS256",
1072
+ typ: "JWT"
1073
+ };
1074
+ const encodedHeader = base64UrlEncode(JSON.stringify(header));
1075
+ const encodedPayload = base64UrlEncode(JSON.stringify(payload));
1076
+ const signatureInput = `${encodedHeader}.${encodedPayload}`;
1077
+ const signature = await createHmacSignature(secret, signatureInput);
1078
+ return `${encodedHeader}.${encodedPayload}.${signature}`;
1079
+ }
1080
+ function decodeToken(token) {
1081
+ const parts = token.split(".");
1082
+ if (parts.length !== 3) {
1083
+ throw new Error("Invalid token format");
1084
+ }
1085
+ const [encodedHeader, encodedPayload, signature] = parts;
1086
+ const header = JSON.parse(base64UrlDecode(encodedHeader));
1087
+ const payload = JSON.parse(base64UrlDecode(encodedPayload));
1088
+ return { header, payload, signature };
1089
+ }
1090
+ async function verifyToken(token, secret) {
1091
+ const parts = token.split(".");
1092
+ if (parts.length !== 3) {
1093
+ return false;
1094
+ }
1095
+ const [encodedHeader, encodedPayload, signature] = parts;
1096
+ const signatureInput = `${encodedHeader}.${encodedPayload}`;
1097
+ return verifyHmacSignature(secret, signatureInput, signature);
1098
+ }
1099
+ function isTokenExpired(token) {
1100
+ try {
1101
+ const decoded = decodeToken(token);
1102
+ const now = Math.floor(Date.now() / 1e3);
1103
+ return decoded.payload.exp < now;
1104
+ } catch {
1105
+ return true;
1106
+ }
1107
+ }
1108
+ function extractProjectId(_hmacKey) {
1109
+ throw new Error(
1110
+ "extractProjectId() is deprecated. The project ID is now separate from the HMAC key for security. Get your project ID from the Chucky portal (app.chucky.cloud) in your project settings."
1111
+ );
1112
+ }
1113
+ function createBudget(options) {
1114
+ return {
1115
+ ai: Math.floor(options.aiDollars * 1e6),
1116
+ // Convert to microdollars
1117
+ compute: Math.floor(options.computeHours * 3600),
1118
+ // Convert to seconds
1119
+ window: options.window,
1120
+ windowStart: (options.windowStart || /* @__PURE__ */ new Date()).toISOString()
1121
+ };
1122
+ }
1123
+
1124
+ // src/utils/errors.ts
1125
+ var ChuckyError = class _ChuckyError extends Error {
1126
+ constructor(message, code, details) {
1127
+ super(message);
1128
+ /** Error code */
1129
+ __publicField(this, "code");
1130
+ /** Additional error details */
1131
+ __publicField(this, "details");
1132
+ this.name = "ChuckyError";
1133
+ this.code = code;
1134
+ this.details = details;
1135
+ if (Error.captureStackTrace) {
1136
+ Error.captureStackTrace(this, _ChuckyError);
1137
+ }
1138
+ }
1139
+ };
1140
+ var ConnectionError = class extends ChuckyError {
1141
+ constructor(message, details) {
1142
+ super(message, "CONNECTION_ERROR", details);
1143
+ this.name = "ConnectionError";
1144
+ }
1145
+ };
1146
+ var AuthenticationError = class extends ChuckyError {
1147
+ constructor(message, details) {
1148
+ super(message, "AUTHENTICATION_ERROR", details);
1149
+ this.name = "AuthenticationError";
1150
+ }
1151
+ };
1152
+ var BudgetExceededError = class extends ChuckyError {
1153
+ constructor(message, details) {
1154
+ super(message, "BUDGET_EXCEEDED", details);
1155
+ this.name = "BudgetExceededError";
1156
+ }
1157
+ };
1158
+ var ConcurrencyLimitError = class extends ChuckyError {
1159
+ constructor(message, details) {
1160
+ super(message, "CONCURRENCY_LIMIT", details);
1161
+ this.name = "ConcurrencyLimitError";
1162
+ }
1163
+ };
1164
+ var RateLimitError = class extends ChuckyError {
1165
+ constructor(message, details) {
1166
+ super(message, "RATE_LIMIT", details);
1167
+ this.name = "RateLimitError";
1168
+ }
1169
+ };
1170
+ var SessionError = class extends ChuckyError {
1171
+ constructor(message, details) {
1172
+ super(message, "SESSION_ERROR", details);
1173
+ this.name = "SessionError";
1174
+ }
1175
+ };
1176
+ var ToolExecutionError = class extends ChuckyError {
1177
+ constructor(message, toolName, details) {
1178
+ super(message, "TOOL_EXECUTION_ERROR", { ...details, toolName });
1179
+ /** Tool name */
1180
+ __publicField(this, "toolName");
1181
+ this.name = "ToolExecutionError";
1182
+ this.toolName = toolName;
1183
+ }
1184
+ };
1185
+ var TimeoutError = class extends ChuckyError {
1186
+ constructor(message, details) {
1187
+ super(message, "TIMEOUT", details);
1188
+ this.name = "TimeoutError";
1189
+ }
1190
+ };
1191
+ var ValidationError = class extends ChuckyError {
1192
+ constructor(message, details) {
1193
+ super(message, "VALIDATION_ERROR", details);
1194
+ this.name = "ValidationError";
1195
+ }
1196
+ };
1197
+ function parseErrorCode(message) {
1198
+ const patterns = [
1199
+ { pattern: /budget.*exceed/i, code: "BUDGET_EXCEEDED" },
1200
+ { pattern: /concurrency.*limit/i, code: "CONCURRENCY_LIMIT" },
1201
+ { pattern: /rate.*limit/i, code: "RATE_LIMIT" },
1202
+ { pattern: /auth|unauthorized|forbidden/i, code: "AUTHENTICATION_ERROR" },
1203
+ { pattern: /timeout/i, code: "TIMEOUT" },
1204
+ { pattern: /connect|disconnect|websocket/i, code: "CONNECTION_ERROR" },
1205
+ { pattern: /session/i, code: "SESSION_ERROR" },
1206
+ { pattern: /tool/i, code: "TOOL_EXECUTION_ERROR" },
1207
+ { pattern: /invalid|validation/i, code: "VALIDATION_ERROR" }
1208
+ ];
1209
+ for (const { pattern, code } of patterns) {
1210
+ if (pattern.test(message)) {
1211
+ return code;
1212
+ }
1213
+ }
1214
+ return null;
1215
+ }
1216
+ function createError(message, code) {
1217
+ const errorCode = code || parseErrorCode(message) || "UNKNOWN_ERROR";
1218
+ switch (errorCode) {
1219
+ case "CONNECTION_ERROR":
1220
+ return new ConnectionError(message);
1221
+ case "AUTHENTICATION_ERROR":
1222
+ return new AuthenticationError(message);
1223
+ case "BUDGET_EXCEEDED":
1224
+ return new BudgetExceededError(message);
1225
+ case "CONCURRENCY_LIMIT":
1226
+ return new ConcurrencyLimitError(message);
1227
+ case "RATE_LIMIT":
1228
+ return new RateLimitError(message);
1229
+ case "SESSION_ERROR":
1230
+ return new SessionError(message);
1231
+ case "TIMEOUT":
1232
+ return new TimeoutError(message);
1233
+ case "VALIDATION_ERROR":
1234
+ return new ValidationError(message);
1235
+ default:
1236
+ return new ChuckyError(message, errorCode);
1237
+ }
1238
+ }
1239
+ export {
1240
+ AuthenticationError,
1241
+ BudgetExceededError,
1242
+ ChuckyClient,
1243
+ ChuckyError,
1244
+ ConcurrencyLimitError,
1245
+ ConnectionError,
1246
+ McpServerBuilder,
1247
+ RateLimitError,
1248
+ Session,
1249
+ SessionError,
1250
+ TimeoutError,
1251
+ ToolExecutionError,
1252
+ ValidationError,
1253
+ WebSocketTransport,
1254
+ browserTool,
1255
+ createBudget,
1256
+ createClient,
1257
+ createControlMessage,
1258
+ createError,
1259
+ createInitMessage,
1260
+ createMcpServer,
1261
+ createPingMessage,
1262
+ createToken,
1263
+ createTool,
1264
+ createToolResultMessage,
1265
+ createUserMessage,
1266
+ decodeToken,
1267
+ errorResult,
1268
+ extractProjectId,
1269
+ getAssistantText,
1270
+ getResultText,
1271
+ imageResult,
1272
+ isAssistantMessage,
1273
+ isControlMessage,
1274
+ isErrorMessage,
1275
+ isErrorResult,
1276
+ isResultMessage,
1277
+ isStreamEvent,
1278
+ isSuccessResult,
1279
+ isSystemMessage,
1280
+ isTokenExpired,
1281
+ isToolCallMessage,
1282
+ isUserMessage,
1283
+ mcpServer,
1284
+ serverTool,
1285
+ textResult,
1286
+ tool,
1287
+ verifyToken
1288
+ };
12
1289
  //# sourceMappingURL=browser.js.map