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