@athenaintel/react 0.10.41 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -3
- package/dist/chat/statewire-client-tools.d.ts +14 -7
- package/dist/diagnostics/athena-diagnostics.d.ts +138 -0
- package/dist/diagnostics/errors.d.ts +67 -0
- package/dist/diagnostics/useAthenaDiagnostics.d.ts +13 -0
- package/dist/index.cjs +2008 -1156
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2036 -1184
- package/dist/index.js.map +1 -1
- package/dist/provider/AthenaProvider.d.ts +38 -2
- package/dist/runtime/statewire-run-config.d.ts +16 -1
- package/dist/runtime/useAthenaStatewireRuntime.d.ts +5 -0
- package/dist/tools/tool-uis.d.ts +18 -0
- package/dist/version.d.ts +6 -0
- package/package.json +3 -3
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,
|
|
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,
|
|
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,236 +29,1140 @@ 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,
|
|
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";
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
backendUrl: "https://api.athenaintel.com/api/assistant-ui",
|
|
39
|
-
appUrl: "https://app.athenaintel.com"
|
|
40
|
-
},
|
|
41
|
-
staging: {
|
|
42
|
-
apiUrl: "https://iris.stg.athenaintel.com/api/chat",
|
|
43
|
-
backendUrl: "https://staging-api.athenaintel.com/api/assistant-ui",
|
|
44
|
-
appUrl: "https://staging-app.athenaintel.com"
|
|
45
|
-
}
|
|
36
|
+
const version$1 = "0.11.1";
|
|
37
|
+
const packageJson = {
|
|
38
|
+
version: version$1
|
|
46
39
|
};
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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 }
|
|
62
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));
|
|
63
101
|
}
|
|
64
|
-
function
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}) {
|
|
68
|
-
if (statewireSyncUrl) return statewireSyncUrl;
|
|
69
|
-
const derived = deriveStatewireSyncUrl({ apiUrl });
|
|
70
|
-
if (derived) return derived;
|
|
71
|
-
throw new Error(
|
|
72
|
-
`[AthenaSDK] transport 'statewire' could not derive a sync URL from apiUrl (${JSON.stringify(
|
|
73
|
-
apiUrl ?? null
|
|
74
|
-
)}). Pass an explicit statewireSyncUrl (the …/v2/threads mount). Credentials are never sent to a default host.`
|
|
75
|
-
);
|
|
102
|
+
function shouldBypassCaptureGate(options) {
|
|
103
|
+
if (!options || typeof options !== "object") return false;
|
|
104
|
+
return options[BYPASS_OPTION_KEY] === true;
|
|
76
105
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const getHostname$1 = (value) => {
|
|
88
|
-
if (!value) return null;
|
|
89
|
-
try {
|
|
90
|
-
return new URL(value).hostname;
|
|
91
|
-
} catch {
|
|
92
|
-
return null;
|
|
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();
|
|
93
116
|
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
return `${parsedUrl.protocol}//${match2.groups.prefix}--${MARATHON_APP_PORT}.${match2.groups.domain}`;
|
|
109
|
-
} catch {
|
|
110
|
-
return null;
|
|
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(",")}]`;
|
|
111
130
|
}
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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];
|
|
122
158
|
}
|
|
123
|
-
return `${parsedUrl.protocol}//${match2.groups.prefix}--8787.${match2.groups.domain}/api/chat`;
|
|
124
|
-
} catch {
|
|
125
|
-
return null;
|
|
126
159
|
}
|
|
127
|
-
|
|
128
|
-
function getAthenaEnvironmentUrls({
|
|
129
|
-
environment = DEFAULT_ATHENA_ENVIRONMENT
|
|
130
|
-
} = {}) {
|
|
131
|
-
return ATHENA_ENVIRONMENT_URLS[environment];
|
|
160
|
+
return stableStringify(subset);
|
|
132
161
|
}
|
|
133
|
-
function
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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;
|
|
143
204
|
}
|
|
144
|
-
|
|
145
|
-
|
|
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" };
|
|
146
216
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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);
|
|
153
224
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
sourcePort: "8000"
|
|
167
|
-
});
|
|
168
|
-
if (workspaceAppUrl) return workspaceAppUrl;
|
|
169
|
-
const backendHostname = getHostname$1(backendUrl);
|
|
170
|
-
if (backendHostname === "api.athenaintel.com") {
|
|
171
|
-
return ATHENA_ENVIRONMENT_URLS.production.appUrl;
|
|
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);
|
|
172
237
|
}
|
|
173
|
-
|
|
174
|
-
|
|
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);
|
|
175
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" };
|
|
176
251
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
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
|
+
});
|
|
186
270
|
}
|
|
187
|
-
|
|
188
|
-
|
|
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;
|
|
189
278
|
}
|
|
190
279
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (assetIds) {
|
|
200
|
-
const normalizedAssetIds = (Array.isArray(assetIds) ? assetIds : [assetIds]).map((assetId) => assetId.trim()).filter((assetId) => assetId.length > 0);
|
|
201
|
-
if (normalizedAssetIds.length > 0) {
|
|
202
|
-
url.searchParams.set("asset_ids", normalizedAssetIds.join(","));
|
|
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;
|
|
203
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
|
+
};
|
|
204
300
|
}
|
|
205
|
-
|
|
206
|
-
|
|
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
|
+
}));
|
|
207
312
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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
|
+
});
|
|
218
330
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return false;
|
|
331
|
+
this.coalescedTotal += 1;
|
|
332
|
+
this.activeDedupe.set(event, { fingerprint, bucketKey, at: now });
|
|
333
|
+
return { action: "coalesce", reason, bucketKey };
|
|
223
334
|
}
|
|
224
335
|
}
|
|
225
|
-
const
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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);
|
|
236
356
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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);
|
|
241
375
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
376
|
+
}
|
|
377
|
+
function wrapPosthogClient(client) {
|
|
378
|
+
if (wrappedClient === client) {
|
|
379
|
+
return client;
|
|
245
380
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
+
}
|
|
939
|
+
const ATHENA_ENVIRONMENT_URLS = {
|
|
940
|
+
production: {
|
|
941
|
+
apiUrl: "https://iris.prd.athenaintel.com/api/chat",
|
|
942
|
+
backendUrl: "https://api.athenaintel.com/api/assistant-ui",
|
|
943
|
+
appUrl: "https://app.athenaintel.com"
|
|
944
|
+
},
|
|
945
|
+
staging: {
|
|
946
|
+
apiUrl: "https://iris.stg.athenaintel.com/api/chat",
|
|
947
|
+
backendUrl: "https://staging-api.athenaintel.com/api/assistant-ui",
|
|
948
|
+
appUrl: "https://staging-app.athenaintel.com"
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
const DEFAULT_ATHENA_ENVIRONMENT = "production";
|
|
952
|
+
const DEFAULT_API_URL = ATHENA_ENVIRONMENT_URLS.production.apiUrl;
|
|
953
|
+
const DEFAULT_BACKEND_URL = ATHENA_ENVIRONMENT_URLS.production.backendUrl;
|
|
954
|
+
const DEFAULT_APP_URL = ATHENA_ENVIRONMENT_URLS.production.appUrl;
|
|
955
|
+
const DEFAULT_STATEWIRE_SYNC_URL = "https://iris.prd.athenaintel.com/v2/threads";
|
|
956
|
+
const STATEWIRE_SYNC_PATHNAME = "/v2/threads";
|
|
957
|
+
function deriveStatewireSyncUrl({
|
|
958
|
+
apiUrl
|
|
959
|
+
}) {
|
|
960
|
+
if (!apiUrl) return null;
|
|
961
|
+
try {
|
|
962
|
+
const parsedUrl = new URL(apiUrl);
|
|
963
|
+
return `${parsedUrl.origin}${STATEWIRE_SYNC_PATHNAME}`;
|
|
964
|
+
} catch {
|
|
965
|
+
return null;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
function resolveStatewireSyncUrl({
|
|
969
|
+
statewireSyncUrl,
|
|
970
|
+
apiUrl
|
|
971
|
+
}) {
|
|
972
|
+
if (statewireSyncUrl) return statewireSyncUrl;
|
|
973
|
+
const derived = deriveStatewireSyncUrl({ apiUrl });
|
|
974
|
+
if (derived) return derived;
|
|
975
|
+
throw new Error(
|
|
976
|
+
`[AthenaSDK] transport 'statewire' could not derive a sync URL from apiUrl (${JSON.stringify(
|
|
977
|
+
apiUrl ?? null
|
|
978
|
+
)}). Pass an explicit statewireSyncUrl (the …/v2/threads mount). Credentials are never sent to a default host.`
|
|
979
|
+
);
|
|
980
|
+
}
|
|
981
|
+
const MARATHON_APP_PORT = "8082";
|
|
982
|
+
const SPACES_PATHNAME = "dashboard/spaces/";
|
|
983
|
+
const normalizeBaseUrl = (url) => url.replace(/\/+$/, "");
|
|
984
|
+
const createUrlWithFallback = (url, fallbackUrl) => {
|
|
985
|
+
try {
|
|
986
|
+
return new URL(`${normalizeBaseUrl(url)}/`);
|
|
987
|
+
} catch {
|
|
988
|
+
return new URL(`${normalizeBaseUrl(fallbackUrl)}/`);
|
|
989
|
+
}
|
|
990
|
+
};
|
|
991
|
+
const getHostname$1 = (value) => {
|
|
992
|
+
if (!value) return null;
|
|
993
|
+
try {
|
|
994
|
+
return new URL(value).hostname;
|
|
995
|
+
} catch {
|
|
996
|
+
return null;
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
const deriveWorkspaceAppUrl = ({
|
|
1000
|
+
sourceUrl,
|
|
1001
|
+
sourcePort
|
|
1002
|
+
}) => {
|
|
1003
|
+
var _a3;
|
|
1004
|
+
try {
|
|
1005
|
+
const parsedUrl = new URL(sourceUrl);
|
|
1006
|
+
const match2 = parsedUrl.hostname.match(
|
|
1007
|
+
new RegExp(`^(?<prefix>.+)--${sourcePort}\\.(?<domain>app\\.athenaintel\\.com|staging-app\\.athenaintel\\.com)$`)
|
|
1008
|
+
);
|
|
1009
|
+
if (!((_a3 = match2 == null ? void 0 : match2.groups) == null ? void 0 : _a3.prefix) || !match2.groups.domain) {
|
|
1010
|
+
return null;
|
|
1011
|
+
}
|
|
1012
|
+
return `${parsedUrl.protocol}//${match2.groups.prefix}--${MARATHON_APP_PORT}.${match2.groups.domain}`;
|
|
1013
|
+
} catch {
|
|
1014
|
+
return null;
|
|
1015
|
+
}
|
|
1016
|
+
};
|
|
1017
|
+
const deriveWorkspaceApiUrl = (backendUrl) => {
|
|
1018
|
+
var _a3;
|
|
1019
|
+
try {
|
|
1020
|
+
const parsedUrl = new URL(backendUrl);
|
|
1021
|
+
const match2 = parsedUrl.hostname.match(
|
|
1022
|
+
/^(?<prefix>.+)--8000\.(?<domain>app\.athenaintel\.com|staging-app\.athenaintel\.com)$/
|
|
1023
|
+
);
|
|
1024
|
+
if (!((_a3 = match2 == null ? void 0 : match2.groups) == null ? void 0 : _a3.prefix) || !match2.groups.domain) {
|
|
1025
|
+
return null;
|
|
1026
|
+
}
|
|
1027
|
+
return `${parsedUrl.protocol}//${match2.groups.prefix}--8787.${match2.groups.domain}/api/chat`;
|
|
1028
|
+
} catch {
|
|
1029
|
+
return null;
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
function getAthenaEnvironmentUrls({
|
|
1033
|
+
environment = DEFAULT_ATHENA_ENVIRONMENT
|
|
1034
|
+
} = {}) {
|
|
1035
|
+
return ATHENA_ENVIRONMENT_URLS[environment];
|
|
1036
|
+
}
|
|
1037
|
+
function deriveAthenaApiUrl({
|
|
1038
|
+
backendUrl
|
|
1039
|
+
}) {
|
|
1040
|
+
if (!backendUrl) return null;
|
|
1041
|
+
const workspaceApiUrl = deriveWorkspaceApiUrl(backendUrl);
|
|
1042
|
+
if (workspaceApiUrl) return workspaceApiUrl;
|
|
1043
|
+
try {
|
|
1044
|
+
const parsedUrl = new URL(backendUrl);
|
|
1045
|
+
if (parsedUrl.hostname === "api.athenaintel.com") {
|
|
1046
|
+
return ATHENA_ENVIRONMENT_URLS.production.apiUrl;
|
|
1047
|
+
}
|
|
1048
|
+
if (parsedUrl.hostname === "staging-api.athenaintel.com") {
|
|
1049
|
+
return ATHENA_ENVIRONMENT_URLS.staging.apiUrl;
|
|
1050
|
+
}
|
|
1051
|
+
if (parsedUrl.hostname === "localhost" || parsedUrl.hostname === "127.0.0.1") {
|
|
1052
|
+
parsedUrl.port = "8787";
|
|
1053
|
+
parsedUrl.pathname = "/api/chat";
|
|
1054
|
+
parsedUrl.search = "";
|
|
1055
|
+
parsedUrl.hash = "";
|
|
1056
|
+
return parsedUrl.toString();
|
|
1057
|
+
}
|
|
1058
|
+
} catch {
|
|
1059
|
+
return null;
|
|
1060
|
+
}
|
|
1061
|
+
return null;
|
|
1062
|
+
}
|
|
1063
|
+
function deriveAthenaAppUrl({
|
|
1064
|
+
apiUrl,
|
|
1065
|
+
backendUrl
|
|
1066
|
+
}) {
|
|
1067
|
+
if (backendUrl) {
|
|
1068
|
+
const workspaceAppUrl = deriveWorkspaceAppUrl({
|
|
1069
|
+
sourceUrl: backendUrl,
|
|
1070
|
+
sourcePort: "8000"
|
|
1071
|
+
});
|
|
1072
|
+
if (workspaceAppUrl) return workspaceAppUrl;
|
|
1073
|
+
const backendHostname = getHostname$1(backendUrl);
|
|
1074
|
+
if (backendHostname === "api.athenaintel.com") {
|
|
1075
|
+
return ATHENA_ENVIRONMENT_URLS.production.appUrl;
|
|
1076
|
+
}
|
|
1077
|
+
if (backendHostname === "staging-api.athenaintel.com") {
|
|
1078
|
+
return ATHENA_ENVIRONMENT_URLS.staging.appUrl;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
if (apiUrl) {
|
|
1082
|
+
const workspaceAppUrl = deriveWorkspaceAppUrl({
|
|
1083
|
+
sourceUrl: apiUrl,
|
|
1084
|
+
sourcePort: "8787"
|
|
1085
|
+
});
|
|
1086
|
+
if (workspaceAppUrl) return workspaceAppUrl;
|
|
1087
|
+
const apiHostname = getHostname$1(apiUrl);
|
|
1088
|
+
if (apiHostname === "sync.athenaintel.com" || apiHostname === "iris.prd.athenaintel.com") {
|
|
1089
|
+
return ATHENA_ENVIRONMENT_URLS.production.appUrl;
|
|
1090
|
+
}
|
|
1091
|
+
if (apiHostname === "staging-sync.athenaintel.com" || apiHostname === "iris.stg.athenaintel.com") {
|
|
1092
|
+
return ATHENA_ENVIRONMENT_URLS.staging.appUrl;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
return null;
|
|
1096
|
+
}
|
|
1097
|
+
function createAthenaSpacesUrl({
|
|
1098
|
+
appUrl = DEFAULT_APP_URL,
|
|
1099
|
+
assetIds,
|
|
1100
|
+
sessionId
|
|
1101
|
+
}) {
|
|
1102
|
+
const url = new URL(SPACES_PATHNAME, createUrlWithFallback(appUrl, DEFAULT_APP_URL));
|
|
1103
|
+
if (assetIds) {
|
|
1104
|
+
const normalizedAssetIds = (Array.isArray(assetIds) ? assetIds : [assetIds]).map((assetId) => assetId.trim()).filter((assetId) => assetId.length > 0);
|
|
1105
|
+
if (normalizedAssetIds.length > 0) {
|
|
1106
|
+
url.searchParams.set("asset_ids", normalizedAssetIds.join(","));
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
if (sessionId) {
|
|
1110
|
+
url.searchParams.set("session_id", sessionId);
|
|
1111
|
+
}
|
|
1112
|
+
return url.toString();
|
|
1113
|
+
}
|
|
1114
|
+
function isTrustedOrigin({
|
|
1115
|
+
origin,
|
|
1116
|
+
trustedOrigins
|
|
1117
|
+
}) {
|
|
1118
|
+
try {
|
|
1119
|
+
const normalizedOrigin = new URL(origin).origin;
|
|
1120
|
+
if (trustedOrigins.includes(normalizedOrigin)) {
|
|
1121
|
+
return true;
|
|
1122
|
+
}
|
|
1123
|
+
const { hostname } = new URL(normalizedOrigin);
|
|
1124
|
+
return hostname === "athenaintel.com" || hostname.endsWith(".athenaintel.com") || hostname === "localhost";
|
|
1125
|
+
} catch {
|
|
1126
|
+
return false;
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
const BRIDGE_TIMEOUT_MS = 2e3;
|
|
1130
|
+
const TOKEN_REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
1131
|
+
const TOKEN_REFRESH_RETRY_BASE_MS = 60 * 1e3;
|
|
1132
|
+
const TOKEN_REFRESH_RETRY_MAX_MS = 5 * 60 * 1e3;
|
|
1133
|
+
const DEFAULT_TOKEN_REFRESH_MS = 55 * 60 * 1e3;
|
|
1134
|
+
const EMPTY_TRUSTED_ORIGINS = [];
|
|
1135
|
+
const normalizeOrigin = (value) => {
|
|
1136
|
+
try {
|
|
1137
|
+
return new URL(value).origin;
|
|
1138
|
+
} catch {
|
|
1139
|
+
return null;
|
|
1140
|
+
}
|
|
1141
|
+
};
|
|
1142
|
+
const getTokenRefreshDelay = (expiresAt, nowMs2) => {
|
|
1143
|
+
if (typeof expiresAt !== "string") {
|
|
1144
|
+
return DEFAULT_TOKEN_REFRESH_MS;
|
|
1145
|
+
}
|
|
1146
|
+
const expiresAtMs = Date.parse(expiresAt);
|
|
1147
|
+
if (!Number.isFinite(expiresAtMs)) {
|
|
1148
|
+
return DEFAULT_TOKEN_REFRESH_MS;
|
|
1149
|
+
}
|
|
1150
|
+
return Math.max(TOKEN_REFRESH_RETRY_BASE_MS, expiresAtMs - nowMs2 - TOKEN_REFRESH_BUFFER_MS);
|
|
1151
|
+
};
|
|
1152
|
+
const getAuthRetryDelay = (retryAttempt) => {
|
|
1153
|
+
const safeAttempt = Number.isFinite(retryAttempt) ? Math.max(0, Math.floor(retryAttempt)) : 0;
|
|
1154
|
+
return Math.min(TOKEN_REFRESH_RETRY_MAX_MS, TOKEN_REFRESH_RETRY_BASE_MS * 2 ** safeAttempt);
|
|
1155
|
+
};
|
|
1156
|
+
function useParentBridge({
|
|
1157
|
+
trustedOrigins = EMPTY_TRUSTED_ORIGINS
|
|
1158
|
+
} = {}) {
|
|
1159
|
+
const isInIframe = typeof window !== "undefined" && window.parent !== window;
|
|
1160
|
+
const runtimeTrustedOrigins = useMemo(() => {
|
|
1161
|
+
const origins = /* @__PURE__ */ new Set();
|
|
1162
|
+
if (typeof window !== "undefined") {
|
|
1163
|
+
origins.add(window.location.origin);
|
|
1164
|
+
}
|
|
1165
|
+
for (const trustedOrigin of trustedOrigins) {
|
|
262
1166
|
const normalizedOrigin = normalizeOrigin(trustedOrigin);
|
|
263
1167
|
if (normalizedOrigin) {
|
|
264
1168
|
origins.add(normalizedOrigin);
|
|
@@ -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
|
|
9846
|
-
|
|
9847
|
-
|
|
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
|
-
|
|
9859
|
-
|
|
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
|
-
|
|
9926
|
-
threadId,
|
|
9927
|
-
|
|
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
|
-
|
|
9943
|
-
|
|
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
|
|
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
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
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 = ((
|
|
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) =>
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
|
|
10777
|
-
|
|
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
|
|
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;
|
|
@@ -10999,6 +12031,9 @@ function useDeepAgentThread({
|
|
|
10999
12031
|
return statewireTransport(
|
|
11000
12032
|
{
|
|
11001
12033
|
url: `${baseUrl.replace(/\/+$/, "")}/${encodeURIComponent(threadId)}`,
|
|
12034
|
+
// A never-started chat has no server session yet: the transport
|
|
12035
|
+
// makes no network calls until the first command send.
|
|
12036
|
+
...preloadRef.current.preload && { isNew: true },
|
|
11002
12037
|
headers: (ctx) => headersRef.current(ctx),
|
|
11003
12038
|
...sessionStore && { sessionStore }
|
|
11004
12039
|
},
|
|
@@ -11035,7 +12070,7 @@ function useDeepAgentThread({
|
|
|
11035
12070
|
}
|
|
11036
12071
|
const connection = projectDeepAgentConnection(meta.connection);
|
|
11037
12072
|
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) {
|
|
12073
|
+
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
12074
|
const update = { threadId: attachId, connection };
|
|
11040
12075
|
lastConnectionRef.current = update;
|
|
11041
12076
|
queueMicrotask(() => {
|
|
@@ -11107,46 +12142,30 @@ function toJSONSchema(schema2) {
|
|
|
11107
12142
|
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
12143
|
return schema2;
|
|
11109
12144
|
}
|
|
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
12145
|
function hasCallableExecute(entry) {
|
|
11127
12146
|
return !!entry && typeof entry === "object" && typeof entry.execute === "function";
|
|
11128
12147
|
}
|
|
11129
12148
|
function collectStatewireClientTools(toolkit) {
|
|
11130
12149
|
const executable = Object.entries(toolkit).filter(([, entry]) => hasCallableExecute(entry));
|
|
11131
12150
|
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
12151
|
return executable.flatMap(([name, entry]) => {
|
|
11142
|
-
|
|
11143
|
-
|
|
12152
|
+
if (entry.parameters === void 0) return [];
|
|
12153
|
+
let parameters;
|
|
12154
|
+
try {
|
|
12155
|
+
parameters = toJSONSchema(entry.parameters);
|
|
12156
|
+
} catch (error2) {
|
|
12157
|
+
console.warn(
|
|
12158
|
+
`[AthenaSDK] failed to convert frontend tool schema for statewire (${name}):`,
|
|
12159
|
+
error2
|
|
12160
|
+
);
|
|
12161
|
+
return [];
|
|
12162
|
+
}
|
|
11144
12163
|
const execute = entry.execute;
|
|
11145
12164
|
return [
|
|
11146
12165
|
{
|
|
11147
12166
|
name,
|
|
11148
|
-
description:
|
|
11149
|
-
parameters
|
|
12167
|
+
description: entry.description,
|
|
12168
|
+
parameters,
|
|
11150
12169
|
handler: async (args, { toolCallId }) => {
|
|
11151
12170
|
const controller = new AbortController();
|
|
11152
12171
|
const output = await execute(args, {
|
|
@@ -11170,39 +12189,6 @@ function statewireClientToolWireEntries(tools) {
|
|
|
11170
12189
|
requires_write: false
|
|
11171
12190
|
}));
|
|
11172
12191
|
}
|
|
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
12192
|
const EMPTY_TOOLKIT = {};
|
|
11207
12193
|
const EMPTY_TOOL_IDS = [];
|
|
11208
12194
|
function useStatewireClientTools(frontendToolkit) {
|
|
@@ -11220,6 +12206,8 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
11220
12206
|
token,
|
|
11221
12207
|
getToken,
|
|
11222
12208
|
model,
|
|
12209
|
+
agent: agent2,
|
|
12210
|
+
channel,
|
|
11223
12211
|
tools = EMPTY_TOOL_IDS,
|
|
11224
12212
|
frontendToolIds = EMPTY_TOOL_IDS,
|
|
11225
12213
|
frontendToolkit = EMPTY_TOOLKIT,
|
|
@@ -11247,6 +12235,28 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
11247
12235
|
const clientToolsRef = useRef(clientTools);
|
|
11248
12236
|
clientToolsRef.current = clientTools;
|
|
11249
12237
|
const [canPersistSession] = useState(() => typeof localStorage !== "undefined");
|
|
12238
|
+
useEffect(() => {
|
|
12239
|
+
if (agent2 && !parseCollabAgentRef(agent2)) {
|
|
12240
|
+
athenaDiagnostics.emit("sdk.config.warning", {
|
|
12241
|
+
level: "warn",
|
|
12242
|
+
data: {
|
|
12243
|
+
prop: "agent",
|
|
12244
|
+
value: agent2,
|
|
12245
|
+
reason: "the statewire transport always runs the Athena deep agent; only 'collab_agent:<asset_id>' refs apply. Use transport='legacy' for named agents."
|
|
12246
|
+
}
|
|
12247
|
+
});
|
|
12248
|
+
}
|
|
12249
|
+
}, [agent2]);
|
|
12250
|
+
const attachSpanRef = useRef(null);
|
|
12251
|
+
const attachThreadRef = useRef(null);
|
|
12252
|
+
if (attachThreadRef.current !== threadId) {
|
|
12253
|
+
attachThreadRef.current = threadId;
|
|
12254
|
+
attachSpanRef.current = athenaDiagnostics.span(
|
|
12255
|
+
`statewire.attach:${threadId}`,
|
|
12256
|
+
"statewire.attach.start",
|
|
12257
|
+
{ thread_id: threadId, is_new_chat: isNewChat }
|
|
12258
|
+
);
|
|
12259
|
+
}
|
|
11250
12260
|
const thread = useDeepAgentThread({
|
|
11251
12261
|
threadId,
|
|
11252
12262
|
baseUrl: syncUrl,
|
|
@@ -11276,11 +12286,47 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
11276
12286
|
}
|
|
11277
12287
|
},
|
|
11278
12288
|
capabilities: { edit: true, reload: true, continue: true },
|
|
11279
|
-
|
|
12289
|
+
onStateChange: () => {
|
|
12290
|
+
const endSpan = attachSpanRef.current;
|
|
12291
|
+
if (endSpan) {
|
|
12292
|
+
attachSpanRef.current = null;
|
|
12293
|
+
endSpan("statewire.snapshot", { data: { thread_id: threadId } });
|
|
12294
|
+
}
|
|
12295
|
+
},
|
|
12296
|
+
onConnectionChange: (connection) => {
|
|
12297
|
+
athenaDiagnostics.gauge("statewire.connection", (connection == null ? void 0 : connection.status) ?? null);
|
|
12298
|
+
if ((connection == null ? void 0 : connection.status) === "gone") {
|
|
12299
|
+
athenaDiagnostics.emit("statewire.connection", {
|
|
12300
|
+
level: "warn",
|
|
12301
|
+
data: { status: connection.status, message: connection.message }
|
|
12302
|
+
});
|
|
12303
|
+
}
|
|
12304
|
+
onConnectionChange == null ? void 0 : onConnectionChange(connection);
|
|
12305
|
+
},
|
|
11280
12306
|
onRawConnectionChange,
|
|
11281
|
-
onLegacyReadOnly
|
|
12307
|
+
onLegacyReadOnly: (legacyReadOnly) => {
|
|
12308
|
+
if (legacyReadOnly) {
|
|
12309
|
+
athenaDiagnostics.emit("statewire.read_only", {
|
|
12310
|
+
level: "warn",
|
|
12311
|
+
data: { thread_id: threadId }
|
|
12312
|
+
});
|
|
12313
|
+
}
|
|
12314
|
+
onLegacyReadOnly == null ? void 0 : onLegacyReadOnly(legacyReadOnly);
|
|
12315
|
+
},
|
|
11282
12316
|
onRunningChange,
|
|
11283
12317
|
onError: (error2) => {
|
|
12318
|
+
if (!isStatewireChannelTeardown(error2)) {
|
|
12319
|
+
athenaDiagnostics.error(
|
|
12320
|
+
"statewire.error",
|
|
12321
|
+
error2,
|
|
12322
|
+
{
|
|
12323
|
+
code: "statewire_rejected",
|
|
12324
|
+
message: "The statewire host rejected a command",
|
|
12325
|
+
hint: "Inspect error.detail — agora rejections carry a structured {code, message}."
|
|
12326
|
+
},
|
|
12327
|
+
{ thread_id: threadId }
|
|
12328
|
+
);
|
|
12329
|
+
}
|
|
11284
12330
|
if (onErrorRef.current) {
|
|
11285
12331
|
onErrorRef.current(error2);
|
|
11286
12332
|
return;
|
|
@@ -11296,6 +12342,8 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
11296
12342
|
const aui = useAui({ thread, tools: auiTools });
|
|
11297
12343
|
const runConfigInputsRef = useRef({
|
|
11298
12344
|
model,
|
|
12345
|
+
agent: agent2,
|
|
12346
|
+
channel,
|
|
11299
12347
|
tools,
|
|
11300
12348
|
frontendToolIds,
|
|
11301
12349
|
workbench,
|
|
@@ -11307,6 +12355,8 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
11307
12355
|
});
|
|
11308
12356
|
runConfigInputsRef.current = {
|
|
11309
12357
|
model,
|
|
12358
|
+
agent: agent2,
|
|
12359
|
+
channel,
|
|
11310
12360
|
tools,
|
|
11311
12361
|
frontendToolIds,
|
|
11312
12362
|
workbench,
|
|
@@ -16069,7 +17119,7 @@ function selectThreadListItemRemoteId(state) {
|
|
|
16069
17119
|
return (_a3 = state.threadListItem) == null ? void 0 : _a3.remoteId;
|
|
16070
17120
|
}
|
|
16071
17121
|
function useAthenaAuiThreadRemoteId() {
|
|
16072
|
-
return useAuiState(selectThreadListItemRemoteId);
|
|
17122
|
+
return useAuiState$1(selectThreadListItemRemoteId);
|
|
16073
17123
|
}
|
|
16074
17124
|
function useAthenaThreadId() {
|
|
16075
17125
|
return useContext(AthenaThreadIdContext);
|
|
@@ -18892,7 +19942,7 @@ const TITLE_POLL_MAX_DURATION_MS = 6e4;
|
|
|
18892
19942
|
function StatewireThreadTitlePoller() {
|
|
18893
19943
|
var _a3;
|
|
18894
19944
|
const list2 = useAthenaStatewireThreadList();
|
|
18895
|
-
const hasMessages = useAuiState((s) => {
|
|
19945
|
+
const hasMessages = useAuiState$1((s) => {
|
|
18896
19946
|
var _a4;
|
|
18897
19947
|
return (((_a4 = s.optional.thread) == null ? void 0 : _a4.messages.length) ?? 0) > 0;
|
|
18898
19948
|
});
|
|
@@ -18947,15 +19997,15 @@ function useActiveThreadStateHydration({
|
|
|
18947
19997
|
}) {
|
|
18948
19998
|
const aui = useAui();
|
|
18949
19999
|
const hasThread = aui.thread.source !== null;
|
|
18950
|
-
const threadId = useAuiState((s) => {
|
|
20000
|
+
const threadId = useAuiState$1((s) => {
|
|
18951
20001
|
const item = s.optional.threadListItem;
|
|
18952
20002
|
return item ? selectHydratableThreadId(item) : null;
|
|
18953
20003
|
});
|
|
18954
|
-
const messageCount = useAuiState((s) => {
|
|
20004
|
+
const messageCount = useAuiState$1((s) => {
|
|
18955
20005
|
var _a3;
|
|
18956
20006
|
return ((_a3 = s.optional.thread) == null ? void 0 : _a3.messages.length) ?? 0;
|
|
18957
20007
|
});
|
|
18958
|
-
const isRunning = useAuiState((s) => {
|
|
20008
|
+
const isRunning = useAuiState$1((s) => {
|
|
18959
20009
|
var _a3;
|
|
18960
20010
|
return ((_a3 = s.optional.thread) == null ? void 0 : _a3.isRunning) ?? false;
|
|
18961
20011
|
});
|
|
@@ -18967,786 +20017,340 @@ function useActiveThreadStateHydration({
|
|
|
18967
20017
|
return;
|
|
18968
20018
|
}
|
|
18969
20019
|
if (!token && !apiKey) {
|
|
18970
|
-
return;
|
|
18971
|
-
}
|
|
18972
|
-
const hydrationKey = createHydrationKey({
|
|
18973
|
-
backendUrl,
|
|
18974
|
-
threadId,
|
|
18975
|
-
apiKey,
|
|
18976
|
-
token
|
|
18977
|
-
});
|
|
18978
|
-
if (hydratedKeysRef.current.has(hydrationKey)) {
|
|
18979
|
-
return;
|
|
18980
|
-
}
|
|
18981
|
-
let cancelled = false;
|
|
18982
|
-
(async () => {
|
|
18983
|
-
var _a3, _b2;
|
|
18984
|
-
try {
|
|
18985
|
-
const state = await getThreadState(backendUrl, { apiKey, token }, threadId);
|
|
18986
|
-
if (cancelled || activeThreadIdRef.current !== threadId) {
|
|
18987
|
-
return;
|
|
18988
|
-
}
|
|
18989
|
-
if (aui.thread.getState().messages.length > 0) {
|
|
18990
|
-
return;
|
|
18991
|
-
}
|
|
18992
|
-
(_b2 = (_a3 = aui.thread).importExternalState) == null ? void 0 : _b2.call(_a3, state);
|
|
18993
|
-
hydratedKeysRef.current.add(hydrationKey);
|
|
18994
|
-
} catch (error2) {
|
|
18995
|
-
console.warn("[AthenaSDK] Failed to hydrate active thread state:", error2);
|
|
18996
|
-
}
|
|
18997
|
-
})();
|
|
18998
|
-
return () => {
|
|
18999
|
-
cancelled = true;
|
|
19000
|
-
};
|
|
19001
|
-
}, [apiKey, aui, backendUrl, hasThread, isRunning, messageCount, threadId, token]);
|
|
19002
|
-
}
|
|
19003
|
-
const LOCAL_ID_PREFIX = "__LOCALID_";
|
|
19004
|
-
const isLocalPlaceholder = (id) => !!id && id.startsWith(LOCAL_ID_PREFIX);
|
|
19005
|
-
const selectActiveThreadRemoteId = (state) => {
|
|
19006
|
-
const { mainThreadId, threadItems } = state;
|
|
19007
|
-
if (!mainThreadId) {
|
|
19008
|
-
return null;
|
|
19009
|
-
}
|
|
19010
|
-
const item = threadItems.find((t) => t.id === mainThreadId);
|
|
19011
|
-
const remoteId = item ? item.remoteId ?? null : mainThreadId;
|
|
19012
|
-
return isLocalPlaceholder(remoteId) ? null : remoteId;
|
|
19013
|
-
};
|
|
19014
|
-
function useAthenaThreadManager() {
|
|
19015
|
-
const statewireList = useAthenaStatewireThreadList();
|
|
19016
|
-
const statewireIsThreadLoading = useAuiState((s) => {
|
|
19017
|
-
var _a3;
|
|
19018
|
-
return ((_a3 = s.optional.thread) == null ? void 0 : _a3.isLoading) ?? false;
|
|
19019
|
-
});
|
|
19020
|
-
const statewireManager = useMemo(() => {
|
|
19021
|
-
if (!statewireList) return null;
|
|
19022
|
-
return {
|
|
19023
|
-
activeThreadId: statewireList.isNewChat ? null : statewireList.activeThreadId,
|
|
19024
|
-
isListLoading: statewireList.isLoading,
|
|
19025
|
-
isThreadLoading: statewireIsThreadLoading,
|
|
19026
|
-
switchToThread: async (threadId) => statewireList.selectThread(threadId),
|
|
19027
|
-
switchToNewThread: async () => statewireList.newThread()
|
|
19028
|
-
};
|
|
19029
|
-
}, [statewireList, statewireIsThreadLoading]);
|
|
19030
|
-
const aui = useAui();
|
|
19031
|
-
const hasThreads = aui.threads.source !== null;
|
|
19032
|
-
const activeThreadId = useAuiState((s) => {
|
|
19033
|
-
const threads = s.optional.threads;
|
|
19034
|
-
return threads ? selectActiveThreadRemoteId(threads) : null;
|
|
19035
|
-
});
|
|
19036
|
-
const isThreadLoading = useAuiState((s) => {
|
|
19037
|
-
var _a3;
|
|
19038
|
-
return ((_a3 = s.optional.thread) == null ? void 0 : _a3.isLoading) ?? false;
|
|
19039
|
-
});
|
|
19040
|
-
const isListLoading = useAuiState((s) => {
|
|
19041
|
-
var _a3;
|
|
19042
|
-
return (_a3 = s.optional.threads) == null ? void 0 : _a3.isLoading;
|
|
19043
|
-
});
|
|
19044
|
-
const auiRef = useRef(aui);
|
|
19045
|
-
auiRef.current = aui;
|
|
19046
|
-
const switchToThread = useCallback(
|
|
19047
|
-
async (id) => auiRef.current.threads.switchToThread(id),
|
|
19048
|
-
[]
|
|
19049
|
-
);
|
|
19050
|
-
const switchToNewThread = useCallback(
|
|
19051
|
-
async () => auiRef.current.threads.switchToNewThread(),
|
|
19052
|
-
[]
|
|
19053
|
-
);
|
|
19054
|
-
const legacyManager = useMemo(() => {
|
|
19055
|
-
if (!hasThreads || isListLoading == null) {
|
|
19056
|
-
return null;
|
|
19057
|
-
}
|
|
19058
|
-
return {
|
|
19059
|
-
activeThreadId,
|
|
19060
|
-
isListLoading,
|
|
19061
|
-
isThreadLoading,
|
|
19062
|
-
switchToThread,
|
|
19063
|
-
switchToNewThread
|
|
19064
|
-
};
|
|
19065
|
-
}, [hasThreads, activeThreadId, isListLoading, isThreadLoading, switchToThread, switchToNewThread]);
|
|
19066
|
-
return statewireManager ?? legacyManager;
|
|
19067
|
-
}
|
|
19068
|
-
const POLL_DELAY_MS = 5e3;
|
|
19069
|
-
const POLL_INTERVAL_MS = 1e3;
|
|
19070
|
-
const POLL_MAX_DURATION_MS = 6e4;
|
|
19071
|
-
function useThreadTitlePolling(refresh) {
|
|
19072
|
-
const threadKey = useAuiState(
|
|
19073
|
-
(s) => {
|
|
19074
|
-
var _a3, _b2;
|
|
19075
|
-
return ((_a3 = s.optional.threadListItem) == null ? void 0 : _a3.remoteId) ?? ((_b2 = s.optional.threadListItem) == null ? void 0 : _b2.id) ?? null;
|
|
19076
|
-
}
|
|
19077
|
-
);
|
|
19078
|
-
const hasMessages = useAuiState((s) => {
|
|
19079
|
-
var _a3;
|
|
19080
|
-
return (((_a3 = s.optional.thread) == null ? void 0 : _a3.messages.length) ?? 0) > 0;
|
|
19081
|
-
});
|
|
19082
|
-
const currentTitle = useAuiState((s) => {
|
|
19083
|
-
var _a3;
|
|
19084
|
-
return ((_a3 = s.optional.threadListItem) == null ? void 0 : _a3.title) ?? "";
|
|
19085
|
-
});
|
|
19086
|
-
const trimmedTitle = currentTitle.trim();
|
|
19087
|
-
const hasTitle = trimmedTitle.length > 0 && !isSerializedContentPartsTitle(trimmedTitle);
|
|
19088
|
-
const polledThreadsRef = useRef(/* @__PURE__ */ new Set());
|
|
19089
|
-
const refreshRef = useRef(refresh);
|
|
19090
|
-
refreshRef.current = refresh;
|
|
19091
|
-
useEffect(() => {
|
|
19092
|
-
if (!threadKey || hasTitle || !hasMessages) {
|
|
19093
|
-
return;
|
|
19094
|
-
}
|
|
19095
|
-
if (polledThreadsRef.current.has(threadKey)) {
|
|
19096
|
-
return;
|
|
19097
|
-
}
|
|
19098
|
-
polledThreadsRef.current.add(threadKey);
|
|
19099
|
-
let stopped = false;
|
|
19100
|
-
let intervalId = null;
|
|
19101
|
-
let maxTimeoutId = null;
|
|
19102
|
-
const stop = () => {
|
|
19103
|
-
stopped = true;
|
|
19104
|
-
if (intervalId !== null) {
|
|
19105
|
-
clearInterval(intervalId);
|
|
19106
|
-
intervalId = null;
|
|
19107
|
-
}
|
|
19108
|
-
if (maxTimeoutId !== null) {
|
|
19109
|
-
clearTimeout(maxTimeoutId);
|
|
19110
|
-
maxTimeoutId = null;
|
|
19111
|
-
}
|
|
19112
|
-
};
|
|
19113
|
-
const startTimeoutId = setTimeout(() => {
|
|
19114
|
-
if (stopped) return;
|
|
19115
|
-
refreshRef.current();
|
|
19116
|
-
intervalId = setInterval(() => {
|
|
19117
|
-
refreshRef.current();
|
|
19118
|
-
}, POLL_INTERVAL_MS);
|
|
19119
|
-
maxTimeoutId = setTimeout(stop, POLL_MAX_DURATION_MS - POLL_DELAY_MS);
|
|
19120
|
-
}, POLL_DELAY_MS);
|
|
19121
|
-
return () => {
|
|
19122
|
-
clearTimeout(startTimeoutId);
|
|
19123
|
-
stop();
|
|
19124
|
-
};
|
|
19125
|
-
}, [threadKey, hasTitle, hasMessages]);
|
|
19126
|
-
}
|
|
19127
|
-
const THEME_TO_CSS = {
|
|
19128
|
-
primary: "--primary",
|
|
19129
|
-
primaryForeground: "--primary-foreground",
|
|
19130
|
-
background: "--background",
|
|
19131
|
-
foreground: "--foreground",
|
|
19132
|
-
muted: "--muted",
|
|
19133
|
-
mutedForeground: "--muted-foreground",
|
|
19134
|
-
accent: "--accent",
|
|
19135
|
-
accentForeground: "--accent-foreground",
|
|
19136
|
-
secondary: "--secondary",
|
|
19137
|
-
secondaryForeground: "--secondary-foreground",
|
|
19138
|
-
card: "--card",
|
|
19139
|
-
cardForeground: "--card-foreground",
|
|
19140
|
-
popover: "--popover",
|
|
19141
|
-
popoverForeground: "--popover-foreground",
|
|
19142
|
-
destructive: "--destructive",
|
|
19143
|
-
border: "--border",
|
|
19144
|
-
input: "--input",
|
|
19145
|
-
ring: "--ring",
|
|
19146
|
-
radius: "--radius",
|
|
19147
|
-
fontFamily: "--font-family",
|
|
19148
|
-
// Extended SDK-specific variables
|
|
19149
|
-
sidebarBackground: "--sidebar-background",
|
|
19150
|
-
sidebarBorder: "--sidebar-border",
|
|
19151
|
-
sidebarWidth: "--sidebar-width",
|
|
19152
|
-
userBubble: "--user-bubble",
|
|
19153
|
-
userBubbleForeground: "--user-bubble-foreground",
|
|
19154
|
-
userBubbleRadius: "--user-bubble-radius",
|
|
19155
|
-
assistantForeground: "--assistant-foreground",
|
|
19156
|
-
assistantBubble: "--assistant-bubble",
|
|
19157
|
-
composerBorder: "--composer-border",
|
|
19158
|
-
composerRadius: "--composer-radius",
|
|
19159
|
-
threadMaxWidth: "--thread-max-width"
|
|
19160
|
-
};
|
|
19161
|
-
function themeToStyleVars(theme) {
|
|
19162
|
-
const vars = {};
|
|
19163
|
-
for (const [key, value] of Object.entries(theme)) {
|
|
19164
|
-
if (value != null && THEME_TO_CSS[key]) {
|
|
19165
|
-
vars[THEME_TO_CSS[key]] = value;
|
|
19166
|
-
}
|
|
19167
|
-
}
|
|
19168
|
-
return vars;
|
|
19169
|
-
}
|
|
19170
|
-
const themes = {
|
|
19171
|
-
/** Default light theme. Neutral grays with blue accent. */
|
|
19172
|
-
light: {
|
|
19173
|
-
background: "oklch(0.99 0 0)",
|
|
19174
|
-
foreground: "oklch(0.13 0 0)",
|
|
19175
|
-
primary: "oklch(0.55 0.2 250)",
|
|
19176
|
-
primaryForeground: "oklch(1 0 0)",
|
|
19177
|
-
secondary: "oklch(0.96 0.005 250)",
|
|
19178
|
-
secondaryForeground: "oklch(0.13 0 0)",
|
|
19179
|
-
muted: "oklch(0.96 0.005 250)",
|
|
19180
|
-
mutedForeground: "oklch(0.5 0.02 250)",
|
|
19181
|
-
accent: "oklch(0.94 0.01 250)",
|
|
19182
|
-
accentForeground: "oklch(0.13 0 0)",
|
|
19183
|
-
card: "oklch(0.99 0 0)",
|
|
19184
|
-
cardForeground: "oklch(0.13 0 0)",
|
|
19185
|
-
popover: "oklch(0.99 0 0)",
|
|
19186
|
-
popoverForeground: "oklch(0.13 0 0)",
|
|
19187
|
-
destructive: "oklch(0.55 0.22 27)",
|
|
19188
|
-
border: "oklch(0.91 0.005 250)",
|
|
19189
|
-
input: "oklch(0.91 0.005 250)",
|
|
19190
|
-
ring: "oklch(0.55 0.2 250)",
|
|
19191
|
-
radius: "0.625rem"
|
|
19192
|
-
},
|
|
19193
|
-
/** Dark theme. Deep gray background with lighter text. */
|
|
19194
|
-
dark: {
|
|
19195
|
-
background: "oklch(0.15 0 0)",
|
|
19196
|
-
foreground: "oklch(0.95 0 0)",
|
|
19197
|
-
primary: "oklch(0.7 0.15 250)",
|
|
19198
|
-
primaryForeground: "oklch(0.13 0 0)",
|
|
19199
|
-
secondary: "oklch(0.22 0 0)",
|
|
19200
|
-
secondaryForeground: "oklch(0.95 0 0)",
|
|
19201
|
-
muted: "oklch(0.22 0 0)",
|
|
19202
|
-
mutedForeground: "oklch(0.65 0 0)",
|
|
19203
|
-
accent: "oklch(0.25 0 0)",
|
|
19204
|
-
accentForeground: "oklch(0.95 0 0)",
|
|
19205
|
-
card: "oklch(0.18 0 0)",
|
|
19206
|
-
cardForeground: "oklch(0.95 0 0)",
|
|
19207
|
-
popover: "oklch(0.18 0 0)",
|
|
19208
|
-
popoverForeground: "oklch(0.95 0 0)",
|
|
19209
|
-
destructive: "oklch(0.65 0.2 25)",
|
|
19210
|
-
border: "oklch(1 0 0 / 10%)",
|
|
19211
|
-
input: "oklch(1 0 0 / 15%)",
|
|
19212
|
-
ring: "oklch(0.7 0.15 250)",
|
|
19213
|
-
radius: "0.625rem"
|
|
19214
|
-
},
|
|
19215
|
-
/** Midnight theme. Deep navy with soft blue tones. */
|
|
19216
|
-
midnight: {
|
|
19217
|
-
background: "oklch(0.16 0.02 260)",
|
|
19218
|
-
foreground: "oklch(0.92 0.01 250)",
|
|
19219
|
-
primary: "oklch(0.68 0.16 250)",
|
|
19220
|
-
primaryForeground: "oklch(0.98 0 0)",
|
|
19221
|
-
secondary: "oklch(0.22 0.02 260)",
|
|
19222
|
-
secondaryForeground: "oklch(0.92 0.01 250)",
|
|
19223
|
-
muted: "oklch(0.22 0.02 260)",
|
|
19224
|
-
mutedForeground: "oklch(0.6 0.04 250)",
|
|
19225
|
-
accent: "oklch(0.26 0.03 260)",
|
|
19226
|
-
accentForeground: "oklch(0.92 0.01 250)",
|
|
19227
|
-
card: "oklch(0.19 0.02 260)",
|
|
19228
|
-
cardForeground: "oklch(0.92 0.01 250)",
|
|
19229
|
-
popover: "oklch(0.19 0.02 260)",
|
|
19230
|
-
popoverForeground: "oklch(0.92 0.01 250)",
|
|
19231
|
-
destructive: "oklch(0.65 0.2 25)",
|
|
19232
|
-
border: "oklch(0.3 0.03 260)",
|
|
19233
|
-
input: "oklch(0.3 0.03 260)",
|
|
19234
|
-
ring: "oklch(0.68 0.16 250)",
|
|
19235
|
-
radius: "0.625rem"
|
|
19236
|
-
},
|
|
19237
|
-
/** Warm earthy theme. Brown and sand tones. */
|
|
19238
|
-
warm: {
|
|
19239
|
-
background: "oklch(0.98 0.005 80)",
|
|
19240
|
-
foreground: "oklch(0.2 0.02 50)",
|
|
19241
|
-
primary: "oklch(0.55 0.12 50)",
|
|
19242
|
-
primaryForeground: "oklch(0.98 0 0)",
|
|
19243
|
-
secondary: "oklch(0.94 0.01 80)",
|
|
19244
|
-
secondaryForeground: "oklch(0.2 0.02 50)",
|
|
19245
|
-
muted: "oklch(0.95 0.01 80)",
|
|
19246
|
-
mutedForeground: "oklch(0.5 0.03 50)",
|
|
19247
|
-
accent: "oklch(0.92 0.015 80)",
|
|
19248
|
-
accentForeground: "oklch(0.2 0.02 50)",
|
|
19249
|
-
card: "oklch(0.98 0.005 80)",
|
|
19250
|
-
cardForeground: "oklch(0.2 0.02 50)",
|
|
19251
|
-
popover: "oklch(0.98 0.005 80)",
|
|
19252
|
-
popoverForeground: "oklch(0.2 0.02 50)",
|
|
19253
|
-
destructive: "oklch(0.55 0.2 25)",
|
|
19254
|
-
border: "oklch(0.9 0.01 80)",
|
|
19255
|
-
input: "oklch(0.9 0.01 80)",
|
|
19256
|
-
ring: "oklch(0.55 0.12 50)",
|
|
19257
|
-
radius: "0.75rem"
|
|
19258
|
-
},
|
|
19259
|
-
/** Purple creative theme. Vibrant purple accent. */
|
|
19260
|
-
purple: {
|
|
19261
|
-
background: "oklch(0.99 0.003 310)",
|
|
19262
|
-
foreground: "oklch(0.15 0.02 310)",
|
|
19263
|
-
primary: "oklch(0.55 0.22 310)",
|
|
19264
|
-
primaryForeground: "oklch(1 0 0)",
|
|
19265
|
-
secondary: "oklch(0.96 0.01 310)",
|
|
19266
|
-
secondaryForeground: "oklch(0.15 0.02 310)",
|
|
19267
|
-
muted: "oklch(0.96 0.01 310)",
|
|
19268
|
-
mutedForeground: "oklch(0.5 0.04 310)",
|
|
19269
|
-
accent: "oklch(0.94 0.015 310)",
|
|
19270
|
-
accentForeground: "oklch(0.15 0.02 310)",
|
|
19271
|
-
card: "oklch(0.99 0.003 310)",
|
|
19272
|
-
cardForeground: "oklch(0.15 0.02 310)",
|
|
19273
|
-
popover: "oklch(0.99 0.003 310)",
|
|
19274
|
-
popoverForeground: "oklch(0.15 0.02 310)",
|
|
19275
|
-
destructive: "oklch(0.55 0.22 27)",
|
|
19276
|
-
border: "oklch(0.92 0.005 310)",
|
|
19277
|
-
input: "oklch(0.92 0.005 310)",
|
|
19278
|
-
ring: "oklch(0.55 0.22 310)",
|
|
19279
|
-
radius: "0.75rem"
|
|
19280
|
-
},
|
|
19281
|
-
/** Green nature theme. Fresh green tones. */
|
|
19282
|
-
green: {
|
|
19283
|
-
background: "oklch(0.99 0.003 150)",
|
|
19284
|
-
foreground: "oklch(0.15 0.02 150)",
|
|
19285
|
-
primary: "oklch(0.55 0.18 155)",
|
|
19286
|
-
primaryForeground: "oklch(1 0 0)",
|
|
19287
|
-
secondary: "oklch(0.96 0.01 150)",
|
|
19288
|
-
secondaryForeground: "oklch(0.15 0.02 150)",
|
|
19289
|
-
muted: "oklch(0.96 0.01 150)",
|
|
19290
|
-
mutedForeground: "oklch(0.5 0.03 150)",
|
|
19291
|
-
accent: "oklch(0.94 0.015 150)",
|
|
19292
|
-
accentForeground: "oklch(0.15 0.02 150)",
|
|
19293
|
-
card: "oklch(0.99 0.003 150)",
|
|
19294
|
-
cardForeground: "oklch(0.15 0.02 150)",
|
|
19295
|
-
popover: "oklch(0.99 0.003 150)",
|
|
19296
|
-
popoverForeground: "oklch(0.15 0.02 150)",
|
|
19297
|
-
destructive: "oklch(0.55 0.22 27)",
|
|
19298
|
-
border: "oklch(0.92 0.008 150)",
|
|
19299
|
-
input: "oklch(0.92 0.008 150)",
|
|
19300
|
-
ring: "oklch(0.55 0.18 155)",
|
|
19301
|
-
radius: "0.625rem"
|
|
19302
|
-
}
|
|
19303
|
-
};
|
|
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;
|
|
20020
|
+
return;
|
|
19655
20021
|
}
|
|
19656
|
-
|
|
19657
|
-
|
|
19658
|
-
|
|
19659
|
-
|
|
19660
|
-
|
|
19661
|
-
|
|
19662
|
-
|
|
19663
|
-
|
|
19664
|
-
|
|
19665
|
-
|
|
19666
|
-
|
|
19667
|
-
|
|
19668
|
-
|
|
19669
|
-
|
|
20022
|
+
const hydrationKey = createHydrationKey({
|
|
20023
|
+
backendUrl,
|
|
20024
|
+
threadId,
|
|
20025
|
+
apiKey,
|
|
20026
|
+
token
|
|
20027
|
+
});
|
|
20028
|
+
if (hydratedKeysRef.current.has(hydrationKey)) {
|
|
20029
|
+
return;
|
|
20030
|
+
}
|
|
20031
|
+
let cancelled = false;
|
|
20032
|
+
(async () => {
|
|
20033
|
+
var _a3, _b2;
|
|
20034
|
+
try {
|
|
20035
|
+
const state = await getThreadState(backendUrl, { apiKey, token }, threadId);
|
|
20036
|
+
if (cancelled || activeThreadIdRef.current !== threadId) {
|
|
20037
|
+
return;
|
|
19670
20038
|
}
|
|
19671
|
-
|
|
20039
|
+
if (aui.thread.getState().messages.length > 0) {
|
|
20040
|
+
return;
|
|
20041
|
+
}
|
|
20042
|
+
(_b2 = (_a3 = aui.thread).importExternalState) == null ? void 0 : _b2.call(_a3, state);
|
|
20043
|
+
hydratedKeysRef.current.add(hydrationKey);
|
|
20044
|
+
} catch (error2) {
|
|
20045
|
+
console.warn("[AthenaSDK] Failed to hydrate active thread state:", error2);
|
|
19672
20046
|
}
|
|
19673
|
-
|
|
19674
|
-
|
|
19675
|
-
|
|
19676
|
-
|
|
19677
|
-
|
|
19678
|
-
}
|
|
19679
|
-
function capturePosthogEvent(client, event, properties, options) {
|
|
19680
|
-
if (!client || typeof client.capture !== "function") return;
|
|
19681
|
-
client.capture(event, properties, options);
|
|
20047
|
+
})();
|
|
20048
|
+
return () => {
|
|
20049
|
+
cancelled = true;
|
|
20050
|
+
};
|
|
20051
|
+
}, [apiKey, aui, backendUrl, hasThread, isRunning, messageCount, threadId, token]);
|
|
19682
20052
|
}
|
|
19683
|
-
|
|
19684
|
-
|
|
19685
|
-
|
|
19686
|
-
|
|
19687
|
-
|
|
20053
|
+
const LOCAL_ID_PREFIX = "__LOCALID_";
|
|
20054
|
+
const isLocalPlaceholder = (id) => !!id && id.startsWith(LOCAL_ID_PREFIX);
|
|
20055
|
+
const selectActiveThreadRemoteId = (state) => {
|
|
20056
|
+
const { mainThreadId, threadItems } = state;
|
|
20057
|
+
if (!mainThreadId) {
|
|
20058
|
+
return null;
|
|
19688
20059
|
}
|
|
19689
|
-
|
|
19690
|
-
|
|
19691
|
-
|
|
19692
|
-
|
|
19693
|
-
|
|
19694
|
-
|
|
19695
|
-
|
|
19696
|
-
|
|
19697
|
-
|
|
19698
|
-
|
|
20060
|
+
const item = threadItems.find((t) => t.id === mainThreadId);
|
|
20061
|
+
const remoteId = item ? item.remoteId ?? null : mainThreadId;
|
|
20062
|
+
return isLocalPlaceholder(remoteId) ? null : remoteId;
|
|
20063
|
+
};
|
|
20064
|
+
function useAthenaThreadManager() {
|
|
20065
|
+
const statewireList = useAthenaStatewireThreadList();
|
|
20066
|
+
const statewireIsThreadLoading = useAuiState$1((s) => {
|
|
20067
|
+
var _a3;
|
|
20068
|
+
return ((_a3 = s.optional.thread) == null ? void 0 : _a3.isLoading) ?? false;
|
|
20069
|
+
});
|
|
20070
|
+
const statewireManager = useMemo(() => {
|
|
20071
|
+
if (!statewireList) return null;
|
|
20072
|
+
return {
|
|
20073
|
+
activeThreadId: statewireList.isNewChat ? null : statewireList.activeThreadId,
|
|
20074
|
+
isListLoading: statewireList.isLoading,
|
|
20075
|
+
isThreadLoading: statewireIsThreadLoading,
|
|
20076
|
+
switchToThread: async (threadId) => statewireList.selectThread(threadId),
|
|
20077
|
+
switchToNewThread: async () => statewireList.newThread()
|
|
20078
|
+
};
|
|
20079
|
+
}, [statewireList, statewireIsThreadLoading]);
|
|
20080
|
+
const aui = useAui();
|
|
20081
|
+
const hasThreads = aui.threads.source !== null;
|
|
20082
|
+
const activeThreadId = useAuiState$1((s) => {
|
|
20083
|
+
const threads = s.optional.threads;
|
|
20084
|
+
return threads ? selectActiveThreadRemoteId(threads) : null;
|
|
20085
|
+
});
|
|
20086
|
+
const isThreadLoading = useAuiState$1((s) => {
|
|
20087
|
+
var _a3;
|
|
20088
|
+
return ((_a3 = s.optional.thread) == null ? void 0 : _a3.isLoading) ?? false;
|
|
20089
|
+
});
|
|
20090
|
+
const isListLoading = useAuiState$1((s) => {
|
|
20091
|
+
var _a3;
|
|
20092
|
+
return (_a3 = s.optional.threads) == null ? void 0 : _a3.isLoading;
|
|
20093
|
+
});
|
|
20094
|
+
const auiRef = useRef(aui);
|
|
20095
|
+
auiRef.current = aui;
|
|
20096
|
+
const switchToThread = useCallback(
|
|
20097
|
+
async (id) => auiRef.current.threads.switchToThread(id),
|
|
20098
|
+
[]
|
|
20099
|
+
);
|
|
20100
|
+
const switchToNewThread = useCallback(
|
|
20101
|
+
async () => auiRef.current.threads.switchToNewThread(),
|
|
20102
|
+
[]
|
|
19699
20103
|
);
|
|
20104
|
+
const legacyManager = useMemo(() => {
|
|
20105
|
+
if (!hasThreads || isListLoading == null) {
|
|
20106
|
+
return null;
|
|
20107
|
+
}
|
|
20108
|
+
return {
|
|
20109
|
+
activeThreadId,
|
|
20110
|
+
isListLoading,
|
|
20111
|
+
isThreadLoading,
|
|
20112
|
+
switchToThread,
|
|
20113
|
+
switchToNewThread
|
|
20114
|
+
};
|
|
20115
|
+
}, [hasThreads, activeThreadId, isListLoading, isThreadLoading, switchToThread, switchToNewThread]);
|
|
20116
|
+
return statewireManager ?? legacyManager;
|
|
19700
20117
|
}
|
|
19701
|
-
|
|
19702
|
-
|
|
19703
|
-
const
|
|
19704
|
-
|
|
19705
|
-
|
|
19706
|
-
|
|
19707
|
-
|
|
19708
|
-
|
|
19709
|
-
|
|
19710
|
-
|
|
19711
|
-
|
|
19712
|
-
|
|
19713
|
-
|
|
19714
|
-
|
|
19715
|
-
|
|
19716
|
-
|
|
19717
|
-
|
|
19718
|
-
|
|
19719
|
-
|
|
19720
|
-
|
|
19721
|
-
|
|
20118
|
+
const POLL_DELAY_MS = 5e3;
|
|
20119
|
+
const POLL_INTERVAL_MS = 1e3;
|
|
20120
|
+
const POLL_MAX_DURATION_MS = 6e4;
|
|
20121
|
+
function useThreadTitlePolling(refresh) {
|
|
20122
|
+
const threadKey = useAuiState$1(
|
|
20123
|
+
(s) => {
|
|
20124
|
+
var _a3, _b2;
|
|
20125
|
+
return ((_a3 = s.optional.threadListItem) == null ? void 0 : _a3.remoteId) ?? ((_b2 = s.optional.threadListItem) == null ? void 0 : _b2.id) ?? null;
|
|
20126
|
+
}
|
|
20127
|
+
);
|
|
20128
|
+
const hasMessages = useAuiState$1((s) => {
|
|
20129
|
+
var _a3;
|
|
20130
|
+
return (((_a3 = s.optional.thread) == null ? void 0 : _a3.messages.length) ?? 0) > 0;
|
|
20131
|
+
});
|
|
20132
|
+
const currentTitle = useAuiState$1((s) => {
|
|
20133
|
+
var _a3;
|
|
20134
|
+
return ((_a3 = s.optional.threadListItem) == null ? void 0 : _a3.title) ?? "";
|
|
20135
|
+
});
|
|
20136
|
+
const trimmedTitle = currentTitle.trim();
|
|
20137
|
+
const hasTitle = trimmedTitle.length > 0 && !isSerializedContentPartsTitle(trimmedTitle);
|
|
20138
|
+
const polledThreadsRef = useRef(/* @__PURE__ */ new Set());
|
|
20139
|
+
const refreshRef = useRef(refresh);
|
|
20140
|
+
refreshRef.current = refresh;
|
|
20141
|
+
useEffect(() => {
|
|
20142
|
+
if (!threadKey || hasTitle || !hasMessages) {
|
|
20143
|
+
return;
|
|
20144
|
+
}
|
|
20145
|
+
if (polledThreadsRef.current.has(threadKey)) {
|
|
20146
|
+
return;
|
|
20147
|
+
}
|
|
20148
|
+
polledThreadsRef.current.add(threadKey);
|
|
20149
|
+
let stopped = false;
|
|
20150
|
+
let intervalId = null;
|
|
20151
|
+
let maxTimeoutId = null;
|
|
20152
|
+
const stop = () => {
|
|
20153
|
+
stopped = true;
|
|
20154
|
+
if (intervalId !== null) {
|
|
20155
|
+
clearInterval(intervalId);
|
|
20156
|
+
intervalId = null;
|
|
19722
20157
|
}
|
|
19723
|
-
|
|
19724
|
-
|
|
19725
|
-
|
|
19726
|
-
|
|
19727
|
-
|
|
19728
|
-
|
|
19729
|
-
|
|
19730
|
-
|
|
19731
|
-
|
|
19732
|
-
|
|
19733
|
-
|
|
20158
|
+
if (maxTimeoutId !== null) {
|
|
20159
|
+
clearTimeout(maxTimeoutId);
|
|
20160
|
+
maxTimeoutId = null;
|
|
20161
|
+
}
|
|
20162
|
+
};
|
|
20163
|
+
const startTimeoutId = setTimeout(() => {
|
|
20164
|
+
if (stopped) return;
|
|
20165
|
+
refreshRef.current();
|
|
20166
|
+
intervalId = setInterval(() => {
|
|
20167
|
+
refreshRef.current();
|
|
20168
|
+
}, POLL_INTERVAL_MS);
|
|
20169
|
+
maxTimeoutId = setTimeout(stop, POLL_MAX_DURATION_MS - POLL_DELAY_MS);
|
|
20170
|
+
}, POLL_DELAY_MS);
|
|
20171
|
+
return () => {
|
|
20172
|
+
clearTimeout(startTimeoutId);
|
|
20173
|
+
stop();
|
|
20174
|
+
};
|
|
20175
|
+
}, [threadKey, hasTitle, hasMessages]);
|
|
19734
20176
|
}
|
|
19735
|
-
|
|
19736
|
-
|
|
19737
|
-
|
|
19738
|
-
|
|
19739
|
-
|
|
19740
|
-
|
|
19741
|
-
|
|
19742
|
-
|
|
19743
|
-
|
|
19744
|
-
|
|
19745
|
-
|
|
20177
|
+
const THEME_TO_CSS = {
|
|
20178
|
+
primary: "--primary",
|
|
20179
|
+
primaryForeground: "--primary-foreground",
|
|
20180
|
+
background: "--background",
|
|
20181
|
+
foreground: "--foreground",
|
|
20182
|
+
muted: "--muted",
|
|
20183
|
+
mutedForeground: "--muted-foreground",
|
|
20184
|
+
accent: "--accent",
|
|
20185
|
+
accentForeground: "--accent-foreground",
|
|
20186
|
+
secondary: "--secondary",
|
|
20187
|
+
secondaryForeground: "--secondary-foreground",
|
|
20188
|
+
card: "--card",
|
|
20189
|
+
cardForeground: "--card-foreground",
|
|
20190
|
+
popover: "--popover",
|
|
20191
|
+
popoverForeground: "--popover-foreground",
|
|
20192
|
+
destructive: "--destructive",
|
|
20193
|
+
border: "--border",
|
|
20194
|
+
input: "--input",
|
|
20195
|
+
ring: "--ring",
|
|
20196
|
+
radius: "--radius",
|
|
20197
|
+
fontFamily: "--font-family",
|
|
20198
|
+
// Extended SDK-specific variables
|
|
20199
|
+
sidebarBackground: "--sidebar-background",
|
|
20200
|
+
sidebarBorder: "--sidebar-border",
|
|
20201
|
+
sidebarWidth: "--sidebar-width",
|
|
20202
|
+
userBubble: "--user-bubble",
|
|
20203
|
+
userBubbleForeground: "--user-bubble-foreground",
|
|
20204
|
+
userBubbleRadius: "--user-bubble-radius",
|
|
20205
|
+
assistantForeground: "--assistant-foreground",
|
|
20206
|
+
assistantBubble: "--assistant-bubble",
|
|
20207
|
+
composerBorder: "--composer-border",
|
|
20208
|
+
composerRadius: "--composer-radius",
|
|
20209
|
+
threadMaxWidth: "--thread-max-width"
|
|
20210
|
+
};
|
|
20211
|
+
function themeToStyleVars(theme) {
|
|
20212
|
+
const vars = {};
|
|
20213
|
+
for (const [key, value] of Object.entries(theme)) {
|
|
20214
|
+
if (value != null && THEME_TO_CSS[key]) {
|
|
20215
|
+
vars[THEME_TO_CSS[key]] = value;
|
|
19746
20216
|
}
|
|
19747
|
-
}
|
|
19748
|
-
return
|
|
20217
|
+
}
|
|
20218
|
+
return vars;
|
|
19749
20219
|
}
|
|
20220
|
+
const themes = {
|
|
20221
|
+
/** Default light theme. Neutral grays with blue accent. */
|
|
20222
|
+
light: {
|
|
20223
|
+
background: "oklch(0.99 0 0)",
|
|
20224
|
+
foreground: "oklch(0.13 0 0)",
|
|
20225
|
+
primary: "oklch(0.55 0.2 250)",
|
|
20226
|
+
primaryForeground: "oklch(1 0 0)",
|
|
20227
|
+
secondary: "oklch(0.96 0.005 250)",
|
|
20228
|
+
secondaryForeground: "oklch(0.13 0 0)",
|
|
20229
|
+
muted: "oklch(0.96 0.005 250)",
|
|
20230
|
+
mutedForeground: "oklch(0.5 0.02 250)",
|
|
20231
|
+
accent: "oklch(0.94 0.01 250)",
|
|
20232
|
+
accentForeground: "oklch(0.13 0 0)",
|
|
20233
|
+
card: "oklch(0.99 0 0)",
|
|
20234
|
+
cardForeground: "oklch(0.13 0 0)",
|
|
20235
|
+
popover: "oklch(0.99 0 0)",
|
|
20236
|
+
popoverForeground: "oklch(0.13 0 0)",
|
|
20237
|
+
destructive: "oklch(0.55 0.22 27)",
|
|
20238
|
+
border: "oklch(0.91 0.005 250)",
|
|
20239
|
+
input: "oklch(0.91 0.005 250)",
|
|
20240
|
+
ring: "oklch(0.55 0.2 250)",
|
|
20241
|
+
radius: "0.625rem"
|
|
20242
|
+
},
|
|
20243
|
+
/** Dark theme. Deep gray background with lighter text. */
|
|
20244
|
+
dark: {
|
|
20245
|
+
background: "oklch(0.15 0 0)",
|
|
20246
|
+
foreground: "oklch(0.95 0 0)",
|
|
20247
|
+
primary: "oklch(0.7 0.15 250)",
|
|
20248
|
+
primaryForeground: "oklch(0.13 0 0)",
|
|
20249
|
+
secondary: "oklch(0.22 0 0)",
|
|
20250
|
+
secondaryForeground: "oklch(0.95 0 0)",
|
|
20251
|
+
muted: "oklch(0.22 0 0)",
|
|
20252
|
+
mutedForeground: "oklch(0.65 0 0)",
|
|
20253
|
+
accent: "oklch(0.25 0 0)",
|
|
20254
|
+
accentForeground: "oklch(0.95 0 0)",
|
|
20255
|
+
card: "oklch(0.18 0 0)",
|
|
20256
|
+
cardForeground: "oklch(0.95 0 0)",
|
|
20257
|
+
popover: "oklch(0.18 0 0)",
|
|
20258
|
+
popoverForeground: "oklch(0.95 0 0)",
|
|
20259
|
+
destructive: "oklch(0.65 0.2 25)",
|
|
20260
|
+
border: "oklch(1 0 0 / 10%)",
|
|
20261
|
+
input: "oklch(1 0 0 / 15%)",
|
|
20262
|
+
ring: "oklch(0.7 0.15 250)",
|
|
20263
|
+
radius: "0.625rem"
|
|
20264
|
+
},
|
|
20265
|
+
/** Midnight theme. Deep navy with soft blue tones. */
|
|
20266
|
+
midnight: {
|
|
20267
|
+
background: "oklch(0.16 0.02 260)",
|
|
20268
|
+
foreground: "oklch(0.92 0.01 250)",
|
|
20269
|
+
primary: "oklch(0.68 0.16 250)",
|
|
20270
|
+
primaryForeground: "oklch(0.98 0 0)",
|
|
20271
|
+
secondary: "oklch(0.22 0.02 260)",
|
|
20272
|
+
secondaryForeground: "oklch(0.92 0.01 250)",
|
|
20273
|
+
muted: "oklch(0.22 0.02 260)",
|
|
20274
|
+
mutedForeground: "oklch(0.6 0.04 250)",
|
|
20275
|
+
accent: "oklch(0.26 0.03 260)",
|
|
20276
|
+
accentForeground: "oklch(0.92 0.01 250)",
|
|
20277
|
+
card: "oklch(0.19 0.02 260)",
|
|
20278
|
+
cardForeground: "oklch(0.92 0.01 250)",
|
|
20279
|
+
popover: "oklch(0.19 0.02 260)",
|
|
20280
|
+
popoverForeground: "oklch(0.92 0.01 250)",
|
|
20281
|
+
destructive: "oklch(0.65 0.2 25)",
|
|
20282
|
+
border: "oklch(0.3 0.03 260)",
|
|
20283
|
+
input: "oklch(0.3 0.03 260)",
|
|
20284
|
+
ring: "oklch(0.68 0.16 250)",
|
|
20285
|
+
radius: "0.625rem"
|
|
20286
|
+
},
|
|
20287
|
+
/** Warm earthy theme. Brown and sand tones. */
|
|
20288
|
+
warm: {
|
|
20289
|
+
background: "oklch(0.98 0.005 80)",
|
|
20290
|
+
foreground: "oklch(0.2 0.02 50)",
|
|
20291
|
+
primary: "oklch(0.55 0.12 50)",
|
|
20292
|
+
primaryForeground: "oklch(0.98 0 0)",
|
|
20293
|
+
secondary: "oklch(0.94 0.01 80)",
|
|
20294
|
+
secondaryForeground: "oklch(0.2 0.02 50)",
|
|
20295
|
+
muted: "oklch(0.95 0.01 80)",
|
|
20296
|
+
mutedForeground: "oklch(0.5 0.03 50)",
|
|
20297
|
+
accent: "oklch(0.92 0.015 80)",
|
|
20298
|
+
accentForeground: "oklch(0.2 0.02 50)",
|
|
20299
|
+
card: "oklch(0.98 0.005 80)",
|
|
20300
|
+
cardForeground: "oklch(0.2 0.02 50)",
|
|
20301
|
+
popover: "oklch(0.98 0.005 80)",
|
|
20302
|
+
popoverForeground: "oklch(0.2 0.02 50)",
|
|
20303
|
+
destructive: "oklch(0.55 0.2 25)",
|
|
20304
|
+
border: "oklch(0.9 0.01 80)",
|
|
20305
|
+
input: "oklch(0.9 0.01 80)",
|
|
20306
|
+
ring: "oklch(0.55 0.12 50)",
|
|
20307
|
+
radius: "0.75rem"
|
|
20308
|
+
},
|
|
20309
|
+
/** Purple creative theme. Vibrant purple accent. */
|
|
20310
|
+
purple: {
|
|
20311
|
+
background: "oklch(0.99 0.003 310)",
|
|
20312
|
+
foreground: "oklch(0.15 0.02 310)",
|
|
20313
|
+
primary: "oklch(0.55 0.22 310)",
|
|
20314
|
+
primaryForeground: "oklch(1 0 0)",
|
|
20315
|
+
secondary: "oklch(0.96 0.01 310)",
|
|
20316
|
+
secondaryForeground: "oklch(0.15 0.02 310)",
|
|
20317
|
+
muted: "oklch(0.96 0.01 310)",
|
|
20318
|
+
mutedForeground: "oklch(0.5 0.04 310)",
|
|
20319
|
+
accent: "oklch(0.94 0.015 310)",
|
|
20320
|
+
accentForeground: "oklch(0.15 0.02 310)",
|
|
20321
|
+
card: "oklch(0.99 0.003 310)",
|
|
20322
|
+
cardForeground: "oklch(0.15 0.02 310)",
|
|
20323
|
+
popover: "oklch(0.99 0.003 310)",
|
|
20324
|
+
popoverForeground: "oklch(0.15 0.02 310)",
|
|
20325
|
+
destructive: "oklch(0.55 0.22 27)",
|
|
20326
|
+
border: "oklch(0.92 0.005 310)",
|
|
20327
|
+
input: "oklch(0.92 0.005 310)",
|
|
20328
|
+
ring: "oklch(0.55 0.22 310)",
|
|
20329
|
+
radius: "0.75rem"
|
|
20330
|
+
},
|
|
20331
|
+
/** Green nature theme. Fresh green tones. */
|
|
20332
|
+
green: {
|
|
20333
|
+
background: "oklch(0.99 0.003 150)",
|
|
20334
|
+
foreground: "oklch(0.15 0.02 150)",
|
|
20335
|
+
primary: "oklch(0.55 0.18 155)",
|
|
20336
|
+
primaryForeground: "oklch(1 0 0)",
|
|
20337
|
+
secondary: "oklch(0.96 0.01 150)",
|
|
20338
|
+
secondaryForeground: "oklch(0.15 0.02 150)",
|
|
20339
|
+
muted: "oklch(0.96 0.01 150)",
|
|
20340
|
+
mutedForeground: "oklch(0.5 0.03 150)",
|
|
20341
|
+
accent: "oklch(0.94 0.015 150)",
|
|
20342
|
+
accentForeground: "oklch(0.15 0.02 150)",
|
|
20343
|
+
card: "oklch(0.99 0.003 150)",
|
|
20344
|
+
cardForeground: "oklch(0.15 0.02 150)",
|
|
20345
|
+
popover: "oklch(0.99 0.003 150)",
|
|
20346
|
+
popoverForeground: "oklch(0.15 0.02 150)",
|
|
20347
|
+
destructive: "oklch(0.55 0.22 27)",
|
|
20348
|
+
border: "oklch(0.92 0.008 150)",
|
|
20349
|
+
input: "oklch(0.92 0.008 150)",
|
|
20350
|
+
ring: "oklch(0.55 0.18 155)",
|
|
20351
|
+
radius: "0.625rem"
|
|
20352
|
+
}
|
|
20353
|
+
};
|
|
19750
20354
|
const resolveTokenOverride = ({
|
|
19751
20355
|
config: config2,
|
|
19752
20356
|
token
|
|
@@ -19876,6 +20480,8 @@ function AthenaStatewireStandalone({
|
|
|
19876
20480
|
token,
|
|
19877
20481
|
getToken,
|
|
19878
20482
|
model,
|
|
20483
|
+
agent: agent2,
|
|
20484
|
+
channel,
|
|
19879
20485
|
tools,
|
|
19880
20486
|
frontendToolIds,
|
|
19881
20487
|
frontendTools,
|
|
@@ -19907,6 +20513,8 @@ function AthenaStatewireStandalone({
|
|
|
19907
20513
|
token,
|
|
19908
20514
|
getToken,
|
|
19909
20515
|
model,
|
|
20516
|
+
agent: agent2,
|
|
20517
|
+
channel,
|
|
19910
20518
|
tools,
|
|
19911
20519
|
frontendToolIds,
|
|
19912
20520
|
frontendToolkit: frontendTools,
|
|
@@ -20182,6 +20790,7 @@ function AthenaProvider({
|
|
|
20182
20790
|
apiKey,
|
|
20183
20791
|
token: tokenProp,
|
|
20184
20792
|
agent: agent2,
|
|
20793
|
+
channel,
|
|
20185
20794
|
model,
|
|
20186
20795
|
tools = [],
|
|
20187
20796
|
frontendTools = {},
|
|
@@ -20204,8 +20813,32 @@ function AthenaProvider({
|
|
|
20204
20813
|
theme,
|
|
20205
20814
|
linkClicks,
|
|
20206
20815
|
citationLinks,
|
|
20207
|
-
posthog: posthogProp
|
|
20816
|
+
posthog: posthogProp,
|
|
20817
|
+
debug,
|
|
20818
|
+
onDiagnostic,
|
|
20819
|
+
onError
|
|
20208
20820
|
}) {
|
|
20821
|
+
const onDiagnosticRef = useRef(onDiagnostic);
|
|
20822
|
+
onDiagnosticRef.current = onDiagnostic;
|
|
20823
|
+
const onErrorRef = useRef(onError);
|
|
20824
|
+
onErrorRef.current = onError;
|
|
20825
|
+
useEffect(() => {
|
|
20826
|
+
installAthenaDiagnosticsGlobal();
|
|
20827
|
+
return athenaDiagnostics.addConsumer({
|
|
20828
|
+
onEvent: (event) => {
|
|
20829
|
+
var _a3;
|
|
20830
|
+
return (_a3 = onDiagnosticRef.current) == null ? void 0 : _a3.call(onDiagnosticRef, event);
|
|
20831
|
+
},
|
|
20832
|
+
onError: (error2, event) => {
|
|
20833
|
+
var _a3;
|
|
20834
|
+
return (_a3 = onErrorRef.current) == null ? void 0 : _a3.call(onErrorRef, error2, event);
|
|
20835
|
+
}
|
|
20836
|
+
});
|
|
20837
|
+
}, []);
|
|
20838
|
+
const debugKey = JSON.stringify(debugPropToDiagnosticsConfig(debug));
|
|
20839
|
+
useEffect(() => {
|
|
20840
|
+
athenaDiagnostics.configure(debugPropToDiagnosticsConfig(debug));
|
|
20841
|
+
}, [debugKey]);
|
|
20209
20842
|
const frontendToolNames = useMemo(() => Object.keys(frontendTools), [frontendTools]);
|
|
20210
20843
|
const effectiveFrontendTools = useMemo(
|
|
20211
20844
|
() => disableAutoOpen ? frontendTools : { ...DEFAULT_AUTO_OPEN_TOOLS, ...frontendTools },
|
|
@@ -20232,10 +20865,31 @@ function AthenaProvider({
|
|
|
20232
20865
|
transport: configuredTransport
|
|
20233
20866
|
});
|
|
20234
20867
|
useEffect(() => {
|
|
20868
|
+
athenaDiagnostics.gauge("sdk.transport", effectiveTransport);
|
|
20869
|
+
athenaDiagnostics.emit("sdk.transport", {
|
|
20870
|
+
level: "debug",
|
|
20871
|
+
data: { transport: effectiveTransport, thread_list: enableThreadList }
|
|
20872
|
+
});
|
|
20235
20873
|
if (transportFallbackReason) {
|
|
20874
|
+
athenaDiagnostics.emit("sdk.config.warning", {
|
|
20875
|
+
level: "warn",
|
|
20876
|
+
data: { prop: "transport", reason: transportFallbackReason }
|
|
20877
|
+
});
|
|
20236
20878
|
console.warn(`[AthenaSDK] ${transportFallbackReason}`);
|
|
20237
20879
|
}
|
|
20238
|
-
}, [transportFallbackReason]);
|
|
20880
|
+
}, [effectiveTransport, enableThreadList, transportFallbackReason]);
|
|
20881
|
+
useEffect(() => {
|
|
20882
|
+
if (channel && effectiveTransport !== "statewire") {
|
|
20883
|
+
athenaDiagnostics.emit("sdk.config.warning", {
|
|
20884
|
+
level: "warn",
|
|
20885
|
+
data: {
|
|
20886
|
+
prop: "channel",
|
|
20887
|
+
value: channel,
|
|
20888
|
+
reason: "the 'channel' prop requires transport='statewire'; the legacy transport ignores it."
|
|
20889
|
+
}
|
|
20890
|
+
});
|
|
20891
|
+
}
|
|
20892
|
+
}, [channel, effectiveTransport]);
|
|
20239
20893
|
const bridge = useParentBridge({
|
|
20240
20894
|
trustedOrigins: configuredTrustedParentOrigins
|
|
20241
20895
|
});
|
|
@@ -20262,6 +20916,8 @@ function AthenaProvider({
|
|
|
20262
20916
|
token: effectiveToken,
|
|
20263
20917
|
getToken: configuredGetToken,
|
|
20264
20918
|
model,
|
|
20919
|
+
agent: agent2,
|
|
20920
|
+
channel,
|
|
20265
20921
|
tools,
|
|
20266
20922
|
frontendToolIds: frontendToolNames,
|
|
20267
20923
|
frontendTools: effectiveFrontendTools,
|
|
@@ -36917,7 +37573,7 @@ function requireUseSyncExternalStoreShim_development$1() {
|
|
|
36917
37573
|
var useState2 = React$1.useState, useEffect2 = React$1.useEffect, useLayoutEffect3 = React$1.useLayoutEffect, useDebugValue2 = React$1.useDebugValue;
|
|
36918
37574
|
var didWarnOld18Alpha = false;
|
|
36919
37575
|
var didWarnUncachedGetSnapshot = false;
|
|
36920
|
-
function
|
|
37576
|
+
function useSyncExternalStore2(subscribe, getSnapshot, getServerSnapshot) {
|
|
36921
37577
|
{
|
|
36922
37578
|
if (!didWarnOld18Alpha) {
|
|
36923
37579
|
if (React$1.startTransition !== void 0) {
|
|
@@ -36984,7 +37640,7 @@ function requireUseSyncExternalStoreShim_development$1() {
|
|
|
36984
37640
|
}
|
|
36985
37641
|
var canUseDOM2 = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
|
|
36986
37642
|
var isServerEnvironment = !canUseDOM2;
|
|
36987
|
-
var shim2 = isServerEnvironment ? useSyncExternalStore$1 :
|
|
37643
|
+
var shim2 = isServerEnvironment ? useSyncExternalStore$1 : useSyncExternalStore2;
|
|
36988
37644
|
var useSyncExternalStore$2 = React$1.useSyncExternalStore !== void 0 ? React$1.useSyncExternalStore : shim2;
|
|
36989
37645
|
useSyncExternalStoreShim_development$1.useSyncExternalStore = useSyncExternalStore$2;
|
|
36990
37646
|
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") {
|
|
@@ -37287,7 +37943,7 @@ function requireWithSelector_development$1() {
|
|
|
37287
37943
|
return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y;
|
|
37288
37944
|
}
|
|
37289
37945
|
var objectIs = typeof Object.is === "function" ? Object.is : is;
|
|
37290
|
-
var
|
|
37946
|
+
var useSyncExternalStore2 = shim2.useSyncExternalStore;
|
|
37291
37947
|
var useRef2 = React$1.useRef, useEffect2 = React$1.useEffect, useMemo2 = React$1.useMemo, useDebugValue2 = React$1.useDebugValue;
|
|
37292
37948
|
function useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
|
|
37293
37949
|
var instRef = useRef2(null);
|
|
@@ -37344,7 +38000,7 @@ function requireWithSelector_development$1() {
|
|
|
37344
38000
|
};
|
|
37345
38001
|
return [getSnapshotWithSelector, getServerSnapshotWithSelector];
|
|
37346
38002
|
}, [getSnapshot, getServerSnapshot, selector, isEqual]), getSelection2 = _useMemo[0], getServerSelection = _useMemo[1];
|
|
37347
|
-
var value =
|
|
38003
|
+
var value = useSyncExternalStore2(subscribe, getSelection2, getServerSelection);
|
|
37348
38004
|
useEffect2(function() {
|
|
37349
38005
|
inst.hasValue = true;
|
|
37350
38006
|
inst.value = value;
|
|
@@ -37713,8 +38369,8 @@ function canReceiveRef(Component) {
|
|
|
37713
38369
|
}
|
|
37714
38370
|
function isReact19Plus() {
|
|
37715
38371
|
try {
|
|
37716
|
-
if (version$
|
|
37717
|
-
const majorVersion = parseInt(version$
|
|
38372
|
+
if (version$2) {
|
|
38373
|
+
const majorVersion = parseInt(version$2.split(".")[0], 10);
|
|
37718
38374
|
return majorVersion >= 19;
|
|
37719
38375
|
}
|
|
37720
38376
|
} catch {
|
|
@@ -54393,7 +55049,7 @@ function requireWithSelector_production() {
|
|
|
54393
55049
|
function is(x, y) {
|
|
54394
55050
|
return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
|
|
54395
55051
|
}
|
|
54396
|
-
var objectIs = "function" === typeof Object.is ? Object.is : is,
|
|
55052
|
+
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
55053
|
withSelector_production.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
|
|
54398
55054
|
var instRef = useRef2(null);
|
|
54399
55055
|
if (null === instRef.current) {
|
|
@@ -54434,7 +55090,7 @@ function requireWithSelector_production() {
|
|
|
54434
55090
|
},
|
|
54435
55091
|
[getSnapshot, getServerSnapshot, selector, isEqual]
|
|
54436
55092
|
);
|
|
54437
|
-
var value =
|
|
55093
|
+
var value = useSyncExternalStore2(subscribe, instRef[0], instRef[1]);
|
|
54438
55094
|
useEffect2(
|
|
54439
55095
|
function() {
|
|
54440
55096
|
inst.hasValue = true;
|
|
@@ -54466,7 +55122,7 @@ function requireWithSelector_development() {
|
|
|
54466
55122
|
return x === y && (0 !== x || 1 / x === 1 / y) || x !== x && y !== y;
|
|
54467
55123
|
}
|
|
54468
55124
|
"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,
|
|
55125
|
+
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
55126
|
withSelector_development.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
|
|
54471
55127
|
var instRef = useRef2(null);
|
|
54472
55128
|
if (null === instRef.current) {
|
|
@@ -54508,7 +55164,7 @@ function requireWithSelector_development() {
|
|
|
54508
55164
|
},
|
|
54509
55165
|
[getSnapshot, getServerSnapshot, selector, isEqual]
|
|
54510
55166
|
);
|
|
54511
|
-
var value =
|
|
55167
|
+
var value = useSyncExternalStore2(subscribe, instRef[0], instRef[1]);
|
|
54512
55168
|
useEffect2(
|
|
54513
55169
|
function() {
|
|
54514
55170
|
inst.hasValue = true;
|
|
@@ -55322,7 +55978,7 @@ const TiptapComposer = ({ tools = [], rootCategories }) => {
|
|
|
55322
55978
|
quoteRef.current = quote;
|
|
55323
55979
|
const isUploadingRef = useRef(isUploading);
|
|
55324
55980
|
isUploadingRef.current = isUploading;
|
|
55325
|
-
const isRunningThread = useAuiState((s) => s.thread.isRunning);
|
|
55981
|
+
const isRunningThread = useAuiState$1((s) => s.thread.isRunning);
|
|
55326
55982
|
const isThreadRunning = allowsMidRunSend(transport) ? false : isRunningThread;
|
|
55327
55983
|
const isThreadRunningRef = useRef(isThreadRunning);
|
|
55328
55984
|
isThreadRunningRef.current = isThreadRunning;
|
|
@@ -55346,13 +56002,13 @@ const TiptapComposer = ({ tools = [], rootCategories }) => {
|
|
|
55346
56002
|
});
|
|
55347
56003
|
if (fullMessage) {
|
|
55348
56004
|
aui.composer.setText(fullMessage);
|
|
55349
|
-
aui.composer.send();
|
|
56005
|
+
aui.composer.send({ steer: false });
|
|
55350
56006
|
clearAttachments();
|
|
55351
56007
|
clearQuote();
|
|
55352
56008
|
}
|
|
55353
56009
|
} else {
|
|
55354
56010
|
aui.composer.setText(markdown);
|
|
55355
|
-
aui.composer.send();
|
|
56011
|
+
aui.composer.send({ steer: false });
|
|
55356
56012
|
}
|
|
55357
56013
|
editor2.commands.clearContent();
|
|
55358
56014
|
}, [aui, clearAttachments, clearQuote, appUrl]);
|
|
@@ -55573,7 +56229,7 @@ function readInterruptMessage(value) {
|
|
|
55573
56229
|
}
|
|
55574
56230
|
const PENDING_RESUME_GRACE_MS = 15e3;
|
|
55575
56231
|
const StatewireApprovalCard = () => {
|
|
55576
|
-
const extras = useAuiState((s) => s.thread.extras);
|
|
56232
|
+
const extras = useAuiState$1((s) => s.thread.extras);
|
|
55577
56233
|
if (!hasStatewireThreadExtras(extras)) return null;
|
|
55578
56234
|
return /* @__PURE__ */ jsx(StatewireApprovalCardInner, {});
|
|
55579
56235
|
};
|
|
@@ -55593,7 +56249,7 @@ const StatewireApprovalCardInner = () => {
|
|
|
55593
56249
|
prevRequestIdRef.current = requestId;
|
|
55594
56250
|
if (pending) setPending(false);
|
|
55595
56251
|
}
|
|
55596
|
-
const isRunning = useAuiState((s) => s.thread.isRunning);
|
|
56252
|
+
const isRunning = useAuiState$1((s) => s.thread.isRunning);
|
|
55597
56253
|
const sawResumeRunRef = useRef(false);
|
|
55598
56254
|
useEffect(() => {
|
|
55599
56255
|
if (!pending) {
|
|
@@ -55715,7 +56371,7 @@ function queueItemText(parts) {
|
|
|
55715
56371
|
).join("\n\n");
|
|
55716
56372
|
}
|
|
55717
56373
|
const StatewireQueuedMessages = () => {
|
|
55718
|
-
const extras = useAuiState((s) => s.thread.extras);
|
|
56374
|
+
const extras = useAuiState$1((s) => s.thread.extras);
|
|
55719
56375
|
if (!hasStatewireThreadExtras(extras)) return null;
|
|
55720
56376
|
return /* @__PURE__ */ jsx(StatewireQueuedMessagesInner, {});
|
|
55721
56377
|
};
|
|
@@ -55989,6 +56645,10 @@ const TOOL_META = {
|
|
|
55989
56645
|
// Presentations
|
|
55990
56646
|
create_powerpoint_deck: { displayName: "Building presentation", icon: Monitor },
|
|
55991
56647
|
execute_presentation_code: { displayName: "Generating slides", icon: Monitor },
|
|
56648
|
+
execute_word_document_code: { displayName: "Editing Word document", icon: FileText },
|
|
56649
|
+
execute_spreadsheet_code: { displayName: "Editing spreadsheet", icon: ChartColumn },
|
|
56650
|
+
execute_spreadsheet_commands: { displayName: "Editing spreadsheet", icon: ChartColumn },
|
|
56651
|
+
unified_email_list_accounts: { displayName: "Checking email accounts", icon: Mail },
|
|
55992
56652
|
// Code & Data
|
|
55993
56653
|
run_python_code: { displayName: "Running analysis", icon: Code },
|
|
55994
56654
|
run_sql_query_tool: { displayName: "Running SQL query", icon: Database, describer: (a) => a.sql_query ?? a.query ?? a.sql ? `"${truncateLine(a.sql_query ?? a.query ?? a.sql)}"` : "" },
|
|
@@ -56036,14 +56696,14 @@ function extractResultMessage(result) {
|
|
|
56036
56696
|
return null;
|
|
56037
56697
|
}
|
|
56038
56698
|
function isResultSuccess(result) {
|
|
56039
|
-
|
|
56040
|
-
|
|
56041
|
-
if (
|
|
56042
|
-
|
|
56043
|
-
|
|
56044
|
-
return result.success === true;
|
|
56699
|
+
const obj = typeof result === "string" ? tryParseJson$1(result) : typeof result === "object" && result !== null ? result : null;
|
|
56700
|
+
if (obj) {
|
|
56701
|
+
if (obj.success === false || obj.ok === false) return false;
|
|
56702
|
+
if (typeof obj.error === "string" && obj.error.length > 0) return false;
|
|
56703
|
+
return true;
|
|
56045
56704
|
}
|
|
56046
|
-
return
|
|
56705
|
+
if (typeof result === "string") return !/^\s*error\b/i.test(result);
|
|
56706
|
+
return true;
|
|
56047
56707
|
}
|
|
56048
56708
|
function extractAssetId$1(result) {
|
|
56049
56709
|
if (!result) return null;
|
|
@@ -56208,7 +56868,7 @@ function ToolFallbackTrigger({
|
|
|
56208
56868
|
"span",
|
|
56209
56869
|
{
|
|
56210
56870
|
className: cn(
|
|
56211
|
-
"relative inline-block leading-tight",
|
|
56871
|
+
"relative inline-block text-[13px] font-medium leading-tight",
|
|
56212
56872
|
isCancelled && "text-muted-foreground line-through"
|
|
56213
56873
|
),
|
|
56214
56874
|
children: [
|
|
@@ -57193,17 +57853,103 @@ BrowseToolUI.displayName = "BrowseToolUI";
|
|
|
57193
57853
|
function parseEmailResults(data) {
|
|
57194
57854
|
const results = data.limited_results ?? data.results ?? data.emails ?? data.messages;
|
|
57195
57855
|
if (!Array.isArray(results)) return [];
|
|
57196
|
-
return results.slice(0,
|
|
57197
|
-
const item = r2;
|
|
57198
|
-
return
|
|
57199
|
-
|
|
57200
|
-
|
|
57201
|
-
|
|
57202
|
-
|
|
57203
|
-
|
|
57204
|
-
|
|
57856
|
+
return results.slice(0, 50).flatMap((r2) => {
|
|
57857
|
+
const item = asRecord(r2);
|
|
57858
|
+
if (!item) return [];
|
|
57859
|
+
return [
|
|
57860
|
+
{
|
|
57861
|
+
subject: asString(item.subject) ?? asString(item.title),
|
|
57862
|
+
from: asString(item.from) ?? asString(item.sender) ?? asString(item.from_email),
|
|
57863
|
+
date: asString(item.date) ?? asString(item.received_at) ?? asString(item.sent_at),
|
|
57864
|
+
snippet: asString(item.snippet) ?? asString(item.preview) ?? asString(item.body_preview),
|
|
57865
|
+
isDraft: item.is_draft === true
|
|
57866
|
+
}
|
|
57867
|
+
];
|
|
57205
57868
|
});
|
|
57206
57869
|
}
|
|
57870
|
+
function formatEmailDate(raw) {
|
|
57871
|
+
if (!raw) return void 0;
|
|
57872
|
+
const dateOnly = /^(\d{4})-(\d{2})-(\d{2})$/.exec(raw.trim());
|
|
57873
|
+
const date2 = dateOnly ? new Date(Number(dateOnly[1]), Number(dateOnly[2]) - 1, Number(dateOnly[3])) : new Date(raw);
|
|
57874
|
+
if (Number.isNaN(date2.getTime())) return raw;
|
|
57875
|
+
const now = /* @__PURE__ */ new Date();
|
|
57876
|
+
if (!dateOnly && date2.toDateString() === now.toDateString()) {
|
|
57877
|
+
return date2.toLocaleTimeString(void 0, {
|
|
57878
|
+
hour: "numeric",
|
|
57879
|
+
minute: "2-digit"
|
|
57880
|
+
});
|
|
57881
|
+
}
|
|
57882
|
+
const sameYear = date2.getFullYear() === now.getFullYear();
|
|
57883
|
+
return date2.toLocaleDateString(void 0, {
|
|
57884
|
+
month: "short",
|
|
57885
|
+
day: "numeric",
|
|
57886
|
+
...sameYear ? {} : { year: "numeric" }
|
|
57887
|
+
});
|
|
57888
|
+
}
|
|
57889
|
+
const EMAIL_QUERY_OPERATOR = /(?:^|\s)(received|after|before|from|to|subject|has|in|is):(?:"([^"]+)"|(\S+))/gi;
|
|
57890
|
+
function humanEmailDate(raw) {
|
|
57891
|
+
return formatEmailDate(raw.replace(/\//g, "-")) ?? raw;
|
|
57892
|
+
}
|
|
57893
|
+
function humanizeEmailQuery(query) {
|
|
57894
|
+
if (!query.trim()) return "";
|
|
57895
|
+
const phrases = [];
|
|
57896
|
+
let freeText = query;
|
|
57897
|
+
for (const match2 of query.matchAll(EMAIL_QUERY_OPERATOR)) {
|
|
57898
|
+
const [token, op, quoted, bare] = match2;
|
|
57899
|
+
const value = quoted ?? bare ?? "";
|
|
57900
|
+
freeText = freeText.replace(token, " ");
|
|
57901
|
+
switch (op.toLowerCase()) {
|
|
57902
|
+
case "received": {
|
|
57903
|
+
const [start, end] = value.split("..");
|
|
57904
|
+
phrases.push(
|
|
57905
|
+
end ? `${humanEmailDate(start)} – ${humanEmailDate(end)}` : humanEmailDate(start)
|
|
57906
|
+
);
|
|
57907
|
+
break;
|
|
57908
|
+
}
|
|
57909
|
+
case "after":
|
|
57910
|
+
phrases.push(`after ${humanEmailDate(value)}`);
|
|
57911
|
+
break;
|
|
57912
|
+
case "before":
|
|
57913
|
+
phrases.push(`before ${humanEmailDate(value)}`);
|
|
57914
|
+
break;
|
|
57915
|
+
case "from":
|
|
57916
|
+
phrases.push(`from ${value}`);
|
|
57917
|
+
break;
|
|
57918
|
+
case "to":
|
|
57919
|
+
phrases.push(`to ${value}`);
|
|
57920
|
+
break;
|
|
57921
|
+
case "subject":
|
|
57922
|
+
phrases.push(`subject “${value}”`);
|
|
57923
|
+
break;
|
|
57924
|
+
case "has":
|
|
57925
|
+
phrases.push(value === "attachment" ? "with attachments" : `has ${value}`);
|
|
57926
|
+
break;
|
|
57927
|
+
case "in":
|
|
57928
|
+
phrases.push(value === "drafts" ? "drafts only" : `in ${value}`);
|
|
57929
|
+
break;
|
|
57930
|
+
case "is":
|
|
57931
|
+
phrases.push(value);
|
|
57932
|
+
break;
|
|
57933
|
+
}
|
|
57934
|
+
}
|
|
57935
|
+
const remainder = freeText.trim().replace(/\s+/g, " ");
|
|
57936
|
+
if (remainder) phrases.push(`“${remainder}”`);
|
|
57937
|
+
return phrases.join(" · ");
|
|
57938
|
+
}
|
|
57939
|
+
const INLINE_EMAIL_ROWS = 3;
|
|
57940
|
+
function EmailResultRow({ email: email2 }) {
|
|
57941
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 py-2 first:pt-0 last:pb-0", children: [
|
|
57942
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
57943
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-baseline gap-1.5 text-[12px] font-medium text-foreground", children: [
|
|
57944
|
+
email2.isDraft && /* @__PURE__ */ jsx("span", { className: "shrink-0 rounded bg-amber-100 px-1 py-px text-[9px] font-semibold uppercase tracking-wide text-amber-700", children: "Draft" }),
|
|
57945
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: email2.subject || "No subject" })
|
|
57946
|
+
] }),
|
|
57947
|
+
email2.date && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: formatEmailDate(email2.date) })
|
|
57948
|
+
] }),
|
|
57949
|
+
email2.from && /* @__PURE__ */ jsx("span", { className: "truncate text-[11px] text-muted-foreground", children: email2.from }),
|
|
57950
|
+
email2.snippet && /* @__PURE__ */ jsx("p", { className: "text-[11px] leading-relaxed text-muted-foreground/80", children: truncate(email2.snippet, 150) })
|
|
57951
|
+
] });
|
|
57952
|
+
}
|
|
57207
57953
|
const EmailSearchToolUIImpl = ({
|
|
57208
57954
|
toolName,
|
|
57209
57955
|
args,
|
|
@@ -57214,35 +57960,96 @@ const EmailSearchToolUIImpl = ({
|
|
|
57214
57960
|
const query = (typedArgs == null ? void 0 : typedArgs.query) ?? (typedArgs == null ? void 0 : typedArgs.search_query) ?? "";
|
|
57215
57961
|
const data = useMemo(() => normalizeResult(result), [result]);
|
|
57216
57962
|
const emails = useMemo(() => data ? parseEmailResults(data) : [], [data]);
|
|
57963
|
+
const provider = typeof (data == null ? void 0 : data.provider) === "string" ? data.provider : void 0;
|
|
57964
|
+
const totalCount = typeof (data == null ? void 0 : data.count) === "number" ? data.count : emails.length;
|
|
57217
57965
|
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
57218
57966
|
const isComplete = (status == null ? void 0 : status.type) === "complete";
|
|
57219
57967
|
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
57968
|
+
const readableQuery = useMemo(() => humanizeEmailQuery(query), [query]);
|
|
57969
|
+
const inlineEmails = emails.slice(0, INLINE_EMAIL_ROWS);
|
|
57970
|
+
const overflowEmails = emails.slice(INLINE_EMAIL_ROWS);
|
|
57971
|
+
const countLabel = emails.length > 0 && totalCount > emails.length ? `${emails.length} of ${totalCount}` : `${totalCount}`;
|
|
57220
57972
|
return /* @__PURE__ */ jsx(
|
|
57221
57973
|
ToolCard,
|
|
57222
57974
|
{
|
|
57223
57975
|
icon: Mail,
|
|
57224
57976
|
status: (status == null ? void 0 : status.type) ?? "complete",
|
|
57225
|
-
title: isRunning ? "Searching
|
|
57226
|
-
subtitle:
|
|
57977
|
+
title: isRunning ? "Searching email…" : "Email search",
|
|
57978
|
+
subtitle: readableQuery ? truncate(readableQuery, 90) : void 0,
|
|
57227
57979
|
toolName,
|
|
57228
57980
|
args: typedArgs,
|
|
57229
57981
|
result,
|
|
57230
|
-
badge: isComplete
|
|
57982
|
+
badge: isComplete ? totalCount > 0 ? `${countLabel} email${totalCount === 1 ? "" : "s"}${provider ? ` · ${provider}` : ""}` : "No matches" : void 0,
|
|
57983
|
+
error: errorMsg,
|
|
57984
|
+
children: isComplete && emails.length > 0 && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-4 py-2.5", children: [
|
|
57985
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y divide-border/30", children: inlineEmails.map((email2, i) => /* @__PURE__ */ jsx(EmailResultRow, { email: email2 }, i)) }),
|
|
57986
|
+
overflowEmails.length > 0 && /* @__PURE__ */ jsx(
|
|
57987
|
+
ExpandableSection,
|
|
57988
|
+
{
|
|
57989
|
+
label: `Show ${overflowEmails.length} more`,
|
|
57990
|
+
children: /* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y divide-border/30", children: overflowEmails.map((email2, i) => /* @__PURE__ */ jsx(EmailResultRow, { email: email2 }, i)) })
|
|
57991
|
+
}
|
|
57992
|
+
)
|
|
57993
|
+
] })
|
|
57994
|
+
}
|
|
57995
|
+
);
|
|
57996
|
+
};
|
|
57997
|
+
const EmailSearchToolUI = memo(
|
|
57998
|
+
EmailSearchToolUIImpl
|
|
57999
|
+
);
|
|
58000
|
+
EmailSearchToolUI.displayName = "EmailSearchToolUI";
|
|
58001
|
+
function parseEmailAccounts(data) {
|
|
58002
|
+
const accounts = data.accounts ?? data.results;
|
|
58003
|
+
if (!Array.isArray(accounts)) return [];
|
|
58004
|
+
return accounts.slice(0, 10).flatMap((raw) => {
|
|
58005
|
+
const item = asRecord(raw);
|
|
58006
|
+
if (!item) return [];
|
|
58007
|
+
const defaultFlag = typeof item.is_default === "boolean" ? item.is_default : item.default;
|
|
58008
|
+
return [
|
|
58009
|
+
{
|
|
58010
|
+
address: asString(item.email_address) ?? asString(item.email) ?? asString(item.address),
|
|
58011
|
+
provider: asString(item.provider) ?? asString(item.provider_name),
|
|
58012
|
+
name: asString(item.account_name) ?? asString(item.name),
|
|
58013
|
+
isDefault: defaultFlag === true
|
|
58014
|
+
}
|
|
58015
|
+
];
|
|
58016
|
+
});
|
|
58017
|
+
}
|
|
58018
|
+
const EmailAccountsToolUIImpl = ({
|
|
58019
|
+
toolName,
|
|
58020
|
+
args,
|
|
58021
|
+
result,
|
|
58022
|
+
status
|
|
58023
|
+
}) => {
|
|
58024
|
+
const data = useMemo(() => normalizeResult(result), [result]);
|
|
58025
|
+
const accounts = useMemo(
|
|
58026
|
+
() => data ? parseEmailAccounts(data) : [],
|
|
58027
|
+
[data]
|
|
58028
|
+
);
|
|
58029
|
+
const isRunning = (status == null ? void 0 : status.type) === "running";
|
|
58030
|
+
const isComplete = (status == null ? void 0 : status.type) === "complete";
|
|
58031
|
+
const errorMsg = (status == null ? void 0 : status.type) === "incomplete" ? status.error : null;
|
|
58032
|
+
return /* @__PURE__ */ jsx(
|
|
58033
|
+
ToolCard,
|
|
58034
|
+
{
|
|
58035
|
+
icon: Mail,
|
|
58036
|
+
status: (status == null ? void 0 : status.type) ?? "complete",
|
|
58037
|
+
title: isRunning ? "Checking connected email accounts…" : "Email accounts",
|
|
58038
|
+
toolName,
|
|
58039
|
+
args,
|
|
58040
|
+
result,
|
|
58041
|
+
badge: isComplete && accounts.length > 0 ? `${accounts.length} connected` : void 0,
|
|
57231
58042
|
error: errorMsg,
|
|
57232
|
-
children: isComplete &&
|
|
58043
|
+
children: isComplete && accounts.length > 0 && /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 px-4 py-2.5", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col divide-y divide-border/30", children: accounts.map((account, i) => /* @__PURE__ */ jsxs(
|
|
57233
58044
|
"div",
|
|
57234
58045
|
{
|
|
57235
|
-
className:
|
|
58046
|
+
className: "flex items-center justify-between gap-2 py-1.5 first:pt-0 last:pb-0",
|
|
57236
58047
|
children: [
|
|
57237
|
-
/* @__PURE__ */
|
|
57238
|
-
|
|
57239
|
-
|
|
57240
|
-
|
|
57241
|
-
|
|
57242
|
-
email2.date && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: email2.date })
|
|
57243
|
-
] }),
|
|
57244
|
-
email2.from && /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground", children: email2.from }),
|
|
57245
|
-
email2.snippet && /* @__PURE__ */ jsx("p", { className: "text-[11px] leading-relaxed text-muted-foreground/80", children: truncate(email2.snippet, 150) })
|
|
58048
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-[12px] text-foreground", children: account.address || account.name || "Unknown account" }),
|
|
58049
|
+
/* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
58050
|
+
account.isDefault && /* @__PURE__ */ jsx("span", { className: "rounded-full bg-emerald-50 px-1.5 py-px text-[9px] font-semibold uppercase tracking-wide text-emerald-700", children: "Default" }),
|
|
58051
|
+
account.provider && /* @__PURE__ */ jsx("span", { className: "rounded-md bg-muted/60 px-1.5 py-0.5 text-[10px] text-muted-foreground", children: account.provider })
|
|
58052
|
+
] })
|
|
57246
58053
|
]
|
|
57247
58054
|
},
|
|
57248
58055
|
i
|
|
@@ -57250,10 +58057,10 @@ const EmailSearchToolUIImpl = ({
|
|
|
57250
58057
|
}
|
|
57251
58058
|
);
|
|
57252
58059
|
};
|
|
57253
|
-
const
|
|
57254
|
-
|
|
58060
|
+
const EmailAccountsToolUI = memo(
|
|
58061
|
+
EmailAccountsToolUIImpl
|
|
57255
58062
|
);
|
|
57256
|
-
|
|
58063
|
+
EmailAccountsToolUI.displayName = "EmailAccountsToolUI";
|
|
57257
58064
|
function extractAssetId(result) {
|
|
57258
58065
|
const data = normalizeResult(result);
|
|
57259
58066
|
if (!data) return null;
|
|
@@ -57290,6 +58097,9 @@ function asRecord(value) {
|
|
|
57290
58097
|
}
|
|
57291
58098
|
return value;
|
|
57292
58099
|
}
|
|
58100
|
+
function asString(value) {
|
|
58101
|
+
return typeof value === "string" ? value : void 0;
|
|
58102
|
+
}
|
|
57293
58103
|
const PRESENTATION_CODE_SLIDE_NUMBER_KEYS = [
|
|
57294
58104
|
"slideNumber",
|
|
57295
58105
|
"slide_number",
|
|
@@ -57386,22 +58196,51 @@ function CreateAssetToolUIImpl({
|
|
|
57386
58196
|
args: typedArgs,
|
|
57387
58197
|
result,
|
|
57388
58198
|
error: errorMsg,
|
|
57389
|
-
children: assetId && isComplete && !isCancelled && /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 px-4 py-2", children: /* @__PURE__ */ jsxs(
|
|
58199
|
+
children: assetId && isComplete && !isCancelled && /* @__PURE__ */ jsx("div", { className: "border-t border-border/40 px-4 py-2.5", children: /* @__PURE__ */ jsxs(
|
|
57390
58200
|
"button",
|
|
57391
58201
|
{
|
|
57392
58202
|
type: "button",
|
|
57393
58203
|
onClick: handleOpen,
|
|
57394
|
-
className: "flex items-center gap-
|
|
58204
|
+
className: "group flex w-full items-center gap-3 rounded-lg border border-border/60 bg-muted/20 px-3 py-2.5 text-left transition-colors hover:border-border hover:bg-muted/40",
|
|
57395
58205
|
children: [
|
|
57396
|
-
/* @__PURE__ */ jsx(
|
|
57397
|
-
|
|
57398
|
-
|
|
58206
|
+
/* @__PURE__ */ jsx(
|
|
58207
|
+
"div",
|
|
58208
|
+
{
|
|
58209
|
+
className: cn(
|
|
58210
|
+
"flex size-10 shrink-0 items-center justify-center rounded-lg",
|
|
58211
|
+
ASSET_TILE_STYLE[assetType] ?? ASSET_TILE_STYLE.unknown
|
|
58212
|
+
),
|
|
58213
|
+
children: /* @__PURE__ */ jsx(Icon2, { className: "size-5" })
|
|
58214
|
+
}
|
|
58215
|
+
),
|
|
58216
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
58217
|
+
/* @__PURE__ */ jsx("div", { className: "truncate text-[13px] font-medium text-foreground", children: createdName || name || "Untitled" }),
|
|
58218
|
+
/* @__PURE__ */ jsxs("div", { className: "text-[11px] text-muted-foreground", children: [
|
|
58219
|
+
ASSET_TILE_LABEL[assetType] ?? "Asset",
|
|
58220
|
+
" · Click to open"
|
|
58221
|
+
] })
|
|
58222
|
+
] }),
|
|
58223
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "size-3.5 shrink-0 text-muted-foreground opacity-0 transition-opacity group-hover:opacity-100" })
|
|
57399
58224
|
]
|
|
57400
58225
|
}
|
|
57401
58226
|
) })
|
|
57402
58227
|
}
|
|
57403
58228
|
);
|
|
57404
58229
|
}
|
|
58230
|
+
const ASSET_TILE_STYLE = {
|
|
58231
|
+
document: "bg-blue-500/10 text-blue-600",
|
|
58232
|
+
spreadsheet: "bg-emerald-500/10 text-emerald-600",
|
|
58233
|
+
presentation: "bg-orange-500/10 text-orange-600",
|
|
58234
|
+
notebook: "bg-violet-500/10 text-violet-600",
|
|
58235
|
+
unknown: "bg-muted text-muted-foreground"
|
|
58236
|
+
};
|
|
58237
|
+
const ASSET_TILE_LABEL = {
|
|
58238
|
+
document: "Document",
|
|
58239
|
+
spreadsheet: "Spreadsheet",
|
|
58240
|
+
presentation: "Presentation",
|
|
58241
|
+
notebook: "Notebook",
|
|
58242
|
+
unknown: "Asset"
|
|
58243
|
+
};
|
|
57405
58244
|
const CreateDocumentToolUIImpl = (props) => /* @__PURE__ */ jsx(
|
|
57406
58245
|
CreateAssetToolUIImpl,
|
|
57407
58246
|
{
|
|
@@ -59824,6 +60663,8 @@ const TOOL_UI_REGISTRY = {
|
|
|
59824
60663
|
open_browser: OpenBrowserToolUI,
|
|
59825
60664
|
search_email: EmailSearchToolUI,
|
|
59826
60665
|
unified_email_search: EmailSearchToolUI,
|
|
60666
|
+
unified_email_list_accounts: EmailAccountsToolUI,
|
|
60667
|
+
email_list_accounts: EmailAccountsToolUI,
|
|
59827
60668
|
create_email_draft: CreateEmailDraftToolUI,
|
|
59828
60669
|
unified_email_create_draft: CreateEmailDraftToolUI,
|
|
59829
60670
|
create_new_document: CreateDocumentToolUI,
|
|
@@ -59879,13 +60720,13 @@ const TOOLKIT_THEMES = {
|
|
|
59879
60720
|
};
|
|
59880
60721
|
const DEFAULT_THEME = { color: "#919EAB" };
|
|
59881
60722
|
const CollapsibleGroup = ({ groupKey, indices, children }) => {
|
|
59882
|
-
const isMessageRunning = useAuiState((s) => {
|
|
60723
|
+
const isMessageRunning = useAuiState$1((s) => {
|
|
59883
60724
|
var _a3;
|
|
59884
60725
|
return ((_a3 = s.message.status) == null ? void 0 : _a3.type) === "running";
|
|
59885
60726
|
});
|
|
59886
60727
|
const [userOpened, setOpen] = useState();
|
|
59887
60728
|
const open = userOpened ?? isMessageRunning;
|
|
59888
|
-
const toolCallCount = useAuiState((s) => {
|
|
60729
|
+
const toolCallCount = useAuiState$1((s) => {
|
|
59889
60730
|
if (s.message.role !== "assistant") return 0;
|
|
59890
60731
|
const parts = s.message.content;
|
|
59891
60732
|
if (!parts) return 0;
|
|
@@ -60158,8 +60999,8 @@ function PulsingDots() {
|
|
|
60158
60999
|
const SuperGroupingFinalText = memo(function SuperGroupingFinalText2({
|
|
60159
61000
|
TextComponent
|
|
60160
61001
|
}) {
|
|
60161
|
-
const messageContent = useAuiState((s) => s.message.content);
|
|
60162
|
-
const isRunning = useAuiState((s) => {
|
|
61002
|
+
const messageContent = useAuiState$1((s) => s.message.content);
|
|
61003
|
+
const isRunning = useAuiState$1((s) => {
|
|
60163
61004
|
var _a3;
|
|
60164
61005
|
return ((_a3 = s.message.status) == null ? void 0 : _a3.type) === "running";
|
|
60165
61006
|
});
|
|
@@ -60189,7 +61030,7 @@ const SuperGroupingCard = memo(function SuperGroupingCard2({
|
|
|
60189
61030
|
ReasoningComponent,
|
|
60190
61031
|
getToolGroupKey = defaultGetToolGroupKey
|
|
60191
61032
|
}) {
|
|
60192
|
-
const messageId = useAuiState((s) => s.message.id);
|
|
61033
|
+
const messageId = useAuiState$1((s) => s.message.id);
|
|
60193
61034
|
const [showDetails, setShowDetails] = useState(() => expandedMessageIds.has(messageId));
|
|
60194
61035
|
const handleToggleDetails = useCallback(() => {
|
|
60195
61036
|
setShowDetails((prev) => {
|
|
@@ -60214,7 +61055,7 @@ const SuperGroupingCard = memo(function SuperGroupingCard2({
|
|
|
60214
61055
|
expandedMessageIds.delete(messageId);
|
|
60215
61056
|
};
|
|
60216
61057
|
}, [messageId, showDetails]);
|
|
60217
|
-
const messageStatus = useAuiState((s) => {
|
|
61058
|
+
const messageStatus = useAuiState$1((s) => {
|
|
60218
61059
|
var _a3;
|
|
60219
61060
|
return (_a3 = s.message.status) == null ? void 0 : _a3.type;
|
|
60220
61061
|
});
|
|
@@ -60234,7 +61075,7 @@ const SuperGroupingCard = memo(function SuperGroupingCard2({
|
|
|
60234
61075
|
})).filter((g) => g.indices.length > 0);
|
|
60235
61076
|
};
|
|
60236
61077
|
}, [getToolGroupKey]);
|
|
60237
|
-
const messageContent = useAuiState((s) => s.message.content);
|
|
61078
|
+
const messageContent = useAuiState$1((s) => s.message.content);
|
|
60238
61079
|
const toolStatuses = useMemo(() => {
|
|
60239
61080
|
if (!messageContent) return EMPTY_STATUSES;
|
|
60240
61081
|
const statuses = [];
|
|
@@ -60582,7 +61423,7 @@ function useSendMessage() {
|
|
|
60582
61423
|
shouldReplace || !currentText ? text2 : `${currentText}
|
|
60583
61424
|
${text2}`
|
|
60584
61425
|
);
|
|
60585
|
-
await aui.composer.send();
|
|
61426
|
+
await aui.composer.send({ steer: false });
|
|
60586
61427
|
},
|
|
60587
61428
|
[aui]
|
|
60588
61429
|
);
|
|
@@ -61113,7 +61954,7 @@ const useScrollToTop = () => {
|
|
|
61113
61954
|
};
|
|
61114
61955
|
const ThreadScrollToTop = () => {
|
|
61115
61956
|
const { isAtTop, containerRef, handleClick: handleClick2 } = useScrollToTop();
|
|
61116
|
-
const isEmpty3 = useAuiState((s) => s.thread.isEmpty);
|
|
61957
|
+
const isEmpty3 = useAuiState$1((s) => s.thread.isEmpty);
|
|
61117
61958
|
if (isEmpty3) return null;
|
|
61118
61959
|
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
61960
|
TooltipIconButton,
|
|
@@ -61164,7 +62005,7 @@ const ComposerSendWithQuote = () => {
|
|
|
61164
62005
|
const { attachments, clearAttachments, isUploading } = useAttachments();
|
|
61165
62006
|
const editorRef = useComposerEditorRef();
|
|
61166
62007
|
const editorEmpty = useComposerEditorEmpty();
|
|
61167
|
-
const isRunningThread = useAuiState((s) => s.thread.isRunning);
|
|
62008
|
+
const isRunningThread = useAuiState$1((s) => s.thread.isRunning);
|
|
61168
62009
|
const isThreadRunning = allowsMidRunSend(transport) ? false : isRunningThread;
|
|
61169
62010
|
const hasExtras = !!quote || attachments.length > 0;
|
|
61170
62011
|
const handleSend = useCallback(() => {
|
|
@@ -61182,13 +62023,13 @@ const ComposerSendWithQuote = () => {
|
|
|
61182
62023
|
});
|
|
61183
62024
|
if (!fullMessage) return;
|
|
61184
62025
|
aui.composer.setText(fullMessage);
|
|
61185
|
-
aui.composer.send();
|
|
62026
|
+
aui.composer.send({ steer: false });
|
|
61186
62027
|
clearQuote();
|
|
61187
62028
|
clearAttachments();
|
|
61188
62029
|
} else {
|
|
61189
62030
|
if (!userText) return;
|
|
61190
62031
|
aui.composer.setText(userText);
|
|
61191
|
-
aui.composer.send();
|
|
62032
|
+
aui.composer.send({ steer: false });
|
|
61192
62033
|
}
|
|
61193
62034
|
editor == null ? void 0 : editor.clear();
|
|
61194
62035
|
}, [aui, quote, attachments, hasExtras, isUploading, isThreadRunning, clearQuote, clearAttachments, editorRef, appUrl]);
|
|
@@ -61228,8 +62069,8 @@ const AthenaAssistantMessageEmpty = ({ status }) => {
|
|
|
61228
62069
|
const AthenaMessageEmptyIndicator = ({
|
|
61229
62070
|
EmptyComponent: EmptyComponent2
|
|
61230
62071
|
}) => {
|
|
61231
|
-
const hasParts = useAuiState((s) => s.message.parts.length > 0);
|
|
61232
|
-
const isRunning = useAuiState((s) => {
|
|
62072
|
+
const hasParts = useAuiState$1((s) => s.message.parts.length > 0);
|
|
62073
|
+
const isRunning = useAuiState$1((s) => {
|
|
61233
62074
|
var _a3;
|
|
61234
62075
|
return ((_a3 = s.message.status) == null ? void 0 : _a3.type) === "running";
|
|
61235
62076
|
});
|
|
@@ -61243,11 +62084,11 @@ const AthenaReasoningPart = ({
|
|
|
61243
62084
|
}) => {
|
|
61244
62085
|
const inheritedTextComponent = useContext(AthenaReasoningTextComponentContext);
|
|
61245
62086
|
const EffectiveTextComponent = TextComponent ?? inheritedTextComponent ?? TiptapText;
|
|
61246
|
-
const isMessageRunning = useAuiState((state) => {
|
|
62087
|
+
const isMessageRunning = useAuiState$1((state) => {
|
|
61247
62088
|
var _a3;
|
|
61248
62089
|
return ((_a3 = state.message.status) == null ? void 0 : _a3.type) === "running";
|
|
61249
62090
|
});
|
|
61250
|
-
const reasoningTokens = useAuiState(
|
|
62091
|
+
const reasoningTokens = useAuiState$1(
|
|
61251
62092
|
(state) => getReasoningTokensFromMetadata(state.message.metadata)
|
|
61252
62093
|
);
|
|
61253
62094
|
const isRunning = isMessageRunning || (status == null ? void 0 : status.type) === "running";
|
|
@@ -62419,6 +63260,8 @@ function useComposerAttachment() {
|
|
|
62419
63260
|
return { addFile, addContent, clear };
|
|
62420
63261
|
}
|
|
62421
63262
|
export {
|
|
63263
|
+
ATHENA_REACT_SDK_VERSION,
|
|
63264
|
+
ATHENA_SDK_ERROR_CODES,
|
|
62422
63265
|
ATHENA_TRANSPORTS,
|
|
62423
63266
|
AppendDocumentToolUI,
|
|
62424
63267
|
AssetPanel,
|
|
@@ -62429,10 +63272,12 @@ export {
|
|
|
62429
63272
|
AthenaLayout,
|
|
62430
63273
|
AthenaProvider,
|
|
62431
63274
|
AthenaReasoningPart,
|
|
63275
|
+
AthenaSdkError,
|
|
62432
63276
|
AthenaThreadIdContext,
|
|
62433
63277
|
AthenaUserMessage,
|
|
62434
63278
|
BrowseToolUI,
|
|
62435
63279
|
Button,
|
|
63280
|
+
COLLAB_AGENT_REF_PREFIX,
|
|
62436
63281
|
Collapsible,
|
|
62437
63282
|
CollapsibleContent,
|
|
62438
63283
|
CollapsibleTrigger,
|
|
@@ -62492,6 +63337,7 @@ export {
|
|
|
62492
63337
|
allowsMidRunSend,
|
|
62493
63338
|
archiveThread,
|
|
62494
63339
|
asHitlApproval,
|
|
63340
|
+
athenaDiagnostics,
|
|
62495
63341
|
athenaStatewireErrorNotice,
|
|
62496
63342
|
autoCloseInFlightSubgraphMessages,
|
|
62497
63343
|
buildCoalescedCaptureProperties,
|
|
@@ -62515,13 +63361,17 @@ export {
|
|
|
62515
63361
|
getPosthogCaptureGate,
|
|
62516
63362
|
getThreadState,
|
|
62517
63363
|
hasStatewireThreadExtras,
|
|
63364
|
+
installAthenaDiagnosticsGlobal,
|
|
62518
63365
|
isAthenaCitationUrl,
|
|
63366
|
+
isAthenaSdkError,
|
|
62519
63367
|
isCriticalPosthogEvent,
|
|
62520
63368
|
isPendingInterrupt,
|
|
62521
63369
|
listThreads,
|
|
62522
63370
|
normalizeResult,
|
|
62523
63371
|
parseAthenaCitationLink,
|
|
63372
|
+
parseCollabAgentRef,
|
|
62524
63373
|
readInterruptMessage,
|
|
63374
|
+
readRejectionDetail,
|
|
62525
63375
|
resetAssetAutoOpen,
|
|
62526
63376
|
resolveAthenaTransport,
|
|
62527
63377
|
resolveStatewireSyncUrl,
|
|
@@ -62529,6 +63379,7 @@ export {
|
|
|
62529
63379
|
statewireClientToolWireEntries,
|
|
62530
63380
|
themeToStyleVars,
|
|
62531
63381
|
themes,
|
|
63382
|
+
toAthenaSdkError,
|
|
62532
63383
|
truncate,
|
|
62533
63384
|
tryParseJson$2 as tryParseJson,
|
|
62534
63385
|
useAppendToComposer,
|
|
@@ -62536,6 +63387,7 @@ export {
|
|
|
62536
63387
|
useAssetPanelStore,
|
|
62537
63388
|
useAthenaCitationLinkHandler,
|
|
62538
63389
|
useAthenaConfig,
|
|
63390
|
+
useAthenaDiagnostics,
|
|
62539
63391
|
useAthenaLinkClickHandler,
|
|
62540
63392
|
useAthenaRuntime,
|
|
62541
63393
|
useAthenaStatewireLifecycle,
|