@athenaintel/react 0.10.41 → 0.11.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.
package/dist/index.js CHANGED
@@ -18,10 +18,10 @@ var __privateWrapper = (obj, member, setter, getter) => ({
18
18
  }
19
19
  });
20
20
  var _focused, _cleanup, _setup, _a2, _provider, _providerCalled, _b, _online, _cleanup2, _setup2, _c, _gcTimeout, _d, _initialState, _revertState, _cache, _client, _retryer, _defaultOptions, _abortSignalConsumed, _Query_instances, isInitialPausedFetch_fn, dispatch_fn, _e, _client2, _currentQuery, _currentQueryInitialState, _currentResult, _currentResultState, _currentResultOptions, _currentThenable, _selectError, _selectFn, _selectResult, _lastQueryWithDefinedData, _staleTimeoutId, _refetchIntervalId, _currentRefetchInterval, _trackedProps, _QueryObserver_instances, executeFetch_fn, updateStaleTimeout_fn, computeRefetchInterval_fn, updateRefetchInterval_fn, updateTimers_fn, clearStaleTimeout_fn, clearRefetchInterval_fn, updateQuery_fn, notify_fn, _f, _client3, _observers, _mutationCache, _retryer2, _Mutation_instances, dispatch_fn2, _g, _mutations, _scopes, _mutationId, _h, _queries, _i, _queryCache, _mutationCache2, _defaultOptions2, _queryDefaults, _mutationDefaults, _mountCount, _unsubscribeFocus, _unsubscribeOnline, _j;
21
- import { jsx, jsxs, Fragment as Fragment$1 } from "react/jsx-runtime";
22
- import { fromThreadMessageLike, bindExternalStoreMessage, getExternalStoreMessages, INTERNAL, useAssistantTransportRuntime, Tools, useAui, useAuiState, AuiProvider, useRemoteThreadListRuntime, AssistantRuntimeProvider, MessagePartPrimitive, MessagePrimitive, useScrollLock, ActionBarPrimitive, AuiIf, ActionBarMorePrimitive, ThreadPrimitive, ComposerPrimitive, ErrorPrimitive, ThreadListPrimitive, ThreadListItemPrimitive } from "@assistant-ui/react";
21
+ import { jsx, Fragment as Fragment$1, jsxs } from "react/jsx-runtime";
23
22
  import * as React from "react";
24
- import React__default, { useMemo, useState, useRef, useEffect, useContext, createContext, useCallback, useLayoutEffect, useReducer, useDebugValue, forwardRef, createRef, memo, createElement, version as version$1, useImperativeHandle } from "react";
23
+ import React__default, { useEffect, useSyncExternalStore, useCallback, useMemo, useState, useRef, useContext, createContext, useLayoutEffect, useReducer, useDebugValue, forwardRef, createRef, memo, createElement, version as version$2, useImperativeHandle } from "react";
24
+ import { fromThreadMessageLike, bindExternalStoreMessage, getExternalStoreMessages, INTERNAL, useAssistantTransportRuntime, Tools, useAui, useAuiState as useAuiState$1, AuiProvider, useRemoteThreadListRuntime, AssistantRuntimeProvider, MessagePartPrimitive, MessagePrimitive, useScrollLock, ActionBarPrimitive, AuiIf, ActionBarMorePrimitive, ThreadPrimitive, ComposerPrimitive, ErrorPrimitive, ThreadListPrimitive, ThreadListItemPrimitive } from "@assistant-ui/react";
25
25
  import { A as AthenaAuthContext } from "./AthenaAuthContext-DQsdayH2.js";
26
26
  import { LocalStorageSession } from "@assistant-ui/react-statewire/local-storage";
27
27
  import { resource, withKey } from "@assistant-ui/tap";
@@ -29,9 +29,913 @@ import { StatewireSendError, StatewireSSE, StatewireWS } from "statewire";
29
29
  import "@assistant-ui/core";
30
30
  import { createMessageConverter } from "@assistant-ui/core/react";
31
31
  import { convertLangChainMessages } from "@assistant-ui/react-langgraph";
32
- import { runsMaterialize, useStatewireState, StatewireThread, useStatewireSendCommand, useStatewireRuns } from "@assistant-ui/react-statewire";
32
+ import { runsMaterialize, StatewireThread, useStatewireSendCommand, useStatewireRuns, useStatewireState } from "@assistant-ui/react-statewire";
33
+ import { useAuiState } from "@assistant-ui/store";
33
34
  import * as ReactDOM from "react-dom";
34
35
  import ReactDOM__default, { flushSync } from "react-dom";
36
+ const version$1 = "0.11.0";
37
+ const packageJson = {
38
+ version: version$1
39
+ };
40
+ const ATHENA_REACT_SDK_VERSION = packageJson.version;
41
+ const DEFAULT_CAPTURE_GATE_CONFIG = {
42
+ globalMaxPerWindow: 50,
43
+ globalWindowMs: 1e4,
44
+ criticalReservePerWindow: 15,
45
+ defaultEventMaxPerWindow: 12,
46
+ defaultEventWindowMs: 6e4,
47
+ defaultDedupeWindowMs: 5e3,
48
+ flushIntervalMs: 3e4,
49
+ flushCoalesceThreshold: 20,
50
+ eventOverrides: {
51
+ memory_profile_sample: { maxPerWindow: 2, windowMs: 3e4, dedupeWindowMs: 15e3 },
52
+ long_task_detected: { maxPerWindow: 3, windowMs: 6e4, dedupeWindowMs: 1e4 },
53
+ collab_connection_status_changed: { maxPerWindow: 6, windowMs: 6e4 },
54
+ collab_first_remote_update: { maxPerWindow: 3, windowMs: 6e4 },
55
+ collab_first_local_update: { maxPerWindow: 3, windowMs: 6e4 },
56
+ collab_render_time_sync_fix: { maxPerWindow: 3, windowMs: 6e4 },
57
+ collab_visibility_recovery: { maxPerWindow: 4, windowMs: 6e4 },
58
+ langgraph_message_validation_error: {
59
+ maxPerWindow: 8,
60
+ windowMs: 6e4,
61
+ dedupeWindowMs: 15e3
62
+ },
63
+ langgraph_messages_validation_error: {
64
+ maxPerWindow: 5,
65
+ windowMs: 6e4,
66
+ dedupeWindowMs: 15e3
67
+ },
68
+ langgraph_interrupt_validation_error: {
69
+ maxPerWindow: 5,
70
+ windowMs: 6e4,
71
+ dedupeWindowMs: 15e3
72
+ },
73
+ langgraph_state_validation_error: {
74
+ maxPerWindow: 5,
75
+ windowMs: 6e4,
76
+ dedupeWindowMs: 15e3
77
+ },
78
+ graphql_error: { maxPerWindow: 12, windowMs: 6e4, dedupeWindowMs: 1e4 },
79
+ chat_error: { maxPerWindow: 8, windowMs: 6e4, dedupeWindowMs: 5e3 },
80
+ memory_critical_threshold: { maxPerWindow: 3, windowMs: 3e5 },
81
+ memory_warning_threshold: { maxPerWindow: 3, windowMs: 3e5 },
82
+ pptx_slide_changed: { maxPerWindow: 8, windowMs: 3e4 }
83
+ }
84
+ };
85
+ const CRITICAL_EVENT_PATTERNS = [
86
+ /(?:^|_)failed$/,
87
+ /(?:^|_)error(?:_|$)/,
88
+ /crash/,
89
+ /^oom_/,
90
+ /aw_snap/,
91
+ /chunk_load/,
92
+ /global_error/,
93
+ /\$exception$/,
94
+ /^404_error$/,
95
+ /^500_error$/,
96
+ /_boundary_/
97
+ ];
98
+ const BYPASS_OPTION_KEY = "__posthog_gate_bypass";
99
+ function isCriticalPosthogEvent(event) {
100
+ return CRITICAL_EVENT_PATTERNS.some((pattern) => pattern.test(event));
101
+ }
102
+ function shouldBypassCaptureGate(options) {
103
+ if (!options || typeof options !== "object") return false;
104
+ return options[BYPASS_OPTION_KEY] === true;
105
+ }
106
+ function withCaptureGateBypass(options) {
107
+ return {
108
+ ...options ?? {},
109
+ [BYPASS_OPTION_KEY]: true
110
+ };
111
+ }
112
+ function pruneWindow(window2, now, windowMs) {
113
+ const cutoff = now - windowMs;
114
+ while (window2.timestamps.length > 0 && window2.timestamps[0] < cutoff) {
115
+ window2.timestamps.shift();
116
+ }
117
+ }
118
+ function countInWindow(window2, now, windowMs) {
119
+ pruneWindow(window2, now, windowMs);
120
+ return window2.timestamps.length;
121
+ }
122
+ function recordInWindow(window2, now) {
123
+ window2.timestamps.push(now);
124
+ }
125
+ function stableStringify(value) {
126
+ if (value == null) return String(value);
127
+ if (typeof value !== "object") return String(value);
128
+ if (Array.isArray(value)) {
129
+ return `[${value.map((item) => stableStringify(item)).join(",")}]`;
130
+ }
131
+ const record2 = value;
132
+ const keys2 = Object.keys(record2).sort();
133
+ return `{${keys2.map((key) => `${key}:${stableStringify(record2[key])}`).join(",")}}`;
134
+ }
135
+ function fingerprintProperties(properties) {
136
+ if (!properties) return "";
137
+ const keys2 = [
138
+ "error",
139
+ "error_message",
140
+ "message",
141
+ "reason",
142
+ "status",
143
+ "code",
144
+ "asset_id",
145
+ "doc_id",
146
+ "thread_id",
147
+ "session_id",
148
+ "operation",
149
+ "path",
150
+ "url",
151
+ "chunk_identifier",
152
+ "validation_path"
153
+ ];
154
+ const subset = {};
155
+ for (const key of keys2) {
156
+ if (key in properties) {
157
+ subset[key] = properties[key];
158
+ }
159
+ }
160
+ return stableStringify(subset);
161
+ }
162
+ function buildCaptureFingerprint(event, properties) {
163
+ return `${event}|${fingerprintProperties(properties)}`;
164
+ }
165
+ function buildCoalescedCaptureProperties(payload) {
166
+ const windowMs = payload.lastAt - payload.firstAt;
167
+ return {
168
+ ...payload.properties,
169
+ coalesced: true,
170
+ coalesced_count: payload.coalescedCount,
171
+ coalesced_first_at: new Date(payload.firstAt).toISOString(),
172
+ coalesced_last_at: new Date(payload.lastAt).toISOString(),
173
+ coalesced_window_ms: windowMs,
174
+ coalesced_suppression_reason: payload.suppressionReason
175
+ };
176
+ }
177
+ class PosthogCaptureGate {
178
+ constructor(config2 = DEFAULT_CAPTURE_GATE_CONFIG) {
179
+ __publicField(this, "config");
180
+ __publicField(this, "globalWindow", { timestamps: [] });
181
+ __publicField(this, "eventWindows", /* @__PURE__ */ new Map());
182
+ __publicField(this, "activeDedupe", /* @__PURE__ */ new Map());
183
+ __publicField(this, "coalesceBuckets", /* @__PURE__ */ new Map());
184
+ __publicField(this, "emittedTotal", 0);
185
+ __publicField(this, "coalescedTotal", 0);
186
+ __publicField(this, "flushedCoalescedTotal", 0);
187
+ this.config = config2;
188
+ }
189
+ resetForTests() {
190
+ this.globalWindow.timestamps.length = 0;
191
+ this.eventWindows.clear();
192
+ this.activeDedupe.clear();
193
+ this.coalesceBuckets.clear();
194
+ this.emittedTotal = 0;
195
+ this.coalescedTotal = 0;
196
+ this.flushedCoalescedTotal = 0;
197
+ }
198
+ getSnapshot() {
199
+ const coalescedPendingByEvent = {};
200
+ let coalescedPending = 0;
201
+ for (const bucket of this.coalesceBuckets.values()) {
202
+ coalescedPending += bucket.count;
203
+ coalescedPendingByEvent[bucket.event] = (coalescedPendingByEvent[bucket.event] ?? 0) + bucket.count;
204
+ }
205
+ return {
206
+ coalescedPending,
207
+ coalescedPendingByEvent,
208
+ emittedTotal: this.emittedTotal,
209
+ coalescedTotal: this.coalescedTotal,
210
+ flushedCoalescedTotal: this.flushedCoalescedTotal
211
+ };
212
+ }
213
+ evaluateCapture(event, properties, options, now = Date.now()) {
214
+ if (shouldBypassCaptureGate(options)) {
215
+ return { action: "emit" };
216
+ }
217
+ const fingerprint = buildCaptureFingerprint(event, properties);
218
+ const bucketKey = fingerprint;
219
+ const override = this.config.eventOverrides[event];
220
+ const dedupeWindowMs = (override == null ? void 0 : override.dedupeWindowMs) ?? this.config.defaultDedupeWindowMs;
221
+ const lastDedupe = this.activeDedupe.get(event);
222
+ if (lastDedupe && lastDedupe.fingerprint === fingerprint && now - lastDedupe.at < dedupeWindowMs) {
223
+ return this.recordCoalesce(event, bucketKey, fingerprint, properties, "dedupe", now);
224
+ }
225
+ const critical = isCriticalPosthogEvent(event);
226
+ const globalCount = countInWindow(this.globalWindow, now, this.config.globalWindowMs);
227
+ const normalBudget = Math.max(
228
+ 0,
229
+ this.config.globalMaxPerWindow - this.config.criticalReservePerWindow
230
+ );
231
+ if (critical) {
232
+ if (globalCount >= this.config.globalMaxPerWindow) {
233
+ return this.recordCoalesce(event, bucketKey, fingerprint, properties, "global_budget", now);
234
+ }
235
+ } else if (globalCount >= normalBudget) {
236
+ return this.recordCoalesce(event, bucketKey, fingerprint, properties, "global_budget", now);
237
+ }
238
+ const eventWindow = this.eventWindows.get(event) ?? { timestamps: [] };
239
+ this.eventWindows.set(event, eventWindow);
240
+ const eventMax = (override == null ? void 0 : override.maxPerWindow) ?? this.config.defaultEventMaxPerWindow;
241
+ const eventWindowMs = (override == null ? void 0 : override.windowMs) ?? this.config.defaultEventWindowMs;
242
+ const eventCount = countInWindow(eventWindow, now, eventWindowMs);
243
+ if (eventCount >= eventMax) {
244
+ return this.recordCoalesce(event, bucketKey, fingerprint, properties, "event_budget", now);
245
+ }
246
+ recordInWindow(this.globalWindow, now);
247
+ recordInWindow(eventWindow, now);
248
+ this.activeDedupe.set(event, { fingerprint, bucketKey, at: now });
249
+ this.emittedTotal += 1;
250
+ return { action: "emit" };
251
+ }
252
+ /** Returns payloads ready to flush (does not mutate buckets until caller confirms). */
253
+ collectFlushCandidates(now = Date.now()) {
254
+ const payloads = [];
255
+ for (const bucket of this.coalesceBuckets.values()) {
256
+ const shouldFlushBySize = bucket.count >= this.config.flushCoalesceThreshold;
257
+ const shouldFlushByAge = now - bucket.firstAt >= this.config.flushIntervalMs;
258
+ if (!shouldFlushBySize && !shouldFlushByAge) {
259
+ continue;
260
+ }
261
+ payloads.push({
262
+ bucketKey: bucket.bucketKey,
263
+ event: bucket.event,
264
+ properties: bucket.sampleProperties,
265
+ coalescedCount: bucket.count,
266
+ firstAt: bucket.firstAt,
267
+ lastAt: bucket.lastAt,
268
+ suppressionReason: bucket.suppressionReason
269
+ });
270
+ }
271
+ return payloads;
272
+ }
273
+ /** Remove flushed bucket keys after successful emit. */
274
+ acknowledgeFlushed(payloads) {
275
+ for (const payload of payloads) {
276
+ this.coalesceBuckets.delete(payload.bucketKey);
277
+ this.flushedCoalescedTotal += payload.coalescedCount;
278
+ }
279
+ }
280
+ /** After coalescing, flush immediately if the bucket crossed the early threshold. */
281
+ takeBucketIfReady(bucketKey, now = Date.now()) {
282
+ const bucket = this.coalesceBuckets.get(bucketKey);
283
+ if (!bucket) return null;
284
+ const shouldFlushBySize = bucket.count >= this.config.flushCoalesceThreshold;
285
+ const shouldFlushByAge = now - bucket.firstAt >= this.config.flushIntervalMs;
286
+ if (!shouldFlushBySize && !shouldFlushByAge) {
287
+ return null;
288
+ }
289
+ this.coalesceBuckets.delete(bucketKey);
290
+ this.flushedCoalescedTotal += bucket.count;
291
+ return {
292
+ bucketKey: bucket.bucketKey,
293
+ event: bucket.event,
294
+ properties: bucket.sampleProperties,
295
+ coalescedCount: bucket.count,
296
+ firstAt: bucket.firstAt,
297
+ lastAt: bucket.lastAt,
298
+ suppressionReason: bucket.suppressionReason
299
+ };
300
+ }
301
+ /** Force-flush every pending bucket (e.g. page hide). */
302
+ collectAllPending() {
303
+ return [...this.coalesceBuckets.values()].map((bucket) => ({
304
+ bucketKey: bucket.bucketKey,
305
+ event: bucket.event,
306
+ properties: bucket.sampleProperties,
307
+ coalescedCount: bucket.count,
308
+ firstAt: bucket.firstAt,
309
+ lastAt: bucket.lastAt,
310
+ suppressionReason: bucket.suppressionReason
311
+ }));
312
+ }
313
+ recordCoalesce(event, bucketKey, fingerprint, properties, reason, now) {
314
+ const existing = this.coalesceBuckets.get(bucketKey);
315
+ if (existing) {
316
+ existing.count += 1;
317
+ existing.lastAt = now;
318
+ existing.sampleProperties = { ...existing.sampleProperties, ...properties ?? {} };
319
+ } else {
320
+ this.coalesceBuckets.set(bucketKey, {
321
+ event,
322
+ bucketKey,
323
+ fingerprint,
324
+ count: 1,
325
+ firstAt: now,
326
+ lastAt: now,
327
+ suppressionReason: reason,
328
+ sampleProperties: { ...properties ?? {} }
329
+ });
330
+ }
331
+ this.coalescedTotal += 1;
332
+ this.activeDedupe.set(event, { fingerprint, bucketKey, at: now });
333
+ return { action: "coalesce", reason, bucketKey };
334
+ }
335
+ }
336
+ const gate = new PosthogCaptureGate(DEFAULT_CAPTURE_GATE_CONFIG);
337
+ let wrappedClient = null;
338
+ let originalCaptureRef = null;
339
+ let flushTimer = null;
340
+ let lifecycleHooksInstalled = false;
341
+ function getPosthogCaptureGate() {
342
+ return gate;
343
+ }
344
+ function emitThroughOriginal(event, properties, options) {
345
+ if (!originalCaptureRef) return void 0;
346
+ return originalCaptureRef(event, properties, withCaptureGateBypass(options));
347
+ }
348
+ function flushCoalescedPayload(payload) {
349
+ emitThroughOriginal(payload.event, buildCoalescedCaptureProperties(payload));
350
+ }
351
+ function flushCoalescedCaptures(options) {
352
+ const payloads = (options == null ? void 0 : options.force) ? gate.collectAllPending() : gate.collectFlushCandidates();
353
+ if (payloads.length === 0) return;
354
+ for (const payload of payloads) {
355
+ flushCoalescedPayload(payload);
356
+ }
357
+ gate.acknowledgeFlushed(payloads);
358
+ }
359
+ function installLifecycleFlushHooks() {
360
+ if (lifecycleHooksInstalled || typeof window === "undefined") return;
361
+ lifecycleHooksInstalled = true;
362
+ const flushOnHide = () => {
363
+ flushCoalescedCaptures({ force: true });
364
+ };
365
+ window.addEventListener("pagehide", flushOnHide);
366
+ document.addEventListener("visibilitychange", () => {
367
+ if (document.visibilityState === "hidden") {
368
+ flushOnHide();
369
+ }
370
+ });
371
+ if (!flushTimer) {
372
+ flushTimer = setInterval(() => {
373
+ flushCoalescedCaptures();
374
+ }, DEFAULT_CAPTURE_GATE_CONFIG.flushIntervalMs);
375
+ }
376
+ }
377
+ function wrapPosthogClient(client) {
378
+ if (wrappedClient === client) {
379
+ return client;
380
+ }
381
+ originalCaptureRef = client.capture.bind(client);
382
+ const originalCaptureException = typeof client.captureException === "function" ? client.captureException.bind(client) : null;
383
+ installLifecycleFlushHooks();
384
+ client.capture = ((event, properties, options) => {
385
+ const outcome = gate.evaluateCapture(event, properties, options);
386
+ if (outcome.action === "coalesce") {
387
+ const readyPayload = gate.takeBucketIfReady(outcome.bucketKey);
388
+ if (readyPayload) {
389
+ flushCoalescedPayload(readyPayload);
390
+ }
391
+ return void 0;
392
+ }
393
+ return emitThroughOriginal(event, properties, options);
394
+ });
395
+ if (originalCaptureException) {
396
+ client.captureException = ((error2, additionalProperties) => {
397
+ const mergedProperties = {
398
+ ...additionalProperties ?? {},
399
+ $exception_message: error2 instanceof Error ? error2.message : String(error2),
400
+ $exception_type: error2 instanceof Error ? error2.name : typeof error2
401
+ };
402
+ const outcome = gate.evaluateCapture("$exception", mergedProperties);
403
+ if (outcome.action === "coalesce") {
404
+ const readyPayload = gate.takeBucketIfReady(outcome.bucketKey);
405
+ if (readyPayload) {
406
+ flushCoalescedPayload(readyPayload);
407
+ }
408
+ return void 0;
409
+ }
410
+ return originalCaptureException(error2, additionalProperties);
411
+ });
412
+ }
413
+ wrappedClient = client;
414
+ return client;
415
+ }
416
+ function capturePosthogEvent(client, event, properties, options) {
417
+ if (!client || typeof client.capture !== "function") return;
418
+ client.capture(event, properties, options);
419
+ }
420
+ function capturePosthogException(client, error2, properties, options) {
421
+ if (!client) return;
422
+ if (typeof client.captureException === "function") {
423
+ client.captureException(error2, properties);
424
+ return;
425
+ }
426
+ capturePosthogEvent(
427
+ client,
428
+ "$exception",
429
+ {
430
+ ...properties ?? {},
431
+ $exception_message: error2.message,
432
+ $exception_type: error2.name,
433
+ $exception_stack: error2.stack
434
+ },
435
+ options
436
+ );
437
+ }
438
+ let posthogInstance = null;
439
+ let initPromise = null;
440
+ const DEFAULT_HOST = "https://us.i.posthog.com";
441
+ async function initializePostHog(apiKey, host, debug) {
442
+ if (posthogInstance) return posthogInstance;
443
+ if (typeof window === "undefined") return null;
444
+ try {
445
+ const posthog = (await import("posthog-js")).default;
446
+ posthog.init(apiKey, {
447
+ api_host: host,
448
+ autocapture: true,
449
+ capture_pageview: false,
450
+ session_recording: {
451
+ recordCrossOriginIframes: true,
452
+ maskAllInputs: true
453
+ },
454
+ loaded: (ph) => {
455
+ wrapPosthogClient(ph);
456
+ if (debug) {
457
+ ph.debug(true);
458
+ }
459
+ }
460
+ });
461
+ wrapPosthogClient(posthog);
462
+ posthogInstance = posthog;
463
+ return posthog;
464
+ } catch {
465
+ initPromise = null;
466
+ return null;
467
+ }
468
+ }
469
+ function getPostHogInstance() {
470
+ return posthogInstance;
471
+ }
472
+ function PostHogProvider({
473
+ children,
474
+ config: config2
475
+ }) {
476
+ const apiKey = (config2 == null ? void 0 : config2.apiKey) ?? "";
477
+ const host = (config2 == null ? void 0 : config2.host) ?? DEFAULT_HOST;
478
+ const debug = (config2 == null ? void 0 : config2.debug) ?? false;
479
+ useEffect(() => {
480
+ if (!apiKey || typeof window === "undefined") return;
481
+ if (!initPromise) {
482
+ initPromise = initializePostHog(apiKey, host, debug);
483
+ }
484
+ }, [apiKey, host, debug]);
485
+ return /* @__PURE__ */ jsx(Fragment$1, { children });
486
+ }
487
+ const ATHENA_SDK_ERROR_CODES = {
488
+ /** No token and no API key resolved before a request had to be sent. */
489
+ auth_missing: "auth_missing",
490
+ /** The server refused the credential (401 / statewire `unauthorized` fin). */
491
+ auth_rejected: "auth_rejected",
492
+ /** `/_athena/auth` or the iframe bridge did not answer within the timeout. */
493
+ auth_bridge_timeout: "auth_bridge_timeout",
494
+ /** `/_athena/auth` answered with a non-404 error. */
495
+ auth_bridge_failed: "auth_bridge_failed",
496
+ /** The statewire sync URL could not be derived from the configuration. */
497
+ config_invalid: "config_invalid",
498
+ /** A prop was set that the active transport ignores (e.g. `agent` on statewire). */
499
+ config_ignored: "config_ignored",
500
+ /** The thread list request failed. */
501
+ threads_list_failed: "threads_list_failed",
502
+ /** Loading a thread's history failed. */
503
+ thread_load_failed: "thread_load_failed",
504
+ /** The statewire host rejected a command (structured `{status, detail}`). */
505
+ statewire_rejected: "statewire_rejected",
506
+ /** The statewire connection is gone and will not reconnect on its own. */
507
+ statewire_gone: "statewire_gone",
508
+ /** The legacy `/api/chat` stream failed. */
509
+ stream_failed: "stream_failed",
510
+ /** The selected collab agent / channel was refused by the backend. */
511
+ collab_agent_rejected: "collab_agent_rejected",
512
+ /** Anything else. */
513
+ unknown: "unknown"
514
+ };
515
+ class AthenaSdkError extends Error {
516
+ constructor(options) {
517
+ super(options.message, options.cause === void 0 ? void 0 : { cause: options.cause });
518
+ __publicField(this, "code");
519
+ __publicField(this, "hint");
520
+ __publicField(this, "status");
521
+ __publicField(this, "detail");
522
+ __publicField(this, "context");
523
+ this.name = "AthenaSdkError";
524
+ this.code = options.code;
525
+ this.hint = options.hint;
526
+ this.status = options.status;
527
+ this.detail = options.detail;
528
+ this.context = options.context ?? {};
529
+ }
530
+ /** A log/console-friendly one-liner: `[code] message — hint`. */
531
+ describe() {
532
+ return `[${this.code}] ${this.message}${this.hint ? ` — ${this.hint}` : ""}`;
533
+ }
534
+ toJSON() {
535
+ return {
536
+ name: this.name,
537
+ code: this.code,
538
+ message: this.message,
539
+ hint: this.hint,
540
+ status: this.status,
541
+ detail: this.detail,
542
+ context: this.context
543
+ };
544
+ }
545
+ }
546
+ function isAthenaSdkError(value) {
547
+ return value instanceof AthenaSdkError;
548
+ }
549
+ function toAthenaSdkError(value, fallback) {
550
+ if (isAthenaSdkError(value)) return value;
551
+ const message = value instanceof Error && value.message ? value.message : fallback.message;
552
+ return new AthenaSdkError({ ...fallback, message, cause: value });
553
+ }
554
+ function readRejectionDetail(detail) {
555
+ if (typeof detail === "string") return { code: null, message: detail || null };
556
+ if (!detail || typeof detail !== "object") return { code: null, message: null };
557
+ const record2 = detail;
558
+ return {
559
+ code: typeof record2.code === "string" ? record2.code : null,
560
+ message: typeof record2.message === "string" ? record2.message : null
561
+ };
562
+ }
563
+ const ATHENA_DIAGNOSTIC_LEVELS = ["debug", "info", "warn", "error"];
564
+ const LEVEL_RANK = {
565
+ debug: 0,
566
+ info: 1,
567
+ warn: 2,
568
+ error: 3
569
+ };
570
+ const DEFAULT_CONFIG = {
571
+ console: false,
572
+ posthog: false,
573
+ bufferSize: 300
574
+ };
575
+ const CONSOLE_PREFIX = "[AthenaSDK]";
576
+ const LOCAL_STORAGE_DEBUG_KEY = "athena:debug";
577
+ const GLOBAL_KEY = "__ATHENA_SDK__";
578
+ const REDACT_KEYS = /token|secret|api[-_]?key|authorization|cookie|password/i;
579
+ function redact(data) {
580
+ if (!data) return void 0;
581
+ const out = {};
582
+ for (const [key, value] of Object.entries(data)) {
583
+ if (REDACT_KEYS.test(key)) {
584
+ out[key] = typeof value === "string" && value.length > 0 ? `<redacted:${value.length}>` : "<redacted>";
585
+ } else {
586
+ out[key] = value;
587
+ }
588
+ }
589
+ return out;
590
+ }
591
+ function nowMs() {
592
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
593
+ }
594
+ function readLocalDebugLevel() {
595
+ try {
596
+ if (typeof localStorage === "undefined") return null;
597
+ const raw = localStorage.getItem(LOCAL_STORAGE_DEBUG_KEY);
598
+ if (!raw) return null;
599
+ if (ATHENA_DIAGNOSTIC_LEVELS.includes(raw)) {
600
+ return raw;
601
+ }
602
+ return raw === "1" || raw === "true" ? "debug" : null;
603
+ } catch {
604
+ return null;
605
+ }
606
+ }
607
+ class AthenaDiagnosticsBus {
608
+ constructor() {
609
+ __publicField(this, "config", { ...DEFAULT_CONFIG });
610
+ __publicField(this, "events", []);
611
+ __publicField(this, "listeners", /* @__PURE__ */ new Set());
612
+ __publicField(this, "snapshotListeners", /* @__PURE__ */ new Set());
613
+ __publicField(this, "seq", 0);
614
+ __publicField(this, "gauges", {});
615
+ __publicField(this, "timings", {});
616
+ __publicField(this, "spans", /* @__PURE__ */ new Map());
617
+ __publicField(this, "cachedSnapshot", null);
618
+ }
619
+ configure(partial2) {
620
+ this.config = { ...this.config, ...partial2 };
621
+ if (this.events.length > this.config.bufferSize) {
622
+ this.events = this.events.slice(-this.config.bufferSize);
623
+ }
624
+ this.invalidate();
625
+ }
626
+ getConfig() {
627
+ return this.config;
628
+ }
629
+ /** Effective console level: the configured one, or `localStorage['athena:debug']`. */
630
+ consoleLevel() {
631
+ if (this.config.console !== false) return this.config.console;
632
+ return readLocalDebugLevel() ?? false;
633
+ }
634
+ emit(name, options = {}) {
635
+ const level = options.level ?? (options.error !== void 0 ? "error" : "info");
636
+ const error2 = options.error === void 0 ? void 0 : toAthenaSdkError(options.error, {
637
+ code: "unknown",
638
+ message: `Unexpected error during ${name}`
639
+ });
640
+ const event = {
641
+ seq: ++this.seq,
642
+ t: Math.round(nowMs() * 10) / 10,
643
+ at: (/* @__PURE__ */ new Date()).toISOString(),
644
+ name,
645
+ level,
646
+ ...options.durationMs !== void 0 && { durationMs: Math.round(options.durationMs) },
647
+ ...options.data && { data: redact(options.data) },
648
+ ...error2 && { error: error2 }
649
+ };
650
+ this.events.push(event);
651
+ if (this.events.length > this.config.bufferSize) {
652
+ this.events.splice(0, this.events.length - this.config.bufferSize);
653
+ }
654
+ if (event.durationMs !== void 0) {
655
+ this.timings[name] = event.durationMs;
656
+ }
657
+ this.invalidate();
658
+ this.echoToConsole(event);
659
+ this.forwardToPostHog(event);
660
+ for (const listener of this.listeners) {
661
+ try {
662
+ listener(event);
663
+ } catch (listenerError) {
664
+ console.error(`${CONSOLE_PREFIX} diagnostics listener threw`, listenerError);
665
+ }
666
+ }
667
+ if (this.config.onEvent) {
668
+ try {
669
+ this.config.onEvent(event);
670
+ } catch (callbackError) {
671
+ console.error(`${CONSOLE_PREFIX} onDiagnostic callback threw`, callbackError);
672
+ }
673
+ }
674
+ if (error2 && this.config.onError) {
675
+ try {
676
+ this.config.onError(error2, event);
677
+ } catch (callbackError) {
678
+ console.error(`${CONSOLE_PREFIX} onError callback threw`, callbackError);
679
+ }
680
+ }
681
+ for (const notify of this.snapshotListeners) notify();
682
+ return event;
683
+ }
684
+ /** Record an error-level event. Returns the normalized `AthenaSdkError`. */
685
+ error(name, error2, fallback, data) {
686
+ const normalized = toAthenaSdkError(error2, fallback);
687
+ this.emit(name, { level: "error", error: normalized, data });
688
+ return normalized;
689
+ }
690
+ /**
691
+ * Start a named span. Returns a function that ends it and emits `doneName`
692
+ * with `durationMs` (or `errorName` when passed an error). Also records a
693
+ * `performance.measure` so the span shows in the browser's Performance panel.
694
+ */
695
+ span(spanName, startName, data) {
696
+ const startedAt = nowMs();
697
+ this.spans.set(spanName, startedAt);
698
+ this.mark(`${spanName}:start`);
699
+ this.emit(startName, { level: "debug", data });
700
+ return (doneName, doneOptions = {}) => {
701
+ const durationMs = nowMs() - startedAt;
702
+ this.spans.delete(spanName);
703
+ this.mark(`${spanName}:end`);
704
+ this.measure(spanName);
705
+ this.emit(doneName, {
706
+ level: doneOptions.error !== void 0 ? "error" : "info",
707
+ durationMs,
708
+ data: doneOptions.data,
709
+ error: doneOptions.error
710
+ });
711
+ return durationMs;
712
+ };
713
+ }
714
+ /** Set a gauge (latest-value metric): connection status, transport, auth mode. */
715
+ gauge(name, value) {
716
+ if (this.gauges[name] === value) return;
717
+ this.gauges[name] = value;
718
+ this.invalidate();
719
+ for (const notify of this.snapshotListeners) notify();
720
+ }
721
+ subscribe(listener) {
722
+ this.listeners.add(listener);
723
+ return () => {
724
+ this.listeners.delete(listener);
725
+ };
726
+ }
727
+ /**
728
+ * Additive consumer registration: every registered consumer receives every
729
+ * event (and every error), unlike the single `onEvent`/`onError` config
730
+ * slots which are last-writer-wins. `AthenaProvider` registers through this
731
+ * so two mounted providers never clobber each other's callbacks.
732
+ */
733
+ addConsumer(consumer) {
734
+ return this.subscribe((event) => {
735
+ var _a3, _b2;
736
+ try {
737
+ (_a3 = consumer.onEvent) == null ? void 0 : _a3.call(consumer, event);
738
+ } catch (callbackError) {
739
+ console.error(`${CONSOLE_PREFIX} onDiagnostic consumer threw`, callbackError);
740
+ }
741
+ if (event.error) {
742
+ try {
743
+ (_b2 = consumer.onError) == null ? void 0 : _b2.call(consumer, event.error, event);
744
+ } catch (callbackError) {
745
+ console.error(`${CONSOLE_PREFIX} onError consumer threw`, callbackError);
746
+ }
747
+ }
748
+ });
749
+ }
750
+ /** Subscribe to snapshot changes (for `useSyncExternalStore`). */
751
+ subscribeSnapshot(listener) {
752
+ this.snapshotListeners.add(listener);
753
+ return () => {
754
+ this.snapshotListeners.delete(listener);
755
+ };
756
+ }
757
+ snapshot() {
758
+ if (!this.cachedSnapshot) {
759
+ const { onEvent: _onEvent, onError: _onError, ...config2 } = this.config;
760
+ this.cachedSnapshot = {
761
+ sdkVersion: ATHENA_REACT_SDK_VERSION,
762
+ config: config2,
763
+ events: [...this.events],
764
+ gauges: { ...this.gauges },
765
+ timings: { ...this.timings }
766
+ };
767
+ }
768
+ return this.cachedSnapshot;
769
+ }
770
+ /** Copy-paste-able JSON of the current snapshot (errors serialized). */
771
+ export() {
772
+ return JSON.stringify(
773
+ this.snapshot(),
774
+ (_key, value) => isAthenaSdkError(value) ? value.toJSON() : value,
775
+ 2
776
+ );
777
+ }
778
+ clear() {
779
+ this.events = [];
780
+ this.timings = {};
781
+ this.invalidate();
782
+ for (const notify of this.snapshotListeners) notify();
783
+ }
784
+ invalidate() {
785
+ this.cachedSnapshot = null;
786
+ }
787
+ mark(name) {
788
+ try {
789
+ if (typeof performance !== "undefined" && typeof performance.mark === "function") {
790
+ performance.mark(`athena-sdk:${name}`);
791
+ }
792
+ } catch {
793
+ }
794
+ }
795
+ measure(spanName) {
796
+ try {
797
+ if (typeof performance !== "undefined" && typeof performance.measure === "function") {
798
+ performance.measure(
799
+ `athena-sdk:${spanName}`,
800
+ `athena-sdk:${spanName}:start`,
801
+ `athena-sdk:${spanName}:end`
802
+ );
803
+ }
804
+ } catch {
805
+ }
806
+ }
807
+ echoToConsole(event) {
808
+ const level = this.consoleLevel();
809
+ if (level === false) {
810
+ if (event.level === "error" && event.error) {
811
+ console.error(`${CONSOLE_PREFIX} ${event.name}: ${event.error.describe()}`, event.data ?? "");
812
+ }
813
+ return;
814
+ }
815
+ if (LEVEL_RANK[event.level] < LEVEL_RANK[level]) return;
816
+ const suffix = event.durationMs !== void 0 ? ` (${event.durationMs}ms)` : "";
817
+ const line = `${CONSOLE_PREFIX} ${event.name}${suffix}`;
818
+ const payload = event.error ? { ...event.data, error: event.error.describe() } : event.data;
819
+ const method = event.level === "error" ? console.error : event.level === "warn" ? console.warn : event.level === "debug" ? console.debug : console.info;
820
+ method(line, payload ?? "");
821
+ }
822
+ forwardToPostHog(event) {
823
+ if (!this.config.posthog) return;
824
+ if (event.durationMs === void 0 && event.level !== "error") return;
825
+ try {
826
+ const client = getPostHogInstance();
827
+ capturePosthogEvent(client, `athena_sdk_${event.name.replace(/\./g, "_")}`, {
828
+ sdk_version: ATHENA_REACT_SDK_VERSION,
829
+ level: event.level,
830
+ ...event.durationMs !== void 0 && { duration_ms: event.durationMs },
831
+ ...event.error && {
832
+ error_code: event.error.code,
833
+ error_message: event.error.message,
834
+ error_status: event.error.status
835
+ },
836
+ ...event.data
837
+ });
838
+ } catch {
839
+ }
840
+ }
841
+ }
842
+ const athenaDiagnostics = new AthenaDiagnosticsBus();
843
+ function installAthenaDiagnosticsGlobal() {
844
+ if (typeof window === "undefined") return;
845
+ const globalWindow = window;
846
+ const existing = globalWindow[GLOBAL_KEY] ?? {};
847
+ globalWindow[GLOBAL_KEY] = {
848
+ ...existing,
849
+ version: ATHENA_REACT_SDK_VERSION,
850
+ diagnostics: {
851
+ snapshot: () => athenaDiagnostics.snapshot(),
852
+ export: () => athenaDiagnostics.export(),
853
+ clear: () => athenaDiagnostics.clear(),
854
+ enableConsole: (level = "debug") => {
855
+ try {
856
+ localStorage.setItem(LOCAL_STORAGE_DEBUG_KEY, level);
857
+ } catch {
858
+ }
859
+ athenaDiagnostics.configure({ console: level });
860
+ },
861
+ disableConsole: () => {
862
+ try {
863
+ localStorage.removeItem(LOCAL_STORAGE_DEBUG_KEY);
864
+ } catch {
865
+ }
866
+ athenaDiagnostics.configure({ console: false });
867
+ }
868
+ }
869
+ };
870
+ }
871
+ function debugPropToDiagnosticsConfig(debug) {
872
+ if (debug === void 0) return {};
873
+ if (debug === true) return { console: "debug" };
874
+ if (debug === false) return { console: false };
875
+ if (typeof debug === "string") return { console: debug };
876
+ return debug;
877
+ }
878
+ function useAthenaDiagnostics() {
879
+ const snapshot = useSyncExternalStore(
880
+ athenaDiagnostics.subscribeSnapshot.bind(athenaDiagnostics),
881
+ athenaDiagnostics.snapshot.bind(athenaDiagnostics),
882
+ athenaDiagnostics.snapshot.bind(athenaDiagnostics)
883
+ );
884
+ const clear = useCallback(() => athenaDiagnostics.clear(), []);
885
+ const exportJson = useCallback(() => athenaDiagnostics.export(), []);
886
+ return { ...snapshot, clear, export: exportJson };
887
+ }
888
+ const DEEP_AGENT_RUNTIME_MARKER = "athena_deep_agent";
889
+ const STATEWIRE_START_CHANNEL = "web";
890
+ const STATEWIRE_RUN_LABEL = "Athena SDK";
891
+ const DEFAULT_STATEWIRE_MODEL = "claude-sonnet-5";
892
+ const COLLAB_AGENT_REF_PREFIX = "collab_agent:";
893
+ function parseCollabAgentRef(agent2) {
894
+ if (typeof agent2 !== "string" || !agent2.startsWith(COLLAB_AGENT_REF_PREFIX)) return null;
895
+ const assetId = agent2.slice(COLLAB_AGENT_REF_PREFIX.length).trim();
896
+ return assetId || null;
897
+ }
898
+ function buildStatewireRunConfig(options = {}) {
899
+ var _a3, _b2, _c2, _d2, _e2;
900
+ const collabAgentId = parseCollabAgentRef(options.agent);
901
+ const collabChannelId = collabAgentId && ((_a3 = options.channel) == null ? void 0 : _a3.trim()) ? options.channel.trim() : void 0;
902
+ const model = options.model ?? (collabAgentId ? void 0 : DEFAULT_STATEWIRE_MODEL);
903
+ const panelModel = model ?? DEFAULT_STATEWIRE_MODEL;
904
+ const enabledTools = Array.from(
905
+ /* @__PURE__ */ new Set([...options.tools ?? [], ...options.frontendToolIds ?? []])
906
+ );
907
+ const systemPrompt = ((_b2 = options.systemPrompt) == null ? void 0 : _b2.trim()) ?? "";
908
+ return {
909
+ custom: {
910
+ runtime: DEEP_AGENT_RUNTIME_MARKER,
911
+ // With a collab channel selected, omit the SDK's own 'web' stamp: the
912
+ // request's explicit start_channel would win over the backend overlay's
913
+ // kind-mapped provenance (a custom SMS channel must stamp 'sms').
914
+ ...collabChannelId ? {} : { start_channel: STATEWIRE_START_CHANNEL },
915
+ ...model ? { model } : {},
916
+ // An empty list is behavior-identical to an absent key for the parser
917
+ // (both coerce to []), but the collab-agent overlay merges request keys
918
+ // OVER the agent definition — so an explicit empty list would erase the
919
+ // agent's configured tools. Omit it when empty.
920
+ ...enabledTools.length > 0 ? { enabled_tools: enabledTools } : {},
921
+ panel_config: {
922
+ model: panelModel,
923
+ enabled_tools: enabledTools,
924
+ system_prompt: systemPrompt,
925
+ run_label: STATEWIRE_RUN_LABEL
926
+ },
927
+ ...collabAgentId ? { collab_agent_id: collabAgentId } : {},
928
+ ...collabChannelId ? { collab_channel_id: collabChannelId } : {},
929
+ ...systemPrompt ? { system_prompt: systemPrompt } : {},
930
+ ...((_c2 = options.workbench) == null ? void 0 : _c2.length) ? { workbench: options.workbench } : {},
931
+ ...((_d2 = options.knowledgeBase) == null ? void 0 : _d2.length) ? { knowledge_base: options.knowledgeBase } : {},
932
+ ...options.customToolConfigs ? { custom_tool_configs: options.customToolConfigs } : {},
933
+ ...options.appId ? { app_id: options.appId } : {},
934
+ ...((_e2 = options.clientTools) == null ? void 0 : _e2.length) ? { client_tools: options.clientTools } : {},
935
+ ...options.extraRunConfig ?? {}
936
+ }
937
+ };
938
+ }
35
939
  const ATHENA_ENVIRONMENT_URLS = {
36
940
  production: {
37
941
  apiUrl: "https://iris.prd.athenaintel.com/api/chat",
@@ -235,7 +1139,7 @@ const normalizeOrigin = (value) => {
235
1139
  return null;
236
1140
  }
237
1141
  };
238
- const getTokenRefreshDelay = (expiresAt, nowMs) => {
1142
+ const getTokenRefreshDelay = (expiresAt, nowMs2) => {
239
1143
  if (typeof expiresAt !== "string") {
240
1144
  return DEFAULT_TOKEN_REFRESH_MS;
241
1145
  }
@@ -243,7 +1147,7 @@ const getTokenRefreshDelay = (expiresAt, nowMs) => {
243
1147
  if (!Number.isFinite(expiresAtMs)) {
244
1148
  return DEFAULT_TOKEN_REFRESH_MS;
245
1149
  }
246
- return Math.max(TOKEN_REFRESH_RETRY_BASE_MS, expiresAtMs - nowMs - TOKEN_REFRESH_BUFFER_MS);
1150
+ return Math.max(TOKEN_REFRESH_RETRY_BASE_MS, expiresAtMs - nowMs2 - TOKEN_REFRESH_BUFFER_MS);
247
1151
  };
248
1152
  const getAuthRetryDelay = (retryAttempt) => {
249
1153
  const safeAttempt = Number.isFinite(retryAttempt) ? Math.max(0, Math.floor(retryAttempt)) : 0;
@@ -277,6 +1181,15 @@ function useParentBridge({
277
1181
  const configReceived = useRef(false);
278
1182
  useEffect(() => {
279
1183
  if (!isInIframe) return;
1184
+ const endBridgeSpan = athenaDiagnostics.span("auth.bridge", "auth.bridge.start", {
1185
+ mode: "iframe"
1186
+ });
1187
+ let spanEnded = false;
1188
+ const endOnce = (name, options) => {
1189
+ if (spanEnded) return 0;
1190
+ spanEnded = true;
1191
+ return endBridgeSpan(name, options);
1192
+ };
280
1193
  const handler = (event) => {
281
1194
  if (!isTrustedOrigin({ origin: event.origin, trustedOrigins: runtimeTrustedOrigins })) {
282
1195
  return;
@@ -295,6 +1208,11 @@ function useParentBridge({
295
1208
  }));
296
1209
  }
297
1210
  if (event.data.type === "athena-auth" && typeof event.data.token === "string") {
1211
+ endOnce("auth.bridge.ready", { data: { mode: "iframe" } });
1212
+ athenaDiagnostics.emit("auth.token.acquired", {
1213
+ level: "debug",
1214
+ data: { source: "iframe-postmessage" }
1215
+ });
298
1216
  setState((prev) => ({
299
1217
  ...prev,
300
1218
  token: event.data.token,
@@ -308,6 +1226,13 @@ function useParentBridge({
308
1226
  readySignalSent.current = true;
309
1227
  }
310
1228
  const timer = setTimeout(() => {
1229
+ endOnce("auth.bridge.timeout", {
1230
+ data: {
1231
+ mode: "iframe",
1232
+ timeout_ms: BRIDGE_TIMEOUT_MS,
1233
+ config_received: configReceived.current
1234
+ }
1235
+ });
311
1236
  setState((prev) => prev.ready ? prev : { ...prev, ready: true });
312
1237
  }, BRIDGE_TIMEOUT_MS);
313
1238
  return () => {
@@ -360,9 +1285,20 @@ function useParentBridge({
360
1285
  }) => {
361
1286
  controller == null ? void 0 : controller.abort();
362
1287
  controller = new AbortController();
1288
+ const isInitial = markReadyOnFailure;
1289
+ const rawEndSpan = isInitial ? athenaDiagnostics.span("auth.bridge", "auth.bridge.start", { mode: "marathon" }) : null;
1290
+ let spanEnded = false;
1291
+ const endBridgeSpan = rawEndSpan ? (name, options) => {
1292
+ if (spanEnded) return 0;
1293
+ spanEnded = true;
1294
+ return rawEndSpan(name, options);
1295
+ } : null;
363
1296
  clearRequestTimer();
364
1297
  requestTimer = setTimeout(() => {
365
1298
  controller == null ? void 0 : controller.abort();
1299
+ endBridgeSpan == null ? void 0 : endBridgeSpan("auth.bridge.timeout", {
1300
+ data: { mode: "marathon", timeout_ms: BRIDGE_TIMEOUT_MS }
1301
+ });
366
1302
  if (markReadyOnFailure) {
367
1303
  markReady();
368
1304
  }
@@ -376,17 +1312,43 @@ function useParentBridge({
376
1312
  if (cancelled) return;
377
1313
  if (!resp.ok) {
378
1314
  if (resp.status === 404) {
1315
+ endBridgeSpan == null ? void 0 : endBridgeSpan("auth.bridge.absent", {
1316
+ data: { mode: "marathon", status: resp.status }
1317
+ });
379
1318
  markReady();
380
- } else if (markReadyOnFailure) {
381
- markReady();
382
- scheduleRetry();
383
1319
  } else {
1320
+ const failure = {
1321
+ level: "warn",
1322
+ data: { mode: "marathon", status: resp.status }
1323
+ };
1324
+ if (endBridgeSpan) {
1325
+ endBridgeSpan("auth.bridge.error", failure);
1326
+ } else {
1327
+ athenaDiagnostics.emit("auth.token.refresh_failed", failure);
1328
+ }
1329
+ if (markReadyOnFailure) {
1330
+ markReady();
1331
+ }
384
1332
  scheduleRetry();
385
1333
  }
386
1334
  return;
387
1335
  }
388
1336
  const data = await resp.json();
389
1337
  if (cancelled) return;
1338
+ if (endBridgeSpan) {
1339
+ endBridgeSpan("auth.bridge.ready", {
1340
+ data: { mode: "marathon", has_token: typeof data.token === "string" }
1341
+ });
1342
+ athenaDiagnostics.emit("auth.token.acquired", {
1343
+ level: "debug",
1344
+ data: { source: "marathon", expires_at: data.expires_at }
1345
+ });
1346
+ } else {
1347
+ athenaDiagnostics.emit("auth.token.refreshed", {
1348
+ level: "debug",
1349
+ data: { source: "marathon", expires_at: data.expires_at }
1350
+ });
1351
+ }
390
1352
  setState({
391
1353
  token: typeof data.token === "string" ? data.token : null,
392
1354
  apiUrl: typeof data.apiUrl === "string" ? data.apiUrl : null,
@@ -395,7 +1357,15 @@ function useParentBridge({
395
1357
  ready: true
396
1358
  });
397
1359
  scheduleRefresh(data.expires_at);
398
- } catch {
1360
+ } catch (error2) {
1361
+ if (!cancelled && !(error2 instanceof DOMException && error2.name === "AbortError")) {
1362
+ const failure = { level: "warn", data: { mode: "marathon" }, error: error2 };
1363
+ if (endBridgeSpan) {
1364
+ endBridgeSpan("auth.bridge.error", failure);
1365
+ } else {
1366
+ athenaDiagnostics.emit("auth.token.refresh_failed", failure);
1367
+ }
1368
+ }
399
1369
  if (markReadyOnFailure) {
400
1370
  markReady();
401
1371
  }
@@ -9841,24 +10811,42 @@ function getAthenaApiBaseUrl(backendUrl) {
9841
10811
  return stripped;
9842
10812
  }
9843
10813
  async function listThreads(backendUrl, auth, opts = {}) {
10814
+ var _a3;
9844
10815
  const base2 = getAthenaApiBaseUrl(backendUrl);
9845
- const res = await fetch(`${base2}/api/conversations/threads/list`, {
9846
- method: "POST",
9847
- headers: { "Content-Type": "application/json", ...getAuthHeaders(auth) },
9848
- body: JSON.stringify({
9849
- limit: opts.limit ?? 50,
9850
- offset: opts.offset ?? 0,
9851
- // Default to the full recent-conversations set unless a caller
9852
- // explicitly asks to hide triggered/background sessions.
9853
- exclude_triggered: opts.exclude_triggered ?? false,
9854
- ...opts.app_id ? { app_id: opts.app_id } : {},
9855
- ...opts.start_channel ? { start_channel: opts.start_channel } : {}
9856
- })
10816
+ const endSpan = athenaDiagnostics.span("threads.list", "threads.list.start", {
10817
+ auth_mode: getAuthMode(auth),
10818
+ app_id: opts.app_id
9857
10819
  });
9858
- if (!res.ok) {
9859
- throw new Error(`[AthenaSDK] Failed to list threads: ${res.status}`);
10820
+ try {
10821
+ const res = await fetch(`${base2}/api/conversations/threads/list`, {
10822
+ method: "POST",
10823
+ headers: { "Content-Type": "application/json", ...getAuthHeaders(auth) },
10824
+ body: JSON.stringify({
10825
+ limit: opts.limit ?? 50,
10826
+ offset: opts.offset ?? 0,
10827
+ // Default to the full recent-conversations set unless a caller
10828
+ // explicitly asks to hide triggered/background sessions.
10829
+ exclude_triggered: opts.exclude_triggered ?? false,
10830
+ ...opts.app_id ? { app_id: opts.app_id } : {},
10831
+ ...opts.start_channel ? { start_channel: opts.start_channel } : {}
10832
+ })
10833
+ });
10834
+ if (!res.ok) {
10835
+ throw new AthenaSdkError({
10836
+ code: res.status === 401 || res.status === 403 ? "auth_rejected" : "threads_list_failed",
10837
+ message: `Failed to list threads: ${res.status}`,
10838
+ status: res.status,
10839
+ hint: res.status === 401 || res.status === 403 ? "The credential was refused. Check the token/API key and that the user belongs to the workspace." : "Check backendUrl points at the Agora API base.",
10840
+ context: { auth_mode: getAuthMode(auth) }
10841
+ });
10842
+ }
10843
+ const data = await res.json();
10844
+ endSpan("threads.list.done", { data: { count: ((_a3 = data.threads) == null ? void 0 : _a3.length) ?? 0 } });
10845
+ return data;
10846
+ } catch (error2) {
10847
+ endSpan("threads.list.error", { error: error2 });
10848
+ throw error2;
9860
10849
  }
9861
- return res.json();
9862
10850
  }
9863
10851
  async function setThreadReadState(backendUrl, auth, opts) {
9864
10852
  const base2 = getAthenaApiBaseUrl(backendUrl);
@@ -9919,31 +10907,49 @@ function getResponseErrorBody(response) {
9919
10907
  return response.text().catch(() => "");
9920
10908
  }
9921
10909
  async function getThreadState(backendUrl, auth, threadId) {
10910
+ var _a3, _b2, _c2, _d2;
9922
10911
  const base2 = getAthenaApiBaseUrl(backendUrl);
9923
10912
  const authMode = getAuthMode(auth);
9924
10913
  const endpoint = `${base2}/api/conversations/threads/get`;
9925
- console.info("[AthenaSDK] Loading thread state from conversations API:", {
9926
- threadId,
9927
- endpoint,
9928
- authMode,
9929
- hasToken: Boolean(auth.token),
9930
- hasApiKey: Boolean(auth.apiKey)
9931
- });
9932
- const res = await fetch(endpoint, {
9933
- method: "POST",
9934
- headers: { "Content-Type": "application/json", ...getAuthHeaders(auth) },
9935
- body: JSON.stringify({
9936
- thread_id: threadId,
9937
- skip_cache: true
9938
- })
10914
+ const endSpan = athenaDiagnostics.span("threads.history", "threads.history.start", {
10915
+ thread_id: threadId,
10916
+ auth_mode: authMode
9939
10917
  });
10918
+ let res;
10919
+ try {
10920
+ res = await fetch(endpoint, {
10921
+ method: "POST",
10922
+ headers: { "Content-Type": "application/json", ...getAuthHeaders(auth) },
10923
+ body: JSON.stringify({
10924
+ thread_id: threadId,
10925
+ skip_cache: true
10926
+ })
10927
+ });
10928
+ } catch (error2) {
10929
+ endSpan("threads.history.error", { error: error2, data: { thread_id: threadId } });
10930
+ throw error2;
10931
+ }
9940
10932
  if (!res.ok) {
9941
10933
  const body = await getResponseErrorBody(res);
9942
- throw new Error(
9943
- `[AthenaSDK] Failed to get thread state: ${res.status} (${authMode})${body ? `: ${body.slice(0, 300)}` : ""}`
9944
- );
10934
+ const error2 = new AthenaSdkError({
10935
+ code: res.status === 401 || res.status === 403 ? "auth_rejected" : "thread_load_failed",
10936
+ message: `Failed to get thread state: ${res.status} (${authMode})${body ? `: ${body.slice(0, 300)}` : ""}`,
10937
+ status: res.status,
10938
+ hint: "A brand-new thread may not be persisted yet; anything else means the credential or backendUrl is wrong.",
10939
+ context: { thread_id: threadId, auth_mode: authMode }
10940
+ });
10941
+ endSpan("threads.history.error", { error: error2, data: { thread_id: threadId } });
10942
+ throw error2;
9945
10943
  }
9946
10944
  const data = await res.json();
10945
+ const channelMessages = (_b2 = (_a3 = data.thread) == null ? void 0 : _a3.channel_values) == null ? void 0 : _b2.messages;
10946
+ endSpan("threads.history.done", {
10947
+ data: {
10948
+ thread_id: threadId,
10949
+ found: data.thread_found !== false,
10950
+ message_count: Array.isArray(channelMessages) ? channelMessages.length : ((_d2 = (_c2 = data.thread) == null ? void 0 : _c2.messages) == null ? void 0 : _d2.length) ?? 0
10951
+ }
10952
+ });
9947
10953
  const thread = data.thread;
9948
10954
  if (data.thread_found === false || !thread) {
9949
10955
  return {
@@ -10225,17 +11231,35 @@ const useAthenaRuntime = (config2) => {
10225
11231
  };
10226
11232
  },
10227
11233
  onResponse: () => {
11234
+ athenaDiagnostics.emit("stream.connected", {
11235
+ level: "debug",
11236
+ data: { transport: "legacy", thread_id: threadIdRef.current }
11237
+ });
10228
11238
  if (IS_DEV) {
10229
11239
  console.log("[AthenaSDK] Stream connected");
10230
11240
  }
10231
11241
  },
10232
11242
  onFinish: () => {
11243
+ athenaDiagnostics.emit("run.done", {
11244
+ level: "debug",
11245
+ data: { transport: "legacy", thread_id: threadIdRef.current }
11246
+ });
10233
11247
  if (IS_DEV) {
10234
11248
  console.log("[AthenaSDK] Stream completed");
10235
11249
  }
10236
11250
  },
10237
11251
  onError: (error2, { commands: commands2, updateState }) => {
10238
11252
  var _a3;
11253
+ athenaDiagnostics.error(
11254
+ "stream.error",
11255
+ error2,
11256
+ {
11257
+ code: /\b401\b|unauthori[sz]ed/i.test(error2.message) ? "auth_rejected" : "stream_failed",
11258
+ message: error2.message || "The chat stream failed",
11259
+ hint: "Check the Iris apiUrl and the credential; the raw error is in `cause`."
11260
+ },
11261
+ { transport: "legacy", thread_id: threadIdRef.current }
11262
+ );
10239
11263
  const pendingCommands = commandsToMessages(commands2);
10240
11264
  const isInvalidStringLength = error2 instanceof RangeError && /Invalid string length/i.test(error2.message);
10241
11265
  const userErrorMessage = isInvalidStringLength ? "The response was too large to process. Try reducing the amount of content in a single request or starting a new chat." : error2.message;
@@ -10357,33 +11381,21 @@ const useAthenaRuntime = (config2) => {
10357
11381
  if (isExistingThread && !hasResumedRef.current) {
10358
11382
  hasResumedRef.current = true;
10359
11383
  (async () => {
10360
- var _a3, _b2;
11384
+ var _a3;
10361
11385
  const currentToken = getTokenRef.current ? await getTokenRef.current() ?? tokenRef.current : tokenRef.current;
10362
11386
  const auth = { apiKey: apiKeyRef.current, token: currentToken };
10363
- console.log("[AthenaSDK] Loading existing thread state:", {
10364
- threadId,
10365
- backendUrl
10366
- });
10367
11387
  try {
10368
11388
  const state = await getThreadState(backendUrl, auth, threadId);
10369
- const messageCount = ((_a3 = state == null ? void 0 : state.messages) == null ? void 0 : _a3.length) ?? 0;
10370
- console.log("[AthenaSDK] Got thread state:", {
10371
- threadId,
10372
- messageCount,
10373
- hasMessages: messageCount > 0
10374
- });
10375
11389
  runtime.thread.importExternalState({
10376
11390
  ...state
10377
11391
  });
10378
- console.log(
10379
- "[AthenaSDK] importExternalState completed, runtime messages:",
10380
- runtime.thread.getState().messages.length
10381
- );
10382
11392
  } catch (err) {
10383
- console.warn(
10384
- "[AthenaSDK] Failed to load thread state (may be a new streaming thread):",
10385
- err
10386
- );
11393
+ if (IS_DEV) {
11394
+ console.warn(
11395
+ "[AthenaSDK] Failed to load thread state (may be a new streaming thread):",
11396
+ err
11397
+ );
11398
+ }
10387
11399
  }
10388
11400
  try {
10389
11401
  const statusRes = await fetch(resolvedStatusApiUrl, {
@@ -10395,7 +11407,7 @@ const useAthenaRuntime = (config2) => {
10395
11407
  const status = await statusRes.json();
10396
11408
  if (status.isRunning) {
10397
11409
  try {
10398
- const lastMessageId = ((_b2 = runtime.thread.getState().messages.at(-1)) == null ? void 0 : _b2.id) ?? null;
11410
+ const lastMessageId = ((_a3 = runtime.thread.getState().messages.at(-1)) == null ? void 0 : _a3.id) ?? null;
10399
11411
  runtime.thread.resumeRun({ parentId: lastMessageId });
10400
11412
  } catch (resumeErr) {
10401
11413
  if (IS_DEV) {
@@ -10543,6 +11555,7 @@ function projectDeepAgentConnection(connection) {
10543
11555
  return {
10544
11556
  status: connection.status,
10545
11557
  cause: connection.cause,
11558
+ attempt: connection.attempt,
10546
11559
  ...message !== void 0 && { message }
10547
11560
  };
10548
11561
  }
@@ -10718,6 +11731,22 @@ function liftAopSourceIntoMetadata(message) {
10718
11731
  }
10719
11732
  };
10720
11733
  }
11734
+ function liftBranchIntoMetadata(message) {
11735
+ if (message.type !== "human" && message.type !== "ai") return message;
11736
+ const branch = message.branch;
11737
+ if (typeof branch !== "object" || branch === null || Array.isArray(branch)) return message;
11738
+ const kwargs = message.additional_kwargs;
11739
+ const existingMetadata = kwargs == null ? void 0 : kwargs.metadata;
11740
+ const metadata = typeof existingMetadata === "object" && existingMetadata !== null ? existingMetadata : {};
11741
+ if (typeof metadata.branch === "object" && metadata.branch !== null) return message;
11742
+ return {
11743
+ ...message,
11744
+ additional_kwargs: {
11745
+ ...kwargs,
11746
+ metadata: { ...metadata, branch }
11747
+ }
11748
+ };
11749
+ }
10721
11750
  const TOOL_MESSAGE_INTERNAL_KWARGS = /* @__PURE__ */ new Set([
10722
11751
  "reasoning",
10723
11752
  "tool_outputs",
@@ -10770,11 +11799,13 @@ function isConvertibleChatMessage(message) {
10770
11799
  }
10771
11800
  function sanitizeLangChainMessages(messages) {
10772
11801
  return messages.filter((message) => isConvertibleChatMessage(message) && !isMessageHiddenFromFrontend(message)).map(
10773
- (message) => liftToolMessageMetadataIntoArtifact(
10774
- liftAopSourceIntoMetadata(
10775
- liftCompactionBoundaryIntoMetadata(
10776
- liftConversationStatsIntoMetadata(
10777
- liftModelIntoMetadata(liftRunMarkerIntoMetadata(message))
11802
+ (message) => liftBranchIntoMetadata(
11803
+ liftToolMessageMetadataIntoArtifact(
11804
+ liftAopSourceIntoMetadata(
11805
+ liftCompactionBoundaryIntoMetadata(
11806
+ liftConversationStatsIntoMetadata(
11807
+ liftModelIntoMetadata(liftRunMarkerIntoMetadata(message))
11808
+ )
10778
11809
  )
10779
11810
  )
10780
11811
  )
@@ -10807,14 +11838,15 @@ function registerDeepAgentRunConfig(aui, getRunConfig) {
10807
11838
  })
10808
11839
  });
10809
11840
  }
10810
- function deepAgentThreadStatus(state) {
10811
- var _a3;
10812
- const runs = state == null ? void 0 : state.runs;
10813
- if (runs === void 0) return "loading";
10814
- return ((_a3 = runs[0]) == null ? void 0 : _a3.status) ?? "ready";
10815
- }
10816
11841
  function useDeepAgentThreadStatus() {
10817
- return useStatewireState(deepAgentThreadStatus);
11842
+ return useAuiState((s) => {
11843
+ var _a3;
11844
+ const status = (_a3 = s.thread.extras) == null ? void 0 : _a3.status;
11845
+ if (status === void 0) {
11846
+ throw new Error("useDeepAgentThreadStatus requires a statewire thread");
11847
+ }
11848
+ return status;
11849
+ });
10818
11850
  }
10819
11851
  function shouldNotifyRunningChange(previous, next) {
10820
11852
  if (previous === null) return next.isRunning;
@@ -11035,7 +12067,7 @@ function useDeepAgentThread({
11035
12067
  }
11036
12068
  const connection = projectDeepAgentConnection(meta.connection);
11037
12069
  const previous = lastConnectionRef.current;
11038
- if ((previous == null ? void 0 : previous.threadId) !== attachId || previous.connection.status !== connection.status || previous.connection.cause !== connection.cause || previous.connection.message !== connection.message) {
12070
+ if ((previous == null ? void 0 : previous.threadId) !== attachId || previous.connection.status !== connection.status || previous.connection.cause !== connection.cause || previous.connection.message !== connection.message || previous.connection.attempt !== connection.attempt) {
11039
12071
  const update = { threadId: attachId, connection };
11040
12072
  lastConnectionRef.current = update;
11041
12073
  queueMicrotask(() => {
@@ -11107,46 +12139,30 @@ function toJSONSchema(schema2) {
11107
12139
  if (isStandardSchema(schema2)) throw new Error("Could not convert schema to JSON Schema. The schema implements Standard Schema but does not support JSON Schema conversion. If you are using Zod, please upgrade to Zod v4 (npm install zod@latest). Alternatively, pass a plain JSON Schema object instead.");
11108
12140
  return schema2;
11109
12141
  }
11110
- function defaultToolFilter(_name, tool) {
11111
- return !tool.disabled && tool.type !== "backend" && (tool.type !== "frontend" || tool.execute !== void 0);
11112
- }
11113
- function toolHasUploadableParameters(tool) {
11114
- var _a3;
11115
- return tool.parameters !== void 0 && !((_a3 = tool.unstable_backendDefault) == null ? void 0 : _a3.parameters);
11116
- }
11117
- function toToolsJSONSchema(tools, options = {}) {
11118
- if (!tools) return {};
11119
- const filter = options.filter ?? defaultToolFilter;
11120
- return Object.fromEntries(Object.entries(tools).filter(([name, tool]) => filter(name, tool)).filter((entry) => toolHasUploadableParameters(entry[1])).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([name, tool]) => [name, {
11121
- ...tool.description && { description: tool.description },
11122
- parameters: toJSONSchema(tool.parameters),
11123
- ...tool.providerOptions && { providerOptions: tool.providerOptions }
11124
- }]));
11125
- }
11126
12142
  function hasCallableExecute(entry) {
11127
12143
  return !!entry && typeof entry === "object" && typeof entry.execute === "function";
11128
12144
  }
11129
12145
  function collectStatewireClientTools(toolkit) {
11130
12146
  const executable = Object.entries(toolkit).filter(([, entry]) => hasCallableExecute(entry));
11131
12147
  if (executable.length === 0) return [];
11132
- let schemas;
11133
- try {
11134
- schemas = toToolsJSONSchema(toolkit, {
11135
- filter: (name) => executable.some(([toolName]) => toolName === name)
11136
- });
11137
- } catch (error2) {
11138
- console.warn("[AthenaSDK] failed to convert frontend tool schemas for statewire:", error2);
11139
- return [];
11140
- }
11141
12148
  return executable.flatMap(([name, entry]) => {
11142
- const schema2 = schemas[name];
11143
- if (!schema2) return [];
12149
+ if (entry.parameters === void 0) return [];
12150
+ let parameters;
12151
+ try {
12152
+ parameters = toJSONSchema(entry.parameters);
12153
+ } catch (error2) {
12154
+ console.warn(
12155
+ `[AthenaSDK] failed to convert frontend tool schema for statewire (${name}):`,
12156
+ error2
12157
+ );
12158
+ return [];
12159
+ }
11144
12160
  const execute = entry.execute;
11145
12161
  return [
11146
12162
  {
11147
12163
  name,
11148
- description: schema2.description,
11149
- parameters: schema2.parameters ?? { type: "object" },
12164
+ description: entry.description,
12165
+ parameters,
11150
12166
  handler: async (args, { toolCallId }) => {
11151
12167
  const controller = new AbortController();
11152
12168
  const output = await execute(args, {
@@ -11170,39 +12186,6 @@ function statewireClientToolWireEntries(tools) {
11170
12186
  requires_write: false
11171
12187
  }));
11172
12188
  }
11173
- const DEEP_AGENT_RUNTIME_MARKER = "athena_deep_agent";
11174
- const STATEWIRE_START_CHANNEL = "web";
11175
- const STATEWIRE_RUN_LABEL = "Athena SDK";
11176
- const DEFAULT_STATEWIRE_MODEL = "claude-sonnet-5";
11177
- function buildStatewireRunConfig(options = {}) {
11178
- var _a3, _b2, _c2, _d2;
11179
- const model = options.model ?? DEFAULT_STATEWIRE_MODEL;
11180
- const enabledTools = Array.from(
11181
- /* @__PURE__ */ new Set([...options.tools ?? [], ...options.frontendToolIds ?? []])
11182
- );
11183
- const systemPrompt = ((_a3 = options.systemPrompt) == null ? void 0 : _a3.trim()) ?? "";
11184
- return {
11185
- custom: {
11186
- runtime: DEEP_AGENT_RUNTIME_MARKER,
11187
- start_channel: STATEWIRE_START_CHANNEL,
11188
- model,
11189
- enabled_tools: enabledTools,
11190
- panel_config: {
11191
- model,
11192
- enabled_tools: enabledTools,
11193
- system_prompt: systemPrompt,
11194
- run_label: STATEWIRE_RUN_LABEL
11195
- },
11196
- ...systemPrompt ? { system_prompt: systemPrompt } : {},
11197
- ...((_b2 = options.workbench) == null ? void 0 : _b2.length) ? { workbench: options.workbench } : {},
11198
- ...((_c2 = options.knowledgeBase) == null ? void 0 : _c2.length) ? { knowledge_base: options.knowledgeBase } : {},
11199
- ...options.customToolConfigs ? { custom_tool_configs: options.customToolConfigs } : {},
11200
- ...options.appId ? { app_id: options.appId } : {},
11201
- ...((_d2 = options.clientTools) == null ? void 0 : _d2.length) ? { client_tools: options.clientTools } : {},
11202
- ...options.extraRunConfig ?? {}
11203
- }
11204
- };
11205
- }
11206
12189
  const EMPTY_TOOLKIT = {};
11207
12190
  const EMPTY_TOOL_IDS = [];
11208
12191
  function useStatewireClientTools(frontendToolkit) {
@@ -11220,6 +12203,8 @@ function useAthenaStatewireRuntime(config2) {
11220
12203
  token,
11221
12204
  getToken,
11222
12205
  model,
12206
+ agent: agent2,
12207
+ channel,
11223
12208
  tools = EMPTY_TOOL_IDS,
11224
12209
  frontendToolIds = EMPTY_TOOL_IDS,
11225
12210
  frontendToolkit = EMPTY_TOOLKIT,
@@ -11247,6 +12232,28 @@ function useAthenaStatewireRuntime(config2) {
11247
12232
  const clientToolsRef = useRef(clientTools);
11248
12233
  clientToolsRef.current = clientTools;
11249
12234
  const [canPersistSession] = useState(() => typeof localStorage !== "undefined");
12235
+ useEffect(() => {
12236
+ if (agent2 && !parseCollabAgentRef(agent2)) {
12237
+ athenaDiagnostics.emit("sdk.config.warning", {
12238
+ level: "warn",
12239
+ data: {
12240
+ prop: "agent",
12241
+ value: agent2,
12242
+ reason: "the statewire transport always runs the Athena deep agent; only 'collab_agent:<asset_id>' refs apply. Use transport='legacy' for named agents."
12243
+ }
12244
+ });
12245
+ }
12246
+ }, [agent2]);
12247
+ const attachSpanRef = useRef(null);
12248
+ const attachThreadRef = useRef(null);
12249
+ if (attachThreadRef.current !== threadId) {
12250
+ attachThreadRef.current = threadId;
12251
+ attachSpanRef.current = athenaDiagnostics.span(
12252
+ `statewire.attach:${threadId}`,
12253
+ "statewire.attach.start",
12254
+ { thread_id: threadId, is_new_chat: isNewChat }
12255
+ );
12256
+ }
11250
12257
  const thread = useDeepAgentThread({
11251
12258
  threadId,
11252
12259
  baseUrl: syncUrl,
@@ -11276,11 +12283,47 @@ function useAthenaStatewireRuntime(config2) {
11276
12283
  }
11277
12284
  },
11278
12285
  capabilities: { edit: true, reload: true, continue: true },
11279
- onConnectionChange,
12286
+ onStateChange: () => {
12287
+ const endSpan = attachSpanRef.current;
12288
+ if (endSpan) {
12289
+ attachSpanRef.current = null;
12290
+ endSpan("statewire.snapshot", { data: { thread_id: threadId } });
12291
+ }
12292
+ },
12293
+ onConnectionChange: (connection) => {
12294
+ athenaDiagnostics.gauge("statewire.connection", (connection == null ? void 0 : connection.status) ?? null);
12295
+ if ((connection == null ? void 0 : connection.status) === "gone") {
12296
+ athenaDiagnostics.emit("statewire.connection", {
12297
+ level: "warn",
12298
+ data: { status: connection.status, message: connection.message }
12299
+ });
12300
+ }
12301
+ onConnectionChange == null ? void 0 : onConnectionChange(connection);
12302
+ },
11280
12303
  onRawConnectionChange,
11281
- onLegacyReadOnly,
12304
+ onLegacyReadOnly: (legacyReadOnly) => {
12305
+ if (legacyReadOnly) {
12306
+ athenaDiagnostics.emit("statewire.read_only", {
12307
+ level: "warn",
12308
+ data: { thread_id: threadId }
12309
+ });
12310
+ }
12311
+ onLegacyReadOnly == null ? void 0 : onLegacyReadOnly(legacyReadOnly);
12312
+ },
11282
12313
  onRunningChange,
11283
12314
  onError: (error2) => {
12315
+ if (!isStatewireChannelTeardown(error2)) {
12316
+ athenaDiagnostics.error(
12317
+ "statewire.error",
12318
+ error2,
12319
+ {
12320
+ code: "statewire_rejected",
12321
+ message: "The statewire host rejected a command",
12322
+ hint: "Inspect error.detail — agora rejections carry a structured {code, message}."
12323
+ },
12324
+ { thread_id: threadId }
12325
+ );
12326
+ }
11284
12327
  if (onErrorRef.current) {
11285
12328
  onErrorRef.current(error2);
11286
12329
  return;
@@ -11296,6 +12339,8 @@ function useAthenaStatewireRuntime(config2) {
11296
12339
  const aui = useAui({ thread, tools: auiTools });
11297
12340
  const runConfigInputsRef = useRef({
11298
12341
  model,
12342
+ agent: agent2,
12343
+ channel,
11299
12344
  tools,
11300
12345
  frontendToolIds,
11301
12346
  workbench,
@@ -11307,6 +12352,8 @@ function useAthenaStatewireRuntime(config2) {
11307
12352
  });
11308
12353
  runConfigInputsRef.current = {
11309
12354
  model,
12355
+ agent: agent2,
12356
+ channel,
11310
12357
  tools,
11311
12358
  frontendToolIds,
11312
12359
  workbench,
@@ -16069,7 +17116,7 @@ function selectThreadListItemRemoteId(state) {
16069
17116
  return (_a3 = state.threadListItem) == null ? void 0 : _a3.remoteId;
16070
17117
  }
16071
17118
  function useAthenaAuiThreadRemoteId() {
16072
- return useAuiState(selectThreadListItemRemoteId);
17119
+ return useAuiState$1(selectThreadListItemRemoteId);
16073
17120
  }
16074
17121
  function useAthenaThreadId() {
16075
17122
  return useContext(AthenaThreadIdContext);
@@ -18892,7 +19939,7 @@ const TITLE_POLL_MAX_DURATION_MS = 6e4;
18892
19939
  function StatewireThreadTitlePoller() {
18893
19940
  var _a3;
18894
19941
  const list2 = useAthenaStatewireThreadList();
18895
- const hasMessages = useAuiState((s) => {
19942
+ const hasMessages = useAuiState$1((s) => {
18896
19943
  var _a4;
18897
19944
  return (((_a4 = s.optional.thread) == null ? void 0 : _a4.messages.length) ?? 0) > 0;
18898
19945
  });
@@ -18947,15 +19994,15 @@ function useActiveThreadStateHydration({
18947
19994
  }) {
18948
19995
  const aui = useAui();
18949
19996
  const hasThread = aui.thread.source !== null;
18950
- const threadId = useAuiState((s) => {
19997
+ const threadId = useAuiState$1((s) => {
18951
19998
  const item = s.optional.threadListItem;
18952
19999
  return item ? selectHydratableThreadId(item) : null;
18953
20000
  });
18954
- const messageCount = useAuiState((s) => {
20001
+ const messageCount = useAuiState$1((s) => {
18955
20002
  var _a3;
18956
20003
  return ((_a3 = s.optional.thread) == null ? void 0 : _a3.messages.length) ?? 0;
18957
20004
  });
18958
- const isRunning = useAuiState((s) => {
20005
+ const isRunning = useAuiState$1((s) => {
18959
20006
  var _a3;
18960
20007
  return ((_a3 = s.optional.thread) == null ? void 0 : _a3.isRunning) ?? false;
18961
20008
  });
@@ -19013,7 +20060,7 @@ const selectActiveThreadRemoteId = (state) => {
19013
20060
  };
19014
20061
  function useAthenaThreadManager() {
19015
20062
  const statewireList = useAthenaStatewireThreadList();
19016
- const statewireIsThreadLoading = useAuiState((s) => {
20063
+ const statewireIsThreadLoading = useAuiState$1((s) => {
19017
20064
  var _a3;
19018
20065
  return ((_a3 = s.optional.thread) == null ? void 0 : _a3.isLoading) ?? false;
19019
20066
  });
@@ -19029,15 +20076,15 @@ function useAthenaThreadManager() {
19029
20076
  }, [statewireList, statewireIsThreadLoading]);
19030
20077
  const aui = useAui();
19031
20078
  const hasThreads = aui.threads.source !== null;
19032
- const activeThreadId = useAuiState((s) => {
20079
+ const activeThreadId = useAuiState$1((s) => {
19033
20080
  const threads = s.optional.threads;
19034
20081
  return threads ? selectActiveThreadRemoteId(threads) : null;
19035
20082
  });
19036
- const isThreadLoading = useAuiState((s) => {
20083
+ const isThreadLoading = useAuiState$1((s) => {
19037
20084
  var _a3;
19038
20085
  return ((_a3 = s.optional.thread) == null ? void 0 : _a3.isLoading) ?? false;
19039
20086
  });
19040
- const isListLoading = useAuiState((s) => {
20087
+ const isListLoading = useAuiState$1((s) => {
19041
20088
  var _a3;
19042
20089
  return (_a3 = s.optional.threads) == null ? void 0 : _a3.isLoading;
19043
20090
  });
@@ -19069,17 +20116,17 @@ const POLL_DELAY_MS = 5e3;
19069
20116
  const POLL_INTERVAL_MS = 1e3;
19070
20117
  const POLL_MAX_DURATION_MS = 6e4;
19071
20118
  function useThreadTitlePolling(refresh) {
19072
- const threadKey = useAuiState(
20119
+ const threadKey = useAuiState$1(
19073
20120
  (s) => {
19074
20121
  var _a3, _b2;
19075
20122
  return ((_a3 = s.optional.threadListItem) == null ? void 0 : _a3.remoteId) ?? ((_b2 = s.optional.threadListItem) == null ? void 0 : _b2.id) ?? null;
19076
20123
  }
19077
20124
  );
19078
- const hasMessages = useAuiState((s) => {
20125
+ const hasMessages = useAuiState$1((s) => {
19079
20126
  var _a3;
19080
20127
  return (((_a3 = s.optional.thread) == null ? void 0 : _a3.messages.length) ?? 0) > 0;
19081
20128
  });
19082
- const currentTitle = useAuiState((s) => {
20129
+ const currentTitle = useAuiState$1((s) => {
19083
20130
  var _a3;
19084
20131
  return ((_a3 = s.optional.threadListItem) == null ? void 0 : _a3.title) ?? "";
19085
20132
  });
@@ -19301,452 +20348,6 @@ const themes = {
19301
20348
  radius: "0.625rem"
19302
20349
  }
19303
20350
  };
19304
- const DEFAULT_CAPTURE_GATE_CONFIG = {
19305
- globalMaxPerWindow: 50,
19306
- globalWindowMs: 1e4,
19307
- criticalReservePerWindow: 15,
19308
- defaultEventMaxPerWindow: 12,
19309
- defaultEventWindowMs: 6e4,
19310
- defaultDedupeWindowMs: 5e3,
19311
- flushIntervalMs: 3e4,
19312
- flushCoalesceThreshold: 20,
19313
- eventOverrides: {
19314
- memory_profile_sample: { maxPerWindow: 2, windowMs: 3e4, dedupeWindowMs: 15e3 },
19315
- long_task_detected: { maxPerWindow: 3, windowMs: 6e4, dedupeWindowMs: 1e4 },
19316
- collab_connection_status_changed: { maxPerWindow: 6, windowMs: 6e4 },
19317
- collab_first_remote_update: { maxPerWindow: 3, windowMs: 6e4 },
19318
- collab_first_local_update: { maxPerWindow: 3, windowMs: 6e4 },
19319
- collab_render_time_sync_fix: { maxPerWindow: 3, windowMs: 6e4 },
19320
- collab_visibility_recovery: { maxPerWindow: 4, windowMs: 6e4 },
19321
- langgraph_message_validation_error: {
19322
- maxPerWindow: 8,
19323
- windowMs: 6e4,
19324
- dedupeWindowMs: 15e3
19325
- },
19326
- langgraph_messages_validation_error: {
19327
- maxPerWindow: 5,
19328
- windowMs: 6e4,
19329
- dedupeWindowMs: 15e3
19330
- },
19331
- langgraph_interrupt_validation_error: {
19332
- maxPerWindow: 5,
19333
- windowMs: 6e4,
19334
- dedupeWindowMs: 15e3
19335
- },
19336
- langgraph_state_validation_error: {
19337
- maxPerWindow: 5,
19338
- windowMs: 6e4,
19339
- dedupeWindowMs: 15e3
19340
- },
19341
- graphql_error: { maxPerWindow: 12, windowMs: 6e4, dedupeWindowMs: 1e4 },
19342
- chat_error: { maxPerWindow: 8, windowMs: 6e4, dedupeWindowMs: 5e3 },
19343
- memory_critical_threshold: { maxPerWindow: 3, windowMs: 3e5 },
19344
- memory_warning_threshold: { maxPerWindow: 3, windowMs: 3e5 },
19345
- pptx_slide_changed: { maxPerWindow: 8, windowMs: 3e4 }
19346
- }
19347
- };
19348
- const CRITICAL_EVENT_PATTERNS = [
19349
- /(?:^|_)failed$/,
19350
- /(?:^|_)error(?:_|$)/,
19351
- /crash/,
19352
- /^oom_/,
19353
- /aw_snap/,
19354
- /chunk_load/,
19355
- /global_error/,
19356
- /\$exception$/,
19357
- /^404_error$/,
19358
- /^500_error$/,
19359
- /_boundary_/
19360
- ];
19361
- const BYPASS_OPTION_KEY = "__posthog_gate_bypass";
19362
- function isCriticalPosthogEvent(event) {
19363
- return CRITICAL_EVENT_PATTERNS.some((pattern) => pattern.test(event));
19364
- }
19365
- function shouldBypassCaptureGate(options) {
19366
- if (!options || typeof options !== "object") return false;
19367
- return options[BYPASS_OPTION_KEY] === true;
19368
- }
19369
- function withCaptureGateBypass(options) {
19370
- return {
19371
- ...options ?? {},
19372
- [BYPASS_OPTION_KEY]: true
19373
- };
19374
- }
19375
- function pruneWindow(window2, now, windowMs) {
19376
- const cutoff = now - windowMs;
19377
- while (window2.timestamps.length > 0 && window2.timestamps[0] < cutoff) {
19378
- window2.timestamps.shift();
19379
- }
19380
- }
19381
- function countInWindow(window2, now, windowMs) {
19382
- pruneWindow(window2, now, windowMs);
19383
- return window2.timestamps.length;
19384
- }
19385
- function recordInWindow(window2, now) {
19386
- window2.timestamps.push(now);
19387
- }
19388
- function stableStringify(value) {
19389
- if (value == null) return String(value);
19390
- if (typeof value !== "object") return String(value);
19391
- if (Array.isArray(value)) {
19392
- return `[${value.map((item) => stableStringify(item)).join(",")}]`;
19393
- }
19394
- const record2 = value;
19395
- const keys2 = Object.keys(record2).sort();
19396
- return `{${keys2.map((key) => `${key}:${stableStringify(record2[key])}`).join(",")}}`;
19397
- }
19398
- function fingerprintProperties(properties) {
19399
- if (!properties) return "";
19400
- const keys2 = [
19401
- "error",
19402
- "error_message",
19403
- "message",
19404
- "reason",
19405
- "status",
19406
- "code",
19407
- "asset_id",
19408
- "doc_id",
19409
- "thread_id",
19410
- "session_id",
19411
- "operation",
19412
- "path",
19413
- "url",
19414
- "chunk_identifier",
19415
- "validation_path"
19416
- ];
19417
- const subset = {};
19418
- for (const key of keys2) {
19419
- if (key in properties) {
19420
- subset[key] = properties[key];
19421
- }
19422
- }
19423
- return stableStringify(subset);
19424
- }
19425
- function buildCaptureFingerprint(event, properties) {
19426
- return `${event}|${fingerprintProperties(properties)}`;
19427
- }
19428
- function buildCoalescedCaptureProperties(payload) {
19429
- const windowMs = payload.lastAt - payload.firstAt;
19430
- return {
19431
- ...payload.properties,
19432
- coalesced: true,
19433
- coalesced_count: payload.coalescedCount,
19434
- coalesced_first_at: new Date(payload.firstAt).toISOString(),
19435
- coalesced_last_at: new Date(payload.lastAt).toISOString(),
19436
- coalesced_window_ms: windowMs,
19437
- coalesced_suppression_reason: payload.suppressionReason
19438
- };
19439
- }
19440
- class PosthogCaptureGate {
19441
- constructor(config2 = DEFAULT_CAPTURE_GATE_CONFIG) {
19442
- __publicField(this, "config");
19443
- __publicField(this, "globalWindow", { timestamps: [] });
19444
- __publicField(this, "eventWindows", /* @__PURE__ */ new Map());
19445
- __publicField(this, "activeDedupe", /* @__PURE__ */ new Map());
19446
- __publicField(this, "coalesceBuckets", /* @__PURE__ */ new Map());
19447
- __publicField(this, "emittedTotal", 0);
19448
- __publicField(this, "coalescedTotal", 0);
19449
- __publicField(this, "flushedCoalescedTotal", 0);
19450
- this.config = config2;
19451
- }
19452
- resetForTests() {
19453
- this.globalWindow.timestamps.length = 0;
19454
- this.eventWindows.clear();
19455
- this.activeDedupe.clear();
19456
- this.coalesceBuckets.clear();
19457
- this.emittedTotal = 0;
19458
- this.coalescedTotal = 0;
19459
- this.flushedCoalescedTotal = 0;
19460
- }
19461
- getSnapshot() {
19462
- const coalescedPendingByEvent = {};
19463
- let coalescedPending = 0;
19464
- for (const bucket of this.coalesceBuckets.values()) {
19465
- coalescedPending += bucket.count;
19466
- coalescedPendingByEvent[bucket.event] = (coalescedPendingByEvent[bucket.event] ?? 0) + bucket.count;
19467
- }
19468
- return {
19469
- coalescedPending,
19470
- coalescedPendingByEvent,
19471
- emittedTotal: this.emittedTotal,
19472
- coalescedTotal: this.coalescedTotal,
19473
- flushedCoalescedTotal: this.flushedCoalescedTotal
19474
- };
19475
- }
19476
- evaluateCapture(event, properties, options, now = Date.now()) {
19477
- if (shouldBypassCaptureGate(options)) {
19478
- return { action: "emit" };
19479
- }
19480
- const fingerprint = buildCaptureFingerprint(event, properties);
19481
- const bucketKey = fingerprint;
19482
- const override = this.config.eventOverrides[event];
19483
- const dedupeWindowMs = (override == null ? void 0 : override.dedupeWindowMs) ?? this.config.defaultDedupeWindowMs;
19484
- const lastDedupe = this.activeDedupe.get(event);
19485
- if (lastDedupe && lastDedupe.fingerprint === fingerprint && now - lastDedupe.at < dedupeWindowMs) {
19486
- return this.recordCoalesce(event, bucketKey, fingerprint, properties, "dedupe", now);
19487
- }
19488
- const critical = isCriticalPosthogEvent(event);
19489
- const globalCount = countInWindow(this.globalWindow, now, this.config.globalWindowMs);
19490
- const normalBudget = Math.max(
19491
- 0,
19492
- this.config.globalMaxPerWindow - this.config.criticalReservePerWindow
19493
- );
19494
- if (critical) {
19495
- if (globalCount >= this.config.globalMaxPerWindow) {
19496
- return this.recordCoalesce(event, bucketKey, fingerprint, properties, "global_budget", now);
19497
- }
19498
- } else if (globalCount >= normalBudget) {
19499
- return this.recordCoalesce(event, bucketKey, fingerprint, properties, "global_budget", now);
19500
- }
19501
- const eventWindow = this.eventWindows.get(event) ?? { timestamps: [] };
19502
- this.eventWindows.set(event, eventWindow);
19503
- const eventMax = (override == null ? void 0 : override.maxPerWindow) ?? this.config.defaultEventMaxPerWindow;
19504
- const eventWindowMs = (override == null ? void 0 : override.windowMs) ?? this.config.defaultEventWindowMs;
19505
- const eventCount = countInWindow(eventWindow, now, eventWindowMs);
19506
- if (eventCount >= eventMax) {
19507
- return this.recordCoalesce(event, bucketKey, fingerprint, properties, "event_budget", now);
19508
- }
19509
- recordInWindow(this.globalWindow, now);
19510
- recordInWindow(eventWindow, now);
19511
- this.activeDedupe.set(event, { fingerprint, bucketKey, at: now });
19512
- this.emittedTotal += 1;
19513
- return { action: "emit" };
19514
- }
19515
- /** Returns payloads ready to flush (does not mutate buckets until caller confirms). */
19516
- collectFlushCandidates(now = Date.now()) {
19517
- const payloads = [];
19518
- for (const bucket of this.coalesceBuckets.values()) {
19519
- const shouldFlushBySize = bucket.count >= this.config.flushCoalesceThreshold;
19520
- const shouldFlushByAge = now - bucket.firstAt >= this.config.flushIntervalMs;
19521
- if (!shouldFlushBySize && !shouldFlushByAge) {
19522
- continue;
19523
- }
19524
- payloads.push({
19525
- bucketKey: bucket.bucketKey,
19526
- event: bucket.event,
19527
- properties: bucket.sampleProperties,
19528
- coalescedCount: bucket.count,
19529
- firstAt: bucket.firstAt,
19530
- lastAt: bucket.lastAt,
19531
- suppressionReason: bucket.suppressionReason
19532
- });
19533
- }
19534
- return payloads;
19535
- }
19536
- /** Remove flushed bucket keys after successful emit. */
19537
- acknowledgeFlushed(payloads) {
19538
- for (const payload of payloads) {
19539
- this.coalesceBuckets.delete(payload.bucketKey);
19540
- this.flushedCoalescedTotal += payload.coalescedCount;
19541
- }
19542
- }
19543
- /** After coalescing, flush immediately if the bucket crossed the early threshold. */
19544
- takeBucketIfReady(bucketKey, now = Date.now()) {
19545
- const bucket = this.coalesceBuckets.get(bucketKey);
19546
- if (!bucket) return null;
19547
- const shouldFlushBySize = bucket.count >= this.config.flushCoalesceThreshold;
19548
- const shouldFlushByAge = now - bucket.firstAt >= this.config.flushIntervalMs;
19549
- if (!shouldFlushBySize && !shouldFlushByAge) {
19550
- return null;
19551
- }
19552
- this.coalesceBuckets.delete(bucketKey);
19553
- this.flushedCoalescedTotal += bucket.count;
19554
- return {
19555
- bucketKey: bucket.bucketKey,
19556
- event: bucket.event,
19557
- properties: bucket.sampleProperties,
19558
- coalescedCount: bucket.count,
19559
- firstAt: bucket.firstAt,
19560
- lastAt: bucket.lastAt,
19561
- suppressionReason: bucket.suppressionReason
19562
- };
19563
- }
19564
- /** Force-flush every pending bucket (e.g. page hide). */
19565
- collectAllPending() {
19566
- return [...this.coalesceBuckets.values()].map((bucket) => ({
19567
- bucketKey: bucket.bucketKey,
19568
- event: bucket.event,
19569
- properties: bucket.sampleProperties,
19570
- coalescedCount: bucket.count,
19571
- firstAt: bucket.firstAt,
19572
- lastAt: bucket.lastAt,
19573
- suppressionReason: bucket.suppressionReason
19574
- }));
19575
- }
19576
- recordCoalesce(event, bucketKey, fingerprint, properties, reason, now) {
19577
- const existing = this.coalesceBuckets.get(bucketKey);
19578
- if (existing) {
19579
- existing.count += 1;
19580
- existing.lastAt = now;
19581
- existing.sampleProperties = { ...existing.sampleProperties, ...properties ?? {} };
19582
- } else {
19583
- this.coalesceBuckets.set(bucketKey, {
19584
- event,
19585
- bucketKey,
19586
- fingerprint,
19587
- count: 1,
19588
- firstAt: now,
19589
- lastAt: now,
19590
- suppressionReason: reason,
19591
- sampleProperties: { ...properties ?? {} }
19592
- });
19593
- }
19594
- this.coalescedTotal += 1;
19595
- this.activeDedupe.set(event, { fingerprint, bucketKey, at: now });
19596
- return { action: "coalesce", reason, bucketKey };
19597
- }
19598
- }
19599
- const gate = new PosthogCaptureGate(DEFAULT_CAPTURE_GATE_CONFIG);
19600
- let wrappedClient = null;
19601
- let originalCaptureRef = null;
19602
- let flushTimer = null;
19603
- let lifecycleHooksInstalled = false;
19604
- function getPosthogCaptureGate() {
19605
- return gate;
19606
- }
19607
- function emitThroughOriginal(event, properties, options) {
19608
- if (!originalCaptureRef) return void 0;
19609
- return originalCaptureRef(event, properties, withCaptureGateBypass(options));
19610
- }
19611
- function flushCoalescedPayload(payload) {
19612
- emitThroughOriginal(payload.event, buildCoalescedCaptureProperties(payload));
19613
- }
19614
- function flushCoalescedCaptures(options) {
19615
- const payloads = (options == null ? void 0 : options.force) ? gate.collectAllPending() : gate.collectFlushCandidates();
19616
- if (payloads.length === 0) return;
19617
- for (const payload of payloads) {
19618
- flushCoalescedPayload(payload);
19619
- }
19620
- gate.acknowledgeFlushed(payloads);
19621
- }
19622
- function installLifecycleFlushHooks() {
19623
- if (lifecycleHooksInstalled || typeof window === "undefined") return;
19624
- lifecycleHooksInstalled = true;
19625
- const flushOnHide = () => {
19626
- flushCoalescedCaptures({ force: true });
19627
- };
19628
- window.addEventListener("pagehide", flushOnHide);
19629
- document.addEventListener("visibilitychange", () => {
19630
- if (document.visibilityState === "hidden") {
19631
- flushOnHide();
19632
- }
19633
- });
19634
- if (!flushTimer) {
19635
- flushTimer = setInterval(() => {
19636
- flushCoalescedCaptures();
19637
- }, DEFAULT_CAPTURE_GATE_CONFIG.flushIntervalMs);
19638
- }
19639
- }
19640
- function wrapPosthogClient(client) {
19641
- if (wrappedClient === client) {
19642
- return client;
19643
- }
19644
- originalCaptureRef = client.capture.bind(client);
19645
- const originalCaptureException = typeof client.captureException === "function" ? client.captureException.bind(client) : null;
19646
- installLifecycleFlushHooks();
19647
- client.capture = ((event, properties, options) => {
19648
- const outcome = gate.evaluateCapture(event, properties, options);
19649
- if (outcome.action === "coalesce") {
19650
- const readyPayload = gate.takeBucketIfReady(outcome.bucketKey);
19651
- if (readyPayload) {
19652
- flushCoalescedPayload(readyPayload);
19653
- }
19654
- return void 0;
19655
- }
19656
- return emitThroughOriginal(event, properties, options);
19657
- });
19658
- if (originalCaptureException) {
19659
- client.captureException = ((error2, additionalProperties) => {
19660
- const mergedProperties = {
19661
- ...additionalProperties ?? {},
19662
- $exception_message: error2 instanceof Error ? error2.message : String(error2),
19663
- $exception_type: error2 instanceof Error ? error2.name : typeof error2
19664
- };
19665
- const outcome = gate.evaluateCapture("$exception", mergedProperties);
19666
- if (outcome.action === "coalesce") {
19667
- const readyPayload = gate.takeBucketIfReady(outcome.bucketKey);
19668
- if (readyPayload) {
19669
- flushCoalescedPayload(readyPayload);
19670
- }
19671
- return void 0;
19672
- }
19673
- return originalCaptureException(error2, additionalProperties);
19674
- });
19675
- }
19676
- wrappedClient = client;
19677
- return client;
19678
- }
19679
- function capturePosthogEvent(client, event, properties, options) {
19680
- if (!client || typeof client.capture !== "function") return;
19681
- client.capture(event, properties, options);
19682
- }
19683
- function capturePosthogException(client, error2, properties, options) {
19684
- if (!client) return;
19685
- if (typeof client.captureException === "function") {
19686
- client.captureException(error2, properties);
19687
- return;
19688
- }
19689
- capturePosthogEvent(
19690
- client,
19691
- "$exception",
19692
- {
19693
- ...properties ?? {},
19694
- $exception_message: error2.message,
19695
- $exception_type: error2.name,
19696
- $exception_stack: error2.stack
19697
- },
19698
- options
19699
- );
19700
- }
19701
- let posthogInstance = null;
19702
- let initPromise = null;
19703
- const DEFAULT_HOST = "https://us.i.posthog.com";
19704
- async function initializePostHog(apiKey, host, debug) {
19705
- if (posthogInstance) return posthogInstance;
19706
- if (typeof window === "undefined") return null;
19707
- try {
19708
- const posthog = (await import("posthog-js")).default;
19709
- posthog.init(apiKey, {
19710
- api_host: host,
19711
- autocapture: true,
19712
- capture_pageview: false,
19713
- session_recording: {
19714
- recordCrossOriginIframes: true,
19715
- maskAllInputs: true
19716
- },
19717
- loaded: (ph) => {
19718
- wrapPosthogClient(ph);
19719
- if (debug) {
19720
- ph.debug(true);
19721
- }
19722
- }
19723
- });
19724
- wrapPosthogClient(posthog);
19725
- posthogInstance = posthog;
19726
- return posthog;
19727
- } catch {
19728
- initPromise = null;
19729
- return null;
19730
- }
19731
- }
19732
- function getPostHogInstance() {
19733
- return posthogInstance;
19734
- }
19735
- function PostHogProvider({
19736
- children,
19737
- config: config2
19738
- }) {
19739
- const apiKey = (config2 == null ? void 0 : config2.apiKey) ?? "";
19740
- const host = (config2 == null ? void 0 : config2.host) ?? DEFAULT_HOST;
19741
- const debug = (config2 == null ? void 0 : config2.debug) ?? false;
19742
- useEffect(() => {
19743
- if (!apiKey || typeof window === "undefined") return;
19744
- if (!initPromise) {
19745
- initPromise = initializePostHog(apiKey, host, debug);
19746
- }
19747
- }, [apiKey, host, debug]);
19748
- return /* @__PURE__ */ jsx(Fragment$1, { children });
19749
- }
19750
20351
  const resolveTokenOverride = ({
19751
20352
  config: config2,
19752
20353
  token
@@ -19876,6 +20477,8 @@ function AthenaStatewireStandalone({
19876
20477
  token,
19877
20478
  getToken,
19878
20479
  model,
20480
+ agent: agent2,
20481
+ channel,
19879
20482
  tools,
19880
20483
  frontendToolIds,
19881
20484
  frontendTools,
@@ -19907,6 +20510,8 @@ function AthenaStatewireStandalone({
19907
20510
  token,
19908
20511
  getToken,
19909
20512
  model,
20513
+ agent: agent2,
20514
+ channel,
19910
20515
  tools,
19911
20516
  frontendToolIds,
19912
20517
  frontendToolkit: frontendTools,
@@ -20182,6 +20787,7 @@ function AthenaProvider({
20182
20787
  apiKey,
20183
20788
  token: tokenProp,
20184
20789
  agent: agent2,
20790
+ channel,
20185
20791
  model,
20186
20792
  tools = [],
20187
20793
  frontendTools = {},
@@ -20204,8 +20810,32 @@ function AthenaProvider({
20204
20810
  theme,
20205
20811
  linkClicks,
20206
20812
  citationLinks,
20207
- posthog: posthogProp
20813
+ posthog: posthogProp,
20814
+ debug,
20815
+ onDiagnostic,
20816
+ onError
20208
20817
  }) {
20818
+ const onDiagnosticRef = useRef(onDiagnostic);
20819
+ onDiagnosticRef.current = onDiagnostic;
20820
+ const onErrorRef = useRef(onError);
20821
+ onErrorRef.current = onError;
20822
+ useEffect(() => {
20823
+ installAthenaDiagnosticsGlobal();
20824
+ return athenaDiagnostics.addConsumer({
20825
+ onEvent: (event) => {
20826
+ var _a3;
20827
+ return (_a3 = onDiagnosticRef.current) == null ? void 0 : _a3.call(onDiagnosticRef, event);
20828
+ },
20829
+ onError: (error2, event) => {
20830
+ var _a3;
20831
+ return (_a3 = onErrorRef.current) == null ? void 0 : _a3.call(onErrorRef, error2, event);
20832
+ }
20833
+ });
20834
+ }, []);
20835
+ const debugKey = JSON.stringify(debugPropToDiagnosticsConfig(debug));
20836
+ useEffect(() => {
20837
+ athenaDiagnostics.configure(debugPropToDiagnosticsConfig(debug));
20838
+ }, [debugKey]);
20209
20839
  const frontendToolNames = useMemo(() => Object.keys(frontendTools), [frontendTools]);
20210
20840
  const effectiveFrontendTools = useMemo(
20211
20841
  () => disableAutoOpen ? frontendTools : { ...DEFAULT_AUTO_OPEN_TOOLS, ...frontendTools },
@@ -20232,10 +20862,31 @@ function AthenaProvider({
20232
20862
  transport: configuredTransport
20233
20863
  });
20234
20864
  useEffect(() => {
20865
+ athenaDiagnostics.gauge("sdk.transport", effectiveTransport);
20866
+ athenaDiagnostics.emit("sdk.transport", {
20867
+ level: "debug",
20868
+ data: { transport: effectiveTransport, thread_list: enableThreadList }
20869
+ });
20235
20870
  if (transportFallbackReason) {
20871
+ athenaDiagnostics.emit("sdk.config.warning", {
20872
+ level: "warn",
20873
+ data: { prop: "transport", reason: transportFallbackReason }
20874
+ });
20236
20875
  console.warn(`[AthenaSDK] ${transportFallbackReason}`);
20237
20876
  }
20238
- }, [transportFallbackReason]);
20877
+ }, [effectiveTransport, enableThreadList, transportFallbackReason]);
20878
+ useEffect(() => {
20879
+ if (channel && effectiveTransport !== "statewire") {
20880
+ athenaDiagnostics.emit("sdk.config.warning", {
20881
+ level: "warn",
20882
+ data: {
20883
+ prop: "channel",
20884
+ value: channel,
20885
+ reason: "the 'channel' prop requires transport='statewire'; the legacy transport ignores it."
20886
+ }
20887
+ });
20888
+ }
20889
+ }, [channel, effectiveTransport]);
20239
20890
  const bridge = useParentBridge({
20240
20891
  trustedOrigins: configuredTrustedParentOrigins
20241
20892
  });
@@ -20262,6 +20913,8 @@ function AthenaProvider({
20262
20913
  token: effectiveToken,
20263
20914
  getToken: configuredGetToken,
20264
20915
  model,
20916
+ agent: agent2,
20917
+ channel,
20265
20918
  tools,
20266
20919
  frontendToolIds: frontendToolNames,
20267
20920
  frontendTools: effectiveFrontendTools,
@@ -36917,7 +37570,7 @@ function requireUseSyncExternalStoreShim_development$1() {
36917
37570
  var useState2 = React$1.useState, useEffect2 = React$1.useEffect, useLayoutEffect3 = React$1.useLayoutEffect, useDebugValue2 = React$1.useDebugValue;
36918
37571
  var didWarnOld18Alpha = false;
36919
37572
  var didWarnUncachedGetSnapshot = false;
36920
- function useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
37573
+ function useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot) {
36921
37574
  {
36922
37575
  if (!didWarnOld18Alpha) {
36923
37576
  if (React$1.startTransition !== void 0) {
@@ -36984,7 +37637,7 @@ function requireUseSyncExternalStoreShim_development$1() {
36984
37637
  }
36985
37638
  var canUseDOM2 = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
36986
37639
  var isServerEnvironment = !canUseDOM2;
36987
- var shim2 = isServerEnvironment ? useSyncExternalStore$1 : useSyncExternalStore;
37640
+ var shim2 = isServerEnvironment ? useSyncExternalStore$1 : useSyncExternalStore2;
36988
37641
  var useSyncExternalStore$2 = React$1.useSyncExternalStore !== void 0 ? React$1.useSyncExternalStore : shim2;
36989
37642
  useSyncExternalStoreShim_development$1.useSyncExternalStore = useSyncExternalStore$2;
36990
37643
  if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") {
@@ -37287,7 +37940,7 @@ function requireWithSelector_development$1() {
37287
37940
  return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y;
37288
37941
  }
37289
37942
  var objectIs = typeof Object.is === "function" ? Object.is : is;
37290
- var useSyncExternalStore = shim2.useSyncExternalStore;
37943
+ var useSyncExternalStore2 = shim2.useSyncExternalStore;
37291
37944
  var useRef2 = React$1.useRef, useEffect2 = React$1.useEffect, useMemo2 = React$1.useMemo, useDebugValue2 = React$1.useDebugValue;
37292
37945
  function useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
37293
37946
  var instRef = useRef2(null);
@@ -37344,7 +37997,7 @@ function requireWithSelector_development$1() {
37344
37997
  };
37345
37998
  return [getSnapshotWithSelector, getServerSnapshotWithSelector];
37346
37999
  }, [getSnapshot, getServerSnapshot, selector, isEqual]), getSelection2 = _useMemo[0], getServerSelection = _useMemo[1];
37347
- var value = useSyncExternalStore(subscribe, getSelection2, getServerSelection);
38000
+ var value = useSyncExternalStore2(subscribe, getSelection2, getServerSelection);
37348
38001
  useEffect2(function() {
37349
38002
  inst.hasValue = true;
37350
38003
  inst.value = value;
@@ -37713,8 +38366,8 @@ function canReceiveRef(Component) {
37713
38366
  }
37714
38367
  function isReact19Plus() {
37715
38368
  try {
37716
- if (version$1) {
37717
- const majorVersion = parseInt(version$1.split(".")[0], 10);
38369
+ if (version$2) {
38370
+ const majorVersion = parseInt(version$2.split(".")[0], 10);
37718
38371
  return majorVersion >= 19;
37719
38372
  }
37720
38373
  } catch {
@@ -54393,7 +55046,7 @@ function requireWithSelector_production() {
54393
55046
  function is(x, y) {
54394
55047
  return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
54395
55048
  }
54396
- var objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore = shim2.useSyncExternalStore, useRef2 = React2.useRef, useEffect2 = React2.useEffect, useMemo2 = React2.useMemo, useDebugValue2 = React2.useDebugValue;
55049
+ var objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore2 = shim2.useSyncExternalStore, useRef2 = React2.useRef, useEffect2 = React2.useEffect, useMemo2 = React2.useMemo, useDebugValue2 = React2.useDebugValue;
54397
55050
  withSelector_production.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
54398
55051
  var instRef = useRef2(null);
54399
55052
  if (null === instRef.current) {
@@ -54434,7 +55087,7 @@ function requireWithSelector_production() {
54434
55087
  },
54435
55088
  [getSnapshot, getServerSnapshot, selector, isEqual]
54436
55089
  );
54437
- var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]);
55090
+ var value = useSyncExternalStore2(subscribe, instRef[0], instRef[1]);
54438
55091
  useEffect2(
54439
55092
  function() {
54440
55093
  inst.hasValue = true;
@@ -54466,7 +55119,7 @@ function requireWithSelector_development() {
54466
55119
  return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
54467
55120
  }
54468
55121
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
54469
- var React2 = React__default, shim2 = requireShim(), objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore = shim2.useSyncExternalStore, useRef2 = React2.useRef, useEffect2 = React2.useEffect, useMemo2 = React2.useMemo, useDebugValue2 = React2.useDebugValue;
55122
+ var React2 = React__default, shim2 = requireShim(), objectIs = "function" === typeof Object.is ? Object.is : is, useSyncExternalStore2 = shim2.useSyncExternalStore, useRef2 = React2.useRef, useEffect2 = React2.useEffect, useMemo2 = React2.useMemo, useDebugValue2 = React2.useDebugValue;
54470
55123
  withSelector_development.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
54471
55124
  var instRef = useRef2(null);
54472
55125
  if (null === instRef.current) {
@@ -54508,7 +55161,7 @@ function requireWithSelector_development() {
54508
55161
  },
54509
55162
  [getSnapshot, getServerSnapshot, selector, isEqual]
54510
55163
  );
54511
- var value = useSyncExternalStore(subscribe, instRef[0], instRef[1]);
55164
+ var value = useSyncExternalStore2(subscribe, instRef[0], instRef[1]);
54512
55165
  useEffect2(
54513
55166
  function() {
54514
55167
  inst.hasValue = true;
@@ -55322,7 +55975,7 @@ const TiptapComposer = ({ tools = [], rootCategories }) => {
55322
55975
  quoteRef.current = quote;
55323
55976
  const isUploadingRef = useRef(isUploading);
55324
55977
  isUploadingRef.current = isUploading;
55325
- const isRunningThread = useAuiState((s) => s.thread.isRunning);
55978
+ const isRunningThread = useAuiState$1((s) => s.thread.isRunning);
55326
55979
  const isThreadRunning = allowsMidRunSend(transport) ? false : isRunningThread;
55327
55980
  const isThreadRunningRef = useRef(isThreadRunning);
55328
55981
  isThreadRunningRef.current = isThreadRunning;
@@ -55573,7 +56226,7 @@ function readInterruptMessage(value) {
55573
56226
  }
55574
56227
  const PENDING_RESUME_GRACE_MS = 15e3;
55575
56228
  const StatewireApprovalCard = () => {
55576
- const extras = useAuiState((s) => s.thread.extras);
56229
+ const extras = useAuiState$1((s) => s.thread.extras);
55577
56230
  if (!hasStatewireThreadExtras(extras)) return null;
55578
56231
  return /* @__PURE__ */ jsx(StatewireApprovalCardInner, {});
55579
56232
  };
@@ -55593,7 +56246,7 @@ const StatewireApprovalCardInner = () => {
55593
56246
  prevRequestIdRef.current = requestId;
55594
56247
  if (pending) setPending(false);
55595
56248
  }
55596
- const isRunning = useAuiState((s) => s.thread.isRunning);
56249
+ const isRunning = useAuiState$1((s) => s.thread.isRunning);
55597
56250
  const sawResumeRunRef = useRef(false);
55598
56251
  useEffect(() => {
55599
56252
  if (!pending) {
@@ -55715,7 +56368,7 @@ function queueItemText(parts) {
55715
56368
  ).join("\n\n");
55716
56369
  }
55717
56370
  const StatewireQueuedMessages = () => {
55718
- const extras = useAuiState((s) => s.thread.extras);
56371
+ const extras = useAuiState$1((s) => s.thread.extras);
55719
56372
  if (!hasStatewireThreadExtras(extras)) return null;
55720
56373
  return /* @__PURE__ */ jsx(StatewireQueuedMessagesInner, {});
55721
56374
  };
@@ -59879,13 +60532,13 @@ const TOOLKIT_THEMES = {
59879
60532
  };
59880
60533
  const DEFAULT_THEME = { color: "#919EAB" };
59881
60534
  const CollapsibleGroup = ({ groupKey, indices, children }) => {
59882
- const isMessageRunning = useAuiState((s) => {
60535
+ const isMessageRunning = useAuiState$1((s) => {
59883
60536
  var _a3;
59884
60537
  return ((_a3 = s.message.status) == null ? void 0 : _a3.type) === "running";
59885
60538
  });
59886
60539
  const [userOpened, setOpen] = useState();
59887
60540
  const open = userOpened ?? isMessageRunning;
59888
- const toolCallCount = useAuiState((s) => {
60541
+ const toolCallCount = useAuiState$1((s) => {
59889
60542
  if (s.message.role !== "assistant") return 0;
59890
60543
  const parts = s.message.content;
59891
60544
  if (!parts) return 0;
@@ -60158,8 +60811,8 @@ function PulsingDots() {
60158
60811
  const SuperGroupingFinalText = memo(function SuperGroupingFinalText2({
60159
60812
  TextComponent
60160
60813
  }) {
60161
- const messageContent = useAuiState((s) => s.message.content);
60162
- const isRunning = useAuiState((s) => {
60814
+ const messageContent = useAuiState$1((s) => s.message.content);
60815
+ const isRunning = useAuiState$1((s) => {
60163
60816
  var _a3;
60164
60817
  return ((_a3 = s.message.status) == null ? void 0 : _a3.type) === "running";
60165
60818
  });
@@ -60189,7 +60842,7 @@ const SuperGroupingCard = memo(function SuperGroupingCard2({
60189
60842
  ReasoningComponent,
60190
60843
  getToolGroupKey = defaultGetToolGroupKey
60191
60844
  }) {
60192
- const messageId = useAuiState((s) => s.message.id);
60845
+ const messageId = useAuiState$1((s) => s.message.id);
60193
60846
  const [showDetails, setShowDetails] = useState(() => expandedMessageIds.has(messageId));
60194
60847
  const handleToggleDetails = useCallback(() => {
60195
60848
  setShowDetails((prev) => {
@@ -60214,7 +60867,7 @@ const SuperGroupingCard = memo(function SuperGroupingCard2({
60214
60867
  expandedMessageIds.delete(messageId);
60215
60868
  };
60216
60869
  }, [messageId, showDetails]);
60217
- const messageStatus = useAuiState((s) => {
60870
+ const messageStatus = useAuiState$1((s) => {
60218
60871
  var _a3;
60219
60872
  return (_a3 = s.message.status) == null ? void 0 : _a3.type;
60220
60873
  });
@@ -60234,7 +60887,7 @@ const SuperGroupingCard = memo(function SuperGroupingCard2({
60234
60887
  })).filter((g) => g.indices.length > 0);
60235
60888
  };
60236
60889
  }, [getToolGroupKey]);
60237
- const messageContent = useAuiState((s) => s.message.content);
60890
+ const messageContent = useAuiState$1((s) => s.message.content);
60238
60891
  const toolStatuses = useMemo(() => {
60239
60892
  if (!messageContent) return EMPTY_STATUSES;
60240
60893
  const statuses = [];
@@ -61113,7 +61766,7 @@ const useScrollToTop = () => {
61113
61766
  };
61114
61767
  const ThreadScrollToTop = () => {
61115
61768
  const { isAtTop, containerRef, handleClick: handleClick2 } = useScrollToTop();
61116
- const isEmpty3 = useAuiState((s) => s.thread.isEmpty);
61769
+ const isEmpty3 = useAuiState$1((s) => s.thread.isEmpty);
61117
61770
  if (isEmpty3) return null;
61118
61771
  return /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 mx-auto flex h-0 w-full max-w-(--thread-max-width) justify-center", children: /* @__PURE__ */ jsx(
61119
61772
  TooltipIconButton,
@@ -61164,7 +61817,7 @@ const ComposerSendWithQuote = () => {
61164
61817
  const { attachments, clearAttachments, isUploading } = useAttachments();
61165
61818
  const editorRef = useComposerEditorRef();
61166
61819
  const editorEmpty = useComposerEditorEmpty();
61167
- const isRunningThread = useAuiState((s) => s.thread.isRunning);
61820
+ const isRunningThread = useAuiState$1((s) => s.thread.isRunning);
61168
61821
  const isThreadRunning = allowsMidRunSend(transport) ? false : isRunningThread;
61169
61822
  const hasExtras = !!quote || attachments.length > 0;
61170
61823
  const handleSend = useCallback(() => {
@@ -61228,8 +61881,8 @@ const AthenaAssistantMessageEmpty = ({ status }) => {
61228
61881
  const AthenaMessageEmptyIndicator = ({
61229
61882
  EmptyComponent: EmptyComponent2
61230
61883
  }) => {
61231
- const hasParts = useAuiState((s) => s.message.parts.length > 0);
61232
- const isRunning = useAuiState((s) => {
61884
+ const hasParts = useAuiState$1((s) => s.message.parts.length > 0);
61885
+ const isRunning = useAuiState$1((s) => {
61233
61886
  var _a3;
61234
61887
  return ((_a3 = s.message.status) == null ? void 0 : _a3.type) === "running";
61235
61888
  });
@@ -61243,11 +61896,11 @@ const AthenaReasoningPart = ({
61243
61896
  }) => {
61244
61897
  const inheritedTextComponent = useContext(AthenaReasoningTextComponentContext);
61245
61898
  const EffectiveTextComponent = TextComponent ?? inheritedTextComponent ?? TiptapText;
61246
- const isMessageRunning = useAuiState((state) => {
61899
+ const isMessageRunning = useAuiState$1((state) => {
61247
61900
  var _a3;
61248
61901
  return ((_a3 = state.message.status) == null ? void 0 : _a3.type) === "running";
61249
61902
  });
61250
- const reasoningTokens = useAuiState(
61903
+ const reasoningTokens = useAuiState$1(
61251
61904
  (state) => getReasoningTokensFromMetadata(state.message.metadata)
61252
61905
  );
61253
61906
  const isRunning = isMessageRunning || (status == null ? void 0 : status.type) === "running";
@@ -62419,6 +63072,8 @@ function useComposerAttachment() {
62419
63072
  return { addFile, addContent, clear };
62420
63073
  }
62421
63074
  export {
63075
+ ATHENA_REACT_SDK_VERSION,
63076
+ ATHENA_SDK_ERROR_CODES,
62422
63077
  ATHENA_TRANSPORTS,
62423
63078
  AppendDocumentToolUI,
62424
63079
  AssetPanel,
@@ -62429,10 +63084,12 @@ export {
62429
63084
  AthenaLayout,
62430
63085
  AthenaProvider,
62431
63086
  AthenaReasoningPart,
63087
+ AthenaSdkError,
62432
63088
  AthenaThreadIdContext,
62433
63089
  AthenaUserMessage,
62434
63090
  BrowseToolUI,
62435
63091
  Button,
63092
+ COLLAB_AGENT_REF_PREFIX,
62436
63093
  Collapsible,
62437
63094
  CollapsibleContent,
62438
63095
  CollapsibleTrigger,
@@ -62492,6 +63149,7 @@ export {
62492
63149
  allowsMidRunSend,
62493
63150
  archiveThread,
62494
63151
  asHitlApproval,
63152
+ athenaDiagnostics,
62495
63153
  athenaStatewireErrorNotice,
62496
63154
  autoCloseInFlightSubgraphMessages,
62497
63155
  buildCoalescedCaptureProperties,
@@ -62515,13 +63173,17 @@ export {
62515
63173
  getPosthogCaptureGate,
62516
63174
  getThreadState,
62517
63175
  hasStatewireThreadExtras,
63176
+ installAthenaDiagnosticsGlobal,
62518
63177
  isAthenaCitationUrl,
63178
+ isAthenaSdkError,
62519
63179
  isCriticalPosthogEvent,
62520
63180
  isPendingInterrupt,
62521
63181
  listThreads,
62522
63182
  normalizeResult,
62523
63183
  parseAthenaCitationLink,
63184
+ parseCollabAgentRef,
62524
63185
  readInterruptMessage,
63186
+ readRejectionDetail,
62525
63187
  resetAssetAutoOpen,
62526
63188
  resolveAthenaTransport,
62527
63189
  resolveStatewireSyncUrl,
@@ -62529,6 +63191,7 @@ export {
62529
63191
  statewireClientToolWireEntries,
62530
63192
  themeToStyleVars,
62531
63193
  themes,
63194
+ toAthenaSdkError,
62532
63195
  truncate,
62533
63196
  tryParseJson$2 as tryParseJson,
62534
63197
  useAppendToComposer,
@@ -62536,6 +63199,7 @@ export {
62536
63199
  useAssetPanelStore,
62537
63200
  useAthenaCitationLinkHandler,
62538
63201
  useAthenaConfig,
63202
+ useAthenaDiagnostics,
62539
63203
  useAthenaLinkClickHandler,
62540
63204
  useAthenaRuntime,
62541
63205
  useAthenaStatewireLifecycle,