@blade-hq/agent-react 2610.0.0-beta.53 → 2610.0.0-beta.55
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 +29 -0
- package/dist/components/ConnectorPanel.d.ts +41 -0
- package/dist/components/PluginConnectorList.d.ts +47 -0
- package/dist/components/SessionPluginIcon.d.ts +5 -1
- package/dist/components/connector-panel-types.d.ts +35 -0
- package/dist/components/plugin-connector.d.ts +41 -0
- package/dist/components/use-session-plugin-activation.d.ts +40 -0
- package/dist/embed/entry.d.ts +3 -2
- package/dist/index.d.ts +10 -0
- package/dist/index.js +1195 -676
- package/dist/index.js.map +1 -1
- package/dist/style.full.css +1 -1
- package/package.json +2 -2
- package/public-api.md +226 -29
package/dist/index.js
CHANGED
|
@@ -1554,7 +1554,7 @@ var require_react_is_development = __commonJS({
|
|
|
1554
1554
|
var ContextProvider = REACT_PROVIDER_TYPE;
|
|
1555
1555
|
var Element = REACT_ELEMENT_TYPE;
|
|
1556
1556
|
var ForwardRef = REACT_FORWARD_REF_TYPE;
|
|
1557
|
-
var
|
|
1557
|
+
var Fragment10 = REACT_FRAGMENT_TYPE;
|
|
1558
1558
|
var Lazy = REACT_LAZY_TYPE;
|
|
1559
1559
|
var Memo = REACT_MEMO_TYPE;
|
|
1560
1560
|
var Portal = REACT_PORTAL_TYPE;
|
|
@@ -1622,7 +1622,7 @@ var require_react_is_development = __commonJS({
|
|
|
1622
1622
|
exports.ContextProvider = ContextProvider;
|
|
1623
1623
|
exports.Element = Element;
|
|
1624
1624
|
exports.ForwardRef = ForwardRef;
|
|
1625
|
-
exports.Fragment =
|
|
1625
|
+
exports.Fragment = Fragment10;
|
|
1626
1626
|
exports.Lazy = Lazy;
|
|
1627
1627
|
exports.Memo = Memo;
|
|
1628
1628
|
exports.Portal = Portal;
|
|
@@ -2888,10 +2888,10 @@ var X = createLucideIcon("X", [
|
|
|
2888
2888
|
]);
|
|
2889
2889
|
|
|
2890
2890
|
// src/components/AgentChat.tsx
|
|
2891
|
-
import { useCallback as
|
|
2891
|
+
import { useCallback as useCallback27, useEffect as useEffect21, useMemo as useMemo17, useRef as useRef23, useState as useState31 } from "react";
|
|
2892
2892
|
|
|
2893
2893
|
// src/components/SessionPluginSelector.tsx
|
|
2894
|
-
import { useEffect as
|
|
2894
|
+
import { useEffect as useEffect11, useState as useState16 } from "react";
|
|
2895
2895
|
|
|
2896
2896
|
// src/components/SessionPluginConfigDialog.tsx
|
|
2897
2897
|
import { useEffect as useEffect9, useRef as useRef9, useState as useState14 } from "react";
|
|
@@ -15469,6 +15469,13 @@ function presentationSchema(schema) {
|
|
|
15469
15469
|
}
|
|
15470
15470
|
return result;
|
|
15471
15471
|
}
|
|
15472
|
+
function ConfigMultiSchemaField(props) {
|
|
15473
|
+
return /* @__PURE__ */ jsxs("div", { className: "rjsf-field", children: [
|
|
15474
|
+
/* @__PURE__ */ jsx2("label", { htmlFor: isValidElement(props.selector) ? props.selector.props.id : void 0, children: "\u914D\u7F6E\u65B9\u5F0F" }),
|
|
15475
|
+
props.selector,
|
|
15476
|
+
props.optionSchemaField
|
|
15477
|
+
] });
|
|
15478
|
+
}
|
|
15472
15479
|
function ConfigSchemaField(inputProps) {
|
|
15473
15480
|
const path = inputProps.name === "" && inputProps.onKeyRename ? [...inputProps.fieldPathId.path, ""] : inputProps.fieldPathId.path;
|
|
15474
15481
|
const props = {
|
|
@@ -15658,17 +15665,7 @@ function SessionPluginConfigForm({
|
|
|
15658
15665
|
templates: {
|
|
15659
15666
|
FieldTemplate: ConfigFieldTemplate,
|
|
15660
15667
|
ArrayFieldItemTemplate: ConfigArrayItem,
|
|
15661
|
-
MultiSchemaFieldTemplate:
|
|
15662
|
-
/* @__PURE__ */ jsx2(
|
|
15663
|
-
"label",
|
|
15664
|
-
{
|
|
15665
|
-
htmlFor: isValidElement(props.selector) ? props.selector.props.id : void 0,
|
|
15666
|
-
children: "\u914D\u7F6E\u65B9\u5F0F"
|
|
15667
|
-
}
|
|
15668
|
-
),
|
|
15669
|
-
props.selector,
|
|
15670
|
-
props.optionSchemaField
|
|
15671
|
-
] }),
|
|
15668
|
+
MultiSchemaFieldTemplate: ConfigMultiSchemaField,
|
|
15672
15669
|
ButtonTemplates: {
|
|
15673
15670
|
...defaults.templates.ButtonTemplates,
|
|
15674
15671
|
AddButton: (props) => /* @__PURE__ */ jsx2(
|
|
@@ -15744,10 +15741,10 @@ function iconBlob(client, sessionId, name, token) {
|
|
|
15744
15741
|
blobCache = /* @__PURE__ */ new Map();
|
|
15745
15742
|
clientCaches.set(client, blobCache);
|
|
15746
15743
|
}
|
|
15747
|
-
const key = `${sessionId}:${name}:${token}`;
|
|
15744
|
+
const key = sessionId ? `${sessionId}:${name}:${token}` : `account:${name}:${token}`;
|
|
15748
15745
|
const cached2 = blobCache.get(key);
|
|
15749
15746
|
if (cached2) return cached2;
|
|
15750
|
-
const pending = client.sessions.fetchSessionPluginIcon(sessionId, name).catch(() => {
|
|
15747
|
+
const pending = (sessionId ? client.sessions.fetchSessionPluginIcon(sessionId, name) : client.plugins.fetchIcon(name)).catch(() => {
|
|
15751
15748
|
blobCache?.delete(key);
|
|
15752
15749
|
return null;
|
|
15753
15750
|
});
|
|
@@ -15760,7 +15757,7 @@ function SessionPluginIcon({ client, sessionId, plugin, className }) {
|
|
|
15760
15757
|
const token = plugin.icon;
|
|
15761
15758
|
useEffect8(() => {
|
|
15762
15759
|
setUrl(null);
|
|
15763
|
-
if (!token
|
|
15760
|
+
if (!token) return;
|
|
15764
15761
|
let alive = true;
|
|
15765
15762
|
let objectUrl = null;
|
|
15766
15763
|
void iconBlob(client, sessionId, plugin.name, token).then((blob) => {
|
|
@@ -15914,6 +15911,12 @@ function ConfigDialogState({
|
|
|
15914
15911
|
event.preventDefault();
|
|
15915
15912
|
onClose();
|
|
15916
15913
|
},
|
|
15914
|
+
onKeyDown: (event) => {
|
|
15915
|
+
if (event.key !== "Escape") return;
|
|
15916
|
+
event.preventDefault();
|
|
15917
|
+
event.stopPropagation();
|
|
15918
|
+
onClose();
|
|
15919
|
+
},
|
|
15917
15920
|
style: {
|
|
15918
15921
|
position: "fixed",
|
|
15919
15922
|
inset: 0,
|
|
@@ -15975,40 +15978,256 @@ function ConfigDialogState({
|
|
|
15975
15978
|
] });
|
|
15976
15979
|
}
|
|
15977
15980
|
|
|
15978
|
-
// src/components/
|
|
15981
|
+
// src/components/plugin-connector.ts
|
|
15982
|
+
function catalogToConnectorItems(catalog) {
|
|
15983
|
+
return catalog.map((entry) => ({
|
|
15984
|
+
name: entry.name,
|
|
15985
|
+
display_name: entry.display_name,
|
|
15986
|
+
icon: entry.icon,
|
|
15987
|
+
iconSource: "account",
|
|
15988
|
+
installed: entry.installed,
|
|
15989
|
+
active: false,
|
|
15990
|
+
status: "not_prepared",
|
|
15991
|
+
projected: false
|
|
15992
|
+
}));
|
|
15993
|
+
}
|
|
15994
|
+
function mergeConnectorItems(sessionPlugins, catalog) {
|
|
15995
|
+
const byName = new Map((catalog ?? []).map((entry) => [entry.name, entry]));
|
|
15996
|
+
return sessionPlugins.map((plugin) => {
|
|
15997
|
+
const entry = byName.get(plugin.name);
|
|
15998
|
+
if (!entry) {
|
|
15999
|
+
return {
|
|
16000
|
+
name: plugin.name,
|
|
16001
|
+
display_name: plugin.display_name ?? null,
|
|
16002
|
+
icon: plugin.icon ?? null,
|
|
16003
|
+
iconSource: "session",
|
|
16004
|
+
installed: plugin.installed,
|
|
16005
|
+
active: plugin.active,
|
|
16006
|
+
status: plugin.status,
|
|
16007
|
+
reason: plugin.reason,
|
|
16008
|
+
config: plugin.config,
|
|
16009
|
+
projected: plugin.projected
|
|
16010
|
+
};
|
|
16011
|
+
}
|
|
16012
|
+
return {
|
|
16013
|
+
name: plugin.name,
|
|
16014
|
+
display_name: entry.display_name ?? plugin.display_name ?? null,
|
|
16015
|
+
icon: entry.icon,
|
|
16016
|
+
iconSource: "account",
|
|
16017
|
+
installed: entry.installed,
|
|
16018
|
+
active: plugin.active,
|
|
16019
|
+
status: plugin.status,
|
|
16020
|
+
reason: plugin.reason,
|
|
16021
|
+
config: plugin.config,
|
|
16022
|
+
projected: plugin.projected
|
|
16023
|
+
};
|
|
16024
|
+
});
|
|
16025
|
+
}
|
|
16026
|
+
function pluginConnectorSummary(state) {
|
|
16027
|
+
if (state === "configured") return "\u914D\u7F6E\u5DF2\u4FDD\u5B58";
|
|
16028
|
+
if (state === "required") return "\u8FD8\u9700\u8981\u586B\u5199\u914D\u7F6E";
|
|
16029
|
+
if (state === "error") return "\u914D\u7F6E\u58F0\u660E\u6709\u95EE\u9898";
|
|
16030
|
+
return null;
|
|
16031
|
+
}
|
|
16032
|
+
function filterConnectorItems(items, query) {
|
|
16033
|
+
const needle = query.trim().toLowerCase();
|
|
16034
|
+
if (!needle) return items;
|
|
16035
|
+
return items.filter(
|
|
16036
|
+
(item) => `${item.display_name ?? ""} ${item.name}`.toLowerCase().includes(needle)
|
|
16037
|
+
);
|
|
16038
|
+
}
|
|
16039
|
+
|
|
16040
|
+
// src/components/PluginConnectorList.tsx
|
|
15979
16041
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
15980
|
-
function
|
|
15981
|
-
|
|
16042
|
+
function PluginSwitch({
|
|
16043
|
+
label,
|
|
16044
|
+
checked,
|
|
16045
|
+
pending,
|
|
16046
|
+
disabled,
|
|
16047
|
+
/** 首页的开关只是"这次输入的待选",不是"已经启用",措辞必须跟着分。 */
|
|
16048
|
+
draft = false,
|
|
16049
|
+
onToggle
|
|
16050
|
+
}) {
|
|
16051
|
+
return /* @__PURE__ */ jsx5(
|
|
16052
|
+
"button",
|
|
16053
|
+
{
|
|
16054
|
+
type: "button",
|
|
16055
|
+
role: "switch",
|
|
16056
|
+
"aria-checked": checked,
|
|
16057
|
+
"aria-label": draft ? `${label} \u5F85\u9009` : `${label} \u542F\u7528`,
|
|
16058
|
+
disabled,
|
|
16059
|
+
onClick: () => onToggle(!checked),
|
|
16060
|
+
className: `relative inline-flex h-[18px] w-8 shrink-0 cursor-pointer items-center rounded-full border transition-colors disabled:cursor-not-allowed disabled:opacity-50 ${checked ? "border-transparent bg-[hsl(213_94%_55%)]" : "border-[hsl(var(--border))] bg-[hsl(var(--muted))]"}`,
|
|
16061
|
+
children: /* @__PURE__ */ jsx5(
|
|
16062
|
+
"span",
|
|
16063
|
+
{
|
|
16064
|
+
"aria-hidden": "true",
|
|
16065
|
+
className: `pointer-events-none flex h-3.5 w-3.5 items-center justify-center rounded-full bg-white shadow transition-transform ${checked ? "translate-x-[16px]" : "translate-x-[2px]"}`,
|
|
16066
|
+
children: pending ? /* @__PURE__ */ jsx5(LoaderCircle, { size: 9, className: "animate-spin text-[hsl(var(--muted-foreground))]" }) : null
|
|
16067
|
+
}
|
|
16068
|
+
)
|
|
16069
|
+
}
|
|
16070
|
+
);
|
|
15982
16071
|
}
|
|
15983
|
-
function
|
|
15984
|
-
|
|
16072
|
+
function PluginConnectorList({
|
|
16073
|
+
client,
|
|
16074
|
+
sessionId,
|
|
16075
|
+
items,
|
|
16076
|
+
inFlight,
|
|
16077
|
+
busy,
|
|
16078
|
+
mutationError,
|
|
16079
|
+
onToggle,
|
|
16080
|
+
onRetry,
|
|
16081
|
+
onEditConfig,
|
|
16082
|
+
configuring,
|
|
16083
|
+
onConfigSaved,
|
|
16084
|
+
onConfigClose,
|
|
16085
|
+
disabledReason,
|
|
16086
|
+
unavailableText,
|
|
16087
|
+
emptyText,
|
|
16088
|
+
draft = false
|
|
16089
|
+
}) {
|
|
16090
|
+
const configuringItem = configuring ? items.find((item) => item.name === configuring.name) ?? null : null;
|
|
16091
|
+
return /* @__PURE__ */ jsxs3("div", { className: "py-0.5", children: [
|
|
16092
|
+
disabledReason ? /* @__PURE__ */ jsx5("div", { className: "px-3 py-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: disabledReason }) : null,
|
|
16093
|
+
items.length === 0 ? /* @__PURE__ */ jsx5("div", { className: "px-3 py-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: unavailableText ?? emptyText }) : null,
|
|
16094
|
+
items.map((item) => {
|
|
16095
|
+
const label = sessionPluginLabel(item);
|
|
16096
|
+
const summary = pluginConnectorSummary(item.config);
|
|
16097
|
+
const actionable = !disabledReason && item.installed !== false || item.active;
|
|
16098
|
+
const pending = Boolean(inFlight[item.name]);
|
|
16099
|
+
const checked = item.active;
|
|
16100
|
+
return /* @__PURE__ */ jsxs3("div", { className: "px-3 py-1", children: [
|
|
16101
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
|
|
16102
|
+
/* @__PURE__ */ jsx5(
|
|
16103
|
+
SessionPluginIcon,
|
|
16104
|
+
{
|
|
16105
|
+
client,
|
|
16106
|
+
sessionId: item.iconSource === "account" ? null : sessionId,
|
|
16107
|
+
plugin: item
|
|
16108
|
+
}
|
|
16109
|
+
),
|
|
16110
|
+
/* @__PURE__ */ jsx5("span", { className: "min-w-0 flex-1 truncate text-[11px]", title: label, children: label }),
|
|
16111
|
+
/* @__PURE__ */ jsx5(
|
|
16112
|
+
PluginSwitch,
|
|
16113
|
+
{
|
|
16114
|
+
label,
|
|
16115
|
+
checked,
|
|
16116
|
+
pending,
|
|
16117
|
+
draft,
|
|
16118
|
+
disabled: !actionable,
|
|
16119
|
+
onToggle: (next) => onToggle(item, next)
|
|
16120
|
+
}
|
|
16121
|
+
)
|
|
16122
|
+
] }),
|
|
16123
|
+
!draft && summary && item.config !== "not_required" ? /* @__PURE__ */ jsxs3("div", { className: "mt-0.5 flex items-center gap-2 pl-7 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
|
|
16124
|
+
/* @__PURE__ */ jsx5("span", { children: summary }),
|
|
16125
|
+
item.config === "configured" ? /* @__PURE__ */ jsx5(
|
|
16126
|
+
"button",
|
|
16127
|
+
{
|
|
16128
|
+
type: "button",
|
|
16129
|
+
disabled: busy || !sessionId,
|
|
16130
|
+
onClick: () => onEditConfig(item),
|
|
16131
|
+
className: "underline disabled:cursor-not-allowed disabled:opacity-50",
|
|
16132
|
+
children: "\u914D\u7F6E"
|
|
16133
|
+
}
|
|
16134
|
+
) : null
|
|
16135
|
+
] }) : null,
|
|
16136
|
+
!draft && item.active && item.status !== "valid" && item.status !== "required" ? /* @__PURE__ */ jsxs3("div", { className: "mt-0.5 flex items-center gap-2 pl-7 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
|
|
16137
|
+
/* @__PURE__ */ jsx5("span", { children: item.reason || "\u63D2\u4EF6\u6682\u4E0D\u53EF\u7528" }),
|
|
16138
|
+
/* @__PURE__ */ jsx5(
|
|
16139
|
+
"button",
|
|
16140
|
+
{
|
|
16141
|
+
type: "button",
|
|
16142
|
+
disabled: busy,
|
|
16143
|
+
onClick: () => onRetry(item),
|
|
16144
|
+
className: "underline disabled:cursor-not-allowed disabled:opacity-50",
|
|
16145
|
+
children: "\u91CD\u8BD5"
|
|
16146
|
+
}
|
|
16147
|
+
)
|
|
16148
|
+
] }) : null
|
|
16149
|
+
] }, item.name);
|
|
16150
|
+
}),
|
|
16151
|
+
mutationError ? /* @__PURE__ */ jsx5("div", { className: "px-3 pt-1 text-[10px] text-[hsl(var(--destructive))]", children: "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5" }) : null,
|
|
16152
|
+
configuring && configuringItem && sessionId ? /* @__PURE__ */ jsx5(
|
|
16153
|
+
SessionPluginConfigDialog,
|
|
16154
|
+
{
|
|
16155
|
+
client,
|
|
16156
|
+
sessionId,
|
|
16157
|
+
plugin: configuringItem,
|
|
16158
|
+
onSaved: onConfigSaved,
|
|
16159
|
+
onClose: onConfigClose
|
|
16160
|
+
}
|
|
16161
|
+
) : null
|
|
16162
|
+
] });
|
|
16163
|
+
}
|
|
16164
|
+
|
|
16165
|
+
// src/components/use-session-plugin-activation.ts
|
|
16166
|
+
import { useCallback as useCallback22, useEffect as useEffect10, useMemo as useMemo11, useRef as useRef10, useState as useState15 } from "react";
|
|
16167
|
+
function useSessionPluginActivation({
|
|
16168
|
+
client,
|
|
16169
|
+
sessionId,
|
|
16170
|
+
onChange
|
|
16171
|
+
}) {
|
|
15985
16172
|
const [plugins, setPlugins] = useState15([]);
|
|
16173
|
+
const [catalog, setCatalog] = useState15(null);
|
|
15986
16174
|
const [loading, setLoading] = useState15(false);
|
|
15987
|
-
const [busy, setBusy] = useState15(false);
|
|
15988
16175
|
const [listError, setListError] = useState15(false);
|
|
15989
16176
|
const [mutationError, setMutationError] = useState15(false);
|
|
16177
|
+
const [inFlight, setInFlight] = useState15({});
|
|
15990
16178
|
const [configuring, setConfiguring] = useState15(null);
|
|
15991
|
-
const latestPlugins = useRef10(plugins);
|
|
15992
|
-
latestPlugins.current = plugins;
|
|
15993
16179
|
const alive = useRef10(true);
|
|
15994
16180
|
const generation = useRef10(0);
|
|
15995
16181
|
const mutationGenerations = useRef10(/* @__PURE__ */ new Map());
|
|
15996
16182
|
const desiredActivations = useRef10(/* @__PURE__ */ new Map());
|
|
15997
16183
|
const pendingMutations = useRef10(/* @__PURE__ */ new Map());
|
|
16184
|
+
const submittedActivations = useRef10(/* @__PURE__ */ new Set());
|
|
16185
|
+
const serverActive = useRef10(/* @__PURE__ */ new Set());
|
|
15998
16186
|
const lifetime = useRef10(0);
|
|
15999
16187
|
const request = useRef10(null);
|
|
16188
|
+
const [desiredVersion, setDesiredVersion] = useState15(0);
|
|
16189
|
+
const setDesired = useCallback22((name, value) => {
|
|
16190
|
+
if (value === null) {
|
|
16191
|
+
if (!desiredActivations.current.delete(name)) return;
|
|
16192
|
+
} else {
|
|
16193
|
+
if (desiredActivations.current.get(name) === value) return;
|
|
16194
|
+
desiredActivations.current.set(name, value);
|
|
16195
|
+
}
|
|
16196
|
+
setDesiredVersion((version2) => version2 + 1);
|
|
16197
|
+
}, []);
|
|
16198
|
+
const items = useMemo11(() => {
|
|
16199
|
+
void desiredVersion;
|
|
16200
|
+
const merged = mergeConnectorItems(plugins, catalog);
|
|
16201
|
+
return merged.map((item) => {
|
|
16202
|
+
if (configuring?.name === item.name && configuring.pendingActivation) {
|
|
16203
|
+
return { ...item, active: false };
|
|
16204
|
+
}
|
|
16205
|
+
const desired = desiredActivations.current.get(item.name);
|
|
16206
|
+
return desired === void 0 ? item : { ...item, active: desired };
|
|
16207
|
+
});
|
|
16208
|
+
}, [catalog, configuring, desiredVersion, plugins]);
|
|
16209
|
+
const markInFlight = useCallback22((name, on) => {
|
|
16210
|
+
setInFlight((current) => {
|
|
16211
|
+
if (on) return current[name] ? current : { ...current, [name]: true };
|
|
16212
|
+
if (!current[name]) return current;
|
|
16213
|
+
const { [name]: removed, ...rest } = current;
|
|
16214
|
+
void removed;
|
|
16215
|
+
return rest;
|
|
16216
|
+
});
|
|
16217
|
+
}, []);
|
|
16000
16218
|
useEffect10(() => {
|
|
16001
16219
|
alive.current = true;
|
|
16002
16220
|
setPlugins([]);
|
|
16003
|
-
|
|
16221
|
+
setCatalog(null);
|
|
16004
16222
|
setLoading(false);
|
|
16005
|
-
setBusy(false);
|
|
16006
16223
|
setListError(false);
|
|
16007
16224
|
setMutationError(false);
|
|
16225
|
+
setInFlight({});
|
|
16008
16226
|
setConfiguring(null);
|
|
16009
16227
|
desiredActivations.current.clear();
|
|
16010
16228
|
mutationGenerations.current.clear();
|
|
16011
16229
|
pendingMutations.current.clear();
|
|
16230
|
+
submittedActivations.current.clear();
|
|
16012
16231
|
return () => {
|
|
16013
16232
|
alive.current = false;
|
|
16014
16233
|
lifetime.current++;
|
|
@@ -16016,7 +16235,7 @@ function PluginSelectorState({ client, sessionId, className, side = "bottom", on
|
|
|
16016
16235
|
request.current?.abort();
|
|
16017
16236
|
};
|
|
16018
16237
|
}, [client]);
|
|
16019
|
-
const load = async () => {
|
|
16238
|
+
const load = useCallback22(async () => {
|
|
16020
16239
|
if (!alive.current) return;
|
|
16021
16240
|
request.current?.abort();
|
|
16022
16241
|
const controller = new AbortController();
|
|
@@ -16027,136 +16246,245 @@ function PluginSelectorState({ client, sessionId, className, side = "bottom", on
|
|
|
16027
16246
|
try {
|
|
16028
16247
|
const result = await client.sessions.listSessionPlugins(sessionId, { signal: controller.signal });
|
|
16029
16248
|
if (alive.current && current === generation.current) {
|
|
16249
|
+
serverActive.current = new Set(result.plugins.filter((item) => item.active).map((item) => item.name));
|
|
16030
16250
|
setPlugins(result.plugins.map((item) => {
|
|
16031
|
-
const pending = pendingMutations.current.has(item.name);
|
|
16032
16251
|
const desired = desiredActivations.current.get(item.name);
|
|
16033
|
-
return
|
|
16252
|
+
return desired === void 0 ? item : { ...item, active: desired };
|
|
16034
16253
|
}));
|
|
16035
|
-
setConfiguring((current2) => {
|
|
16036
|
-
const fresh = result.plugins.find((item) => item.name === current2?.name);
|
|
16037
|
-
return current2 && fresh ? { ...current2, display_name: fresh.display_name, icon: fresh.icon } : current2;
|
|
16038
|
-
});
|
|
16039
16254
|
}
|
|
16040
16255
|
} catch {
|
|
16041
16256
|
if (alive.current && current === generation.current && !controller.signal.aborted) setListError(true);
|
|
16042
16257
|
} finally {
|
|
16043
16258
|
if (alive.current && current === generation.current) setLoading(false);
|
|
16044
16259
|
}
|
|
16045
|
-
};
|
|
16046
|
-
const
|
|
16047
|
-
|
|
16048
|
-
|
|
16049
|
-
|
|
16050
|
-
|
|
16051
|
-
|
|
16260
|
+
}, [client, sessionId]);
|
|
16261
|
+
const loadCatalog = useCallback22(async () => {
|
|
16262
|
+
try {
|
|
16263
|
+
const { plugins: entries } = await client.plugins.catalog();
|
|
16264
|
+
if (alive.current) setCatalog(entries);
|
|
16265
|
+
} catch {
|
|
16266
|
+
}
|
|
16267
|
+
}, [client]);
|
|
16268
|
+
const reload = useCallback22(() => {
|
|
16269
|
+
void load();
|
|
16270
|
+
void loadCatalog();
|
|
16271
|
+
}, [load, loadCatalog]);
|
|
16272
|
+
const abandon = useCallback22((name) => {
|
|
16273
|
+
setDesired(name, null);
|
|
16274
|
+
pendingMutations.current.delete(name);
|
|
16275
|
+
mutationGenerations.current.set(name, (mutationGenerations.current.get(name) ?? 0) + 1);
|
|
16276
|
+
markInFlight(name, false);
|
|
16277
|
+
void load();
|
|
16278
|
+
}, [load, markInFlight, setDesired]);
|
|
16279
|
+
const finish = useCallback22((name, mutation) => {
|
|
16280
|
+
pendingMutations.current.delete(name);
|
|
16281
|
+
setDesired(name, null);
|
|
16282
|
+
if (mutation === mutationGenerations.current.get(name)) markInFlight(name, false);
|
|
16283
|
+
}, [markInFlight, setDesired]);
|
|
16284
|
+
const commitActivation = useCallback22(
|
|
16285
|
+
async (name, active, mutation, startedAt) => {
|
|
16286
|
+
submittedActivations.current.add(name);
|
|
16287
|
+
try {
|
|
16288
|
+
const { plugin } = await client.sessions.setSessionPluginActivation(sessionId, name, active);
|
|
16289
|
+
if (!alive.current || startedAt !== lifetime.current) return;
|
|
16290
|
+
if (mutation !== mutationGenerations.current.get(name)) {
|
|
16291
|
+
const desired = desiredActivations.current.get(name);
|
|
16292
|
+
if (desired !== void 0 && desired !== plugin.active) {
|
|
16293
|
+
const next = (mutationGenerations.current.get(name) ?? 0) + 1;
|
|
16294
|
+
mutationGenerations.current.set(name, next);
|
|
16295
|
+
pendingMutations.current.set(name, next);
|
|
16296
|
+
markInFlight(name, true);
|
|
16297
|
+
await commitActivation(name, desired, next, startedAt);
|
|
16298
|
+
}
|
|
16299
|
+
return;
|
|
16300
|
+
}
|
|
16301
|
+
if (active) serverActive.current.add(name);
|
|
16302
|
+
else serverActive.current.delete(name);
|
|
16303
|
+
finish(name, mutation);
|
|
16304
|
+
setPlugins((current) => current.map((item) => item.name === plugin.name ? { ...item, ...plugin } : item));
|
|
16305
|
+
onChange?.(plugin);
|
|
16306
|
+
if (plugin.active && plugin.status === "required") {
|
|
16307
|
+
setConfiguring({ name: plugin.name, pendingActivation: true });
|
|
16308
|
+
}
|
|
16309
|
+
await load();
|
|
16310
|
+
} catch {
|
|
16311
|
+
if (alive.current && startedAt === lifetime.current && mutation === mutationGenerations.current.get(name)) {
|
|
16312
|
+
pendingMutations.current.delete(name);
|
|
16313
|
+
submittedActivations.current.delete(name);
|
|
16314
|
+
setDesired(name, null);
|
|
16315
|
+
markInFlight(name, false);
|
|
16316
|
+
setMutationError(true);
|
|
16317
|
+
void load();
|
|
16318
|
+
}
|
|
16319
|
+
}
|
|
16320
|
+
},
|
|
16321
|
+
[client, finish, load, markInFlight, onChange, sessionId, setDesired]
|
|
16322
|
+
);
|
|
16323
|
+
const enable = useCallback22(async (name) => {
|
|
16324
|
+
if (!alive.current) return;
|
|
16325
|
+
const startedAt = lifetime.current;
|
|
16326
|
+
const mutation = (mutationGenerations.current.get(name) ?? 0) + 1;
|
|
16327
|
+
mutationGenerations.current.set(name, mutation);
|
|
16328
|
+
pendingMutations.current.set(name, mutation);
|
|
16329
|
+
setDesired(name, true);
|
|
16330
|
+
setMutationError(false);
|
|
16331
|
+
markInFlight(name, true);
|
|
16052
16332
|
request.current?.abort();
|
|
16053
16333
|
generation.current++;
|
|
16054
16334
|
setLoading(false);
|
|
16055
|
-
|
|
16056
|
-
setMutationError(false);
|
|
16057
|
-
setPlugins((current) => current.map((item) => item.name === name ? { ...item, active } : item));
|
|
16335
|
+
let state;
|
|
16058
16336
|
try {
|
|
16059
|
-
const
|
|
16060
|
-
if (!alive.current ||
|
|
16061
|
-
|
|
16062
|
-
const desired = desiredActivations.current.get(name);
|
|
16063
|
-
if (desired !== void 0 && desired !== plugin.active) void select(name, desired);
|
|
16064
|
-
return;
|
|
16065
|
-
}
|
|
16066
|
-
pendingMutations.current.delete(name);
|
|
16067
|
-
setBusy(pendingMutations.current.size > 0);
|
|
16068
|
-
setPlugins((current) => current.map((item) => item.name === plugin.name ? { ...item, ...plugin } : item));
|
|
16069
|
-
onChange?.(plugin);
|
|
16070
|
-
if (plugin.active && plugin.status === "required") {
|
|
16071
|
-
const row = latestPlugins.current.find((item) => item.name === plugin.name);
|
|
16072
|
-
if (row) setConfiguring({ ...row, ...plugin });
|
|
16073
|
-
}
|
|
16074
|
-
await load();
|
|
16337
|
+
const result = await client.sessions.prepareSessionPluginConfig(sessionId, name);
|
|
16338
|
+
if (!alive.current || startedAt !== lifetime.current || mutation !== mutationGenerations.current.get(name)) return;
|
|
16339
|
+
state = result.config;
|
|
16075
16340
|
} catch {
|
|
16076
|
-
if (alive.current
|
|
16077
|
-
|
|
16078
|
-
|
|
16079
|
-
|
|
16080
|
-
|
|
16081
|
-
|
|
16341
|
+
if (!alive.current || startedAt !== lifetime.current || mutation !== mutationGenerations.current.get(name)) return;
|
|
16342
|
+
abandon(name);
|
|
16343
|
+
setMutationError(true);
|
|
16344
|
+
return;
|
|
16345
|
+
}
|
|
16346
|
+
if (state.state === "required") {
|
|
16347
|
+
pendingMutations.current.delete(name);
|
|
16348
|
+
markInFlight(name, false);
|
|
16349
|
+
setConfiguring({ name, pendingActivation: true });
|
|
16350
|
+
return;
|
|
16351
|
+
}
|
|
16352
|
+
if (state.state !== "configured" && state.state !== "not_required") {
|
|
16353
|
+
abandon(name);
|
|
16354
|
+
setMutationError(true);
|
|
16355
|
+
return;
|
|
16082
16356
|
}
|
|
16083
|
-
};
|
|
16084
|
-
const finishPreparation = async (name, state) => {
|
|
16085
16357
|
setPlugins((current) => current.map((item) => item.name === name ? { ...item, config: state.state } : item));
|
|
16086
|
-
|
|
16087
|
-
|
|
16088
|
-
|
|
16358
|
+
await commitActivation(name, true, mutation, startedAt);
|
|
16359
|
+
}, [abandon, client, commitActivation, markInFlight, sessionId, setDesired]);
|
|
16360
|
+
const disable = useCallback22((name) => {
|
|
16361
|
+
const startedAt = lifetime.current;
|
|
16362
|
+
request.current?.abort();
|
|
16363
|
+
generation.current++;
|
|
16364
|
+
setLoading(false);
|
|
16365
|
+
if (!submittedActivations.current.has(name) && !serverActive.current.has(name)) {
|
|
16366
|
+
abandon(name);
|
|
16367
|
+
return;
|
|
16368
|
+
}
|
|
16369
|
+
const mutation = (mutationGenerations.current.get(name) ?? 0) + 1;
|
|
16370
|
+
mutationGenerations.current.set(name, mutation);
|
|
16371
|
+
pendingMutations.current.set(name, mutation);
|
|
16372
|
+
setDesired(name, false);
|
|
16373
|
+
setMutationError(false);
|
|
16374
|
+
markInFlight(name, true);
|
|
16375
|
+
void commitActivation(name, false, mutation, startedAt);
|
|
16376
|
+
}, [abandon, commitActivation, markInFlight, setDesired]);
|
|
16377
|
+
const toggle = useCallback22((item, next) => {
|
|
16378
|
+
if (next) void enable(item.name);
|
|
16379
|
+
else disable(item.name);
|
|
16380
|
+
}, [disable, enable]);
|
|
16381
|
+
const retry = useCallback22((item) => {
|
|
16382
|
+
void enable(item.name);
|
|
16383
|
+
}, [enable]);
|
|
16384
|
+
const editConfig = useCallback22((item) => {
|
|
16385
|
+
setConfiguring({ name: item.name, pendingActivation: false });
|
|
16386
|
+
}, []);
|
|
16387
|
+
const onConfigSaved = useCallback22((state) => {
|
|
16388
|
+
const target = configuring;
|
|
16389
|
+
if (!target) return;
|
|
16390
|
+
setConfiguring(null);
|
|
16391
|
+
setPlugins((current) => current.map((item) => item.name === target.name ? { ...item, config: state.state } : item));
|
|
16392
|
+
if (!target.pendingActivation || state.state !== "configured") {
|
|
16393
|
+
void load();
|
|
16089
16394
|
return;
|
|
16090
16395
|
}
|
|
16091
|
-
|
|
16396
|
+
const startedAt = lifetime.current;
|
|
16397
|
+
const mutation = (mutationGenerations.current.get(target.name) ?? 0) + 1;
|
|
16398
|
+
mutationGenerations.current.set(target.name, mutation);
|
|
16399
|
+
pendingMutations.current.set(target.name, mutation);
|
|
16400
|
+
setDesired(target.name, true);
|
|
16401
|
+
markInFlight(target.name, true);
|
|
16402
|
+
void commitActivation(target.name, true, mutation, startedAt);
|
|
16403
|
+
}, [commitActivation, configuring, load, markInFlight, setDesired]);
|
|
16404
|
+
const onConfigClose = useCallback22(() => {
|
|
16405
|
+
const target = configuring;
|
|
16406
|
+
if (!target) return;
|
|
16407
|
+
setConfiguring(null);
|
|
16408
|
+
if (target.pendingActivation) abandon(target.name);
|
|
16409
|
+
else void load();
|
|
16410
|
+
}, [abandon, configuring, load]);
|
|
16411
|
+
return {
|
|
16412
|
+
items,
|
|
16413
|
+
loading,
|
|
16414
|
+
listError,
|
|
16415
|
+
mutationError,
|
|
16416
|
+
inFlight,
|
|
16417
|
+
busy: Object.keys(inFlight).length > 0,
|
|
16418
|
+
configuring,
|
|
16419
|
+
reload,
|
|
16420
|
+
toggle,
|
|
16421
|
+
retry,
|
|
16422
|
+
editConfig,
|
|
16423
|
+
onConfigSaved,
|
|
16424
|
+
onConfigClose
|
|
16092
16425
|
};
|
|
16093
|
-
|
|
16094
|
-
|
|
16426
|
+
}
|
|
16427
|
+
|
|
16428
|
+
// src/components/SessionPluginSelector.tsx
|
|
16429
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
16430
|
+
function SessionPluginSelector(props) {
|
|
16431
|
+
return /* @__PURE__ */ jsx6(PluginSelectorState, { ...props }, props.sessionId);
|
|
16432
|
+
}
|
|
16433
|
+
function PluginSelectorState({ client, sessionId, className, side = "bottom", onChange }) {
|
|
16434
|
+
const [open2, setOpen] = useState16(false);
|
|
16435
|
+
return /* @__PURE__ */ jsxs4("div", { className: `relative text-xs ${className ?? ""}`, children: [
|
|
16436
|
+
/* @__PURE__ */ jsx6(
|
|
16095
16437
|
"button",
|
|
16096
16438
|
{
|
|
16097
16439
|
type: "button",
|
|
16098
16440
|
disabled: !sessionId,
|
|
16099
16441
|
"aria-expanded": open2,
|
|
16100
|
-
onClick: () =>
|
|
16101
|
-
setOpen(!open2);
|
|
16102
|
-
if (!open2) void load();
|
|
16103
|
-
},
|
|
16442
|
+
onClick: () => setOpen(!open2),
|
|
16104
16443
|
className: "rounded-full border border-[hsl(var(--border))] px-2.5 py-1",
|
|
16105
16444
|
children: "\u4F1A\u8BDD\u63D2\u4EF6"
|
|
16106
16445
|
}
|
|
16107
16446
|
),
|
|
16108
|
-
open2 ? /* @__PURE__ */
|
|
16109
|
-
loading ? /* @__PURE__ */ jsx5("div", { children: "\u6B63\u5728\u83B7\u53D6\u63D2\u4EF6\u2026" }) : null,
|
|
16110
|
-
listError ? /* @__PURE__ */ jsx5("button", { type: "button", onClick: () => void load(), children: "\u63D2\u4EF6\u5217\u8868\u6682\u4E0D\u53EF\u7528\uFF0C\u70B9\u51FB\u91CD\u8BD5" }) : null,
|
|
16111
|
-
!loading && !listError && !plugins.length ? /* @__PURE__ */ jsx5("div", { children: "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6" }) : null,
|
|
16112
|
-
plugins.map((plugin) => /* @__PURE__ */ jsxs3("div", { className: "py-1", children: [
|
|
16113
|
-
/* @__PURE__ */ jsxs3("label", { className: "flex items-center justify-between gap-2", children: [
|
|
16114
|
-
/* @__PURE__ */ jsxs3("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
16115
|
-
/* @__PURE__ */ jsx5(SessionPluginIcon, { client, sessionId, plugin }),
|
|
16116
|
-
/* @__PURE__ */ jsx5("span", { className: "min-w-0 truncate", title: sessionPluginLabel(plugin), children: sessionPluginLabel(plugin) })
|
|
16117
|
-
] }),
|
|
16118
|
-
/* @__PURE__ */ jsx5(
|
|
16119
|
-
"input",
|
|
16120
|
-
{
|
|
16121
|
-
type: "checkbox",
|
|
16122
|
-
className: "shrink-0",
|
|
16123
|
-
checked: plugin.active,
|
|
16124
|
-
disabled: busy && !plugin.active || !plugin.installed && !plugin.active,
|
|
16125
|
-
onChange: (event) => void select(plugin.name, event.target.checked),
|
|
16126
|
-
"aria-label": `${plugin.name} \u4F1A\u8BDD\u6FC0\u6D3B`
|
|
16127
|
-
}
|
|
16128
|
-
)
|
|
16129
|
-
] }),
|
|
16130
|
-
plugin.status === "required" ? /* @__PURE__ */ jsxs3("div", { className: "text-[hsl(var(--muted-foreground))]", children: [
|
|
16131
|
-
plugin.reason || "\u8FD8\u9700\u8981\u586B\u5199\u914D\u7F6E",
|
|
16132
|
-
/* @__PURE__ */ jsx5("button", { type: "button", disabled: busy, onClick: () => setConfiguring(plugin), className: "ml-2 underline", children: "\u586B\u5199\u914D\u7F6E" })
|
|
16133
|
-
] }) : plugin.active && plugin.status !== "valid" ? /* @__PURE__ */ jsxs3("div", { className: "text-[hsl(var(--muted-foreground))]", children: [
|
|
16134
|
-
plugin.reason || "\u63D2\u4EF6\u6682\u4E0D\u53EF\u7528",
|
|
16135
|
-
/* @__PURE__ */ jsx5("button", { type: "button", disabled: busy, onClick: () => void select(plugin.name, true), className: "ml-2 underline", children: "\u91CD\u8BD5" })
|
|
16136
|
-
] }) : plugin.config && plugin.config !== "not_required" ? /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 text-[hsl(var(--muted-foreground))]", children: [
|
|
16137
|
-
configSummary(plugin.config) ? /* @__PURE__ */ jsx5("span", { children: configSummary(plugin.config) }) : null,
|
|
16138
|
-
/* @__PURE__ */ jsx5("button", { type: "button", disabled: !sessionId, onClick: () => setConfiguring(plugin), className: "underline", children: "\u914D\u7F6E" })
|
|
16139
|
-
] }) : null
|
|
16140
|
-
] }, plugin.name)),
|
|
16141
|
-
mutationError ? /* @__PURE__ */ jsx5("div", { children: "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u91CD\u8BD5" }) : null
|
|
16142
|
-
] }) : null,
|
|
16143
|
-
configuring ? /* @__PURE__ */ jsx5(
|
|
16144
|
-
SessionPluginConfigDialog,
|
|
16145
|
-
{
|
|
16146
|
-
client,
|
|
16147
|
-
sessionId,
|
|
16148
|
-
plugin: configuring,
|
|
16149
|
-
onSaved: (state) => void finishPreparation(configuring.name, state),
|
|
16150
|
-
onClose: () => setConfiguring(null)
|
|
16151
|
-
}
|
|
16152
|
-
) : null
|
|
16447
|
+
open2 ? /* @__PURE__ */ jsx6(PluginSelectorList, { client, sessionId, side, onChange }) : null
|
|
16153
16448
|
] });
|
|
16154
16449
|
}
|
|
16155
|
-
function
|
|
16156
|
-
|
|
16157
|
-
|
|
16158
|
-
|
|
16159
|
-
|
|
16450
|
+
function PluginSelectorList({
|
|
16451
|
+
client,
|
|
16452
|
+
sessionId,
|
|
16453
|
+
side,
|
|
16454
|
+
onChange
|
|
16455
|
+
}) {
|
|
16456
|
+
const controller = useSessionPluginActivation({ client, sessionId, onChange });
|
|
16457
|
+
const { reload } = controller;
|
|
16458
|
+
useEffect11(() => {
|
|
16459
|
+
reload();
|
|
16460
|
+
}, [reload]);
|
|
16461
|
+
return /* @__PURE__ */ jsxs4(
|
|
16462
|
+
"div",
|
|
16463
|
+
{
|
|
16464
|
+
className: `absolute left-0 z-40 my-2 max-h-72 w-72 max-w-[calc(100vw-2rem)] overflow-y-auto rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--popover))] p-3 text-[hsl(var(--popover-foreground))] shadow-lg ${side === "top" ? "bottom-full" : "top-full"}`,
|
|
16465
|
+
children: [
|
|
16466
|
+
controller.listError ? /* @__PURE__ */ jsx6("button", { type: "button", onClick: reload, children: "\u63D2\u4EF6\u5217\u8868\u6682\u4E0D\u53EF\u7528\uFF0C\u70B9\u51FB\u91CD\u8BD5" }) : null,
|
|
16467
|
+
/* @__PURE__ */ jsx6(
|
|
16468
|
+
PluginConnectorList,
|
|
16469
|
+
{
|
|
16470
|
+
client,
|
|
16471
|
+
sessionId,
|
|
16472
|
+
items: controller.items,
|
|
16473
|
+
inFlight: controller.inFlight,
|
|
16474
|
+
busy: controller.busy,
|
|
16475
|
+
mutationError: controller.mutationError,
|
|
16476
|
+
onToggle: controller.toggle,
|
|
16477
|
+
onRetry: controller.retry,
|
|
16478
|
+
onEditConfig: controller.editConfig,
|
|
16479
|
+
configuring: controller.configuring,
|
|
16480
|
+
onConfigSaved: controller.onConfigSaved,
|
|
16481
|
+
onConfigClose: controller.onConfigClose,
|
|
16482
|
+
emptyText: "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6"
|
|
16483
|
+
}
|
|
16484
|
+
)
|
|
16485
|
+
]
|
|
16486
|
+
}
|
|
16487
|
+
);
|
|
16160
16488
|
}
|
|
16161
16489
|
|
|
16162
16490
|
// src/components/SessionQueuePanel.tsx
|
|
@@ -16167,7 +16495,7 @@ import {
|
|
|
16167
16495
|
queuePauseReasonLabel,
|
|
16168
16496
|
queuedMessageStatusLabel
|
|
16169
16497
|
} from "@blade-hq/agent-client";
|
|
16170
|
-
import { useRef as useRef11, useState as
|
|
16498
|
+
import { useRef as useRef11, useState as useState17 } from "react";
|
|
16171
16499
|
|
|
16172
16500
|
// src/lib/utils.ts
|
|
16173
16501
|
function cn(...inputs) {
|
|
@@ -16199,7 +16527,7 @@ async function copyToClipboard(text) {
|
|
|
16199
16527
|
}
|
|
16200
16528
|
|
|
16201
16529
|
// src/components/SessionQueuePanel.tsx
|
|
16202
|
-
import { Fragment as Fragment4, jsx as
|
|
16530
|
+
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
16203
16531
|
var ACTION_BUTTON = "flex h-6 w-6 items-center justify-center rounded text-[hsl(var(--muted-foreground))] transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:bg-transparent";
|
|
16204
16532
|
function SessionQueuePanel({
|
|
16205
16533
|
snapshot,
|
|
@@ -16214,13 +16542,13 @@ function SessionQueuePanel({
|
|
|
16214
16542
|
onReorder,
|
|
16215
16543
|
onDeliver
|
|
16216
16544
|
}) {
|
|
16217
|
-
const [collapsed, setCollapsed] =
|
|
16218
|
-
const [editing, setEditing] =
|
|
16545
|
+
const [collapsed, setCollapsed] = useState17(false);
|
|
16546
|
+
const [editing, setEditing] = useState17(
|
|
16219
16547
|
null
|
|
16220
16548
|
);
|
|
16221
|
-
const [draggingId, setDraggingId] =
|
|
16549
|
+
const [draggingId, setDraggingId] = useState17(null);
|
|
16222
16550
|
const requeuePending = useRef11(false);
|
|
16223
|
-
const [requeueing, setRequeueing] =
|
|
16551
|
+
const [requeueing, setRequeueing] = useState17(false);
|
|
16224
16552
|
const items = snapshot.items;
|
|
16225
16553
|
if (items.length === 0 && !snapshot.paused && !notice && !editing) return null;
|
|
16226
16554
|
const pendingIds = items.filter(canEditQueuedMessage).map((item) => item.id);
|
|
@@ -16259,23 +16587,23 @@ function SessionQueuePanel({
|
|
|
16259
16587
|
next.splice(to, 0, sourceId);
|
|
16260
16588
|
onReorder(next);
|
|
16261
16589
|
};
|
|
16262
|
-
return /* @__PURE__ */
|
|
16590
|
+
return /* @__PURE__ */ jsx7(
|
|
16263
16591
|
"section",
|
|
16264
16592
|
{
|
|
16265
16593
|
className: "blade-chat-queue shrink-0 border-t border-[hsl(var(--border))] px-4 pt-3",
|
|
16266
16594
|
"aria-label": "\u5F85\u6267\u884C\u6D88\u606F",
|
|
16267
|
-
children: /* @__PURE__ */
|
|
16268
|
-
/* @__PURE__ */
|
|
16269
|
-
/* @__PURE__ */
|
|
16595
|
+
children: /* @__PURE__ */ jsxs5("div", { className: "mx-auto max-w-[748px]", children: [
|
|
16596
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
16597
|
+
/* @__PURE__ */ jsxs5("span", { className: "font-medium text-[hsl(var(--foreground))]", children: [
|
|
16270
16598
|
"\u5F85\u6267\u884C \xB7 ",
|
|
16271
16599
|
items.length
|
|
16272
16600
|
] }),
|
|
16273
|
-
snapshot.paused && /* @__PURE__ */
|
|
16274
|
-
/* @__PURE__ */
|
|
16275
|
-
/* @__PURE__ */
|
|
16601
|
+
snapshot.paused && /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
16602
|
+
/* @__PURE__ */ jsxs5("span", { className: "inline-flex items-center gap-1 text-[hsl(var(--destructive))]", children: [
|
|
16603
|
+
/* @__PURE__ */ jsx7(CirclePause, { size: 12 }),
|
|
16276
16604
|
pauseLabel
|
|
16277
16605
|
] }),
|
|
16278
|
-
/* @__PURE__ */
|
|
16606
|
+
/* @__PURE__ */ jsx7(
|
|
16279
16607
|
"button",
|
|
16280
16608
|
{
|
|
16281
16609
|
type: "button",
|
|
@@ -16285,7 +16613,7 @@ function SessionQueuePanel({
|
|
|
16285
16613
|
}
|
|
16286
16614
|
)
|
|
16287
16615
|
] }),
|
|
16288
|
-
collapsible && /* @__PURE__ */
|
|
16616
|
+
collapsible && /* @__PURE__ */ jsxs5(
|
|
16289
16617
|
"button",
|
|
16290
16618
|
{
|
|
16291
16619
|
type: "button",
|
|
@@ -16294,18 +16622,18 @@ function SessionQueuePanel({
|
|
|
16294
16622
|
className: "ml-auto inline-flex items-center gap-1 rounded-md px-1.5 py-0.5 transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
|
|
16295
16623
|
children: [
|
|
16296
16624
|
collapsed ? "\u5C55\u5F00" : "\u6298\u53E0",
|
|
16297
|
-
/* @__PURE__ */
|
|
16625
|
+
/* @__PURE__ */ jsx7(ChevronDown, { size: 12, className: cn(!collapsed && "rotate-180") })
|
|
16298
16626
|
]
|
|
16299
16627
|
}
|
|
16300
16628
|
)
|
|
16301
16629
|
] }),
|
|
16302
|
-
notice && /* @__PURE__ */
|
|
16303
|
-
/* @__PURE__ */
|
|
16304
|
-
/* @__PURE__ */
|
|
16630
|
+
notice && /* @__PURE__ */ jsxs5("div", { className: "blade-chat-queue-notice mt-2 flex items-start gap-1.5 text-xs text-[hsl(var(--destructive))]", children: [
|
|
16631
|
+
/* @__PURE__ */ jsx7(CircleAlert, { size: 13, className: "mt-0.5 shrink-0" }),
|
|
16632
|
+
/* @__PURE__ */ jsx7("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: notice })
|
|
16305
16633
|
] }),
|
|
16306
|
-
detachedEdit && /* @__PURE__ */
|
|
16307
|
-
/* @__PURE__ */
|
|
16308
|
-
/* @__PURE__ */
|
|
16634
|
+
detachedEdit && /* @__PURE__ */ jsxs5("div", { className: "mt-2 flex flex-col gap-2 text-xs", children: [
|
|
16635
|
+
/* @__PURE__ */ jsx7("span", { children: "\u539F\u6D88\u606F\u5DF2\u53D8\u5316\uFF0C\u4FEE\u6539\u5185\u5BB9\u5DF2\u4FDD\u7559" }),
|
|
16636
|
+
/* @__PURE__ */ jsx7(
|
|
16309
16637
|
"textarea",
|
|
16310
16638
|
{
|
|
16311
16639
|
"aria-label": "\u4FDD\u7559\u7684\u4FEE\u6539\u5185\u5BB9",
|
|
@@ -16315,9 +16643,9 @@ function SessionQueuePanel({
|
|
|
16315
16643
|
className: "w-full rounded border border-[hsl(var(--border))] bg-transparent p-2"
|
|
16316
16644
|
}
|
|
16317
16645
|
),
|
|
16318
|
-
/* @__PURE__ */
|
|
16319
|
-
/* @__PURE__ */
|
|
16320
|
-
onRequeue && /* @__PURE__ */
|
|
16646
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex justify-end gap-2", children: [
|
|
16647
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "rounded border border-[hsl(var(--border))] px-2 py-1", disabled: requeueing, onClick: stopEdit, children: "\u653E\u5F03\u4FEE\u6539" }),
|
|
16648
|
+
onRequeue && /* @__PURE__ */ jsx7("button", { type: "button", className: "rounded bg-[hsl(var(--primary))] px-2 py-1 text-[hsl(var(--primary-foreground))] disabled:opacity-40", disabled: requeueing || !detachedEdit.text.trim(), onClick: async () => {
|
|
16321
16649
|
if (requeuePending.current) return;
|
|
16322
16650
|
requeuePending.current = true;
|
|
16323
16651
|
setRequeueing(true);
|
|
@@ -16333,7 +16661,7 @@ function SessionQueuePanel({
|
|
|
16333
16661
|
}, children: "\u4F5C\u4E3A\u65B0\u6D88\u606F\u6392\u961F" })
|
|
16334
16662
|
] })
|
|
16335
16663
|
] }),
|
|
16336
|
-
/* @__PURE__ */
|
|
16664
|
+
/* @__PURE__ */ jsx7("ul", { className: "mt-2 flex max-h-56 flex-col gap-1.5 overflow-y-auto", children: visibleItems.map((item) => {
|
|
16337
16665
|
const position = items.indexOf(item) + 1;
|
|
16338
16666
|
const pending = canEditQueuedMessage(item);
|
|
16339
16667
|
const busy = pendingItemId === item.id;
|
|
@@ -16341,7 +16669,7 @@ function SessionQueuePanel({
|
|
|
16341
16669
|
const pendingIndex = pendingIds.indexOf(item.id);
|
|
16342
16670
|
const statusLabel = queuedMessageStatusLabel(item.status);
|
|
16343
16671
|
const deliverable = canDeliver && canDeliverQueuedMessage(item);
|
|
16344
|
-
return /* @__PURE__ */
|
|
16672
|
+
return /* @__PURE__ */ jsxs5(
|
|
16345
16673
|
"li",
|
|
16346
16674
|
{
|
|
16347
16675
|
draggable: pending && !busy,
|
|
@@ -16360,9 +16688,9 @@ function SessionQueuePanel({
|
|
|
16360
16688
|
draggingId === item.id && "opacity-40"
|
|
16361
16689
|
),
|
|
16362
16690
|
children: [
|
|
16363
|
-
/* @__PURE__ */
|
|
16364
|
-
/* @__PURE__ */
|
|
16365
|
-
/* @__PURE__ */
|
|
16691
|
+
/* @__PURE__ */ jsx7("span", { className: "mt-0.5 w-4 shrink-0 text-right tabular-nums text-[hsl(var(--muted-foreground))]", children: position }),
|
|
16692
|
+
/* @__PURE__ */ jsx7("div", { className: "min-w-0 flex-1", children: isEditing ? /* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-1.5", children: [
|
|
16693
|
+
/* @__PURE__ */ jsx7(
|
|
16366
16694
|
"textarea",
|
|
16367
16695
|
{
|
|
16368
16696
|
value: activeEdit?.text ?? "",
|
|
@@ -16374,8 +16702,8 @@ function SessionQueuePanel({
|
|
|
16374
16702
|
className: "w-full resize-none rounded border border-[hsl(var(--border))] bg-transparent px-1.5 py-1 text-xs leading-5 text-[hsl(var(--foreground))] outline-none"
|
|
16375
16703
|
}
|
|
16376
16704
|
),
|
|
16377
|
-
/* @__PURE__ */
|
|
16378
|
-
/* @__PURE__ */
|
|
16705
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex justify-end gap-1.5", children: [
|
|
16706
|
+
/* @__PURE__ */ jsx7(
|
|
16379
16707
|
"button",
|
|
16380
16708
|
{
|
|
16381
16709
|
type: "button",
|
|
@@ -16384,7 +16712,7 @@ function SessionQueuePanel({
|
|
|
16384
16712
|
children: "\u53D6\u6D88"
|
|
16385
16713
|
}
|
|
16386
16714
|
),
|
|
16387
|
-
/* @__PURE__ */
|
|
16715
|
+
/* @__PURE__ */ jsx7(
|
|
16388
16716
|
"button",
|
|
16389
16717
|
{
|
|
16390
16718
|
type: "button",
|
|
@@ -16395,19 +16723,19 @@ function SessionQueuePanel({
|
|
|
16395
16723
|
}
|
|
16396
16724
|
)
|
|
16397
16725
|
] })
|
|
16398
|
-
] }) : /* @__PURE__ */
|
|
16399
|
-
/* @__PURE__ */
|
|
16400
|
-
/* @__PURE__ */
|
|
16401
|
-
statusLabel && /* @__PURE__ */
|
|
16402
|
-
busy && /* @__PURE__ */
|
|
16403
|
-
/* @__PURE__ */
|
|
16726
|
+
] }) : /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
16727
|
+
/* @__PURE__ */ jsx7("div", { className: "line-clamp-2 whitespace-pre-wrap break-words text-[hsl(var(--foreground))]", children: item.content }),
|
|
16728
|
+
/* @__PURE__ */ jsxs5("div", { className: "mt-0.5 flex items-center gap-2 text-[hsl(var(--muted-foreground))]", children: [
|
|
16729
|
+
statusLabel && /* @__PURE__ */ jsx7("span", { children: statusLabel }),
|
|
16730
|
+
busy && /* @__PURE__ */ jsxs5("span", { className: "inline-flex items-center gap-1", children: [
|
|
16731
|
+
/* @__PURE__ */ jsx7(LoaderCircle, { size: 11, className: "animate-spin" }),
|
|
16404
16732
|
"\u5904\u7406\u4E2D"
|
|
16405
16733
|
] }),
|
|
16406
|
-
item.error && /* @__PURE__ */
|
|
16734
|
+
item.error && /* @__PURE__ */ jsx7("span", { className: "text-[hsl(var(--destructive))]", children: item.error })
|
|
16407
16735
|
] })
|
|
16408
16736
|
] }) }),
|
|
16409
|
-
/* @__PURE__ */
|
|
16410
|
-
/* @__PURE__ */
|
|
16737
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex shrink-0 items-center gap-0.5", children: [
|
|
16738
|
+
/* @__PURE__ */ jsx7(
|
|
16411
16739
|
"button",
|
|
16412
16740
|
{
|
|
16413
16741
|
type: "button",
|
|
@@ -16416,10 +16744,10 @@ function SessionQueuePanel({
|
|
|
16416
16744
|
disabled: busy || pendingIndex <= 0,
|
|
16417
16745
|
onClick: () => onMove(item, -1),
|
|
16418
16746
|
className: ACTION_BUTTON,
|
|
16419
|
-
children: /* @__PURE__ */
|
|
16747
|
+
children: /* @__PURE__ */ jsx7(ChevronUp, { size: 13 })
|
|
16420
16748
|
}
|
|
16421
16749
|
),
|
|
16422
|
-
/* @__PURE__ */
|
|
16750
|
+
/* @__PURE__ */ jsx7(
|
|
16423
16751
|
"button",
|
|
16424
16752
|
{
|
|
16425
16753
|
type: "button",
|
|
@@ -16428,10 +16756,10 @@ function SessionQueuePanel({
|
|
|
16428
16756
|
disabled: busy || pendingIndex < 0 || pendingIndex >= pendingIds.length - 1,
|
|
16429
16757
|
onClick: () => onMove(item, 1),
|
|
16430
16758
|
className: ACTION_BUTTON,
|
|
16431
|
-
children: /* @__PURE__ */
|
|
16759
|
+
children: /* @__PURE__ */ jsx7(ChevronDown, { size: 13 })
|
|
16432
16760
|
}
|
|
16433
16761
|
),
|
|
16434
|
-
/* @__PURE__ */
|
|
16762
|
+
/* @__PURE__ */ jsx7(
|
|
16435
16763
|
"button",
|
|
16436
16764
|
{
|
|
16437
16765
|
type: "button",
|
|
@@ -16440,10 +16768,10 @@ function SessionQueuePanel({
|
|
|
16440
16768
|
disabled: busy || !canEditQueuedMessage(item),
|
|
16441
16769
|
onClick: () => startEdit(item),
|
|
16442
16770
|
className: ACTION_BUTTON,
|
|
16443
|
-
children: /* @__PURE__ */
|
|
16771
|
+
children: /* @__PURE__ */ jsx7(Pencil, { size: 12 })
|
|
16444
16772
|
}
|
|
16445
16773
|
),
|
|
16446
|
-
/* @__PURE__ */
|
|
16774
|
+
/* @__PURE__ */ jsx7(
|
|
16447
16775
|
"button",
|
|
16448
16776
|
{
|
|
16449
16777
|
type: "button",
|
|
@@ -16452,10 +16780,10 @@ function SessionQueuePanel({
|
|
|
16452
16780
|
disabled: busy || !canCancelQueuedMessage(item),
|
|
16453
16781
|
onClick: () => onCancel(item),
|
|
16454
16782
|
className: ACTION_BUTTON,
|
|
16455
|
-
children: /* @__PURE__ */
|
|
16783
|
+
children: /* @__PURE__ */ jsx7(Trash2, { size: 12 })
|
|
16456
16784
|
}
|
|
16457
16785
|
),
|
|
16458
|
-
/* @__PURE__ */
|
|
16786
|
+
/* @__PURE__ */ jsx7(
|
|
16459
16787
|
"button",
|
|
16460
16788
|
{
|
|
16461
16789
|
type: "button",
|
|
@@ -16464,7 +16792,7 @@ function SessionQueuePanel({
|
|
|
16464
16792
|
disabled: busy || !deliverable,
|
|
16465
16793
|
onClick: () => onDeliver(item),
|
|
16466
16794
|
className: ACTION_BUTTON,
|
|
16467
|
-
children: /* @__PURE__ */
|
|
16795
|
+
children: /* @__PURE__ */ jsx7(Send, { size: 12 })
|
|
16468
16796
|
}
|
|
16469
16797
|
)
|
|
16470
16798
|
] })
|
|
@@ -16479,7 +16807,7 @@ function SessionQueuePanel({
|
|
|
16479
16807
|
}
|
|
16480
16808
|
|
|
16481
16809
|
// src/components/ReplayBar.tsx
|
|
16482
|
-
import { jsx as
|
|
16810
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
16483
16811
|
var SPEED_OPTIONS = [1, 2, 5];
|
|
16484
16812
|
function ReplayBar({
|
|
16485
16813
|
isReplay,
|
|
@@ -16490,7 +16818,7 @@ function ReplayBar({
|
|
|
16490
16818
|
className
|
|
16491
16819
|
}) {
|
|
16492
16820
|
if (!isReplay) return null;
|
|
16493
|
-
return /* @__PURE__ */
|
|
16821
|
+
return /* @__PURE__ */ jsxs6(
|
|
16494
16822
|
"div",
|
|
16495
16823
|
{
|
|
16496
16824
|
className: cn(
|
|
@@ -16498,13 +16826,13 @@ function ReplayBar({
|
|
|
16498
16826
|
className
|
|
16499
16827
|
),
|
|
16500
16828
|
children: [
|
|
16501
|
-
/* @__PURE__ */
|
|
16502
|
-
/* @__PURE__ */
|
|
16829
|
+
/* @__PURE__ */ jsxs6("span", { className: "inline-flex items-center gap-1.5 font-medium text-[hsl(var(--foreground))]", children: [
|
|
16830
|
+
/* @__PURE__ */ jsx8(Play, { size: 13 }),
|
|
16503
16831
|
"\u56DE\u653E\u6A21\u5F0F"
|
|
16504
16832
|
] }),
|
|
16505
|
-
/* @__PURE__ */
|
|
16506
|
-
/* @__PURE__ */
|
|
16507
|
-
/* @__PURE__ */
|
|
16833
|
+
/* @__PURE__ */ jsx8("span", { className: "text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u91CD\u73B0\u4E4B\u524D\u7684\u5BF9\u8BDD" }),
|
|
16834
|
+
/* @__PURE__ */ jsxs6("div", { className: "ml-auto flex items-center gap-2", children: [
|
|
16835
|
+
/* @__PURE__ */ jsx8("div", { className: "flex items-center gap-0.5 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-0.5", children: SPEED_OPTIONS.map((option) => /* @__PURE__ */ jsxs6(
|
|
16508
16836
|
"button",
|
|
16509
16837
|
{
|
|
16510
16838
|
type: "button",
|
|
@@ -16523,7 +16851,7 @@ function ReplayBar({
|
|
|
16523
16851
|
},
|
|
16524
16852
|
option
|
|
16525
16853
|
)) }),
|
|
16526
|
-
/* @__PURE__ */
|
|
16854
|
+
/* @__PURE__ */ jsx8(
|
|
16527
16855
|
"button",
|
|
16528
16856
|
{
|
|
16529
16857
|
type: "button",
|
|
@@ -16543,10 +16871,10 @@ function ReplayBar({
|
|
|
16543
16871
|
}
|
|
16544
16872
|
|
|
16545
16873
|
// src/components/ReplayMismatchPrompt.tsx
|
|
16546
|
-
import { jsx as
|
|
16874
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
16547
16875
|
function ReplayMismatchPrompt({ mismatch, className }) {
|
|
16548
16876
|
if (!mismatch) return null;
|
|
16549
|
-
return /* @__PURE__ */
|
|
16877
|
+
return /* @__PURE__ */ jsxs7(
|
|
16550
16878
|
"div",
|
|
16551
16879
|
{
|
|
16552
16880
|
className: cn(
|
|
@@ -16554,19 +16882,19 @@ function ReplayMismatchPrompt({ mismatch, className }) {
|
|
|
16554
16882
|
className
|
|
16555
16883
|
),
|
|
16556
16884
|
children: [
|
|
16557
|
-
/* @__PURE__ */
|
|
16558
|
-
/* @__PURE__ */
|
|
16559
|
-
/* @__PURE__ */
|
|
16560
|
-
/* @__PURE__ */
|
|
16561
|
-
/* @__PURE__ */
|
|
16885
|
+
/* @__PURE__ */ jsx9("div", { className: "font-medium text-[hsl(var(--foreground))]", children: "\u8FD9\u53E5\u8BDD\u548C\u4E4B\u524D\u5F55\u5236\u7684\u4E0D\u4E00\u6837" }),
|
|
16886
|
+
/* @__PURE__ */ jsxs7("dl", { className: "mt-2 space-y-1 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
16887
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex gap-2", children: [
|
|
16888
|
+
/* @__PURE__ */ jsx9("dt", { className: "shrink-0", children: "\u5F55\u5236\u7684\u662F" }),
|
|
16889
|
+
/* @__PURE__ */ jsx9("dd", { className: "min-w-0 break-words text-[hsl(var(--foreground))]", children: mismatch.expectedMessage || "\uFF08\u7A7A\uFF09" })
|
|
16562
16890
|
] }),
|
|
16563
|
-
/* @__PURE__ */
|
|
16564
|
-
/* @__PURE__ */
|
|
16565
|
-
/* @__PURE__ */
|
|
16891
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex gap-2", children: [
|
|
16892
|
+
/* @__PURE__ */ jsx9("dt", { className: "shrink-0", children: "\u4F60\u8F93\u5165\u7684" }),
|
|
16893
|
+
/* @__PURE__ */ jsx9("dd", { className: "min-w-0 break-words text-[hsl(var(--foreground))]", children: mismatch.actualMessage || "\uFF08\u7A7A\uFF09" })
|
|
16566
16894
|
] })
|
|
16567
16895
|
] }),
|
|
16568
|
-
/* @__PURE__ */
|
|
16569
|
-
/* @__PURE__ */
|
|
16896
|
+
/* @__PURE__ */ jsxs7("div", { className: "mt-3 flex flex-wrap gap-2", children: [
|
|
16897
|
+
/* @__PURE__ */ jsx9(
|
|
16570
16898
|
"button",
|
|
16571
16899
|
{
|
|
16572
16900
|
type: "button",
|
|
@@ -16575,7 +16903,7 @@ function ReplayMismatchPrompt({ mismatch, className }) {
|
|
|
16575
16903
|
children: "\u6309\u5F55\u5236\u5185\u5BB9\u7EE7\u7EED"
|
|
16576
16904
|
}
|
|
16577
16905
|
),
|
|
16578
|
-
/* @__PURE__ */
|
|
16906
|
+
/* @__PURE__ */ jsx9(
|
|
16579
16907
|
"button",
|
|
16580
16908
|
{
|
|
16581
16909
|
type: "button",
|
|
@@ -16591,7 +16919,7 @@ function ReplayMismatchPrompt({ mismatch, className }) {
|
|
|
16591
16919
|
}
|
|
16592
16920
|
|
|
16593
16921
|
// src/components/PlanUpdateBlock.tsx
|
|
16594
|
-
import { useEffect as
|
|
16922
|
+
import { useEffect as useEffect12, useRef as useRef12, useState as useState18 } from "react";
|
|
16595
16923
|
|
|
16596
16924
|
// src/components/display-utils.ts
|
|
16597
16925
|
var TOOL_NAME_ALIASES = {
|
|
@@ -16735,7 +17063,7 @@ function formatToolResult(result) {
|
|
|
16735
17063
|
}
|
|
16736
17064
|
|
|
16737
17065
|
// src/components/PlanUpdateBlock.tsx
|
|
16738
|
-
import { jsx as
|
|
17066
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
16739
17067
|
var PLAN_STEP_STATUSES = /* @__PURE__ */ new Set(["pending", "in_progress", "completed"]);
|
|
16740
17068
|
var PLAN_AUTO_COLLAPSE_MS = 5e3;
|
|
16741
17069
|
function isPlanUpdateTool(toolCall) {
|
|
@@ -16790,12 +17118,12 @@ function PlanStepIcon({
|
|
|
16790
17118
|
running = false
|
|
16791
17119
|
}) {
|
|
16792
17120
|
if (status === "completed") {
|
|
16793
|
-
return /* @__PURE__ */
|
|
17121
|
+
return /* @__PURE__ */ jsx10(Check, { size, strokeWidth: 2, className: "shrink-0 text-emerald-500" });
|
|
16794
17122
|
}
|
|
16795
17123
|
if (status === "in_progress") {
|
|
16796
|
-
return running ? /* @__PURE__ */
|
|
17124
|
+
return running ? /* @__PURE__ */ jsx10(LoaderCircle, { size, className: "shrink-0 animate-spin text-[hsl(var(--muted-foreground))]" }) : /* @__PURE__ */ jsx10(CircleDot, { size, className: "shrink-0 text-amber-500" });
|
|
16797
17125
|
}
|
|
16798
|
-
return /* @__PURE__ */
|
|
17126
|
+
return /* @__PURE__ */ jsx10(Circle, { size, className: "shrink-0 text-[hsl(var(--muted-foreground))]/60" });
|
|
16799
17127
|
}
|
|
16800
17128
|
function PlanUpdateBlock({
|
|
16801
17129
|
toolCall,
|
|
@@ -16804,10 +17132,10 @@ function PlanUpdateBlock({
|
|
|
16804
17132
|
}) {
|
|
16805
17133
|
const updateKey = `${toolCall.id}:${toolCall.arguments}`;
|
|
16806
17134
|
const revealKey = autoReveal ? updateKey : null;
|
|
16807
|
-
const [collapsed, setCollapsed] =
|
|
17135
|
+
const [collapsed, setCollapsed] = useState18(!autoReveal);
|
|
16808
17136
|
const collapseTimerRef = useRef12(null);
|
|
16809
17137
|
const data = parsePlanUpdate(toolCall.arguments);
|
|
16810
|
-
|
|
17138
|
+
useEffect12(() => {
|
|
16811
17139
|
if (!revealKey) return;
|
|
16812
17140
|
if (collapseTimerRef.current) clearTimeout(collapseTimerRef.current);
|
|
16813
17141
|
setCollapsed(false);
|
|
@@ -16816,7 +17144,7 @@ function PlanUpdateBlock({
|
|
|
16816
17144
|
collapseTimerRef.current = null;
|
|
16817
17145
|
}, PLAN_AUTO_COLLAPSE_MS);
|
|
16818
17146
|
}, [revealKey]);
|
|
16819
|
-
|
|
17147
|
+
useEffect12(
|
|
16820
17148
|
() => () => {
|
|
16821
17149
|
if (collapseTimerRef.current) clearTimeout(collapseTimerRef.current);
|
|
16822
17150
|
},
|
|
@@ -16826,8 +17154,8 @@ function PlanUpdateBlock({
|
|
|
16826
17154
|
const completed = data.plan.filter((item) => item.status === "completed").length;
|
|
16827
17155
|
const currentStep = pickCurrentPlanStep(data.plan);
|
|
16828
17156
|
const pausedAtCurrentStep = !running && currentStep?.status === "in_progress";
|
|
16829
|
-
return /* @__PURE__ */
|
|
16830
|
-
/* @__PURE__ */
|
|
17157
|
+
return /* @__PURE__ */ jsxs8("section", { className: "overflow-hidden", children: [
|
|
17158
|
+
/* @__PURE__ */ jsxs8(
|
|
16831
17159
|
"button",
|
|
16832
17160
|
{
|
|
16833
17161
|
type: "button",
|
|
@@ -16844,21 +17172,21 @@ function PlanUpdateBlock({
|
|
|
16844
17172
|
!collapsed && "border-b border-[hsl(var(--border))]"
|
|
16845
17173
|
),
|
|
16846
17174
|
children: [
|
|
16847
|
-
collapsed && currentStep ? /* @__PURE__ */
|
|
16848
|
-
/* @__PURE__ */
|
|
16849
|
-
/* @__PURE__ */
|
|
16850
|
-
pausedAtCurrentStep ? /* @__PURE__ */
|
|
16851
|
-
] }) : /* @__PURE__ */
|
|
16852
|
-
/* @__PURE__ */
|
|
16853
|
-
/* @__PURE__ */
|
|
16854
|
-
pausedAtCurrentStep ? /* @__PURE__ */
|
|
17175
|
+
collapsed && currentStep ? /* @__PURE__ */ jsxs8("span", { className: "flex min-w-0 flex-1 items-center gap-1.5 text-xs text-[hsl(var(--foreground))]", children: [
|
|
17176
|
+
/* @__PURE__ */ jsx10(PlanStepIcon, { status: currentStep.status, size: 14, running }),
|
|
17177
|
+
/* @__PURE__ */ jsx10("span", { className: "truncate", children: currentStep.step }),
|
|
17178
|
+
pausedAtCurrentStep ? /* @__PURE__ */ jsx10("span", { className: "shrink-0 text-[11px] text-amber-500", children: "\u5DF2\u6682\u505C" }) : null
|
|
17179
|
+
] }) : /* @__PURE__ */ jsxs8("span", { className: "flex min-w-0 flex-1 items-center gap-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
17180
|
+
/* @__PURE__ */ jsx10(ListChecks, { size: 14, className: "shrink-0", "aria-hidden": "true" }),
|
|
17181
|
+
/* @__PURE__ */ jsx10("span", { className: "truncate", children: "\u4EFB\u52A1\u8FDB\u5EA6" }),
|
|
17182
|
+
pausedAtCurrentStep ? /* @__PURE__ */ jsx10("span", { className: "shrink-0 text-amber-500", children: "\u5DF2\u6682\u505C" }) : null
|
|
16855
17183
|
] }),
|
|
16856
|
-
/* @__PURE__ */
|
|
17184
|
+
/* @__PURE__ */ jsxs8("span", { className: "shrink-0 text-[11px] tabular-nums text-[hsl(var(--muted-foreground))]", children: [
|
|
16857
17185
|
completed,
|
|
16858
17186
|
"/",
|
|
16859
17187
|
data.plan.length
|
|
16860
17188
|
] }),
|
|
16861
|
-
/* @__PURE__ */
|
|
17189
|
+
/* @__PURE__ */ jsx10(
|
|
16862
17190
|
ChevronDown,
|
|
16863
17191
|
{
|
|
16864
17192
|
size: 14,
|
|
@@ -16871,7 +17199,7 @@ function PlanUpdateBlock({
|
|
|
16871
17199
|
]
|
|
16872
17200
|
}
|
|
16873
17201
|
),
|
|
16874
|
-
/* @__PURE__ */
|
|
17202
|
+
/* @__PURE__ */ jsx10(
|
|
16875
17203
|
"div",
|
|
16876
17204
|
{
|
|
16877
17205
|
"aria-hidden": collapsed,
|
|
@@ -16879,9 +17207,9 @@ function PlanUpdateBlock({
|
|
|
16879
17207
|
"grid transition-[grid-template-rows,opacity] duration-300 ease-out motion-reduce:transition-none",
|
|
16880
17208
|
collapsed ? "grid-rows-[0fr] opacity-0" : "grid-rows-[1fr] opacity-100"
|
|
16881
17209
|
),
|
|
16882
|
-
children: /* @__PURE__ */
|
|
16883
|
-
/* @__PURE__ */
|
|
16884
|
-
/* @__PURE__ */
|
|
17210
|
+
children: /* @__PURE__ */ jsx10("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ jsx10("div", { className: "flex max-h-40 flex-col gap-0.5 overflow-y-auto px-3 py-2", children: data.plan.length === 0 ? /* @__PURE__ */ jsx10("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6682\u65E0\u4EFB\u52A1\u6B65\u9AA4" }) : data.plan.map((item, index) => /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-2 py-0.5", children: [
|
|
17211
|
+
/* @__PURE__ */ jsx10("span", { className: "mt-[3px] flex shrink-0", children: /* @__PURE__ */ jsx10(PlanStepIcon, { status: item.status, size: 14, running }) }),
|
|
17212
|
+
/* @__PURE__ */ jsx10(
|
|
16885
17213
|
"span",
|
|
16886
17214
|
{
|
|
16887
17215
|
className: cn(
|
|
@@ -16906,17 +17234,17 @@ function CurrentPlanPanel({
|
|
|
16906
17234
|
const { current, updating } = getPlanUpdateDisplayState(messages);
|
|
16907
17235
|
const revealBaselinesRef = useRef12(/* @__PURE__ */ new Map([[sessionId, revealRevision]]));
|
|
16908
17236
|
const autoReveal = (revealBaselinesRef.current.get(sessionId) ?? 0) !== revealRevision;
|
|
16909
|
-
|
|
17237
|
+
useEffect12(() => {
|
|
16910
17238
|
if (!current) return;
|
|
16911
17239
|
revealBaselinesRef.current.set(sessionId, revealRevision);
|
|
16912
17240
|
}, [current, revealRevision, sessionId]);
|
|
16913
17241
|
if (!current && !updating) return null;
|
|
16914
|
-
return /* @__PURE__ */
|
|
16915
|
-
updating ? /* @__PURE__ */
|
|
16916
|
-
/* @__PURE__ */
|
|
16917
|
-
/* @__PURE__ */
|
|
17242
|
+
return /* @__PURE__ */ jsxs8("div", { className: cn("blade-chat-plan mx-auto w-full max-w-[748px] px-4", className), children: [
|
|
17243
|
+
updating ? /* @__PURE__ */ jsxs8("div", { className: "mb-2 flex items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
17244
|
+
/* @__PURE__ */ jsx10(LoaderCircle, { size: 14, className: "shrink-0 animate-spin" }),
|
|
17245
|
+
/* @__PURE__ */ jsx10("span", { children: "\u6B63\u5728\u66F4\u65B0\u4EFB\u52A1\u8FDB\u5EA6\u2026" })
|
|
16918
17246
|
] }) : null,
|
|
16919
|
-
current ? /* @__PURE__ */
|
|
17247
|
+
current ? /* @__PURE__ */ jsx10(
|
|
16920
17248
|
PlanUpdateBlock,
|
|
16921
17249
|
{
|
|
16922
17250
|
toolCall: current,
|
|
@@ -16930,7 +17258,7 @@ function CurrentPlanPanel({
|
|
|
16930
17258
|
|
|
16931
17259
|
// src/components/ChatSurface.tsx
|
|
16932
17260
|
import { chatErrorForDisplay as chatErrorForDisplay2 } from "@blade-hq/agent-client";
|
|
16933
|
-
import { useState as
|
|
17261
|
+
import { useState as useState30 } from "react";
|
|
16934
17262
|
|
|
16935
17263
|
// src/components/McpAppCard.tsx
|
|
16936
17264
|
import { BladeApiError } from "@blade-hq/agent-client";
|
|
@@ -41782,8 +42110,8 @@ function SF(G, Q2) {
|
|
|
41782
42110
|
}
|
|
41783
42111
|
|
|
41784
42112
|
// src/components/McpAppCard.tsx
|
|
41785
|
-
import { createContext as createContext3, useContext as useContext3, useEffect as
|
|
41786
|
-
import { jsx as
|
|
42113
|
+
import { createContext as createContext3, useContext as useContext3, useEffect as useEffect13, useLayoutEffect, useRef as useRef13, useState as useState19 } from "react";
|
|
42114
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
41787
42115
|
var McpAppMessageContext = createContext3(null);
|
|
41788
42116
|
function securedHtml(archive) {
|
|
41789
42117
|
const ui = archive.resourceMeta.ui;
|
|
@@ -41829,12 +42157,12 @@ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: su
|
|
|
41829
42157
|
const frame = useRef13(null);
|
|
41830
42158
|
const panel = useRef13(null);
|
|
41831
42159
|
const bridgeRef = useRef13(null);
|
|
41832
|
-
const [html, setHtml] =
|
|
41833
|
-
const [title, setTitle] =
|
|
41834
|
-
const [error61, setError] =
|
|
41835
|
-
const [ready, setReady] =
|
|
41836
|
-
const [expanded, setExpanded] =
|
|
41837
|
-
const [height, setHeight] =
|
|
42160
|
+
const [html, setHtml] = useState19();
|
|
42161
|
+
const [title, setTitle] = useState19("\u5DE5\u5177\u754C\u9762");
|
|
42162
|
+
const [error61, setError] = useState19(null);
|
|
42163
|
+
const [ready, setReady] = useState19(false);
|
|
42164
|
+
const [expanded, setExpanded] = useState19(false);
|
|
42165
|
+
const [height, setHeight] = useState19(360);
|
|
41838
42166
|
useLayoutEffect(() => {
|
|
41839
42167
|
const dialog = panel.current;
|
|
41840
42168
|
if (!dialog) return;
|
|
@@ -41842,7 +42170,7 @@ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: su
|
|
|
41842
42170
|
if (expanded) dialog.showModal();
|
|
41843
42171
|
else dialog.show();
|
|
41844
42172
|
}, [expanded]);
|
|
41845
|
-
|
|
42173
|
+
useEffect13(() => {
|
|
41846
42174
|
const controller = new AbortController();
|
|
41847
42175
|
let bridge;
|
|
41848
42176
|
let disposed = false;
|
|
@@ -41998,7 +42326,7 @@ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: su
|
|
|
41998
42326
|
setExpanded(!expanded);
|
|
41999
42327
|
bridgeRef.current?.setHostContext({ displayMode: expanded ? "inline" : "fullscreen" });
|
|
42000
42328
|
};
|
|
42001
|
-
return /* @__PURE__ */
|
|
42329
|
+
return /* @__PURE__ */ jsxs9("dialog", { ref: panel, onCancel: () => {
|
|
42002
42330
|
setExpanded(false);
|
|
42003
42331
|
bridgeRef.current?.setHostContext({ displayMode: "inline" });
|
|
42004
42332
|
}, className: "blade-mcp-app", style: expanded ? {
|
|
@@ -42020,12 +42348,12 @@ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: su
|
|
|
42020
42348
|
display: "flex",
|
|
42021
42349
|
flexDirection: "column"
|
|
42022
42350
|
} : { position: "relative", margin: 0, padding: 0, width: "100%", maxWidth: "none", maxHeight: "none", border: "1px solid #d4d4d8", borderRadius: 6, overflow: "hidden", background: "white" }, children: [
|
|
42023
|
-
/* @__PURE__ */
|
|
42024
|
-
/* @__PURE__ */
|
|
42025
|
-
/* @__PURE__ */
|
|
42351
|
+
/* @__PURE__ */ jsxs9("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", padding: "8px 12px", color: "#27272a" }, children: [
|
|
42352
|
+
/* @__PURE__ */ jsx11("span", { children: title }),
|
|
42353
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: toggle, title: expanded ? "\u6536\u8D77" : "\u5C55\u5F00", "aria-label": expanded ? "\u6536\u8D77" : "\u5C55\u5F00", style: { width: 32, height: 32, display: "grid", placeItems: "center", background: "transparent", border: 0, padding: 0 }, children: expanded ? /* @__PURE__ */ jsx11(Minimize2, { size: 16 }) : /* @__PURE__ */ jsx11(Maximize2, { size: 16 }) })
|
|
42026
42354
|
] }),
|
|
42027
|
-
error61 ? /* @__PURE__ */
|
|
42028
|
-
/* @__PURE__ */
|
|
42355
|
+
error61 ? /* @__PURE__ */ jsx11("p", { role: "alert", style: { padding: 12, color: "#b91c1c" }, children: error61 }) : !ready ? /* @__PURE__ */ jsx11("output", { style: { padding: 12 }, children: "\u6B63\u5728\u52A0\u8F7D" }) : null,
|
|
42356
|
+
/* @__PURE__ */ jsx11(
|
|
42029
42357
|
"iframe",
|
|
42030
42358
|
{
|
|
42031
42359
|
ref: frame,
|
|
@@ -42040,8 +42368,8 @@ function McpAppCard({ sessionId, sourceId, client: suppliedClient, onMessage: su
|
|
|
42040
42368
|
}
|
|
42041
42369
|
|
|
42042
42370
|
// src/components/ChatInput.tsx
|
|
42043
|
-
import { useRef as useRef14, useState as
|
|
42044
|
-
import { Fragment as Fragment5, jsx as
|
|
42371
|
+
import { useRef as useRef14, useState as useState20 } from "react";
|
|
42372
|
+
import { Fragment as Fragment5, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
42045
42373
|
function isImeCompositionKey(event) {
|
|
42046
42374
|
return event.isComposing || event.keyCode === 229;
|
|
42047
42375
|
}
|
|
@@ -42065,7 +42393,7 @@ function ChatInput({
|
|
|
42065
42393
|
const latestValue = useRef14(value);
|
|
42066
42394
|
latestValue.current = value;
|
|
42067
42395
|
const sending = useRef14(false);
|
|
42068
|
-
const [isSending2, setIsSending] =
|
|
42396
|
+
const [isSending2, setIsSending] = useState20(false);
|
|
42069
42397
|
void queueKey;
|
|
42070
42398
|
const canSend = !isSending2 && (trimmed.length > 0 || hasAttachments) && (!isStreaming || !hasAttachments && !isStopping && !!onAppend);
|
|
42071
42399
|
const handleSend = async () => {
|
|
@@ -42093,8 +42421,8 @@ function ChatInput({
|
|
|
42093
42421
|
void handleSend();
|
|
42094
42422
|
}
|
|
42095
42423
|
};
|
|
42096
|
-
return /* @__PURE__ */
|
|
42097
|
-
/* @__PURE__ */
|
|
42424
|
+
return /* @__PURE__ */ jsx12("div", { className: cn("blade-chat-input border-t border-[hsl(var(--border))] py-3", className), children: /* @__PURE__ */ jsxs10("div", { className: "blade-chat-input-inner mx-auto flex max-w-[748px] items-end gap-2 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-2", children: [
|
|
42425
|
+
/* @__PURE__ */ jsx12(
|
|
42098
42426
|
"textarea",
|
|
42099
42427
|
{
|
|
42100
42428
|
value,
|
|
@@ -42111,10 +42439,10 @@ function ChatInput({
|
|
|
42111
42439
|
className: "blade-chat-textarea max-h-48 min-h-[28px] flex-1 resize-none bg-transparent py-1 text-sm leading-6 text-[hsl(var(--foreground))] outline-none placeholder:text-[hsl(var(--muted-foreground)/0.6)]"
|
|
42112
42440
|
}
|
|
42113
42441
|
),
|
|
42114
|
-
isStreaming ? /* @__PURE__ */
|
|
42115
|
-
/* @__PURE__ */
|
|
42116
|
-
/* @__PURE__ */
|
|
42117
|
-
] }) : /* @__PURE__ */
|
|
42442
|
+
isStreaming ? /* @__PURE__ */ jsxs10(Fragment5, { children: [
|
|
42443
|
+
/* @__PURE__ */ jsx12("button", { type: "button", onClick: handleSend, disabled: !canSend, "aria-label": "\u52A0\u5165\u6392\u961F", title: "\u52A0\u5165\u6392\u961F", className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] disabled:opacity-40", children: /* @__PURE__ */ jsx12(ArrowUp, { size: 15 }) }),
|
|
42444
|
+
/* @__PURE__ */ jsx12("button", { type: "button", onClick: onStop, disabled: isStopping, "aria-label": isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u56DE\u590D", title: isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u56DE\u590D", className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--muted))] text-[hsl(var(--foreground))] transition-opacity hover:opacity-90 disabled:opacity-60", children: isStopping ? /* @__PURE__ */ jsx12(LoaderCircle, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx12(Square, { size: 12, fill: "currentColor" }) })
|
|
42445
|
+
] }) : /* @__PURE__ */ jsx12(
|
|
42118
42446
|
"button",
|
|
42119
42447
|
{
|
|
42120
42448
|
type: "button",
|
|
@@ -42123,23 +42451,23 @@ function ChatInput({
|
|
|
42123
42451
|
"aria-label": "\u53D1\u9001\u6D88\u606F",
|
|
42124
42452
|
title: "\u53D1\u9001\u6D88\u606F",
|
|
42125
42453
|
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40",
|
|
42126
|
-
children: /* @__PURE__ */
|
|
42454
|
+
children: /* @__PURE__ */ jsx12(ArrowUp, { size: 15 })
|
|
42127
42455
|
}
|
|
42128
42456
|
)
|
|
42129
42457
|
] }) });
|
|
42130
42458
|
}
|
|
42131
42459
|
|
|
42132
42460
|
// src/components/ConnectionBanner.tsx
|
|
42133
|
-
import { useEffect as
|
|
42134
|
-
import { jsx as
|
|
42461
|
+
import { useEffect as useEffect14, useRef as useRef15, useState as useState21 } from "react";
|
|
42462
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
42135
42463
|
var CONNECTION_NOTICE_DELAY_MS = 3e3;
|
|
42136
42464
|
var CONNECTION_ERROR_DELAY_MS = 15e3;
|
|
42137
42465
|
function useConnectionNoticePhase(connected) {
|
|
42138
|
-
const [phase, setPhase] =
|
|
42466
|
+
const [phase, setPhase] = useState21("hidden");
|
|
42139
42467
|
const connectedRef = useRef15(connected);
|
|
42140
42468
|
const timersRef = useRef15([]);
|
|
42141
42469
|
connectedRef.current = connected;
|
|
42142
|
-
|
|
42470
|
+
useEffect14(() => {
|
|
42143
42471
|
const clearTimers = () => {
|
|
42144
42472
|
for (const timer of timersRef.current) clearTimeout(timer);
|
|
42145
42473
|
timersRef.current = [];
|
|
@@ -42186,7 +42514,7 @@ function ConnectionBanner({ connection, className }) {
|
|
|
42186
42514
|
if (connected || phase === "hidden") return null;
|
|
42187
42515
|
const recovering = phase === "recovering";
|
|
42188
42516
|
const firstConnection = !hasConnectedRef.current;
|
|
42189
|
-
return /* @__PURE__ */
|
|
42517
|
+
return /* @__PURE__ */ jsx13("div", { className: cn("blade-chat-banner bg-[hsl(var(--background))] px-5 pt-3", className), children: /* @__PURE__ */ jsxs11(
|
|
42190
42518
|
"div",
|
|
42191
42519
|
{
|
|
42192
42520
|
className: cn(
|
|
@@ -42194,10 +42522,10 @@ function ConnectionBanner({ connection, className }) {
|
|
|
42194
42522
|
recovering ? "border-amber-500/25 bg-amber-500/10 text-amber-100" : "border-rose-500/25 bg-rose-500/10 text-rose-100"
|
|
42195
42523
|
),
|
|
42196
42524
|
children: [
|
|
42197
|
-
/* @__PURE__ */
|
|
42198
|
-
/* @__PURE__ */
|
|
42199
|
-
/* @__PURE__ */
|
|
42200
|
-
/* @__PURE__ */
|
|
42525
|
+
/* @__PURE__ */ jsx13("span", { className: "mt-0.5 shrink-0", children: recovering ? /* @__PURE__ */ jsx13(LoaderCircle, { size: 14, className: "animate-spin" }) : /* @__PURE__ */ jsx13(TriangleAlert, { size: 14 }) }),
|
|
42526
|
+
/* @__PURE__ */ jsxs11("div", { className: "min-w-0", children: [
|
|
42527
|
+
/* @__PURE__ */ jsx13("div", { className: "text-sm font-medium", children: recovering ? firstConnection ? "\u6B63\u5728\u8FDE\u63A5\u2026" : "\u6B63\u5728\u6062\u590D\u8FDE\u63A5\u2026" : "\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5" }),
|
|
42528
|
+
/* @__PURE__ */ jsx13("div", { className: "text-xs opacity-80", children: recovering ? "\u6062\u590D\u540E\u4F1A\u81EA\u52A8\u540C\u6B65\u6700\u65B0\u6D88\u606F\uFF0C\u8BF7\u7A0D\u5019" : "\u8BF7\u68C0\u67E5\u7F51\u7EDC\u6216\u670D\u52A1\u72B6\u6001\uFF0C\u7CFB\u7EDF\u4F1A\u7EE7\u7EED\u81EA\u52A8\u91CD\u8BD5" })
|
|
42201
42529
|
] })
|
|
42202
42530
|
]
|
|
42203
42531
|
}
|
|
@@ -42206,10 +42534,10 @@ function ConnectionBanner({ connection, className }) {
|
|
|
42206
42534
|
|
|
42207
42535
|
// src/components/MessageList.tsx
|
|
42208
42536
|
import { isHiddenInternalMessage } from "@blade-hq/agent-client";
|
|
42209
|
-
import { useCallback as
|
|
42537
|
+
import { useCallback as useCallback26, useEffect as useEffect20, useMemo as useMemo16, useRef as useRef22, useState as useState29 } from "react";
|
|
42210
42538
|
|
|
42211
42539
|
// ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
|
|
42212
|
-
import { useCallback as
|
|
42540
|
+
import { useCallback as useCallback23, useMemo as useMemo12, useRef as useRef16, useState as useState22 } from "react";
|
|
42213
42541
|
var DEFAULT_SPRING_ANIMATION = {
|
|
42214
42542
|
/**
|
|
42215
42543
|
* A value from 0 to 1, on how much to damp the animation.
|
|
@@ -42246,12 +42574,12 @@ globalThis.document?.addEventListener("click", () => {
|
|
|
42246
42574
|
mouseDown = false;
|
|
42247
42575
|
});
|
|
42248
42576
|
var useStickToBottom = (options = {}) => {
|
|
42249
|
-
const [escapedFromLock, updateEscapedFromLock] =
|
|
42250
|
-
const [isAtBottom, updateIsAtBottom] =
|
|
42251
|
-
const [isNearBottom, setIsNearBottom] =
|
|
42577
|
+
const [escapedFromLock, updateEscapedFromLock] = useState22(false);
|
|
42578
|
+
const [isAtBottom, updateIsAtBottom] = useState22(options.initial !== false);
|
|
42579
|
+
const [isNearBottom, setIsNearBottom] = useState22(false);
|
|
42252
42580
|
const optionsRef = useRef16(null);
|
|
42253
42581
|
optionsRef.current = options;
|
|
42254
|
-
const isSelecting =
|
|
42582
|
+
const isSelecting = useCallback23(() => {
|
|
42255
42583
|
if (!mouseDown) {
|
|
42256
42584
|
return false;
|
|
42257
42585
|
}
|
|
@@ -42262,15 +42590,15 @@ var useStickToBottom = (options = {}) => {
|
|
|
42262
42590
|
const range = selection.getRangeAt(0);
|
|
42263
42591
|
return range.commonAncestorContainer.contains(scrollRef.current) || scrollRef.current?.contains(range.commonAncestorContainer);
|
|
42264
42592
|
}, []);
|
|
42265
|
-
const setIsAtBottom =
|
|
42593
|
+
const setIsAtBottom = useCallback23((isAtBottom2) => {
|
|
42266
42594
|
state.isAtBottom = isAtBottom2;
|
|
42267
42595
|
updateIsAtBottom(isAtBottom2);
|
|
42268
42596
|
}, []);
|
|
42269
|
-
const setEscapedFromLock =
|
|
42597
|
+
const setEscapedFromLock = useCallback23((escapedFromLock2) => {
|
|
42270
42598
|
state.escapedFromLock = escapedFromLock2;
|
|
42271
42599
|
updateEscapedFromLock(escapedFromLock2);
|
|
42272
42600
|
}, []);
|
|
42273
|
-
const state =
|
|
42601
|
+
const state = useMemo12(() => {
|
|
42274
42602
|
let lastCalculation;
|
|
42275
42603
|
return {
|
|
42276
42604
|
escapedFromLock,
|
|
@@ -42323,7 +42651,7 @@ var useStickToBottom = (options = {}) => {
|
|
|
42323
42651
|
}
|
|
42324
42652
|
};
|
|
42325
42653
|
}, []);
|
|
42326
|
-
const scrollToBottom =
|
|
42654
|
+
const scrollToBottom = useCallback23((scrollOptions = {}) => {
|
|
42327
42655
|
if (typeof scrollOptions === "string") {
|
|
42328
42656
|
scrollOptions = { animation: scrollOptions };
|
|
42329
42657
|
}
|
|
@@ -42408,11 +42736,11 @@ var useStickToBottom = (options = {}) => {
|
|
|
42408
42736
|
}
|
|
42409
42737
|
return next();
|
|
42410
42738
|
}, [setIsAtBottom, isSelecting, state]);
|
|
42411
|
-
const stopScroll =
|
|
42739
|
+
const stopScroll = useCallback23(() => {
|
|
42412
42740
|
setEscapedFromLock(true);
|
|
42413
42741
|
setIsAtBottom(false);
|
|
42414
42742
|
}, [setEscapedFromLock, setIsAtBottom]);
|
|
42415
|
-
const handleScroll =
|
|
42743
|
+
const handleScroll = useCallback23(({ target }) => {
|
|
42416
42744
|
if (target !== scrollRef.current) {
|
|
42417
42745
|
return;
|
|
42418
42746
|
}
|
|
@@ -42451,7 +42779,7 @@ var useStickToBottom = (options = {}) => {
|
|
|
42451
42779
|
}
|
|
42452
42780
|
}, 1);
|
|
42453
42781
|
}, [setEscapedFromLock, setIsAtBottom, isSelecting, state]);
|
|
42454
|
-
const handleWheel =
|
|
42782
|
+
const handleWheel = useCallback23(({ target, deltaY }) => {
|
|
42455
42783
|
let element = target;
|
|
42456
42784
|
while (!["scroll", "auto"].includes(getComputedStyle(element).overflow)) {
|
|
42457
42785
|
if (!element.parentElement) {
|
|
@@ -42521,7 +42849,7 @@ var useStickToBottom = (options = {}) => {
|
|
|
42521
42849
|
};
|
|
42522
42850
|
};
|
|
42523
42851
|
function useRefCallback(callback, deps) {
|
|
42524
|
-
const result =
|
|
42852
|
+
const result = useCallback23((ref) => {
|
|
42525
42853
|
result.current = ref;
|
|
42526
42854
|
return callback(ref);
|
|
42527
42855
|
}, deps);
|
|
@@ -42553,9 +42881,9 @@ function mergeAnimations(...animations) {
|
|
|
42553
42881
|
|
|
42554
42882
|
// ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/StickToBottom.js
|
|
42555
42883
|
import * as React from "react";
|
|
42556
|
-
import { createContext as createContext4, useContext as useContext4, useEffect as
|
|
42884
|
+
import { createContext as createContext4, useContext as useContext4, useEffect as useEffect15, useImperativeHandle, useLayoutEffect as useLayoutEffect2, useMemo as useMemo13, useRef as useRef17 } from "react";
|
|
42557
42885
|
var StickToBottomContext = createContext4(null);
|
|
42558
|
-
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect2 :
|
|
42886
|
+
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect2 : useEffect15;
|
|
42559
42887
|
function StickToBottom({ instance, children, resize, initial, mass, damping, stiffness, targetScrollTop: currentTargetScrollTop, contextRef, ...props }) {
|
|
42560
42888
|
const customTargetScrollTop = useRef17(null);
|
|
42561
42889
|
const targetScrollTop = React.useCallback((target, elements) => {
|
|
@@ -42571,7 +42899,7 @@ function StickToBottom({ instance, children, resize, initial, mass, damping, sti
|
|
|
42571
42899
|
targetScrollTop
|
|
42572
42900
|
});
|
|
42573
42901
|
const { scrollRef, contentRef, scrollToBottom, stopScroll, isAtBottom, escapedFromLock, state } = instance ?? defaultInstance;
|
|
42574
|
-
const context =
|
|
42902
|
+
const context = useMemo13(() => ({
|
|
42575
42903
|
scrollToBottom,
|
|
42576
42904
|
stopScroll,
|
|
42577
42905
|
scrollRef,
|
|
@@ -42640,11 +42968,11 @@ import {
|
|
|
42640
42968
|
getTextContent,
|
|
42641
42969
|
normalizeMessageContent
|
|
42642
42970
|
} from "@blade-hq/agent-client";
|
|
42643
|
-
import { useEffect as
|
|
42971
|
+
import { useEffect as useEffect18, useRef as useRef20, useState as useState27 } from "react";
|
|
42644
42972
|
|
|
42645
42973
|
// src/components/AgentLoopBlock.tsx
|
|
42646
|
-
import { useState as
|
|
42647
|
-
import { jsx as
|
|
42974
|
+
import { useState as useState23 } from "react";
|
|
42975
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
42648
42976
|
function parseAgentDescription(argumentsJson) {
|
|
42649
42977
|
try {
|
|
42650
42978
|
const parsed = JSON.parse(argumentsJson);
|
|
@@ -42654,7 +42982,7 @@ function parseAgentDescription(argumentsJson) {
|
|
|
42654
42982
|
}
|
|
42655
42983
|
}
|
|
42656
42984
|
function AgentLoopBlock({ toolCall }) {
|
|
42657
|
-
const [expanded, setExpanded] =
|
|
42985
|
+
const [expanded, setExpanded] = useState23(false);
|
|
42658
42986
|
const description = parseAgentDescription(toolCall.arguments);
|
|
42659
42987
|
const running = toolCall.status === "pending" || toolCall.status === "awaiting_answer";
|
|
42660
42988
|
const failed = toolCall.status === "error" || toolCall.status === "cancelled";
|
|
@@ -42663,8 +42991,8 @@ function AgentLoopBlock({ toolCall }) {
|
|
|
42663
42991
|
"size-3.5 shrink-0",
|
|
42664
42992
|
failed ? "text-red-500" : "text-[hsl(var(--muted-foreground))]"
|
|
42665
42993
|
);
|
|
42666
|
-
return /* @__PURE__ */
|
|
42667
|
-
/* @__PURE__ */
|
|
42994
|
+
return /* @__PURE__ */ jsxs12("div", { className: "blade-chat-agent-loop text-xs leading-[22px]", children: [
|
|
42995
|
+
/* @__PURE__ */ jsxs12(
|
|
42668
42996
|
"button",
|
|
42669
42997
|
{
|
|
42670
42998
|
type: "button",
|
|
@@ -42679,12 +43007,12 @@ function AgentLoopBlock({ toolCall }) {
|
|
|
42679
43007
|
),
|
|
42680
43008
|
title: `\u5B50\u4EFB\u52A1\uFF1A${description}`,
|
|
42681
43009
|
children: [
|
|
42682
|
-
running ? /* @__PURE__ */
|
|
42683
|
-
/* @__PURE__ */
|
|
43010
|
+
running ? /* @__PURE__ */ jsx14(LoaderCircle, { className: cn(iconClass, "animate-spin"), "aria-hidden": "true" }) : toolCall.status === "error" ? /* @__PURE__ */ jsx14(CircleAlert, { className: iconClass, "aria-hidden": "true" }) : toolCall.status === "cancelled" ? /* @__PURE__ */ jsx14(X, { className: iconClass, "aria-hidden": "true" }) : /* @__PURE__ */ jsx14(Bot, { className: iconClass, "aria-hidden": "true" }),
|
|
43011
|
+
/* @__PURE__ */ jsxs12("span", { className: "min-w-0 truncate", children: [
|
|
42684
43012
|
"\u5B50\u4EFB\u52A1\uFF1A",
|
|
42685
43013
|
description
|
|
42686
43014
|
] }),
|
|
42687
|
-
hasResult ? /* @__PURE__ */
|
|
43015
|
+
hasResult ? /* @__PURE__ */ jsx14(
|
|
42688
43016
|
ChevronRight,
|
|
42689
43017
|
{
|
|
42690
43018
|
size: 14,
|
|
@@ -42699,18 +43027,18 @@ function AgentLoopBlock({ toolCall }) {
|
|
|
42699
43027
|
]
|
|
42700
43028
|
}
|
|
42701
43029
|
),
|
|
42702
|
-
expanded && hasResult ? /* @__PURE__ */
|
|
43030
|
+
expanded && hasResult ? /* @__PURE__ */ jsx14("div", { className: "ml-[18px] mt-1.5 max-h-[400px] overflow-auto whitespace-pre-wrap text-xs leading-[22px] text-[hsl(var(--muted-foreground))]", children: formatToolResult(toolCall.result) }) : null
|
|
42703
43031
|
] });
|
|
42704
43032
|
}
|
|
42705
43033
|
|
|
42706
43034
|
// src/components/MarkdownContent.tsx
|
|
42707
43035
|
import {
|
|
42708
|
-
useEffect as
|
|
42709
|
-
useMemo as
|
|
43036
|
+
useEffect as useEffect16,
|
|
43037
|
+
useMemo as useMemo14,
|
|
42710
43038
|
useRef as useRef18,
|
|
42711
|
-
useState as
|
|
43039
|
+
useState as useState24
|
|
42712
43040
|
} from "react";
|
|
42713
|
-
import { jsx as
|
|
43041
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
42714
43042
|
var SYSTEM_REMINDER_RE = /<system-reminder>[\s\S]*?<\/system-reminder>/gi;
|
|
42715
43043
|
function normalizeAdjacentUrlFormatting(value) {
|
|
42716
43044
|
const protectedSegments = [];
|
|
@@ -42726,9 +43054,9 @@ function normalizeAdjacentUrlFormatting(value) {
|
|
|
42726
43054
|
}
|
|
42727
43055
|
function CodeBlockPre({ children, node: _node, ...props }) {
|
|
42728
43056
|
const preRef = useRef18(null);
|
|
42729
|
-
const [copied, setCopied] =
|
|
42730
|
-
const [language, setLanguage] =
|
|
42731
|
-
|
|
43057
|
+
const [copied, setCopied] = useState24(false);
|
|
43058
|
+
const [language, setLanguage] = useState24("");
|
|
43059
|
+
useEffect16(() => {
|
|
42732
43060
|
const codeEl = preRef.current?.querySelector("code");
|
|
42733
43061
|
setLanguage(codeEl?.className.match(/language-(\S+)/)?.[1] ?? "");
|
|
42734
43062
|
}, []);
|
|
@@ -42739,10 +43067,10 @@ function CodeBlockPre({ children, node: _node, ...props }) {
|
|
|
42739
43067
|
setTimeout(() => setCopied(false), 2e3);
|
|
42740
43068
|
}
|
|
42741
43069
|
};
|
|
42742
|
-
return /* @__PURE__ */
|
|
42743
|
-
/* @__PURE__ */
|
|
42744
|
-
/* @__PURE__ */
|
|
42745
|
-
/* @__PURE__ */
|
|
43070
|
+
return /* @__PURE__ */ jsxs13("div", { className: "blade-chat-codeblock not-prose my-3 overflow-hidden rounded-xl border border-[hsl(var(--border))]", children: [
|
|
43071
|
+
/* @__PURE__ */ jsxs13("div", { className: "blade-chat-codeblock-header flex h-[34px] items-center justify-between border-b border-[hsl(var(--border))] bg-[hsl(var(--muted))/0.5] pl-3.5 pr-1.5", children: [
|
|
43072
|
+
/* @__PURE__ */ jsx15("span", { className: "font-mono text-[12px] text-[hsl(var(--muted-foreground))]", children: language || "code" }),
|
|
43073
|
+
/* @__PURE__ */ jsxs13(
|
|
42746
43074
|
"button",
|
|
42747
43075
|
{
|
|
42748
43076
|
type: "button",
|
|
@@ -42752,13 +43080,13 @@ function CodeBlockPre({ children, node: _node, ...props }) {
|
|
|
42752
43080
|
copied ? "text-[hsl(var(--primary))]" : "text-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]"
|
|
42753
43081
|
),
|
|
42754
43082
|
children: [
|
|
42755
|
-
copied ? /* @__PURE__ */
|
|
42756
|
-
/* @__PURE__ */
|
|
43083
|
+
copied ? /* @__PURE__ */ jsx15(Check, { size: 12 }) : /* @__PURE__ */ jsx15(Copy, { size: 12 }),
|
|
43084
|
+
/* @__PURE__ */ jsx15("span", { children: copied ? "\u5DF2\u590D\u5236" : "\u590D\u5236" })
|
|
42757
43085
|
]
|
|
42758
43086
|
}
|
|
42759
43087
|
)
|
|
42760
43088
|
] }),
|
|
42761
|
-
/* @__PURE__ */
|
|
43089
|
+
/* @__PURE__ */ jsx15(
|
|
42762
43090
|
"pre",
|
|
42763
43091
|
{
|
|
42764
43092
|
ref: preRef,
|
|
@@ -42770,17 +43098,17 @@ function CodeBlockPre({ children, node: _node, ...props }) {
|
|
|
42770
43098
|
] });
|
|
42771
43099
|
}
|
|
42772
43100
|
function ExternalAnchor({ node: _node, children, ...props }) {
|
|
42773
|
-
return /* @__PURE__ */
|
|
43101
|
+
return /* @__PURE__ */ jsx15("a", { ...props, target: "_blank", rel: "noopener noreferrer", children });
|
|
42774
43102
|
}
|
|
42775
43103
|
var MARKDOWN_COMPONENTS = {
|
|
42776
43104
|
pre: CodeBlockPre,
|
|
42777
43105
|
a: ExternalAnchor
|
|
42778
43106
|
};
|
|
42779
43107
|
function MarkdownContent({ children, className, mode, sessionId }) {
|
|
42780
|
-
const resolvedChildren =
|
|
43108
|
+
const resolvedChildren = useMemo14(() => {
|
|
42781
43109
|
return normalizeAdjacentUrlFormatting(children.replace(SYSTEM_REMINDER_RE, ""));
|
|
42782
43110
|
}, [children]);
|
|
42783
|
-
return /* @__PURE__ */
|
|
43111
|
+
return /* @__PURE__ */ jsx15(
|
|
42784
43112
|
_r,
|
|
42785
43113
|
{
|
|
42786
43114
|
className: cn("blade-chat-markdown break-words", className),
|
|
@@ -42793,17 +43121,17 @@ function MarkdownContent({ children, className, mode, sessionId }) {
|
|
|
42793
43121
|
}
|
|
42794
43122
|
|
|
42795
43123
|
// src/components/Shimmer.tsx
|
|
42796
|
-
import { jsx as
|
|
43124
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
42797
43125
|
function Shimmer({ children = "\u6B63\u5728\u601D\u8003...", className }) {
|
|
42798
|
-
return /* @__PURE__ */
|
|
43126
|
+
return /* @__PURE__ */ jsx16("span", { className: cn("blade-shimmer-text text-sm font-medium", className), children });
|
|
42799
43127
|
}
|
|
42800
43128
|
|
|
42801
43129
|
// src/components/ToolCallBlock.tsx
|
|
42802
|
-
import { useState as
|
|
43130
|
+
import { useState as useState26 } from "react";
|
|
42803
43131
|
|
|
42804
43132
|
// src/components/AskUserQuestionBlock.tsx
|
|
42805
|
-
import { useEffect as
|
|
42806
|
-
import { jsx as
|
|
43133
|
+
import { useEffect as useEffect17, useMemo as useMemo15, useRef as useRef19, useState as useState25 } from "react";
|
|
43134
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
42807
43135
|
var CUSTOM_TEXTAREA_MAX_HEIGHT = 160;
|
|
42808
43136
|
function resizeCustomTextarea(textarea) {
|
|
42809
43137
|
textarea.style.height = "auto";
|
|
@@ -42812,11 +43140,11 @@ function resizeCustomTextarea(textarea) {
|
|
|
42812
43140
|
}
|
|
42813
43141
|
function useAutoResizeTextarea(value) {
|
|
42814
43142
|
const textareaRef = useRef19(null);
|
|
42815
|
-
|
|
43143
|
+
useEffect17(() => {
|
|
42816
43144
|
const textarea = textareaRef.current;
|
|
42817
43145
|
if (textarea?.value === value) resizeCustomTextarea(textarea);
|
|
42818
43146
|
}, [value]);
|
|
42819
|
-
|
|
43147
|
+
useEffect17(() => {
|
|
42820
43148
|
const textarea = textareaRef.current;
|
|
42821
43149
|
if (!textarea || typeof ResizeObserver === "undefined") return;
|
|
42822
43150
|
let previousWidth = textarea.clientWidth;
|
|
@@ -42841,17 +43169,17 @@ function AskUserQuestionBlock({
|
|
|
42841
43169
|
answerData,
|
|
42842
43170
|
onAnswer
|
|
42843
43171
|
}) {
|
|
42844
|
-
const [selections, setSelections] =
|
|
42845
|
-
const [customTexts, setCustomTexts] =
|
|
42846
|
-
const [usingCustom, setUsingCustom] =
|
|
42847
|
-
const [note, setNote] =
|
|
42848
|
-
const [submitted, setSubmitted] =
|
|
42849
|
-
|
|
43172
|
+
const [selections, setSelections] = useState25(/* @__PURE__ */ new Map());
|
|
43173
|
+
const [customTexts, setCustomTexts] = useState25(/* @__PURE__ */ new Map());
|
|
43174
|
+
const [usingCustom, setUsingCustom] = useState25(/* @__PURE__ */ new Set());
|
|
43175
|
+
const [note, setNote] = useState25("");
|
|
43176
|
+
const [submitted, setSubmitted] = useState25(false);
|
|
43177
|
+
useEffect17(() => {
|
|
42850
43178
|
if (sessionStatus === "failed" || sessionStatus === "interrupted") {
|
|
42851
43179
|
setSubmitted(false);
|
|
42852
43180
|
}
|
|
42853
43181
|
}, [sessionStatus]);
|
|
42854
|
-
const displayAnswerState =
|
|
43182
|
+
const displayAnswerState = useMemo15(() => {
|
|
42855
43183
|
if (!(answered && answerData)) {
|
|
42856
43184
|
return { selections, customTexts, usingCustom, note };
|
|
42857
43185
|
}
|
|
@@ -42944,7 +43272,7 @@ ${parts.join("\n")}`,
|
|
|
42944
43272
|
setSubmitted(true);
|
|
42945
43273
|
onAnswer(text, toolCallId, nextAnswerData);
|
|
42946
43274
|
};
|
|
42947
|
-
return /* @__PURE__ */
|
|
43275
|
+
return /* @__PURE__ */ jsxs14(
|
|
42948
43276
|
"div",
|
|
42949
43277
|
{
|
|
42950
43278
|
className: cn(
|
|
@@ -42952,12 +43280,12 @@ ${parts.join("\n")}`,
|
|
|
42952
43280
|
answered ? "max-w-2xl space-y-3 p-3 text-xs text-[hsl(var(--muted-foreground))] opacity-80" : "max-w-lg space-y-5 p-4 text-sm"
|
|
42953
43281
|
),
|
|
42954
43282
|
children: [
|
|
42955
|
-
data.source_loop?.description && /* @__PURE__ */
|
|
43283
|
+
data.source_loop?.description && /* @__PURE__ */ jsxs14("div", { className: "rounded-lg bg-[hsl(var(--muted)/0.35)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
42956
43284
|
"\u5B50\u667A\u80FD\u4F53\u300C",
|
|
42957
43285
|
data.source_loop.description,
|
|
42958
43286
|
"\u300D\u5728\u7B49\u5F85\u4F60\u7684\u56DE\u7B54"
|
|
42959
43287
|
] }),
|
|
42960
|
-
data.questions.map((q2, qIdx) => /* @__PURE__ */
|
|
43288
|
+
data.questions.map((q2, qIdx) => /* @__PURE__ */ jsx17(
|
|
42961
43289
|
QuestionCard,
|
|
42962
43290
|
{
|
|
42963
43291
|
question: q2,
|
|
@@ -42972,7 +43300,7 @@ ${parts.join("\n")}`,
|
|
|
42972
43300
|
},
|
|
42973
43301
|
q2.question
|
|
42974
43302
|
)),
|
|
42975
|
-
/* @__PURE__ */
|
|
43303
|
+
/* @__PURE__ */ jsx17(
|
|
42976
43304
|
NoteField,
|
|
42977
43305
|
{
|
|
42978
43306
|
answered,
|
|
@@ -42981,7 +43309,7 @@ ${parts.join("\n")}`,
|
|
|
42981
43309
|
onChange: setNote
|
|
42982
43310
|
}
|
|
42983
43311
|
),
|
|
42984
|
-
!answered && !submitted && onAnswer && /* @__PURE__ */
|
|
43312
|
+
!answered && !submitted && onAnswer && /* @__PURE__ */ jsx17(
|
|
42985
43313
|
"button",
|
|
42986
43314
|
{
|
|
42987
43315
|
type: "button",
|
|
@@ -42991,14 +43319,14 @@ ${parts.join("\n")}`,
|
|
|
42991
43319
|
children: allAnswered ? "\u786E\u8BA4" : "\u8BF7\u5148\u9009\u62E9\u4E00\u4E2A\u9009\u9879"
|
|
42992
43320
|
}
|
|
42993
43321
|
),
|
|
42994
|
-
submitted && !answered && /* @__PURE__ */
|
|
43322
|
+
submitted && !answered && /* @__PURE__ */ jsxs14(
|
|
42995
43323
|
"button",
|
|
42996
43324
|
{
|
|
42997
43325
|
type: "button",
|
|
42998
43326
|
disabled: true,
|
|
42999
43327
|
className: "flex w-full items-center justify-center gap-2 rounded-lg bg-[hsl(var(--primary))] px-4 py-2 text-xs font-semibold text-[hsl(var(--primary-foreground))] opacity-80",
|
|
43000
43328
|
children: [
|
|
43001
|
-
/* @__PURE__ */
|
|
43329
|
+
/* @__PURE__ */ jsx17(LoaderCircle, { size: 14, className: "animate-spin" }),
|
|
43002
43330
|
"\u786E\u8BA4\u4E2D"
|
|
43003
43331
|
]
|
|
43004
43332
|
}
|
|
@@ -43020,30 +43348,30 @@ function QuestionCard({
|
|
|
43020
43348
|
}) {
|
|
43021
43349
|
const multi = question.multiSelect ?? false;
|
|
43022
43350
|
const customTextareaRef = useAutoResizeTextarea(customText);
|
|
43023
|
-
return /* @__PURE__ */
|
|
43024
|
-
/* @__PURE__ */
|
|
43025
|
-
/* @__PURE__ */
|
|
43351
|
+
return /* @__PURE__ */ jsxs14("div", { children: [
|
|
43352
|
+
/* @__PURE__ */ jsxs14("div", { className: cn("flex items-start gap-2", answered ? "mb-2" : "mb-3"), children: [
|
|
43353
|
+
/* @__PURE__ */ jsx17(
|
|
43026
43354
|
MessageSquareMore,
|
|
43027
43355
|
{
|
|
43028
43356
|
size: answered ? 12 : 13,
|
|
43029
43357
|
className: "mt-0.5 shrink-0 text-[hsl(var(--primary))]"
|
|
43030
43358
|
}
|
|
43031
43359
|
),
|
|
43032
|
-
/* @__PURE__ */
|
|
43360
|
+
/* @__PURE__ */ jsx17(
|
|
43033
43361
|
"div",
|
|
43034
43362
|
{
|
|
43035
43363
|
className: cn(
|
|
43036
43364
|
"min-w-0 flex-1 font-medium text-[hsl(var(--foreground))]",
|
|
43037
43365
|
answered ? "text-xs" : "text-sm"
|
|
43038
43366
|
),
|
|
43039
|
-
children: /* @__PURE__ */
|
|
43367
|
+
children: /* @__PURE__ */ jsx17(MarkdownContent, { className: "blade-chat-prose", children: question.question })
|
|
43040
43368
|
}
|
|
43041
43369
|
)
|
|
43042
43370
|
] }),
|
|
43043
|
-
/* @__PURE__ */
|
|
43371
|
+
/* @__PURE__ */ jsxs14("div", { className: cn("flex flex-col pl-5", answered ? "gap-1" : "gap-1.5"), children: [
|
|
43044
43372
|
question.options.map((opt, optIdx) => {
|
|
43045
43373
|
const isSel = selected.has(optIdx);
|
|
43046
|
-
return /* @__PURE__ */
|
|
43374
|
+
return /* @__PURE__ */ jsxs14(
|
|
43047
43375
|
"button",
|
|
43048
43376
|
{
|
|
43049
43377
|
type: "button",
|
|
@@ -43057,14 +43385,14 @@ function QuestionCard({
|
|
|
43057
43385
|
answered && "cursor-default opacity-70"
|
|
43058
43386
|
),
|
|
43059
43387
|
children: [
|
|
43060
|
-
multi && /* @__PURE__ */
|
|
43388
|
+
multi && /* @__PURE__ */ jsx17(
|
|
43061
43389
|
"div",
|
|
43062
43390
|
{
|
|
43063
43391
|
className: cn(
|
|
43064
43392
|
"mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border transition-colors",
|
|
43065
43393
|
isSel && !answered ? "border-[hsl(var(--primary-foreground)/0.6)] bg-[hsl(var(--primary-foreground)/0.2)]" : isSel ? "border-[hsl(var(--primary)/0.45)] bg-[hsl(var(--primary)/0.12)]" : "border-[hsl(var(--border))]"
|
|
43066
43394
|
),
|
|
43067
|
-
children: isSel && /* @__PURE__ */
|
|
43395
|
+
children: isSel && /* @__PURE__ */ jsx17(
|
|
43068
43396
|
Check,
|
|
43069
43397
|
{
|
|
43070
43398
|
size: 9,
|
|
@@ -43073,9 +43401,9 @@ function QuestionCard({
|
|
|
43073
43401
|
)
|
|
43074
43402
|
}
|
|
43075
43403
|
),
|
|
43076
|
-
/* @__PURE__ */
|
|
43077
|
-
/* @__PURE__ */
|
|
43078
|
-
opt.description && /* @__PURE__ */
|
|
43404
|
+
/* @__PURE__ */ jsxs14("div", { className: "min-w-0", children: [
|
|
43405
|
+
/* @__PURE__ */ jsx17("div", { className: cn("font-medium", answered ? "text-xs" : "text-[13px]"), children: opt.label }),
|
|
43406
|
+
opt.description && /* @__PURE__ */ jsx17(
|
|
43079
43407
|
"div",
|
|
43080
43408
|
{
|
|
43081
43409
|
className: cn(
|
|
@@ -43092,7 +43420,7 @@ function QuestionCard({
|
|
|
43092
43420
|
opt.label
|
|
43093
43421
|
);
|
|
43094
43422
|
}),
|
|
43095
|
-
answered && !isCustom ? null : /* @__PURE__ */
|
|
43423
|
+
answered && !isCustom ? null : /* @__PURE__ */ jsxs14(
|
|
43096
43424
|
"div",
|
|
43097
43425
|
{
|
|
43098
43426
|
className: cn(
|
|
@@ -43102,8 +43430,8 @@ function QuestionCard({
|
|
|
43102
43430
|
answered && "cursor-default opacity-70"
|
|
43103
43431
|
),
|
|
43104
43432
|
children: [
|
|
43105
|
-
/* @__PURE__ */
|
|
43106
|
-
/* @__PURE__ */
|
|
43433
|
+
/* @__PURE__ */ jsx17("span", { className: "shrink-0 pt-1 text-xs text-[hsl(var(--muted-foreground))]", children: "\u5176\u4ED6\uFF1A" }),
|
|
43434
|
+
/* @__PURE__ */ jsx17(
|
|
43107
43435
|
"textarea",
|
|
43108
43436
|
{
|
|
43109
43437
|
ref: customTextareaRef,
|
|
@@ -43135,7 +43463,7 @@ function NoteField({
|
|
|
43135
43463
|
const textareaRef = useAutoResizeTextarea(note);
|
|
43136
43464
|
const readOnly = answered || submitted;
|
|
43137
43465
|
if (answered && !note.trim()) return null;
|
|
43138
|
-
return /* @__PURE__ */
|
|
43466
|
+
return /* @__PURE__ */ jsxs14(
|
|
43139
43467
|
"label",
|
|
43140
43468
|
{
|
|
43141
43469
|
className: cn(
|
|
@@ -43145,8 +43473,8 @@ function NoteField({
|
|
|
43145
43473
|
readOnly && "cursor-default opacity-70"
|
|
43146
43474
|
),
|
|
43147
43475
|
children: [
|
|
43148
|
-
/* @__PURE__ */
|
|
43149
|
-
/* @__PURE__ */
|
|
43476
|
+
/* @__PURE__ */ jsx17("span", { className: "mb-1.5 block text-xs text-[hsl(var(--muted-foreground))]", children: "\u8865\u5145\u8BF4\u660E\uFF08\u53EF\u9009\uFF09" }),
|
|
43477
|
+
/* @__PURE__ */ jsx17(
|
|
43150
43478
|
"textarea",
|
|
43151
43479
|
{
|
|
43152
43480
|
ref: textareaRef,
|
|
@@ -43235,7 +43563,7 @@ function normalizeOptionItem(value) {
|
|
|
43235
43563
|
}
|
|
43236
43564
|
|
|
43237
43565
|
// src/components/ToolCallBlock.tsx
|
|
43238
|
-
import { Fragment as Fragment6, jsx as
|
|
43566
|
+
import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
43239
43567
|
function resolveAskQuestionState({
|
|
43240
43568
|
toolStatus,
|
|
43241
43569
|
hasAnswerData,
|
|
@@ -43257,12 +43585,12 @@ function ToolCallBlock({
|
|
|
43257
43585
|
isActiveQuestion,
|
|
43258
43586
|
renderer
|
|
43259
43587
|
}) {
|
|
43260
|
-
const [expanded, setExpanded] =
|
|
43588
|
+
const [expanded, setExpanded] = useState26(false);
|
|
43261
43589
|
const normalizedName = formatToolName(toolCall.name);
|
|
43262
43590
|
if (renderer) {
|
|
43263
43591
|
const custom2 = renderer(toolCall);
|
|
43264
43592
|
if (custom2 !== null && custom2 !== void 0) {
|
|
43265
|
-
return /* @__PURE__ */
|
|
43593
|
+
return /* @__PURE__ */ jsx18(Fragment6, { children: custom2 });
|
|
43266
43594
|
}
|
|
43267
43595
|
}
|
|
43268
43596
|
if (normalizedName === "AskUserQuestion") {
|
|
@@ -43275,7 +43603,7 @@ function ToolCallBlock({
|
|
|
43275
43603
|
});
|
|
43276
43604
|
const canAnswer = questionState.awaitingAnswer && Boolean(onAnswer);
|
|
43277
43605
|
if (askData) {
|
|
43278
|
-
return /* @__PURE__ */
|
|
43606
|
+
return /* @__PURE__ */ jsx18(
|
|
43279
43607
|
AskUserQuestionBlock,
|
|
43280
43608
|
{
|
|
43281
43609
|
data: askData,
|
|
@@ -43288,31 +43616,31 @@ function ToolCallBlock({
|
|
|
43288
43616
|
);
|
|
43289
43617
|
}
|
|
43290
43618
|
if (toolCall.status === "pending") {
|
|
43291
|
-
return /* @__PURE__ */
|
|
43292
|
-
/* @__PURE__ */
|
|
43293
|
-
/* @__PURE__ */
|
|
43619
|
+
return /* @__PURE__ */ jsxs15("div", { className: "ml-4 flex max-w-lg items-center gap-2 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-4 text-sm text-[hsl(var(--muted-foreground))]", children: [
|
|
43620
|
+
/* @__PURE__ */ jsx18(LoaderCircle, { size: 14, className: "animate-spin" }),
|
|
43621
|
+
/* @__PURE__ */ jsx18("span", { children: "\u6B63\u5728\u51C6\u5907\u95EE\u9898\u2026" })
|
|
43294
43622
|
] });
|
|
43295
43623
|
}
|
|
43296
43624
|
const errorDetail = parseAskUserQuestionError(
|
|
43297
43625
|
typeof toolCall.result === "string" ? toolCall.result : null
|
|
43298
43626
|
);
|
|
43299
|
-
return /* @__PURE__ */
|
|
43300
|
-
/* @__PURE__ */
|
|
43301
|
-
/* @__PURE__ */
|
|
43302
|
-
errorDetail?.detail ? /* @__PURE__ */
|
|
43303
|
-
/* @__PURE__ */
|
|
43304
|
-
/* @__PURE__ */
|
|
43627
|
+
return /* @__PURE__ */ jsxs15("div", { className: "ml-4 max-w-lg rounded-xl border border-amber-500/35 bg-amber-500/10 p-4 text-sm text-[hsl(var(--foreground))]", children: [
|
|
43628
|
+
/* @__PURE__ */ jsx18("div", { className: "font-semibold", children: "\u9009\u62E9\u9898\u5185\u5BB9\u6682\u65F6\u65E0\u6CD5\u663E\u793A" }),
|
|
43629
|
+
/* @__PURE__ */ jsx18("div", { className: "mt-1 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: errorDetail?.message ?? "\u6536\u5230\u7684\u4EA4\u4E92\u6570\u636E\u4E0D\u5B8C\u6574\u3002\u8BF7\u8BA9\u667A\u80FD\u4F53\u91CD\u65B0\u63D0\u95EE\u3002" }),
|
|
43630
|
+
errorDetail?.detail ? /* @__PURE__ */ jsxs15("details", { className: "mt-2 text-xs text-[hsl(var(--muted-foreground))]", children: [
|
|
43631
|
+
/* @__PURE__ */ jsx18("summary", { className: "cursor-pointer", children: "\u67E5\u770B\u5177\u4F53\u539F\u56E0" }),
|
|
43632
|
+
/* @__PURE__ */ jsx18("div", { className: "mt-1 break-words font-mono", children: errorDetail.detail })
|
|
43305
43633
|
] }) : null
|
|
43306
43634
|
] });
|
|
43307
43635
|
}
|
|
43308
43636
|
const tone = getToolTone(toolCall.status);
|
|
43309
43637
|
const displayName = getToolDisplayLabel(toolCall);
|
|
43310
43638
|
const toneClass = tone === "red" ? "border-l-[hsl(var(--muted-foreground)/0.5)]" : tone === "amber" ? "border-l-amber-400" : tone === "blue" ? "border-l-blue-500" : "border-l-[hsl(var(--primary))]";
|
|
43311
|
-
const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */
|
|
43639
|
+
const statusIcon = toolCall.status === "pending" ? /* @__PURE__ */ jsx18(LoaderCircle, { size: 11, className: "animate-spin" }) : toolCall.status === "awaiting_answer" ? /* @__PURE__ */ jsx18(MessageSquareMore, { size: 11 }) : toolCall.status === "cancelled" || toolCall.status === "error" ? /* @__PURE__ */ jsx18(X, { size: 11 }) : /* @__PURE__ */ jsx18(Check, { size: 11 });
|
|
43312
43640
|
const statusTextClass = tone === "red" ? "text-[hsl(var(--muted-foreground))]" : tone === "amber" ? "text-amber-300" : tone === "blue" ? "text-blue-300" : "text-[hsl(var(--primary))]";
|
|
43313
|
-
return /* @__PURE__ */
|
|
43314
|
-
/* @__PURE__ */
|
|
43315
|
-
/* @__PURE__ */
|
|
43641
|
+
return /* @__PURE__ */ jsxs15("div", { className: "blade-chat-tool ml-4 text-xs", children: [
|
|
43642
|
+
/* @__PURE__ */ jsxs15("div", { className: cn("border-l-[3px] flex items-center gap-2 px-3 py-2", toneClass), children: [
|
|
43643
|
+
/* @__PURE__ */ jsxs15(
|
|
43316
43644
|
"button",
|
|
43317
43645
|
{
|
|
43318
43646
|
type: "button",
|
|
@@ -43320,7 +43648,7 @@ function ToolCallBlock({
|
|
|
43320
43648
|
className: "flex min-w-0 flex-1 items-center gap-2 text-left transition-colors hover:bg-white/3 focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
|
|
43321
43649
|
"aria-expanded": expanded,
|
|
43322
43650
|
children: [
|
|
43323
|
-
/* @__PURE__ */
|
|
43651
|
+
/* @__PURE__ */ jsx18(
|
|
43324
43652
|
ChevronRight,
|
|
43325
43653
|
{
|
|
43326
43654
|
size: 11,
|
|
@@ -43330,24 +43658,24 @@ function ToolCallBlock({
|
|
|
43330
43658
|
)
|
|
43331
43659
|
}
|
|
43332
43660
|
),
|
|
43333
|
-
/* @__PURE__ */
|
|
43661
|
+
/* @__PURE__ */ jsxs15("span", { className: cn("flex shrink-0 items-center gap-1 text-[10px]", statusTextClass), children: [
|
|
43334
43662
|
statusIcon,
|
|
43335
|
-
/* @__PURE__ */
|
|
43663
|
+
/* @__PURE__ */ jsx18("span", { children: getToolStatusLabel(toolCall.status) })
|
|
43336
43664
|
] }),
|
|
43337
|
-
/* @__PURE__ */
|
|
43665
|
+
/* @__PURE__ */ jsx18("span", { className: "min-w-0 flex-1 truncate font-medium text-[hsl(var(--foreground))]", children: displayName })
|
|
43338
43666
|
]
|
|
43339
43667
|
}
|
|
43340
43668
|
),
|
|
43341
|
-
typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */
|
|
43669
|
+
typeof toolCall.duration_ms === "number" && toolCall.duration_ms > 0 && /* @__PURE__ */ jsx18("span", { className: "shrink-0 font-mono text-[10px] text-[hsl(var(--muted-foreground))]", children: formatToolDuration(toolCall.duration_ms) })
|
|
43342
43670
|
] }),
|
|
43343
|
-
expanded && /* @__PURE__ */
|
|
43344
|
-
/* @__PURE__ */
|
|
43345
|
-
/* @__PURE__ */
|
|
43346
|
-
/* @__PURE__ */
|
|
43347
|
-
/* @__PURE__ */
|
|
43348
|
-
toolCall.result != null && /* @__PURE__ */
|
|
43349
|
-
/* @__PURE__ */
|
|
43350
|
-
/* @__PURE__ */
|
|
43671
|
+
expanded && /* @__PURE__ */ jsxs15("div", { className: "blade-chat-tool-detail ml-4 mt-1 rounded-xl bg-[hsl(var(--card))] px-3 py-3", children: [
|
|
43672
|
+
/* @__PURE__ */ jsx18("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u5DE5\u5177" }),
|
|
43673
|
+
/* @__PURE__ */ jsx18("div", { className: "mb-3 font-mono text-[11px] text-[hsl(var(--foreground))]", children: normalizedName }),
|
|
43674
|
+
/* @__PURE__ */ jsx18("div", { className: "mb-1 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u53C2\u6570" }),
|
|
43675
|
+
/* @__PURE__ */ jsx18("pre", { className: "overflow-x-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolArgs(toolCall.arguments) }),
|
|
43676
|
+
toolCall.result != null && /* @__PURE__ */ jsxs15(Fragment6, { children: [
|
|
43677
|
+
/* @__PURE__ */ jsx18("div", { className: "mb-1 mt-3 text-[10px] uppercase tracking-wider text-[hsl(var(--muted-foreground))]", children: "\u7ED3\u679C" }),
|
|
43678
|
+
/* @__PURE__ */ jsx18("pre", { className: "max-h-[400px] overflow-auto whitespace-pre-wrap rounded-md bg-[hsl(var(--muted))] p-2 font-mono text-[11px] text-[hsl(var(--foreground))]", children: formatToolResult(toolCall.result) })
|
|
43351
43679
|
] })
|
|
43352
43680
|
] })
|
|
43353
43681
|
] });
|
|
@@ -43366,13 +43694,13 @@ function buildAskUserPayload(argumentsJson) {
|
|
|
43366
43694
|
|
|
43367
43695
|
// src/components/ToolUiCardView.tsx
|
|
43368
43696
|
import { resolveToolUiCardContent } from "@blade-hq/agent-client";
|
|
43369
|
-
import { jsx as
|
|
43697
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
43370
43698
|
function ToolUiCardView({ card, sessionId }) {
|
|
43371
|
-
if (card.mcpApp) return sessionId ? /* @__PURE__ */
|
|
43699
|
+
if (card.mcpApp) return sessionId ? /* @__PURE__ */ jsx19(McpAppCard, { sessionId, sourceId: card.mcpApp.sourceId }) : null;
|
|
43372
43700
|
const resolved = resolveToolUiCardContent(card);
|
|
43373
43701
|
if (!resolved) return null;
|
|
43374
43702
|
const sandbox = resolved.type === "resource-uri" ? "allow-scripts allow-same-origin" : "allow-scripts";
|
|
43375
|
-
return /* @__PURE__ */
|
|
43703
|
+
return /* @__PURE__ */ jsx19(
|
|
43376
43704
|
"iframe",
|
|
43377
43705
|
{
|
|
43378
43706
|
title: card.title ?? "\u5DE5\u5177\u754C\u9762",
|
|
@@ -43403,12 +43731,12 @@ ${html}`;
|
|
|
43403
43731
|
}
|
|
43404
43732
|
|
|
43405
43733
|
// src/components/AssistantTurnBlock.tsx
|
|
43406
|
-
import { jsx as
|
|
43734
|
+
import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
43407
43735
|
function ThinkingBlock({ reasoning, isStreaming }) {
|
|
43408
|
-
const [open2, setOpen] =
|
|
43736
|
+
const [open2, setOpen] = useState27(false);
|
|
43409
43737
|
if (!isStreaming) return null;
|
|
43410
|
-
return /* @__PURE__ */
|
|
43411
|
-
/* @__PURE__ */
|
|
43738
|
+
return /* @__PURE__ */ jsxs16("div", { className: "blade-chat-thinking text-xs", children: [
|
|
43739
|
+
/* @__PURE__ */ jsxs16(
|
|
43412
43740
|
"button",
|
|
43413
43741
|
{
|
|
43414
43742
|
type: "button",
|
|
@@ -43416,8 +43744,8 @@ function ThinkingBlock({ reasoning, isStreaming }) {
|
|
|
43416
43744
|
"aria-expanded": open2,
|
|
43417
43745
|
className: "group/thinking inline-flex items-center gap-1 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
|
|
43418
43746
|
children: [
|
|
43419
|
-
/* @__PURE__ */
|
|
43420
|
-
/* @__PURE__ */
|
|
43747
|
+
/* @__PURE__ */ jsx20(Shimmer, { className: "text-xs", children: "\u6B63\u5728\u601D\u8003" }),
|
|
43748
|
+
/* @__PURE__ */ jsx20(
|
|
43421
43749
|
ChevronRight,
|
|
43422
43750
|
{
|
|
43423
43751
|
size: 14,
|
|
@@ -43430,7 +43758,7 @@ function ThinkingBlock({ reasoning, isStreaming }) {
|
|
|
43430
43758
|
]
|
|
43431
43759
|
}
|
|
43432
43760
|
),
|
|
43433
|
-
open2 ? /* @__PURE__ */
|
|
43761
|
+
open2 ? /* @__PURE__ */ jsx20("div", { className: "mt-1.5 whitespace-pre-wrap text-xs leading-[22px] text-[hsl(var(--muted-foreground))]", children: reasoning }) : null
|
|
43434
43762
|
] });
|
|
43435
43763
|
}
|
|
43436
43764
|
function getMessageText(message) {
|
|
@@ -43622,14 +43950,14 @@ function ExecutionToolRow({ toolCall }) {
|
|
|
43622
43950
|
"size-3.5 shrink-0",
|
|
43623
43951
|
failed ? "text-red-500" : "text-[hsl(var(--muted-foreground))]"
|
|
43624
43952
|
);
|
|
43625
|
-
const icon = toolCall.status === "pending" ? /* @__PURE__ */
|
|
43953
|
+
const icon = toolCall.status === "pending" ? /* @__PURE__ */ jsx20(LoaderCircle, { className: cn(iconClass, "animate-spin"), "aria-hidden": "true" }) : toolCall.status === "error" ? /* @__PURE__ */ jsx20(CircleAlert, { className: iconClass, "aria-hidden": "true" }) : toolCall.status === "cancelled" ? /* @__PURE__ */ jsx20(X, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "WebSearch" || normalizedName === "WebFetch" ? /* @__PURE__ */ jsx20(Earth, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Bash" || normalizedName === "BgBash" ? /* @__PURE__ */ jsx20(Terminal, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Write" || normalizedName === "Edit" || normalizedName === "MultiEdit" ? /* @__PURE__ */ jsx20(FilePenLine, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Read" || normalizedName === "ReadSkill" || normalizedName === "get_skill_content" ? /* @__PURE__ */ jsx20(BookOpen, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Grep" || normalizedName === "Glob" || normalizedName === "search_skills" ? /* @__PURE__ */ jsx20(Search, { className: iconClass, "aria-hidden": "true" }) : normalizedName === "Agent" ? /* @__PURE__ */ jsx20(Bot, { className: iconClass, "aria-hidden": "true" }) : /* @__PURE__ */ jsx20(Wrench, { className: iconClass, "aria-hidden": "true" });
|
|
43626
43954
|
const rowClassName = cn(
|
|
43627
43955
|
"flex min-w-0 items-center gap-1 py-1.5 text-xs leading-[22px]",
|
|
43628
43956
|
failed ? "text-red-500" : "text-[hsl(var(--muted-foreground))]"
|
|
43629
43957
|
);
|
|
43630
|
-
return /* @__PURE__ */
|
|
43958
|
+
return /* @__PURE__ */ jsxs16("div", { "data-testid": "execution-tool-intent", className: rowClassName, title: label, children: [
|
|
43631
43959
|
icon,
|
|
43632
|
-
/* @__PURE__ */
|
|
43960
|
+
/* @__PURE__ */ jsx20("span", { className: "min-w-0 truncate", children: label })
|
|
43633
43961
|
] });
|
|
43634
43962
|
}
|
|
43635
43963
|
function AssistantTurnBlock({
|
|
@@ -43675,12 +44003,12 @@ function AssistantTurnBlock({
|
|
|
43675
44003
|
)
|
|
43676
44004
|
);
|
|
43677
44005
|
const activeQuestionId = questionToolCalls.filter((toolCall) => toolCall.status === "pending").at(-1)?.id;
|
|
43678
|
-
const [displayMode, setDisplayMode] =
|
|
44006
|
+
const [displayMode, setDisplayMode] = useState27(
|
|
43679
44007
|
() => isStreaming || hasActionableToolCall ? "detail" : "compact"
|
|
43680
44008
|
);
|
|
43681
44009
|
const userSelectedDisplayModeRef = useRef20(false);
|
|
43682
44010
|
const wasStreamingRef = useRef20(isStreaming);
|
|
43683
|
-
|
|
44011
|
+
useEffect18(() => {
|
|
43684
44012
|
if (wasStreamingRef.current && !isStreaming && !userSelectedDisplayModeRef.current) {
|
|
43685
44013
|
setDisplayMode(hasActionableToolCall ? "detail" : "compact");
|
|
43686
44014
|
}
|
|
@@ -43688,11 +44016,11 @@ function AssistantTurnBlock({
|
|
|
43688
44016
|
}, [hasActionableToolCall, isStreaming]);
|
|
43689
44017
|
const effectiveMode = resolveTurnDisplayMode({ isStreaming, displayMode });
|
|
43690
44018
|
const executionDurationMs = getExecutionDurationMs({ messages, isStreaming });
|
|
43691
|
-
const [clock, setClock] =
|
|
44019
|
+
const [clock, setClock] = useState27(() => Date.now());
|
|
43692
44020
|
const hasLiveStartTime = messages.some(
|
|
43693
44021
|
(message) => message.timestamp != null && Number.isFinite(Date.parse(message.timestamp))
|
|
43694
44022
|
);
|
|
43695
|
-
|
|
44023
|
+
useEffect18(() => {
|
|
43696
44024
|
if (!isStreaming || !hasLiveStartTime) return;
|
|
43697
44025
|
const timer = window.setInterval(() => setClock(Date.now()), 1e3);
|
|
43698
44026
|
return () => window.clearInterval(timer);
|
|
@@ -43701,21 +44029,21 @@ function AssistantTurnBlock({
|
|
|
43701
44029
|
const memoryRefs = collectMemoryRefs(messages);
|
|
43702
44030
|
const inlineToolUiCards = collectInlineToolUiCards(messages);
|
|
43703
44031
|
if (!hasExecutionProcess) {
|
|
43704
|
-
return /* @__PURE__ */
|
|
44032
|
+
return /* @__PURE__ */ jsxs16(
|
|
43705
44033
|
"div",
|
|
43706
44034
|
{
|
|
43707
44035
|
"aria-busy": isStreaming || void 0,
|
|
43708
44036
|
className: "blade-chat-assistant-turn flex flex-col gap-3",
|
|
43709
44037
|
children: [
|
|
43710
|
-
memoryRefs.length > 0 ? /* @__PURE__ */
|
|
43711
|
-
hasInterrupted && /* @__PURE__ */
|
|
43712
|
-
hasFailedWithoutContent && /* @__PURE__ */
|
|
44038
|
+
memoryRefs.length > 0 ? /* @__PURE__ */ jsx20(MemoryRefsHint, { refs: memoryRefs }) : null,
|
|
44039
|
+
hasInterrupted && /* @__PURE__ */ jsx20("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
|
|
44040
|
+
hasFailedWithoutContent && /* @__PURE__ */ jsx20("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
|
|
43713
44041
|
messages.map((message, index) => {
|
|
43714
|
-
return hasRenderableMessageContent(message) ? /* @__PURE__ */
|
|
44042
|
+
return hasRenderableMessageContent(message) ? /* @__PURE__ */ jsx20(
|
|
43715
44043
|
"div",
|
|
43716
44044
|
{
|
|
43717
44045
|
className: "flex flex-col gap-3",
|
|
43718
|
-
children: /* @__PURE__ */
|
|
44046
|
+
children: /* @__PURE__ */ jsx20(
|
|
43719
44047
|
AssistantMessageContent,
|
|
43720
44048
|
{
|
|
43721
44049
|
message,
|
|
@@ -43727,31 +44055,31 @@ function AssistantTurnBlock({
|
|
|
43727
44055
|
message.entry_id ?? `${message.timestamp ?? "assistant"}-${index}`
|
|
43728
44056
|
) : null;
|
|
43729
44057
|
}),
|
|
43730
|
-
inlineToolUiCards.length > 0 ? /* @__PURE__ */
|
|
44058
|
+
inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx20(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null
|
|
43731
44059
|
]
|
|
43732
44060
|
}
|
|
43733
44061
|
);
|
|
43734
44062
|
}
|
|
43735
|
-
return /* @__PURE__ */
|
|
44063
|
+
return /* @__PURE__ */ jsxs16(
|
|
43736
44064
|
"div",
|
|
43737
44065
|
{
|
|
43738
44066
|
"aria-busy": isStreaming || void 0,
|
|
43739
44067
|
className: "blade-chat-assistant-turn flex flex-col gap-3",
|
|
43740
44068
|
children: [
|
|
43741
|
-
memoryRefs.length > 0 ? /* @__PURE__ */
|
|
43742
|
-
hasInterrupted && /* @__PURE__ */
|
|
43743
|
-
hasFailedWithoutContent && /* @__PURE__ */
|
|
43744
|
-
/* @__PURE__ */
|
|
43745
|
-
/* @__PURE__ */
|
|
44069
|
+
memoryRefs.length > 0 ? /* @__PURE__ */ jsx20(MemoryRefsHint, { refs: memoryRefs }) : null,
|
|
44070
|
+
hasInterrupted && /* @__PURE__ */ jsx20("div", { className: "ml-4 w-fit rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }),
|
|
44071
|
+
hasFailedWithoutContent && /* @__PURE__ */ jsx20("div", { className: "ml-4 w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }),
|
|
44072
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex w-full items-start gap-2.5", children: [
|
|
44073
|
+
/* @__PURE__ */ jsx20(
|
|
43746
44074
|
"span",
|
|
43747
44075
|
{
|
|
43748
44076
|
className: "grid size-[30px] shrink-0 place-items-center rounded-full bg-[hsl(var(--muted)/0.55)] text-[hsl(var(--foreground))]",
|
|
43749
44077
|
"aria-hidden": "true",
|
|
43750
|
-
children: /* @__PURE__ */
|
|
44078
|
+
children: /* @__PURE__ */ jsx20(Bot, { size: 16 })
|
|
43751
44079
|
}
|
|
43752
44080
|
),
|
|
43753
|
-
/* @__PURE__ */
|
|
43754
|
-
/* @__PURE__ */
|
|
44081
|
+
/* @__PURE__ */ jsxs16("div", { className: "min-w-0 flex-1 pt-0.5", children: [
|
|
44082
|
+
/* @__PURE__ */ jsxs16(
|
|
43755
44083
|
"button",
|
|
43756
44084
|
{
|
|
43757
44085
|
type: "button",
|
|
@@ -43764,14 +44092,14 @@ function AssistantTurnBlock({
|
|
|
43764
44092
|
"data-testid": "assistant-execution-summary",
|
|
43765
44093
|
className: "inline-flex min-w-0 max-w-full select-none items-center gap-1 bg-transparent p-0 text-left text-xs leading-[22px] text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))] focus-visible:ring-1 focus-visible:ring-[hsl(var(--ring))] focus:outline-none",
|
|
43766
44094
|
children: [
|
|
43767
|
-
/* @__PURE__ */
|
|
44095
|
+
/* @__PURE__ */ jsx20("span", { className: "min-w-0 truncate", children: executionSummaryLabel({
|
|
43768
44096
|
messages,
|
|
43769
44097
|
isStreaming,
|
|
43770
44098
|
durationMs: liveExecutionDurationMs,
|
|
43771
44099
|
sessionStatus,
|
|
43772
44100
|
askAnswers
|
|
43773
44101
|
}) }),
|
|
43774
|
-
/* @__PURE__ */
|
|
44102
|
+
/* @__PURE__ */ jsx20(
|
|
43775
44103
|
ChevronRight,
|
|
43776
44104
|
{
|
|
43777
44105
|
size: 14,
|
|
@@ -43786,10 +44114,10 @@ function AssistantTurnBlock({
|
|
|
43786
44114
|
]
|
|
43787
44115
|
}
|
|
43788
44116
|
),
|
|
43789
|
-
/* @__PURE__ */
|
|
44117
|
+
/* @__PURE__ */ jsx20("div", { className: "mt-3 h-px w-full bg-[hsl(var(--border)/0.75)]" })
|
|
43790
44118
|
] })
|
|
43791
44119
|
] }),
|
|
43792
|
-
effectiveMode === "detail" ? /* @__PURE__ */
|
|
44120
|
+
effectiveMode === "detail" ? /* @__PURE__ */ jsx20("div", { className: "ml-10 flex flex-col gap-3 pt-1", children: messages.map((message, index) => {
|
|
43793
44121
|
const isLast = index === messages.length - 1;
|
|
43794
44122
|
const streamingThis = isStreaming && isLast;
|
|
43795
44123
|
const text = getMessageText(message);
|
|
@@ -43799,14 +44127,14 @@ function AssistantTurnBlock({
|
|
|
43799
44127
|
const orderedParts = getOrderedMessageParts(message, toolCalls);
|
|
43800
44128
|
const showReasoning = !!message.reasoning && isStreaming && index === latestReasoningIndex;
|
|
43801
44129
|
const messageToolUiCards = collectInlineToolUiCards([message]);
|
|
43802
|
-
return /* @__PURE__ */
|
|
44130
|
+
return /* @__PURE__ */ jsxs16(
|
|
43803
44131
|
"div",
|
|
43804
44132
|
{
|
|
43805
44133
|
className: "flex flex-col gap-3",
|
|
43806
44134
|
children: [
|
|
43807
|
-
showReasoning && message.reasoning ? /* @__PURE__ */
|
|
44135
|
+
showReasoning && message.reasoning ? /* @__PURE__ */ jsx20(ThinkingBlock, { reasoning: message.reasoning, isStreaming: streamingThis && !text }) : null,
|
|
43808
44136
|
orderedParts.length > 0 ? orderedParts.map(
|
|
43809
|
-
(part) => part.type === "text" ? /* @__PURE__ */
|
|
44137
|
+
(part) => part.type === "text" ? /* @__PURE__ */ jsx20(
|
|
43810
44138
|
AssistantMessageContent,
|
|
43811
44139
|
{
|
|
43812
44140
|
message: { ...message, content: part.content, tool_calls: turnToolCalls },
|
|
@@ -43815,11 +44143,11 @@ function AssistantTurnBlock({
|
|
|
43815
44143
|
compact: true
|
|
43816
44144
|
},
|
|
43817
44145
|
part.key
|
|
43818
|
-
) : /* @__PURE__ */
|
|
44146
|
+
) : /* @__PURE__ */ jsx20("div", { className: "flex flex-col gap-0.5", children: part.toolCalls.map((toolCall) => {
|
|
43819
44147
|
const custom2 = toolCallRenderer?.(toolCall);
|
|
43820
|
-
return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */
|
|
44148
|
+
return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx20("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx20(AgentLoopBlock, { toolCall }, toolCall.id) : /* @__PURE__ */ jsx20(ExecutionToolRow, { toolCall }, toolCall.id);
|
|
43821
44149
|
}) }, part.key)
|
|
43822
|
-
) : hasRenderableMessageContent(message) && message !== finalMessage ? /* @__PURE__ */
|
|
44150
|
+
) : hasRenderableMessageContent(message) && message !== finalMessage ? /* @__PURE__ */ jsx20(
|
|
43823
44151
|
AssistantMessageContent,
|
|
43824
44152
|
{
|
|
43825
44153
|
message,
|
|
@@ -43828,18 +44156,18 @@ function AssistantTurnBlock({
|
|
|
43828
44156
|
compact: true
|
|
43829
44157
|
}
|
|
43830
44158
|
) : null,
|
|
43831
|
-
orderedParts.length === 0 && toolCalls.length > 0 ? /* @__PURE__ */
|
|
44159
|
+
orderedParts.length === 0 && toolCalls.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "flex flex-col gap-0.5", children: toolCalls.map((toolCall) => {
|
|
43832
44160
|
const custom2 = toolCallRenderer?.(toolCall);
|
|
43833
|
-
return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */
|
|
44161
|
+
return custom2 !== null && custom2 !== void 0 ? /* @__PURE__ */ jsx20("div", { children: custom2 }, toolCall.id) : formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx20(AgentLoopBlock, { toolCall }, toolCall.id) : /* @__PURE__ */ jsx20(ExecutionToolRow, { toolCall }, toolCall.id);
|
|
43834
44162
|
}) }) : null,
|
|
43835
|
-
messageToolUiCards.map((entry) => /* @__PURE__ */
|
|
44163
|
+
messageToolUiCards.map((entry) => /* @__PURE__ */ jsx20(ToolUiCardView, { card: entry.card, sessionId }, entry.key))
|
|
43836
44164
|
]
|
|
43837
44165
|
},
|
|
43838
44166
|
message.entry_id ?? `${message.timestamp ?? "assistant"}-${index}`
|
|
43839
44167
|
);
|
|
43840
44168
|
}) }) : null,
|
|
43841
|
-
effectiveMode === "compact" && inlineToolUiCards.length > 0 ? /* @__PURE__ */
|
|
43842
|
-
finalMessage && (effectiveMode === "compact" || finalOrderedParts.length === 0) ? /* @__PURE__ */
|
|
44169
|
+
effectiveMode === "compact" && inlineToolUiCards.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "ml-10 flex flex-col gap-3", children: inlineToolUiCards.map((entry) => /* @__PURE__ */ jsx20(ToolUiCardView, { card: entry.card, sessionId }, entry.key)) }) : null,
|
|
44170
|
+
finalMessage && (effectiveMode === "compact" || finalOrderedParts.length === 0) ? /* @__PURE__ */ jsx20("div", { className: "ml-10", children: /* @__PURE__ */ jsx20(
|
|
43843
44171
|
AssistantMessageContent,
|
|
43844
44172
|
{
|
|
43845
44173
|
message: finalMessage,
|
|
@@ -43847,7 +44175,7 @@ function AssistantTurnBlock({
|
|
|
43847
44175
|
streaming: isStreaming && finalMessage === messages[messages.length - 1]
|
|
43848
44176
|
}
|
|
43849
44177
|
) }) : null,
|
|
43850
|
-
questionToolCalls.map((toolCall) => /* @__PURE__ */
|
|
44178
|
+
questionToolCalls.map((toolCall) => /* @__PURE__ */ jsx20(
|
|
43851
44179
|
ToolCallBlock,
|
|
43852
44180
|
{
|
|
43853
44181
|
toolCall,
|
|
@@ -43872,22 +44200,22 @@ function collectMemoryRefs(messages) {
|
|
|
43872
44200
|
return [...refs.values()];
|
|
43873
44201
|
}
|
|
43874
44202
|
function MemoryRefsHint({ refs }) {
|
|
43875
|
-
const [expanded, setExpanded] =
|
|
44203
|
+
const [expanded, setExpanded] = useState27(false);
|
|
43876
44204
|
const label = refs.some((ref) => ref.skill_name) ? "\u53C2\u8003\u4E86\u8BE5\u6280\u80FD\u7684\u5386\u53F2\u7ECF\u9A8C" : "\u53C2\u8003\u4E86\u5386\u53F2\u7ECF\u9A8C";
|
|
43877
|
-
return /* @__PURE__ */
|
|
43878
|
-
/* @__PURE__ */
|
|
43879
|
-
/* @__PURE__ */
|
|
43880
|
-
/* @__PURE__ */
|
|
44205
|
+
return /* @__PURE__ */ jsxs16("div", { className: "blade-chat-memory-refs ml-1 w-full max-w-[680px]", children: [
|
|
44206
|
+
/* @__PURE__ */ jsxs16("button", { type: "button", onClick: () => setExpanded((value) => !value), className: "inline-flex h-8 items-center gap-1.5 rounded-lg border border-[hsl(var(--primary)/0.22)] bg-[hsl(var(--primary)/0.07)] px-3 text-xs font-medium text-[hsl(var(--primary))]", children: [
|
|
44207
|
+
/* @__PURE__ */ jsx20(BookOpen, { size: 12 }),
|
|
44208
|
+
/* @__PURE__ */ jsxs16("span", { children: [
|
|
43881
44209
|
label,
|
|
43882
44210
|
"\uFF08",
|
|
43883
44211
|
refs.length,
|
|
43884
44212
|
"\uFF09"
|
|
43885
44213
|
] }),
|
|
43886
|
-
/* @__PURE__ */
|
|
44214
|
+
/* @__PURE__ */ jsx20(ChevronRight, { size: 10, className: cn("transition-transform", expanded && "rotate-90") })
|
|
43887
44215
|
] }),
|
|
43888
|
-
expanded ? /* @__PURE__ */
|
|
43889
|
-
/* @__PURE__ */
|
|
43890
|
-
ref.skill_name ? /* @__PURE__ */
|
|
44216
|
+
expanded ? /* @__PURE__ */ jsx20("div", { className: "mt-2 flex flex-col gap-2 rounded-xl border border-[hsl(var(--border)/0.8)] bg-[hsl(var(--muted)/0.28)] p-2.5", children: refs.map((ref) => /* @__PURE__ */ jsxs16("div", { className: "rounded-lg border border-[hsl(var(--border)/0.55)] bg-[hsl(var(--background)/0.72)] px-3 py-2.5 text-xs", children: [
|
|
44217
|
+
/* @__PURE__ */ jsx20("p", { className: "line-clamp-2 break-words leading-5", children: ref.content_preview }),
|
|
44218
|
+
ref.skill_name ? /* @__PURE__ */ jsx20("span", { className: "mt-1 inline-flex text-[10px] text-[hsl(var(--primary))]", children: ref.skill_name }) : null
|
|
43891
44219
|
] }, ref.id)) }) : null
|
|
43892
44220
|
] });
|
|
43893
44221
|
}
|
|
@@ -43901,15 +44229,15 @@ function AssistantMessageContent({
|
|
|
43901
44229
|
const imageParts = getImageParts(message.content);
|
|
43902
44230
|
const fileParts = getFileParts(message.content);
|
|
43903
44231
|
const failed = message.status === "failed";
|
|
43904
|
-
const failedBadge = failed ? /* @__PURE__ */
|
|
43905
|
-
const textContent = text ? /* @__PURE__ */
|
|
44232
|
+
const failedBadge = failed ? /* @__PURE__ */ jsx20("div", { className: "w-fit rounded-full border border-red-500/30 bg-red-500/10 px-2.5 py-1 text-[10px] font-medium text-red-400", children: "\u751F\u6210\u5931\u8D25" }) : null;
|
|
44233
|
+
const textContent = text ? /* @__PURE__ */ jsx20(
|
|
43906
44234
|
"div",
|
|
43907
44235
|
{
|
|
43908
44236
|
className: cn(
|
|
43909
44237
|
"blade-chat-assistant-text",
|
|
43910
44238
|
compact ? "text-xs leading-[22px] text-[hsl(var(--foreground))]" : "text-[15px] leading-8 text-[hsl(var(--foreground))]"
|
|
43911
44239
|
),
|
|
43912
|
-
children: /* @__PURE__ */
|
|
44240
|
+
children: /* @__PURE__ */ jsx20(
|
|
43913
44241
|
MarkdownContent,
|
|
43914
44242
|
{
|
|
43915
44243
|
mode: streaming ? "streaming" : "static",
|
|
@@ -43922,14 +44250,14 @@ function AssistantMessageContent({
|
|
|
43922
44250
|
) : null;
|
|
43923
44251
|
if (imageParts.length === 0 && fileParts.length === 0) {
|
|
43924
44252
|
if (!failed) return textContent;
|
|
43925
|
-
return failedBadge || textContent ? /* @__PURE__ */
|
|
44253
|
+
return failedBadge || textContent ? /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-2", children: [
|
|
43926
44254
|
failedBadge,
|
|
43927
44255
|
textContent
|
|
43928
44256
|
] }) : null;
|
|
43929
44257
|
}
|
|
43930
|
-
return /* @__PURE__ */
|
|
44258
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-3", children: [
|
|
43931
44259
|
failedBadge,
|
|
43932
|
-
imageParts.length > 0 ? /* @__PURE__ */
|
|
44260
|
+
imageParts.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx20(
|
|
43933
44261
|
"img",
|
|
43934
44262
|
{
|
|
43935
44263
|
src: part.image_url.url,
|
|
@@ -43938,14 +44266,14 @@ function AssistantMessageContent({
|
|
|
43938
44266
|
},
|
|
43939
44267
|
part.image_url.url
|
|
43940
44268
|
)) }) : null,
|
|
43941
|
-
fileParts.length > 0 ? /* @__PURE__ */
|
|
44269
|
+
fileParts.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "flex flex-wrap gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs16(
|
|
43942
44270
|
"div",
|
|
43943
44271
|
{
|
|
43944
44272
|
className: "flex min-w-0 items-center gap-1.5 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.3)] px-2.5 py-1.5 text-xs text-[hsl(var(--muted-foreground))]",
|
|
43945
44273
|
title: part.name,
|
|
43946
44274
|
children: [
|
|
43947
|
-
/* @__PURE__ */
|
|
43948
|
-
/* @__PURE__ */
|
|
44275
|
+
/* @__PURE__ */ jsx20(FileText, { size: 12, className: "shrink-0" }),
|
|
44276
|
+
/* @__PURE__ */ jsx20("span", { className: "max-w-56 truncate", children: part.name })
|
|
43949
44277
|
]
|
|
43950
44278
|
},
|
|
43951
44279
|
`${part.name}-${part.data.slice(0, 32)}`
|
|
@@ -43956,7 +44284,7 @@ function AssistantMessageContent({
|
|
|
43956
44284
|
|
|
43957
44285
|
// src/components/RenderErrorBoundary.tsx
|
|
43958
44286
|
import { Component as Component2 } from "react";
|
|
43959
|
-
import { jsx as
|
|
44287
|
+
import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
43960
44288
|
function getFirstComponentName(componentStack) {
|
|
43961
44289
|
const match = componentStack.match(/\n\s+at\s+([^\s(]+)/);
|
|
43962
44290
|
return match?.[1] ?? null;
|
|
@@ -43989,26 +44317,26 @@ var RenderErrorBoundary = class extends Component2 {
|
|
|
43989
44317
|
return children;
|
|
43990
44318
|
}
|
|
43991
44319
|
const componentName = getFirstComponentName(componentStack);
|
|
43992
|
-
return /* @__PURE__ */
|
|
43993
|
-
/* @__PURE__ */
|
|
43994
|
-
/* @__PURE__ */
|
|
43995
|
-
/* @__PURE__ */
|
|
44320
|
+
return /* @__PURE__ */ jsx21("div", { className: "blade-chat-render-error rounded-xl border border-amber-500/30 bg-amber-500/8 px-4 py-3 text-sm text-amber-100", children: /* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-2", children: [
|
|
44321
|
+
/* @__PURE__ */ jsx21(TriangleAlert, { className: "mt-0.5 h-4 w-4 shrink-0 text-amber-300" }),
|
|
44322
|
+
/* @__PURE__ */ jsxs17("div", { className: "min-w-0 flex-1", children: [
|
|
44323
|
+
/* @__PURE__ */ jsxs17("div", { className: "font-medium", children: [
|
|
43996
44324
|
label,
|
|
43997
44325
|
"\u6E32\u67D3\u5931\u8D25"
|
|
43998
44326
|
] }),
|
|
43999
|
-
/* @__PURE__ */
|
|
44327
|
+
/* @__PURE__ */ jsxs17("div", { className: "mt-1 break-words text-xs leading-5 text-amber-100/75", children: [
|
|
44000
44328
|
componentName ? `\u7EC4\u4EF6\uFF1A${componentName}\u3002` : null,
|
|
44001
44329
|
error61.message || "\u53D1\u751F\u4E86\u672A\u9884\u671F\u7684\u6E32\u67D3\u9519\u8BEF\u3002"
|
|
44002
44330
|
] }),
|
|
44003
|
-
details ? /* @__PURE__ */
|
|
44331
|
+
details ? /* @__PURE__ */ jsx21("div", { className: "mt-1 truncate text-xs text-amber-100/55", children: details }) : null
|
|
44004
44332
|
] })
|
|
44005
44333
|
] }) });
|
|
44006
44334
|
}
|
|
44007
44335
|
};
|
|
44008
44336
|
|
|
44009
44337
|
// src/components/PostChatFollowupBlock.tsx
|
|
44010
|
-
import { useCallback as
|
|
44011
|
-
import { Fragment as Fragment7, jsx as
|
|
44338
|
+
import { useCallback as useCallback25, useEffect as useEffect19, useRef as useRef21, useState as useState28 } from "react";
|
|
44339
|
+
import { Fragment as Fragment7, jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
44012
44340
|
function emitInteraction(callback, event) {
|
|
44013
44341
|
try {
|
|
44014
44342
|
callback?.(event);
|
|
@@ -44027,10 +44355,10 @@ function ArtifactCard({
|
|
|
44027
44355
|
onArtifactOpened
|
|
44028
44356
|
}) {
|
|
44029
44357
|
const client = useBladeClient();
|
|
44030
|
-
const [downloading, setDownloading] =
|
|
44358
|
+
const [downloading, setDownloading] = useState28(false);
|
|
44031
44359
|
const name = artifact.label || basename(artifact.target);
|
|
44032
44360
|
if (artifact.kind === "link") {
|
|
44033
|
-
return /* @__PURE__ */
|
|
44361
|
+
return /* @__PURE__ */ jsxs18(
|
|
44034
44362
|
"a",
|
|
44035
44363
|
{
|
|
44036
44364
|
href: artifact.target,
|
|
@@ -44041,9 +44369,9 @@ function ArtifactCard({
|
|
|
44041
44369
|
${artifact.target}`,
|
|
44042
44370
|
className: "group relative flex min-w-0 items-center gap-1.5 rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-2 py-1.5 text-xs text-[hsl(var(--card-foreground))] hover:bg-[hsl(var(--accent))]",
|
|
44043
44371
|
children: [
|
|
44044
|
-
/* @__PURE__ */
|
|
44045
|
-
/* @__PURE__ */
|
|
44046
|
-
/* @__PURE__ */
|
|
44372
|
+
/* @__PURE__ */ jsx22(Globe, { size: 15, className: "shrink-0 text-[hsl(var(--primary))]" }),
|
|
44373
|
+
/* @__PURE__ */ jsx22("span", { className: "min-w-0 flex-1 truncate font-medium", children: name }),
|
|
44374
|
+
/* @__PURE__ */ jsx22(ArrowUpRight, { size: 13, className: "absolute right-2 opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100" })
|
|
44047
44375
|
]
|
|
44048
44376
|
}
|
|
44049
44377
|
);
|
|
@@ -44078,7 +44406,7 @@ ${artifact.target}`,
|
|
|
44078
44406
|
setDownloading(false);
|
|
44079
44407
|
}
|
|
44080
44408
|
};
|
|
44081
|
-
return /* @__PURE__ */
|
|
44409
|
+
return /* @__PURE__ */ jsx22(
|
|
44082
44410
|
"a",
|
|
44083
44411
|
{
|
|
44084
44412
|
href: downloadUrl,
|
|
@@ -44106,17 +44434,17 @@ function feedbackReasonLabel(reason) {
|
|
|
44106
44434
|
}
|
|
44107
44435
|
function HistoricalResultFeedback({ feedback }) {
|
|
44108
44436
|
const label = feedbackReasonLabel(feedback.reason);
|
|
44109
|
-
return /* @__PURE__ */
|
|
44437
|
+
return /* @__PURE__ */ jsxs18(
|
|
44110
44438
|
"section",
|
|
44111
44439
|
{
|
|
44112
44440
|
"aria-label": "\u5386\u53F2\u7ED3\u679C\u53CD\u9988",
|
|
44113
44441
|
className: "mt-3 w-fit max-w-full rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.2)] px-3 py-2 text-xs text-[hsl(var(--muted-foreground))]",
|
|
44114
44442
|
children: [
|
|
44115
|
-
/* @__PURE__ */
|
|
44443
|
+
/* @__PURE__ */ jsxs18("span", { children: [
|
|
44116
44444
|
"\u4F60\u5BF9\u6B64\u8F6E\u7ED3\u679C\u7684\u8BC4\u4EF7\uFF1A",
|
|
44117
44445
|
feedback.helpful ? "\u6709\u5E2E\u52A9" : "\u6CA1\u5E2E\u52A9"
|
|
44118
44446
|
] }),
|
|
44119
|
-
label ? /* @__PURE__ */
|
|
44447
|
+
label ? /* @__PURE__ */ jsxs18("span", { children: [
|
|
44120
44448
|
" \xB7 ",
|
|
44121
44449
|
label
|
|
44122
44450
|
] }) : null
|
|
@@ -44133,15 +44461,15 @@ function ResultFeedback({
|
|
|
44133
44461
|
onFeedbackSaved
|
|
44134
44462
|
}) {
|
|
44135
44463
|
const client = useBladeClient();
|
|
44136
|
-
const [saved, setSaved] =
|
|
44137
|
-
const [helpful, setHelpful] =
|
|
44138
|
-
const [reason, setReason] =
|
|
44139
|
-
const [saving, setSaving] =
|
|
44140
|
-
const [saveError, setSaveError] =
|
|
44464
|
+
const [saved, setSaved] = useState28(savedFeedback ?? null);
|
|
44465
|
+
const [helpful, setHelpful] = useState28(savedFeedback?.helpful ?? null);
|
|
44466
|
+
const [reason, setReason] = useState28(savedFeedback?.reason ?? null);
|
|
44467
|
+
const [saving, setSaving] = useState28(false);
|
|
44468
|
+
const [saveError, setSaveError] = useState28(false);
|
|
44141
44469
|
const reportedShown = useRef21(false);
|
|
44142
44470
|
const latestChoice = useRef21(null);
|
|
44143
44471
|
const eligible = followup.feedback_eligible === true && Boolean(sessionId) && !isViewer;
|
|
44144
|
-
|
|
44472
|
+
useEffect19(() => {
|
|
44145
44473
|
if (!eligible || reportedShown.current) return;
|
|
44146
44474
|
reportedShown.current = true;
|
|
44147
44475
|
emitInteraction(onInteraction, {
|
|
@@ -44150,13 +44478,13 @@ function ResultFeedback({
|
|
|
44150
44478
|
assistantEntryId: followup.assistant_entry_id
|
|
44151
44479
|
});
|
|
44152
44480
|
}, [eligible, followup.assistant_entry_id, onInteraction, sessionId]);
|
|
44153
|
-
|
|
44481
|
+
useEffect19(() => {
|
|
44154
44482
|
if (!savedFeedback || latestChoice.current) return;
|
|
44155
44483
|
setSaved(savedFeedback);
|
|
44156
44484
|
setHelpful(savedFeedback.helpful);
|
|
44157
44485
|
setReason(savedFeedback.reason);
|
|
44158
44486
|
}, [savedFeedback]);
|
|
44159
|
-
const submit =
|
|
44487
|
+
const submit = useCallback25(
|
|
44160
44488
|
async (nextHelpful, nextReason) => {
|
|
44161
44489
|
if (!sessionId) return;
|
|
44162
44490
|
const choice = { helpful: nextHelpful, reason: nextReason };
|
|
@@ -44191,15 +44519,15 @@ function ResultFeedback({
|
|
|
44191
44519
|
[client, followup.assistant_entry_id, onFeedbackSaved, onInteraction, sessionId]
|
|
44192
44520
|
);
|
|
44193
44521
|
if (!eligible) return null;
|
|
44194
|
-
return /* @__PURE__ */
|
|
44522
|
+
return /* @__PURE__ */ jsxs18(
|
|
44195
44523
|
"section",
|
|
44196
44524
|
{
|
|
44197
44525
|
"aria-label": "\u7ED3\u679C\u53CD\u9988",
|
|
44198
44526
|
className: "flex flex-col gap-2 border-t border-[hsl(var(--border))] pt-3",
|
|
44199
44527
|
children: [
|
|
44200
|
-
/* @__PURE__ */
|
|
44201
|
-
/* @__PURE__ */
|
|
44202
|
-
/* @__PURE__ */
|
|
44528
|
+
/* @__PURE__ */ jsx22("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u76EE\u524D\u7684\u6574\u4F53\u7ED3\u679C\u6709\u5E2E\u52A9\u5417\uFF1F" }),
|
|
44529
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex flex-wrap gap-1.5", children: [
|
|
44530
|
+
/* @__PURE__ */ jsx22(
|
|
44203
44531
|
"button",
|
|
44204
44532
|
{
|
|
44205
44533
|
type: "button",
|
|
@@ -44210,7 +44538,7 @@ function ResultFeedback({
|
|
|
44210
44538
|
children: "\u6709\u5E2E\u52A9"
|
|
44211
44539
|
}
|
|
44212
44540
|
),
|
|
44213
|
-
/* @__PURE__ */
|
|
44541
|
+
/* @__PURE__ */ jsx22(
|
|
44214
44542
|
"button",
|
|
44215
44543
|
{
|
|
44216
44544
|
type: "button",
|
|
@@ -44222,7 +44550,7 @@ function ResultFeedback({
|
|
|
44222
44550
|
}
|
|
44223
44551
|
)
|
|
44224
44552
|
] }),
|
|
44225
|
-
helpful === false ? /* @__PURE__ */
|
|
44553
|
+
helpful === false ? /* @__PURE__ */ jsx22("div", { className: "flex flex-wrap gap-1.5", "aria-label": "\u6CA1\u5E2E\u52A9\u7684\u4E3B\u8981\u539F\u56E0", children: FEEDBACK_REASONS.map((item) => /* @__PURE__ */ jsx22(
|
|
44226
44554
|
"button",
|
|
44227
44555
|
{
|
|
44228
44556
|
type: "button",
|
|
@@ -44234,9 +44562,9 @@ function ResultFeedback({
|
|
|
44234
44562
|
},
|
|
44235
44563
|
item.value
|
|
44236
44564
|
)) }) : null,
|
|
44237
|
-
saveError ? /* @__PURE__ */
|
|
44238
|
-
/* @__PURE__ */
|
|
44239
|
-
/* @__PURE__ */
|
|
44565
|
+
saveError ? /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2 text-xs text-[hsl(var(--destructive))]", children: [
|
|
44566
|
+
/* @__PURE__ */ jsx22("span", { children: "\u53CD\u9988\u6682\u672A\u4FDD\u5B58\uFF0C\u53EF\u91CD\u8BD5" }),
|
|
44567
|
+
/* @__PURE__ */ jsx22(
|
|
44240
44568
|
"button",
|
|
44241
44569
|
{
|
|
44242
44570
|
type: "button",
|
|
@@ -44248,7 +44576,7 @@ function ResultFeedback({
|
|
|
44248
44576
|
children: "\u91CD\u8BD5"
|
|
44249
44577
|
}
|
|
44250
44578
|
)
|
|
44251
|
-
] }) : saved ? /* @__PURE__ */
|
|
44579
|
+
] }) : saved ? /* @__PURE__ */ jsx22("div", { className: "text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u4FDD\u5B58\uFF0C\u53EF\u968F\u65F6\u4FEE\u6539" }) : null
|
|
44252
44580
|
]
|
|
44253
44581
|
}
|
|
44254
44582
|
);
|
|
@@ -44262,14 +44590,14 @@ function PostChatFollowupBlock({
|
|
|
44262
44590
|
savedFeedback,
|
|
44263
44591
|
onFeedbackSaved
|
|
44264
44592
|
}) {
|
|
44265
|
-
const [expanded, setExpanded] =
|
|
44593
|
+
const [expanded, setExpanded] = useState28(false);
|
|
44266
44594
|
const adopted = useRef21(/* @__PURE__ */ new Set());
|
|
44267
44595
|
const reportedSuggestions = useRef21(false);
|
|
44268
44596
|
const reportedArtifacts = useRef21(/* @__PURE__ */ new Set());
|
|
44269
44597
|
const openedArtifacts = useRef21(/* @__PURE__ */ new Set());
|
|
44270
44598
|
const artifacts = followup.final_artifacts ?? [];
|
|
44271
44599
|
const visibleArtifacts = expanded ? artifacts : artifacts.slice(0, 3);
|
|
44272
|
-
|
|
44600
|
+
useEffect19(() => {
|
|
44273
44601
|
if (!reportedSuggestions.current && followup.suggestions.length > 0) {
|
|
44274
44602
|
reportedSuggestions.current = true;
|
|
44275
44603
|
emitInteraction(onInteraction, {
|
|
@@ -44299,7 +44627,7 @@ function PostChatFollowupBlock({
|
|
|
44299
44627
|
sessionId,
|
|
44300
44628
|
visibleArtifacts
|
|
44301
44629
|
]);
|
|
44302
|
-
const reportArtifactOpened =
|
|
44630
|
+
const reportArtifactOpened = useCallback25(
|
|
44303
44631
|
(artifactIndex, artifactKind) => {
|
|
44304
44632
|
if (openedArtifacts.current.has(artifactIndex)) return;
|
|
44305
44633
|
openedArtifacts.current.add(artifactIndex);
|
|
@@ -44315,15 +44643,15 @@ function PostChatFollowupBlock({
|
|
|
44315
44643
|
);
|
|
44316
44644
|
if (!followup.recaption && artifacts.length === 0 && followup.suggestions.length === 0 && !followup.feedback_eligible)
|
|
44317
44645
|
return null;
|
|
44318
|
-
return /* @__PURE__ */
|
|
44319
|
-
followup.recaption || artifacts.length > 0 ? /* @__PURE__ */
|
|
44320
|
-
/* @__PURE__ */
|
|
44321
|
-
/* @__PURE__ */
|
|
44646
|
+
return /* @__PURE__ */ jsxs18("div", { className: "mt-3 flex w-fit max-w-full flex-col gap-3 rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.28)] p-3 sm:max-w-[680px]", children: [
|
|
44647
|
+
followup.recaption || artifacts.length > 0 ? /* @__PURE__ */ jsxs18("section", { "aria-label": "\u672C\u8F6E\u5C0F\u7ED3", className: "flex flex-col gap-2", children: [
|
|
44648
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-1.5 text-xs font-medium text-[hsl(var(--muted-foreground))]", children: [
|
|
44649
|
+
/* @__PURE__ */ jsx22(Sparkles, { size: 14 }),
|
|
44322
44650
|
"\u672C\u8F6E\u5C0F\u7ED3"
|
|
44323
44651
|
] }),
|
|
44324
|
-
followup.recaption ? /* @__PURE__ */
|
|
44325
|
-
artifacts.length > 0 ? /* @__PURE__ */
|
|
44326
|
-
/* @__PURE__ */
|
|
44652
|
+
followup.recaption ? /* @__PURE__ */ jsx22("p", { className: "text-[13px] leading-5", children: followup.recaption }) : null,
|
|
44653
|
+
artifacts.length > 0 ? /* @__PURE__ */ jsxs18(Fragment7, { children: [
|
|
44654
|
+
/* @__PURE__ */ jsx22("div", { className: "grid max-w-full grid-cols-3 gap-1.5", children: visibleArtifacts.map((artifact, artifactIndex) => /* @__PURE__ */ jsx22(
|
|
44327
44655
|
ArtifactCard,
|
|
44328
44656
|
{
|
|
44329
44657
|
artifact,
|
|
@@ -44335,7 +44663,7 @@ function PostChatFollowupBlock({
|
|
|
44335
44663
|
},
|
|
44336
44664
|
`${artifact.kind}:${artifactIndex}`
|
|
44337
44665
|
)) }),
|
|
44338
|
-
artifacts.length > 3 ? /* @__PURE__ */
|
|
44666
|
+
artifacts.length > 3 ? /* @__PURE__ */ jsxs18(
|
|
44339
44667
|
"button",
|
|
44340
44668
|
{
|
|
44341
44669
|
type: "button",
|
|
@@ -44344,15 +44672,15 @@ function PostChatFollowupBlock({
|
|
|
44344
44672
|
className: "flex w-fit items-center gap-0.5 text-[11px] text-[hsl(var(--muted-foreground))]",
|
|
44345
44673
|
children: [
|
|
44346
44674
|
expanded ? "\u6536\u8D77" : `\u5C55\u5F00 ${artifacts.length - 3} \u4E2A`,
|
|
44347
|
-
/* @__PURE__ */
|
|
44675
|
+
/* @__PURE__ */ jsx22(ChevronDown, { size: 13, className: expanded ? "rotate-180" : void 0 })
|
|
44348
44676
|
]
|
|
44349
44677
|
}
|
|
44350
44678
|
) : null
|
|
44351
44679
|
] }) : null
|
|
44352
44680
|
] }) : null,
|
|
44353
|
-
followup.suggestions.length > 0 ? /* @__PURE__ */
|
|
44354
|
-
/* @__PURE__ */
|
|
44355
|
-
followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */
|
|
44681
|
+
followup.suggestions.length > 0 ? /* @__PURE__ */ jsxs18("section", { "aria-label": "\u4E0B\u4E00\u6B65\u5EFA\u8BAE", className: "flex flex-col gap-1.5", children: [
|
|
44682
|
+
/* @__PURE__ */ jsx22("div", { className: "text-xs font-medium text-[hsl(var(--muted-foreground))]", children: "\u4E0B\u4E00\u6B65\u53EF\u4EE5" }),
|
|
44683
|
+
followup.suggestions.map((suggestion, suggestionIndex) => /* @__PURE__ */ jsxs18(
|
|
44356
44684
|
"button",
|
|
44357
44685
|
{
|
|
44358
44686
|
type: "button",
|
|
@@ -44371,14 +44699,14 @@ function PostChatFollowupBlock({
|
|
|
44371
44699
|
},
|
|
44372
44700
|
className: "group flex items-center gap-2 rounded-xl bg-[hsl(var(--muted)/0.62)] px-3 py-2 text-left text-[13px] disabled:cursor-default disabled:opacity-60",
|
|
44373
44701
|
children: [
|
|
44374
|
-
/* @__PURE__ */
|
|
44375
|
-
/* @__PURE__ */
|
|
44702
|
+
/* @__PURE__ */ jsx22("span", { children: suggestion }),
|
|
44703
|
+
/* @__PURE__ */ jsx22(ArrowRight, { size: 14, className: "ml-auto shrink-0" })
|
|
44376
44704
|
]
|
|
44377
44705
|
},
|
|
44378
44706
|
suggestion
|
|
44379
44707
|
))
|
|
44380
44708
|
] }) : null,
|
|
44381
|
-
/* @__PURE__ */
|
|
44709
|
+
/* @__PURE__ */ jsx22(
|
|
44382
44710
|
ResultFeedback,
|
|
44383
44711
|
{
|
|
44384
44712
|
followup,
|
|
@@ -44453,31 +44781,31 @@ function parseWhatIfPrompt(text) {
|
|
|
44453
44781
|
}
|
|
44454
44782
|
|
|
44455
44783
|
// src/components/WhatIfUserBubble.tsx
|
|
44456
|
-
import { jsx as
|
|
44784
|
+
import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
44457
44785
|
function WhatIfUserBubble({ parsed, onQuoteClick }) {
|
|
44458
44786
|
const { fromStep, quotes, userText } = parsed;
|
|
44459
|
-
return /* @__PURE__ */
|
|
44460
|
-
/* @__PURE__ */
|
|
44461
|
-
/* @__PURE__ */
|
|
44462
|
-
/* @__PURE__ */
|
|
44787
|
+
return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-end gap-2", children: [
|
|
44788
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--muted)/0.5)] px-2.5 py-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: [
|
|
44789
|
+
/* @__PURE__ */ jsx23(RefreshCcw, { size: 10 }),
|
|
44790
|
+
/* @__PURE__ */ jsx23("span", { children: fromStep != null ? `\u91CD\u8DD1\u81EA step ${fromStep}` : "\u91CD\u8DD1" })
|
|
44463
44791
|
] }),
|
|
44464
|
-
quotes.length > 0 && /* @__PURE__ */
|
|
44792
|
+
quotes.length > 0 && /* @__PURE__ */ jsx23("div", { className: "flex max-w-[min(72vw,42rem)] flex-col items-stretch gap-2", children: quotes.map((quote, index) => {
|
|
44465
44793
|
const clickable = quote.stepNumber != null && !!onQuoteClick;
|
|
44466
44794
|
const label = quote.stepNumber != null ? `\u6B65\u9AA4${quote.stepNumber} \xB7 ${quote.label}` : quote.label;
|
|
44467
|
-
return /* @__PURE__ */
|
|
44468
|
-
/* @__PURE__ */
|
|
44469
|
-
/* @__PURE__ */
|
|
44470
|
-
/* @__PURE__ */
|
|
44795
|
+
return /* @__PURE__ */ jsxs19("div", { className: "rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card)/0.8)] px-3 py-2 text-left", children: [
|
|
44796
|
+
/* @__PURE__ */ jsxs19("button", { type: "button", disabled: !clickable, onClick: () => clickable && onQuoteClick(quote.stepNumber), className: "inline-flex max-w-full items-center gap-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))] hover:text-[hsl(var(--foreground))] disabled:cursor-default", title: clickable ? "\u8DF3\u8F6C\u5230\u5BF9\u5E94\u6B65\u9AA4\u5361\u7247" : void 0, children: [
|
|
44797
|
+
/* @__PURE__ */ jsx23("span", { children: "\u21B3" }),
|
|
44798
|
+
/* @__PURE__ */ jsx23("span", { className: "truncate", children: label })
|
|
44471
44799
|
] }),
|
|
44472
|
-
quote.snapshot ? /* @__PURE__ */
|
|
44800
|
+
quote.snapshot ? /* @__PURE__ */ jsx23("div", { className: "mt-1 border-l-2 border-[hsl(var(--accent-foreground)/0.35)] pl-2 text-xs leading-relaxed text-[hsl(var(--foreground)/0.8)]", children: /* @__PURE__ */ jsx23(MarkdownContent, { className: "blade-chat-prose", children: quote.snapshot }) }) : null
|
|
44473
44801
|
] }, `${quote.stepNumber ?? "x"}-${index}`);
|
|
44474
44802
|
}) }),
|
|
44475
|
-
userText && /* @__PURE__ */
|
|
44803
|
+
userText && /* @__PURE__ */ jsx23("div", { className: "rounded-2xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-4 py-2.5 text-sm leading-relaxed text-[hsl(var(--user-msg-fg))]", children: /* @__PURE__ */ jsx23(MarkdownContent, { className: "blade-chat-prose", children: userText }) })
|
|
44476
44804
|
] });
|
|
44477
44805
|
}
|
|
44478
44806
|
|
|
44479
44807
|
// src/components/UserMessageBubble.tsx
|
|
44480
|
-
import { jsx as
|
|
44808
|
+
import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
44481
44809
|
function isUserMessage(message) {
|
|
44482
44810
|
return message.role === "user";
|
|
44483
44811
|
}
|
|
@@ -44491,10 +44819,10 @@ function UserMessageBubble({ message, className }) {
|
|
|
44491
44819
|
const imageParts = getImageParts2(message.content);
|
|
44492
44820
|
const whatifParsed = text && imageParts.length === 0 && fileParts.length === 0 ? parseWhatIfPrompt(text) : null;
|
|
44493
44821
|
if (whatifParsed) {
|
|
44494
|
-
return /* @__PURE__ */
|
|
44822
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("blade-chat-user-row flex justify-end", className), children: /* @__PURE__ */ jsx24("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: /* @__PURE__ */ jsx24(WhatIfUserBubble, { parsed: whatifParsed }) }) });
|
|
44495
44823
|
}
|
|
44496
|
-
return /* @__PURE__ */
|
|
44497
|
-
imageParts.length > 0 && /* @__PURE__ */
|
|
44824
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("blade-chat-user-row flex justify-end", className), children: /* @__PURE__ */ jsxs20("div", { className: "blade-chat-user-col flex max-w-[72%] flex-col items-end gap-3", children: [
|
|
44825
|
+
imageParts.length > 0 && /* @__PURE__ */ jsx24("div", { className: "grid gap-2", children: imageParts.map((part) => /* @__PURE__ */ jsx24(
|
|
44498
44826
|
"img",
|
|
44499
44827
|
{
|
|
44500
44828
|
src: part.image_url.url,
|
|
@@ -44503,21 +44831,21 @@ function UserMessageBubble({ message, className }) {
|
|
|
44503
44831
|
},
|
|
44504
44832
|
part.image_url.url
|
|
44505
44833
|
)) }),
|
|
44506
|
-
fileParts.length > 0 && /* @__PURE__ */
|
|
44834
|
+
fileParts.length > 0 && /* @__PURE__ */ jsx24("div", { className: "flex flex-col items-end gap-1.5", children: fileParts.map((part) => /* @__PURE__ */ jsxs20(
|
|
44507
44835
|
"div",
|
|
44508
44836
|
{
|
|
44509
44837
|
className: "flex items-center gap-1.5 rounded-lg border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--muted)/0.3)] px-2.5 py-1.5 text-xs text-[hsl(var(--muted-foreground))]",
|
|
44510
44838
|
children: [
|
|
44511
|
-
/* @__PURE__ */
|
|
44512
|
-
/* @__PURE__ */
|
|
44839
|
+
/* @__PURE__ */ jsx24(FileText, { size: 12, className: "shrink-0" }),
|
|
44840
|
+
/* @__PURE__ */ jsx24("span", { className: "max-w-56 truncate", title: part.name, children: part.name })
|
|
44513
44841
|
]
|
|
44514
44842
|
},
|
|
44515
44843
|
`${part.name}-${part.data.length}`
|
|
44516
44844
|
)) }),
|
|
44517
|
-
text && /* @__PURE__ */
|
|
44518
|
-
text && isSending(message) && /* @__PURE__ */
|
|
44519
|
-
/* @__PURE__ */
|
|
44520
|
-
/* @__PURE__ */
|
|
44845
|
+
text && /* @__PURE__ */ jsx24("div", { className: "blade-chat-user-bubble max-w-full rounded-[20px] rounded-br-[6px] border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--user-msg-bg))] px-[18px] py-[13px] text-sm leading-[1.65] text-[hsl(var(--user-msg-fg))]", children: /* @__PURE__ */ jsx24(MarkdownContent, { className: "blade-chat-prose", children: text }) }),
|
|
44846
|
+
text && isSending(message) && /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-1 pr-1 text-[11px] font-medium text-[hsl(var(--muted-foreground))/0.85]", children: [
|
|
44847
|
+
/* @__PURE__ */ jsx24(LoaderCircle, { size: 11, className: "animate-spin", "aria-hidden": "true" }),
|
|
44848
|
+
/* @__PURE__ */ jsx24("span", { children: "\u53D1\u9001\u4E2D" })
|
|
44521
44849
|
] })
|
|
44522
44850
|
] }) });
|
|
44523
44851
|
}
|
|
@@ -44526,11 +44854,11 @@ function ErrorMessageBlock({
|
|
|
44526
44854
|
className
|
|
44527
44855
|
}) {
|
|
44528
44856
|
const text = chatErrorForDisplay(getTextContent2(message.content));
|
|
44529
|
-
return /* @__PURE__ */
|
|
44857
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("blade-chat-error-row flex min-w-0 justify-start", className), children: /* @__PURE__ */ jsx24("div", { className: "blade-chat-error-block min-w-0 max-w-full whitespace-pre-wrap break-words border-l-[3px] border-[hsl(var(--border))] px-3 py-1 text-left text-sm leading-7 text-[hsl(var(--muted-foreground))] [overflow-wrap:anywhere]", children: text }) });
|
|
44530
44858
|
}
|
|
44531
44859
|
|
|
44532
44860
|
// src/components/MessageList.tsx
|
|
44533
|
-
import { jsx as
|
|
44861
|
+
import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
44534
44862
|
function parseModeChange(message) {
|
|
44535
44863
|
if (message.kind !== "mode_change" || typeof message.content !== "string") {
|
|
44536
44864
|
return null;
|
|
@@ -44590,7 +44918,7 @@ function MessageList({
|
|
|
44590
44918
|
const userMessages = visibleRootMessages.filter((message) => isUserMessage(message));
|
|
44591
44919
|
const latestUserMessage = userMessages.at(-1);
|
|
44592
44920
|
const shouldPinLatestUser = latestUserMessage != null && (latestUserMessage.entry_id == null ? isStreaming : latestUserMessage.entry_id.startsWith("local-user-"));
|
|
44593
|
-
const renderBlocks =
|
|
44921
|
+
const renderBlocks = useMemo16(() => {
|
|
44594
44922
|
const visible = messages.filter((message) => {
|
|
44595
44923
|
if ((message.loop_name ?? "root") !== "root") return false;
|
|
44596
44924
|
if (isHiddenInternalMessage(message)) return false;
|
|
@@ -44664,25 +44992,25 @@ function MessageList({
|
|
|
44664
44992
|
}
|
|
44665
44993
|
return blocks;
|
|
44666
44994
|
}, [messages, isStreaming]);
|
|
44667
|
-
return /* @__PURE__ */
|
|
44668
|
-
isStreaming ? /* @__PURE__ */
|
|
44669
|
-
/* @__PURE__ */
|
|
44995
|
+
return /* @__PURE__ */ jsxs21("div", { className: cn("blade-chat-messages relative min-h-0 flex-1", className), children: [
|
|
44996
|
+
isStreaming ? /* @__PURE__ */ jsx25("output", { className: "sr-only", children: "\u6B63\u5728\u751F\u6210\u56DE\u590D" }) : null,
|
|
44997
|
+
/* @__PURE__ */ jsxs21(
|
|
44670
44998
|
StickToBottom,
|
|
44671
44999
|
{
|
|
44672
45000
|
className: "h-full overflow-y-hidden",
|
|
44673
45001
|
initial: "instant",
|
|
44674
45002
|
resize: "instant",
|
|
44675
45003
|
children: [
|
|
44676
|
-
/* @__PURE__ */
|
|
44677
|
-
historyPaging && (historyPaging.hasOlder || historyPaging.loading) ? /* @__PURE__ */
|
|
44678
|
-
/* @__PURE__ */
|
|
44679
|
-
renderBlocks.length === 0 ? emptyState ?? /* @__PURE__ */
|
|
44680
|
-
/* @__PURE__ */
|
|
44681
|
-
/* @__PURE__ */
|
|
44682
|
-
/* @__PURE__ */
|
|
45004
|
+
/* @__PURE__ */ jsx25(StickToBottom.Content, { className: "blade-chat-messages-scroll", children: /* @__PURE__ */ jsxs21("div", { className: "blade-chat-messages-content mx-auto max-w-[748px]", children: [
|
|
45005
|
+
historyPaging && (historyPaging.hasOlder || historyPaging.loading) ? /* @__PURE__ */ jsx25(LoadOlderSentinel, { ...historyPaging }) : null,
|
|
45006
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex min-w-0 flex-col", children: [
|
|
45007
|
+
renderBlocks.length === 0 ? emptyState ?? /* @__PURE__ */ jsxs21("div", { className: "blade-chat-empty", children: [
|
|
45008
|
+
/* @__PURE__ */ jsx25(MessageSquare, { size: 40, strokeWidth: 1.5 }),
|
|
45009
|
+
/* @__PURE__ */ jsx25("span", { className: "text-base font-medium", children: "\u5F00\u59CB\u5BF9\u8BDD" }),
|
|
45010
|
+
/* @__PURE__ */ jsx25("span", { className: "text-sm opacity-60", children: "\u5728\u4E0B\u65B9\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u804A\u5929" })
|
|
44683
45011
|
] }) : renderBlocks.map((block) => {
|
|
44684
45012
|
if (block.type === "message") {
|
|
44685
|
-
return /* @__PURE__ */
|
|
45013
|
+
return /* @__PURE__ */ jsx25("div", { "data-entry-id": block.message.entry_id, children: isUserMessage(block.message) ? /* @__PURE__ */ jsx25(UserMessageBubble, { message: block.message }) : isErrorMessage(block.message) ? /* @__PURE__ */ jsx25(ErrorMessageBlock, { message: block.message }) : null }, block.key);
|
|
44686
45014
|
}
|
|
44687
45015
|
if (block.type === "assistant_turn") {
|
|
44688
45016
|
const blockFeedback = block.messages.map(
|
|
@@ -44693,14 +45021,14 @@ function MessageList({
|
|
|
44693
45021
|
(message) => message.entry_id === postChatFollowup.assistant_entry_id
|
|
44694
45022
|
)
|
|
44695
45023
|
);
|
|
44696
|
-
return /* @__PURE__ */
|
|
45024
|
+
return /* @__PURE__ */ jsx25("div", { "data-entry-id": block.messages[0]?.entry_id, children: /* @__PURE__ */ jsxs21(
|
|
44697
45025
|
RenderErrorBoundary,
|
|
44698
45026
|
{
|
|
44699
45027
|
label: "\u52A9\u624B\u6D88\u606F",
|
|
44700
45028
|
details: block.key,
|
|
44701
45029
|
resetKey: getMessageResetSignature(block.messages),
|
|
44702
45030
|
children: [
|
|
44703
|
-
/* @__PURE__ */
|
|
45031
|
+
/* @__PURE__ */ jsx25(
|
|
44704
45032
|
AssistantTurnBlock,
|
|
44705
45033
|
{
|
|
44706
45034
|
messages: block.messages,
|
|
@@ -44713,8 +45041,8 @@ function MessageList({
|
|
|
44713
45041
|
sessionId
|
|
44714
45042
|
}
|
|
44715
45043
|
),
|
|
44716
|
-
blockFeedback && !hasActiveFollowup ? /* @__PURE__ */
|
|
44717
|
-
hasActiveFollowup && postChatFollowup ? /* @__PURE__ */
|
|
45044
|
+
blockFeedback && !hasActiveFollowup ? /* @__PURE__ */ jsx25(HistoricalResultFeedback, { feedback: blockFeedback }) : null,
|
|
45045
|
+
hasActiveFollowup && postChatFollowup ? /* @__PURE__ */ jsx25(
|
|
44718
45046
|
PostChatFollowupBlock,
|
|
44719
45047
|
{
|
|
44720
45048
|
followup: postChatFollowup,
|
|
@@ -44731,24 +45059,24 @@ function MessageList({
|
|
|
44731
45059
|
) }, block.key);
|
|
44732
45060
|
}
|
|
44733
45061
|
if (block.type === "compaction") {
|
|
44734
|
-
return /* @__PURE__ */
|
|
45062
|
+
return /* @__PURE__ */ jsxs21(
|
|
44735
45063
|
"div",
|
|
44736
45064
|
{
|
|
44737
45065
|
className: "flex items-center gap-2 text-xs text-[hsl(var(--muted-foreground))]",
|
|
44738
45066
|
children: [
|
|
44739
|
-
/* @__PURE__ */
|
|
44740
|
-
/* @__PURE__ */
|
|
45067
|
+
/* @__PURE__ */ jsx25(Layers, { size: 12 }),
|
|
45068
|
+
/* @__PURE__ */ jsx25("span", { children: "\u4E0A\u4E0B\u6587\u5DF2\u538B\u7F29" })
|
|
44741
45069
|
]
|
|
44742
45070
|
},
|
|
44743
45071
|
block.key
|
|
44744
45072
|
);
|
|
44745
45073
|
}
|
|
44746
|
-
return /* @__PURE__ */
|
|
45074
|
+
return /* @__PURE__ */ jsx25(PlanningDivider, { kind: block.kind }, block.key);
|
|
44747
45075
|
}),
|
|
44748
|
-
sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */
|
|
45076
|
+
sessionStatus === "interrupted" && !isStreaming ? /* @__PURE__ */ jsx25("div", { className: "flex", children: /* @__PURE__ */ jsx25("div", { className: "rounded-full border border-amber-500/30 bg-amber-500/10 px-2.5 py-1 text-[10px] font-medium uppercase tracking-[0.12em] text-amber-300", children: "\u5DF2\u4E2D\u65AD" }) }) : null
|
|
44749
45077
|
] })
|
|
44750
45078
|
] }) }),
|
|
44751
|
-
/* @__PURE__ */
|
|
45079
|
+
/* @__PURE__ */ jsx25(
|
|
44752
45080
|
PinLatestUserMessage,
|
|
44753
45081
|
{
|
|
44754
45082
|
userMessageCount: userMessages.length,
|
|
@@ -44758,7 +45086,7 @@ function MessageList({
|
|
|
44758
45086
|
},
|
|
44759
45087
|
sessionId ?? "no-session"
|
|
44760
45088
|
),
|
|
44761
|
-
/* @__PURE__ */
|
|
45089
|
+
/* @__PURE__ */ jsx25(ScrollToBottomButton, {})
|
|
44762
45090
|
]
|
|
44763
45091
|
},
|
|
44764
45092
|
sessionId ?? "no-session"
|
|
@@ -44774,7 +45102,7 @@ function LoadOlderSentinel({
|
|
|
44774
45102
|
const sentinelRef = useRef22(null);
|
|
44775
45103
|
const stateRef = useRef22({ hasOlder, loading, loadOlder });
|
|
44776
45104
|
stateRef.current = { hasOlder, loading, loadOlder };
|
|
44777
|
-
|
|
45105
|
+
useEffect20(() => {
|
|
44778
45106
|
const sentinel = sentinelRef.current;
|
|
44779
45107
|
const scroller = scrollRef.current;
|
|
44780
45108
|
if (!sentinel || !scroller || typeof IntersectionObserver === "undefined") return;
|
|
@@ -44833,7 +45161,7 @@ function LoadOlderSentinel({
|
|
|
44833
45161
|
observer.disconnect();
|
|
44834
45162
|
};
|
|
44835
45163
|
}, [contentRef, scrollRef]);
|
|
44836
|
-
return /* @__PURE__ */
|
|
45164
|
+
return /* @__PURE__ */ jsx25("div", { ref: sentinelRef, "data-history-sentinel": true, className: "flex h-6 items-center justify-center", children: loading ? /* @__PURE__ */ jsx25("span", { className: "text-xs text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u52A0\u8F7D\u66F4\u65E9\u6D88\u606F\u2026" }) : null });
|
|
44837
45165
|
}
|
|
44838
45166
|
function PinLatestUserMessage({
|
|
44839
45167
|
userMessageCount,
|
|
@@ -44844,14 +45172,14 @@ function PinLatestUserMessage({
|
|
|
44844
45172
|
const { contentRef, scrollRef, scrollToBottom, stopScroll } = useStickToBottomContext();
|
|
44845
45173
|
const previousCountRef = useRef22(userMessageCount);
|
|
44846
45174
|
const spacerHeightRef = useRef22(0);
|
|
44847
|
-
const getScrollElement =
|
|
44848
|
-
const getContentElement =
|
|
44849
|
-
const getTargetElement =
|
|
45175
|
+
const getScrollElement = useCallback26(() => scrollRef.current, [scrollRef]);
|
|
45176
|
+
const getContentElement = useCallback26(() => contentRef.current, [contentRef]);
|
|
45177
|
+
const getTargetElement = useCallback26(() => {
|
|
44850
45178
|
const rows = contentRef.current?.querySelectorAll(".blade-chat-user-row");
|
|
44851
45179
|
return rows?.item((rows?.length ?? 0) - 1) ?? null;
|
|
44852
45180
|
}, [contentRef]);
|
|
44853
|
-
const getSpacerHeight =
|
|
44854
|
-
const setSpacerHeight =
|
|
45181
|
+
const getSpacerHeight = useCallback26(() => spacerHeightRef.current, []);
|
|
45182
|
+
const setSpacerHeight = useCallback26(
|
|
44855
45183
|
(height) => {
|
|
44856
45184
|
spacerHeightRef.current = height;
|
|
44857
45185
|
const content = contentRef.current;
|
|
@@ -44873,7 +45201,7 @@ function PinLatestUserMessage({
|
|
|
44873
45201
|
stopAutoScroll: stopScroll,
|
|
44874
45202
|
scrollToBottom
|
|
44875
45203
|
});
|
|
44876
|
-
|
|
45204
|
+
useEffect20(() => {
|
|
44877
45205
|
if (userMessageCount > previousCountRef.current && !shouldPinLatestUser) {
|
|
44878
45206
|
scrollToBottom("instant");
|
|
44879
45207
|
}
|
|
@@ -44883,9 +45211,9 @@ function PinLatestUserMessage({
|
|
|
44883
45211
|
}
|
|
44884
45212
|
function ScrollToBottomButton() {
|
|
44885
45213
|
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
|
|
44886
|
-
const [visible, setVisible] =
|
|
45214
|
+
const [visible, setVisible] = useState29(false);
|
|
44887
45215
|
const hideTimerRef = useRef22(null);
|
|
44888
|
-
|
|
45216
|
+
useEffect20(() => {
|
|
44889
45217
|
if (isAtBottom) {
|
|
44890
45218
|
if (!hideTimerRef.current) {
|
|
44891
45219
|
hideTimerRef.current = setTimeout(() => {
|
|
@@ -44907,7 +45235,7 @@ function ScrollToBottomButton() {
|
|
|
44907
45235
|
}
|
|
44908
45236
|
};
|
|
44909
45237
|
}, [isAtBottom]);
|
|
44910
|
-
const handleClick =
|
|
45238
|
+
const handleClick = useCallback26(() => {
|
|
44911
45239
|
if (hideTimerRef.current) {
|
|
44912
45240
|
clearTimeout(hideTimerRef.current);
|
|
44913
45241
|
hideTimerRef.current = null;
|
|
@@ -44916,7 +45244,7 @@ function ScrollToBottomButton() {
|
|
|
44916
45244
|
scrollToBottom();
|
|
44917
45245
|
}, [scrollToBottom]);
|
|
44918
45246
|
if (!visible) return null;
|
|
44919
|
-
return /* @__PURE__ */
|
|
45247
|
+
return /* @__PURE__ */ jsxs21(
|
|
44920
45248
|
"button",
|
|
44921
45249
|
{
|
|
44922
45250
|
type: "button",
|
|
@@ -44924,25 +45252,25 @@ function ScrollToBottomButton() {
|
|
|
44924
45252
|
"aria-label": "\u6EDA\u52A8\u5230\u5E95\u90E8",
|
|
44925
45253
|
className: "blade-chat-scroll-bottom absolute bottom-4 right-4 flex items-center gap-1 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-3 py-1.5 text-xs text-[hsl(var(--muted-foreground))] shadow-lg transition-colors hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))]",
|
|
44926
45254
|
children: [
|
|
44927
|
-
/* @__PURE__ */
|
|
44928
|
-
/* @__PURE__ */
|
|
45255
|
+
/* @__PURE__ */ jsx25(ChevronDown, { size: 14 }),
|
|
45256
|
+
/* @__PURE__ */ jsx25("span", { className: "blade-chat-scroll-bottom-label", children: "\u6EDA\u52A8\u5230\u5E95\u90E8" })
|
|
44929
45257
|
]
|
|
44930
45258
|
}
|
|
44931
45259
|
);
|
|
44932
45260
|
}
|
|
44933
45261
|
function PlanningDivider({ kind }) {
|
|
44934
|
-
return /* @__PURE__ */
|
|
44935
|
-
/* @__PURE__ */
|
|
44936
|
-
/* @__PURE__ */
|
|
44937
|
-
/* @__PURE__ */
|
|
44938
|
-
/* @__PURE__ */
|
|
45262
|
+
return /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3 py-1", children: [
|
|
45263
|
+
/* @__PURE__ */ jsx25("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" }),
|
|
45264
|
+
/* @__PURE__ */ jsxs21("div", { className: "inline-flex items-center gap-1.5 rounded-full border border-amber-500/30 bg-amber-500/10 px-3 py-1 text-[11px] text-amber-300", children: [
|
|
45265
|
+
/* @__PURE__ */ jsx25(Lightbulb, { size: 12 }),
|
|
45266
|
+
/* @__PURE__ */ jsx25("span", { children: kind === "enter" ? "\u8FDB\u5165\u89C4\u5212\u6A21\u5F0F" : "\u89C4\u5212\u5B8C\u6210" })
|
|
44939
45267
|
] }),
|
|
44940
|
-
/* @__PURE__ */
|
|
45268
|
+
/* @__PURE__ */ jsx25("div", { className: "h-px flex-1 bg-gradient-to-r from-transparent via-amber-400/40 to-transparent" })
|
|
44941
45269
|
] });
|
|
44942
45270
|
}
|
|
44943
45271
|
|
|
44944
45272
|
// src/components/ChatSurface.tsx
|
|
44945
|
-
import { jsx as
|
|
45273
|
+
import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
44946
45274
|
function themeAttr(theme) {
|
|
44947
45275
|
return theme === "dark" ? "dark" : void 0;
|
|
44948
45276
|
}
|
|
@@ -44979,7 +45307,7 @@ function ChatSurface({
|
|
|
44979
45307
|
historyPaging,
|
|
44980
45308
|
banner
|
|
44981
45309
|
}) {
|
|
44982
|
-
const [pending, setPending] =
|
|
45310
|
+
const [pending, setPending] = useState30([]);
|
|
44983
45311
|
const currentPending = pending.filter((item) => item.sessionId === sessionId);
|
|
44984
45312
|
const sendWithApps = async (text) => {
|
|
44985
45313
|
const content = [...currentPending.map((item) => `[${item.label}]
|
|
@@ -44991,10 +45319,10 @@ ${item.content}`), text].filter(Boolean).join("\n\n");
|
|
|
44991
45319
|
}
|
|
44992
45320
|
return accepted;
|
|
44993
45321
|
};
|
|
44994
|
-
return /* @__PURE__ */
|
|
45322
|
+
return /* @__PURE__ */ jsx26(McpAppMessageContext.Provider, { value: (message) => {
|
|
44995
45323
|
if (!sessionId || message.sessionId !== sessionId || isViewer) throw new Error("\u5F53\u524D\u4F1A\u8BDD\u4E0D\u80FD\u63A5\u6536\u5E94\u7528\u6D88\u606F");
|
|
44996
45324
|
setPending((items) => [...items, { ...message, sessionId, id: crypto.randomUUID() }]);
|
|
44997
|
-
}, children: /* @__PURE__ */
|
|
45325
|
+
}, children: /* @__PURE__ */ jsxs22(
|
|
44998
45326
|
"div",
|
|
44999
45327
|
{
|
|
45000
45328
|
"data-theme": themeAttr(theme),
|
|
@@ -45003,14 +45331,14 @@ ${item.content}`), text].filter(Boolean).join("\n\n");
|
|
|
45003
45331
|
classNames?.root
|
|
45004
45332
|
),
|
|
45005
45333
|
children: [
|
|
45006
|
-
/* @__PURE__ */
|
|
45334
|
+
/* @__PURE__ */ jsx26(ConnectionBanner, { connection, className: classNames?.banner }),
|
|
45007
45335
|
banner,
|
|
45008
|
-
errorMessage && /* @__PURE__ */
|
|
45009
|
-
/* @__PURE__ */
|
|
45010
|
-
/* @__PURE__ */
|
|
45336
|
+
errorMessage && /* @__PURE__ */ jsxs22("div", { className: "blade-chat-error-bar flex items-start gap-2 border-b px-4 py-3 text-sm", children: [
|
|
45337
|
+
/* @__PURE__ */ jsx26(CircleAlert, { size: 16, className: "mt-0.5 shrink-0" }),
|
|
45338
|
+
/* @__PURE__ */ jsx26("span", { className: "min-w-0 whitespace-pre-wrap break-words [overflow-wrap:anywhere]", children: chatErrorForDisplay2(errorMessage) })
|
|
45011
45339
|
] }),
|
|
45012
45340
|
slots?.header,
|
|
45013
|
-
/* @__PURE__ */
|
|
45341
|
+
/* @__PURE__ */ jsx26(
|
|
45014
45342
|
MessageList,
|
|
45015
45343
|
{
|
|
45016
45344
|
messages,
|
|
@@ -45032,7 +45360,7 @@ ${item.content}`), text].filter(Boolean).join("\n\n");
|
|
|
45032
45360
|
historyPaging
|
|
45033
45361
|
}
|
|
45034
45362
|
),
|
|
45035
|
-
showPlanUpdates ? /* @__PURE__ */
|
|
45363
|
+
showPlanUpdates ? /* @__PURE__ */ jsx26(
|
|
45036
45364
|
CurrentPlanPanel,
|
|
45037
45365
|
{
|
|
45038
45366
|
messages,
|
|
@@ -45044,14 +45372,14 @@ ${item.content}`), text].filter(Boolean).join("\n\n");
|
|
|
45044
45372
|
) : null,
|
|
45045
45373
|
beforeInput,
|
|
45046
45374
|
queuePanel,
|
|
45047
|
-
currentPending.map((item) => /* @__PURE__ */
|
|
45048
|
-
/* @__PURE__ */
|
|
45049
|
-
/* @__PURE__ */
|
|
45050
|
-
/* @__PURE__ */
|
|
45375
|
+
currentPending.map((item) => /* @__PURE__ */ jsxs22("div", { style: { display: "flex", gap: 8, padding: "8px 16px" }, children: [
|
|
45376
|
+
/* @__PURE__ */ jsxs22("details", { style: { flex: 1, minWidth: 0 }, children: [
|
|
45377
|
+
/* @__PURE__ */ jsx26("summary", { children: item.label }),
|
|
45378
|
+
/* @__PURE__ */ jsx26("pre", { style: { whiteSpace: "pre-wrap", overflowWrap: "anywhere" }, children: item.content })
|
|
45051
45379
|
] }),
|
|
45052
|
-
/* @__PURE__ */
|
|
45380
|
+
/* @__PURE__ */ jsx26("button", { type: "button", "aria-label": "\u79FB\u9664\u5F85\u53D1\u9001\u5185\u5BB9", title: "\u79FB\u9664", onClick: () => setPending((items) => items.filter((other) => other.id !== item.id)), children: /* @__PURE__ */ jsx26(X, { size: 16 }) })
|
|
45053
45381
|
] }, item.id)),
|
|
45054
|
-
/* @__PURE__ */
|
|
45382
|
+
/* @__PURE__ */ jsx26(
|
|
45055
45383
|
ChatInput,
|
|
45056
45384
|
{
|
|
45057
45385
|
value: inputText,
|
|
@@ -45074,13 +45402,13 @@ ${item.content}`), text].filter(Boolean).join("\n\n");
|
|
|
45074
45402
|
}
|
|
45075
45403
|
|
|
45076
45404
|
// src/components/AgentChat.tsx
|
|
45077
|
-
import { Fragment as Fragment8, jsx as
|
|
45405
|
+
import { Fragment as Fragment8, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
45078
45406
|
function isUnauthorizedError(error61) {
|
|
45079
45407
|
return error61 instanceof BladeApiError2 && error61.status === 401;
|
|
45080
45408
|
}
|
|
45081
45409
|
function LoginCard({ client, onLoggedIn }) {
|
|
45082
|
-
const [loggingIn, setLoggingIn] =
|
|
45083
|
-
const [loginError, setLoginError] =
|
|
45410
|
+
const [loggingIn, setLoggingIn] = useState31(false);
|
|
45411
|
+
const [loginError, setLoginError] = useState31(null);
|
|
45084
45412
|
const handleLogin = async () => {
|
|
45085
45413
|
setLoggingIn(true);
|
|
45086
45414
|
setLoginError(null);
|
|
@@ -45093,11 +45421,11 @@ function LoginCard({ client, onLoggedIn }) {
|
|
|
45093
45421
|
setLoggingIn(false);
|
|
45094
45422
|
}
|
|
45095
45423
|
};
|
|
45096
|
-
return /* @__PURE__ */
|
|
45097
|
-
/* @__PURE__ */
|
|
45098
|
-
/* @__PURE__ */
|
|
45099
|
-
/* @__PURE__ */
|
|
45100
|
-
/* @__PURE__ */
|
|
45424
|
+
return /* @__PURE__ */ jsx27("div", { className: "blade-chat-login flex flex-1 items-center justify-center p-6", children: /* @__PURE__ */ jsxs23("div", { className: "flex w-full max-w-sm flex-col items-center gap-4 rounded-2xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] px-6 py-8 text-center", children: [
|
|
45425
|
+
/* @__PURE__ */ jsx27(LockKeyhole, { size: 28, className: "text-[hsl(var(--muted-foreground))]" }),
|
|
45426
|
+
/* @__PURE__ */ jsx27("div", { className: "text-base font-medium text-[hsl(var(--foreground))]", children: "\u9700\u8981\u767B\u5F55\u540E\u4F7F\u7528" }),
|
|
45427
|
+
/* @__PURE__ */ jsx27("div", { className: "text-sm text-[hsl(var(--muted-foreground))]", children: "\u767B\u5F55\u540E\u5373\u53EF\u4E0E\u667A\u80FD\u4F53\u5BF9\u8BDD\uFF0C\u4F60\u7684\u4F1A\u8BDD\u5185\u5BB9\u4EC5\u81EA\u5DF1\u53EF\u89C1\u3002" }),
|
|
45428
|
+
/* @__PURE__ */ jsx27(
|
|
45101
45429
|
"button",
|
|
45102
45430
|
{
|
|
45103
45431
|
type: "button",
|
|
@@ -45107,20 +45435,20 @@ function LoginCard({ client, onLoggedIn }) {
|
|
|
45107
45435
|
children: loggingIn ? "\u767B\u5F55\u4E2D\u2026" : "\u767B\u5F55"
|
|
45108
45436
|
}
|
|
45109
45437
|
),
|
|
45110
|
-
loginError && /* @__PURE__ */
|
|
45438
|
+
loginError && /* @__PURE__ */ jsx27("div", { className: "text-xs text-[hsl(var(--destructive))]", children: loginError })
|
|
45111
45439
|
] }) });
|
|
45112
45440
|
}
|
|
45113
45441
|
function AgentChat(props) {
|
|
45114
45442
|
const client = useBladeClient();
|
|
45115
|
-
const [attempt, setAttempt] =
|
|
45116
|
-
const [needLogin, setNeedLogin] =
|
|
45443
|
+
const [attempt, setAttempt] = useState31(0);
|
|
45444
|
+
const [needLogin, setNeedLogin] = useState31(() => !client.hasToken());
|
|
45117
45445
|
if (needLogin) {
|
|
45118
|
-
return /* @__PURE__ */
|
|
45446
|
+
return /* @__PURE__ */ jsx27(
|
|
45119
45447
|
"div",
|
|
45120
45448
|
{
|
|
45121
45449
|
"data-theme": themeAttr(props.theme),
|
|
45122
45450
|
className: cn("blade-chat flex min-h-0 flex-1 flex-col", props.classNames?.root),
|
|
45123
|
-
children: /* @__PURE__ */
|
|
45451
|
+
children: /* @__PURE__ */ jsx27(
|
|
45124
45452
|
LoginCard,
|
|
45125
45453
|
{
|
|
45126
45454
|
client,
|
|
@@ -45133,7 +45461,7 @@ function AgentChat(props) {
|
|
|
45133
45461
|
}
|
|
45134
45462
|
);
|
|
45135
45463
|
}
|
|
45136
|
-
return /* @__PURE__ */
|
|
45464
|
+
return /* @__PURE__ */ jsx27(ChatSessionView, { ...props, onUnauthorized: () => setNeedLogin(true) }, attempt);
|
|
45137
45465
|
}
|
|
45138
45466
|
function ChatSessionView({
|
|
45139
45467
|
sessionId,
|
|
@@ -45151,10 +45479,10 @@ function ChatSessionView({
|
|
|
45151
45479
|
onUnauthorized
|
|
45152
45480
|
}) {
|
|
45153
45481
|
const client = useBladeClient();
|
|
45154
|
-
const [planRevealRevisions, setPlanRevealRevisions] =
|
|
45482
|
+
const [planRevealRevisions, setPlanRevealRevisions] = useState31(
|
|
45155
45483
|
() => /* @__PURE__ */ new Map()
|
|
45156
45484
|
);
|
|
45157
|
-
const handleSessionConnected =
|
|
45485
|
+
const handleSessionConnected = useCallback27((connectedSession) => {
|
|
45158
45486
|
return connectedSession.on("toolResult", ({ toolCall, turn, source }) => {
|
|
45159
45487
|
if (source === "reconnect_replay" || (turn.loop_id || "root") !== "root" || toolCall.status !== "done" || !isPlanUpdateTool(toolCall) || !parsePlanUpdate(toolCall.arguments)) {
|
|
45160
45488
|
return;
|
|
@@ -45172,20 +45500,20 @@ function ChatSessionView({
|
|
|
45172
45500
|
onSessionConnected: handleSessionConnected
|
|
45173
45501
|
});
|
|
45174
45502
|
const replay = useReplay(session);
|
|
45175
|
-
const [stopRequested, setStopRequested] =
|
|
45176
|
-
const [inputText, setInputText] =
|
|
45177
|
-
const [queueNotice, setQueueNotice] =
|
|
45178
|
-
const [queuePendingItemId, setQueuePendingItemId] =
|
|
45179
|
-
const [resultFeedback, setResultFeedback] =
|
|
45503
|
+
const [stopRequested, setStopRequested] = useState31(false);
|
|
45504
|
+
const [inputText, setInputText] = useState31("");
|
|
45505
|
+
const [queueNotice, setQueueNotice] = useState31(null);
|
|
45506
|
+
const [queuePendingItemId, setQueuePendingItemId] = useState31(null);
|
|
45507
|
+
const [resultFeedback, setResultFeedback] = useState31([]);
|
|
45180
45508
|
const resolvedSessionId = session?.sessionId;
|
|
45181
45509
|
const isViewer = state?.viewerRole === "viewer";
|
|
45182
45510
|
const onSessionReadyRef = useRef23(onSessionReady);
|
|
45183
45511
|
const readySessionRef = useRef23(null);
|
|
45184
45512
|
const hasOnSessionReady = onSessionReady !== void 0;
|
|
45185
|
-
|
|
45513
|
+
useEffect21(() => {
|
|
45186
45514
|
onSessionReadyRef.current = onSessionReady;
|
|
45187
45515
|
}, [onSessionReady]);
|
|
45188
|
-
|
|
45516
|
+
useEffect21(() => {
|
|
45189
45517
|
setResultFeedback([]);
|
|
45190
45518
|
if (!resolvedSessionId || isViewer) return;
|
|
45191
45519
|
let cancelled = false;
|
|
@@ -45210,23 +45538,23 @@ function ChatSessionView({
|
|
|
45210
45538
|
cancelled = true;
|
|
45211
45539
|
};
|
|
45212
45540
|
}, [client, isViewer, resolvedSessionId]);
|
|
45213
|
-
const resultFeedbackByEntry =
|
|
45541
|
+
const resultFeedbackByEntry = useMemo17(
|
|
45214
45542
|
() => new Map(resultFeedback.map((item) => [item.assistant_entry_id, item])),
|
|
45215
45543
|
[resultFeedback]
|
|
45216
45544
|
);
|
|
45217
|
-
const handleResultFeedbackSaved =
|
|
45545
|
+
const handleResultFeedbackSaved = useCallback27((saved) => {
|
|
45218
45546
|
setResultFeedback((current) => [
|
|
45219
45547
|
...current.filter((item) => item.assistant_entry_id !== saved.assistant_entry_id),
|
|
45220
45548
|
saved
|
|
45221
45549
|
]);
|
|
45222
45550
|
}, []);
|
|
45223
|
-
|
|
45551
|
+
useEffect21(() => {
|
|
45224
45552
|
const handler = onSessionReadyRef.current;
|
|
45225
45553
|
if (!session || !hasOnSessionReady || !handler || readySessionRef.current === session) return;
|
|
45226
45554
|
readySessionRef.current = session;
|
|
45227
45555
|
handler(session);
|
|
45228
45556
|
}, [session, hasOnSessionReady]);
|
|
45229
|
-
|
|
45557
|
+
useEffect21(() => {
|
|
45230
45558
|
if (!session) return;
|
|
45231
45559
|
const offAttach = session.on("attachRequested", ({ label, content }) => {
|
|
45232
45560
|
setInputText((prev) => `${prev ? `${prev}
|
|
@@ -45242,12 +45570,12 @@ ${content}`);
|
|
|
45242
45570
|
offInsert();
|
|
45243
45571
|
};
|
|
45244
45572
|
}, [session]);
|
|
45245
|
-
|
|
45573
|
+
useEffect21(() => {
|
|
45246
45574
|
if (isUnauthorizedError(error61)) {
|
|
45247
45575
|
onUnauthorized();
|
|
45248
45576
|
}
|
|
45249
45577
|
}, [error61, onUnauthorized]);
|
|
45250
|
-
|
|
45578
|
+
useEffect21(() => {
|
|
45251
45579
|
if (!session || !commands) return;
|
|
45252
45580
|
const unsubscribes = Object.entries(commands).map(
|
|
45253
45581
|
([action, handler]) => session.onCommand(action, (payload) => handler(payload))
|
|
@@ -45322,7 +45650,7 @@ ${content}`);
|
|
|
45322
45650
|
next[to] = item.id;
|
|
45323
45651
|
handleQueueReorder(next);
|
|
45324
45652
|
};
|
|
45325
|
-
return /* @__PURE__ */
|
|
45653
|
+
return /* @__PURE__ */ jsx27(
|
|
45326
45654
|
ChatSurface,
|
|
45327
45655
|
{
|
|
45328
45656
|
theme,
|
|
@@ -45332,9 +45660,9 @@ ${content}`);
|
|
|
45332
45660
|
slots,
|
|
45333
45661
|
placeholder,
|
|
45334
45662
|
connection: state?.connection ?? "connecting",
|
|
45335
|
-
banner: /* @__PURE__ */
|
|
45336
|
-
resolvedSessionId && !isViewer && (sessionPluginControls ? sessionPluginControls(resolvedSessionId) : /* @__PURE__ */
|
|
45337
|
-
/* @__PURE__ */
|
|
45663
|
+
banner: /* @__PURE__ */ jsxs23(Fragment8, { children: [
|
|
45664
|
+
resolvedSessionId && !isViewer && (sessionPluginControls ? sessionPluginControls(resolvedSessionId) : /* @__PURE__ */ jsx27(SessionPluginSelector, { client, sessionId: resolvedSessionId })),
|
|
45665
|
+
/* @__PURE__ */ jsx27(
|
|
45338
45666
|
ReplayBar,
|
|
45339
45667
|
{
|
|
45340
45668
|
isReplay: replay.isReplay,
|
|
@@ -45344,7 +45672,7 @@ ${content}`);
|
|
|
45344
45672
|
onExit: () => void replay.exitToAutonomous()
|
|
45345
45673
|
}
|
|
45346
45674
|
),
|
|
45347
|
-
/* @__PURE__ */
|
|
45675
|
+
/* @__PURE__ */ jsx27(ReplayMismatchPrompt, { mismatch: replay.mismatch })
|
|
45348
45676
|
] }),
|
|
45349
45677
|
errorMessage,
|
|
45350
45678
|
messages: state?.messages ?? [],
|
|
@@ -45356,7 +45684,7 @@ ${content}`);
|
|
|
45356
45684
|
planRevealRevision,
|
|
45357
45685
|
queuePanel: (
|
|
45358
45686
|
// 只读身份不能操作队列,藏起来免得每个按钮都弹冲突。
|
|
45359
|
-
isViewer ? void 0 : /* @__PURE__ */
|
|
45687
|
+
isViewer ? void 0 : /* @__PURE__ */ jsx27(
|
|
45360
45688
|
SessionQueuePanel,
|
|
45361
45689
|
{
|
|
45362
45690
|
snapshot: state?.queue ?? EMPTY_SESSION_QUEUE,
|
|
@@ -45411,11 +45739,11 @@ ${content}`);
|
|
|
45411
45739
|
}
|
|
45412
45740
|
|
|
45413
45741
|
// src/components/LlmChat.tsx
|
|
45414
|
-
import { useEffect as
|
|
45742
|
+
import { useEffect as useEffect22, useMemo as useMemo18, useState as useState33 } from "react";
|
|
45415
45743
|
|
|
45416
45744
|
// src/components/LlmAdvancedSettings.tsx
|
|
45417
|
-
import { useState as
|
|
45418
|
-
import { jsx as
|
|
45745
|
+
import { useState as useState32 } from "react";
|
|
45746
|
+
import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
45419
45747
|
var FIELDS = [
|
|
45420
45748
|
{ id: "baseURL", label: "\u6A21\u578B\u670D\u52A1\u5730\u5740", placeholder: "http://\u5185\u7F51\u5730\u5740/v1" },
|
|
45421
45749
|
{ id: "model", label: "\u6A21\u578B", placeholder: "\u6A21\u578B\u540D\u79F0" },
|
|
@@ -45461,13 +45789,13 @@ function writeOverride(settings, baseURL, override) {
|
|
|
45461
45789
|
}
|
|
45462
45790
|
function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onChange }) {
|
|
45463
45791
|
const normalized = normalizeAdvanced(settings);
|
|
45464
|
-
const [open2, setOpen] =
|
|
45465
|
-
const [draft, setDraft] =
|
|
45792
|
+
const [open2, setOpen] = useState32(false);
|
|
45793
|
+
const [draft, setDraft] = useState32(override);
|
|
45466
45794
|
if (!normalized) return null;
|
|
45467
45795
|
const fields2 = FIELDS.filter((field) => normalized[field.id]);
|
|
45468
45796
|
const dirty = Object.keys(override).length > 0;
|
|
45469
|
-
return /* @__PURE__ */
|
|
45470
|
-
/* @__PURE__ */
|
|
45797
|
+
return /* @__PURE__ */ jsxs24("div", { className: "blade-chat-advanced border-t border-[hsl(var(--border))] px-4 py-2 text-xs", children: [
|
|
45798
|
+
/* @__PURE__ */ jsxs24(
|
|
45471
45799
|
"button",
|
|
45472
45800
|
{
|
|
45473
45801
|
type: "button",
|
|
@@ -45477,16 +45805,16 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
|
|
|
45477
45805
|
},
|
|
45478
45806
|
className: "flex items-center gap-1.5 text-[hsl(var(--muted-foreground))] transition-colors hover:text-[hsl(var(--foreground))]",
|
|
45479
45807
|
children: [
|
|
45480
|
-
/* @__PURE__ */
|
|
45808
|
+
/* @__PURE__ */ jsx28(Settings2, { size: 13 }),
|
|
45481
45809
|
"\u9AD8\u7EA7\u8BBE\u7F6E",
|
|
45482
|
-
dirty && /* @__PURE__ */
|
|
45810
|
+
dirty && /* @__PURE__ */ jsx28("span", { className: "text-[hsl(var(--primary))]", children: "\uFF08\u5DF2\u81EA\u5B9A\u4E49\uFF09" })
|
|
45483
45811
|
]
|
|
45484
45812
|
}
|
|
45485
45813
|
),
|
|
45486
|
-
open2 && /* @__PURE__ */
|
|
45487
|
-
fields2.map((field) => /* @__PURE__ */
|
|
45488
|
-
/* @__PURE__ */
|
|
45489
|
-
/* @__PURE__ */
|
|
45814
|
+
open2 && /* @__PURE__ */ jsxs24("div", { className: "mt-2 flex flex-col gap-2", children: [
|
|
45815
|
+
fields2.map((field) => /* @__PURE__ */ jsxs24("label", { className: "flex flex-col gap-1", children: [
|
|
45816
|
+
/* @__PURE__ */ jsx28("span", { className: "text-[hsl(var(--muted-foreground))]", children: field.label }),
|
|
45817
|
+
/* @__PURE__ */ jsx28(
|
|
45490
45818
|
"input",
|
|
45491
45819
|
{
|
|
45492
45820
|
type: field.secret ? "password" : "text",
|
|
@@ -45497,9 +45825,9 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
|
|
|
45497
45825
|
}
|
|
45498
45826
|
)
|
|
45499
45827
|
] }, field.id)),
|
|
45500
|
-
normalized.apiKey && /* @__PURE__ */
|
|
45501
|
-
/* @__PURE__ */
|
|
45502
|
-
/* @__PURE__ */
|
|
45828
|
+
normalized.apiKey && /* @__PURE__ */ jsx28("p", { className: "text-[hsl(var(--muted-foreground))]", children: "\u5BC6\u94A5\u4F1A\u5B58\u5728\u8FD9\u53F0\u6D4F\u89C8\u5668\u91CC\u3002\u53EA\u5728\u4F60\u4FE1\u5F97\u8FC7\u8FD9\u53F0\u673A\u5668\u65F6\u586B\u3002" }),
|
|
45829
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-2", children: [
|
|
45830
|
+
/* @__PURE__ */ jsx28(
|
|
45503
45831
|
"button",
|
|
45504
45832
|
{
|
|
45505
45833
|
type: "button",
|
|
@@ -45514,7 +45842,7 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
|
|
|
45514
45842
|
children: "\u4FDD\u5B58"
|
|
45515
45843
|
}
|
|
45516
45844
|
),
|
|
45517
|
-
/* @__PURE__ */
|
|
45845
|
+
/* @__PURE__ */ jsx28(
|
|
45518
45846
|
"button",
|
|
45519
45847
|
{
|
|
45520
45848
|
type: "button",
|
|
@@ -45533,7 +45861,7 @@ function LlmAdvancedSettingsBar({ settings, defaults: defaults2, override, onCha
|
|
|
45533
45861
|
}
|
|
45534
45862
|
|
|
45535
45863
|
// src/components/LlmChat.tsx
|
|
45536
|
-
import { jsx as
|
|
45864
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
45537
45865
|
function LlmChat({
|
|
45538
45866
|
classNames,
|
|
45539
45867
|
renderers,
|
|
@@ -45545,12 +45873,12 @@ function LlmChat({
|
|
|
45545
45873
|
onOverrideChange,
|
|
45546
45874
|
...options
|
|
45547
45875
|
}) {
|
|
45548
|
-
const [override, setOverride] =
|
|
45876
|
+
const [override, setOverride] = useState33(() => readOverride(advanced, options.baseURL));
|
|
45549
45877
|
const effective = { ...options, ...override };
|
|
45550
45878
|
const { messages, isStreaming, error: error61, send, stop, reset } = useLlmChat(effective);
|
|
45551
|
-
const [inputText, setInputText] =
|
|
45552
|
-
const [stopRequested, setStopRequested] =
|
|
45553
|
-
const handle =
|
|
45879
|
+
const [inputText, setInputText] = useState33("");
|
|
45880
|
+
const [stopRequested, setStopRequested] = useState33(false);
|
|
45881
|
+
const handle = useMemo18(
|
|
45554
45882
|
() => ({
|
|
45555
45883
|
insertText: (text) => setInputText((prev) => prev ? `${prev}
|
|
45556
45884
|
${text}` : text),
|
|
@@ -45559,10 +45887,10 @@ ${text}` : text),
|
|
|
45559
45887
|
}),
|
|
45560
45888
|
[send, reset]
|
|
45561
45889
|
);
|
|
45562
|
-
|
|
45890
|
+
useEffect22(() => {
|
|
45563
45891
|
onReady?.(handle);
|
|
45564
45892
|
}, [handle, onReady]);
|
|
45565
|
-
return /* @__PURE__ */
|
|
45893
|
+
return /* @__PURE__ */ jsx29(
|
|
45566
45894
|
ChatSurface,
|
|
45567
45895
|
{
|
|
45568
45896
|
theme,
|
|
@@ -45587,7 +45915,7 @@ ${text}` : text),
|
|
|
45587
45915
|
setStopRequested(true);
|
|
45588
45916
|
stop();
|
|
45589
45917
|
},
|
|
45590
|
-
beforeInput: advanced ? /* @__PURE__ */
|
|
45918
|
+
beforeInput: advanced ? /* @__PURE__ */ jsx29(
|
|
45591
45919
|
LlmAdvancedSettingsBar,
|
|
45592
45920
|
{
|
|
45593
45921
|
settings: advanced,
|
|
@@ -45605,14 +45933,14 @@ ${text}` : text),
|
|
|
45605
45933
|
}
|
|
45606
45934
|
|
|
45607
45935
|
// src/components/ChatView.tsx
|
|
45608
|
-
import { jsx as
|
|
45936
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
45609
45937
|
function ChatView(props) {
|
|
45610
45938
|
const { mode, llm, onLlmReady, ...rest } = props;
|
|
45611
45939
|
if (mode === "llm") {
|
|
45612
45940
|
if (!llm) {
|
|
45613
45941
|
throw new Error('ChatView: mode="llm" \u9700\u8981\u540C\u65F6\u4F20 llm={{ baseURL, model }}');
|
|
45614
45942
|
}
|
|
45615
|
-
return /* @__PURE__ */
|
|
45943
|
+
return /* @__PURE__ */ jsx30(
|
|
45616
45944
|
LlmChat,
|
|
45617
45945
|
{
|
|
45618
45946
|
...llm,
|
|
@@ -45625,7 +45953,188 @@ function ChatView(props) {
|
|
|
45625
45953
|
}
|
|
45626
45954
|
);
|
|
45627
45955
|
}
|
|
45628
|
-
return /* @__PURE__ */
|
|
45956
|
+
return /* @__PURE__ */ jsx30(AgentChat, { ...rest });
|
|
45957
|
+
}
|
|
45958
|
+
|
|
45959
|
+
// src/components/ConnectorPanel.tsx
|
|
45960
|
+
import { useCallback as useCallback28, useEffect as useEffect23, useMemo as useMemo19, useRef as useRef24, useState as useState34 } from "react";
|
|
45961
|
+
|
|
45962
|
+
// src/components/connector-panel-types.ts
|
|
45963
|
+
function selectionFromItem(item) {
|
|
45964
|
+
return {
|
|
45965
|
+
name: item.name,
|
|
45966
|
+
displayName: item.display_name ?? null,
|
|
45967
|
+
icon: item.icon,
|
|
45968
|
+
iconSource: item.iconSource
|
|
45969
|
+
};
|
|
45970
|
+
}
|
|
45971
|
+
var TRIGGER_ICON_LIMIT = 3;
|
|
45972
|
+
function triggerSummary(items) {
|
|
45973
|
+
const withIcon = items.filter((item) => Boolean(item.icon));
|
|
45974
|
+
return {
|
|
45975
|
+
icons: withIcon.slice(0, TRIGGER_ICON_LIMIT),
|
|
45976
|
+
overflow: Math.max(0, items.length - Math.min(withIcon.length, TRIGGER_ICON_LIMIT)),
|
|
45977
|
+
total: items.length
|
|
45978
|
+
};
|
|
45979
|
+
}
|
|
45980
|
+
|
|
45981
|
+
// src/components/ConnectorPanel.tsx
|
|
45982
|
+
import { Fragment as Fragment9, jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
45983
|
+
function PanelDivider() {
|
|
45984
|
+
return /* @__PURE__ */ jsx31("div", { className: "my-1 border-[hsl(var(--border))] border-t" });
|
|
45985
|
+
}
|
|
45986
|
+
function PanelTitle({ children }) {
|
|
45987
|
+
return /* @__PURE__ */ jsx31("div", { className: "px-3 pt-1 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children });
|
|
45988
|
+
}
|
|
45989
|
+
function ConnectorPanel({
|
|
45990
|
+
client,
|
|
45991
|
+
sessionId,
|
|
45992
|
+
pendingPlugins,
|
|
45993
|
+
onPendingPluginsChange,
|
|
45994
|
+
pendingDisabledReason,
|
|
45995
|
+
onPluginsChanged,
|
|
45996
|
+
onSelectedChange,
|
|
45997
|
+
renderComputerSection,
|
|
45998
|
+
renderExternalAccounts,
|
|
45999
|
+
renderFooterActions,
|
|
46000
|
+
className
|
|
46001
|
+
}) {
|
|
46002
|
+
const [query, setQuery] = useState34("");
|
|
46003
|
+
const [pendingCatalog, setPendingCatalog] = useState34(null);
|
|
46004
|
+
const [pendingLoading, setPendingLoading] = useState34(false);
|
|
46005
|
+
const [pendingError, setPendingError] = useState34(false);
|
|
46006
|
+
const activation = useSessionPluginActivation({
|
|
46007
|
+
client,
|
|
46008
|
+
// 首页不会走这个分支:待选在下面自己处理开关,不碰会话接口。
|
|
46009
|
+
sessionId: sessionId ?? "",
|
|
46010
|
+
onChange: onPluginsChanged
|
|
46011
|
+
});
|
|
46012
|
+
const { reload, items: sessionItems } = activation;
|
|
46013
|
+
useEffect23(() => {
|
|
46014
|
+
if (sessionId) reload();
|
|
46015
|
+
}, [reload, sessionId]);
|
|
46016
|
+
const loadPendingCatalog = useCallback28(async () => {
|
|
46017
|
+
setPendingLoading(true);
|
|
46018
|
+
setPendingError(false);
|
|
46019
|
+
try {
|
|
46020
|
+
const { plugins } = await client.plugins.catalog();
|
|
46021
|
+
setPendingCatalog(plugins);
|
|
46022
|
+
} catch {
|
|
46023
|
+
setPendingError(true);
|
|
46024
|
+
} finally {
|
|
46025
|
+
setPendingLoading(false);
|
|
46026
|
+
}
|
|
46027
|
+
}, [client]);
|
|
46028
|
+
useEffect23(() => {
|
|
46029
|
+
if (sessionId) return;
|
|
46030
|
+
void loadPendingCatalog();
|
|
46031
|
+
}, [loadPendingCatalog, sessionId]);
|
|
46032
|
+
const selected = useMemo19(
|
|
46033
|
+
() => new Set((pendingPlugins ?? []).map((item) => item.name)),
|
|
46034
|
+
[pendingPlugins]
|
|
46035
|
+
);
|
|
46036
|
+
const items = useMemo19(() => {
|
|
46037
|
+
if (sessionId) return sessionItems;
|
|
46038
|
+
return catalogToConnectorItems(pendingCatalog ?? []).map((item) => ({
|
|
46039
|
+
...item,
|
|
46040
|
+
active: selected.has(item.name)
|
|
46041
|
+
}));
|
|
46042
|
+
}, [pendingCatalog, selected, sessionId, sessionItems]);
|
|
46043
|
+
const visibleItems = useMemo19(
|
|
46044
|
+
() => sessionId ? filterConnectorItems(items, query) : filterConnectorItems(items, query).map((item) => ({ ...item, config: void 0 })),
|
|
46045
|
+
[items, query, sessionId]
|
|
46046
|
+
);
|
|
46047
|
+
const togglePending = useCallback28((item, next) => {
|
|
46048
|
+
const kept = (pendingPlugins ?? []).filter((entry) => entry.name !== item.name);
|
|
46049
|
+
onPendingPluginsChange?.(next ? [...kept, selectionFromItem(item)] : kept);
|
|
46050
|
+
}, [onPendingPluginsChange, pendingPlugins]);
|
|
46051
|
+
const toggle = useCallback28((item, next) => {
|
|
46052
|
+
if (sessionId) activation.toggle(item, next);
|
|
46053
|
+
else togglePending(item, next);
|
|
46054
|
+
}, [activation, sessionId, togglePending]);
|
|
46055
|
+
const selectedItems = useMemo19(
|
|
46056
|
+
() => items.filter((item) => item.active),
|
|
46057
|
+
[items]
|
|
46058
|
+
);
|
|
46059
|
+
const onSelectedChangeRef = useRef24(onSelectedChange);
|
|
46060
|
+
onSelectedChangeRef.current = onSelectedChange;
|
|
46061
|
+
const latestSelected = useRef24(selectedItems);
|
|
46062
|
+
latestSelected.current = selectedItems;
|
|
46063
|
+
const reportSelected = useCallback28(() => {
|
|
46064
|
+
onSelectedChangeRef.current?.(latestSelected.current);
|
|
46065
|
+
}, []);
|
|
46066
|
+
const selectedNames = selectedItems.map((item) => item.name).join("\0");
|
|
46067
|
+
useEffect23(reportSelected, [reportSelected, selectedNames]);
|
|
46068
|
+
const failed = sessionId ? activation.listError : pendingError;
|
|
46069
|
+
return /* @__PURE__ */ jsxs25("div", { className, children: [
|
|
46070
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2 border-[hsl(var(--border))] border-b px-3 py-2", children: [
|
|
46071
|
+
/* @__PURE__ */ jsx31(Search, { size: 12, className: "shrink-0 text-[hsl(var(--muted-foreground))]", "aria-hidden": "true" }),
|
|
46072
|
+
/* @__PURE__ */ jsx31(
|
|
46073
|
+
"input",
|
|
46074
|
+
{
|
|
46075
|
+
value: query,
|
|
46076
|
+
onChange: (event) => setQuery(event.target.value),
|
|
46077
|
+
placeholder: "\u641C\u7D22\u8FDE\u63A5\u5668",
|
|
46078
|
+
"aria-label": "\u641C\u7D22\u8FDE\u63A5\u5668",
|
|
46079
|
+
className: "min-w-0 flex-1 bg-transparent text-[11px] outline-none placeholder:text-[hsl(var(--muted-foreground))]"
|
|
46080
|
+
}
|
|
46081
|
+
)
|
|
46082
|
+
] }),
|
|
46083
|
+
renderComputerSection ? /* @__PURE__ */ jsxs25(Fragment9, { children: [
|
|
46084
|
+
/* @__PURE__ */ jsx31(PanelTitle, { children: "\u7535\u8111" }),
|
|
46085
|
+
renderComputerSection(query)
|
|
46086
|
+
] }) : null,
|
|
46087
|
+
/* @__PURE__ */ jsx31(PanelDivider, {}),
|
|
46088
|
+
/* @__PURE__ */ jsx31(PanelTitle, { children: "\u63D2\u4EF6" }),
|
|
46089
|
+
!sessionId ? (
|
|
46090
|
+
// 首页没有会话,开关只记下「这条消息要带上谁」:不说清楚,用户会以为已经
|
|
46091
|
+
// 生效(issue 明确要求「明确为待选,不宣称已经激活」)。
|
|
46092
|
+
/* @__PURE__ */ jsx31("div", { className: "px-3 pb-0.5 text-[10px] text-[hsl(var(--muted-foreground))]", children: "\u5148\u9009\u4E2D\uFF0C\u53D1\u9001\u8FD9\u6761\u6D88\u606F\u65F6\u4F1A\u4E00\u5E76\u542F\u7528" })
|
|
46093
|
+
) : null,
|
|
46094
|
+
(sessionId ? activation.loading : pendingLoading) && visibleItems.length === 0 ? /* @__PURE__ */ jsxs25("div", { className: "px-3 py-1.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: [
|
|
46095
|
+
/* @__PURE__ */ jsx31(LoaderCircle, { size: 12, className: "mr-1 inline animate-spin" }),
|
|
46096
|
+
"\u6B63\u5728\u83B7\u53D6\u63D2\u4EF6\u2026"
|
|
46097
|
+
] }) : null,
|
|
46098
|
+
failed ? /* @__PURE__ */ jsx31(
|
|
46099
|
+
"button",
|
|
46100
|
+
{
|
|
46101
|
+
type: "button",
|
|
46102
|
+
onClick: () => sessionId ? reload() : void loadPendingCatalog(),
|
|
46103
|
+
className: "px-3 py-1.5 text-left text-[11px] text-[hsl(var(--muted-foreground))] underline",
|
|
46104
|
+
children: "\u63D2\u4EF6\u5217\u8868\u6682\u4E0D\u53EF\u7528\uFF0C\u70B9\u51FB\u91CD\u8BD5"
|
|
46105
|
+
}
|
|
46106
|
+
) : null,
|
|
46107
|
+
/* @__PURE__ */ jsx31(
|
|
46108
|
+
PluginConnectorList,
|
|
46109
|
+
{
|
|
46110
|
+
client,
|
|
46111
|
+
sessionId,
|
|
46112
|
+
items: visibleItems,
|
|
46113
|
+
inFlight: activation.inFlight,
|
|
46114
|
+
busy: sessionId ? activation.busy : pendingLoading,
|
|
46115
|
+
mutationError: sessionId ? activation.mutationError : false,
|
|
46116
|
+
onToggle: toggle,
|
|
46117
|
+
onRetry: activation.retry,
|
|
46118
|
+
onEditConfig: activation.editConfig,
|
|
46119
|
+
configuring: sessionId ? activation.configuring : null,
|
|
46120
|
+
onConfigSaved: activation.onConfigSaved,
|
|
46121
|
+
onConfigClose: activation.onConfigClose,
|
|
46122
|
+
disabledReason: sessionId ? null : pendingDisabledReason,
|
|
46123
|
+
unavailableText: failed ? null : query.trim() ? "\u6CA1\u6709\u5339\u914D\u7684\u63D2\u4EF6" : null,
|
|
46124
|
+
emptyText: sessionId ? "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6" : "\u5C1A\u672A\u5B89\u88C5\u63D2\u4EF6\uFF0C\u53BB\u5E94\u7528\u5E02\u573A\u6DFB\u52A0\u4E00\u4E2A",
|
|
46125
|
+
draft: !sessionId
|
|
46126
|
+
}
|
|
46127
|
+
),
|
|
46128
|
+
renderExternalAccounts ? /* @__PURE__ */ jsxs25(Fragment9, { children: [
|
|
46129
|
+
/* @__PURE__ */ jsx31(PanelDivider, {}),
|
|
46130
|
+
/* @__PURE__ */ jsx31(PanelTitle, { children: "\u5916\u90E8\u8D26\u53F7" }),
|
|
46131
|
+
renderExternalAccounts(query)
|
|
46132
|
+
] }) : null,
|
|
46133
|
+
renderFooterActions ? /* @__PURE__ */ jsxs25(Fragment9, { children: [
|
|
46134
|
+
/* @__PURE__ */ jsx31(PanelDivider, {}),
|
|
46135
|
+
renderFooterActions()
|
|
46136
|
+
] }) : null
|
|
46137
|
+
] });
|
|
45629
46138
|
}
|
|
45630
46139
|
|
|
45631
46140
|
// src/components/ContextCard.tsx
|
|
@@ -45633,16 +46142,16 @@ import {
|
|
|
45633
46142
|
getContextDisplayState,
|
|
45634
46143
|
getContextGroupDisplayState
|
|
45635
46144
|
} from "@blade-hq/agent-client";
|
|
45636
|
-
import { jsx as
|
|
46145
|
+
import { jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
45637
46146
|
function ContextCard({ context, className }) {
|
|
45638
46147
|
const display = getContextDisplayState(context);
|
|
45639
|
-
return /* @__PURE__ */
|
|
46148
|
+
return /* @__PURE__ */ jsxs26(
|
|
45640
46149
|
"details",
|
|
45641
46150
|
{
|
|
45642
46151
|
className: `blade-chat-context-card group/context-card rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`,
|
|
45643
46152
|
children: [
|
|
45644
|
-
/* @__PURE__ */
|
|
45645
|
-
/* @__PURE__ */
|
|
46153
|
+
/* @__PURE__ */ jsxs26("summary", { className: "blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden", children: [
|
|
46154
|
+
/* @__PURE__ */ jsx32(
|
|
45646
46155
|
Layers,
|
|
45647
46156
|
{
|
|
45648
46157
|
size: 15,
|
|
@@ -45650,11 +46159,11 @@ function ContextCard({ context, className }) {
|
|
|
45650
46159
|
"aria-hidden": "true"
|
|
45651
46160
|
}
|
|
45652
46161
|
),
|
|
45653
|
-
/* @__PURE__ */
|
|
45654
|
-
/* @__PURE__ */
|
|
45655
|
-
/* @__PURE__ */
|
|
46162
|
+
/* @__PURE__ */ jsxs26("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
|
|
46163
|
+
/* @__PURE__ */ jsx32("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: display.title }),
|
|
46164
|
+
/* @__PURE__ */ jsx32("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: display.summary })
|
|
45656
46165
|
] }),
|
|
45657
|
-
/* @__PURE__ */
|
|
46166
|
+
/* @__PURE__ */ jsx32(
|
|
45658
46167
|
ChevronDown,
|
|
45659
46168
|
{
|
|
45660
46169
|
size: 14,
|
|
@@ -45663,7 +46172,7 @@ function ContextCard({ context, className }) {
|
|
|
45663
46172
|
}
|
|
45664
46173
|
)
|
|
45665
46174
|
] }),
|
|
45666
|
-
/* @__PURE__ */
|
|
46175
|
+
/* @__PURE__ */ jsx32("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: display.detail })
|
|
45667
46176
|
]
|
|
45668
46177
|
}
|
|
45669
46178
|
);
|
|
@@ -45672,9 +46181,9 @@ function ContextGroupCard({ contexts, className }) {
|
|
|
45672
46181
|
if (contexts.length === 0) return null;
|
|
45673
46182
|
const single = contexts.length === 1 ? getContextDisplayState(contexts[0]) : null;
|
|
45674
46183
|
const group = single ? null : getContextGroupDisplayState(contexts);
|
|
45675
|
-
return /* @__PURE__ */
|
|
45676
|
-
/* @__PURE__ */
|
|
45677
|
-
/* @__PURE__ */
|
|
46184
|
+
return /* @__PURE__ */ jsxs26("details", { className: `blade-chat-context-card group/context-group rounded-xl border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-sm ${className ?? ""}`, children: [
|
|
46185
|
+
/* @__PURE__ */ jsxs26("summary", { className: "blade-chat-context-summary flex cursor-pointer list-none items-center gap-2 px-3 py-2.5 [&::-webkit-details-marker]:hidden", children: [
|
|
46186
|
+
/* @__PURE__ */ jsx32(
|
|
45678
46187
|
Layers,
|
|
45679
46188
|
{
|
|
45680
46189
|
size: 15,
|
|
@@ -45682,11 +46191,11 @@ function ContextGroupCard({ contexts, className }) {
|
|
|
45682
46191
|
"aria-hidden": "true"
|
|
45683
46192
|
}
|
|
45684
46193
|
),
|
|
45685
|
-
/* @__PURE__ */
|
|
45686
|
-
/* @__PURE__ */
|
|
45687
|
-
/* @__PURE__ */
|
|
46194
|
+
/* @__PURE__ */ jsxs26("span", { className: "blade-chat-context-copy min-w-0 flex-1", children: [
|
|
46195
|
+
/* @__PURE__ */ jsx32("span", { className: "blade-chat-context-title block font-medium text-[hsl(var(--foreground))]", children: single ? single.title : `${group?.title} \xB7 ${group?.count} \u9879` }),
|
|
46196
|
+
/* @__PURE__ */ jsx32("span", { className: "blade-chat-context-status block truncate text-xs text-[hsl(var(--muted-foreground))]", children: single ? single.summary : group?.summary })
|
|
45688
46197
|
] }),
|
|
45689
|
-
/* @__PURE__ */
|
|
46198
|
+
/* @__PURE__ */ jsx32(
|
|
45690
46199
|
ChevronDown,
|
|
45691
46200
|
{
|
|
45692
46201
|
size: 14,
|
|
@@ -45695,7 +46204,7 @@ function ContextGroupCard({ contexts, className }) {
|
|
|
45695
46204
|
}
|
|
45696
46205
|
)
|
|
45697
46206
|
] }),
|
|
45698
|
-
single ? /* @__PURE__ */
|
|
46207
|
+
single ? /* @__PURE__ */ jsx32("div", { className: "blade-chat-context-detail border-t border-[hsl(var(--border))] px-3 py-2.5 text-xs leading-5 text-[hsl(var(--muted-foreground))]", children: single.detail }) : /* @__PURE__ */ jsx32("div", { className: "blade-chat-context-group-items flex flex-col gap-1.5 border-t border-[hsl(var(--border))] p-2", children: contexts.map((context) => /* @__PURE__ */ jsx32(
|
|
45699
46208
|
ContextCard,
|
|
45700
46209
|
{
|
|
45701
46210
|
context
|
|
@@ -45706,8 +46215,8 @@ function ContextGroupCard({ contexts, className }) {
|
|
|
45706
46215
|
}
|
|
45707
46216
|
|
|
45708
46217
|
// src/components/SessionMemoryToggle.tsx
|
|
45709
|
-
import { useCallback as
|
|
45710
|
-
import { jsx as
|
|
46218
|
+
import { useCallback as useCallback29, useEffect as useEffect24, useRef as useRef25, useState as useState35, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
46219
|
+
import { jsx as jsx33, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
45711
46220
|
var saveStates = /* @__PURE__ */ new WeakMap();
|
|
45712
46221
|
function getSaveState(client, sessionId) {
|
|
45713
46222
|
let clientStates = saveStates.get(client);
|
|
@@ -45748,7 +46257,7 @@ function SessionMemoryToggle({
|
|
|
45748
46257
|
throw new Error("SessionMemoryToggle \u5FC5\u987B\u5728 <BladeProvider> \u5185\u4F7F\u7528\u6216\u663E\u5F0F\u4F20\u5165 client");
|
|
45749
46258
|
}
|
|
45750
46259
|
const saveState = getSaveState(client, sessionId);
|
|
45751
|
-
const subscribe =
|
|
46260
|
+
const subscribe = useCallback29(
|
|
45752
46261
|
(listener) => {
|
|
45753
46262
|
saveState.listeners.add(listener);
|
|
45754
46263
|
return () => {
|
|
@@ -45758,19 +46267,19 @@ function SessionMemoryToggle({
|
|
|
45758
46267
|
},
|
|
45759
46268
|
[client, saveState, sessionId]
|
|
45760
46269
|
);
|
|
45761
|
-
const getSaving =
|
|
46270
|
+
const getSaving = useCallback29(() => saveState.saving, [saveState]);
|
|
45762
46271
|
const saving = useSyncExternalStore2(
|
|
45763
46272
|
subscribe,
|
|
45764
46273
|
getSaving,
|
|
45765
46274
|
getSaving
|
|
45766
46275
|
);
|
|
45767
|
-
const [draftEnabled, setDraftEnabled] =
|
|
45768
|
-
const activeSessionIdRef =
|
|
46276
|
+
const [draftEnabled, setDraftEnabled] = useState35(enabled);
|
|
46277
|
+
const activeSessionIdRef = useRef25(sessionId);
|
|
45769
46278
|
activeSessionIdRef.current = sessionId;
|
|
45770
|
-
|
|
46279
|
+
useEffect24(() => {
|
|
45771
46280
|
setDraftEnabled(enabled);
|
|
45772
46281
|
}, [enabled, sessionId]);
|
|
45773
|
-
const update =
|
|
46282
|
+
const update = useCallback29(
|
|
45774
46283
|
(nextEnabled) => {
|
|
45775
46284
|
const currentSaveState = getSaveState(client, sessionId);
|
|
45776
46285
|
if (currentSaveState.saving) return;
|
|
@@ -45796,9 +46305,9 @@ function SessionMemoryToggle({
|
|
|
45796
46305
|
},
|
|
45797
46306
|
[client, enabled, onError, onSaved, sessionId]
|
|
45798
46307
|
);
|
|
45799
|
-
return /* @__PURE__ */
|
|
45800
|
-
/* @__PURE__ */
|
|
45801
|
-
/* @__PURE__ */
|
|
46308
|
+
return /* @__PURE__ */ jsxs27("label", { className: cn("flex items-center justify-between", className), children: [
|
|
46309
|
+
/* @__PURE__ */ jsx33("span", { className: labelClassName, children: label }),
|
|
46310
|
+
/* @__PURE__ */ jsx33(
|
|
45802
46311
|
"input",
|
|
45803
46312
|
{
|
|
45804
46313
|
type: "checkbox",
|
|
@@ -45859,6 +46368,7 @@ export {
|
|
|
45859
46368
|
AgentChat,
|
|
45860
46369
|
BladeProvider,
|
|
45861
46370
|
ChatView,
|
|
46371
|
+
ConnectorPanel,
|
|
45862
46372
|
ContextCard,
|
|
45863
46373
|
ContextGroupCard,
|
|
45864
46374
|
CurrentPlanPanel,
|
|
@@ -45868,6 +46378,7 @@ export {
|
|
|
45868
46378
|
MemoryRefsHint,
|
|
45869
46379
|
PLAN_AUTO_COLLAPSE_MS,
|
|
45870
46380
|
PlanUpdateBlock,
|
|
46381
|
+
PluginConnectorList,
|
|
45871
46382
|
ReplayBar,
|
|
45872
46383
|
ReplayMismatchPrompt,
|
|
45873
46384
|
SessionMemoryToggle,
|
|
@@ -45876,24 +46387,32 @@ export {
|
|
|
45876
46387
|
SessionPluginIcon,
|
|
45877
46388
|
SessionPluginSelector,
|
|
45878
46389
|
SessionQueuePanel,
|
|
46390
|
+
TRIGGER_ICON_LIMIT,
|
|
45879
46391
|
ToolUiCardView,
|
|
45880
46392
|
WhatIfUserBubble,
|
|
46393
|
+
catalogToConnectorItems,
|
|
45881
46394
|
classifyAgentComputerLaunchOutcome,
|
|
45882
46395
|
collectMemoryRefs,
|
|
46396
|
+
filterConnectorItems,
|
|
45883
46397
|
getPlanUpdateDisplayState,
|
|
45884
46398
|
isAgentComputerCommand,
|
|
45885
46399
|
isAgentComputerToolCall,
|
|
45886
46400
|
isPlanUpdateTool,
|
|
46401
|
+
mergeConnectorItems,
|
|
45887
46402
|
normalizeAdjacentUrlFormatting,
|
|
45888
46403
|
parsePlanUpdate,
|
|
45889
46404
|
parseWhatIfPrompt,
|
|
45890
46405
|
pickCurrentPlanStep,
|
|
46406
|
+
pluginConnectorSummary,
|
|
46407
|
+
selectionFromItem,
|
|
45891
46408
|
sessionPluginLabel,
|
|
46409
|
+
triggerSummary,
|
|
45892
46410
|
useAgentSession,
|
|
45893
46411
|
useBladeClient,
|
|
45894
46412
|
useLlmChat,
|
|
45895
46413
|
useMessagePin,
|
|
45896
|
-
useReplay
|
|
46414
|
+
useReplay,
|
|
46415
|
+
useSessionPluginActivation
|
|
45897
46416
|
};
|
|
45898
46417
|
/*! Bundled license information:
|
|
45899
46418
|
|