@athenaintel/react 0.12.3 → 0.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat/AthenaChatErrorBoundary.d.ts +27 -0
- package/dist/chat/StatewireApprovalCard.d.ts +19 -1
- package/dist/chat/StatewireClientToolBridge.d.ts +4 -0
- package/dist/chat/statewire-approval.d.ts +5 -33
- package/dist/collab/client.d.ts +12 -0
- package/dist/collab/react.d.ts +6 -0
- package/dist/collab.cjs +60 -3
- package/dist/collab.cjs.map +1 -1
- package/dist/collab.js +60 -3
- package/dist/collab.js.map +1 -1
- package/dist/diagnostics/errors.d.ts +2 -0
- package/dist/index.cjs +825 -293
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +849 -317
- package/dist/index.js.map +1 -1
- package/dist/lib/posthog/before-send.d.ts +9 -0
- package/dist/runtime/useAthenaStatewireRuntime.d.ts +5 -5
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -45,7 +45,6 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
45
45
|
const React = require("react");
|
|
46
46
|
const react$1 = require("@assistant-ui/react");
|
|
47
47
|
const AthenaAuthContext = require("./AthenaAuthContext-B3AwLA5Z.cjs");
|
|
48
|
-
const localStorage$1 = require("@assistant-ui/react-statewire/local-storage");
|
|
49
48
|
const tap = require("@assistant-ui/tap");
|
|
50
49
|
const statewire = require("statewire");
|
|
51
50
|
require("@assistant-ui/core");
|
|
@@ -73,11 +72,64 @@ function _interopNamespaceDefault(e) {
|
|
|
73
72
|
}
|
|
74
73
|
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
75
74
|
const ReactDOM__namespace = /* @__PURE__ */ _interopNamespaceDefault(ReactDOM);
|
|
76
|
-
const version$1 = "0.12.
|
|
75
|
+
const version$1 = "0.12.4";
|
|
77
76
|
const packageJson = {
|
|
78
77
|
version: version$1
|
|
79
78
|
};
|
|
80
79
|
const ATHENA_REACT_SDK_VERSION = packageJson.version;
|
|
80
|
+
const BENIGN_BROWSER_EXCEPTION_SIGNATURES = /* @__PURE__ */ new Set([
|
|
81
|
+
"TypeError: Failed to fetch",
|
|
82
|
+
// fetch — Chromium
|
|
83
|
+
"TypeError: Load failed",
|
|
84
|
+
// fetch — Safari / WebKit
|
|
85
|
+
"TypeError: NetworkError when attempting to fetch resource.",
|
|
86
|
+
// fetch — Firefox
|
|
87
|
+
"AxiosError: Network Error",
|
|
88
|
+
// axios — no response received
|
|
89
|
+
"Error: ResizeObserver loop limit exceeded",
|
|
90
|
+
// Chromium
|
|
91
|
+
"Error: ResizeObserver loop completed with undelivered notifications.",
|
|
92
|
+
// Safari / Firefox
|
|
93
|
+
"TimeoutError: signal timed out",
|
|
94
|
+
// AbortSignal.timeout() on handled requests
|
|
95
|
+
"NegotiationError: negotiation timed out"
|
|
96
|
+
// WebRTC negotiation on flaky networks
|
|
97
|
+
]);
|
|
98
|
+
const BENIGN_MESSAGE_PATTERNS = [
|
|
99
|
+
// assistant-ui useClientLookup recoverable races — the library retries.
|
|
100
|
+
/\(ignore if recovered\)$/,
|
|
101
|
+
// Drift-proof ResizeObserver loop diagnostics across engines.
|
|
102
|
+
/^ResizeObserver loop /
|
|
103
|
+
];
|
|
104
|
+
const FORMULA_ERROR_CODE_TYPE_PATTERN = /^#[A-Z0-9/_]{1,14}[!?]?$/;
|
|
105
|
+
function isBenignBrowserExceptionEntry(exception) {
|
|
106
|
+
var _a3, _b2;
|
|
107
|
+
const type = (_a3 = exception.type) == null ? void 0 : _a3.trim();
|
|
108
|
+
const value = (_b2 = exception.value) == null ? void 0 : _b2.trim();
|
|
109
|
+
if (type === "AggregateError" && !value) return true;
|
|
110
|
+
if (type !== void 0 && FORMULA_ERROR_CODE_TYPE_PATTERN.test(type)) return true;
|
|
111
|
+
if (type === void 0 || value === void 0) return false;
|
|
112
|
+
if (BENIGN_BROWSER_EXCEPTION_SIGNATURES.has(`${type}: ${value}`)) return true;
|
|
113
|
+
return BENIGN_MESSAGE_PATTERNS.some((pattern) => pattern.test(value));
|
|
114
|
+
}
|
|
115
|
+
function isBenignBrowserException(captureResult) {
|
|
116
|
+
var _a3, _b2, _c2;
|
|
117
|
+
if (captureResult.event !== "$exception") return false;
|
|
118
|
+
const exceptionList = (_a3 = captureResult.properties) == null ? void 0 : _a3.$exception_list;
|
|
119
|
+
if (Array.isArray(exceptionList) && exceptionList.length > 0) {
|
|
120
|
+
return exceptionList.every(isBenignBrowserExceptionEntry);
|
|
121
|
+
}
|
|
122
|
+
return isBenignBrowserExceptionEntry({
|
|
123
|
+
type: (_b2 = captureResult.properties) == null ? void 0 : _b2.$exception_type,
|
|
124
|
+
value: (_c2 = captureResult.properties) == null ? void 0 : _c2.$exception_message
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
const dropBenignBrowserExceptions = (captureResult) => {
|
|
128
|
+
if (captureResult && isBenignBrowserException(captureResult)) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
return captureResult;
|
|
132
|
+
};
|
|
81
133
|
const DEFAULT_CAPTURE_GATE_CONFIG = {
|
|
82
134
|
globalMaxPerWindow: 50,
|
|
83
135
|
globalWindowMs: 1e4,
|
|
@@ -486,6 +538,7 @@ async function initializePostHog(apiKey, host, debug) {
|
|
|
486
538
|
posthog.init(apiKey, {
|
|
487
539
|
api_host: host,
|
|
488
540
|
autocapture: true,
|
|
541
|
+
before_send: dropBenignBrowserExceptions,
|
|
489
542
|
capture_pageview: false,
|
|
490
543
|
session_recording: {
|
|
491
544
|
recordCrossOriginIframes: true,
|
|
@@ -549,6 +602,8 @@ const ATHENA_SDK_ERROR_CODES = {
|
|
|
549
602
|
stream_failed: "stream_failed",
|
|
550
603
|
/** The selected collab agent / channel was refused by the backend. */
|
|
551
604
|
collab_agent_rejected: "collab_agent_rejected",
|
|
605
|
+
/** A React render error crashed the chat surface (caught by the SDK's error boundary). */
|
|
606
|
+
chat_render_crash: "chat_render_crash",
|
|
552
607
|
/** Anything else. */
|
|
553
608
|
unknown: "unknown"
|
|
554
609
|
};
|
|
@@ -5931,7 +5986,7 @@ const cn = function() {
|
|
|
5931
5986
|
}
|
|
5932
5987
|
return twMerge.mergeString(result);
|
|
5933
5988
|
};
|
|
5934
|
-
function isRecord$
|
|
5989
|
+
function isRecord$3(value) {
|
|
5935
5990
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5936
5991
|
}
|
|
5937
5992
|
var _a$2;
|
|
@@ -10607,10 +10662,10 @@ const autoCloseInFlightSubgraphMessages = (msgs) => {
|
|
|
10607
10662
|
const beginIds = /* @__PURE__ */ new Set();
|
|
10608
10663
|
const endIds = /* @__PURE__ */ new Set();
|
|
10609
10664
|
for (const message of msgs) {
|
|
10610
|
-
if (!isRecord$
|
|
10665
|
+
if (!isRecord$3(message)) continue;
|
|
10611
10666
|
if (message.type === "ai" && Array.isArray(message.tool_calls)) {
|
|
10612
10667
|
for (const toolCall of message.tool_calls) {
|
|
10613
|
-
if (!isRecord$
|
|
10668
|
+
if (!isRecord$3(toolCall)) continue;
|
|
10614
10669
|
const id = toolCall.id;
|
|
10615
10670
|
if (typeof id === "string") beginIds.add(id);
|
|
10616
10671
|
}
|
|
@@ -10672,7 +10727,7 @@ const contentToParts = (content) => {
|
|
|
10672
10727
|
const getNumberAtPath = (value, path) => {
|
|
10673
10728
|
let current = value;
|
|
10674
10729
|
for (const segment of path) {
|
|
10675
|
-
if (!isRecord$
|
|
10730
|
+
if (!isRecord$3(current)) {
|
|
10676
10731
|
return void 0;
|
|
10677
10732
|
}
|
|
10678
10733
|
current = current[segment];
|
|
@@ -10693,7 +10748,7 @@ const buildCustomMetadata = ({
|
|
|
10693
10748
|
}) => {
|
|
10694
10749
|
const customMetadata = additionalKwargs ? { ...additionalKwargs } : {};
|
|
10695
10750
|
const reasoningTokens = extractReasoningTokens({ usageMetadata, responseMetadata });
|
|
10696
|
-
const existingAthenaMetadata = isRecord$
|
|
10751
|
+
const existingAthenaMetadata = isRecord$3(customMetadata._athena) ? customMetadata._athena : void 0;
|
|
10697
10752
|
const athenaMetadata = {
|
|
10698
10753
|
...existingAthenaMetadata ?? {}
|
|
10699
10754
|
};
|
|
@@ -10712,9 +10767,9 @@ const buildCustomMetadata = ({
|
|
|
10712
10767
|
return Object.keys(customMetadata).length > 0 ? customMetadata : void 0;
|
|
10713
10768
|
};
|
|
10714
10769
|
const getSubgraphMessages = (artifact) => {
|
|
10715
|
-
if (!isRecord$
|
|
10770
|
+
if (!isRecord$3(artifact)) return void 0;
|
|
10716
10771
|
const subgraphState = artifact.subgraph_state;
|
|
10717
|
-
if (!isRecord$
|
|
10772
|
+
if (!isRecord$3(subgraphState)) return void 0;
|
|
10718
10773
|
const messages = subgraphState.messages;
|
|
10719
10774
|
return Array.isArray(messages) && messages.length > 0 ? messages : void 0;
|
|
10720
10775
|
};
|
|
@@ -11466,7 +11521,104 @@ const useAthenaRuntime = (config2) => {
|
|
|
11466
11521
|
}, [isExistingThread, runtime, threadId, backendUrl, resolvedStatusApiUrl]);
|
|
11467
11522
|
return runtime;
|
|
11468
11523
|
};
|
|
11524
|
+
const RUN_CONFIG_CUSTOM_KEYS = [
|
|
11525
|
+
"agent",
|
|
11526
|
+
"agent_catalog_asset_ids",
|
|
11527
|
+
"allowed_tab_ids",
|
|
11528
|
+
"app_id",
|
|
11529
|
+
"async_subagents",
|
|
11530
|
+
"catalog_asset_ids",
|
|
11531
|
+
"channel",
|
|
11532
|
+
"client_tools",
|
|
11533
|
+
"collab_agent_id",
|
|
11534
|
+
"collab_channel_id",
|
|
11535
|
+
"compiled_subagents",
|
|
11536
|
+
"declined_toolkit_ids",
|
|
11537
|
+
"deterministic",
|
|
11538
|
+
"device_id",
|
|
11539
|
+
"drive_mounts",
|
|
11540
|
+
"dry_run",
|
|
11541
|
+
"enable_interpreter",
|
|
11542
|
+
"enable_persistent_fs",
|
|
11543
|
+
"enable_sandbox",
|
|
11544
|
+
"enable_skills",
|
|
11545
|
+
"enabled_toolkits",
|
|
11546
|
+
"enabled_tools",
|
|
11547
|
+
"environment",
|
|
11548
|
+
"environment_asset_id",
|
|
11549
|
+
"environment_id",
|
|
11550
|
+
"environment_name",
|
|
11551
|
+
"excluded_middleware",
|
|
11552
|
+
"excluded_tools",
|
|
11553
|
+
"extra_middleware",
|
|
11554
|
+
"frontend_available",
|
|
11555
|
+
"github_identity",
|
|
11556
|
+
"interpreter_max_ptc_calls",
|
|
11557
|
+
"interpreter_mode",
|
|
11558
|
+
"interpreter_ptc",
|
|
11559
|
+
"interpreter_ptc_exclusive",
|
|
11560
|
+
"interpreter_runtime",
|
|
11561
|
+
"interpreter_subagents",
|
|
11562
|
+
"interpreter_timeout_seconds",
|
|
11563
|
+
"interrupt_on",
|
|
11564
|
+
"knowledge_base",
|
|
11565
|
+
"max_tokens",
|
|
11566
|
+
"mcp_server_configs",
|
|
11567
|
+
"mcp_servers",
|
|
11568
|
+
"memory",
|
|
11569
|
+
"middleware",
|
|
11570
|
+
"model",
|
|
11571
|
+
"office_context",
|
|
11572
|
+
"panel_config",
|
|
11573
|
+
"permissions",
|
|
11574
|
+
"recursion_limit",
|
|
11575
|
+
"run_label",
|
|
11576
|
+
"runtime",
|
|
11577
|
+
"sandbox_runtime",
|
|
11578
|
+
"secret_asset_ids",
|
|
11579
|
+
"session_id",
|
|
11580
|
+
"session_tab_id",
|
|
11581
|
+
"session_vm_retention",
|
|
11582
|
+
"skill_asset_ids",
|
|
11583
|
+
"skills",
|
|
11584
|
+
"skip_title_generation",
|
|
11585
|
+
"source_aop_id",
|
|
11586
|
+
"start_channel",
|
|
11587
|
+
"structured_output",
|
|
11588
|
+
"subagents",
|
|
11589
|
+
"system_prompt",
|
|
11590
|
+
"temperature",
|
|
11591
|
+
"tool_description_overrides",
|
|
11592
|
+
"tool_limit_override",
|
|
11593
|
+
"trigger_type",
|
|
11594
|
+
"voice_update_handle",
|
|
11595
|
+
"workbench",
|
|
11596
|
+
"workspace_id"
|
|
11597
|
+
];
|
|
11598
|
+
new Set(
|
|
11599
|
+
RUN_CONFIG_CUSTOM_KEYS
|
|
11600
|
+
);
|
|
11601
|
+
const KNOWN_START_CHANNELS = [
|
|
11602
|
+
"api",
|
|
11603
|
+
"chrome_extension",
|
|
11604
|
+
"default_voice",
|
|
11605
|
+
"email",
|
|
11606
|
+
"mobile_app",
|
|
11607
|
+
"orchestration",
|
|
11608
|
+
"programmatic",
|
|
11609
|
+
"slack",
|
|
11610
|
+
"sms",
|
|
11611
|
+
"task",
|
|
11612
|
+
"teams",
|
|
11613
|
+
"voice",
|
|
11614
|
+
"web"
|
|
11615
|
+
];
|
|
11616
|
+
new Set(
|
|
11617
|
+
KNOWN_START_CHANNELS
|
|
11618
|
+
);
|
|
11469
11619
|
const CLIENT_TOOL_INTERRUPT_SOURCE = "client_tool";
|
|
11620
|
+
const CLIENT_TOOL_RESULT_STATUS_SUCCESS = "success";
|
|
11621
|
+
const CLIENT_TOOL_RESULT_STATUS_ERROR = "error";
|
|
11470
11622
|
function isClientToolCallRequest(value) {
|
|
11471
11623
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
11472
11624
|
const candidate = value;
|
|
@@ -11490,11 +11642,14 @@ function clientToolResultsResumeValue(results) {
|
|
|
11490
11642
|
return { client_tool_results: results };
|
|
11491
11643
|
}
|
|
11492
11644
|
function clientToolSuccessEnvelope(result) {
|
|
11493
|
-
return {
|
|
11645
|
+
return {
|
|
11646
|
+
status: CLIENT_TOOL_RESULT_STATUS_SUCCESS,
|
|
11647
|
+
result: result === void 0 ? null : result
|
|
11648
|
+
};
|
|
11494
11649
|
}
|
|
11495
11650
|
function clientToolErrorEnvelope(error2) {
|
|
11496
11651
|
const message = error2 instanceof Error ? error2.message : typeof error2 === "string" ? error2 : "Client tool execution failed.";
|
|
11497
|
-
return { status:
|
|
11652
|
+
return { status: CLIENT_TOOL_RESULT_STATUS_ERROR, error: message };
|
|
11498
11653
|
}
|
|
11499
11654
|
function createClientToolRequestTracker() {
|
|
11500
11655
|
const handled = /* @__PURE__ */ new Set();
|
|
@@ -11512,6 +11667,170 @@ function createClientToolRequestTracker() {
|
|
|
11512
11667
|
}
|
|
11513
11668
|
};
|
|
11514
11669
|
}
|
|
11670
|
+
const CLIENT_TOOL_WRITE_DECLINED_MESSAGE = "The user declined this edit. Do not retry it; ask the user how to proceed.";
|
|
11671
|
+
function defaultMissingClientToolMessage(toolName) {
|
|
11672
|
+
return `This surface has no tool named '${toolName}'.`;
|
|
11673
|
+
}
|
|
11674
|
+
function clientToolClaimKey(threadId, requestId) {
|
|
11675
|
+
return `${threadId}:${requestId}`;
|
|
11676
|
+
}
|
|
11677
|
+
function jsonSafeClientToolResult(value) {
|
|
11678
|
+
const serialized = JSON.stringify(value);
|
|
11679
|
+
return serialized === void 0 ? null : JSON.parse(serialized);
|
|
11680
|
+
}
|
|
11681
|
+
function isPendingClientToolRequest(request) {
|
|
11682
|
+
if (request.type !== "interrupt" || "response" in request) return false;
|
|
11683
|
+
return isClientToolInterrupt(request.payload);
|
|
11684
|
+
}
|
|
11685
|
+
async function executeClientToolBatch(options) {
|
|
11686
|
+
const {
|
|
11687
|
+
calls,
|
|
11688
|
+
tools,
|
|
11689
|
+
isLive,
|
|
11690
|
+
confirmWrites,
|
|
11691
|
+
writeDeclinedMessage = CLIENT_TOOL_WRITE_DECLINED_MESSAGE,
|
|
11692
|
+
missingToolMessage = defaultMissingClientToolMessage,
|
|
11693
|
+
onCallSettled,
|
|
11694
|
+
onExecutionStart
|
|
11695
|
+
} = options;
|
|
11696
|
+
const registry2 = new Map(tools.map((tool) => [tool.name, tool]));
|
|
11697
|
+
let writesDeclined = false;
|
|
11698
|
+
const writeToolNames = calls.filter((call) => {
|
|
11699
|
+
var _a3;
|
|
11700
|
+
return ((_a3 = registry2.get(call.tool_name)) == null ? void 0 : _a3.requiresWrite) === true;
|
|
11701
|
+
}).map((call) => call.tool_name);
|
|
11702
|
+
if (writeToolNames.length > 0 && confirmWrites) {
|
|
11703
|
+
const decision = await confirmWrites({ writeToolNames });
|
|
11704
|
+
if (decision === "abandoned" || !isLive()) {
|
|
11705
|
+
return null;
|
|
11706
|
+
}
|
|
11707
|
+
writesDeclined = decision === "declined";
|
|
11708
|
+
}
|
|
11709
|
+
onExecutionStart == null ? void 0 : onExecutionStart();
|
|
11710
|
+
const results = {};
|
|
11711
|
+
for (const call of calls) {
|
|
11712
|
+
if (!isLive()) return null;
|
|
11713
|
+
const tool = registry2.get(call.tool_name);
|
|
11714
|
+
let envelope;
|
|
11715
|
+
let status = "success";
|
|
11716
|
+
let errorType;
|
|
11717
|
+
if (!tool) {
|
|
11718
|
+
envelope = clientToolErrorEnvelope(missingToolMessage(call.tool_name));
|
|
11719
|
+
status = "error";
|
|
11720
|
+
errorType = "UnknownClientTool";
|
|
11721
|
+
} else if (tool.requiresWrite === true && writesDeclined) {
|
|
11722
|
+
envelope = clientToolErrorEnvelope(writeDeclinedMessage);
|
|
11723
|
+
status = "declined";
|
|
11724
|
+
} else {
|
|
11725
|
+
try {
|
|
11726
|
+
envelope = clientToolSuccessEnvelope(
|
|
11727
|
+
jsonSafeClientToolResult(
|
|
11728
|
+
await tool.run(clientToolCallArgs(call), {
|
|
11729
|
+
toolCallId: call.interrupt_id
|
|
11730
|
+
})
|
|
11731
|
+
)
|
|
11732
|
+
);
|
|
11733
|
+
} catch (error2) {
|
|
11734
|
+
envelope = clientToolErrorEnvelope(error2);
|
|
11735
|
+
status = "error";
|
|
11736
|
+
errorType = error2 instanceof Error ? error2.name : typeof error2;
|
|
11737
|
+
}
|
|
11738
|
+
}
|
|
11739
|
+
results[call.interrupt_id] = envelope;
|
|
11740
|
+
onCallSettled == null ? void 0 : onCallSettled({
|
|
11741
|
+
toolName: call.tool_name,
|
|
11742
|
+
status,
|
|
11743
|
+
...errorType !== void 0 ? { errorType } : {}
|
|
11744
|
+
});
|
|
11745
|
+
}
|
|
11746
|
+
return isLive() ? results : null;
|
|
11747
|
+
}
|
|
11748
|
+
function useStatewireClientToolBridge(options) {
|
|
11749
|
+
const { threadId, tracker, inputRequests, logLabel = "[AthenaSDK]" } = options;
|
|
11750
|
+
const optionsRef = React.useRef(options);
|
|
11751
|
+
optionsRef.current = options;
|
|
11752
|
+
const pendingRequest = inputRequests == null ? void 0 : inputRequests.find(isPendingClientToolRequest);
|
|
11753
|
+
const ownedClaimsRef = React.useRef(/* @__PURE__ */ new Set());
|
|
11754
|
+
const startedClaimsRef = React.useRef(/* @__PURE__ */ new Set());
|
|
11755
|
+
const activeRef = React.useRef(true);
|
|
11756
|
+
const releaseClaim = React.useCallback(
|
|
11757
|
+
(claim) => {
|
|
11758
|
+
const owned = ownedClaimsRef.current.delete(claim);
|
|
11759
|
+
startedClaimsRef.current.delete(claim);
|
|
11760
|
+
if (owned) tracker.release(claim);
|
|
11761
|
+
},
|
|
11762
|
+
[tracker]
|
|
11763
|
+
);
|
|
11764
|
+
React.useEffect(() => {
|
|
11765
|
+
activeRef.current = true;
|
|
11766
|
+
const ownedClaims = ownedClaimsRef.current;
|
|
11767
|
+
const startedClaims = startedClaimsRef.current;
|
|
11768
|
+
return () => {
|
|
11769
|
+
activeRef.current = false;
|
|
11770
|
+
for (const claim of ownedClaims) {
|
|
11771
|
+
if (startedClaims.has(claim)) continue;
|
|
11772
|
+
ownedClaims.delete(claim);
|
|
11773
|
+
tracker.release(claim);
|
|
11774
|
+
}
|
|
11775
|
+
};
|
|
11776
|
+
}, [tracker]);
|
|
11777
|
+
const liveRequestIdsRef = React.useRef(/* @__PURE__ */ new Set());
|
|
11778
|
+
liveRequestIdsRef.current = new Set((inputRequests ?? []).map((request) => request.id));
|
|
11779
|
+
const executeRequest = React.useCallback(
|
|
11780
|
+
async (request) => {
|
|
11781
|
+
const payload = request.payload;
|
|
11782
|
+
if (!isClientToolInterrupt(payload)) return;
|
|
11783
|
+
const claim = clientToolClaimKey(threadId, request.id);
|
|
11784
|
+
const {
|
|
11785
|
+
tools,
|
|
11786
|
+
confirmWrites,
|
|
11787
|
+
writeDeclinedMessage,
|
|
11788
|
+
missingToolMessage,
|
|
11789
|
+
onCallSettled,
|
|
11790
|
+
sendResume
|
|
11791
|
+
} = optionsRef.current;
|
|
11792
|
+
const results = await executeClientToolBatch({
|
|
11793
|
+
calls: payload.context.requests,
|
|
11794
|
+
tools,
|
|
11795
|
+
// Live while the request still exists AND this surface may answer it:
|
|
11796
|
+
// mounted, or already past the point of no return (handlers started —
|
|
11797
|
+
// the detached execution must finish and settle, never re-execute).
|
|
11798
|
+
// After unmount the request-id snapshot freezes at its last observed
|
|
11799
|
+
// state, which keeps a started batch's own request visible to it.
|
|
11800
|
+
isLive: () => liveRequestIdsRef.current.has(request.id) && (activeRef.current || startedClaimsRef.current.has(claim)),
|
|
11801
|
+
onExecutionStart: () => {
|
|
11802
|
+
startedClaimsRef.current.add(claim);
|
|
11803
|
+
},
|
|
11804
|
+
...confirmWrites ? {
|
|
11805
|
+
confirmWrites: ({ writeToolNames }) => confirmWrites({ requestId: request.id, writeToolNames })
|
|
11806
|
+
} : {},
|
|
11807
|
+
...writeDeclinedMessage !== void 0 ? { writeDeclinedMessage } : {},
|
|
11808
|
+
...missingToolMessage ? { missingToolMessage } : {},
|
|
11809
|
+
...onCallSettled ? { onCallSettled } : {}
|
|
11810
|
+
});
|
|
11811
|
+
if (results === null) {
|
|
11812
|
+
releaseClaim(claim);
|
|
11813
|
+
return;
|
|
11814
|
+
}
|
|
11815
|
+
try {
|
|
11816
|
+
sendResume(request.id, clientToolResultsResumeValue(results));
|
|
11817
|
+
ownedClaimsRef.current.delete(claim);
|
|
11818
|
+
startedClaimsRef.current.delete(claim);
|
|
11819
|
+
} catch (error2) {
|
|
11820
|
+
releaseClaim(claim);
|
|
11821
|
+
console.error(`${logLabel} failed to resume client tool results:`, error2);
|
|
11822
|
+
}
|
|
11823
|
+
},
|
|
11824
|
+
[logLabel, releaseClaim, threadId]
|
|
11825
|
+
);
|
|
11826
|
+
React.useEffect(() => {
|
|
11827
|
+
if (!pendingRequest) return;
|
|
11828
|
+
const claim = clientToolClaimKey(threadId, pendingRequest.id);
|
|
11829
|
+
if (!tracker.claim(claim)) return;
|
|
11830
|
+
ownedClaimsRef.current.add(claim);
|
|
11831
|
+
void executeRequest(pendingRequest);
|
|
11832
|
+
}, [executeRequest, pendingRequest, threadId, tracker]);
|
|
11833
|
+
}
|
|
11515
11834
|
const AUTH_DENIAL_PARK_THRESHOLD = 8;
|
|
11516
11835
|
const initialAuthDenialTrackerState = () => ({
|
|
11517
11836
|
lastAttempt: null,
|
|
@@ -11609,6 +11928,125 @@ function projectDeepAgentConnection(connection, { awaitingFirstSend = false } =
|
|
|
11609
11928
|
if (connection.status === "connecting" && awaitingFirstSend) return { status: "ready" };
|
|
11610
11929
|
return { status: connection.status };
|
|
11611
11930
|
}
|
|
11931
|
+
const preStreamState = { messages: [], todos: [] };
|
|
11932
|
+
Object.freeze(preStreamState.messages);
|
|
11933
|
+
Object.freeze(preStreamState.todos);
|
|
11934
|
+
const DEEP_AGENT_PRE_STREAM_STATE = Object.freeze(preStreamState);
|
|
11935
|
+
function readDeepAgentStreamValues(state) {
|
|
11936
|
+
return typeof state === "object" && state !== null ? state : DEEP_AGENT_PRE_STREAM_STATE;
|
|
11937
|
+
}
|
|
11938
|
+
function isRecord$2(value) {
|
|
11939
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11940
|
+
}
|
|
11941
|
+
function isPendingInterrupt(request) {
|
|
11942
|
+
return request.type === "interrupt" && !("response" in request);
|
|
11943
|
+
}
|
|
11944
|
+
function isApprovalCardInterrupt(request) {
|
|
11945
|
+
if (!isPendingInterrupt(request)) return false;
|
|
11946
|
+
return !hasClientToolInterruptSource(request.payload);
|
|
11947
|
+
}
|
|
11948
|
+
function asHitlApproval(value) {
|
|
11949
|
+
if (!isRecord$2(value)) return null;
|
|
11950
|
+
return value.type === "hitl" && value.source === "hitl_approval" && typeof value.message === "string" ? value : null;
|
|
11951
|
+
}
|
|
11952
|
+
const DEFAULT_INTERRUPT_PAUSED_MESSAGE = "The agent is paused and waiting for input.";
|
|
11953
|
+
function readInterruptMessage(value, fallback = DEFAULT_INTERRUPT_PAUSED_MESSAGE) {
|
|
11954
|
+
if (isRecord$2(value) && typeof value.message === "string" && value.message.length > 0) {
|
|
11955
|
+
return value.message;
|
|
11956
|
+
}
|
|
11957
|
+
return fallback;
|
|
11958
|
+
}
|
|
11959
|
+
function readAbandonedInputRequests(state) {
|
|
11960
|
+
const abandoned = readDeepAgentStreamValues(state).abandonedInputRequests;
|
|
11961
|
+
return Array.isArray(abandoned) ? abandoned : void 0;
|
|
11962
|
+
}
|
|
11963
|
+
function findAbandonedInterrupt(abandoned) {
|
|
11964
|
+
return abandoned == null ? void 0 : abandoned.find(
|
|
11965
|
+
(request) => isRecord$2(request) && request.type === "interrupt" && typeof request.id === "string"
|
|
11966
|
+
);
|
|
11967
|
+
}
|
|
11968
|
+
const HITL_REJECT_REASON = "User rejected the action.";
|
|
11969
|
+
function hitlResumeApprove() {
|
|
11970
|
+
return { action: "approve" };
|
|
11971
|
+
}
|
|
11972
|
+
function hitlResumeReject(reason = HITL_REJECT_REASON) {
|
|
11973
|
+
return { action: "reject", reason };
|
|
11974
|
+
}
|
|
11975
|
+
function hitlResumeContinue() {
|
|
11976
|
+
return { action: "continue" };
|
|
11977
|
+
}
|
|
11978
|
+
function useApprovalResumeLock(options) {
|
|
11979
|
+
const { requestId, isRunning, sendResume, pendingResumeGraceMs } = options;
|
|
11980
|
+
const [pending, setPending] = React.useState(false);
|
|
11981
|
+
const prevRequestIdRef = React.useRef(requestId);
|
|
11982
|
+
if (prevRequestIdRef.current !== requestId) {
|
|
11983
|
+
prevRequestIdRef.current = requestId;
|
|
11984
|
+
if (pending) setPending(false);
|
|
11985
|
+
}
|
|
11986
|
+
const sawResumeRunRef = React.useRef(false);
|
|
11987
|
+
React.useEffect(() => {
|
|
11988
|
+
if (!pending) {
|
|
11989
|
+
sawResumeRunRef.current = false;
|
|
11990
|
+
return;
|
|
11991
|
+
}
|
|
11992
|
+
if (isRunning) {
|
|
11993
|
+
sawResumeRunRef.current = true;
|
|
11994
|
+
return;
|
|
11995
|
+
}
|
|
11996
|
+
if (sawResumeRunRef.current) {
|
|
11997
|
+
sawResumeRunRef.current = false;
|
|
11998
|
+
setPending(false);
|
|
11999
|
+
}
|
|
12000
|
+
}, [pending, isRunning]);
|
|
12001
|
+
React.useEffect(() => {
|
|
12002
|
+
if (!pending || pendingResumeGraceMs === void 0) return;
|
|
12003
|
+
const timer = setTimeout(() => {
|
|
12004
|
+
if (!sawResumeRunRef.current) setPending(false);
|
|
12005
|
+
}, pendingResumeGraceMs);
|
|
12006
|
+
return () => clearTimeout(timer);
|
|
12007
|
+
}, [pending, requestId, pendingResumeGraceMs]);
|
|
12008
|
+
const sendResumeRef = React.useRef(sendResume);
|
|
12009
|
+
sendResumeRef.current = sendResume;
|
|
12010
|
+
const pendingRef = React.useRef(pending);
|
|
12011
|
+
pendingRef.current = pending;
|
|
12012
|
+
const resume = React.useCallback(
|
|
12013
|
+
(value) => {
|
|
12014
|
+
if (requestId === void 0 || pendingRef.current) return;
|
|
12015
|
+
setPending(true);
|
|
12016
|
+
pendingRef.current = true;
|
|
12017
|
+
sendResumeRef.current(requestId, value);
|
|
12018
|
+
},
|
|
12019
|
+
[requestId]
|
|
12020
|
+
);
|
|
12021
|
+
return { pending, resume };
|
|
12022
|
+
}
|
|
12023
|
+
function queueEntryText(parts) {
|
|
12024
|
+
return parts.flatMap(
|
|
12025
|
+
(part) => part.type === "text" && typeof part.text === "string" ? [part.text] : []
|
|
12026
|
+
).join("\n\n");
|
|
12027
|
+
}
|
|
12028
|
+
function queueLaneFlags(status) {
|
|
12029
|
+
return {
|
|
12030
|
+
isRunning: status === "running",
|
|
12031
|
+
isContinuable: status === "stopped" || status === "error"
|
|
12032
|
+
};
|
|
12033
|
+
}
|
|
12034
|
+
function buildStatewireQueueRows(options) {
|
|
12035
|
+
const { queue, steerQueue, isContinuable } = options;
|
|
12036
|
+
return [
|
|
12037
|
+
...isContinuable ? steerQueue.map((item) => ({ item, lane: "steer" })) : [],
|
|
12038
|
+
...queue.map((item) => ({ item, lane: "queue" }))
|
|
12039
|
+
];
|
|
12040
|
+
}
|
|
12041
|
+
function showQueueRowSendNow(options) {
|
|
12042
|
+
const { lane, index: index2, isRunning, isContinuable } = options;
|
|
12043
|
+
return lane === "queue" && (isContinuable || isRunning && index2 === 0);
|
|
12044
|
+
}
|
|
12045
|
+
function hasStatewireThreadExtras(extras) {
|
|
12046
|
+
if (!extras || typeof extras !== "object") return false;
|
|
12047
|
+
const candidate = extras;
|
|
12048
|
+
return typeof candidate.sendCommand === "function" && Array.isArray(candidate.inputRequests) && typeof candidate.runs === "object" && candidate.runs !== null;
|
|
12049
|
+
}
|
|
11612
12050
|
const buildOptimisticHumanContent = (parts) => {
|
|
11613
12051
|
const imageParts = parts.filter(
|
|
11614
12052
|
(part) => part.type === "image"
|
|
@@ -11858,10 +12296,11 @@ function isLangGraphState(value) {
|
|
|
11858
12296
|
}
|
|
11859
12297
|
function convertDeepAgentState(state, { laneProjection = "both" } = {}) {
|
|
11860
12298
|
var _a3, _b2;
|
|
11861
|
-
const
|
|
12299
|
+
const values = readDeepAgentStreamValues(state);
|
|
12300
|
+
const status = (_b2 = (_a3 = values.runs) == null ? void 0 : _a3[0]) == null ? void 0 : _b2.status;
|
|
11862
12301
|
const isRunning = status === "running";
|
|
11863
|
-
const laneTail = status === "stopped" || status === "error" ? [] : laneTailMessages(
|
|
11864
|
-
const stateMessages = isLangGraphState(
|
|
12302
|
+
const laneTail = status === "stopped" || status === "error" ? [] : laneTailMessages(values, laneProjection);
|
|
12303
|
+
const stateMessages = isLangGraphState(values) ? sanitizeLangChainMessages(values.messages) : [];
|
|
11865
12304
|
return {
|
|
11866
12305
|
messages: messageConverter.toThreadMessages(
|
|
11867
12306
|
[...withPendingAssistantMessage(stateMessages, isRunning), ...laneTail],
|
|
@@ -11879,6 +12318,132 @@ function registerDeepAgentRunConfig(aui, getRunConfig) {
|
|
|
11879
12318
|
})
|
|
11880
12319
|
});
|
|
11881
12320
|
}
|
|
12321
|
+
const browserGlobals = globalThis;
|
|
12322
|
+
function requireLocalStorage() {
|
|
12323
|
+
const storage = browserGlobals.localStorage;
|
|
12324
|
+
if (!storage) {
|
|
12325
|
+
throw new Error("statewire: QuotaSafeLocalStorageSession requires localStorage");
|
|
12326
|
+
}
|
|
12327
|
+
return storage;
|
|
12328
|
+
}
|
|
12329
|
+
const SESSION_PREFIX = "aui:statewire-session:";
|
|
12330
|
+
const SESSION_LOCK_PREFIX = "aui:statewire-session-lock:";
|
|
12331
|
+
function isStorageQuotaError(error2) {
|
|
12332
|
+
if (typeof DOMException !== "undefined" && error2 instanceof DOMException) {
|
|
12333
|
+
return error2.name === "QuotaExceededError" || error2.name === "NS_ERROR_DOM_QUOTA_REACHED" || error2.code === 22 || error2.code === 1014;
|
|
12334
|
+
}
|
|
12335
|
+
if (error2 instanceof Error) {
|
|
12336
|
+
return /exceeded the quota|quotaexceedederror|ns_error_dom_quota_reached/i.test(error2.message);
|
|
12337
|
+
}
|
|
12338
|
+
return false;
|
|
12339
|
+
}
|
|
12340
|
+
function readEvictionMeta(raw) {
|
|
12341
|
+
if (!raw) return { savedAt: 0, hasPendingCommands: false };
|
|
12342
|
+
try {
|
|
12343
|
+
const parsed = JSON.parse(raw);
|
|
12344
|
+
return {
|
|
12345
|
+
savedAt: typeof (parsed == null ? void 0 : parsed.savedAt) === "number" ? parsed.savedAt : 0,
|
|
12346
|
+
hasPendingCommands: Array.isArray(parsed == null ? void 0 : parsed.commands) && parsed.commands.length > 0
|
|
12347
|
+
};
|
|
12348
|
+
} catch {
|
|
12349
|
+
return { savedAt: 0, hasPendingCommands: false };
|
|
12350
|
+
}
|
|
12351
|
+
}
|
|
12352
|
+
function evictOldestStatewireSessions(currentKey) {
|
|
12353
|
+
const storage = requireLocalStorage();
|
|
12354
|
+
const candidates = [];
|
|
12355
|
+
for (let i = 0; i < storage.length; i++) {
|
|
12356
|
+
const key = storage.key(i);
|
|
12357
|
+
if (!key || !key.startsWith(SESSION_PREFIX) || key === currentKey) continue;
|
|
12358
|
+
candidates.push({ key, ...readEvictionMeta(storage.getItem(key)) });
|
|
12359
|
+
}
|
|
12360
|
+
candidates.sort(
|
|
12361
|
+
(a, b) => Number(a.hasPendingCommands) - Number(b.hasPendingCommands) || a.savedAt - b.savedAt
|
|
12362
|
+
);
|
|
12363
|
+
const evictCount = Math.min(candidates.length, Math.max(1, Math.ceil(candidates.length / 2)));
|
|
12364
|
+
let removed = 0;
|
|
12365
|
+
for (const { key } of candidates.slice(0, evictCount)) {
|
|
12366
|
+
try {
|
|
12367
|
+
storage.removeItem(key);
|
|
12368
|
+
removed++;
|
|
12369
|
+
} catch {
|
|
12370
|
+
}
|
|
12371
|
+
}
|
|
12372
|
+
return removed;
|
|
12373
|
+
}
|
|
12374
|
+
function createQuotaSafeSessionStorage({
|
|
12375
|
+
storageKey,
|
|
12376
|
+
lockName
|
|
12377
|
+
}) {
|
|
12378
|
+
return {
|
|
12379
|
+
load: () => {
|
|
12380
|
+
const raw = requireLocalStorage().getItem(storageKey);
|
|
12381
|
+
if (raw === null) return null;
|
|
12382
|
+
return JSON.parse(raw);
|
|
12383
|
+
},
|
|
12384
|
+
save: (record2) => {
|
|
12385
|
+
const storage = requireLocalStorage();
|
|
12386
|
+
const serialized = JSON.stringify({ ...record2, savedAt: Date.now() });
|
|
12387
|
+
try {
|
|
12388
|
+
storage.setItem(storageKey, serialized);
|
|
12389
|
+
} catch (error2) {
|
|
12390
|
+
if (!isStorageQuotaError(error2)) throw error2;
|
|
12391
|
+
evictOldestStatewireSessions(storageKey);
|
|
12392
|
+
try {
|
|
12393
|
+
storage.setItem(storageKey, serialized);
|
|
12394
|
+
} catch (retryError) {
|
|
12395
|
+
if (!isStorageQuotaError(retryError)) throw retryError;
|
|
12396
|
+
console.warn(
|
|
12397
|
+
"[statewire] session save skipped — localStorage quota exhausted even after evicting old statewire sessions; the lane will not survive a reload",
|
|
12398
|
+
{ storageKey }
|
|
12399
|
+
);
|
|
12400
|
+
}
|
|
12401
|
+
}
|
|
12402
|
+
},
|
|
12403
|
+
// localStorage is shared across tabs: record mutations serialize through a
|
|
12404
|
+
// per-key Web Lock, and `subscribe` mirrors other sharers' saves. In
|
|
12405
|
+
// browsers `globalThis` IS `window`, so the storage events land here.
|
|
12406
|
+
lock: (fn) => {
|
|
12407
|
+
var _a3;
|
|
12408
|
+
const locks = (_a3 = browserGlobals.navigator) == null ? void 0 : _a3.locks;
|
|
12409
|
+
if (!locks) {
|
|
12410
|
+
throw new Error(
|
|
12411
|
+
"statewire: QuotaSafeLocalStorageSession requires the Web Locks API (navigator.locks)"
|
|
12412
|
+
);
|
|
12413
|
+
}
|
|
12414
|
+
return locks.request(lockName, async () => fn());
|
|
12415
|
+
},
|
|
12416
|
+
subscribe: (listener) => {
|
|
12417
|
+
var _a3;
|
|
12418
|
+
const onStorage = (event) => {
|
|
12419
|
+
if (event.key === storageKey) listener();
|
|
12420
|
+
};
|
|
12421
|
+
(_a3 = browserGlobals.addEventListener) == null ? void 0 : _a3.call(browserGlobals, "storage", onStorage);
|
|
12422
|
+
return () => {
|
|
12423
|
+
var _a4;
|
|
12424
|
+
return (_a4 = browserGlobals.removeEventListener) == null ? void 0 : _a4.call(browserGlobals, "storage", onStorage);
|
|
12425
|
+
};
|
|
12426
|
+
}
|
|
12427
|
+
};
|
|
12428
|
+
}
|
|
12429
|
+
const useQuotaSafeLocalStorageSession = ({
|
|
12430
|
+
threadId,
|
|
12431
|
+
key = (id) => id
|
|
12432
|
+
}) => {
|
|
12433
|
+
var _a3;
|
|
12434
|
+
requireLocalStorage();
|
|
12435
|
+
if (((_a3 = browserGlobals.navigator) == null ? void 0 : _a3.locks) === void 0)
|
|
12436
|
+
throw new Error(
|
|
12437
|
+
"statewire: QuotaSafeLocalStorageSession requires the Web Locks API (navigator.locks)"
|
|
12438
|
+
);
|
|
12439
|
+
const storageKey = SESSION_PREFIX + key(threadId);
|
|
12440
|
+
const lockName = SESSION_LOCK_PREFIX + key(threadId);
|
|
12441
|
+
return React.useMemo(
|
|
12442
|
+
() => createQuotaSafeSessionStorage({ storageKey, lockName }),
|
|
12443
|
+
[storageKey, lockName]
|
|
12444
|
+
);
|
|
12445
|
+
};
|
|
12446
|
+
const QuotaSafeLocalStorageSession = tap.resource(useQuotaSafeLocalStorageSession);
|
|
11882
12447
|
function useDeepAgentThreadStatus() {
|
|
11883
12448
|
return store.useAuiState((s) => {
|
|
11884
12449
|
var _a3;
|
|
@@ -11918,6 +12483,7 @@ function useDeepAgentThread({
|
|
|
11918
12483
|
capabilities,
|
|
11919
12484
|
laneProjection = "both",
|
|
11920
12485
|
adapters,
|
|
12486
|
+
diagnostics,
|
|
11921
12487
|
onError,
|
|
11922
12488
|
onStateChange,
|
|
11923
12489
|
onCommandChange,
|
|
@@ -11948,6 +12514,8 @@ function useDeepAgentThread({
|
|
|
11948
12514
|
onRawConnectionChangeRef.current = onRawConnectionChange;
|
|
11949
12515
|
const headersRef = React.useRef(headers);
|
|
11950
12516
|
headersRef.current = headers;
|
|
12517
|
+
const diagnosticsRef = React.useRef(diagnostics);
|
|
12518
|
+
diagnosticsRef.current = diagnostics;
|
|
11951
12519
|
const lastRunningRef = React.useRef(null);
|
|
11952
12520
|
const lastLegacyRunActiveRef = React.useRef(null);
|
|
11953
12521
|
const appliedStateRunConfigThreadRef = React.useRef(null);
|
|
@@ -12078,7 +12646,11 @@ function useDeepAgentThread({
|
|
|
12078
12646
|
// A never-started chat has no server session yet: the transport
|
|
12079
12647
|
// makes no network calls until the first command send.
|
|
12080
12648
|
...preloadRef.current.preload && { isNew: true },
|
|
12081
|
-
headers: (ctx) =>
|
|
12649
|
+
headers: (ctx) => {
|
|
12650
|
+
var _a3;
|
|
12651
|
+
(_a3 = diagnosticsRef.current) == null ? void 0 : _a3.observeAuthResolve(ctx);
|
|
12652
|
+
return headersRef.current(ctx);
|
|
12653
|
+
},
|
|
12082
12654
|
...sessionStore && { sessionStore }
|
|
12083
12655
|
},
|
|
12084
12656
|
{ sse }
|
|
@@ -12093,7 +12665,8 @@ function useDeepAgentThread({
|
|
|
12093
12665
|
// former `runs: true` opt-in is gone) — the converter only maps app-owned
|
|
12094
12666
|
// keys, including the `run/stop` runId stamp the lib projects itself.
|
|
12095
12667
|
converter: (state, meta) => {
|
|
12096
|
-
var _a3, _b2, _c2, _d2;
|
|
12668
|
+
var _a3, _b2, _c2, _d2, _e2;
|
|
12669
|
+
(_a3 = diagnosticsRef.current) == null ? void 0 : _a3.observeConnection(meta.connection);
|
|
12097
12670
|
if (authDenialRef.current.attachId !== attachIdRef.current) {
|
|
12098
12671
|
authDenialRef.current = {
|
|
12099
12672
|
attachId: attachIdRef.current,
|
|
@@ -12112,7 +12685,7 @@ function useDeepAgentThread({
|
|
|
12112
12685
|
);
|
|
12113
12686
|
});
|
|
12114
12687
|
}
|
|
12115
|
-
if (awaitingFirstSendRef.current.awaiting && ((((
|
|
12688
|
+
if (awaitingFirstSendRef.current.awaiting && ((((_b2 = state == null ? void 0 : state.runs) == null ? void 0 : _b2.length) ?? 0) > 0 || (((_c2 = state == null ? void 0 : state.messages) == null ? void 0 : _c2.length) ?? 0) > 0)) {
|
|
12116
12689
|
awaitingFirstSendRef.current = {
|
|
12117
12690
|
threadId: awaitingFirstSendRef.current.threadId,
|
|
12118
12691
|
awaiting: false
|
|
@@ -12131,7 +12704,7 @@ function useDeepAgentThread({
|
|
|
12131
12704
|
(_a4 = onConnectionChangeRef.current) == null ? void 0 : _a4.call(onConnectionChangeRef, connection);
|
|
12132
12705
|
});
|
|
12133
12706
|
}
|
|
12134
|
-
return converter(state, ((
|
|
12707
|
+
return converter(state, ((_e2 = (_d2 = state == null ? void 0 : state.runs) == null ? void 0 : _d2[0]) == null ? void 0 : _e2.status) === "running");
|
|
12135
12708
|
},
|
|
12136
12709
|
// Makes the server's dispatch record concrete in state (after the
|
|
12137
12710
|
// optimistic folds); the lib's post-converter dispatch merge turns off.
|
|
@@ -12147,19 +12720,29 @@ function useDeepAgentThread({
|
|
|
12147
12720
|
// deliberate user stop.
|
|
12148
12721
|
stopPayload: () => ({ reason: "user_stop" }),
|
|
12149
12722
|
onError: (error2) => {
|
|
12150
|
-
var _a3;
|
|
12151
|
-
|
|
12723
|
+
var _a3, _b2;
|
|
12724
|
+
(_a3 = diagnosticsRef.current) == null ? void 0 : _a3.observeError(error2);
|
|
12725
|
+
(_b2 = onErrorRef.current) == null ? void 0 : _b2.call(onErrorRef, error2);
|
|
12152
12726
|
},
|
|
12153
12727
|
...onStateChange && {
|
|
12728
|
+
// The lib types the observed state `NonNullable`, but the runtime
|
|
12729
|
+
// delivers `undefined` where the wire has no snapshot (pre-attach and
|
|
12730
|
+
// replay boundaries republish it) — normalize so the type is true and
|
|
12731
|
+
// host observers never crash on a field read.
|
|
12154
12732
|
onStateChange: ((state, ctx) => {
|
|
12155
12733
|
var _a3;
|
|
12156
|
-
return (_a3 = onStateChangeRef.current) == null ? void 0 : _a3.call(
|
|
12734
|
+
return (_a3 = onStateChangeRef.current) == null ? void 0 : _a3.call(
|
|
12735
|
+
onStateChangeRef,
|
|
12736
|
+
readDeepAgentStreamValues(state),
|
|
12737
|
+
ctx
|
|
12738
|
+
);
|
|
12157
12739
|
})
|
|
12158
12740
|
},
|
|
12159
|
-
...onCommandChange && {
|
|
12741
|
+
...(onCommandChange || diagnostics) && {
|
|
12160
12742
|
onCommandChange: ((update, ctx) => {
|
|
12161
|
-
var _a3;
|
|
12162
|
-
|
|
12743
|
+
var _a3, _b2;
|
|
12744
|
+
(_a3 = diagnosticsRef.current) == null ? void 0 : _a3.observeCommand(update);
|
|
12745
|
+
(_b2 = onCommandChangeRef.current) == null ? void 0 : _b2.call(onCommandChangeRef, update, ctx);
|
|
12163
12746
|
})
|
|
12164
12747
|
},
|
|
12165
12748
|
...onRawConnectionChange && {
|
|
@@ -12173,6 +12756,66 @@ function useDeepAgentThread({
|
|
|
12173
12756
|
}
|
|
12174
12757
|
});
|
|
12175
12758
|
}
|
|
12759
|
+
function canPersistDeepAgentSession() {
|
|
12760
|
+
try {
|
|
12761
|
+
const storage = globalThis.localStorage;
|
|
12762
|
+
if (!storage) return false;
|
|
12763
|
+
const probeKey = "__athena_statewire_session_probe__";
|
|
12764
|
+
storage.setItem(probeKey, probeKey);
|
|
12765
|
+
storage.removeItem(probeKey);
|
|
12766
|
+
return true;
|
|
12767
|
+
} catch {
|
|
12768
|
+
return false;
|
|
12769
|
+
}
|
|
12770
|
+
}
|
|
12771
|
+
function logUnhandledStatewireError(surface, error2) {
|
|
12772
|
+
if (isStatewireChannelTeardown(error2)) {
|
|
12773
|
+
console.debug(`[${surface}] statewire channel teardown:`, error2);
|
|
12774
|
+
return;
|
|
12775
|
+
}
|
|
12776
|
+
console.error(`[${surface}] statewire transport error:`, error2);
|
|
12777
|
+
}
|
|
12778
|
+
function useDeepAgentRuntime(options) {
|
|
12779
|
+
const { surface, session = false, useClient, runConfig, onError, ...threadOptions } = options;
|
|
12780
|
+
const [canPersistLocalSession] = React.useState(canPersistDeepAgentSession);
|
|
12781
|
+
const onErrorRef = React.useRef(onError);
|
|
12782
|
+
onErrorRef.current = onError;
|
|
12783
|
+
const surfaceRef = React.useRef(surface);
|
|
12784
|
+
surfaceRef.current = surface;
|
|
12785
|
+
const thread = useDeepAgentThread({
|
|
12786
|
+
...threadOptions,
|
|
12787
|
+
...session !== false && session.kind === "local-storage" && canPersistLocalSession && {
|
|
12788
|
+
storage: {
|
|
12789
|
+
session: QuotaSafeLocalStorageSession({
|
|
12790
|
+
threadId: threadOptions.threadId,
|
|
12791
|
+
key: session.key
|
|
12792
|
+
})
|
|
12793
|
+
}
|
|
12794
|
+
},
|
|
12795
|
+
...session !== false && session.kind === "session-store" && { sessionStore: session.store },
|
|
12796
|
+
onError: (error2) => {
|
|
12797
|
+
const handler = onErrorRef.current;
|
|
12798
|
+
if (handler) {
|
|
12799
|
+
handler(error2);
|
|
12800
|
+
return;
|
|
12801
|
+
}
|
|
12802
|
+
logUnhandledStatewireError(surfaceRef.current, error2);
|
|
12803
|
+
}
|
|
12804
|
+
});
|
|
12805
|
+
const client = useClient(thread);
|
|
12806
|
+
const getRunConfigRef = React.useRef(runConfig == null ? void 0 : runConfig.get);
|
|
12807
|
+
getRunConfigRef.current = runConfig == null ? void 0 : runConfig.get;
|
|
12808
|
+
const hasRunConfig = runConfig !== void 0;
|
|
12809
|
+
const runConfigKey = runConfig == null ? void 0 : runConfig.key;
|
|
12810
|
+
React.useEffect(() => {
|
|
12811
|
+
if (!hasRunConfig) return void 0;
|
|
12812
|
+
return registerDeepAgentRunConfig(client, () => {
|
|
12813
|
+
var _a3;
|
|
12814
|
+
return ((_a3 = getRunConfigRef.current) == null ? void 0 : _a3.call(getRunConfigRef)) ?? {};
|
|
12815
|
+
});
|
|
12816
|
+
}, [client, hasRunConfig, runConfigKey]);
|
|
12817
|
+
return client;
|
|
12818
|
+
}
|
|
12176
12819
|
function isStandardSchema(schema2) {
|
|
12177
12820
|
return typeof schema2 === "object" && schema2 !== null && "~standard" in schema2 && typeof schema2["~standard"] === "object";
|
|
12178
12821
|
}
|
|
@@ -12275,18 +12918,7 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
12275
12918
|
onLegacyReadOnly,
|
|
12276
12919
|
onRunningChange
|
|
12277
12920
|
} = config2;
|
|
12278
|
-
const tokenRef = React.useRef(token);
|
|
12279
|
-
tokenRef.current = token;
|
|
12280
|
-
const getTokenRef = React.useRef(getToken);
|
|
12281
|
-
getTokenRef.current = getToken;
|
|
12282
|
-
const apiKeyRef = React.useRef(apiKey);
|
|
12283
|
-
apiKeyRef.current = apiKey;
|
|
12284
|
-
const onErrorRef = React.useRef(onError);
|
|
12285
|
-
onErrorRef.current = onError;
|
|
12286
12921
|
const clientTools = useStatewireClientTools(frontendToolkit);
|
|
12287
|
-
const clientToolsRef = React.useRef(clientTools);
|
|
12288
|
-
clientToolsRef.current = clientTools;
|
|
12289
|
-
const [canPersistSession] = React.useState(() => typeof localStorage !== "undefined");
|
|
12290
12922
|
React.useEffect(() => {
|
|
12291
12923
|
if (agent2 && !parseCollabAgentRef(agent2)) {
|
|
12292
12924
|
athenaDiagnostics.emit("sdk.config.warning", {
|
|
@@ -12309,16 +12941,22 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
12309
12941
|
{ thread_id: threadId, is_new_chat: isNewChat }
|
|
12310
12942
|
);
|
|
12311
12943
|
}
|
|
12312
|
-
const
|
|
12944
|
+
const auiTools = React.useMemo(() => react$1.Tools({ toolkit: frontendToolkit }), [frontendToolkit]);
|
|
12945
|
+
const useSdkClient = (thread) => react$1.useAui({ thread, tools: auiTools });
|
|
12946
|
+
return useDeepAgentRuntime({
|
|
12947
|
+
surface: "AthenaSDK",
|
|
12313
12948
|
threadId,
|
|
12314
12949
|
baseUrl: syncUrl,
|
|
12950
|
+
// Option closures are re-read per render by the core, so credential
|
|
12951
|
+
// rotation (new `token`/`getToken`/`apiKey` props) reaches the next
|
|
12952
|
+
// request without remounting the thread.
|
|
12315
12953
|
headers: async () => {
|
|
12316
|
-
const currentToken =
|
|
12954
|
+
const currentToken = getToken ? await getToken() ?? token : token;
|
|
12317
12955
|
if (currentToken) {
|
|
12318
12956
|
return { Authorization: `Bearer ${currentToken}` };
|
|
12319
12957
|
}
|
|
12320
|
-
if (
|
|
12321
|
-
return { "X-API-KEY":
|
|
12958
|
+
if (apiKey) {
|
|
12959
|
+
return { "X-API-KEY": apiKey };
|
|
12322
12960
|
}
|
|
12323
12961
|
return {};
|
|
12324
12962
|
},
|
|
@@ -12328,16 +12966,12 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
12328
12966
|
laneProjection: "steer-only",
|
|
12329
12967
|
// Durable session: a reload resumes the lane and resends whatever the
|
|
12330
12968
|
// server has not marked durable. Scoped by host — a thread id is only
|
|
12331
|
-
// meaningful against the backend that minted it.
|
|
12332
|
-
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
threadId,
|
|
12336
|
-
key: (id) => `${syncUrl}:${id}`
|
|
12337
|
-
})
|
|
12338
|
-
}
|
|
12339
|
-
},
|
|
12969
|
+
// meaningful against the backend that minted it. (Consumers server-render
|
|
12970
|
+
// this SDK; the core's availability probe keeps those sessions
|
|
12971
|
+
// process-local, as before the seam existed.)
|
|
12972
|
+
session: { kind: "local-storage", key: (id) => `${syncUrl}:${id}` },
|
|
12340
12973
|
capabilities: { edit: true, reload: true, continue: true },
|
|
12974
|
+
useClient: useSdkClient,
|
|
12341
12975
|
onStateChange: () => {
|
|
12342
12976
|
const endSpan = attachSpanRef.current;
|
|
12343
12977
|
if (endSpan) {
|
|
@@ -12366,6 +13000,26 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
12366
13000
|
onLegacyReadOnly == null ? void 0 : onLegacyReadOnly(legacyReadOnly);
|
|
12367
13001
|
},
|
|
12368
13002
|
onRunningChange,
|
|
13003
|
+
// The runConfig getter is pulled at command-send time through the core's
|
|
13004
|
+
// per-render ref, so it reads the latest props — consumers commonly pass
|
|
13005
|
+
// fresh array literals per render, which must not thrash the registration
|
|
13006
|
+
// (no `key`: the provider registers once per client).
|
|
13007
|
+
runConfig: {
|
|
13008
|
+
get: () => buildStatewireRunConfig({
|
|
13009
|
+
model,
|
|
13010
|
+
agent: agent2,
|
|
13011
|
+
channel,
|
|
13012
|
+
tools,
|
|
13013
|
+
frontendToolIds,
|
|
13014
|
+
workbench,
|
|
13015
|
+
knowledgeBase,
|
|
13016
|
+
systemPrompt,
|
|
13017
|
+
customToolConfigs,
|
|
13018
|
+
appId,
|
|
13019
|
+
extraRunConfig,
|
|
13020
|
+
clientTools: statewireClientToolWireEntries(clientTools)
|
|
13021
|
+
})
|
|
13022
|
+
},
|
|
12369
13023
|
onError: (error2) => {
|
|
12370
13024
|
if (!isStatewireChannelTeardown(error2)) {
|
|
12371
13025
|
athenaDiagnostics.error(
|
|
@@ -12379,60 +13033,17 @@ function useAthenaStatewireRuntime(config2) {
|
|
|
12379
13033
|
{ thread_id: threadId }
|
|
12380
13034
|
);
|
|
12381
13035
|
}
|
|
12382
|
-
if (
|
|
12383
|
-
|
|
12384
|
-
return;
|
|
12385
|
-
}
|
|
12386
|
-
if (isStatewireChannelTeardown(error2)) {
|
|
12387
|
-
console.debug("[AthenaSDK] statewire channel teardown:", error2);
|
|
13036
|
+
if (onError) {
|
|
13037
|
+
onError(error2);
|
|
12388
13038
|
return;
|
|
12389
13039
|
}
|
|
12390
|
-
|
|
13040
|
+
logUnhandledStatewireError("AthenaSDK", error2);
|
|
12391
13041
|
}
|
|
12392
13042
|
});
|
|
12393
|
-
const auiTools = React.useMemo(() => react$1.Tools({ toolkit: frontendToolkit }), [frontendToolkit]);
|
|
12394
|
-
const aui = react$1.useAui({ thread, tools: auiTools });
|
|
12395
|
-
const runConfigInputsRef = React.useRef({
|
|
12396
|
-
model,
|
|
12397
|
-
agent: agent2,
|
|
12398
|
-
channel,
|
|
12399
|
-
tools,
|
|
12400
|
-
frontendToolIds,
|
|
12401
|
-
workbench,
|
|
12402
|
-
knowledgeBase,
|
|
12403
|
-
systemPrompt,
|
|
12404
|
-
customToolConfigs,
|
|
12405
|
-
appId,
|
|
12406
|
-
extraRunConfig
|
|
12407
|
-
});
|
|
12408
|
-
runConfigInputsRef.current = {
|
|
12409
|
-
model,
|
|
12410
|
-
agent: agent2,
|
|
12411
|
-
channel,
|
|
12412
|
-
tools,
|
|
12413
|
-
frontendToolIds,
|
|
12414
|
-
workbench,
|
|
12415
|
-
knowledgeBase,
|
|
12416
|
-
systemPrompt,
|
|
12417
|
-
customToolConfigs,
|
|
12418
|
-
appId,
|
|
12419
|
-
extraRunConfig
|
|
12420
|
-
};
|
|
12421
|
-
React.useEffect(
|
|
12422
|
-
() => registerDeepAgentRunConfig(
|
|
12423
|
-
aui,
|
|
12424
|
-
() => buildStatewireRunConfig({
|
|
12425
|
-
...runConfigInputsRef.current,
|
|
12426
|
-
clientTools: statewireClientToolWireEntries(clientToolsRef.current)
|
|
12427
|
-
})
|
|
12428
|
-
),
|
|
12429
|
-
[aui]
|
|
12430
|
-
);
|
|
12431
|
-
return aui;
|
|
12432
13043
|
}
|
|
12433
13044
|
function readDetailMessage(detail) {
|
|
12434
13045
|
if (typeof detail === "string" && detail.length > 0) return detail;
|
|
12435
|
-
if (!isRecord$
|
|
13046
|
+
if (!isRecord$3(detail)) return null;
|
|
12436
13047
|
const message = detail.message;
|
|
12437
13048
|
return typeof message === "string" && message.length > 0 ? message : null;
|
|
12438
13049
|
}
|
|
@@ -12466,99 +13077,32 @@ function useAthenaStatewireLifecycle() {
|
|
|
12466
13077
|
return React.useContext(AthenaStatewireLifecycleContext);
|
|
12467
13078
|
}
|
|
12468
13079
|
const clientToolRequests = createClientToolRequestTracker();
|
|
12469
|
-
function requestKey(threadId, requestId) {
|
|
12470
|
-
return `${threadId}:${requestId}`;
|
|
12471
|
-
}
|
|
12472
|
-
function jsonSafeResult(value) {
|
|
12473
|
-
const serialized = JSON.stringify(value);
|
|
12474
|
-
return serialized === void 0 ? null : JSON.parse(serialized);
|
|
12475
|
-
}
|
|
12476
|
-
function isPendingClientToolRequest(request) {
|
|
12477
|
-
if (request.type !== "interrupt" || "response" in request) return false;
|
|
12478
|
-
return isClientToolInterrupt(request.payload);
|
|
12479
|
-
}
|
|
12480
13080
|
function StatewireClientToolBridge({
|
|
12481
13081
|
tools,
|
|
12482
13082
|
threadId
|
|
12483
13083
|
}) {
|
|
12484
13084
|
const sendCommand = reactStatewire.useStatewireSendCommand();
|
|
12485
13085
|
const inputRequests = reactStatewire.useStatewireRuns().inputRequests;
|
|
12486
|
-
const
|
|
12487
|
-
|
|
12488
|
-
|
|
12489
|
-
|
|
12490
|
-
|
|
12491
|
-
|
|
12492
|
-
ownedClaimsRef.current.delete(claim);
|
|
12493
|
-
clientToolRequests.release(claim);
|
|
12494
|
-
}, []);
|
|
12495
|
-
React.useEffect(() => {
|
|
12496
|
-
activeRef.current = true;
|
|
12497
|
-
return () => {
|
|
12498
|
-
activeRef.current = false;
|
|
12499
|
-
for (const claim of ownedClaimsRef.current) clientToolRequests.release(claim);
|
|
12500
|
-
ownedClaimsRef.current.clear();
|
|
12501
|
-
};
|
|
12502
|
-
}, []);
|
|
12503
|
-
const liveRequestIdsRef = React.useRef(/* @__PURE__ */ new Set());
|
|
12504
|
-
liveRequestIdsRef.current = new Set((inputRequests ?? []).map((request) => request.id));
|
|
12505
|
-
const executeRequest = React.useCallback(
|
|
12506
|
-
async (request) => {
|
|
12507
|
-
const payload = request.payload;
|
|
12508
|
-
if (!isClientToolInterrupt(payload)) return;
|
|
12509
|
-
const calls = payload.context.requests;
|
|
12510
|
-
const registry2 = new Map(toolsRef.current.map((tool) => [tool.name, tool]));
|
|
12511
|
-
const results = {};
|
|
12512
|
-
for (const call of calls) {
|
|
12513
|
-
if (!activeRef.current || !liveRequestIdsRef.current.has(request.id)) {
|
|
12514
|
-
releaseClaim(requestKey(threadId, request.id));
|
|
12515
|
-
return;
|
|
12516
|
-
}
|
|
12517
|
-
const tool = registry2.get(call.tool_name);
|
|
12518
|
-
if (!tool) {
|
|
12519
|
-
results[call.interrupt_id] = clientToolErrorEnvelope(
|
|
12520
|
-
`This surface has no tool named '${call.tool_name}'.`
|
|
12521
|
-
);
|
|
12522
|
-
continue;
|
|
12523
|
-
}
|
|
12524
|
-
try {
|
|
12525
|
-
results[call.interrupt_id] = clientToolSuccessEnvelope(
|
|
12526
|
-
jsonSafeResult(
|
|
12527
|
-
await tool.handler(clientToolCallArgs(call), {
|
|
12528
|
-
toolCallId: call.interrupt_id
|
|
12529
|
-
})
|
|
12530
|
-
)
|
|
12531
|
-
);
|
|
12532
|
-
} catch (error2) {
|
|
12533
|
-
results[call.interrupt_id] = clientToolErrorEnvelope(error2);
|
|
12534
|
-
}
|
|
12535
|
-
}
|
|
12536
|
-
if (!activeRef.current || !liveRequestIdsRef.current.has(request.id)) {
|
|
12537
|
-
releaseClaim(requestKey(threadId, request.id));
|
|
12538
|
-
return;
|
|
12539
|
-
}
|
|
12540
|
-
try {
|
|
12541
|
-
const wireValue = clientToolResultsResumeValue(results);
|
|
12542
|
-
sendCommand({
|
|
12543
|
-
type: "run/input",
|
|
12544
|
-
requestId: request.id,
|
|
12545
|
-
response: { type: "resume", value: wireValue }
|
|
12546
|
-
});
|
|
12547
|
-
ownedClaimsRef.current.delete(requestKey(threadId, request.id));
|
|
12548
|
-
} catch (error2) {
|
|
12549
|
-
releaseClaim(requestKey(threadId, request.id));
|
|
12550
|
-
console.error("[AthenaSDK] failed to resume client tool results:", error2);
|
|
12551
|
-
}
|
|
12552
|
-
},
|
|
12553
|
-
[releaseClaim, sendCommand, threadId]
|
|
13086
|
+
const bridgeTools = React.useMemo(
|
|
13087
|
+
() => tools.map((tool) => ({
|
|
13088
|
+
name: tool.name,
|
|
13089
|
+
run: (args, context) => tool.handler(args, context)
|
|
13090
|
+
})),
|
|
13091
|
+
[tools]
|
|
12554
13092
|
);
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
13093
|
+
useStatewireClientToolBridge({
|
|
13094
|
+
threadId,
|
|
13095
|
+
tools: bridgeTools,
|
|
13096
|
+
tracker: clientToolRequests,
|
|
13097
|
+
inputRequests,
|
|
13098
|
+
sendResume: (requestId, value) => {
|
|
13099
|
+
sendCommand({
|
|
13100
|
+
type: "run/input",
|
|
13101
|
+
requestId,
|
|
13102
|
+
response: { type: "resume", value }
|
|
13103
|
+
});
|
|
13104
|
+
}
|
|
13105
|
+
});
|
|
12562
13106
|
return null;
|
|
12563
13107
|
}
|
|
12564
13108
|
const ATHENA_TRANSPORTS = {
|
|
@@ -52819,7 +53363,7 @@ const DEFAULT_PILL_STYLE = "border-gray-300 bg-gray-50 text-gray-800 dark:border
|
|
|
52819
53363
|
function MentionNodeView({ node }) {
|
|
52820
53364
|
const { type, name, params } = node.attrs;
|
|
52821
53365
|
const config2 = getMentionConfig(type);
|
|
52822
|
-
const icon = isRecord$
|
|
53366
|
+
const icon = isRecord$3(params) && typeof params.icon === "string" ? params.icon : (config2 == null ? void 0 : config2.style.icon) ?? "📎";
|
|
52823
53367
|
const pillStyle = PILL_STYLES[type] ?? DEFAULT_PILL_STYLE;
|
|
52824
53368
|
return /* @__PURE__ */ jsxRuntime.jsx(NodeViewWrapper, { as: "span", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52825
53369
|
"span",
|
|
@@ -56271,102 +56815,103 @@ function Button({
|
|
|
56271
56815
|
}
|
|
56272
56816
|
);
|
|
56273
56817
|
}
|
|
56274
|
-
|
|
56275
|
-
|
|
56276
|
-
|
|
56277
|
-
|
|
56278
|
-
|
|
56279
|
-
|
|
56280
|
-
}
|
|
56281
|
-
|
|
56282
|
-
|
|
56283
|
-
|
|
56284
|
-
}
|
|
56285
|
-
|
|
56286
|
-
|
|
56287
|
-
|
|
56288
|
-
|
|
56289
|
-
|
|
56290
|
-
|
|
56291
|
-
|
|
56818
|
+
class AthenaChatErrorBoundary extends React.Component {
|
|
56819
|
+
constructor(props) {
|
|
56820
|
+
super(props);
|
|
56821
|
+
__publicField(this, "handleRetry", () => {
|
|
56822
|
+
this.setState((prev) => ({ error: null, retrySeq: prev.retrySeq + 1 }));
|
|
56823
|
+
});
|
|
56824
|
+
this.state = { error: null, retrySeq: 0 };
|
|
56825
|
+
}
|
|
56826
|
+
static getDerivedStateFromError(error2) {
|
|
56827
|
+
return { error: error2 };
|
|
56828
|
+
}
|
|
56829
|
+
componentDidCatch(error2, errorInfo) {
|
|
56830
|
+
var _a3;
|
|
56831
|
+
athenaDiagnostics.error(
|
|
56832
|
+
"sdk.error",
|
|
56833
|
+
error2,
|
|
56834
|
+
{
|
|
56835
|
+
code: "chat_render_crash",
|
|
56836
|
+
message: "The chat surface crashed while rendering",
|
|
56837
|
+
hint: "Inspect component_stack — a custom tool UI or message component is the usual culprit."
|
|
56838
|
+
},
|
|
56839
|
+
{ component_stack: ((_a3 = errorInfo.componentStack) == null ? void 0 : _a3.slice(0, 2e3)) ?? null }
|
|
56840
|
+
);
|
|
56841
|
+
}
|
|
56842
|
+
render() {
|
|
56843
|
+
if (this.state.error !== null) {
|
|
56844
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-h-48 flex-col items-center justify-center gap-3 p-6 text-center", children: [
|
|
56845
|
+
/* @__PURE__ */ jsxRuntime.jsx(CircleAlert, { className: "size-6 text-destructive" }),
|
|
56846
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
56847
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-foreground", children: "The chat hit an error" }),
|
|
56848
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Your conversation is safe on the server — reload the chat to continue." })
|
|
56849
|
+
] }),
|
|
56850
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "outline", size: "sm", onClick: this.handleRetry, children: [
|
|
56851
|
+
/* @__PURE__ */ jsxRuntime.jsx(RefreshCw, { className: "mr-1.5 size-3.5" }),
|
|
56852
|
+
"Reload chat"
|
|
56853
|
+
] })
|
|
56854
|
+
] });
|
|
56855
|
+
}
|
|
56856
|
+
return /* @__PURE__ */ jsxRuntime.jsx(React.Fragment, { children: this.props.children }, this.state.retrySeq);
|
|
56292
56857
|
}
|
|
56293
|
-
return "The agent is paused and waiting for input.";
|
|
56294
56858
|
}
|
|
56295
56859
|
const PENDING_RESUME_GRACE_MS = 15e3;
|
|
56296
|
-
const StatewireApprovalCard = () => {
|
|
56860
|
+
const StatewireApprovalCard = (props) => {
|
|
56297
56861
|
const extras = react$1.useAuiState((s) => s.thread.extras);
|
|
56298
56862
|
if (!hasStatewireThreadExtras(extras)) return null;
|
|
56299
|
-
return /* @__PURE__ */ jsxRuntime.jsx(StatewireApprovalCardInner, {});
|
|
56863
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StatewireApprovalCardInner, { ...props });
|
|
56300
56864
|
};
|
|
56301
|
-
const StatewireApprovalCardInner = (
|
|
56865
|
+
const StatewireApprovalCardInner = ({
|
|
56866
|
+
classNames,
|
|
56867
|
+
fallbackMessage,
|
|
56868
|
+
interruptPredicate = isApprovalCardInterrupt
|
|
56869
|
+
}) => {
|
|
56302
56870
|
var _a3, _b2, _c2, _d2, _e2;
|
|
56303
56871
|
const sendCommand = reactStatewire.useStatewireSendCommand();
|
|
56304
|
-
const request = (_a3 = reactStatewire.useStatewireRuns().inputRequests) == null ? void 0 : _a3.find(
|
|
56872
|
+
const request = (_a3 = reactStatewire.useStatewireRuns().inputRequests) == null ? void 0 : _a3.find(interruptPredicate);
|
|
56305
56873
|
const requestId = request == null ? void 0 : request.id;
|
|
56306
|
-
const abandoned = reactStatewire.useStatewireState(
|
|
56307
|
-
|
|
56308
|
-
);
|
|
56309
|
-
const abandonedInterrupt = abandoned == null ? void 0 : abandoned.find((r2) => r2.type === "interrupt");
|
|
56874
|
+
const abandoned = reactStatewire.useStatewireState(readAbandonedInputRequests);
|
|
56875
|
+
const abandonedInterrupt = findAbandonedInterrupt(abandoned);
|
|
56310
56876
|
const [dismissedId, setDismissedId] = React.useState();
|
|
56311
|
-
const [pending, setPending] = React.useState(false);
|
|
56312
|
-
const prevRequestIdRef = React.useRef(requestId);
|
|
56313
|
-
if (prevRequestIdRef.current !== requestId) {
|
|
56314
|
-
prevRequestIdRef.current = requestId;
|
|
56315
|
-
if (pending) setPending(false);
|
|
56316
|
-
}
|
|
56317
56877
|
const isRunning = react$1.useAuiState((s) => s.thread.isRunning);
|
|
56318
|
-
const
|
|
56319
|
-
|
|
56320
|
-
|
|
56321
|
-
|
|
56322
|
-
|
|
56323
|
-
|
|
56324
|
-
|
|
56325
|
-
|
|
56326
|
-
|
|
56327
|
-
|
|
56328
|
-
if (sawResumeRunRef.current) {
|
|
56329
|
-
sawResumeRunRef.current = false;
|
|
56330
|
-
setPending(false);
|
|
56331
|
-
}
|
|
56332
|
-
}, [pending, isRunning]);
|
|
56333
|
-
React.useEffect(() => {
|
|
56334
|
-
if (!pending) return;
|
|
56335
|
-
const timer = setTimeout(() => {
|
|
56336
|
-
if (!sawResumeRunRef.current) setPending(false);
|
|
56337
|
-
}, PENDING_RESUME_GRACE_MS);
|
|
56338
|
-
return () => clearTimeout(timer);
|
|
56339
|
-
}, [pending, requestId]);
|
|
56340
|
-
const resume = React.useCallback(
|
|
56341
|
-
(value) => {
|
|
56342
|
-
if (requestId === void 0) return;
|
|
56343
|
-
setPending(true);
|
|
56344
|
-
sendCommand({
|
|
56345
|
-
type: "run/input",
|
|
56346
|
-
requestId,
|
|
56347
|
-
response: { type: "resume", value }
|
|
56348
|
-
});
|
|
56349
|
-
},
|
|
56350
|
-
[sendCommand, requestId]
|
|
56351
|
-
);
|
|
56878
|
+
const { pending, resume } = useApprovalResumeLock({
|
|
56879
|
+
requestId,
|
|
56880
|
+
isRunning,
|
|
56881
|
+
pendingResumeGraceMs: PENDING_RESUME_GRACE_MS,
|
|
56882
|
+
sendResume: (id, value) => sendCommand({
|
|
56883
|
+
type: "run/input",
|
|
56884
|
+
requestId: id,
|
|
56885
|
+
response: { type: "resume", value }
|
|
56886
|
+
})
|
|
56887
|
+
});
|
|
56352
56888
|
if (!request) {
|
|
56353
56889
|
if (!abandonedInterrupt || abandonedInterrupt.id === dismissedId) return null;
|
|
56354
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
56355
|
-
|
|
56356
|
-
|
|
56357
|
-
|
|
56358
|
-
|
|
56359
|
-
|
|
56360
|
-
|
|
56361
|
-
|
|
56362
|
-
|
|
56363
|
-
|
|
56364
|
-
|
|
56365
|
-
|
|
56366
|
-
|
|
56890
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
56891
|
+
"div",
|
|
56892
|
+
{
|
|
56893
|
+
className: cn(
|
|
56894
|
+
"aui-approval-abandoned flex w-full items-center justify-between gap-3 rounded-xl border border-amber-300 bg-amber-50 px-3 py-2 text-amber-800 text-xs",
|
|
56895
|
+
classNames == null ? void 0 : classNames.abandoned
|
|
56896
|
+
),
|
|
56897
|
+
children: [
|
|
56898
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: "Approval was cancelled — the run moved on." }),
|
|
56899
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
56900
|
+
"button",
|
|
56901
|
+
{
|
|
56902
|
+
type: "button",
|
|
56903
|
+
"aria-label": "Dismiss cancelled approval",
|
|
56904
|
+
onClick: () => setDismissedId(abandonedInterrupt.id),
|
|
56905
|
+
className: "shrink-0 rounded-md p-1 hover:bg-amber-100",
|
|
56906
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(X, { className: "size-3.5" })
|
|
56907
|
+
}
|
|
56908
|
+
)
|
|
56909
|
+
]
|
|
56910
|
+
}
|
|
56911
|
+
);
|
|
56367
56912
|
}
|
|
56368
56913
|
const hitl = asHitlApproval(request.payload);
|
|
56369
|
-
const message = readInterruptMessage(request.payload);
|
|
56914
|
+
const message = readInterruptMessage(request.payload, fallbackMessage);
|
|
56370
56915
|
const toolName = ((_b2 = hitl == null ? void 0 : hitl.context) == null ? void 0 : _b2.tool_name) ?? ((_c2 = hitl == null ? void 0 : hitl.context) == null ? void 0 : _c2.tool_id);
|
|
56371
56916
|
const toolArgs = (_d2 = hitl == null ? void 0 : hitl.context) == null ? void 0 : _d2.tool_args;
|
|
56372
56917
|
const pendingCount = ((_e2 = hitl == null ? void 0 : hitl.context) == null ? void 0 : _e2.pending_action_count) ?? 1;
|
|
@@ -56374,7 +56919,10 @@ const StatewireApprovalCardInner = () => {
|
|
|
56374
56919
|
"section",
|
|
56375
56920
|
{
|
|
56376
56921
|
"aria-label": hitl ? "Approval required" : "Input required",
|
|
56377
|
-
className:
|
|
56922
|
+
className: cn(
|
|
56923
|
+
"aui-approval-card w-full rounded-2xl border border-amber-300 bg-amber-50 px-4 py-3 text-amber-900",
|
|
56924
|
+
classNames == null ? void 0 : classNames.root
|
|
56925
|
+
),
|
|
56378
56926
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
56379
56927
|
/* @__PURE__ */ jsxRuntime.jsx(TriangleAlert, { className: "mt-0.5 size-4 shrink-0" }),
|
|
56380
56928
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
@@ -56396,7 +56944,7 @@ const StatewireApprovalCardInner = () => {
|
|
|
56396
56944
|
{
|
|
56397
56945
|
size: "sm",
|
|
56398
56946
|
disabled: pending,
|
|
56399
|
-
onClick: () => resume(
|
|
56947
|
+
onClick: () => resume(hitlResumeApprove()),
|
|
56400
56948
|
className: "bg-green-600 text-white hover:bg-green-700",
|
|
56401
56949
|
children: [
|
|
56402
56950
|
/* @__PURE__ */ jsxRuntime.jsx(Check, {}),
|
|
@@ -56410,31 +56958,18 @@ const StatewireApprovalCardInner = () => {
|
|
|
56410
56958
|
size: "sm",
|
|
56411
56959
|
variant: "outline",
|
|
56412
56960
|
disabled: pending,
|
|
56413
|
-
onClick: () => resume(
|
|
56961
|
+
onClick: () => resume(hitlResumeReject()),
|
|
56414
56962
|
children: [
|
|
56415
56963
|
/* @__PURE__ */ jsxRuntime.jsx(X, {}),
|
|
56416
56964
|
"Reject"
|
|
56417
56965
|
]
|
|
56418
56966
|
}
|
|
56419
56967
|
)
|
|
56420
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
56421
|
-
Button,
|
|
56422
|
-
{
|
|
56423
|
-
size: "sm",
|
|
56424
|
-
disabled: pending,
|
|
56425
|
-
onClick: () => resume({ action: "continue" }),
|
|
56426
|
-
children: "Continue"
|
|
56427
|
-
}
|
|
56428
|
-
) })
|
|
56968
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", disabled: pending, onClick: () => resume(hitlResumeContinue()), children: "Continue" }) })
|
|
56429
56969
|
] })
|
|
56430
56970
|
}
|
|
56431
56971
|
);
|
|
56432
56972
|
};
|
|
56433
|
-
function queueItemText(parts) {
|
|
56434
|
-
return parts.flatMap(
|
|
56435
|
-
(part) => part.type === "text" && typeof part.text === "string" ? [part.text] : []
|
|
56436
|
-
).join("\n\n");
|
|
56437
|
-
}
|
|
56438
56973
|
const StatewireQueuedMessages = () => {
|
|
56439
56974
|
const extras = react$1.useAuiState((s) => s.thread.extras);
|
|
56440
56975
|
if (!hasStatewireThreadExtras(extras)) return null;
|
|
@@ -56445,12 +56980,8 @@ const StatewireQueuedMessagesInner = () => {
|
|
|
56445
56980
|
const status = useDeepAgentThreadStatus();
|
|
56446
56981
|
const aui = react$1.useAui();
|
|
56447
56982
|
const [expanded, setExpanded] = React.useState(true);
|
|
56448
|
-
const isRunning = status
|
|
56449
|
-
const
|
|
56450
|
-
const rows = [
|
|
56451
|
-
...isContinuable ? steerQueue.map((item) => ({ item, lane: "steer" })) : [],
|
|
56452
|
-
...queue.map((item) => ({ item, lane: "queue" }))
|
|
56453
|
-
];
|
|
56983
|
+
const { isRunning, isContinuable } = queueLaneFlags(status);
|
|
56984
|
+
const rows = buildStatewireQueueRows({ queue, steerQueue, isContinuable });
|
|
56454
56985
|
if (rows.length === 0) return null;
|
|
56455
56986
|
const queueHead = queue[0];
|
|
56456
56987
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -56498,8 +57029,8 @@ const StatewireQueuedMessagesInner = () => {
|
|
|
56498
57029
|
className: "max-h-40 overflow-y-auto",
|
|
56499
57030
|
"data-testid": "athena-statewire-queue",
|
|
56500
57031
|
children: rows.map(({ item, lane }, index2) => {
|
|
56501
|
-
const text2 =
|
|
56502
|
-
const showSendNow = lane
|
|
57032
|
+
const text2 = queueEntryText(item.parts);
|
|
57033
|
+
const showSendNow = showQueueRowSendNow({ lane, index: index2, isRunning, isContinuable });
|
|
56503
57034
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
56504
57035
|
"li",
|
|
56505
57036
|
{
|
|
@@ -62070,15 +62601,15 @@ const AthenaDefaultUserMessage = () => {
|
|
|
62070
62601
|
return /* @__PURE__ */ jsxRuntime.jsx(AthenaUserMessage, { TextComponent });
|
|
62071
62602
|
};
|
|
62072
62603
|
const getReasoningTokensFromMetadata = (metadata) => {
|
|
62073
|
-
if (!isRecord$
|
|
62604
|
+
if (!isRecord$3(metadata)) {
|
|
62074
62605
|
return void 0;
|
|
62075
62606
|
}
|
|
62076
62607
|
const customMetadata = metadata.custom;
|
|
62077
|
-
if (!isRecord$
|
|
62608
|
+
if (!isRecord$3(customMetadata)) {
|
|
62078
62609
|
return void 0;
|
|
62079
62610
|
}
|
|
62080
62611
|
const athenaMetadata = customMetadata._athena;
|
|
62081
|
-
if (!isRecord$
|
|
62612
|
+
if (!isRecord$3(athenaMetadata)) {
|
|
62082
62613
|
return void 0;
|
|
62083
62614
|
}
|
|
62084
62615
|
const reasoningTokens = athenaMetadata.reasoningTokens;
|
|
@@ -62173,7 +62704,7 @@ const AthenaChat = ({
|
|
|
62173
62704
|
);
|
|
62174
62705
|
const AssistantMessageComponent = (components == null ? void 0 : components.AssistantMessage) ?? AthenaDefaultAssistantMessage;
|
|
62175
62706
|
const UserMessageComponent = (components == null ? void 0 : components.UserMessage) ?? AthenaDefaultUserMessage;
|
|
62176
|
-
return /* @__PURE__ */ jsxRuntime.jsx(AthenaChatDefaultComponentsContext.Provider, { value: defaultComponentsContextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
62707
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AthenaChatDefaultComponentsContext.Provider, { value: defaultComponentsContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaChatErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
62177
62708
|
react$1.ThreadPrimitive.Root,
|
|
62178
62709
|
{
|
|
62179
62710
|
className: `aui-root aui-thread-root @container flex h-full flex-col bg-background ${className ?? ""}`,
|
|
@@ -62224,7 +62755,7 @@ const AthenaChat = ({
|
|
|
62224
62755
|
)
|
|
62225
62756
|
]
|
|
62226
62757
|
}
|
|
62227
|
-
) });
|
|
62758
|
+
) }) });
|
|
62228
62759
|
};
|
|
62229
62760
|
const ThreadLoadingOverlay = () => {
|
|
62230
62761
|
const remoteId = useAthenaThreadId();
|
|
@@ -63619,6 +64150,7 @@ exports.AthenaAssetEmbed = AthenaAssetEmbed;
|
|
|
63619
64150
|
exports.AthenaAssistantActionBar = AthenaAssistantActionBar;
|
|
63620
64151
|
exports.AthenaAssistantMessage = AthenaAssistantMessage;
|
|
63621
64152
|
exports.AthenaChat = AthenaChat;
|
|
64153
|
+
exports.AthenaChatErrorBoundary = AthenaChatErrorBoundary;
|
|
63622
64154
|
exports.AthenaLayout = AthenaLayout;
|
|
63623
64155
|
exports.AthenaProvider = AthenaProvider;
|
|
63624
64156
|
exports.AthenaReasoningPart = AthenaReasoningPart;
|