@tangle-network/agent-core 0.2.0

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 (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -0
  3. package/dist/auth/browser.d.ts +22 -0
  4. package/dist/auth/browser.d.ts.map +1 -0
  5. package/dist/auth/browser.js +43 -0
  6. package/dist/auth/browser.js.map +1 -0
  7. package/dist/auth/index.d.ts +430 -0
  8. package/dist/auth/index.d.ts.map +1 -0
  9. package/dist/auth/index.js +841 -0
  10. package/dist/auth/index.js.map +1 -0
  11. package/dist/computer-use/index.d.ts +122 -0
  12. package/dist/computer-use/index.d.ts.map +1 -0
  13. package/dist/computer-use/index.js +422 -0
  14. package/dist/computer-use/index.js.map +1 -0
  15. package/dist/errors-DJ6U6cHY.js +146 -0
  16. package/dist/errors-DJ6U6cHY.js.map +1 -0
  17. package/dist/events/index.d.ts +2 -0
  18. package/dist/events/index.js +2 -0
  19. package/dist/events-CUWh9qrv.js +263 -0
  20. package/dist/events-CUWh9qrv.js.map +1 -0
  21. package/dist/index-CFA8kgHJ.d.ts +352 -0
  22. package/dist/index-CFA8kgHJ.d.ts.map +1 -0
  23. package/dist/index-CtebBodu.d.ts +108 -0
  24. package/dist/index-CtebBodu.d.ts.map +1 -0
  25. package/dist/index-DiQX9bjq.d.ts +55 -0
  26. package/dist/index-DiQX9bjq.d.ts.map +1 -0
  27. package/dist/index-DlPznmKA.d.ts +158 -0
  28. package/dist/index-DlPznmKA.d.ts.map +1 -0
  29. package/dist/index-z2wPdzFb.d.ts +133 -0
  30. package/dist/index-z2wPdzFb.d.ts.map +1 -0
  31. package/dist/index.d.ts +565 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +822 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/resilience/index.d.ts +2 -0
  36. package/dist/resilience/index.js +2 -0
  37. package/dist/resilience-BQzDfw_C.js +221 -0
  38. package/dist/resilience-BQzDfw_C.js.map +1 -0
  39. package/dist/sse/index.d.ts +174 -0
  40. package/dist/sse/index.d.ts.map +1 -0
  41. package/dist/sse/index.js +303 -0
  42. package/dist/sse/index.js.map +1 -0
  43. package/dist/transport/index.d.ts +2 -0
  44. package/dist/transport/index.js +2 -0
  45. package/dist/transport-mKLoQep5.js +427 -0
  46. package/dist/transport-mKLoQep5.js.map +1 -0
  47. package/dist/types/index.d.ts +2 -0
  48. package/dist/types/index.js +2 -0
  49. package/dist/types-D5VLaol0.js +31 -0
  50. package/dist/types-D5VLaol0.js.map +1 -0
  51. package/dist/types-DC6OJ1um.js +331 -0
  52. package/dist/types-DC6OJ1um.js.map +1 -0
  53. package/dist/types-DiDSGM8K.d.ts +320 -0
  54. package/dist/types-DiDSGM8K.d.ts.map +1 -0
  55. package/package.json +132 -0
package/dist/index.js ADDED
@@ -0,0 +1,822 @@
1
+ import { n as isRetryable, r as isSDKError, t as SDKError } from "./errors-DJ6U6cHY.js";
2
+ import { a as ReadTokenPayloadSchema, c as CallbackAuth, d as RefreshableTokenAuth, f as StaticTokenAuth, i as ProjectScopedTokenPayloadSchema, l as NoAuth, n as CreateSessionRequestSchema, o as SendMessageRequestSchema, r as ProductSchema, s as SessionScopedTokenPayloadSchema, t as BatchScopedTokenPayloadSchema, u as ReadTokenAuth } from "./types-DC6OJ1um.js";
3
+ import { EnvTokenAuth, ProductAuth, ProductTokenIssuer, SidecarAuth, canBatchTokenAccessChannel, canProjectTokenAccessChannel, canSessionTokenAccessChannel, canTokenAccessChannel, decodeToken, extractProjectFromChannel, extractSessionFromChannel, generateApiKey, generateSecureToken, generateSigningSecret, getAllowedChannelPatterns, getTokenScope, getTokenTTL, hashApiKey, isBatchScopedToken, isProjectScopedToken, isSessionScopedToken, isTokenExpiringSoon, issueBatchScopedToken, issueProjectScopedToken, issueReadToken, issueSessionScopedToken, validateChannelSubscription, validateTokenScope, verifyApiKey, verifyReadToken } from "./auth/index.js";
4
+ import { n as EventChannel, r as EventBuffer, t as EventDeduplicator } from "./events-CUWh9qrv.js";
5
+ import { a as sleep, c as CircuitOpenError, i as createTimeoutController, n as withProtection, o as withTimeout, r as TimeoutError, s as CircuitBreaker, t as createProtectedFn } from "./resilience-BQzDfw_C.js";
6
+ import { SSEChunkParser, StreamUsageExtractor, consumeSSEStream, createStreamUsageExtractor, createUsageCallback, parseSSEData, parseSSEStream } from "./sse/index.js";
7
+ import { i as DEFAULT_RECONNECTION_CONFIG, n as BaseTransportAdapter, r as ConnectionManager, t as MockTransportAdapter } from "./transport-mKLoQep5.js";
8
+ import { a as isTextPart, i as isSubtaskPart, n as isFilePart, o as isToolPart, r as isReasoningPart, t as AgentEventTypeSchema } from "./types-D5VLaol0.js";
9
+ //#region src/cache/index.ts
10
+ /** In-memory LRU cache */
11
+ var MemoryCache = class {
12
+ cache = /* @__PURE__ */ new Map();
13
+ maxEntries;
14
+ constructor(maxEntries = 1e3) {
15
+ this.maxEntries = maxEntries;
16
+ }
17
+ get(key) {
18
+ const entry = this.cache.get(key);
19
+ if (!entry) return void 0;
20
+ if (Date.now() > entry.expiresAt) {
21
+ this.cache.delete(key);
22
+ return;
23
+ }
24
+ this.cache.delete(key);
25
+ this.cache.set(key, entry);
26
+ return entry;
27
+ }
28
+ set(key, value) {
29
+ if (this.cache.size >= this.maxEntries) {
30
+ const oldest = this.cache.keys().next().value;
31
+ if (oldest) this.cache.delete(oldest);
32
+ }
33
+ this.cache.set(key, value);
34
+ }
35
+ delete(key) {
36
+ this.cache.delete(key);
37
+ }
38
+ clear() {
39
+ this.cache.clear();
40
+ }
41
+ /** Get cache stats */
42
+ stats() {
43
+ return {
44
+ size: this.cache.size,
45
+ maxEntries: this.maxEntries
46
+ };
47
+ }
48
+ };
49
+ /** Response cache manager */
50
+ var ResponseCache = class {
51
+ storage;
52
+ defaultTtlMs;
53
+ keyGenerator;
54
+ constructor(config = {}) {
55
+ this.storage = new MemoryCache(config.maxEntries);
56
+ this.defaultTtlMs = config.defaultTtlMs ?? 6e4;
57
+ this.keyGenerator = config.keyGenerator ?? this.defaultKeyGenerator;
58
+ }
59
+ defaultKeyGenerator(path, params) {
60
+ if (!params || Object.keys(params).length === 0) return path;
61
+ return `${path}?${Object.keys(params).sort().map((k) => `${k}=${JSON.stringify(params[k])}`).join("&")}`;
62
+ }
63
+ /** Get cached response */
64
+ async get(path, params) {
65
+ const key = this.keyGenerator(path, params);
66
+ return (await this.storage.get(key))?.data;
67
+ }
68
+ /** Get with stale-while-revalidate support */
69
+ async getWithMeta(path, params) {
70
+ const key = this.keyGenerator(path, params);
71
+ const entry = await this.storage.get(key);
72
+ if (!entry) return void 0;
73
+ const stale = Date.now() > entry.expiresAt;
74
+ return {
75
+ data: entry.data,
76
+ stale,
77
+ etag: entry.etag
78
+ };
79
+ }
80
+ /** Cache response */
81
+ async set(path, data, options) {
82
+ const key = this.keyGenerator(path, options?.params);
83
+ const now = Date.now();
84
+ const ttl = options?.ttlMs ?? this.defaultTtlMs;
85
+ await this.storage.set(key, {
86
+ data,
87
+ cachedAt: now,
88
+ expiresAt: now + ttl,
89
+ etag: options?.etag
90
+ });
91
+ }
92
+ /** Invalidate cache entry */
93
+ async invalidate(path, params) {
94
+ const key = this.keyGenerator(path, params);
95
+ await this.storage.delete(key);
96
+ }
97
+ /** Invalidate all entries matching prefix */
98
+ async invalidatePrefix(_prefix) {
99
+ if (this.storage instanceof MemoryCache) this.storage.clear();
100
+ }
101
+ /** Clear entire cache */
102
+ async clear() {
103
+ await this.storage.clear();
104
+ }
105
+ /** Parse Cache-Control header */
106
+ static parseCacheControl(header) {
107
+ const result = {};
108
+ const parts = header.split(",").map((p) => p.trim().toLowerCase());
109
+ for (const part of parts) {
110
+ if (part === "no-cache") result.noCache = true;
111
+ if (part === "no-store") result.noStore = true;
112
+ if (part.startsWith("max-age=")) {
113
+ const age = Number.parseInt(part.slice(8), 10);
114
+ if (!Number.isNaN(age)) result.maxAge = age * 1e3;
115
+ }
116
+ }
117
+ return result;
118
+ }
119
+ };
120
+ //#endregion
121
+ //#region src/middleware/index.ts
122
+ /** Interceptor chain executor */
123
+ var InterceptorChain = class {
124
+ interceptors = [];
125
+ /** Add interceptor to chain */
126
+ use(interceptor) {
127
+ this.interceptors.push(interceptor);
128
+ return this;
129
+ }
130
+ /** Remove interceptor */
131
+ remove(interceptor) {
132
+ const idx = this.interceptors.indexOf(interceptor);
133
+ if (idx >= 0) this.interceptors.splice(idx, 1);
134
+ return this;
135
+ }
136
+ /** Run request through interceptors */
137
+ async executeRequest(ctx) {
138
+ let current = ctx;
139
+ for (const interceptor of this.interceptors) if (interceptor.onRequest) current = await interceptor.onRequest(current);
140
+ return current;
141
+ }
142
+ /** Run response through interceptors (reverse order) */
143
+ async executeResponse(ctx) {
144
+ let data = ctx.data;
145
+ for (let i = this.interceptors.length - 1; i >= 0; i--) {
146
+ const interceptor = this.interceptors[i];
147
+ if (interceptor.onResponse) data = await interceptor.onResponse({
148
+ ...ctx,
149
+ data
150
+ });
151
+ }
152
+ return data;
153
+ }
154
+ /** Notify interceptors of error */
155
+ async executeError(ctx) {
156
+ for (const interceptor of this.interceptors) if (interceptor.onError) await interceptor.onError(ctx);
157
+ }
158
+ };
159
+ /** Generate unique request ID */
160
+ function generateRequestId() {
161
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
162
+ }
163
+ /** Logging interceptor */
164
+ function createLoggingInterceptor(logger = console) {
165
+ return {
166
+ onRequest(ctx) {
167
+ logger.debug?.(`[${ctx.requestId}] ${ctx.request.method ?? "GET"} ${ctx.request.path}`, { attempt: ctx.attempt });
168
+ return ctx;
169
+ },
170
+ onResponse(ctx) {
171
+ logger.info?.(`[${ctx.request.requestId}] ${ctx.request.request.method ?? "GET"} ${ctx.request.request.path} ${ctx.status ?? 200} (${ctx.durationMs}ms)`);
172
+ return ctx.data;
173
+ },
174
+ onError(ctx) {
175
+ logger.error?.(`[${ctx.request.requestId}] ${ctx.request.request.method ?? "GET"} ${ctx.request.request.path} ${ctx.error.code} (${ctx.durationMs}ms)`, { error: ctx.error.message });
176
+ }
177
+ };
178
+ }
179
+ /** Metrics interceptor */
180
+ function createMetricsInterceptor(onMetric) {
181
+ return {
182
+ onResponse(ctx) {
183
+ onMetric({
184
+ path: ctx.request.request.path,
185
+ method: ctx.request.request.method ?? "GET",
186
+ status: "success",
187
+ durationMs: ctx.durationMs
188
+ });
189
+ return ctx.data;
190
+ },
191
+ onError(ctx) {
192
+ onMetric({
193
+ path: ctx.request.request.path,
194
+ method: ctx.request.request.method ?? "GET",
195
+ status: "error",
196
+ durationMs: ctx.durationMs,
197
+ errorCode: ctx.error.code
198
+ });
199
+ }
200
+ };
201
+ }
202
+ /** Header injection interceptor */
203
+ function createHeaderInterceptor(headers) {
204
+ return { async onRequest(ctx) {
205
+ const h = typeof headers === "function" ? await headers() : headers;
206
+ return {
207
+ ...ctx,
208
+ request: {
209
+ ...ctx.request,
210
+ headers: {
211
+ ...ctx.request.headers,
212
+ ...h
213
+ }
214
+ }
215
+ };
216
+ } };
217
+ }
218
+ //#endregion
219
+ //#region src/storage/index.ts
220
+ /** In-memory storage (default fallback) */
221
+ var MemoryStorage = class {
222
+ data = /* @__PURE__ */ new Map();
223
+ async get(key) {
224
+ const value = this.data.get(key);
225
+ if (!value) return null;
226
+ try {
227
+ return JSON.parse(value);
228
+ } catch {
229
+ return null;
230
+ }
231
+ }
232
+ async set(key, value) {
233
+ this.data.set(key, JSON.stringify(value));
234
+ }
235
+ async delete(key) {
236
+ this.data.delete(key);
237
+ }
238
+ async clear() {
239
+ this.data.clear();
240
+ }
241
+ async keys() {
242
+ return Array.from(this.data.keys());
243
+ }
244
+ };
245
+ /** Browser localStorage wrapper */
246
+ var LocalStorage = class {
247
+ constructor(prefix = "sdk_") {
248
+ this.prefix = prefix;
249
+ }
250
+ key(k) {
251
+ return `${this.prefix}${k}`;
252
+ }
253
+ async get(key) {
254
+ if (typeof localStorage === "undefined") return null;
255
+ const value = localStorage.getItem(this.key(key));
256
+ if (!value) return null;
257
+ try {
258
+ return JSON.parse(value);
259
+ } catch {
260
+ return null;
261
+ }
262
+ }
263
+ async set(key, value) {
264
+ if (typeof localStorage === "undefined") return;
265
+ localStorage.setItem(this.key(key), JSON.stringify(value));
266
+ }
267
+ async delete(key) {
268
+ if (typeof localStorage === "undefined") return;
269
+ localStorage.removeItem(this.key(key));
270
+ }
271
+ async clear() {
272
+ if (typeof localStorage === "undefined") return;
273
+ const keys = await this.keys();
274
+ for (const key of keys) localStorage.removeItem(this.key(key));
275
+ }
276
+ async keys() {
277
+ if (typeof localStorage === "undefined") return [];
278
+ const result = [];
279
+ for (let i = 0; i < localStorage.length; i++) {
280
+ const key = localStorage.key(i);
281
+ if (key?.startsWith(this.prefix)) result.push(key.slice(this.prefix.length));
282
+ }
283
+ return result;
284
+ }
285
+ };
286
+ /** Offline queue manager */
287
+ var OfflineQueue = class {
288
+ storageKey = "offline_queue";
289
+ constructor(storage) {
290
+ this.storage = storage;
291
+ }
292
+ /** Add request to queue */
293
+ async enqueue(request) {
294
+ const queue = await this.getQueue();
295
+ const id = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
296
+ queue.push({
297
+ ...request,
298
+ id,
299
+ createdAt: Date.now(),
300
+ attempts: 0
301
+ });
302
+ await this.storage.set(this.storageKey, queue);
303
+ return id;
304
+ }
305
+ /** Get all queued requests */
306
+ async getQueue() {
307
+ return await this.storage.get(this.storageKey) ?? [];
308
+ }
309
+ /** Get next request to process */
310
+ async peek() {
311
+ return (await this.getQueue())[0] ?? null;
312
+ }
313
+ /** Remove request from queue */
314
+ async dequeue(id) {
315
+ const filtered = (await this.getQueue()).filter((r) => r.id !== id);
316
+ await this.storage.set(this.storageKey, filtered);
317
+ }
318
+ /** Increment attempt count */
319
+ async incrementAttempts(id) {
320
+ const queue = await this.getQueue();
321
+ const request = queue.find((r) => r.id === id);
322
+ if (request) {
323
+ request.attempts++;
324
+ await this.storage.set(this.storageKey, queue);
325
+ }
326
+ }
327
+ /** Get queue size */
328
+ async size() {
329
+ return (await this.getQueue()).length;
330
+ }
331
+ /** Clear queue */
332
+ async clear() {
333
+ await this.storage.delete(this.storageKey);
334
+ }
335
+ /** Process queue with handler */
336
+ async process(handler, options) {
337
+ const maxAttempts = options?.maxAttempts ?? 3;
338
+ const batchSize = options?.batchSize ?? 10;
339
+ const queue = await this.getQueue();
340
+ let processed = 0;
341
+ let failed = 0;
342
+ for (let i = 0; i < Math.min(queue.length, batchSize); i++) {
343
+ const request = queue[i];
344
+ if (request.attempts >= maxAttempts) {
345
+ await this.dequeue(request.id);
346
+ failed++;
347
+ continue;
348
+ }
349
+ try {
350
+ if (await handler(request)) {
351
+ await this.dequeue(request.id);
352
+ processed++;
353
+ } else await this.incrementAttempts(request.id);
354
+ } catch {
355
+ await this.incrementAttempts(request.id);
356
+ }
357
+ }
358
+ return {
359
+ processed,
360
+ failed
361
+ };
362
+ }
363
+ };
364
+ /** Detect available storage */
365
+ function detectStorage() {
366
+ if (typeof localStorage !== "undefined") return new LocalStorage();
367
+ return new MemoryStorage();
368
+ }
369
+ //#endregion
370
+ //#region src/platform/index.ts
371
+ /**
372
+ * Platform Abstraction Layer
373
+ *
374
+ * Interfaces and adapters that enable the SDK to run across
375
+ * mobile, desktop, TUI, and web without vendor lock-in.
376
+ *
377
+ * Each platform provides its own implementations:
378
+ * - Web: localStorage, navigator.onLine, fetch
379
+ * - React Native: AsyncStorage, NetInfo, fetch polyfill
380
+ * - Electron: electron-store, net module, node-fetch
381
+ * - Tauri: tauri-plugin-store, tauri events, fetch
382
+ * - Node/TUI: fs-based, always online, node-fetch
383
+ */
384
+ /**
385
+ * In-memory secure storage fallback.
386
+ * NOT SECURE - use only for development/testing.
387
+ */
388
+ var MemorySecureStorage = class {
389
+ credentials = /* @__PURE__ */ new Map();
390
+ async setCredential(key, value) {
391
+ this.credentials.set(key, value);
392
+ }
393
+ async getCredential(key) {
394
+ return this.credentials.get(key) ?? null;
395
+ }
396
+ async deleteCredential(key) {
397
+ this.credentials.delete(key);
398
+ }
399
+ async isAvailable() {
400
+ return true;
401
+ }
402
+ };
403
+ /**
404
+ * Browser-based network info using navigator.onLine.
405
+ */
406
+ var BrowserNetworkInfo = class {
407
+ isOnline() {
408
+ return typeof navigator !== "undefined" ? navigator.onLine : true;
409
+ }
410
+ onConnectivityChange(callback) {
411
+ if (typeof window === "undefined") return () => {};
412
+ const onOnline = () => callback(true);
413
+ const onOffline = () => callback(false);
414
+ window.addEventListener("online", onOnline);
415
+ window.addEventListener("offline", onOffline);
416
+ return () => {
417
+ window.removeEventListener("online", onOnline);
418
+ window.removeEventListener("offline", onOffline);
419
+ };
420
+ }
421
+ getConnectionType() {
422
+ const nav = navigator;
423
+ if (nav.connection?.type) {
424
+ const type = nav.connection.type;
425
+ if (type === "wifi") return "wifi";
426
+ if (type === "cellular") return "cellular";
427
+ if (type === "ethernet") return "ethernet";
428
+ }
429
+ return "unknown";
430
+ }
431
+ };
432
+ /**
433
+ * Node.js network info (assumes always online).
434
+ */
435
+ var NodeNetworkInfo = class {
436
+ isOnline() {
437
+ return true;
438
+ }
439
+ onConnectivityChange(_callback) {
440
+ return () => {};
441
+ }
442
+ };
443
+ /**
444
+ * Storage-based persistence adapter.
445
+ * Uses provided Storage implementation for state persistence.
446
+ */
447
+ var StoragePersistence = class {
448
+ constructor(storage) {
449
+ this.storage = storage;
450
+ }
451
+ async saveState(namespace, state) {
452
+ await this.storage.set(`state:${namespace}`, state);
453
+ }
454
+ async loadState(namespace) {
455
+ return this.storage.get(`state:${namespace}`);
456
+ }
457
+ async clearState(namespace) {
458
+ await this.storage.delete(`state:${namespace}`);
459
+ }
460
+ };
461
+ /**
462
+ * Browser persistence with localStorage and storage events for tab sync.
463
+ */
464
+ var BrowserPersistence = class {
465
+ prefix;
466
+ constructor(prefix = "sdk_state:") {
467
+ this.prefix = prefix;
468
+ }
469
+ async saveState(namespace, state) {
470
+ if (typeof localStorage === "undefined") return;
471
+ localStorage.setItem(`${this.prefix}${namespace}`, JSON.stringify(state));
472
+ }
473
+ async loadState(namespace) {
474
+ if (typeof localStorage === "undefined") return null;
475
+ const value = localStorage.getItem(`${this.prefix}${namespace}`);
476
+ if (!value) return null;
477
+ try {
478
+ return JSON.parse(value);
479
+ } catch {
480
+ return null;
481
+ }
482
+ }
483
+ async clearState(namespace) {
484
+ if (typeof localStorage === "undefined") return;
485
+ localStorage.removeItem(`${this.prefix}${namespace}`);
486
+ }
487
+ onExternalChange(namespace, callback) {
488
+ if (typeof window === "undefined") return () => {};
489
+ const key = `${this.prefix}${namespace}`;
490
+ const handler = (event) => {
491
+ if (event.key === key && event.newValue) try {
492
+ callback(JSON.parse(event.newValue));
493
+ } catch {}
494
+ };
495
+ window.addEventListener("storage", handler);
496
+ return () => window.removeEventListener("storage", handler);
497
+ }
498
+ };
499
+ /**
500
+ * Detect current platform.
501
+ */
502
+ function detectPlatform() {
503
+ if (typeof window !== "undefined" && "__TAURI__" in window) return "tauri";
504
+ if (typeof process !== "undefined" && process.versions && "electron" in process.versions) return "electron";
505
+ if (typeof navigator !== "undefined" && navigator.product === "ReactNative") return "react-native";
506
+ if (typeof window !== "undefined" && typeof document !== "undefined") return "web";
507
+ return "node";
508
+ }
509
+ /**
510
+ * Create default platform adapter for current environment.
511
+ * Override with platform-specific implementations for better integration.
512
+ */
513
+ function createDefaultPlatformAdapter() {
514
+ const platform = detectPlatform();
515
+ const isBrowser = platform === "web" || platform === "tauri";
516
+ const storage = detectStorage();
517
+ return {
518
+ capabilities: {
519
+ platform,
520
+ supportsBackground: platform === "node" || platform === "electron",
521
+ supportsSecureStorage: false,
522
+ supportsWebSocket: true,
523
+ supportsSSE: true,
524
+ maxConnections: isBrowser ? 6 : void 0
525
+ },
526
+ storage,
527
+ secureStorage: new MemorySecureStorage(),
528
+ network: isBrowser ? new BrowserNetworkInfo() : new NodeNetworkInfo(),
529
+ persistence: isBrowser ? new BrowserPersistence() : new StoragePersistence(storage),
530
+ fetch: globalThis.fetch.bind(globalThis)
531
+ };
532
+ }
533
+ /**
534
+ * Type-safe platform adapter factory.
535
+ * Use this to create platform adapters with proper typing.
536
+ */
537
+ function createPlatformAdapter(config) {
538
+ return {
539
+ ...createDefaultPlatformAdapter(),
540
+ ...config
541
+ };
542
+ }
543
+ //#endregion
544
+ //#region src/retry/index.ts
545
+ /**
546
+ * Request Retry Logic
547
+ *
548
+ * Per-request retry with exponential backoff and idempotency.
549
+ */
550
+ const DEFAULT_RETRY_CONFIG = {
551
+ maxAttempts: 3,
552
+ initialDelayMs: 1e3,
553
+ maxDelayMs: 3e4,
554
+ multiplier: 2,
555
+ jitter: .2
556
+ };
557
+ /** Calculate delay for attempt with jitter */
558
+ function calculateDelay(attempt, config) {
559
+ const { initialDelayMs, maxDelayMs, multiplier, jitter } = {
560
+ ...DEFAULT_RETRY_CONFIG,
561
+ ...config
562
+ };
563
+ const baseDelay = Math.min(initialDelayMs * multiplier ** attempt, maxDelayMs);
564
+ const jitterRange = baseDelay * jitter;
565
+ const jitterValue = Math.random() * jitterRange * 2 - jitterRange;
566
+ return Math.max(0, Math.floor(baseDelay + jitterValue));
567
+ }
568
+ /** Execute function with retry */
569
+ async function withRetry(fn, config = {}) {
570
+ const maxAttempts = config.maxAttempts ?? DEFAULT_RETRY_CONFIG.maxAttempts;
571
+ let lastError = null;
572
+ for (let attempt = 0; attempt < maxAttempts; attempt++) try {
573
+ return await fn(attempt);
574
+ } catch (error) {
575
+ lastError = SDKError.fromError(error);
576
+ if (!(config.shouldRetry ? config.shouldRetry(lastError, attempt) : isRetryable(lastError)) || attempt >= maxAttempts - 1) throw lastError;
577
+ const delay = lastError.retryAfterMs ?? calculateDelay(attempt, config);
578
+ config.onRetry?.(lastError, attempt + 1, delay);
579
+ await sleep$1(delay);
580
+ }
581
+ throw lastError ?? new SDKError("Max retries exceeded", { code: "UNKNOWN" });
582
+ }
583
+ /** Sleep utility */
584
+ function sleep$1(ms) {
585
+ return new Promise((resolve) => setTimeout(resolve, ms));
586
+ }
587
+ /** Idempotency key generator */
588
+ function generateIdempotencyKey() {
589
+ return `idem_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
590
+ }
591
+ /** Retry decorator for class methods */
592
+ function Retryable(config = {}) {
593
+ return (_target, _propertyKey, descriptor) => {
594
+ const original = descriptor.value;
595
+ if (!original) return descriptor;
596
+ descriptor.value = async function(...args) {
597
+ return withRetry((_attempt) => {
598
+ return original.apply(this, args);
599
+ }, config);
600
+ };
601
+ return descriptor;
602
+ };
603
+ }
604
+ //#endregion
605
+ //#region src/telemetry/genai-attributes.ts
606
+ /**
607
+ * OpenTelemetry GenAI semantic-convention span attributes — the single
608
+ * vocabulary every trace producer in the stack emits and the intelligence
609
+ * ingest reads, so model / token / cost attribution is identical regardless of
610
+ * which producer lowered the span (workflow emitter, SDK trace sink, …).
611
+ *
612
+ * Writers emit the PRIMARY keys (`GEN_AI_*`). The ingest reader accepts the
613
+ * wider candidate lists (`GEN_AI_*_KEYS`) because foreign SDKs spell the same
614
+ * field differently (Langfuse, raw OTLP GenAI, our own legacy `model`).
615
+ * Co-locating writer keys and reader candidates here is the drift guard: a
616
+ * writer's key and the reader's first candidate can never silently disagree.
617
+ *
618
+ * Spec: OpenTelemetry GenAI semantic conventions (`gen_ai.*`).
619
+ */
620
+ /** Model that served a request — the primary key writers emit. */
621
+ const GEN_AI_REQUEST_MODEL = "gen_ai.request.model";
622
+ /** Model named on a response — a reader fallback; writers prefer request.model. */
623
+ const GEN_AI_RESPONSE_MODEL = "gen_ai.response.model";
624
+ /** Prompt / input token count. */
625
+ const GEN_AI_USAGE_INPUT_TOKENS = "gen_ai.usage.input_tokens";
626
+ /** Completion / output token count. */
627
+ const GEN_AI_USAGE_OUTPUT_TOKENS = "gen_ai.usage.output_tokens";
628
+ /** Operation name (e.g. `"invoke_agent"`). */
629
+ const GEN_AI_OPERATION_NAME = "gen_ai.operation.name";
630
+ /** Conversation / session id grouping a multi-turn agent run. */
631
+ const GEN_AI_CONVERSATION_ID = "gen_ai.conversation.id";
632
+ /**
633
+ * Reader candidate keys for the model, highest priority first. The first entry
634
+ * is the writers' primary key; the rest accept foreign-SDK spellings.
635
+ */
636
+ const GEN_AI_MODEL_KEYS = Object.freeze([
637
+ GEN_AI_REQUEST_MODEL,
638
+ GEN_AI_RESPONSE_MODEL,
639
+ "llm.model_name",
640
+ "model"
641
+ ]);
642
+ /** Reader candidate keys for input tokens, highest priority first. These name
643
+ * SPAN ATTRIBUTES on a lowered span — for the raw producer `tokenUsage` OBJECT
644
+ * field names (a distinct layer) see `TOKEN_USAGE_INPUT_KEYS` in
645
+ * `token-usage.ts`; a new producer shape may need an entry in both. */
646
+ const GEN_AI_INPUT_TOKEN_KEYS = Object.freeze([
647
+ GEN_AI_USAGE_INPUT_TOKENS,
648
+ "gen_ai.usage.prompt_tokens",
649
+ "llm.token_count.prompt"
650
+ ]);
651
+ /** Reader candidate keys for output tokens, highest priority first. */
652
+ const GEN_AI_OUTPUT_TOKEN_KEYS = Object.freeze([
653
+ GEN_AI_USAGE_OUTPUT_TOKENS,
654
+ "gen_ai.usage.completion_tokens",
655
+ "llm.token_count.completion"
656
+ ]);
657
+ function isNonNegativeFinite(n) {
658
+ return typeof n === "number" && Number.isFinite(n) && n >= 0;
659
+ }
660
+ /**
661
+ * Lower a usage record to the GenAI semantic-convention attribute bag, OMITTING
662
+ * any unknown field. A synthesized zero token count or empty model would
663
+ * corrupt every downstream token/cost aggregate, so absent stays absent — the
664
+ * ingest then reads "cost not computed", never "free". This is the writer-side
665
+ * mirror of {@link GEN_AI_MODEL_KEYS} / the `*_TOKEN_KEYS` reader candidates.
666
+ */
667
+ function genAiUsageAttributes(usage) {
668
+ const attrs = {};
669
+ if (typeof usage.model === "string" && usage.model.length > 0) attrs[GEN_AI_REQUEST_MODEL] = usage.model;
670
+ if (isNonNegativeFinite(usage.inputTokens)) attrs[GEN_AI_USAGE_INPUT_TOKENS] = usage.inputTokens;
671
+ if (isNonNegativeFinite(usage.outputTokens)) attrs[GEN_AI_USAGE_OUTPUT_TOKENS] = usage.outputTokens;
672
+ return attrs;
673
+ }
674
+ //#endregion
675
+ //#region src/telemetry/token-usage.ts
676
+ /**
677
+ * Candidate field names for a producer-supplied `tokenUsage` bag on a
678
+ * `message.updated` trace event. Agents and SDK layers disagree on the
679
+ * spelling: `StreamTokenUsage` emits `inputTokens`/`outputTokens`, the eval and
680
+ * workflow agent.run paths emit `input`/`output`, and persisted / foreign
681
+ * shapes use snake_case or prompt/completion naming. A reader that wants the
682
+ * token counts must try all of them, highest-priority first, or it silently
683
+ * drops usage for the producers it does not name.
684
+ *
685
+ * Shared so every `tokenUsage` reader (the trace sink's root-span aggregation,
686
+ * the signal extractor) keys off the identical set and cannot drift.
687
+ *
688
+ * Distinct layer from `genai-attributes.ts`: those keys (`GEN_AI_*_TOKEN_KEYS`)
689
+ * name OTel SPAN ATTRIBUTES on an already-lowered span; these name the fields of
690
+ * the raw producer `tokenUsage` OBJECT before lowering. A new producer that
691
+ * spells token usage differently may need an entry in BOTH places.
692
+ */
693
+ const TOKEN_USAGE_INPUT_KEYS = Object.freeze([
694
+ "inputTokens",
695
+ "input",
696
+ "input_tokens",
697
+ "promptTokens",
698
+ "prompt_tokens"
699
+ ]);
700
+ const TOKEN_USAGE_OUTPUT_KEYS = Object.freeze([
701
+ "outputTokens",
702
+ "output",
703
+ "output_tokens",
704
+ "completionTokens",
705
+ "completion_tokens"
706
+ ]);
707
+ //#endregion
708
+ //#region src/utils/channel-matching.ts
709
+ /**
710
+ * Channel Pattern Matching
711
+ *
712
+ * Generic utility for matching channel patterns with wildcard support.
713
+ * Used for channel subscriptions and event filtering.
714
+ *
715
+ * Pattern syntax:
716
+ * - "*" matches all channels
717
+ * - "foo.*" matches "foo.bar", "foo.baz", etc. (dot-separated)
718
+ * - "foo:*" matches "foo:bar", "foo:baz", etc. (colon-separated)
719
+ * - "foo.bar" matches exactly "foo.bar"
720
+ * - "session:abc" matches exactly "session:abc"
721
+ */
722
+ /**
723
+ * Check if a pattern matches a channel name.
724
+ *
725
+ * @param pattern - The pattern to match against (supports wildcards)
726
+ * @param channel - The channel name to check
727
+ * @returns true if the pattern matches the channel
728
+ */
729
+ function matchesChannel(pattern, channel) {
730
+ if (pattern === "*") return true;
731
+ if (pattern.endsWith(".*")) {
732
+ const prefix = pattern.slice(0, -2);
733
+ return channel.startsWith(`${prefix}.`);
734
+ }
735
+ if (pattern.endsWith(":*")) {
736
+ const prefix = pattern.slice(0, -2);
737
+ return channel.startsWith(`${prefix}:`) && channel.length > prefix.length + 1;
738
+ }
739
+ return pattern === channel;
740
+ }
741
+ /**
742
+ * Check if any subscribed channel pattern matches the given channel.
743
+ *
744
+ * @param subscribedChannels - Set or array of channel patterns
745
+ * @param channel - The channel to check
746
+ * @returns true if any pattern matches the channel
747
+ */
748
+ function matchesAnyChannel(subscribedChannels, channel) {
749
+ return (Array.isArray(subscribedChannels) ? subscribedChannels : Array.from(subscribedChannels)).some((pattern) => matchesChannel(pattern, channel));
750
+ }
751
+ //#endregion
752
+ //#region src/utils/session-translator.ts
753
+ /**
754
+ * Escape special regex characters in a string.
755
+ */
756
+ function escapeRegex(str) {
757
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
758
+ }
759
+ /**
760
+ * Translate session IDs in an event object.
761
+ * Performs a deep string replacement via JSON serialization.
762
+ *
763
+ * @param event - The event object to translate
764
+ * @param translation - The session ID mapping
765
+ * @returns A new event object with translated session IDs
766
+ */
767
+ function translateSessionId(event, translation) {
768
+ if (!event || typeof event !== "object") return event;
769
+ if (translation.from === translation.to) return event;
770
+ if (!translation.from) return event;
771
+ try {
772
+ const json = JSON.stringify(event);
773
+ const pattern = new RegExp(escapeRegex(translation.from), "g");
774
+ const translated = json.replace(pattern, translation.to);
775
+ if (translated !== json) return JSON.parse(translated);
776
+ return event;
777
+ } catch {
778
+ return event;
779
+ }
780
+ }
781
+ /**
782
+ * Create a reusable translator function for a specific session mapping.
783
+ * Pre-compiles the regex pattern for better performance when translating
784
+ * many events with the same mapping.
785
+ */
786
+ function createSessionTranslator(translation) {
787
+ const pattern = new RegExp(escapeRegex(translation.from), "g");
788
+ return (event) => {
789
+ if (!event || typeof event !== "object") return event;
790
+ if (translation.from === translation.to || !translation.from) return event;
791
+ try {
792
+ const json = JSON.stringify(event);
793
+ const translated = json.replace(pattern, translation.to);
794
+ if (translated !== json) return JSON.parse(translated);
795
+ return event;
796
+ } catch {
797
+ return event;
798
+ }
799
+ };
800
+ }
801
+ /**
802
+ * Extract session ID from various event structures.
803
+ * Handles different event formats that may contain session information.
804
+ */
805
+ function extractSessionId(event) {
806
+ if (!event || typeof event !== "object") return null;
807
+ const obj = event;
808
+ if (typeof obj.sessionId === "string") return obj.sessionId;
809
+ if (obj.properties && typeof obj.properties === "object") {
810
+ const props = obj.properties;
811
+ if (typeof props.sessionId === "string") return props.sessionId;
812
+ }
813
+ if (obj.data && typeof obj.data === "object") {
814
+ const data = obj.data;
815
+ if (typeof data.sessionId === "string") return data.sessionId;
816
+ }
817
+ return null;
818
+ }
819
+ //#endregion
820
+ export { AgentEventTypeSchema, BaseTransportAdapter, BatchScopedTokenPayloadSchema, BrowserNetworkInfo, BrowserPersistence, CallbackAuth, CircuitBreaker, CircuitOpenError, ConnectionManager, CreateSessionRequestSchema, DEFAULT_RECONNECTION_CONFIG, EnvTokenAuth, EventBuffer, EventChannel, EventDeduplicator, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, InterceptorChain, LocalStorage, MemoryCache, MemorySecureStorage, MemoryStorage, MockTransportAdapter, NoAuth, NodeNetworkInfo, OfflineQueue, ProductAuth, ProductSchema, ProductTokenIssuer, ProjectScopedTokenPayloadSchema, ReadTokenAuth, ReadTokenPayloadSchema, RefreshableTokenAuth, ResponseCache, Retryable, SDKError, SSEChunkParser, SendMessageRequestSchema, SessionScopedTokenPayloadSchema, SidecarAuth, StaticTokenAuth, StoragePersistence, StreamUsageExtractor, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, TimeoutError, calculateDelay, canBatchTokenAccessChannel, canProjectTokenAccessChannel, canSessionTokenAccessChannel, canTokenAccessChannel, consumeSSEStream, createDefaultPlatformAdapter, createHeaderInterceptor, createLoggingInterceptor, createMetricsInterceptor, createPlatformAdapter, createProtectedFn, createSessionTranslator, createStreamUsageExtractor, createTimeoutController, createUsageCallback, decodeToken, detectPlatform, detectStorage, extractProjectFromChannel, extractSessionFromChannel, extractSessionId, genAiUsageAttributes, generateApiKey, generateIdempotencyKey, generateRequestId, generateSecureToken, generateSigningSecret, getAllowedChannelPatterns, getTokenScope, getTokenTTL, hashApiKey, isBatchScopedToken, isFilePart, isProjectScopedToken, isReasoningPart, isRetryable, isSDKError, isSessionScopedToken, isSubtaskPart, isTextPart, isTokenExpiringSoon, isToolPart, issueBatchScopedToken, issueProjectScopedToken, issueReadToken, issueSessionScopedToken, matchesAnyChannel, matchesChannel, parseSSEData, parseSSEStream, sleep, translateSessionId, validateChannelSubscription, validateTokenScope, verifyApiKey, verifyReadToken, withProtection, withRetry, withTimeout };
821
+
822
+ //# sourceMappingURL=index.js.map