@gr33n-ai/jade-sdk-rn-client 0.1.0 → 0.1.2

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.
@@ -1,2795 +0,0 @@
1
- 'use strict';
2
-
3
- var react = require('react');
4
- var reactNative = require('react-native');
5
- var jsxRuntime = require('react/jsx-runtime');
6
-
7
- var __create = Object.create;
8
- var __defProp = Object.defineProperty;
9
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
10
- var __getOwnPropNames = Object.getOwnPropertyNames;
11
- var __getProtoOf = Object.getPrototypeOf;
12
- var __hasOwnProp = Object.prototype.hasOwnProperty;
13
- var __esm = (fn, res) => function __init() {
14
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
15
- };
16
- var __commonJS = (cb, mod) => function __require() {
17
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18
- };
19
- var __export = (target, all) => {
20
- for (var name in all)
21
- __defProp(target, name, { get: all[name], enumerable: true });
22
- };
23
- var __copyProps = (to, from, except, desc) => {
24
- if (from && typeof from === "object" || typeof from === "function") {
25
- for (let key of __getOwnPropNames(from))
26
- if (!__hasOwnProp.call(to, key) && key !== except)
27
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
28
- }
29
- return to;
30
- };
31
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
32
- // If the importer is in node compatibility mode or this is not an ESM
33
- // file that has been converted to a CommonJS file using a Babel-
34
- // compatible transform (i.e. "__esModule" has not been set), then set
35
- // "default" to the CommonJS "module.exports" for node compatibility.
36
- !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
37
- mod
38
- ));
39
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
40
-
41
- // ../../node_modules/.pnpm/react-native-sse@1.2.1/node_modules/react-native-sse/src/EventSource.js
42
- var EventSource_exports = {};
43
- __export(EventSource_exports, {
44
- default: () => EventSource_default
45
- });
46
- var XMLReadyStateMap, EventSource, EventSource_default;
47
- var init_EventSource = __esm({
48
- "../../node_modules/.pnpm/react-native-sse@1.2.1/node_modules/react-native-sse/src/EventSource.js"() {
49
- XMLReadyStateMap = [
50
- "UNSENT",
51
- "OPENED",
52
- "HEADERS_RECEIVED",
53
- "LOADING",
54
- "DONE"
55
- ];
56
- EventSource = class {
57
- ERROR = -1;
58
- CONNECTING = 0;
59
- OPEN = 1;
60
- CLOSED = 2;
61
- CRLF = "\r\n";
62
- LF = "\n";
63
- CR = "\r";
64
- constructor(url, options = {}) {
65
- this.lastEventId = null;
66
- this.status = this.CONNECTING;
67
- this.eventHandlers = {
68
- open: [],
69
- message: [],
70
- error: [],
71
- close: []
72
- };
73
- this.method = options.method || "GET";
74
- this.timeout = options.timeout ?? 0;
75
- this.timeoutBeforeConnection = options.timeoutBeforeConnection ?? 500;
76
- this.withCredentials = options.withCredentials || false;
77
- this.headers = options.headers || {};
78
- this.body = options.body || void 0;
79
- this.debug = options.debug || false;
80
- this.interval = options.pollingInterval ?? 5e3;
81
- this.lineEndingCharacter = options.lineEndingCharacter || null;
82
- this._xhr = null;
83
- this._pollTimer = null;
84
- this._lastIndexProcessed = 0;
85
- if (!url || typeof url !== "string" && typeof url.toString !== "function") {
86
- throw new SyntaxError("[EventSource] Invalid URL argument.");
87
- }
88
- if (typeof url.toString === "function") {
89
- this.url = url.toString();
90
- } else {
91
- this.url = url;
92
- }
93
- this._pollAgain(this.timeoutBeforeConnection, true);
94
- }
95
- _pollAgain(time, allowZero) {
96
- if (time > 0 || allowZero) {
97
- this._logDebug(`[EventSource] Will open new connection in ${time} ms.`);
98
- this._pollTimer = setTimeout(() => {
99
- this.open();
100
- }, time);
101
- }
102
- }
103
- open() {
104
- try {
105
- this.status = this.CONNECTING;
106
- this._lastIndexProcessed = 0;
107
- this._xhr = new XMLHttpRequest();
108
- this._xhr.open(this.method, this.url, true);
109
- if (this.withCredentials) {
110
- this._xhr.withCredentials = true;
111
- }
112
- this._xhr.setRequestHeader("Accept", "text/event-stream");
113
- this._xhr.setRequestHeader("Cache-Control", "no-cache");
114
- this._xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
115
- if (this.headers) {
116
- for (const [key, value] of Object.entries(this.headers)) {
117
- this._xhr.setRequestHeader(key, value);
118
- }
119
- }
120
- if (this.lastEventId !== null) {
121
- this._xhr.setRequestHeader("Last-Event-ID", this.lastEventId);
122
- }
123
- this._xhr.timeout = this.timeout;
124
- this._xhr.onreadystatechange = () => {
125
- if (this.status === this.CLOSED) {
126
- return;
127
- }
128
- const xhr = this._xhr;
129
- this._logDebug(`[EventSource][onreadystatechange] ReadyState: ${XMLReadyStateMap[xhr.readyState] || "Unknown"}(${xhr.readyState}), status: ${xhr.status}`);
130
- if (![XMLHttpRequest.DONE, XMLHttpRequest.LOADING].includes(xhr.readyState)) {
131
- return;
132
- }
133
- if (xhr.status >= 200 && xhr.status < 400) {
134
- if (this.status === this.CONNECTING) {
135
- this.status = this.OPEN;
136
- this.dispatch("open", { type: "open" });
137
- this._logDebug("[EventSource][onreadystatechange][OPEN] Connection opened.");
138
- }
139
- this._handleEvent(xhr.responseText || "");
140
- if (xhr.readyState === XMLHttpRequest.DONE) {
141
- this._logDebug("[EventSource][onreadystatechange][DONE] Operation done.");
142
- this._pollAgain(this.interval, false);
143
- }
144
- } else if (xhr.status !== 0) {
145
- this.status = this.ERROR;
146
- this.dispatch("error", {
147
- type: "error",
148
- message: xhr.responseText,
149
- xhrStatus: xhr.status,
150
- xhrState: xhr.readyState
151
- });
152
- if (xhr.readyState === XMLHttpRequest.DONE) {
153
- this._logDebug("[EventSource][onreadystatechange][ERROR] Response status error.");
154
- this._pollAgain(this.interval, false);
155
- }
156
- }
157
- };
158
- this._xhr.onerror = () => {
159
- if (this.status === this.CLOSED) {
160
- return;
161
- }
162
- this.status = this.ERROR;
163
- this.dispatch("error", {
164
- type: "error",
165
- message: this._xhr.responseText,
166
- xhrStatus: this._xhr.status,
167
- xhrState: this._xhr.readyState
168
- });
169
- };
170
- if (this.body) {
171
- this._xhr.send(this.body);
172
- } else {
173
- this._xhr.send();
174
- }
175
- if (this.timeout > 0) {
176
- setTimeout(() => {
177
- if (this._xhr.readyState === XMLHttpRequest.LOADING) {
178
- this.dispatch("error", { type: "timeout" });
179
- this.close();
180
- }
181
- }, this.timeout);
182
- }
183
- } catch (e) {
184
- this.status = this.ERROR;
185
- this.dispatch("error", {
186
- type: "exception",
187
- message: e.message,
188
- error: e
189
- });
190
- }
191
- }
192
- _logDebug(...msg) {
193
- if (this.debug) {
194
- console.debug(...msg);
195
- }
196
- }
197
- _handleEvent(response) {
198
- if (this.lineEndingCharacter === null) {
199
- const detectedNewlineChar = this._detectNewlineChar(response);
200
- if (detectedNewlineChar !== null) {
201
- this._logDebug(`[EventSource] Automatically detected lineEndingCharacter: ${JSON.stringify(detectedNewlineChar).slice(1, -1)}`);
202
- this.lineEndingCharacter = detectedNewlineChar;
203
- } else {
204
- console.warn("[EventSource] Unable to identify the line ending character. Ensure your server delivers a standard line ending character: \\r\\n, \\n, \\r, or specify your custom character using the 'lineEndingCharacter' option.");
205
- return;
206
- }
207
- }
208
- const indexOfDoubleNewline = this._getLastDoubleNewlineIndex(response);
209
- if (indexOfDoubleNewline <= this._lastIndexProcessed) {
210
- return;
211
- }
212
- const parts = response.substring(this._lastIndexProcessed, indexOfDoubleNewline).split(this.lineEndingCharacter);
213
- this._lastIndexProcessed = indexOfDoubleNewline;
214
- let type = void 0;
215
- let id = null;
216
- let data = [];
217
- let retry = 0;
218
- let line = "";
219
- for (let i = 0; i < parts.length; i++) {
220
- line = parts[i].trim();
221
- if (line.startsWith("event")) {
222
- type = line.replace(/event:?\s*/, "");
223
- } else if (line.startsWith("retry")) {
224
- retry = parseInt(line.replace(/retry:?\s*/, ""), 10);
225
- if (!isNaN(retry)) {
226
- this.interval = retry;
227
- }
228
- } else if (line.startsWith("data")) {
229
- data.push(line.replace(/data:?\s*/, ""));
230
- } else if (line.startsWith("id")) {
231
- id = line.replace(/id:?\s*/, "");
232
- if (id !== "") {
233
- this.lastEventId = id;
234
- } else {
235
- this.lastEventId = null;
236
- }
237
- } else if (line === "") {
238
- if (data.length > 0) {
239
- const eventType = type || "message";
240
- const event = {
241
- type: eventType,
242
- data: data.join("\n"),
243
- url: this.url,
244
- lastEventId: this.lastEventId
245
- };
246
- this.dispatch(eventType, event);
247
- data = [];
248
- type = void 0;
249
- }
250
- }
251
- }
252
- }
253
- _detectNewlineChar(response) {
254
- const supportedLineEndings = [this.CRLF, this.LF, this.CR];
255
- for (const char of supportedLineEndings) {
256
- if (response.includes(char)) {
257
- return char;
258
- }
259
- }
260
- return null;
261
- }
262
- _getLastDoubleNewlineIndex(response) {
263
- const doubleLineEndingCharacter = this.lineEndingCharacter + this.lineEndingCharacter;
264
- const lastIndex = response.lastIndexOf(doubleLineEndingCharacter);
265
- if (lastIndex === -1) {
266
- return -1;
267
- }
268
- return lastIndex + doubleLineEndingCharacter.length;
269
- }
270
- addEventListener(type, listener) {
271
- if (this.eventHandlers[type] === void 0) {
272
- this.eventHandlers[type] = [];
273
- }
274
- this.eventHandlers[type].push(listener);
275
- }
276
- removeEventListener(type, listener) {
277
- if (this.eventHandlers[type] !== void 0) {
278
- this.eventHandlers[type] = this.eventHandlers[type].filter((handler) => handler !== listener);
279
- }
280
- }
281
- removeAllEventListeners(type) {
282
- const availableTypes = Object.keys(this.eventHandlers);
283
- if (type === void 0) {
284
- for (const eventType of availableTypes) {
285
- this.eventHandlers[eventType] = [];
286
- }
287
- } else {
288
- if (!availableTypes.includes(type)) {
289
- throw Error(`[EventSource] '${type}' type is not supported event type.`);
290
- }
291
- this.eventHandlers[type] = [];
292
- }
293
- }
294
- dispatch(type, data) {
295
- const availableTypes = Object.keys(this.eventHandlers);
296
- if (!availableTypes.includes(type)) {
297
- return;
298
- }
299
- for (const handler of Object.values(this.eventHandlers[type])) {
300
- handler(data);
301
- }
302
- }
303
- close() {
304
- if (this.status !== this.CLOSED) {
305
- this.status = this.CLOSED;
306
- this.dispatch("close", { type: "close" });
307
- }
308
- clearTimeout(this._pollTimer);
309
- if (this._xhr) {
310
- this._xhr.abort();
311
- }
312
- }
313
- };
314
- EventSource_default = EventSource;
315
- }
316
- });
317
-
318
- // ../../node_modules/.pnpm/react-native-sse@1.2.1/node_modules/react-native-sse/index.js
319
- var require_react_native_sse = __commonJS({
320
- "../../node_modules/.pnpm/react-native-sse@1.2.1/node_modules/react-native-sse/index.js"(exports$1, module) {
321
- var EventSource3 = (init_EventSource(), __toCommonJS(EventSource_exports));
322
- module.exports = EventSource3;
323
- }
324
- });
325
-
326
- // ../ts-client/dist/index.js
327
- async function getBytes(stream, onChunk) {
328
- const reader = stream.getReader();
329
- let result;
330
- while (!(result = await reader.read()).done) {
331
- onChunk(result.value);
332
- }
333
- }
334
- function getLines(onLine) {
335
- let buffer;
336
- let position;
337
- let fieldLength;
338
- let discardTrailingNewline = false;
339
- return function onChunk(arr) {
340
- if (buffer === void 0) {
341
- buffer = arr;
342
- position = 0;
343
- fieldLength = -1;
344
- } else {
345
- buffer = concat(buffer, arr);
346
- }
347
- const bufLength = buffer.length;
348
- let lineStart = 0;
349
- while (position < bufLength) {
350
- if (discardTrailingNewline) {
351
- if (buffer[position] === 10) {
352
- lineStart = ++position;
353
- }
354
- discardTrailingNewline = false;
355
- }
356
- let lineEnd = -1;
357
- for (; position < bufLength && lineEnd === -1; ++position) {
358
- switch (buffer[position]) {
359
- case 58:
360
- if (fieldLength === -1) {
361
- fieldLength = position - lineStart;
362
- }
363
- break;
364
- case 13:
365
- discardTrailingNewline = true;
366
- case 10:
367
- lineEnd = position;
368
- break;
369
- }
370
- }
371
- if (lineEnd === -1) {
372
- break;
373
- }
374
- onLine(buffer.subarray(lineStart, lineEnd), fieldLength);
375
- lineStart = position;
376
- fieldLength = -1;
377
- }
378
- if (lineStart === bufLength) {
379
- buffer = void 0;
380
- } else if (lineStart !== 0) {
381
- buffer = buffer.subarray(lineStart);
382
- position -= lineStart;
383
- }
384
- };
385
- }
386
- function getMessages(onId, onRetry, onMessage) {
387
- let message = newMessage();
388
- const decoder = new TextDecoder();
389
- return function onLine(line, fieldLength) {
390
- if (line.length === 0) {
391
- onMessage === null || onMessage === void 0 ? void 0 : onMessage(message);
392
- message = newMessage();
393
- } else if (fieldLength > 0) {
394
- const field = decoder.decode(line.subarray(0, fieldLength));
395
- const valueOffset = fieldLength + (line[fieldLength + 1] === 32 ? 2 : 1);
396
- const value = decoder.decode(line.subarray(valueOffset));
397
- switch (field) {
398
- case "data":
399
- message.data = message.data ? message.data + "\n" + value : value;
400
- break;
401
- case "event":
402
- message.event = value;
403
- break;
404
- case "id":
405
- onId(message.id = value);
406
- break;
407
- case "retry":
408
- const retry = parseInt(value, 10);
409
- if (!isNaN(retry)) {
410
- onRetry(message.retry = retry);
411
- }
412
- break;
413
- }
414
- }
415
- };
416
- }
417
- function concat(a, b) {
418
- const res = new Uint8Array(a.length + b.length);
419
- res.set(a);
420
- res.set(b, a.length);
421
- return res;
422
- }
423
- function newMessage() {
424
- return {
425
- data: "",
426
- event: "",
427
- id: "",
428
- retry: void 0
429
- };
430
- }
431
- var __rest = function(s, e) {
432
- var t = {};
433
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
434
- t[p] = s[p];
435
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
436
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
437
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
438
- t[p[i]] = s[p[i]];
439
- }
440
- return t;
441
- };
442
- var EventStreamContentType = "text/event-stream";
443
- var DefaultRetryInterval = 1e3;
444
- var LastEventId = "last-event-id";
445
- function fetchEventSource(input, _a) {
446
- var { signal: inputSignal, headers: inputHeaders, onopen: inputOnOpen, onmessage, onclose, onerror, openWhenHidden, fetch: inputFetch } = _a, rest = __rest(_a, ["signal", "headers", "onopen", "onmessage", "onclose", "onerror", "openWhenHidden", "fetch"]);
447
- return new Promise((resolve, reject) => {
448
- const headers = Object.assign({}, inputHeaders);
449
- if (!headers.accept) {
450
- headers.accept = EventStreamContentType;
451
- }
452
- let curRequestController;
453
- function onVisibilityChange() {
454
- curRequestController.abort();
455
- if (!document.hidden) {
456
- create();
457
- }
458
- }
459
- if (!openWhenHidden) {
460
- document.addEventListener("visibilitychange", onVisibilityChange);
461
- }
462
- let retryInterval = DefaultRetryInterval;
463
- let retryTimer = 0;
464
- function dispose() {
465
- document.removeEventListener("visibilitychange", onVisibilityChange);
466
- window.clearTimeout(retryTimer);
467
- curRequestController.abort();
468
- }
469
- inputSignal === null || inputSignal === void 0 ? void 0 : inputSignal.addEventListener("abort", () => {
470
- dispose();
471
- resolve();
472
- });
473
- const fetch2 = inputFetch !== null && inputFetch !== void 0 ? inputFetch : window.fetch;
474
- const onopen = inputOnOpen !== null && inputOnOpen !== void 0 ? inputOnOpen : defaultOnOpen;
475
- async function create() {
476
- var _a2;
477
- curRequestController = new AbortController();
478
- try {
479
- const response = await fetch2(input, Object.assign(Object.assign({}, rest), { headers, signal: curRequestController.signal }));
480
- await onopen(response);
481
- await getBytes(response.body, getLines(getMessages((id) => {
482
- if (id) {
483
- headers[LastEventId] = id;
484
- } else {
485
- delete headers[LastEventId];
486
- }
487
- }, (retry) => {
488
- retryInterval = retry;
489
- }, onmessage)));
490
- onclose === null || onclose === void 0 ? void 0 : onclose();
491
- dispose();
492
- resolve();
493
- } catch (err) {
494
- if (!curRequestController.signal.aborted) {
495
- try {
496
- const interval = (_a2 = onerror === null || onerror === void 0 ? void 0 : onerror(err)) !== null && _a2 !== void 0 ? _a2 : retryInterval;
497
- window.clearTimeout(retryTimer);
498
- retryTimer = window.setTimeout(create, interval);
499
- } catch (innerErr) {
500
- dispose();
501
- reject(innerErr);
502
- }
503
- }
504
- }
505
- }
506
- create();
507
- });
508
- }
509
- function defaultOnOpen(response) {
510
- const contentType = response.headers.get("content-type");
511
- if (!(contentType === null || contentType === void 0 ? void 0 : contentType.startsWith(EventStreamContentType))) {
512
- throw new Error(`Expected content-type to be ${EventStreamContentType}, Actual: ${contentType}`);
513
- }
514
- }
515
- var AgentEventEmitter = class {
516
- constructor() {
517
- this.handlers = /* @__PURE__ */ new Map();
518
- }
519
- /**
520
- * Subscribe to an event.
521
- * @returns Unsubscribe function
522
- */
523
- on(event, handler) {
524
- if (!this.handlers.has(event)) {
525
- this.handlers.set(event, /* @__PURE__ */ new Set());
526
- }
527
- this.handlers.get(event).add(handler);
528
- return () => this.off(event, handler);
529
- }
530
- /**
531
- * Unsubscribe from an event.
532
- */
533
- off(event, handler) {
534
- this.handlers.get(event)?.delete(handler);
535
- }
536
- /**
537
- * Emit an event to all handlers.
538
- */
539
- emit(event, data) {
540
- this.handlers.get(event)?.forEach((handler) => {
541
- try {
542
- handler(data);
543
- } catch (err) {
544
- console.error(`[AgentEventEmitter] Error in ${event} handler:`, err);
545
- }
546
- });
547
- }
548
- /**
549
- * Remove all event handlers.
550
- */
551
- removeAllListeners() {
552
- this.handlers.clear();
553
- }
554
- };
555
- var AgentClientError = class extends Error {
556
- constructor(message, cause) {
557
- super(message);
558
- this.cause = cause;
559
- this.name = "AgentClientError";
560
- }
561
- };
562
- var AuthenticationError = class extends AgentClientError {
563
- constructor(message = "Authentication failed") {
564
- super(message);
565
- this.name = "AuthenticationError";
566
- }
567
- };
568
- var SessionNotFoundError = class extends AgentClientError {
569
- constructor(sessionId) {
570
- super(`Session not found: ${sessionId}`);
571
- this.sessionId = sessionId;
572
- this.name = "SessionNotFoundError";
573
- }
574
- };
575
- var SkillNotFoundError = class extends AgentClientError {
576
- constructor(skillName) {
577
- super(`Skill not found: ${skillName}`);
578
- this.skillName = skillName;
579
- this.name = "SkillNotFoundError";
580
- }
581
- };
582
- var RequestError = class extends AgentClientError {
583
- constructor(message, statusCode) {
584
- super(message);
585
- this.statusCode = statusCode;
586
- this.name = "RequestError";
587
- }
588
- };
589
- var FatalSSEError = class extends Error {
590
- constructor(message) {
591
- super(message);
592
- this.name = "FatalSSEError";
593
- }
594
- };
595
- var MAX_RETRIES = 5;
596
- var INITIAL_RETRY_DELAY = 1e3;
597
- var MAX_RETRY_DELAY = 1e4;
598
- async function createSSEStream(options) {
599
- const {
600
- url,
601
- method,
602
- headers,
603
- body,
604
- emitter,
605
- signal,
606
- onOpen,
607
- onClose,
608
- lastEventId
609
- } = options;
610
- const processedIds = /* @__PURE__ */ new Set();
611
- let retryCount = 0;
612
- try {
613
- await fetchEventSource(url, {
614
- method,
615
- headers: {
616
- "Content-Type": "application/json",
617
- ...lastEventId ? { "Last-Event-ID": lastEventId } : {},
618
- ...headers
619
- },
620
- body: JSON.stringify(body),
621
- signal,
622
- async onopen(response) {
623
- if (response.ok && response.headers.get("content-type")?.includes(EventStreamContentType)) {
624
- onOpen?.();
625
- return;
626
- }
627
- if (response.status === 401 || response.status === 403) {
628
- throw new FatalSSEError(`Authentication failed: ${response.status}`);
629
- }
630
- if (response.status === 404) {
631
- throw new FatalSSEError("Session not found or not active");
632
- }
633
- if (response.status === 503) {
634
- const text = await response.text().catch(() => "Service unavailable");
635
- throw new FatalSSEError(`Server unavailable: ${text}`);
636
- }
637
- if (response.status >= 400 && response.status < 500) {
638
- const text = await response.text().catch(() => `Error ${response.status}`);
639
- throw new FatalSSEError(text);
640
- }
641
- throw new Error(`Failed to connect: ${response.status}`);
642
- },
643
- onmessage(event) {
644
- if (event.id && processedIds.has(event.id)) {
645
- return;
646
- }
647
- if (event.id) {
648
- processedIds.add(event.id);
649
- }
650
- if (!event.data) {
651
- return;
652
- }
653
- try {
654
- const data = JSON.parse(event.data);
655
- const eventType = event.event || "message";
656
- switch (eventType) {
657
- case "init":
658
- case "session":
659
- emitter.emit("session", { session_id: data.session_id });
660
- break;
661
- case "entry":
662
- emitter.emit("entry", { entry: data });
663
- break;
664
- case "stream_event":
665
- handleStreamEvent(data, emitter);
666
- break;
667
- case "content_block_start":
668
- emitter.emit("content_block_start", data);
669
- break;
670
- case "content_block_delta":
671
- emitter.emit("content_block_delta", data);
672
- break;
673
- case "content_block_stop":
674
- emitter.emit("content_block_stop", data);
675
- break;
676
- case "complete":
677
- emitter.emit("complete", data);
678
- break;
679
- case "error":
680
- emitter.emit("error", { error: data.error });
681
- break;
682
- case "heartbeat":
683
- emitter.emit("heartbeat", {});
684
- break;
685
- default:
686
- break;
687
- }
688
- } catch (e) {
689
- console.error("[SSE] Failed to parse event:", event.data, e);
690
- }
691
- },
692
- onerror(err) {
693
- if (signal?.aborted) {
694
- throw err;
695
- }
696
- if (err instanceof FatalSSEError) {
697
- emitter.emit("error", { error: err.message });
698
- throw err;
699
- }
700
- retryCount++;
701
- if (retryCount > MAX_RETRIES) {
702
- const error = `Connection failed after ${MAX_RETRIES} retries`;
703
- emitter.emit("error", { error });
704
- throw new FatalSSEError(error);
705
- }
706
- const delay = Math.min(INITIAL_RETRY_DELAY * Math.pow(2, retryCount - 1), MAX_RETRY_DELAY);
707
- console.log(`[SSE] Retry ${retryCount}/${MAX_RETRIES} in ${delay}ms`);
708
- return delay;
709
- },
710
- onclose() {
711
- onClose?.();
712
- },
713
- // Keep connection open when tab is hidden - heartbeats keep it alive
714
- openWhenHidden: true
715
- });
716
- } catch (error) {
717
- if (error instanceof FatalSSEError) {
718
- if (error.message.includes("Authentication")) {
719
- throw new AuthenticationError(error.message);
720
- }
721
- throw new RequestError(error.message, 500);
722
- }
723
- if (error instanceof Error) {
724
- emitter.emit("error", { error: error.message });
725
- }
726
- throw error;
727
- }
728
- }
729
- function handleStreamEvent(data, emitter) {
730
- const streamEvent = data.event || data;
731
- const eventData = streamEvent;
732
- switch (eventData.type) {
733
- case "content_block_start":
734
- emitter.emit("content_block_start", eventData);
735
- break;
736
- case "content_block_delta":
737
- emitter.emit("content_block_delta", eventData);
738
- break;
739
- case "content_block_stop":
740
- emitter.emit("content_block_stop", eventData);
741
- break;
742
- }
743
- }
744
- var AgentClient = class {
745
- constructor(config) {
746
- this.activeStreams = /* @__PURE__ */ new Map();
747
- this.config = {
748
- apiVersion: "/v1",
749
- timeout: 3e4,
750
- ...config
751
- };
752
- }
753
- // ===========================================================================
754
- // Public getters
755
- // ===========================================================================
756
- /** Whether org context is configured (orgId is set) */
757
- get hasOrgContext() {
758
- return !!this.config.orgId;
759
- }
760
- // ===========================================================================
761
- // Private helpers
762
- // ===========================================================================
763
- get baseUrl() {
764
- return `${this.config.endpoint}${this.config.apiVersion}`;
765
- }
766
- async getHeaders() {
767
- const headers = {
768
- "Content-Type": "application/json"
769
- };
770
- const token = await this.config.getAuthToken();
771
- if (token) {
772
- headers["Authorization"] = `Bearer ${token}`;
773
- }
774
- return headers;
775
- }
776
- async request(path, options = {}) {
777
- const url = `${this.baseUrl}${path}`;
778
- const headers = await this.getHeaders();
779
- const controller = new AbortController();
780
- const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
781
- try {
782
- const response = await fetch(url, {
783
- ...options,
784
- headers: { ...headers, ...options.headers || {} },
785
- signal: controller.signal
786
- });
787
- if (!response.ok) {
788
- await this.handleErrorResponse(response, path);
789
- }
790
- return response.json();
791
- } finally {
792
- clearTimeout(timeoutId);
793
- }
794
- }
795
- async handleErrorResponse(response, path) {
796
- if (response.status === 401 || response.status === 403) {
797
- throw new AuthenticationError();
798
- }
799
- if (response.status === 404) {
800
- const text = await response.text();
801
- if (text.toLowerCase().includes("session")) {
802
- const sessionId = path.split("/").pop() || "";
803
- throw new SessionNotFoundError(sessionId);
804
- }
805
- if (text.toLowerCase().includes("skill")) {
806
- const skillName = path.split("/").pop() || "";
807
- throw new SkillNotFoundError(skillName);
808
- }
809
- }
810
- throw new RequestError(`Request failed: ${response.status}`, response.status);
811
- }
812
- // ===========================================================================
813
- // Messages API
814
- // ===========================================================================
815
- /**
816
- * Send a message and stream responses.
817
- * @returns Object with event emitter and abort function
818
- */
819
- stream(request) {
820
- const emitter = new AgentEventEmitter();
821
- const controller = new AbortController();
822
- const streamId = request.session_id || `stream-${Date.now()}`;
823
- this.activeStreams.set(streamId, controller);
824
- (async () => {
825
- try {
826
- const headers = await this.getHeaders();
827
- await createSSEStream({
828
- url: `${this.baseUrl}/messages`,
829
- method: "POST",
830
- headers,
831
- body: { ...request, stream: true },
832
- emitter,
833
- signal: controller.signal
834
- });
835
- } catch (error) {
836
- emitter.emit("error", {
837
- error: error instanceof Error ? error.message : "Unknown error"
838
- });
839
- } finally {
840
- this.activeStreams.delete(streamId);
841
- }
842
- })();
843
- return {
844
- emitter,
845
- abort: () => controller.abort()
846
- };
847
- }
848
- // ===========================================================================
849
- // Sessions API
850
- // ===========================================================================
851
- /**
852
- * List all sessions for the authenticated user.
853
- */
854
- async listSessions() {
855
- return this.request("/sessions");
856
- }
857
- /**
858
- * Get session content in display format.
859
- */
860
- async getSession(sessionId) {
861
- return this.request(`/sessions/${sessionId}`);
862
- }
863
- /**
864
- * Get session content as raw JSONL.
865
- */
866
- async getSessionRaw(sessionId) {
867
- return this.request(`/sessions/${sessionId}?format=raw`);
868
- }
869
- /**
870
- * Check if a session is actively streaming.
871
- */
872
- async getSessionStatus(sessionId) {
873
- return this.request(`/sessions/${sessionId}/status`);
874
- }
875
- /**
876
- * Update session metadata (name).
877
- */
878
- async updateSession(sessionId, updates) {
879
- return this.request(`/sessions/${sessionId}`, {
880
- method: "PATCH",
881
- body: JSON.stringify(updates)
882
- });
883
- }
884
- /**
885
- * Delete a session.
886
- */
887
- async deleteSession(sessionId) {
888
- return this.request(`/sessions/${sessionId}`, {
889
- method: "DELETE"
890
- });
891
- }
892
- /**
893
- * Cancel an active session query.
894
- */
895
- async cancelSession(sessionId) {
896
- return this.request(`/sessions/${sessionId}/cancel`, {
897
- method: "POST"
898
- });
899
- }
900
- /**
901
- * Reconnect to an active streaming session.
902
- * @returns Object with event emitter and abort function
903
- */
904
- reconnect(sessionId, lastEventId = -1) {
905
- const emitter = new AgentEventEmitter();
906
- const controller = new AbortController();
907
- (async () => {
908
- try {
909
- const headers = await this.getHeaders();
910
- await createSSEStream({
911
- url: `${this.baseUrl}/sessions/${sessionId}/reconnect`,
912
- method: "POST",
913
- headers,
914
- body: { last_event_id: lastEventId },
915
- emitter,
916
- signal: controller.signal
917
- });
918
- } catch (error) {
919
- emitter.emit("error", {
920
- error: error instanceof Error ? error.message : "Unknown error"
921
- });
922
- }
923
- })();
924
- return {
925
- emitter,
926
- abort: () => controller.abort()
927
- };
928
- }
929
- // ===========================================================================
930
- // Skills API - Personal
931
- // ===========================================================================
932
- /**
933
- * List personal skills.
934
- */
935
- async listSkills() {
936
- return this.request("/skills");
937
- }
938
- /**
939
- * Get personal skill content.
940
- */
941
- async getSkill(name) {
942
- const response = await this.request(`/skills/${name}`);
943
- return this.decodeBase64(response.content);
944
- }
945
- /**
946
- * Create or update a personal skill.
947
- */
948
- async saveSkill(skill) {
949
- const content = this.encodeBase64(skill.content);
950
- return this.request("/skills", {
951
- method: "POST",
952
- body: JSON.stringify({ ...skill, content })
953
- });
954
- }
955
- /**
956
- * Delete a personal skill.
957
- */
958
- async deleteSkill(name) {
959
- return this.request(`/skills/${name}`, {
960
- method: "DELETE"
961
- });
962
- }
963
- // ===========================================================================
964
- // Skills API - Organization
965
- // ===========================================================================
966
- /**
967
- * List organization skills.
968
- */
969
- async listOrgSkills() {
970
- return this.request("/skills/org");
971
- }
972
- /**
973
- * Get organization skill content.
974
- */
975
- async getOrgSkill(name) {
976
- const response = await this.request(
977
- `/skills/org/${name}`
978
- );
979
- return this.decodeBase64(response.content);
980
- }
981
- /**
982
- * Create or update an organization skill.
983
- */
984
- async saveOrgSkill(skill) {
985
- const content = this.encodeBase64(skill.content);
986
- return this.request("/skills/org", {
987
- method: "POST",
988
- body: JSON.stringify({ ...skill, content })
989
- });
990
- }
991
- /**
992
- * Delete an organization skill.
993
- */
994
- async deleteOrgSkill(name) {
995
- return this.request(`/skills/org/${name}`, {
996
- method: "DELETE"
997
- });
998
- }
999
- // ===========================================================================
1000
- // Plugins API
1001
- // ===========================================================================
1002
- /**
1003
- * Get plugin manifest for client sync.
1004
- */
1005
- async getPluginManifest() {
1006
- return this.request("/plugins/manifest");
1007
- }
1008
- /**
1009
- * Download plugin bundle.
1010
- */
1011
- async getPluginBundle(skills) {
1012
- const query = skills?.length ? `?skills=${skills.join(",")}` : "";
1013
- return this.request(`/plugins/bundle${query}`);
1014
- }
1015
- // ===========================================================================
1016
- // Utility methods
1017
- // ===========================================================================
1018
- encodeBase64(data) {
1019
- if (typeof data === "string") {
1020
- const encoder = new TextEncoder();
1021
- data = encoder.encode(data);
1022
- }
1023
- return btoa(String.fromCharCode(...data));
1024
- }
1025
- decodeBase64(base64) {
1026
- return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
1027
- }
1028
- };
1029
- function parseToolResultContent(content) {
1030
- try {
1031
- const pythonMatch = content.match(/\[\{'type':\s*'text',\s*'text':\s*'([\s\S]+)'\}\]$/);
1032
- if (pythonMatch) {
1033
- const innerText = pythonMatch[1].replace(/\\n/g, "\n").replace(/\\"/g, '"');
1034
- const parsed2 = JSON.parse(innerText);
1035
- if (parsed2 && typeof parsed2 === "object" && !Array.isArray(parsed2)) {
1036
- return parsed2;
1037
- }
1038
- }
1039
- const parsed = JSON.parse(content);
1040
- if (Array.isArray(parsed) && parsed.length > 0 && parsed[0].type === "text" && parsed[0].text) {
1041
- const unescapedText = parsed[0].text.replace(/\\n/g, "\n").replace(/\\"/g, '"');
1042
- const innerParsed = JSON.parse(unescapedText);
1043
- if (innerParsed && typeof innerParsed === "object" && !Array.isArray(innerParsed)) {
1044
- return innerParsed;
1045
- }
1046
- }
1047
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1048
- return parsed;
1049
- }
1050
- } catch {
1051
- }
1052
- const jadeUrlMatch = content.match(/https?:\/\/jade\.gr33n\.ai\/media\/([a-zA-Z0-9_-]+)/);
1053
- const falUrl = extractFalMediaUrl(content);
1054
- if (jadeUrlMatch || falUrl) {
1055
- const request_id = jadeUrlMatch ? jadeUrlMatch[1] : "unknown";
1056
- const output_cdn_urls = falUrl ? [falUrl] : [];
1057
- return {
1058
- request_id,
1059
- output_cdn_urls,
1060
- status: "completed"
1061
- };
1062
- }
1063
- return null;
1064
- }
1065
- function extractFalMediaUrl(content) {
1066
- const urlMatch = content.match(/https?:\/\/[^\/]*fal\.media\/files\/[^\s"')]+/);
1067
- return urlMatch ? urlMatch[0] : null;
1068
- }
1069
- function extractMediaInfoFromToolResult(content) {
1070
- const parsed = parseToolResultContent(content);
1071
- if (!parsed) return null;
1072
- const urls = parsed.output_cdn_urls || parsed.urls;
1073
- if (!parsed.request_id || typeof parsed.request_id !== "string" || !Array.isArray(urls) || urls.length === 0) {
1074
- return null;
1075
- }
1076
- return {
1077
- requestId: parsed.request_id,
1078
- urls,
1079
- fileType: parsed.file_type,
1080
- metadata: parsed.metadata,
1081
- originalSource: parsed.original_source
1082
- };
1083
- }
1084
- function createMediaParseResult(displayType) {
1085
- return (content) => {
1086
- const mediaInfo = extractMediaInfoFromToolResult(content);
1087
- if (mediaInfo) {
1088
- return {
1089
- type: displayType,
1090
- data: { mediaInfo }
1091
- };
1092
- }
1093
- return null;
1094
- };
1095
- }
1096
- function extractMediaInfo(content) {
1097
- try {
1098
- const parsed = parseToolResultContent(content);
1099
- if (parsed?.request_id) {
1100
- const urls2 = parsed.output_cdn_urls || parsed.urls;
1101
- if (Array.isArray(urls2) && urls2.length > 0) {
1102
- return {
1103
- requestId: parsed.request_id,
1104
- urls: urls2
1105
- };
1106
- }
1107
- }
1108
- } catch {
1109
- }
1110
- const jadeUrlMatch = content.match(/https?:\/\/jade\.gr33n\.ai\/media\/([a-zA-Z0-9_-]+)/);
1111
- if (!jadeUrlMatch) return null;
1112
- const requestId = jadeUrlMatch[1];
1113
- const cdnUrlMatches = content.matchAll(/https?:\/\/[^\/]*fal\.media\/files\/[^\s"')]+/g);
1114
- const urls = Array.from(cdnUrlMatches, (match) => match[0]);
1115
- if (urls.length === 0) return null;
1116
- return {
1117
- requestId,
1118
- urls
1119
- };
1120
- }
1121
- var TOOL_REGISTRY = {
1122
- "Skill": {
1123
- name: "Skill",
1124
- displayName: "Skill",
1125
- iconName: "BookOpenText",
1126
- category: "system",
1127
- consumesResult: true,
1128
- parseInput: (input) => {
1129
- const inputObj = input;
1130
- const command = inputObj?.skill || inputObj?.command;
1131
- if (!command) return null;
1132
- return {
1133
- type: "skill",
1134
- data: { command }
1135
- };
1136
- },
1137
- parseResult: (content) => ({
1138
- type: "skill_result",
1139
- data: { content }
1140
- })
1141
- },
1142
- "Bash": {
1143
- name: "Bash",
1144
- displayName: "Bash",
1145
- iconName: "Terminal",
1146
- category: "system",
1147
- consumesResult: true,
1148
- parseInput: (input) => {
1149
- const inputObj = input;
1150
- return {
1151
- type: "bash",
1152
- data: {
1153
- command: inputObj?.command,
1154
- description: inputObj?.description
1155
- }
1156
- };
1157
- },
1158
- parseResult: (content) => ({
1159
- type: "bash_output",
1160
- data: { output: content }
1161
- })
1162
- },
1163
- "TodoWrite": {
1164
- name: "TodoWrite",
1165
- displayName: "Todo List",
1166
- iconName: "ListTodo",
1167
- category: "system",
1168
- consumesResult: true,
1169
- parseInput: (input) => {
1170
- const inputObj = input;
1171
- if (!inputObj?.todos) return null;
1172
- return {
1173
- type: "todo_list",
1174
- data: { todos: inputObj.todos }
1175
- };
1176
- },
1177
- parseResult: (content) => ({
1178
- type: "todo_result",
1179
- data: { content }
1180
- })
1181
- },
1182
- "Read": {
1183
- name: "Read",
1184
- displayName: "Read",
1185
- iconName: "BookOpenCheck",
1186
- category: "system",
1187
- consumesResult: true,
1188
- parseInput: (input) => {
1189
- const inputObj = input;
1190
- if (!inputObj?.file_path) return null;
1191
- return {
1192
- type: "read",
1193
- data: {
1194
- file_path: inputObj.file_path,
1195
- offset: inputObj.offset,
1196
- limit: inputObj.limit
1197
- }
1198
- };
1199
- },
1200
- parseResult: (content) => ({
1201
- type: "read_output",
1202
- data: { output: content }
1203
- })
1204
- },
1205
- "Glob": {
1206
- name: "Glob",
1207
- displayName: "File Search",
1208
- iconName: "FolderSearch",
1209
- category: "system",
1210
- consumesResult: true,
1211
- parseInput: (input) => {
1212
- const inputObj = input;
1213
- if (!inputObj?.pattern) return null;
1214
- return {
1215
- type: "glob",
1216
- data: {
1217
- pattern: inputObj.pattern,
1218
- path: inputObj.path
1219
- }
1220
- };
1221
- },
1222
- parseResult: (content) => {
1223
- const files = content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
1224
- return {
1225
- type: "glob_output",
1226
- data: { files }
1227
- };
1228
- }
1229
- },
1230
- "WebSearch": {
1231
- name: "WebSearch",
1232
- displayName: "Web Search",
1233
- iconName: "Search",
1234
- category: "system",
1235
- consumesResult: true,
1236
- parseInput: (input) => {
1237
- const inputObj = input;
1238
- if (!inputObj?.query) return null;
1239
- return {
1240
- type: "web_search",
1241
- data: {
1242
- query: inputObj.query,
1243
- allowed_domains: inputObj.allowed_domains,
1244
- blocked_domains: inputObj.blocked_domains
1245
- }
1246
- };
1247
- },
1248
- parseResult: (content) => ({
1249
- type: "web_search_output",
1250
- data: { output: content }
1251
- })
1252
- },
1253
- "Edit": {
1254
- name: "Edit",
1255
- displayName: "Edit File",
1256
- iconName: "Pencil",
1257
- category: "system",
1258
- consumesResult: true,
1259
- parseInput: (input) => {
1260
- const inputObj = input;
1261
- if (!inputObj?.file_path) return null;
1262
- return {
1263
- type: "edit",
1264
- data: {
1265
- file_path: inputObj.file_path,
1266
- old_string: inputObj.old_string,
1267
- new_string: inputObj.new_string,
1268
- replace_all: inputObj.replace_all
1269
- }
1270
- };
1271
- },
1272
- parseResult: (content) => ({
1273
- type: "edit_result",
1274
- data: { output: content }
1275
- })
1276
- },
1277
- "Write": {
1278
- name: "Write",
1279
- displayName: "Write File",
1280
- iconName: "FilePlus",
1281
- category: "system",
1282
- consumesResult: true,
1283
- parseInput: (input) => {
1284
- const inputObj = input;
1285
- if (!inputObj?.file_path) return null;
1286
- return {
1287
- type: "write",
1288
- data: {
1289
- file_path: inputObj.file_path,
1290
- content: inputObj.content
1291
- }
1292
- };
1293
- },
1294
- parseResult: (content) => ({
1295
- type: "write_result",
1296
- data: { output: content }
1297
- })
1298
- },
1299
- "WebFetch": {
1300
- name: "WebFetch",
1301
- displayName: "Web Fetch",
1302
- iconName: "Globe",
1303
- category: "system",
1304
- consumesResult: true,
1305
- parseInput: (input) => {
1306
- const inputObj = input;
1307
- if (!inputObj?.url) return null;
1308
- return {
1309
- type: "web_fetch",
1310
- data: {
1311
- url: inputObj.url,
1312
- prompt: inputObj.prompt
1313
- }
1314
- };
1315
- },
1316
- parseResult: (content) => ({
1317
- type: "web_fetch_result",
1318
- data: { response: content }
1319
- })
1320
- },
1321
- "mcp__jade__request_status": {
1322
- name: "mcp__jade__request_status",
1323
- displayName: "Request Status",
1324
- iconName: "Loader",
1325
- category: "utility",
1326
- consumesResult: true,
1327
- parseInput: (input) => {
1328
- const inputObj = input;
1329
- return {
1330
- type: "request_status_check",
1331
- data: { requestId: inputObj?.request_id }
1332
- };
1333
- },
1334
- parseResult: (content) => {
1335
- const mediaInfo = extractMediaInfoFromToolResult(content);
1336
- if (mediaInfo) {
1337
- return {
1338
- type: "request_status_completed",
1339
- data: { mediaInfo }
1340
- };
1341
- }
1342
- try {
1343
- const parsed = parseToolResultContent(content);
1344
- if (parsed?.request_id && parsed?.status === "processing") {
1345
- return {
1346
- type: "request_status_processing",
1347
- data: { requestId: parsed.request_id }
1348
- };
1349
- }
1350
- } catch {
1351
- }
1352
- return null;
1353
- }
1354
- },
1355
- "mcp__jade__generative_audio": {
1356
- name: "mcp__jade__generative_audio",
1357
- displayName: "Generative Audio",
1358
- iconName: "AudioLines",
1359
- iconVariant: (input) => {
1360
- const inputObj = input;
1361
- const mode = inputObj?.mode;
1362
- if (mode === "narration") return "Speech";
1363
- if (mode === "sound_effects") return "AudioLines";
1364
- if (mode === "music") return "Music";
1365
- return "AudioLines";
1366
- },
1367
- category: "generation",
1368
- consumesResult: true,
1369
- parseInput: (input) => {
1370
- const inputObj = input;
1371
- return {
1372
- type: "audio_generation",
1373
- data: {
1374
- textInput: inputObj?.text_input,
1375
- videoUrl: inputObj?.video_url,
1376
- mode: inputObj?.mode,
1377
- duration: inputObj?.duration
1378
- }
1379
- };
1380
- },
1381
- parseResult: createMediaParseResult("audio_generation_complete")
1382
- },
1383
- "mcp__jade__generative_image": {
1384
- name: "mcp__jade__generative_image",
1385
- displayName: "Generative Image",
1386
- iconName: "Image",
1387
- category: "generation",
1388
- consumesResult: true,
1389
- parseInput: (input) => {
1390
- const inputObj = input;
1391
- const additionalUrls = inputObj?.additional_image_urls ? typeof inputObj.additional_image_urls === "string" ? inputObj.additional_image_urls.split(",").map((url) => url.trim()).filter(Boolean) : inputObj.additional_image_urls : [];
1392
- const inputImageUrls = [
1393
- inputObj?.image_url,
1394
- ...additionalUrls
1395
- ].filter((url) => url && url !== "");
1396
- return {
1397
- type: "image_generation",
1398
- data: {
1399
- prompt: inputObj?.prompt,
1400
- inputImageUrls,
1401
- model: inputObj?.model,
1402
- aspectRatio: inputObj?.aspect_ratio,
1403
- numImages: inputObj?.num_images
1404
- }
1405
- };
1406
- },
1407
- parseResult: createMediaParseResult("image_generation_complete")
1408
- },
1409
- "mcp__jade__generative_video": {
1410
- name: "mcp__jade__generative_video",
1411
- displayName: "Generative Video",
1412
- iconName: "Video",
1413
- category: "generation",
1414
- consumesResult: true,
1415
- parseInput: (input) => {
1416
- const inputObj = input;
1417
- const inputMediaUrls = [];
1418
- if (inputObj?.input_url) {
1419
- inputMediaUrls.push(inputObj.input_url);
1420
- }
1421
- const lastFrameUrl = inputObj?.last_frame_url;
1422
- if (lastFrameUrl) {
1423
- inputMediaUrls.push(lastFrameUrl);
1424
- }
1425
- const elements = inputObj?.elements;
1426
- if (elements && Array.isArray(elements)) {
1427
- for (const element of elements) {
1428
- if (Array.isArray(element)) {
1429
- for (const url of element) {
1430
- if (url && typeof url === "string") {
1431
- inputMediaUrls.push(url);
1432
- }
1433
- }
1434
- }
1435
- }
1436
- }
1437
- return {
1438
- type: "video_generation",
1439
- data: {
1440
- prompt: inputObj?.prompt,
1441
- inputMediaUrls,
1442
- lastFrameUrl,
1443
- elements,
1444
- model: inputObj?.model_id,
1445
- aspectRatio: inputObj?.aspect_ratio,
1446
- numVideos: inputObj?.num_videos || 1
1447
- }
1448
- };
1449
- },
1450
- parseResult: createMediaParseResult("video_generation_complete")
1451
- },
1452
- "mcp__jade__background_removal": {
1453
- name: "mcp__jade__background_removal",
1454
- displayName: "Background Removal",
1455
- iconName: "ImageOff",
1456
- category: "processing",
1457
- consumesResult: true,
1458
- parseInput: (input) => {
1459
- const inputObj = input;
1460
- return {
1461
- type: "background_removal",
1462
- data: { inputUrl: inputObj?.input_url }
1463
- };
1464
- },
1465
- parseResult: createMediaParseResult("background_removal_complete")
1466
- },
1467
- "mcp__jade__upscale": {
1468
- name: "mcp__jade__upscale",
1469
- displayName: "Upscale",
1470
- iconName: "Maximize2",
1471
- category: "processing",
1472
- consumesResult: true,
1473
- parseInput: (input) => {
1474
- const inputObj = input;
1475
- return {
1476
- type: "upscale",
1477
- data: {
1478
- inputUrl: inputObj?.input_url,
1479
- upscaleFactor: inputObj?.upscale_factor,
1480
- targetResolution: inputObj?.target_resolution
1481
- }
1482
- };
1483
- },
1484
- parseResult: createMediaParseResult("upscale_complete")
1485
- },
1486
- "mcp__jade__generative_character": {
1487
- name: "mcp__jade__generative_character",
1488
- displayName: "Generative Character",
1489
- iconName: "SquareUser",
1490
- category: "generation",
1491
- consumesResult: true,
1492
- parseInput: (input) => {
1493
- const inputObj = input;
1494
- return {
1495
- type: "character_generation",
1496
- data: {
1497
- inputImageUrl: inputObj?.image_url,
1498
- inputAudioUrl: inputObj?.audio_url
1499
- }
1500
- };
1501
- },
1502
- parseResult: createMediaParseResult("character_generation_complete")
1503
- },
1504
- "mcp__jade__import_media": {
1505
- name: "mcp__jade__import_media",
1506
- displayName: "Import Media",
1507
- iconName: "CloudDownload",
1508
- category: "utility",
1509
- consumesResult: true,
1510
- parseInput: (input) => {
1511
- const inputObj = input;
1512
- return {
1513
- type: "media_import",
1514
- data: { source: inputObj?.source }
1515
- };
1516
- },
1517
- parseResult: createMediaParseResult("media_import_complete")
1518
- },
1519
- "mcp__jade__captions_highlights": {
1520
- name: "mcp__jade__captions_highlights",
1521
- displayName: "Captions & Highlights",
1522
- iconName: "Captions",
1523
- category: "processing",
1524
- consumesResult: true,
1525
- parseInput: (input) => {
1526
- const inputObj = input;
1527
- return {
1528
- type: "captions_highlights",
1529
- data: {
1530
- inputUrl: inputObj?.input_url,
1531
- style: inputObj?.style
1532
- }
1533
- };
1534
- },
1535
- parseResult: createMediaParseResult("captions_highlights_complete")
1536
- },
1537
- "mcp__olive__save_skill": {
1538
- name: "mcp__olive__save_skill",
1539
- displayName: "Save Skill",
1540
- iconName: "BookPlus",
1541
- category: "utility",
1542
- consumesResult: true,
1543
- parseInput: (input) => {
1544
- const inputObj = input;
1545
- return {
1546
- type: "save_skill",
1547
- data: {
1548
- source: inputObj?.source,
1549
- name: inputObj?.name,
1550
- scope: inputObj?.scope || "personal",
1551
- edit: inputObj?.edit
1552
- }
1553
- };
1554
- },
1555
- parseResult: (content) => {
1556
- const parsed = parseToolResultContent(content);
1557
- return {
1558
- type: "save_skill_result",
1559
- data: {
1560
- name: parsed?.name,
1561
- description: parsed?.description,
1562
- scope: parsed?.scope,
1563
- action: parsed?.action,
1564
- hasElements: parsed?.has_elements,
1565
- sourceType: parsed?.source_type,
1566
- sizeKb: parsed?.size_kb,
1567
- elements: parsed?.elements || []
1568
- }
1569
- };
1570
- }
1571
- }
1572
- };
1573
- function getToolDefinition(toolName) {
1574
- return TOOL_REGISTRY[toolName];
1575
- }
1576
- var SUGGESTION_REGEX = /<gr3\.suggestion>([\s\S]*?)<\/gr3\.suggestion>/g;
1577
- function parseSuggestions(text) {
1578
- const suggestions = [];
1579
- const segments = [];
1580
- let lastIndex = 0;
1581
- let cleanText = "";
1582
- let match;
1583
- const regex = new RegExp(SUGGESTION_REGEX.source, "g");
1584
- while ((match = regex.exec(text)) !== null) {
1585
- const suggestionText = match[1].trim();
1586
- const matchStart = match.index;
1587
- const matchEnd = match.index + match[0].length;
1588
- if (matchStart > lastIndex) {
1589
- const textBefore = text.slice(lastIndex, matchStart);
1590
- segments.push({ type: "text", content: textBefore });
1591
- cleanText += textBefore;
1592
- }
1593
- const startIndex = cleanText.length;
1594
- cleanText += suggestionText;
1595
- const endIndex = cleanText.length;
1596
- suggestions.push({
1597
- text: suggestionText,
1598
- startIndex,
1599
- endIndex
1600
- });
1601
- segments.push({ type: "suggestion", content: suggestionText });
1602
- lastIndex = matchEnd;
1603
- }
1604
- if (lastIndex < text.length) {
1605
- const remainingText = text.slice(lastIndex);
1606
- segments.push({ type: "text", content: remainingText });
1607
- cleanText += remainingText;
1608
- }
1609
- return { cleanText, suggestions, segments };
1610
- }
1611
- function hasSuggestions(text) {
1612
- return SUGGESTION_REGEX.test(text);
1613
- }
1614
- function processConversation(conversation, options = {}) {
1615
- const {
1616
- skipSkillContext = true,
1617
- pairToolResults = true,
1618
- extractMedia: _extractMedia = true
1619
- } = options;
1620
- const processed = [];
1621
- const consumed = /* @__PURE__ */ new Set();
1622
- const resultsByToolUseId = /* @__PURE__ */ new Map();
1623
- const mediaUrlsByRequestId = /* @__PURE__ */ new Map();
1624
- const metadataByRequestId = /* @__PURE__ */ new Map();
1625
- for (let i = 0; i < conversation.length; i++) {
1626
- const entry = conversation[i];
1627
- if (entry.type === "tool_result" && entry.tool_use_id) {
1628
- resultsByToolUseId.set(entry.tool_use_id, i);
1629
- if (typeof entry.content === "string") {
1630
- const parsed = parseToolResultContent(entry.content);
1631
- if (parsed?.request_id && parsed?.status === "completed" && Array.isArray(parsed?.output_cdn_urls) && parsed.output_cdn_urls.length > 0) {
1632
- mediaUrlsByRequestId.set(parsed.request_id, parsed.output_cdn_urls);
1633
- }
1634
- if (parsed?.request_id && parsed?.status === "completed" && Array.isArray(parsed?.urls) && parsed.urls.length > 0) {
1635
- mediaUrlsByRequestId.set(parsed.request_id, parsed.urls);
1636
- }
1637
- }
1638
- }
1639
- }
1640
- for (let i = 0; i < conversation.length; i++) {
1641
- if (consumed.has(i)) continue;
1642
- const entry = conversation[i];
1643
- if (entry.type === "tool_call" && entry.tool_name) {
1644
- const toolDef = getToolDefinition(entry.tool_name);
1645
- const parsedInput = toolDef?.parseInput?.(entry.tool_input) || null;
1646
- let parsedResult = null;
1647
- if (pairToolResults && toolDef?.consumesResult && toolDef.parseResult && entry.tool_use_id) {
1648
- const resultIndex = resultsByToolUseId.get(entry.tool_use_id);
1649
- if (resultIndex !== void 0) {
1650
- const resultEntry = conversation[resultIndex];
1651
- if (resultEntry.type === "tool_result" && typeof resultEntry.content === "string") {
1652
- parsedResult = toolDef.parseResult(resultEntry.content);
1653
- consumed.add(resultIndex);
1654
- const immediateResult = parseToolResultContent(resultEntry.content);
1655
- const requestId = immediateResult?.request_id;
1656
- if (requestId) {
1657
- const isGenerativeTool = entry.tool_name?.includes("generative_");
1658
- if (isGenerativeTool && entry.tool_use_id && parsedInput?.data) {
1659
- metadataByRequestId.set(requestId, {
1660
- toolUseId: entry.tool_use_id,
1661
- toolName: entry.tool_name,
1662
- prompt: parsedInput.data.prompt,
1663
- model: parsedInput.data.model,
1664
- aspectRatio: parsedInput.data.aspectRatio,
1665
- inputMediaUrls: parsedInput.data.inputMediaUrls || parsedInput.data.inputImageUrls,
1666
- lastFrameUrl: parsedInput.data.lastFrameUrl,
1667
- elements: parsedInput.data.elements
1668
- });
1669
- }
1670
- const eventualUrls = mediaUrlsByRequestId.get(requestId);
1671
- if (eventualUrls) {
1672
- if (!parsedResult) {
1673
- const mediaType = entry.tool_name?.includes("video") ? "video" : entry.tool_name?.includes("audio") ? "audio" : "image";
1674
- parsedResult = {
1675
- type: `${mediaType}_generation_complete`,
1676
- data: { mediaInfo: { urls: eventualUrls, requestId } }
1677
- };
1678
- } else if (!parsedResult.data?.mediaInfo) {
1679
- parsedResult.data.mediaInfo = { urls: eventualUrls, requestId };
1680
- }
1681
- }
1682
- }
1683
- if (toolDef.consumeExtra && toolDef.consumeExtra > 0) {
1684
- for (let j = 1; j <= toolDef.consumeExtra; j++) {
1685
- const extraIndex = resultIndex + j;
1686
- if (extraIndex < conversation.length) {
1687
- consumed.add(extraIndex);
1688
- }
1689
- }
1690
- }
1691
- if (parsedResult?.type === "request_status_completed") {
1692
- const mediaInfo = parsedResult.data?.mediaInfo;
1693
- if (mediaInfo?.requestId) {
1694
- const originalMetadata = metadataByRequestId.get(mediaInfo.requestId);
1695
- if (originalMetadata) {
1696
- mediaInfo.originalToolUseId = originalMetadata.toolUseId;
1697
- mediaInfo.originalToolName = originalMetadata.toolName;
1698
- mediaInfo.prompt = originalMetadata.prompt;
1699
- mediaInfo.model = originalMetadata.model;
1700
- mediaInfo.aspectRatio = originalMetadata.aspectRatio;
1701
- mediaInfo.inputMediaUrls = originalMetadata.inputMediaUrls;
1702
- mediaInfo.lastFrameUrl = originalMetadata.lastFrameUrl;
1703
- mediaInfo.elements = originalMetadata.elements;
1704
- }
1705
- }
1706
- }
1707
- }
1708
- }
1709
- }
1710
- processed.push({
1711
- entry,
1712
- originalType: "tool_call",
1713
- displayType: parsedInput?.type || "unknown_tool",
1714
- iconName: toolDef?.iconName || "Wrench",
1715
- iconData: entry.tool_input,
1716
- title: toolDef && entry.tool_name.startsWith("mcp__jade__") ? toolDef.displayName : void 0,
1717
- data: {
1718
- toolName: entry.tool_name,
1719
- toolUseId: entry.tool_use_id,
1720
- input: parsedInput,
1721
- result: parsedResult
1722
- },
1723
- timestamp: entry.timestamp,
1724
- toolDefinition: toolDef,
1725
- parsedInput: parsedInput || void 0,
1726
- parsedResult: parsedResult || void 0
1727
- });
1728
- continue;
1729
- }
1730
- if (entry.type === "tool_result" && typeof entry.content === "string") {
1731
- try {
1732
- const parsed = parseToolResultContent(entry.content);
1733
- if (parsed?.request_id && parsed?.status && parsed?.message) {
1734
- processed.push({
1735
- entry,
1736
- originalType: "tool_result",
1737
- displayType: "simple_message",
1738
- iconName: "Wrench",
1739
- data: { message: parsed.message },
1740
- timestamp: entry.timestamp
1741
- });
1742
- continue;
1743
- }
1744
- } catch {
1745
- }
1746
- const mediaInfo = extractMediaInfo(entry.content);
1747
- if (mediaInfo) {
1748
- processed.push({
1749
- entry,
1750
- originalType: "tool_result",
1751
- displayType: "media_carousel",
1752
- iconName: "Wrench",
1753
- data: {
1754
- mediaInfo: {
1755
- requestId: mediaInfo.requestId,
1756
- urls: mediaInfo.urls
1757
- }
1758
- },
1759
- timestamp: entry.timestamp
1760
- });
1761
- continue;
1762
- }
1763
- processed.push({
1764
- entry,
1765
- originalType: "tool_result",
1766
- displayType: "raw_content",
1767
- iconName: "Wrench",
1768
- data: { content: entry.content },
1769
- timestamp: entry.timestamp
1770
- });
1771
- continue;
1772
- }
1773
- if (skipSkillContext) {
1774
- if (entry.type === "user_text" && entry.text?.startsWith("Base directory for this skill:")) {
1775
- continue;
1776
- }
1777
- if (entry.type === "user_text" && entry.text?.startsWith("Caveat:")) {
1778
- continue;
1779
- }
1780
- }
1781
- if (entry.type === "user_text" && entry.text) {
1782
- const isCompactSummary = entry.text.startsWith("This session is being continued from a previous conversation");
1783
- if (isCompactSummary) {
1784
- processed.push({
1785
- entry,
1786
- originalType: "compact",
1787
- displayType: "compact",
1788
- iconName: "Sparkles",
1789
- data: {
1790
- isCompacting: false,
1791
- summary: entry.text
1792
- },
1793
- timestamp: entry.timestamp
1794
- });
1795
- continue;
1796
- }
1797
- processed.push({
1798
- entry,
1799
- originalType: "user_text",
1800
- displayType: "user_text",
1801
- iconName: "User",
1802
- data: { text: entry.text },
1803
- timestamp: entry.timestamp
1804
- });
1805
- continue;
1806
- }
1807
- if (entry.type === "assistant_text" && entry.text) {
1808
- const processedEntry = {
1809
- entry,
1810
- originalType: "assistant_text",
1811
- displayType: "markdown_text",
1812
- iconName: "Bot",
1813
- data: { text: entry.text },
1814
- timestamp: entry.timestamp
1815
- };
1816
- if (hasSuggestions(entry.text)) {
1817
- const { cleanText, suggestions, segments } = parseSuggestions(entry.text);
1818
- processedEntry.data = { text: cleanText };
1819
- processedEntry.suggestions = suggestions;
1820
- processedEntry.textSegments = segments;
1821
- }
1822
- processed.push(processedEntry);
1823
- continue;
1824
- }
1825
- if (entry.type === "compact_boundary") {
1826
- const nextEntry = conversation[i + 1];
1827
- const isNextSummary = nextEntry?.type === "compact_summary" || nextEntry?.type === "user_text" && nextEntry.text?.startsWith("This session is being continued from a previous conversation");
1828
- if (isNextSummary) {
1829
- consumed.add(i + 1);
1830
- processed.push({
1831
- entry,
1832
- originalType: "compact",
1833
- displayType: "compact",
1834
- iconName: "Sparkles",
1835
- data: {
1836
- isCompacting: false,
1837
- summary: nextEntry.text || ""
1838
- },
1839
- timestamp: entry.timestamp
1840
- });
1841
- } else {
1842
- processed.push({
1843
- entry,
1844
- originalType: "compact",
1845
- displayType: "compact",
1846
- iconName: "Sparkles",
1847
- data: {
1848
- isCompacting: true,
1849
- summary: null
1850
- },
1851
- timestamp: entry.timestamp
1852
- });
1853
- }
1854
- continue;
1855
- }
1856
- if (entry.type === "compact_summary") {
1857
- processed.push({
1858
- entry,
1859
- originalType: "compact",
1860
- displayType: "compact",
1861
- iconName: "Sparkles",
1862
- data: {
1863
- isCompacting: false,
1864
- summary: entry.text || ""
1865
- },
1866
- timestamp: entry.timestamp
1867
- });
1868
- continue;
1869
- }
1870
- if (entry.type === "error") {
1871
- processed.push({
1872
- entry,
1873
- originalType: "error",
1874
- displayType: "error",
1875
- iconName: "AlertTriangle",
1876
- data: {
1877
- text: entry.text || "Unknown error"
1878
- },
1879
- timestamp: entry.timestamp
1880
- });
1881
- continue;
1882
- }
1883
- }
1884
- return processed;
1885
- }
1886
- var ACCEPTED_EXTENSIONS = {
1887
- image: [".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp", ".svg"],
1888
- video: [".mp4", ".mov", ".webm", ".avi", ".mkv", ".m4v"],
1889
- audio: [".mp3", ".wav", ".m4a", ".aac", ".ogg", ".oga", ".mpeg"],
1890
- document: [".pdf"]
1891
- };
1892
- function getMediaTypeFromExtension(filename) {
1893
- const normalizedFilename = filename.toLowerCase();
1894
- for (const [type, extensions] of Object.entries(ACCEPTED_EXTENSIONS)) {
1895
- if (extensions.some((ext) => normalizedFilename.endsWith(ext))) {
1896
- return type;
1897
- }
1898
- }
1899
- return null;
1900
- }
1901
- function getMediaTypeFromUrl(url) {
1902
- try {
1903
- const urlObj = new URL(url);
1904
- const pathname = urlObj.pathname;
1905
- const filename = pathname.split("/").pop() || "";
1906
- return getMediaTypeFromExtension(filename);
1907
- } catch {
1908
- const cleanUrl = url.split("?")[0];
1909
- return getMediaTypeFromExtension(cleanUrl);
1910
- }
1911
- }
1912
- function extractMedia(conversation) {
1913
- const urlMap = /* @__PURE__ */ new Map();
1914
- const processed = processConversation(conversation);
1915
- for (const entry of processed) {
1916
- if (entry.originalType === "tool_call") {
1917
- const data = entry.data;
1918
- const result = data?.result;
1919
- const resultData = result?.data;
1920
- const mediaInfo = resultData?.mediaInfo;
1921
- const urls = mediaInfo?.urls;
1922
- if (urls && Array.isArray(urls)) {
1923
- const input = data?.input;
1924
- const inputData = input?.data;
1925
- const toolName = data?.toolName;
1926
- const toolUseId = data?.toolUseId;
1927
- for (const url of urls) {
1928
- if (typeof url !== "string") continue;
1929
- const detectedType = getMediaTypeFromUrl(url);
1930
- const type = detectedType === "video" ? "video" : detectedType === "audio" ? "audio" : "image";
1931
- const existing = urlMap.get(url);
1932
- const hasInputMetadata = !!(inputData?.prompt || inputData?.model);
1933
- const existingHasMetadata = !!(existing?.prompt || existing?.model);
1934
- if (!existing || hasInputMetadata && !existingHasMetadata) {
1935
- urlMap.set(url, {
1936
- url,
1937
- type,
1938
- timestamp: entry.timestamp,
1939
- toolName,
1940
- toolUseId,
1941
- prompt: inputData?.prompt,
1942
- model: inputData?.model,
1943
- aspectRatio: inputData?.aspectRatio,
1944
- inputMediaUrls: inputData?.inputImageUrls || inputData?.inputMediaUrls
1945
- });
1946
- }
1947
- }
1948
- continue;
1949
- }
1950
- }
1951
- if (entry.originalType === "tool_result" && entry.displayType === "media_carousel") {
1952
- const data = entry.data;
1953
- const mediaInfo = data?.mediaInfo;
1954
- const urls = mediaInfo?.urls;
1955
- if (urls && Array.isArray(urls)) {
1956
- for (const url of urls) {
1957
- if (typeof url !== "string") continue;
1958
- const detectedType = getMediaTypeFromUrl(url);
1959
- const type = detectedType === "video" ? "video" : detectedType === "audio" ? "audio" : "image";
1960
- if (!urlMap.has(url)) {
1961
- urlMap.set(url, {
1962
- url,
1963
- type,
1964
- timestamp: entry.timestamp
1965
- });
1966
- }
1967
- }
1968
- }
1969
- }
1970
- }
1971
- const mediaArray = Array.from(urlMap.values());
1972
- mediaArray.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
1973
- return mediaArray;
1974
- }
1975
-
1976
- // src/react-native/sse-adapter.ts
1977
- var import_react_native_sse = __toESM(require_react_native_sse());
1978
- var MAX_RETRIES2 = 5;
1979
- var INITIAL_RETRY_DELAY2 = 1e3;
1980
- var MAX_RETRY_DELAY2 = 1e4;
1981
- async function createRNSSEStream(options) {
1982
- const {
1983
- url,
1984
- headers,
1985
- body,
1986
- emitter,
1987
- signal,
1988
- onOpen,
1989
- onClose,
1990
- lastEventId
1991
- } = options;
1992
- const processedIds = /* @__PURE__ */ new Set();
1993
- let retryCount = 0;
1994
- return new Promise((resolve, reject) => {
1995
- let es = null;
1996
- let isClosed = false;
1997
- const cleanup = () => {
1998
- if (!isClosed) {
1999
- isClosed = true;
2000
- es?.close();
2001
- onClose?.();
2002
- resolve();
2003
- }
2004
- };
2005
- const abortHandler = () => {
2006
- cleanup();
2007
- };
2008
- signal?.addEventListener("abort", abortHandler);
2009
- const connect = () => {
2010
- if (isClosed || signal?.aborted) {
2011
- return;
2012
- }
2013
- es = new import_react_native_sse.default(url, {
2014
- method: "POST",
2015
- headers: {
2016
- "Content-Type": "application/json",
2017
- ...lastEventId ? { "Last-Event-ID": lastEventId } : {},
2018
- ...headers
2019
- },
2020
- body: JSON.stringify({ ...body, stream: true }),
2021
- pollingInterval: 0
2022
- // Disable polling, we handle reconnection manually
2023
- });
2024
- es.addEventListener("open", () => {
2025
- retryCount = 0;
2026
- onOpen?.();
2027
- });
2028
- const eventTypes = [
2029
- "init",
2030
- "session",
2031
- "entry",
2032
- "stream_event",
2033
- "content_block_start",
2034
- "content_block_delta",
2035
- "content_block_stop",
2036
- "complete",
2037
- "error",
2038
- "heartbeat"
2039
- ];
2040
- for (const eventType of eventTypes) {
2041
- es.addEventListener(eventType, (event) => {
2042
- console.log(`[RN-SSE] Received ${eventType} event:`, event.data?.substring?.(0, 100) || event.data);
2043
- const eventData = {
2044
- data: event.data,
2045
- lastEventId: event.lastEventId ?? void 0
2046
- };
2047
- handleSSEEvent(eventType, eventData, emitter, processedIds);
2048
- });
2049
- }
2050
- es.addEventListener("message", (event) => {
2051
- console.log("[RN-SSE] Received message event:", event.data?.substring?.(0, 100) || event.data);
2052
- const eventData = {
2053
- data: event.data,
2054
- lastEventId: event.lastEventId ?? void 0
2055
- };
2056
- handleSSEEvent("message", eventData, emitter, processedIds);
2057
- });
2058
- es.addEventListener("error", (event) => {
2059
- console.log("[RN-SSE] Error event:", JSON.stringify(event));
2060
- if (signal?.aborted || isClosed) {
2061
- cleanup();
2062
- return;
2063
- }
2064
- const errorMessage = event.message || "Connection error";
2065
- const status = event.xhrStatus;
2066
- if (status === 401 || status === 403 || errorMessage.includes("401") || errorMessage.includes("403") || errorMessage.includes("Authentication")) {
2067
- const authError = `Authentication failed (${status || "unknown"}): ${errorMessage}`;
2068
- console.log("[RN-SSE] Auth error detected:", authError);
2069
- emitter.emit("error", { error: authError });
2070
- cleanup();
2071
- reject(new Error(authError));
2072
- return;
2073
- }
2074
- if (errorMessage.includes("404")) {
2075
- emitter.emit("error", { error: "Session not found or not active" });
2076
- cleanup();
2077
- reject(new Error("Session not found or not active"));
2078
- return;
2079
- }
2080
- if (errorMessage.includes("503")) {
2081
- emitter.emit("error", { error: `Server unavailable: ${errorMessage}` });
2082
- cleanup();
2083
- reject(new Error(errorMessage));
2084
- return;
2085
- }
2086
- retryCount++;
2087
- if (retryCount > MAX_RETRIES2) {
2088
- const error = `Connection failed after ${MAX_RETRIES2} retries`;
2089
- emitter.emit("error", { error });
2090
- cleanup();
2091
- reject(new Error(error));
2092
- return;
2093
- }
2094
- const delay = Math.min(
2095
- INITIAL_RETRY_DELAY2 * Math.pow(2, retryCount - 1),
2096
- MAX_RETRY_DELAY2
2097
- );
2098
- console.log(`[RN-SSE] Retry ${retryCount}/${MAX_RETRIES2} in ${delay}ms`);
2099
- es?.close();
2100
- setTimeout(connect, delay);
2101
- });
2102
- es.addEventListener("close", () => {
2103
- cleanup();
2104
- });
2105
- };
2106
- connect();
2107
- });
2108
- }
2109
- function handleSSEEvent(eventType, event, emitter, processedIds) {
2110
- if (event.lastEventId && processedIds.has(event.lastEventId)) {
2111
- return;
2112
- }
2113
- if (event.lastEventId) {
2114
- processedIds.add(event.lastEventId);
2115
- }
2116
- if (!event.data) {
2117
- return;
2118
- }
2119
- try {
2120
- const data = JSON.parse(event.data);
2121
- switch (eventType) {
2122
- case "init":
2123
- case "session":
2124
- emitter.emit("session", { session_id: data.session_id });
2125
- break;
2126
- case "entry":
2127
- emitter.emit("entry", { entry: data });
2128
- break;
2129
- case "stream_event":
2130
- handleStreamEvent2(data, emitter);
2131
- break;
2132
- case "content_block_start":
2133
- emitter.emit("content_block_start", data);
2134
- break;
2135
- case "content_block_delta":
2136
- emitter.emit("content_block_delta", data);
2137
- break;
2138
- case "content_block_stop":
2139
- emitter.emit("content_block_stop", data);
2140
- break;
2141
- case "complete":
2142
- emitter.emit("complete", data);
2143
- break;
2144
- case "error":
2145
- emitter.emit("error", { error: data.error });
2146
- break;
2147
- case "heartbeat":
2148
- emitter.emit("heartbeat", {});
2149
- break;
2150
- case "message":
2151
- if (data.type) {
2152
- handleSSEEvent(data.type, { data: JSON.stringify(data) }, emitter, processedIds);
2153
- }
2154
- break;
2155
- default:
2156
- break;
2157
- }
2158
- } catch (e) {
2159
- console.error("[RN-SSE] Failed to parse event:", event.data, e);
2160
- }
2161
- }
2162
- function handleStreamEvent2(data, emitter) {
2163
- const streamEvent = data.event || data;
2164
- const eventData = streamEvent;
2165
- switch (eventData.type) {
2166
- case "content_block_start":
2167
- emitter.emit("content_block_start", eventData);
2168
- break;
2169
- case "content_block_delta":
2170
- emitter.emit("content_block_delta", eventData);
2171
- break;
2172
- case "content_block_stop":
2173
- emitter.emit("content_block_stop", eventData);
2174
- break;
2175
- }
2176
- }
2177
-
2178
- // src/react-native/client.ts
2179
- var RNAgentClient = class {
2180
- config;
2181
- baseClient;
2182
- activeStreams = /* @__PURE__ */ new Map();
2183
- constructor(config) {
2184
- this.config = {
2185
- apiVersion: "/v1",
2186
- timeout: 3e4,
2187
- ...config
2188
- };
2189
- this.baseClient = new AgentClient(config);
2190
- }
2191
- // ===========================================================================
2192
- // Public getters
2193
- // ===========================================================================
2194
- /** Whether org context is configured (orgId is set) */
2195
- get hasOrgContext() {
2196
- return this.baseClient.hasOrgContext;
2197
- }
2198
- // ===========================================================================
2199
- // Private helpers
2200
- // ===========================================================================
2201
- get baseUrl() {
2202
- return `${this.config.endpoint}${this.config.apiVersion}`;
2203
- }
2204
- async getHeaders() {
2205
- const headers = {
2206
- "Content-Type": "application/json"
2207
- };
2208
- const token = await this.config.getAuthToken();
2209
- if (token) {
2210
- headers["Authorization"] = `Bearer ${token}`;
2211
- }
2212
- return headers;
2213
- }
2214
- // ===========================================================================
2215
- // Messages API - React Native specific SSE implementation
2216
- // ===========================================================================
2217
- /**
2218
- * Send a message and stream responses using React Native SSE.
2219
- * @returns Object with event emitter and abort function
2220
- */
2221
- stream(request) {
2222
- const emitter = new AgentEventEmitter();
2223
- const controller = new AbortController();
2224
- const streamId = request.session_id || `stream-${Date.now()}`;
2225
- this.activeStreams.set(streamId, controller);
2226
- (async () => {
2227
- try {
2228
- const headers = await this.getHeaders();
2229
- await createRNSSEStream({
2230
- url: `${this.baseUrl}/messages`,
2231
- method: "POST",
2232
- headers,
2233
- body: { ...request, stream: true },
2234
- emitter,
2235
- signal: controller.signal
2236
- });
2237
- } catch (error) {
2238
- emitter.emit("error", {
2239
- error: error instanceof Error ? error.message : "Unknown error"
2240
- });
2241
- } finally {
2242
- this.activeStreams.delete(streamId);
2243
- }
2244
- })();
2245
- return {
2246
- emitter,
2247
- abort: () => controller.abort()
2248
- };
2249
- }
2250
- /**
2251
- * Reconnect to an active streaming session using React Native SSE.
2252
- * @returns Object with event emitter and abort function
2253
- */
2254
- reconnect(sessionId, lastEventId = -1) {
2255
- const emitter = new AgentEventEmitter();
2256
- const controller = new AbortController();
2257
- (async () => {
2258
- try {
2259
- const headers = await this.getHeaders();
2260
- await createRNSSEStream({
2261
- url: `${this.baseUrl}/sessions/${sessionId}/reconnect`,
2262
- method: "POST",
2263
- headers,
2264
- body: { last_event_id: lastEventId },
2265
- emitter,
2266
- signal: controller.signal
2267
- });
2268
- } catch (error) {
2269
- emitter.emit("error", {
2270
- error: error instanceof Error ? error.message : "Unknown error"
2271
- });
2272
- }
2273
- })();
2274
- return {
2275
- emitter,
2276
- abort: () => controller.abort()
2277
- };
2278
- }
2279
- // ===========================================================================
2280
- // Sessions API - Delegate to base client
2281
- // ===========================================================================
2282
- /**
2283
- * List all sessions for the authenticated user.
2284
- */
2285
- async listSessions() {
2286
- return this.baseClient.listSessions();
2287
- }
2288
- /**
2289
- * Get session content in display format.
2290
- */
2291
- async getSession(sessionId) {
2292
- return this.baseClient.getSession(sessionId);
2293
- }
2294
- /**
2295
- * Get session content as raw JSONL.
2296
- */
2297
- async getSessionRaw(sessionId) {
2298
- return this.baseClient.getSessionRaw(sessionId);
2299
- }
2300
- /**
2301
- * Check if a session is actively streaming.
2302
- */
2303
- async getSessionStatus(sessionId) {
2304
- return this.baseClient.getSessionStatus(sessionId);
2305
- }
2306
- /**
2307
- * Update session metadata (name).
2308
- */
2309
- async updateSession(sessionId, updates) {
2310
- return this.baseClient.updateSession(sessionId, updates);
2311
- }
2312
- /**
2313
- * Delete a session.
2314
- */
2315
- async deleteSession(sessionId) {
2316
- return this.baseClient.deleteSession(sessionId);
2317
- }
2318
- /**
2319
- * Cancel an active session query.
2320
- */
2321
- async cancelSession(sessionId) {
2322
- return this.baseClient.cancelSession(sessionId);
2323
- }
2324
- // ===========================================================================
2325
- // Skills API - Personal - Delegate to base client
2326
- // ===========================================================================
2327
- /**
2328
- * List personal skills.
2329
- */
2330
- async listSkills() {
2331
- return this.baseClient.listSkills();
2332
- }
2333
- /**
2334
- * Get personal skill content.
2335
- */
2336
- async getSkill(name) {
2337
- return this.baseClient.getSkill(name);
2338
- }
2339
- /**
2340
- * Create or update a personal skill.
2341
- */
2342
- async saveSkill(skill) {
2343
- return this.baseClient.saveSkill(skill);
2344
- }
2345
- /**
2346
- * Delete a personal skill.
2347
- */
2348
- async deleteSkill(name) {
2349
- return this.baseClient.deleteSkill(name);
2350
- }
2351
- // ===========================================================================
2352
- // Skills API - Organization - Delegate to base client
2353
- // ===========================================================================
2354
- /**
2355
- * List organization skills.
2356
- */
2357
- async listOrgSkills() {
2358
- return this.baseClient.listOrgSkills();
2359
- }
2360
- /**
2361
- * Get organization skill content.
2362
- */
2363
- async getOrgSkill(name) {
2364
- return this.baseClient.getOrgSkill(name);
2365
- }
2366
- /**
2367
- * Create or update an organization skill.
2368
- */
2369
- async saveOrgSkill(skill) {
2370
- return this.baseClient.saveOrgSkill(skill);
2371
- }
2372
- /**
2373
- * Delete an organization skill.
2374
- */
2375
- async deleteOrgSkill(name) {
2376
- return this.baseClient.deleteOrgSkill(name);
2377
- }
2378
- // ===========================================================================
2379
- // Plugins API - Delegate to base client
2380
- // ===========================================================================
2381
- /**
2382
- * Get plugin manifest for client sync.
2383
- */
2384
- async getPluginManifest() {
2385
- return this.baseClient.getPluginManifest();
2386
- }
2387
- /**
2388
- * Download plugin bundle.
2389
- */
2390
- async getPluginBundle(skills) {
2391
- return this.baseClient.getPluginBundle(skills);
2392
- }
2393
- };
2394
- var RNAgentContext = react.createContext(null);
2395
- function RNAgentProvider({
2396
- children,
2397
- config,
2398
- storage,
2399
- pauseOnBackground = true
2400
- }) {
2401
- const [appState, setAppState] = react.useState(reactNative.AppState.currentState);
2402
- react.useEffect(() => {
2403
- if (!pauseOnBackground) return;
2404
- const subscription = reactNative.AppState.addEventListener("change", (nextState) => {
2405
- setAppState(nextState);
2406
- });
2407
- return () => subscription.remove();
2408
- }, [pauseOnBackground]);
2409
- const client = react.useMemo(
2410
- () => new RNAgentClient(config),
2411
- // Only recreate client if endpoint changes
2412
- [config.endpoint, config.apiVersion, config.timeout]
2413
- );
2414
- const value = react.useMemo(
2415
- () => ({ client, storage, appState }),
2416
- [client, storage, appState]
2417
- );
2418
- return /* @__PURE__ */ jsxRuntime.jsx(RNAgentContext.Provider, { value, children });
2419
- }
2420
- function useRNAgentClient() {
2421
- const context = react.useContext(RNAgentContext);
2422
- if (!context) {
2423
- throw new Error("useRNAgentClient must be used within an RNAgentProvider");
2424
- }
2425
- return context.client;
2426
- }
2427
- function useStorage() {
2428
- const context = react.useContext(RNAgentContext);
2429
- if (!context) {
2430
- throw new Error("useStorage must be used within an RNAgentProvider");
2431
- }
2432
- return context.storage;
2433
- }
2434
- function useAppState() {
2435
- const context = react.useContext(RNAgentContext);
2436
- if (!context) {
2437
- throw new Error("useAppState must be used within an RNAgentProvider");
2438
- }
2439
- return context.appState;
2440
- }
2441
- function useRNAgentSession(options = {}) {
2442
- const client = useRNAgentClient();
2443
- const appState = useAppState();
2444
- const {
2445
- initialSessionId,
2446
- initialConversation,
2447
- onMediaGenerated,
2448
- pauseOnBackground = true
2449
- } = options;
2450
- const [session, setSession] = react.useState({
2451
- sessionId: initialSessionId,
2452
- conversation: initialConversation ?? [],
2453
- isStreaming: false
2454
- });
2455
- const abortRef = react.useRef(null);
2456
- const cancelInProgressRef = react.useRef(false);
2457
- const accumulatedTextRef = react.useRef({});
2458
- react.useEffect(() => {
2459
- if (pauseOnBackground && appState !== "active" && session.isStreaming) {
2460
- console.log("[RNAgentSession] App went to background while streaming");
2461
- }
2462
- }, [appState, pauseOnBackground, session.isStreaming]);
2463
- const setupEventHandlers = react.useCallback(
2464
- (emitter) => {
2465
- emitter.on("session", (data) => {
2466
- setSession((prev) => ({ ...prev, sessionId: data.session_id }));
2467
- });
2468
- emitter.on("content_block_start", (data) => {
2469
- const block = data.content_block;
2470
- if (block?.type === "text") {
2471
- accumulatedTextRef.current[data.index] = "";
2472
- setSession((prev) => ({ ...prev, showTinkering: false }));
2473
- } else if (block?.type === "tool_use") {
2474
- setSession((prev) => ({
2475
- ...prev,
2476
- streamingToolCall: {
2477
- tool_name: block.name || "",
2478
- tool_use_id: block.id || "",
2479
- block_index: data.index,
2480
- accumulated_input: ""
2481
- },
2482
- showTinkering: false
2483
- }));
2484
- }
2485
- });
2486
- emitter.on("content_block_delta", (data) => {
2487
- const delta = data.delta;
2488
- if (delta?.type === "text_delta" && delta.text) {
2489
- const idx = data.index ?? 0;
2490
- accumulatedTextRef.current[idx] = (accumulatedTextRef.current[idx] || "") + delta.text;
2491
- setSession((prev) => ({
2492
- ...prev,
2493
- streamingText: accumulatedTextRef.current[idx],
2494
- streamingBlockIndex: idx,
2495
- showTinkering: false
2496
- }));
2497
- } else if (delta?.type === "input_json_delta" && delta.partial_json) {
2498
- setSession((prev) => {
2499
- if (!prev.streamingToolCall) return prev;
2500
- return {
2501
- ...prev,
2502
- streamingToolCall: {
2503
- ...prev.streamingToolCall,
2504
- accumulated_input: (prev.streamingToolCall.accumulated_input || "") + delta.partial_json
2505
- }
2506
- };
2507
- });
2508
- }
2509
- });
2510
- emitter.on("content_block_stop", (data) => {
2511
- const idx = data.index ?? 0;
2512
- if (accumulatedTextRef.current[idx] !== void 0) {
2513
- delete accumulatedTextRef.current[idx];
2514
- setSession((prev) => ({
2515
- ...prev,
2516
- streamingText: void 0,
2517
- streamingBlockIndex: void 0
2518
- }));
2519
- }
2520
- });
2521
- emitter.on("entry", (data) => {
2522
- const entry = data.entry;
2523
- if (entry.type === "tool_result" && onMediaGenerated) {
2524
- const media = extractMediaFromEntry(entry);
2525
- if (media) {
2526
- onMediaGenerated(media.urls, media.type);
2527
- }
2528
- }
2529
- if (entry.type === "tool_call") {
2530
- setSession((prev) => ({
2531
- ...prev,
2532
- conversation: [...prev.conversation, entry],
2533
- streamingToolCall: void 0
2534
- }));
2535
- } else {
2536
- setSession((prev) => ({
2537
- ...prev,
2538
- conversation: [...prev.conversation, entry]
2539
- }));
2540
- }
2541
- });
2542
- emitter.on("complete", (data) => {
2543
- setSession((prev) => ({
2544
- ...prev,
2545
- sessionId: data.session_id || prev.sessionId,
2546
- isStreaming: false,
2547
- showTinkering: false
2548
- }));
2549
- abortRef.current = null;
2550
- });
2551
- emitter.on("error", (data) => {
2552
- setSession((prev) => ({
2553
- ...prev,
2554
- conversation: [
2555
- ...prev.conversation,
2556
- {
2557
- type: "error",
2558
- text: data.error,
2559
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
2560
- }
2561
- ],
2562
- isStreaming: false,
2563
- showTinkering: false
2564
- }));
2565
- abortRef.current = null;
2566
- });
2567
- },
2568
- [onMediaGenerated]
2569
- );
2570
- const sendMessage = react.useCallback(
2571
- async (prompt, skills) => {
2572
- if (!prompt.trim() || session.isStreaming) return;
2573
- const userEntry = {
2574
- type: "user_text",
2575
- text: prompt,
2576
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
2577
- };
2578
- setSession((prev) => ({
2579
- ...prev,
2580
- conversation: [...prev.conversation, userEntry],
2581
- isStreaming: true,
2582
- showTinkering: true
2583
- }));
2584
- accumulatedTextRef.current = {};
2585
- const { emitter, abort } = client.stream({
2586
- prompt,
2587
- session_id: session.sessionId,
2588
- skills
2589
- });
2590
- abortRef.current = abort;
2591
- setupEventHandlers(emitter);
2592
- },
2593
- [client, session.sessionId, session.isStreaming, setupEventHandlers]
2594
- );
2595
- const cancel = react.useCallback(async () => {
2596
- if (cancelInProgressRef.current) {
2597
- return;
2598
- }
2599
- cancelInProgressRef.current = true;
2600
- try {
2601
- if (session.sessionId) {
2602
- try {
2603
- await client.cancelSession(session.sessionId);
2604
- } catch (error) {
2605
- console.error("[RNAgentSession] Server-side cancel failed:", error);
2606
- }
2607
- } else {
2608
- console.warn("[RNAgentSession] No sessionId available for server-side cancel");
2609
- }
2610
- if (abortRef.current) {
2611
- abortRef.current();
2612
- abortRef.current = null;
2613
- }
2614
- setSession((prev) => ({
2615
- ...prev,
2616
- isStreaming: false,
2617
- showTinkering: false,
2618
- streamingText: void 0,
2619
- streamingToolCall: void 0
2620
- }));
2621
- } finally {
2622
- cancelInProgressRef.current = false;
2623
- }
2624
- }, [client, session.sessionId]);
2625
- const clear = react.useCallback(() => {
2626
- setSession({
2627
- conversation: [],
2628
- isStreaming: false
2629
- });
2630
- }, []);
2631
- const setSessionId = react.useCallback((id) => {
2632
- setSession((prev) => ({ ...prev, sessionId: id }));
2633
- }, []);
2634
- const setConversation = react.useCallback(
2635
- (entries, sessionId) => {
2636
- setSession((prev) => ({
2637
- ...prev,
2638
- conversation: entries,
2639
- sessionId: sessionId ?? prev.sessionId,
2640
- isStreaming: false,
2641
- streamingText: void 0,
2642
- streamingToolCall: void 0,
2643
- showTinkering: false
2644
- }));
2645
- },
2646
- []
2647
- );
2648
- const reconnect = react.useCallback(
2649
- async (targetSessionId, freshConversation, streamingPrompt) => {
2650
- let conversation = freshConversation ?? [];
2651
- if (streamingPrompt) {
2652
- conversation = [
2653
- ...conversation,
2654
- {
2655
- type: "user_text",
2656
- text: streamingPrompt,
2657
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
2658
- }
2659
- ];
2660
- }
2661
- setSession((prev) => ({
2662
- ...prev,
2663
- sessionId: targetSessionId,
2664
- conversation,
2665
- isStreaming: true,
2666
- showTinkering: true
2667
- }));
2668
- accumulatedTextRef.current = {};
2669
- const { emitter, abort } = client.reconnect(targetSessionId, -1);
2670
- abortRef.current = abort;
2671
- setupEventHandlers(emitter);
2672
- },
2673
- [client, setupEventHandlers]
2674
- );
2675
- const loadSession = react.useCallback(
2676
- async (sessionId) => {
2677
- const response = await client.getSession(sessionId);
2678
- return response.conversation;
2679
- },
2680
- [client]
2681
- );
2682
- return {
2683
- sessionId: session.sessionId,
2684
- conversation: session.conversation,
2685
- isStreaming: session.isStreaming,
2686
- streamingText: session.streamingText,
2687
- streamingToolCall: session.streamingToolCall,
2688
- showTinkering: session.showTinkering ?? false,
2689
- sendMessage,
2690
- cancel,
2691
- clear,
2692
- reconnect,
2693
- setSessionId,
2694
- setConversation,
2695
- loadSession
2696
- };
2697
- }
2698
- function detectMediaType(url) {
2699
- if (/\.(mp4|mov|webm|avi|mkv|m4v)(\?|$)/i.test(url)) return "video";
2700
- if (/\.(mp3|wav|m4a|aac|ogg)(\?|$)/i.test(url)) return "audio";
2701
- return "image";
2702
- }
2703
- function extractMediaFromEntry(entry) {
2704
- if (entry.type !== "tool_result") return null;
2705
- let result = null;
2706
- if (typeof entry.content === "string") {
2707
- try {
2708
- result = JSON.parse(entry.content);
2709
- } catch {
2710
- return null;
2711
- }
2712
- }
2713
- if (!result) return null;
2714
- const mediaInfo = result.mediaInfo || result.data?.mediaInfo;
2715
- if (mediaInfo?.urls && mediaInfo.urls.length > 0) {
2716
- const type = detectMediaType(mediaInfo.urls[0]);
2717
- return { urls: mediaInfo.urls, type };
2718
- }
2719
- const cdnUrls = result.output_cdn_urls || result.data?.output_cdn_urls;
2720
- if (cdnUrls && cdnUrls.length > 0) {
2721
- const type = detectMediaType(cdnUrls[0]);
2722
- return { urls: cdnUrls, type };
2723
- }
2724
- return null;
2725
- }
2726
- function useJadeSession(options = {}) {
2727
- const {
2728
- skipSkillContext = true,
2729
- processingOptions,
2730
- ...agentOptions
2731
- } = options;
2732
- const session = useRNAgentSession(agentOptions);
2733
- const processedConversation = react.useMemo(() => {
2734
- return processConversation(session.conversation, {
2735
- skipSkillContext,
2736
- pairToolResults: true,
2737
- extractMedia: true,
2738
- ...processingOptions
2739
- });
2740
- }, [session.conversation, skipSkillContext, processingOptions]);
2741
- const media = react.useMemo(() => {
2742
- return extractMedia(session.conversation);
2743
- }, [session.conversation]);
2744
- return {
2745
- ...session,
2746
- processedConversation,
2747
- media
2748
- };
2749
- }
2750
-
2751
- // src/react-native/storage-adapter.ts
2752
- function createAsyncStorageAdapter(asyncStorage) {
2753
- return {
2754
- getItem: (key) => asyncStorage.getItem(key),
2755
- setItem: (key, value) => asyncStorage.setItem(key, value),
2756
- removeItem: (key) => asyncStorage.removeItem(key)
2757
- };
2758
- }
2759
- function createMMKVAdapter(mmkv) {
2760
- return {
2761
- getItem: async (key) => mmkv.getString(key) ?? null,
2762
- setItem: async (key, value) => mmkv.set(key, value),
2763
- removeItem: async (key) => mmkv.delete(key)
2764
- };
2765
- }
2766
- function createMemoryStorageAdapter() {
2767
- const store = /* @__PURE__ */ new Map();
2768
- return {
2769
- getItem: async (key) => store.get(key) ?? null,
2770
- setItem: async (key, value) => {
2771
- store.set(key, value);
2772
- },
2773
- removeItem: async (key) => {
2774
- store.delete(key);
2775
- }
2776
- };
2777
- }
2778
- var STORAGE_KEYS = {
2779
- AUTH_TOKEN: "@gr33n-ai/auth-token",
2780
- ENDPOINT: "@gr33n-ai/endpoint",
2781
- ORG_ID: "@gr33n-ai/org-id",
2782
- LAST_SESSION_ID: "@gr33n-ai/last-session-id",
2783
- USER_PREFERENCES: "@gr33n-ai/user-preferences"
2784
- };
2785
-
2786
- exports.RNAgentProvider = RNAgentProvider;
2787
- exports.STORAGE_KEYS = STORAGE_KEYS;
2788
- exports.createAsyncStorageAdapter = createAsyncStorageAdapter;
2789
- exports.createMMKVAdapter = createMMKVAdapter;
2790
- exports.createMemoryStorageAdapter = createMemoryStorageAdapter;
2791
- exports.useAppState = useAppState;
2792
- exports.useJadeSession = useJadeSession;
2793
- exports.useRNAgentClient = useRNAgentClient;
2794
- exports.useRNAgentSession = useRNAgentSession;
2795
- exports.useStorage = useStorage;