@frontera-sdk/chat-ui 1.50.46 → 1.50.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.js +20 -15
- package/dist/{chunk-RB2Y4NYC.js → chunk-466MYFJD.js} +1 -1
- package/dist/{chunk-OP4MLJDA.js → chunk-76WUIIOX.js} +1 -1
- package/dist/{chunk-PUIVKDV5.js → chunk-AQGBRSIP.js} +1 -1
- package/dist/{chunk-X5E2DJVO.js → chunk-CWC2IOX7.js} +825 -1043
- package/dist/{chunk-QSSFBZAS.js → chunk-FTLVGUG5.js} +0 -8
- package/dist/{chunk-JD6ETTXC.js → chunk-IHBTHNXV.js} +1 -1
- package/dist/{chunk-WO6DJLFE.js → chunk-SZTQOXLD.js} +3 -3
- package/dist/{chunk-RAKKA3WU.js → chunk-XSEN6ISU.js} +4 -8
- package/dist/header.js +5 -5
- package/dist/message.js +5 -5
- package/dist/new-session.js +2 -2
- package/dist/parts.js +2 -2
- package/dist/{pdf-deck-view-inner-FZVLAEQR.js → pdf-deck-view-inner-3PVGFH26.js} +2 -2
- package/dist/{pdf-document-view-inner-6DF54JWK.js → pdf-document-view-inner-CP6VFHG4.js} +2 -2
- package/dist/pending-cards.js +2 -2
- package/package.json +3 -3
- /package/dist/{chunk-XJFTVKLW.js → chunk-IBCOQG5T.js} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from './chunk-2KEBRV3W.js';
|
|
3
|
-
import { useTranslation } from './chunk-
|
|
4
|
-
import { ToolCallItem } from './chunk-
|
|
5
|
-
import { Shimmer, Collapse, ToolGroupReasoningItem, SkillToolItem, useStreamdownPlugins, getToolMeta, STREAMDOWN_LINK_SAFETY, AppIconFrame, AppIcon, Collapsible, CollapsibleTrigger, CollapsibleContent, Icon } from './chunk-
|
|
3
|
+
import { useTranslation } from './chunk-FTLVGUG5.js';
|
|
4
|
+
import { ToolCallItem } from './chunk-76WUIIOX.js';
|
|
5
|
+
import { Shimmer, Collapse, ToolGroupReasoningItem, SkillToolItem, useStreamdownPlugins, getToolMeta, STREAMDOWN_LINK_SAFETY, AppIconFrame, AppIcon, Collapsible, CollapsibleTrigger, CollapsibleContent, Icon } from './chunk-IBCOQG5T.js';
|
|
6
6
|
import { Button, Skeleton, buttonVariants } from './chunk-GTQH7MPF.js';
|
|
7
7
|
import { Dialog, DialogContent, DialogTitle, DialogDescription, DialogClose, usePortalContainer, DialogHeader, DialogFooter } from './chunk-IQRPGFLI.js';
|
|
8
8
|
import { formatSpecifier, precisionFixed_default, precisionRound_default, precisionPrefix_default, formatPrefix, format, ChartBlockSkeleton, RawJsonFallback, RECHARTS_THEME_CLS, formatCompact, ChartTooltipContent, resolveColor, useChartColors, ChartReadout, ChartErrorBoundary } from './chunk-6BPHEBCF.js';
|
|
@@ -7924,12 +7924,12 @@ var require_use_sync_external_store_shim_production = __commonJS({
|
|
|
7924
7924
|
return x2 === y2 && (0 !== x2 || 1 / x2 === 1 / y2) || x2 !== x2 && y2 !== y2;
|
|
7925
7925
|
}
|
|
7926
7926
|
var objectIs = "function" === typeof Object.is ? Object.is : is3;
|
|
7927
|
-
var
|
|
7928
|
-
var
|
|
7927
|
+
var useState48 = React60.useState;
|
|
7928
|
+
var useEffect38 = React60.useEffect;
|
|
7929
7929
|
var useLayoutEffect10 = React60.useLayoutEffect;
|
|
7930
7930
|
var useDebugValue2 = React60.useDebugValue;
|
|
7931
7931
|
function useSyncExternalStore$2(subscribe, getSnapshot) {
|
|
7932
|
-
var value = getSnapshot(), _useState =
|
|
7932
|
+
var value = getSnapshot(), _useState = useState48({ inst: { value, getSnapshot } }), inst = _useState[0].inst, forceUpdate = _useState[1];
|
|
7933
7933
|
useLayoutEffect10(
|
|
7934
7934
|
function() {
|
|
7935
7935
|
inst.value = value;
|
|
@@ -7938,7 +7938,7 @@ var require_use_sync_external_store_shim_production = __commonJS({
|
|
|
7938
7938
|
},
|
|
7939
7939
|
[subscribe, value, getSnapshot]
|
|
7940
7940
|
);
|
|
7941
|
-
|
|
7941
|
+
useEffect38(
|
|
7942
7942
|
function() {
|
|
7943
7943
|
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
|
|
7944
7944
|
return subscribe(function() {
|
|
@@ -7986,7 +7986,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
7986
7986
|
"The result of getSnapshot should be cached to avoid an infinite loop"
|
|
7987
7987
|
), didWarnUncachedGetSnapshot = true);
|
|
7988
7988
|
}
|
|
7989
|
-
cachedValue =
|
|
7989
|
+
cachedValue = useState48({
|
|
7990
7990
|
inst: { value, getSnapshot }
|
|
7991
7991
|
});
|
|
7992
7992
|
var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
|
|
@@ -7998,7 +7998,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
7998
7998
|
},
|
|
7999
7999
|
[subscribe, value, getSnapshot]
|
|
8000
8000
|
);
|
|
8001
|
-
|
|
8001
|
+
useEffect38(
|
|
8002
8002
|
function() {
|
|
8003
8003
|
checkIfSnapshotChanged(inst) && forceUpdate({ inst });
|
|
8004
8004
|
return subscribe(function() {
|
|
@@ -8024,7 +8024,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
8024
8024
|
return getSnapshot();
|
|
8025
8025
|
}
|
|
8026
8026
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
8027
|
-
var React60 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is3,
|
|
8027
|
+
var React60 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is3, useState48 = React60.useState, useEffect38 = React60.useEffect, useLayoutEffect10 = React60.useLayoutEffect, useDebugValue2 = React60.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
|
|
8028
8028
|
exports.useSyncExternalStore = void 0 !== React60.useSyncExternalStore ? React60.useSyncExternalStore : shim;
|
|
8029
8029
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
8030
8030
|
})();
|
|
@@ -8052,12 +8052,12 @@ var require_with_selector_production = __commonJS({
|
|
|
8052
8052
|
}
|
|
8053
8053
|
var objectIs = "function" === typeof Object.is ? Object.is : is3;
|
|
8054
8054
|
var useSyncExternalStore3 = shim.useSyncExternalStore;
|
|
8055
|
-
var
|
|
8056
|
-
var
|
|
8055
|
+
var useRef36 = React60.useRef;
|
|
8056
|
+
var useEffect38 = React60.useEffect;
|
|
8057
8057
|
var useMemo30 = React60.useMemo;
|
|
8058
8058
|
var useDebugValue2 = React60.useDebugValue;
|
|
8059
8059
|
exports.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual2) {
|
|
8060
|
-
var instRef =
|
|
8060
|
+
var instRef = useRef36(null);
|
|
8061
8061
|
if (null === instRef.current) {
|
|
8062
8062
|
var inst = { hasValue: false, value: null };
|
|
8063
8063
|
instRef.current = inst;
|
|
@@ -8097,7 +8097,7 @@ var require_with_selector_production = __commonJS({
|
|
|
8097
8097
|
[getSnapshot, getServerSnapshot, selector, isEqual2]
|
|
8098
8098
|
);
|
|
8099
8099
|
var value = useSyncExternalStore3(subscribe, instRef[0], instRef[1]);
|
|
8100
|
-
|
|
8100
|
+
useEffect38(
|
|
8101
8101
|
function() {
|
|
8102
8102
|
inst.hasValue = true;
|
|
8103
8103
|
inst.value = value;
|
|
@@ -8118,9 +8118,9 @@ var require_with_selector_development = __commonJS({
|
|
|
8118
8118
|
return x2 === y2 && (0 !== x2 || 1 / x2 === 1 / y2) || x2 !== x2 && y2 !== y2;
|
|
8119
8119
|
}
|
|
8120
8120
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
8121
|
-
var React60 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is3, useSyncExternalStore3 = shim.useSyncExternalStore,
|
|
8121
|
+
var React60 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is3, useSyncExternalStore3 = shim.useSyncExternalStore, useRef36 = React60.useRef, useEffect38 = React60.useEffect, useMemo30 = React60.useMemo, useDebugValue2 = React60.useDebugValue;
|
|
8122
8122
|
exports.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual2) {
|
|
8123
|
-
var instRef =
|
|
8123
|
+
var instRef = useRef36(null);
|
|
8124
8124
|
if (null === instRef.current) {
|
|
8125
8125
|
var inst = { hasValue: false, value: null };
|
|
8126
8126
|
instRef.current = inst;
|
|
@@ -8161,7 +8161,7 @@ var require_with_selector_development = __commonJS({
|
|
|
8161
8161
|
[getSnapshot, getServerSnapshot, selector, isEqual2]
|
|
8162
8162
|
);
|
|
8163
8163
|
var value = useSyncExternalStore3(subscribe, instRef[0], instRef[1]);
|
|
8164
|
-
|
|
8164
|
+
useEffect38(
|
|
8165
8165
|
function() {
|
|
8166
8166
|
inst.hasValue = true;
|
|
8167
8167
|
inst.value = value;
|
|
@@ -8196,12 +8196,12 @@ var require_use_sync_external_store_with_selector_production = __commonJS({
|
|
|
8196
8196
|
}
|
|
8197
8197
|
var objectIs = "function" === typeof Object.is ? Object.is : is3;
|
|
8198
8198
|
var useSyncExternalStore3 = React60.useSyncExternalStore;
|
|
8199
|
-
var
|
|
8200
|
-
var
|
|
8199
|
+
var useRef36 = React60.useRef;
|
|
8200
|
+
var useEffect38 = React60.useEffect;
|
|
8201
8201
|
var useMemo30 = React60.useMemo;
|
|
8202
8202
|
var useDebugValue2 = React60.useDebugValue;
|
|
8203
8203
|
exports.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual2) {
|
|
8204
|
-
var instRef =
|
|
8204
|
+
var instRef = useRef36(null);
|
|
8205
8205
|
if (null === instRef.current) {
|
|
8206
8206
|
var inst = { hasValue: false, value: null };
|
|
8207
8207
|
instRef.current = inst;
|
|
@@ -8241,7 +8241,7 @@ var require_use_sync_external_store_with_selector_production = __commonJS({
|
|
|
8241
8241
|
[getSnapshot, getServerSnapshot, selector, isEqual2]
|
|
8242
8242
|
);
|
|
8243
8243
|
var value = useSyncExternalStore3(subscribe, instRef[0], instRef[1]);
|
|
8244
|
-
|
|
8244
|
+
useEffect38(
|
|
8245
8245
|
function() {
|
|
8246
8246
|
inst.hasValue = true;
|
|
8247
8247
|
inst.value = value;
|
|
@@ -8262,9 +8262,9 @@ var require_use_sync_external_store_with_selector_development = __commonJS({
|
|
|
8262
8262
|
return x2 === y2 && (0 !== x2 || 1 / x2 === 1 / y2) || x2 !== x2 && y2 !== y2;
|
|
8263
8263
|
}
|
|
8264
8264
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
8265
|
-
var React60 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is3, useSyncExternalStore3 = React60.useSyncExternalStore,
|
|
8265
|
+
var React60 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is3, useSyncExternalStore3 = React60.useSyncExternalStore, useRef36 = React60.useRef, useEffect38 = React60.useEffect, useMemo30 = React60.useMemo, useDebugValue2 = React60.useDebugValue;
|
|
8266
8266
|
exports.useSyncExternalStoreWithSelector = function(subscribe, getSnapshot, getServerSnapshot, selector, isEqual2) {
|
|
8267
|
-
var instRef =
|
|
8267
|
+
var instRef = useRef36(null);
|
|
8268
8268
|
if (null === instRef.current) {
|
|
8269
8269
|
var inst = { hasValue: false, value: null };
|
|
8270
8270
|
instRef.current = inst;
|
|
@@ -8305,7 +8305,7 @@ var require_use_sync_external_store_with_selector_development = __commonJS({
|
|
|
8305
8305
|
[getSnapshot, getServerSnapshot, selector, isEqual2]
|
|
8306
8306
|
);
|
|
8307
8307
|
var value = useSyncExternalStore3(subscribe, instRef[0], instRef[1]);
|
|
8308
|
-
|
|
8308
|
+
useEffect38(
|
|
8309
8309
|
function() {
|
|
8310
8310
|
inst.hasValue = true;
|
|
8311
8311
|
inst.value = value;
|
|
@@ -10792,9 +10792,6 @@ function getCanvasStreamData(part) {
|
|
|
10792
10792
|
errorText: getToolErrorText(part)
|
|
10793
10793
|
};
|
|
10794
10794
|
}
|
|
10795
|
-
function isApprovalRequested(part) {
|
|
10796
|
-
return part.state === "approval-requested";
|
|
10797
|
-
}
|
|
10798
10795
|
function getApprovalId(part) {
|
|
10799
10796
|
const approval = part.approval;
|
|
10800
10797
|
return approval?.id;
|
|
@@ -13561,862 +13558,325 @@ function OAuthAuthorizeCard({
|
|
|
13561
13558
|
)
|
|
13562
13559
|
] });
|
|
13563
13560
|
}
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
status: (conversationId) => [DOMAIN7, "status", conversationId]
|
|
13568
|
-
};
|
|
13569
|
-
function conversationDesktop(client, conversationId) {
|
|
13570
|
-
return client.v1.conversations({ conversationId });
|
|
13571
|
-
}
|
|
13572
|
-
async function fetchDesktopStatus(client, conversationId, signal) {
|
|
13573
|
-
const { data, error } = await conversationDesktop(client, conversationId).desktop.get({
|
|
13574
|
-
fetch: { signal }
|
|
13575
|
-
});
|
|
13576
|
-
if (error) throw error;
|
|
13577
|
-
return unwrapData(data);
|
|
13561
|
+
function getDesktop() {
|
|
13562
|
+
if (typeof window === "undefined") return null;
|
|
13563
|
+
return window.fronteraDesktop ?? null;
|
|
13578
13564
|
}
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
|
|
13583
|
-
});
|
|
13584
|
-
if (res.error) {
|
|
13585
|
-
const status = res.error.status;
|
|
13586
|
-
const value = res.error.value;
|
|
13587
|
-
if (status === 503 || isWakingBody(value) || isWakingBody(res.data)) {
|
|
13588
|
-
return { ok: false, waking: true };
|
|
13589
|
-
}
|
|
13590
|
-
throw res.error;
|
|
13591
|
-
}
|
|
13592
|
-
const payload = res.data;
|
|
13593
|
-
if (isWakingBody(payload)) return { ok: false, waking: true };
|
|
13594
|
-
const blob = desktopScreenshotBlob(payload);
|
|
13595
|
-
return { ok: true, blob };
|
|
13565
|
+
var noopSubscribe = () => () => {
|
|
13566
|
+
};
|
|
13567
|
+
function getDesktopAccessBridge() {
|
|
13568
|
+
return getDesktop()?.desktopAccess ?? null;
|
|
13596
13569
|
}
|
|
13597
|
-
|
|
13598
|
-
|
|
13599
|
-
|
|
13570
|
+
var getDesktopAccessSnapshot = () => getDesktopAccessBridge();
|
|
13571
|
+
var getDesktopAccessServerSnapshot = () => null;
|
|
13572
|
+
function useDesktopAccessBridge() {
|
|
13573
|
+
return useSyncExternalStore(
|
|
13574
|
+
noopSubscribe,
|
|
13575
|
+
getDesktopAccessSnapshot,
|
|
13576
|
+
getDesktopAccessServerSnapshot
|
|
13600
13577
|
);
|
|
13601
13578
|
}
|
|
13602
|
-
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13608
|
-
|
|
13609
|
-
|
|
13610
|
-
copy3.set(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
|
|
13611
|
-
return new Blob([copy3], { type: "image/png" });
|
|
13612
|
-
}
|
|
13613
|
-
throw new Error("Desktop screenshot was not an image");
|
|
13614
|
-
}
|
|
13615
|
-
function useConversationDesktopStatus(conversationId) {
|
|
13616
|
-
const client = useClient();
|
|
13617
|
-
return useQuery({
|
|
13618
|
-
queryKey: conversationDesktopKeys.status(conversationId ?? ""),
|
|
13619
|
-
queryFn: () => fetchDesktopStatus(client, conversationId),
|
|
13620
|
-
enabled: !!conversationId,
|
|
13579
|
+
env("NEXT_PUBLIC_SERVICE_URL") || "http://localhost:4000";
|
|
13580
|
+
function useDesktopAccessLocalStatus() {
|
|
13581
|
+
const bridge = useDesktopAccessBridge();
|
|
13582
|
+
const queryClient = useQueryClient();
|
|
13583
|
+
const query = useQuery({
|
|
13584
|
+
queryKey: desktopAccessKeys.local(),
|
|
13585
|
+
queryFn: () => bridge.status(),
|
|
13586
|
+
enabled: bridge !== null,
|
|
13621
13587
|
staleTime: Infinity,
|
|
13622
|
-
|
|
13623
|
-
retry: false,
|
|
13624
|
-
refetchOnWindowFocus: false,
|
|
13625
|
-
refetchOnReconnect: false
|
|
13588
|
+
retry: 1
|
|
13626
13589
|
});
|
|
13590
|
+
useEffect(() => {
|
|
13591
|
+
if (!bridge) return;
|
|
13592
|
+
return bridge.onEvent((event) => {
|
|
13593
|
+
if (event.type === "status" && event.status) {
|
|
13594
|
+
queryClient.setQueryData(desktopAccessKeys.local(), event.status);
|
|
13595
|
+
} else {
|
|
13596
|
+
void queryClient.invalidateQueries({ queryKey: desktopAccessKeys.local() });
|
|
13597
|
+
}
|
|
13598
|
+
void queryClient.invalidateQueries({ queryKey: desktopAccessKeys.all });
|
|
13599
|
+
});
|
|
13600
|
+
}, [bridge, queryClient]);
|
|
13601
|
+
return query;
|
|
13627
13602
|
}
|
|
13628
|
-
|
|
13629
|
-
|
|
13630
|
-
|
|
13631
|
-
|
|
13632
|
-
|
|
13633
|
-
|
|
13634
|
-
|
|
13635
|
-
|
|
13636
|
-
|
|
13637
|
-
|
|
13603
|
+
function useDecideDesktopGrantLocally() {
|
|
13604
|
+
const bridge = useDesktopAccessBridge();
|
|
13605
|
+
const queryClient = useQueryClient();
|
|
13606
|
+
return useMutation({
|
|
13607
|
+
mutationFn: async (input) => {
|
|
13608
|
+
if (!bridge) throw new Error("Desktop Access bridge is not available");
|
|
13609
|
+
return bridge.decideGrant(input);
|
|
13610
|
+
},
|
|
13611
|
+
onSuccess: () => {
|
|
13612
|
+
void queryClient.invalidateQueries({ queryKey: desktopAccessKeys.all });
|
|
13638
13613
|
}
|
|
13639
|
-
|
|
13640
|
-
|
|
13641
|
-
|
|
13642
|
-
|
|
13643
|
-
|
|
13644
|
-
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
|
|
13648
|
-
}
|
|
13649
|
-
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
/* @__PURE__ */ jsxs("div", { className: "group relative aspect-video overflow-hidden rounded-xl", children: [
|
|
13654
|
-
imageUrl ? (
|
|
13655
|
-
// eslint-disable-next-line @next/next/no-img-element -- blob: screenshot URLs
|
|
13656
|
-
/* @__PURE__ */ jsx(
|
|
13657
|
-
"img",
|
|
13658
|
-
{
|
|
13659
|
-
src: imageUrl,
|
|
13660
|
-
alt: caption ?? t("chat.desktop.screen"),
|
|
13661
|
-
className: "absolute inset-0 size-full object-cover"
|
|
13662
|
-
}
|
|
13663
|
-
)
|
|
13664
|
-
) : /* @__PURE__ */ jsx(Skeleton, { className: "absolute inset-0 size-full rounded-none" }),
|
|
13665
|
-
/* @__PURE__ */ jsx(
|
|
13666
|
-
"div",
|
|
13667
|
-
{
|
|
13668
|
-
className: cn(
|
|
13669
|
-
"absolute inset-0 flex items-center justify-center bg-scrim/30 opacity-0 transition-opacity duration-150 group-hover:opacity-100",
|
|
13670
|
-
"focus-within:opacity-100"
|
|
13671
|
-
),
|
|
13672
|
-
children: /* @__PURE__ */ jsx(
|
|
13673
|
-
Button,
|
|
13674
|
-
{
|
|
13675
|
-
type: "button",
|
|
13676
|
-
variant: "default-neutral",
|
|
13677
|
-
size: "sm",
|
|
13678
|
-
className: "rounded-full px-4",
|
|
13679
|
-
onClick: onOpen,
|
|
13680
|
-
children: t("chat.desktop.open")
|
|
13681
|
-
}
|
|
13682
|
-
)
|
|
13683
|
-
}
|
|
13684
|
-
),
|
|
13685
|
-
state === "off" && !imageUrl ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("chat.desktop.asleep") }) : null
|
|
13686
|
-
] }),
|
|
13687
|
-
caption ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-center text-xs text-muted-foreground", children: caption }) : null
|
|
13688
|
-
] });
|
|
13614
|
+
});
|
|
13615
|
+
}
|
|
13616
|
+
function useDecideDesktopApprovalLocally() {
|
|
13617
|
+
const bridge = useDesktopAccessBridge();
|
|
13618
|
+
const queryClient = useQueryClient();
|
|
13619
|
+
return useMutation({
|
|
13620
|
+
mutationFn: async (input) => {
|
|
13621
|
+
if (!bridge) throw new Error("Desktop Access bridge is not available");
|
|
13622
|
+
return bridge.decideApproval(input);
|
|
13623
|
+
},
|
|
13624
|
+
onSuccess: () => {
|
|
13625
|
+
void queryClient.invalidateQueries({ queryKey: desktopAccessKeys.all });
|
|
13626
|
+
}
|
|
13627
|
+
});
|
|
13689
13628
|
}
|
|
13690
13629
|
|
|
13691
|
-
// src/vendor/ui/
|
|
13692
|
-
var
|
|
13693
|
-
|
|
13630
|
+
// src/vendor/ui/desktop-access/utils/desktop-health.ts
|
|
13631
|
+
var PRESENTATION = {
|
|
13632
|
+
desktop_offline: { tone: "bg-muted-foreground", textTone: "text-muted-foreground", labelKey: "desktop_offline", animate: false, usable: false },
|
|
13633
|
+
connecting: { tone: "bg-muted-foreground", textTone: "text-muted-foreground", labelKey: "connecting", animate: true, usable: false },
|
|
13634
|
+
connected_unregistered: { tone: "bg-warning", textTone: "text-warning", labelKey: "connected_unregistered", animate: false, usable: false },
|
|
13635
|
+
registered_unroutable: { tone: "bg-warning", textTone: "text-warning", labelKey: "registered_unroutable", animate: false, usable: false },
|
|
13636
|
+
available_no_grant: { tone: "bg-warning", textTone: "text-warning", labelKey: "available_no_grant", animate: false, usable: false },
|
|
13637
|
+
waiting_for_approval: { tone: "bg-warning", textTone: "text-warning", labelKey: "waiting_for_approval", animate: false, usable: false },
|
|
13638
|
+
blocked_by_org_policy: { tone: "bg-destructive", textTone: "text-destructive", labelKey: "blocked_by_org_policy", animate: false, usable: false },
|
|
13639
|
+
blocked_by_os_permission: { tone: "bg-destructive", textTone: "text-destructive", labelKey: "blocked_by_os_permission", animate: false, usable: false },
|
|
13640
|
+
blocked_by_device_policy: { tone: "bg-destructive", textTone: "text-destructive", labelKey: "blocked_by_device_policy", animate: false, usable: false },
|
|
13641
|
+
resource_unavailable: { tone: "bg-warning", textTone: "text-warning", labelKey: "resource_unavailable", animate: false, usable: false },
|
|
13642
|
+
upgrade_required: { tone: "bg-destructive", textTone: "text-destructive", labelKey: "upgrade_required", animate: false, usable: false },
|
|
13643
|
+
ready: { tone: "bg-success", textTone: "text-foreground", labelKey: "ready", animate: false, usable: true },
|
|
13644
|
+
executing: { tone: "bg-success", textTone: "text-foreground", labelKey: "executing", animate: true, usable: true },
|
|
13645
|
+
degraded: { tone: "bg-warning", textTone: "text-warning", labelKey: "degraded", animate: false, usable: true }
|
|
13646
|
+
};
|
|
13647
|
+
function describeDesktopHealth(health) {
|
|
13648
|
+
return health && PRESENTATION[health] || PRESENTATION.desktop_offline;
|
|
13649
|
+
}
|
|
13650
|
+
function isDeviceReachable(health) {
|
|
13651
|
+
if (!health) return false;
|
|
13652
|
+
return health !== "desktop_offline" && health !== "connecting" && health !== "upgrade_required";
|
|
13653
|
+
}
|
|
13694
13654
|
|
|
13695
|
-
// src/vendor/ui/
|
|
13696
|
-
|
|
13697
|
-
|
|
13698
|
-
|
|
13655
|
+
// src/vendor/ui/desktop-access/utils/desktop-labels.ts
|
|
13656
|
+
var desktopLabelKey = {
|
|
13657
|
+
resourceKind: (kind) => `desktopAccess.resourceKind.${kind}`,
|
|
13658
|
+
operation: (op) => `desktopAccess.operation.${op}`,
|
|
13659
|
+
scope: (scope) => `desktopAccess.scope.${scope}`,
|
|
13660
|
+
writeMode: (mode) => `desktopAccess.writeMode.${mode}`,
|
|
13661
|
+
riskClass: (risk) => `desktopAccess.risk.${risk}`,
|
|
13662
|
+
capabilityClass: (cls) => `desktopAccess.capability.${cls}`,
|
|
13663
|
+
/** `desktop.files.read` → `desktopAccess.tool.files.read` */
|
|
13664
|
+
capability: (name) => `desktopAccess.tool.${name.replace(/^desktop\./, "")}`,
|
|
13665
|
+
health: (health) => `desktopAccess.health.${health}`,
|
|
13666
|
+
trust: (trust) => `desktopAccess.trust.${trust}`,
|
|
13667
|
+
requestStatus: (status) => `desktopAccess.request.status.${status}`,
|
|
13668
|
+
osPermission: (kind) => `desktopAccess.osPermission.${kind}`,
|
|
13669
|
+
osPermissionState: (state) => `desktopAccess.osPermissionState.${state}`,
|
|
13670
|
+
auditKind: (kind) => `desktopAccess.audit.kind.${kind}`
|
|
13671
|
+
};
|
|
13672
|
+
function capabilityFromToolName(toolName) {
|
|
13673
|
+
if (!toolName.startsWith("local_")) return null;
|
|
13674
|
+
const rest = toolName.slice("local_".length);
|
|
13675
|
+
const [group, ...action] = rest.split("_");
|
|
13676
|
+
if (!group || action.length === 0) return null;
|
|
13677
|
+
const family = group === "command" ? "commands" : group;
|
|
13678
|
+
return `desktop.${family}.${action.join("_")}`;
|
|
13699
13679
|
}
|
|
13700
|
-
function
|
|
13701
|
-
|
|
13702
|
-
open,
|
|
13703
|
-
maxDim,
|
|
13704
|
-
fetchers,
|
|
13705
|
-
pollIntervalMs = DESKTOP_SCREEN_POLL_MS
|
|
13706
|
-
}) {
|
|
13707
|
-
const [state, setState] = useState("off");
|
|
13708
|
-
const [imageUrl, setImageUrl] = useState(null);
|
|
13709
|
-
const [reconnecting, setReconnecting] = useState(false);
|
|
13710
|
-
const [display, setDisplay] = useState();
|
|
13711
|
-
const [detail, setDetail] = useState();
|
|
13712
|
-
const imageUrlRef = useRef(null);
|
|
13713
|
-
const fetchersRef = useRef(fetchers);
|
|
13714
|
-
fetchersRef.current = fetchers;
|
|
13715
|
-
useEffect(() => {
|
|
13716
|
-
imageUrlRef.current = imageUrl;
|
|
13717
|
-
}, [imageUrl]);
|
|
13718
|
-
useEffect(() => {
|
|
13719
|
-
if (!open) {
|
|
13720
|
-
setState("off");
|
|
13721
|
-
setReconnecting(false);
|
|
13722
|
-
setDisplay(void 0);
|
|
13723
|
-
const previous = imageUrlRef.current;
|
|
13724
|
-
if (previous) {
|
|
13725
|
-
URL.revokeObjectURL(previous);
|
|
13726
|
-
imageUrlRef.current = null;
|
|
13727
|
-
setImageUrl(null);
|
|
13728
|
-
}
|
|
13729
|
-
}
|
|
13730
|
-
}, [open]);
|
|
13731
|
-
useEffect(() => {
|
|
13732
|
-
if (!open || !conversationId) return;
|
|
13733
|
-
let cancelled2 = false;
|
|
13734
|
-
let inFlight = false;
|
|
13735
|
-
const controller = new AbortController();
|
|
13736
|
-
const tick = async () => {
|
|
13737
|
-
if (cancelled2 || inFlight || !tabIsVisible()) return;
|
|
13738
|
-
inFlight = true;
|
|
13739
|
-
try {
|
|
13740
|
-
const status = await fetchersRef.current.fetchStatus(
|
|
13741
|
-
conversationId,
|
|
13742
|
-
controller.signal
|
|
13743
|
-
);
|
|
13744
|
-
if (cancelled2) return;
|
|
13745
|
-
setDisplay(status.display);
|
|
13746
|
-
setDetail(status.detail);
|
|
13747
|
-
if (!status.enabled) {
|
|
13748
|
-
setState("off");
|
|
13749
|
-
setReconnecting(false);
|
|
13750
|
-
return;
|
|
13751
|
-
}
|
|
13752
|
-
if (status.state === "unavailable" || status.state === "upgradable") {
|
|
13753
|
-
setState(status.state);
|
|
13754
|
-
setReconnecting(false);
|
|
13755
|
-
return;
|
|
13756
|
-
}
|
|
13757
|
-
const shot = await fetchersRef.current.fetchScreenshot(
|
|
13758
|
-
conversationId,
|
|
13759
|
-
maxDim,
|
|
13760
|
-
controller.signal
|
|
13761
|
-
);
|
|
13762
|
-
if (cancelled2) return;
|
|
13763
|
-
if (!shot.ok) {
|
|
13764
|
-
setState("waking");
|
|
13765
|
-
setReconnecting(false);
|
|
13766
|
-
return;
|
|
13767
|
-
}
|
|
13768
|
-
const nextUrl = URL.createObjectURL(shot.blob);
|
|
13769
|
-
const previous = imageUrlRef.current;
|
|
13770
|
-
imageUrlRef.current = nextUrl;
|
|
13771
|
-
setImageUrl(nextUrl);
|
|
13772
|
-
if (previous) URL.revokeObjectURL(previous);
|
|
13773
|
-
setState("live");
|
|
13774
|
-
setReconnecting(false);
|
|
13775
|
-
} catch (error) {
|
|
13776
|
-
if (cancelled2) return;
|
|
13777
|
-
if (controller.signal.aborted) return;
|
|
13778
|
-
if (error instanceof DOMException && error.name === "AbortError") return;
|
|
13779
|
-
if (imageUrlRef.current) {
|
|
13780
|
-
setReconnecting(true);
|
|
13781
|
-
} else {
|
|
13782
|
-
setState("off");
|
|
13783
|
-
}
|
|
13784
|
-
} finally {
|
|
13785
|
-
inFlight = false;
|
|
13786
|
-
}
|
|
13787
|
-
};
|
|
13788
|
-
const onVisibility = () => {
|
|
13789
|
-
if (tabIsVisible()) void tick();
|
|
13790
|
-
};
|
|
13791
|
-
void tick();
|
|
13792
|
-
const interval = setInterval(() => {
|
|
13793
|
-
void tick();
|
|
13794
|
-
}, pollIntervalMs);
|
|
13795
|
-
document.addEventListener("visibilitychange", onVisibility);
|
|
13796
|
-
return () => {
|
|
13797
|
-
cancelled2 = true;
|
|
13798
|
-
controller.abort();
|
|
13799
|
-
clearInterval(interval);
|
|
13800
|
-
document.removeEventListener("visibilitychange", onVisibility);
|
|
13801
|
-
};
|
|
13802
|
-
}, [open, conversationId, maxDim, pollIntervalMs]);
|
|
13803
|
-
useEffect(() => {
|
|
13804
|
-
return () => {
|
|
13805
|
-
const previous = imageUrlRef.current;
|
|
13806
|
-
if (previous) URL.revokeObjectURL(previous);
|
|
13807
|
-
};
|
|
13808
|
-
}, []);
|
|
13809
|
-
return { state, imageUrl, reconnecting, display, detail };
|
|
13680
|
+
function isDesktopAccessTool(toolName) {
|
|
13681
|
+
return capabilityFromToolName(toolName) !== null;
|
|
13810
13682
|
}
|
|
13811
|
-
|
|
13812
|
-
|
|
13813
|
-
|
|
13814
|
-
|
|
13815
|
-
|
|
13816
|
-
|
|
13817
|
-
|
|
13818
|
-
|
|
13819
|
-
|
|
13820
|
-
const client = useClient();
|
|
13821
|
-
const desktop = useConversationDesktopStatus(conversationId);
|
|
13822
|
-
const setLightboxOpen = useDesktopScreenStore((s2) => s2.setLightboxOpen);
|
|
13823
|
-
const openPanel = useDesktopScreenStore((s2) => s2.open);
|
|
13824
|
-
const fetchers = useMemo(
|
|
13825
|
-
() => ({
|
|
13826
|
-
fetchStatus: (id, signal) => fetchDesktopStatus(client, id, signal),
|
|
13827
|
-
fetchScreenshot: (id, maxDim, signal) => fetchDesktopScreenshot(client, id, maxDim, signal)
|
|
13828
|
-
}),
|
|
13829
|
-
[client]
|
|
13830
|
-
);
|
|
13831
|
-
const poll = useDesktopScreenPoll({
|
|
13832
|
-
conversationId,
|
|
13833
|
-
open: phase === "pending" && !!conversationId && desktop.data?.enabled === true,
|
|
13834
|
-
maxDim: DESKTOP_THUMBNAIL_MAX_DIM,
|
|
13835
|
-
fetchers,
|
|
13836
|
-
pollIntervalMs: CARD_POLL_MS
|
|
13837
|
-
});
|
|
13838
|
-
const heading = t("chat.desktop.computer");
|
|
13839
|
-
const badge = phase === "pending" ? {
|
|
13840
|
-
label: t("chat.desktop.actionNeeded"),
|
|
13841
|
-
className: "bg-warning/10 text-warning"} : phase === "done" ? {
|
|
13842
|
-
label: t("chat.desktop.done"),
|
|
13843
|
-
className: "bg-success/10 text-success"} : {
|
|
13844
|
-
label: t("chat.desktop.skipped"),
|
|
13845
|
-
className: "bg-surface-inset text-muted-foreground"};
|
|
13846
|
-
if (phase !== "pending") {
|
|
13847
|
-
return /* @__PURE__ */ jsxs(
|
|
13848
|
-
"div",
|
|
13849
|
-
{
|
|
13850
|
-
"data-slot": "request-human-approval-card",
|
|
13851
|
-
"data-phase": phase,
|
|
13852
|
-
className: "relative my-2 flex items-center gap-2 rounded-xl border border-border bg-surface px-4 py-2",
|
|
13853
|
-
children: [
|
|
13854
|
-
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-sm font-semibold text-foreground", children: heading }),
|
|
13855
|
-
/* @__PURE__ */ jsx(
|
|
13856
|
-
"span",
|
|
13857
|
-
{
|
|
13858
|
-
className: cn(
|
|
13859
|
-
"shrink-0 rounded-full px-2 py-0.5 text-xs font-medium",
|
|
13860
|
-
badge.className
|
|
13861
|
-
),
|
|
13862
|
-
children: badge.label
|
|
13863
|
-
}
|
|
13864
|
-
),
|
|
13865
|
-
title ? /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: title }) : /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1" }),
|
|
13866
|
-
/* @__PURE__ */ jsxs(
|
|
13867
|
-
Button,
|
|
13868
|
-
{
|
|
13869
|
-
type: "button",
|
|
13870
|
-
variant: "outline",
|
|
13871
|
-
size: "sm",
|
|
13872
|
-
className: "shrink-0",
|
|
13873
|
-
onClick: () => {
|
|
13874
|
-
if (conversationId) openPanel(conversationId);
|
|
13875
|
-
setLightboxOpen(true);
|
|
13876
|
-
},
|
|
13877
|
-
children: [
|
|
13878
|
-
/* @__PURE__ */ jsx(DeviceDesktopIcon, { className: "size-3.5" }),
|
|
13879
|
-
t("chat.desktop.openComputer")
|
|
13880
|
-
]
|
|
13881
|
-
}
|
|
13882
|
-
)
|
|
13883
|
-
]
|
|
13884
|
-
}
|
|
13885
|
-
);
|
|
13683
|
+
function formatBytes(bytes) {
|
|
13684
|
+
if (bytes == null || !Number.isFinite(bytes) || bytes < 0) return null;
|
|
13685
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
13686
|
+
const units = ["KB", "MB", "GB", "TB"];
|
|
13687
|
+
let value = bytes / 1024;
|
|
13688
|
+
let unit2 = 0;
|
|
13689
|
+
while (value >= 1024 && unit2 < units.length - 1) {
|
|
13690
|
+
value /= 1024;
|
|
13691
|
+
unit2 += 1;
|
|
13886
13692
|
}
|
|
13693
|
+
return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[unit2]}`;
|
|
13694
|
+
}
|
|
13695
|
+
function shortRevision(revision) {
|
|
13696
|
+
if (!revision) return null;
|
|
13697
|
+
return revision.slice(0, 8);
|
|
13698
|
+
}
|
|
13699
|
+
function DecisionCard({
|
|
13700
|
+
tone = "idle",
|
|
13701
|
+
icon,
|
|
13702
|
+
kind,
|
|
13703
|
+
question,
|
|
13704
|
+
detail,
|
|
13705
|
+
note,
|
|
13706
|
+
actions,
|
|
13707
|
+
settled,
|
|
13708
|
+
children,
|
|
13709
|
+
className,
|
|
13710
|
+
testId
|
|
13711
|
+
}) {
|
|
13712
|
+
const toneClass = tone === "ok" ? "text-success" : tone === "warn" ? "text-warning" : tone === "danger" ? "text-destructive" : "text-muted-foreground";
|
|
13887
13713
|
return /* @__PURE__ */ jsxs(
|
|
13888
13714
|
"div",
|
|
13889
13715
|
{
|
|
13890
|
-
"data-
|
|
13891
|
-
"data-
|
|
13892
|
-
|
|
13716
|
+
"data-testid": testId,
|
|
13717
|
+
"data-tone": tone,
|
|
13718
|
+
"data-settled": settled != null ? "" : void 0,
|
|
13719
|
+
className: cn(
|
|
13720
|
+
"relative mt-2 min-w-0 rounded-xl border border-border bg-surface-raised px-4 py-3",
|
|
13721
|
+
className
|
|
13722
|
+
),
|
|
13893
13723
|
children: [
|
|
13894
|
-
/* @__PURE__ */ jsxs("div", { className: "
|
|
13895
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
13896
|
-
/* @__PURE__ */
|
|
13897
|
-
|
|
13898
|
-
{
|
|
13899
|
-
className: cn(
|
|
13900
|
-
"ml-auto inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium",
|
|
13901
|
-
badge.className
|
|
13902
|
-
),
|
|
13903
|
-
children: [
|
|
13904
|
-
/* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-warning animate-pulse", "aria-hidden": true }),
|
|
13905
|
-
badge.label
|
|
13906
|
-
]
|
|
13907
|
-
}
|
|
13908
|
-
)
|
|
13724
|
+
/* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-center gap-1.5 text-xs", toneClass), children: [
|
|
13725
|
+
/* @__PURE__ */ jsx("span", { className: "flex size-4 shrink-0 items-center justify-center [&_svg]:size-3.5", children: icon ?? /* @__PURE__ */ jsx(DeviceDesktopIcon, { "aria-hidden": true }) }),
|
|
13726
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: kind }),
|
|
13727
|
+
settled != null && /* @__PURE__ */ jsx("span", { className: "ml-auto min-w-0 truncate text-right text-foreground", "data-testid": testId ? `${testId}-settled` : void 0, children: settled })
|
|
13909
13728
|
] }),
|
|
13910
|
-
|
|
13911
|
-
|
|
13912
|
-
|
|
13913
|
-
|
|
13914
|
-
|
|
13915
|
-
|
|
13916
|
-
|
|
13917
|
-
|
|
13918
|
-
) }),
|
|
13919
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
13920
|
-
/* @__PURE__ */ jsx(
|
|
13921
|
-
Button,
|
|
13922
|
-
{
|
|
13923
|
-
type: "button",
|
|
13924
|
-
variant: "default",
|
|
13925
|
-
onClick: () => setLightboxOpen(true),
|
|
13926
|
-
children: t("chat.desktop.takeOver")
|
|
13927
|
-
}
|
|
13928
|
-
),
|
|
13929
|
-
/* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: onApprove, children: t("chat.desktop.imDone") }),
|
|
13930
|
-
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", className: "ml-auto", onClick: onDeny, children: t("chat.desktop.skip") })
|
|
13931
|
-
] })
|
|
13729
|
+
settled == null && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13730
|
+
question != null && /* @__PURE__ */ jsx("p", { className: "mt-1 break-words text-sm text-foreground", children: question }),
|
|
13731
|
+
detail != null && /* @__PURE__ */ jsx("div", { className: "mt-2 min-w-0 overflow-hidden whitespace-pre-wrap break-all rounded-md bg-surface-inset px-3 py-2 font-mono text-xs leading-relaxed text-foreground/90", children: detail }),
|
|
13732
|
+
children,
|
|
13733
|
+
note != null && /* @__PURE__ */ jsx("p", { className: "mt-2 break-words text-xs text-muted-foreground", children: note }),
|
|
13734
|
+
actions != null && /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap items-center justify-end gap-2", children: actions })
|
|
13735
|
+
] }),
|
|
13736
|
+
settled != null && children
|
|
13932
13737
|
]
|
|
13933
13738
|
}
|
|
13934
13739
|
);
|
|
13935
13740
|
}
|
|
13936
|
-
|
|
13937
|
-
|
|
13938
|
-
|
|
13939
|
-
|
|
13940
|
-
|
|
13941
|
-
|
|
13942
|
-
|
|
13943
|
-
|
|
13944
|
-
|
|
13945
|
-
|
|
13946
|
-
const value = record[key];
|
|
13947
|
-
if (typeof value === "string" && value.trim()) return value.trim();
|
|
13948
|
-
}
|
|
13949
|
-
}
|
|
13950
|
-
return fallback;
|
|
13951
|
-
}
|
|
13952
|
-
function requestHumanPhaseFromPart(part) {
|
|
13953
|
-
const state = typeof part.state === "string" ? part.state : "";
|
|
13954
|
-
if (state === "approval-requested") return "pending";
|
|
13955
|
-
const approval = part.approval;
|
|
13956
|
-
if (approval && approval.approved === false) return "skipped";
|
|
13957
|
-
if (state === "output-error" || state === "output-denied" || typeof part.errorText === "string") {
|
|
13958
|
-
return "skipped";
|
|
13959
|
-
}
|
|
13960
|
-
const output = part.output ?? part.result;
|
|
13961
|
-
if (output && typeof output === "object") {
|
|
13962
|
-
const record = output;
|
|
13963
|
-
if (record.skipped === true || record.denied === true || record.approved === false) {
|
|
13964
|
-
return "skipped";
|
|
13741
|
+
function Kbd({ className, ...props }) {
|
|
13742
|
+
return /* @__PURE__ */ jsx(
|
|
13743
|
+
"kbd",
|
|
13744
|
+
{
|
|
13745
|
+
"data-slot": "kbd",
|
|
13746
|
+
className: cn(
|
|
13747
|
+
"pointer-events-none inline-flex h-4 min-w-4 select-none items-center justify-center rounded border border-border bg-surface-inset px-1 font-mono text-[10px] font-medium leading-none text-muted-foreground",
|
|
13748
|
+
className
|
|
13749
|
+
),
|
|
13750
|
+
...props
|
|
13965
13751
|
}
|
|
13966
|
-
|
|
13967
|
-
if (state === "output-available" || state === "result" || output != null) return "done";
|
|
13968
|
-
if (state === "input-available" || state === "input-streaming" || state === "call" || state === "partial-call") {
|
|
13969
|
-
return "pending";
|
|
13970
|
-
}
|
|
13971
|
-
return "done";
|
|
13972
|
-
}
|
|
13973
|
-
function requestHumanThreadPhase(part, pendingStatus) {
|
|
13974
|
-
if (pendingStatus === "pending") return "pending";
|
|
13975
|
-
if (pendingStatus === "abandoned") return "skipped";
|
|
13976
|
-
return requestHumanPhaseFromPart(part);
|
|
13977
|
-
}
|
|
13978
|
-
var ALWAYS_ALLOW_KEY = "sebati-tool-always-allow";
|
|
13979
|
-
function getAlwaysAllowedTools() {
|
|
13980
|
-
if (typeof window === "undefined") return /* @__PURE__ */ new Set();
|
|
13981
|
-
try {
|
|
13982
|
-
const stored = localStorage.getItem(ALWAYS_ALLOW_KEY);
|
|
13983
|
-
if (stored) return new Set(JSON.parse(stored));
|
|
13984
|
-
} catch {
|
|
13985
|
-
}
|
|
13986
|
-
return /* @__PURE__ */ new Set();
|
|
13987
|
-
}
|
|
13988
|
-
function addAlwaysAllowedTool(toolName) {
|
|
13989
|
-
if (typeof window === "undefined") return;
|
|
13990
|
-
const tools = getAlwaysAllowedTools();
|
|
13991
|
-
tools.add(toolName);
|
|
13992
|
-
localStorage.setItem(ALWAYS_ALLOW_KEY, JSON.stringify([...tools]));
|
|
13752
|
+
);
|
|
13993
13753
|
}
|
|
13994
|
-
function
|
|
13995
|
-
|
|
13754
|
+
function DecisionSecondaryButton({
|
|
13755
|
+
label,
|
|
13756
|
+
onClick,
|
|
13757
|
+
disabled,
|
|
13758
|
+
"aria-label": ariaLabel
|
|
13759
|
+
}) {
|
|
13760
|
+
return /* @__PURE__ */ jsxs(Button, { size: "sm", variant: "outline", disabled, onClick, "aria-label": ariaLabel, "data-slot": "decision-secondary", children: [
|
|
13761
|
+
label,
|
|
13762
|
+
/* @__PURE__ */ jsx(Kbd, { "aria-hidden": true, className: "hidden md:inline-flex", children: "Esc" })
|
|
13763
|
+
] });
|
|
13996
13764
|
}
|
|
13997
|
-
function
|
|
13998
|
-
|
|
13999
|
-
|
|
14000
|
-
|
|
14001
|
-
|
|
14002
|
-
|
|
13765
|
+
function DecisionSplitButton({
|
|
13766
|
+
label,
|
|
13767
|
+
onClick,
|
|
13768
|
+
disabled,
|
|
13769
|
+
variant = "default",
|
|
13770
|
+
options,
|
|
13771
|
+
menuLabel,
|
|
13772
|
+
hint = "enter",
|
|
13773
|
+
className,
|
|
13774
|
+
"aria-label": ariaLabel
|
|
14003
13775
|
}) {
|
|
14004
13776
|
const { t } = useTranslation();
|
|
14005
|
-
const
|
|
14006
|
-
const
|
|
14007
|
-
const
|
|
14008
|
-
|
|
14009
|
-
|
|
14010
|
-
|
|
13777
|
+
const hasMenu = !!options && options.length > 0;
|
|
13778
|
+
const kbdClass = variant === "default" || variant === "default-neutral" ? "hidden md:inline-flex border-primary-foreground/30 bg-transparent text-primary-foreground/80" : "hidden md:inline-flex bg-transparent";
|
|
13779
|
+
const main = /* @__PURE__ */ jsxs(
|
|
13780
|
+
Button,
|
|
13781
|
+
{
|
|
13782
|
+
size: "sm",
|
|
13783
|
+
variant,
|
|
13784
|
+
disabled,
|
|
13785
|
+
onClick,
|
|
13786
|
+
"aria-label": ariaLabel,
|
|
13787
|
+
className: cn(hasMenu && "rounded-r-none", className),
|
|
13788
|
+
"data-slot": "decision-primary",
|
|
13789
|
+
children: [
|
|
13790
|
+
label,
|
|
13791
|
+
hint === "enter" && /* @__PURE__ */ jsx(Kbd, { "aria-hidden": true, className: kbdClass, children: "\u23CE" })
|
|
13792
|
+
]
|
|
13793
|
+
}
|
|
14011
13794
|
);
|
|
14012
|
-
if (!
|
|
14013
|
-
|
|
14014
|
-
|
|
14015
|
-
|
|
14016
|
-
{
|
|
14017
|
-
|
|
14018
|
-
|
|
14019
|
-
|
|
14020
|
-
|
|
14021
|
-
|
|
14022
|
-
|
|
14023
|
-
|
|
14024
|
-
|
|
14025
|
-
|
|
14026
|
-
|
|
14027
|
-
|
|
14028
|
-
|
|
14029
|
-
|
|
14030
|
-
|
|
14031
|
-
|
|
14032
|
-
|
|
14033
|
-
|
|
14034
|
-
const handleDeny = () => {
|
|
14035
|
-
setResponded(true);
|
|
14036
|
-
onDeny(approvalId);
|
|
14037
|
-
};
|
|
14038
|
-
const handleAlwaysAllow = () => {
|
|
14039
|
-
setResponded(true);
|
|
14040
|
-
onAlwaysAllow?.(toolName);
|
|
14041
|
-
onApprove(approvalId);
|
|
14042
|
-
};
|
|
14043
|
-
return (
|
|
14044
|
-
// `bg-surface-raised`, not `bg-background`: the thread behind this card is
|
|
14045
|
-
// already `surface-chat`, so `background` painted the card DARKER than what
|
|
14046
|
-
// it sits on — the one card in the run that must be read looked like a hole
|
|
14047
|
-
// punched in the message.
|
|
14048
|
-
//
|
|
14049
|
-
// `relative` is load-bearing. This card renders inside the step timeline,
|
|
14050
|
-
// whose rail is an absolutely-positioned span — so it paints above every
|
|
14051
|
-
// static sibling, and a hairline ran straight down the card's left inset.
|
|
14052
|
-
// Positioning the card puts it in the same paint layer, later in DOM order,
|
|
14053
|
-
// and the rail stops at its edges: the timeline is a thread of small steps,
|
|
14054
|
-
// and this is a panel interrupting it, not a bead on it.
|
|
14055
|
-
/* @__PURE__ */ jsxs("div", { className: "relative rounded-lg border bg-surface-raised p-3 my-1.5", children: [
|
|
14056
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 mb-2", children: /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground", children: t("dialog.toolApproval.title") }) }),
|
|
14057
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-2", children: /* @__PURE__ */ jsx("span", { className: "font-mono text-foreground", children: toolName }) }),
|
|
14058
|
-
displayInput.length > 0 && /* @__PURE__ */ jsx("div", { className: "text-sm bg-surface-inset border rounded p-2 mb-3 space-y-0.5", children: displayInput.map(({ key, value }) => /* @__PURE__ */ jsxs("div", { children: [
|
|
14059
|
-
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
14060
|
-
key,
|
|
14061
|
-
":"
|
|
14062
|
-
] }),
|
|
14063
|
-
" ",
|
|
14064
|
-
/* @__PURE__ */ jsx("span", { className: "text-foreground", children: value })
|
|
14065
|
-
] }, key)) }),
|
|
14066
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
14067
|
-
/* @__PURE__ */ jsx(
|
|
14068
|
-
Button,
|
|
14069
|
-
{
|
|
14070
|
-
variant: "default",
|
|
14071
|
-
className: "gap-1.5",
|
|
14072
|
-
disabled: responded,
|
|
14073
|
-
onClick: handleApprove,
|
|
14074
|
-
children: t("dialog.toolApproval.approve")
|
|
14075
|
-
}
|
|
14076
|
-
),
|
|
14077
|
-
/* @__PURE__ */ jsx(
|
|
14078
|
-
Button,
|
|
14079
|
-
{
|
|
14080
|
-
variant: "outline",
|
|
14081
|
-
className: "gap-1.5",
|
|
14082
|
-
disabled: responded,
|
|
14083
|
-
onClick: handleDeny,
|
|
14084
|
-
children: t("dialog.toolApproval.deny")
|
|
14085
|
-
}
|
|
14086
|
-
),
|
|
14087
|
-
onAlwaysAllow && /* @__PURE__ */ jsx(
|
|
14088
|
-
Button,
|
|
13795
|
+
if (!hasMenu) return main;
|
|
13796
|
+
return /* @__PURE__ */ jsxs("div", { className: "inline-flex items-stretch", "data-slot": "decision-split-button", children: [
|
|
13797
|
+
main,
|
|
13798
|
+
/* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
13799
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
13800
|
+
Button,
|
|
13801
|
+
{
|
|
13802
|
+
size: "sm",
|
|
13803
|
+
variant,
|
|
13804
|
+
disabled,
|
|
13805
|
+
"aria-label": menuLabel ?? t("desktopAccess.action.moreOptions"),
|
|
13806
|
+
className: "rounded-l-none border-l border-l-background/25 px-1.5",
|
|
13807
|
+
"data-slot": "decision-menu-trigger",
|
|
13808
|
+
children: /* @__PURE__ */ jsx(ChevronDownMediumIcon, { "aria-hidden": true })
|
|
13809
|
+
}
|
|
13810
|
+
) }),
|
|
13811
|
+
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", className: "min-w-56", children: /* @__PURE__ */ jsx(TooltipProvider, { children: options.map(
|
|
13812
|
+
(option) => option.disabled && option.disabledReason != null ? /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
13813
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "block", children: /* @__PURE__ */ jsx(DropdownMenuItem, { disabled: true, "data-selected": option.selected ? "" : void 0, children: option.label }) }) }),
|
|
13814
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "left", children: option.disabledReason })
|
|
13815
|
+
] }, option.id) : /* @__PURE__ */ jsx(
|
|
13816
|
+
DropdownMenuItem,
|
|
14089
13817
|
{
|
|
14090
|
-
|
|
14091
|
-
|
|
14092
|
-
|
|
14093
|
-
|
|
14094
|
-
children:
|
|
14095
|
-
}
|
|
13818
|
+
disabled: option.disabled,
|
|
13819
|
+
"data-selected": option.selected ? "" : void 0,
|
|
13820
|
+
className: "data-[selected]:font-medium",
|
|
13821
|
+
onSelect: () => option.onSelect(),
|
|
13822
|
+
children: option.label
|
|
13823
|
+
},
|
|
13824
|
+
option.id
|
|
14096
13825
|
)
|
|
14097
|
-
|
|
13826
|
+
) }) })
|
|
14098
13827
|
] })
|
|
14099
|
-
);
|
|
13828
|
+
] });
|
|
14100
13829
|
}
|
|
14101
|
-
|
|
14102
|
-
|
|
14103
|
-
|
|
13830
|
+
var registry = [];
|
|
13831
|
+
var listening = false;
|
|
13832
|
+
function isTypingTarget(target) {
|
|
13833
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
13834
|
+
if (target.isContentEditable) return true;
|
|
13835
|
+
const tag = target.tagName;
|
|
13836
|
+
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
13837
|
+
return !!target.closest('[role="menu"], [role="dialog"], [role="listbox"], [contenteditable="true"]');
|
|
14104
13838
|
}
|
|
14105
|
-
|
|
14106
|
-
|
|
14107
|
-
|
|
14108
|
-
|
|
13839
|
+
function onKeyDown(event) {
|
|
13840
|
+
if (event.defaultPrevented || event.isComposing) return;
|
|
13841
|
+
if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
|
|
13842
|
+
if (event.key !== "Enter" && event.key !== "Escape") return;
|
|
13843
|
+
const owner = registry[registry.length - 1];
|
|
13844
|
+
if (!owner) return;
|
|
13845
|
+
if (isTypingTarget(event.target) || isTypingTarget(document.activeElement)) return;
|
|
13846
|
+
const handler = event.key === "Enter" ? owner.handlers.current.onPrimary : owner.handlers.current.onSecondary;
|
|
13847
|
+
if (!handler) return;
|
|
13848
|
+
event.preventDefault();
|
|
13849
|
+
handler();
|
|
14109
13850
|
}
|
|
14110
|
-
|
|
14111
|
-
|
|
14112
|
-
|
|
14113
|
-
|
|
14114
|
-
noopSubscribe,
|
|
14115
|
-
getDesktopAccessSnapshot,
|
|
14116
|
-
getDesktopAccessServerSnapshot
|
|
14117
|
-
);
|
|
13851
|
+
function ensureListener() {
|
|
13852
|
+
if (listening || typeof window === "undefined") return;
|
|
13853
|
+
listening = true;
|
|
13854
|
+
window.addEventListener("keydown", onKeyDown);
|
|
14118
13855
|
}
|
|
14119
|
-
|
|
14120
|
-
|
|
14121
|
-
|
|
14122
|
-
|
|
14123
|
-
const query = useQuery({
|
|
14124
|
-
queryKey: desktopAccessKeys.local(),
|
|
14125
|
-
queryFn: () => bridge.status(),
|
|
14126
|
-
enabled: bridge !== null,
|
|
14127
|
-
staleTime: Infinity,
|
|
14128
|
-
retry: 1
|
|
14129
|
-
});
|
|
14130
|
-
useEffect(() => {
|
|
14131
|
-
if (!bridge) return;
|
|
14132
|
-
return bridge.onEvent((event) => {
|
|
14133
|
-
if (event.type === "status" && event.status) {
|
|
14134
|
-
queryClient.setQueryData(desktopAccessKeys.local(), event.status);
|
|
14135
|
-
} else {
|
|
14136
|
-
void queryClient.invalidateQueries({ queryKey: desktopAccessKeys.local() });
|
|
14137
|
-
}
|
|
14138
|
-
void queryClient.invalidateQueries({ queryKey: desktopAccessKeys.all });
|
|
14139
|
-
});
|
|
14140
|
-
}, [bridge, queryClient]);
|
|
14141
|
-
return query;
|
|
13856
|
+
function releaseListener() {
|
|
13857
|
+
if (!listening || registry.length > 0) return;
|
|
13858
|
+
listening = false;
|
|
13859
|
+
window.removeEventListener("keydown", onKeyDown);
|
|
14142
13860
|
}
|
|
14143
|
-
function
|
|
14144
|
-
|
|
14145
|
-
|
|
14146
|
-
|
|
14147
|
-
|
|
14148
|
-
|
|
14149
|
-
|
|
14150
|
-
|
|
14151
|
-
|
|
14152
|
-
|
|
14153
|
-
}
|
|
14154
|
-
|
|
14155
|
-
|
|
14156
|
-
|
|
14157
|
-
|
|
14158
|
-
|
|
14159
|
-
|
|
14160
|
-
|
|
14161
|
-
|
|
14162
|
-
return bridge.decideApproval(input);
|
|
14163
|
-
},
|
|
14164
|
-
onSuccess: () => {
|
|
14165
|
-
void queryClient.invalidateQueries({ queryKey: desktopAccessKeys.all });
|
|
14166
|
-
}
|
|
14167
|
-
});
|
|
14168
|
-
}
|
|
14169
|
-
|
|
14170
|
-
// src/vendor/ui/desktop-access/utils/desktop-health.ts
|
|
14171
|
-
var PRESENTATION = {
|
|
14172
|
-
desktop_offline: { tone: "bg-muted-foreground", textTone: "text-muted-foreground", labelKey: "desktop_offline", animate: false, usable: false },
|
|
14173
|
-
connecting: { tone: "bg-muted-foreground", textTone: "text-muted-foreground", labelKey: "connecting", animate: true, usable: false },
|
|
14174
|
-
connected_unregistered: { tone: "bg-warning", textTone: "text-warning", labelKey: "connected_unregistered", animate: false, usable: false },
|
|
14175
|
-
registered_unroutable: { tone: "bg-warning", textTone: "text-warning", labelKey: "registered_unroutable", animate: false, usable: false },
|
|
14176
|
-
available_no_grant: { tone: "bg-warning", textTone: "text-warning", labelKey: "available_no_grant", animate: false, usable: false },
|
|
14177
|
-
waiting_for_approval: { tone: "bg-warning", textTone: "text-warning", labelKey: "waiting_for_approval", animate: false, usable: false },
|
|
14178
|
-
blocked_by_org_policy: { tone: "bg-destructive", textTone: "text-destructive", labelKey: "blocked_by_org_policy", animate: false, usable: false },
|
|
14179
|
-
blocked_by_os_permission: { tone: "bg-destructive", textTone: "text-destructive", labelKey: "blocked_by_os_permission", animate: false, usable: false },
|
|
14180
|
-
blocked_by_device_policy: { tone: "bg-destructive", textTone: "text-destructive", labelKey: "blocked_by_device_policy", animate: false, usable: false },
|
|
14181
|
-
resource_unavailable: { tone: "bg-warning", textTone: "text-warning", labelKey: "resource_unavailable", animate: false, usable: false },
|
|
14182
|
-
upgrade_required: { tone: "bg-destructive", textTone: "text-destructive", labelKey: "upgrade_required", animate: false, usable: false },
|
|
14183
|
-
ready: { tone: "bg-success", textTone: "text-foreground", labelKey: "ready", animate: false, usable: true },
|
|
14184
|
-
executing: { tone: "bg-success", textTone: "text-foreground", labelKey: "executing", animate: true, usable: true },
|
|
14185
|
-
degraded: { tone: "bg-warning", textTone: "text-warning", labelKey: "degraded", animate: false, usable: true }
|
|
14186
|
-
};
|
|
14187
|
-
function describeDesktopHealth(health) {
|
|
14188
|
-
return health && PRESENTATION[health] || PRESENTATION.desktop_offline;
|
|
14189
|
-
}
|
|
14190
|
-
function isDeviceReachable(health) {
|
|
14191
|
-
if (!health) return false;
|
|
14192
|
-
return health !== "desktop_offline" && health !== "connecting" && health !== "upgrade_required";
|
|
14193
|
-
}
|
|
14194
|
-
|
|
14195
|
-
// src/vendor/ui/desktop-access/utils/desktop-labels.ts
|
|
14196
|
-
var desktopLabelKey = {
|
|
14197
|
-
resourceKind: (kind) => `desktopAccess.resourceKind.${kind}`,
|
|
14198
|
-
operation: (op) => `desktopAccess.operation.${op}`,
|
|
14199
|
-
scope: (scope) => `desktopAccess.scope.${scope}`,
|
|
14200
|
-
writeMode: (mode) => `desktopAccess.writeMode.${mode}`,
|
|
14201
|
-
riskClass: (risk) => `desktopAccess.risk.${risk}`,
|
|
14202
|
-
capabilityClass: (cls) => `desktopAccess.capability.${cls}`,
|
|
14203
|
-
/** `desktop.files.read` → `desktopAccess.tool.files.read` */
|
|
14204
|
-
capability: (name) => `desktopAccess.tool.${name.replace(/^desktop\./, "")}`,
|
|
14205
|
-
health: (health) => `desktopAccess.health.${health}`,
|
|
14206
|
-
trust: (trust) => `desktopAccess.trust.${trust}`,
|
|
14207
|
-
requestStatus: (status) => `desktopAccess.request.status.${status}`,
|
|
14208
|
-
osPermission: (kind) => `desktopAccess.osPermission.${kind}`,
|
|
14209
|
-
osPermissionState: (state) => `desktopAccess.osPermissionState.${state}`,
|
|
14210
|
-
auditKind: (kind) => `desktopAccess.audit.kind.${kind}`
|
|
14211
|
-
};
|
|
14212
|
-
function capabilityFromToolName(toolName) {
|
|
14213
|
-
if (!toolName.startsWith("local_")) return null;
|
|
14214
|
-
const rest = toolName.slice("local_".length);
|
|
14215
|
-
const [group, ...action] = rest.split("_");
|
|
14216
|
-
if (!group || action.length === 0) return null;
|
|
14217
|
-
const family = group === "command" ? "commands" : group;
|
|
14218
|
-
return `desktop.${family}.${action.join("_")}`;
|
|
14219
|
-
}
|
|
14220
|
-
function isDesktopAccessTool(toolName) {
|
|
14221
|
-
return capabilityFromToolName(toolName) !== null;
|
|
14222
|
-
}
|
|
14223
|
-
function formatBytes(bytes) {
|
|
14224
|
-
if (bytes == null || !Number.isFinite(bytes) || bytes < 0) return null;
|
|
14225
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
14226
|
-
const units = ["KB", "MB", "GB", "TB"];
|
|
14227
|
-
let value = bytes / 1024;
|
|
14228
|
-
let unit2 = 0;
|
|
14229
|
-
while (value >= 1024 && unit2 < units.length - 1) {
|
|
14230
|
-
value /= 1024;
|
|
14231
|
-
unit2 += 1;
|
|
14232
|
-
}
|
|
14233
|
-
return `${value < 10 ? value.toFixed(1) : Math.round(value)} ${units[unit2]}`;
|
|
14234
|
-
}
|
|
14235
|
-
function shortRevision(revision) {
|
|
14236
|
-
if (!revision) return null;
|
|
14237
|
-
return revision.slice(0, 8);
|
|
14238
|
-
}
|
|
14239
|
-
function DecisionCard({
|
|
14240
|
-
tone = "idle",
|
|
14241
|
-
icon,
|
|
14242
|
-
kind,
|
|
14243
|
-
question,
|
|
14244
|
-
detail,
|
|
14245
|
-
note,
|
|
14246
|
-
actions,
|
|
14247
|
-
settled,
|
|
14248
|
-
children,
|
|
14249
|
-
className,
|
|
14250
|
-
testId
|
|
14251
|
-
}) {
|
|
14252
|
-
const toneClass = tone === "ok" ? "text-success" : tone === "warn" ? "text-warning" : tone === "danger" ? "text-destructive" : "text-muted-foreground";
|
|
14253
|
-
return /* @__PURE__ */ jsxs(
|
|
14254
|
-
"div",
|
|
14255
|
-
{
|
|
14256
|
-
"data-testid": testId,
|
|
14257
|
-
"data-tone": tone,
|
|
14258
|
-
"data-settled": settled != null ? "" : void 0,
|
|
14259
|
-
className: cn(
|
|
14260
|
-
"relative mt-2 min-w-0 rounded-xl border border-border bg-surface-raised px-4 py-3",
|
|
14261
|
-
className
|
|
14262
|
-
),
|
|
14263
|
-
children: [
|
|
14264
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-center gap-1.5 text-xs", toneClass), children: [
|
|
14265
|
-
/* @__PURE__ */ jsx("span", { className: "flex size-4 shrink-0 items-center justify-center [&_svg]:size-3.5", children: icon ?? /* @__PURE__ */ jsx(DeviceDesktopIcon, { "aria-hidden": true }) }),
|
|
14266
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: kind }),
|
|
14267
|
-
settled != null && /* @__PURE__ */ jsx("span", { className: "ml-auto min-w-0 truncate text-right text-foreground", "data-testid": testId ? `${testId}-settled` : void 0, children: settled })
|
|
14268
|
-
] }),
|
|
14269
|
-
settled == null && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
14270
|
-
question != null && /* @__PURE__ */ jsx("p", { className: "mt-1 break-words text-sm text-foreground", children: question }),
|
|
14271
|
-
detail != null && /* @__PURE__ */ jsx("div", { className: "mt-2 min-w-0 overflow-hidden whitespace-pre-wrap break-all rounded-md bg-surface-inset px-3 py-2 font-mono text-xs leading-relaxed text-foreground/90", children: detail }),
|
|
14272
|
-
children,
|
|
14273
|
-
note != null && /* @__PURE__ */ jsx("p", { className: "mt-2 break-words text-xs text-muted-foreground", children: note }),
|
|
14274
|
-
actions != null && /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap items-center justify-end gap-2", children: actions })
|
|
14275
|
-
] }),
|
|
14276
|
-
settled != null && children
|
|
14277
|
-
]
|
|
14278
|
-
}
|
|
14279
|
-
);
|
|
14280
|
-
}
|
|
14281
|
-
function Kbd({ className, ...props }) {
|
|
14282
|
-
return /* @__PURE__ */ jsx(
|
|
14283
|
-
"kbd",
|
|
14284
|
-
{
|
|
14285
|
-
"data-slot": "kbd",
|
|
14286
|
-
className: cn(
|
|
14287
|
-
"pointer-events-none inline-flex h-4 min-w-4 select-none items-center justify-center rounded border border-border bg-surface-inset px-1 font-mono text-[10px] font-medium leading-none text-muted-foreground",
|
|
14288
|
-
className
|
|
14289
|
-
),
|
|
14290
|
-
...props
|
|
14291
|
-
}
|
|
14292
|
-
);
|
|
14293
|
-
}
|
|
14294
|
-
function DecisionSecondaryButton({
|
|
14295
|
-
label,
|
|
14296
|
-
onClick,
|
|
14297
|
-
disabled,
|
|
14298
|
-
"aria-label": ariaLabel
|
|
14299
|
-
}) {
|
|
14300
|
-
return /* @__PURE__ */ jsxs(Button, { size: "sm", variant: "outline", disabled, onClick, "aria-label": ariaLabel, "data-slot": "decision-secondary", children: [
|
|
14301
|
-
label,
|
|
14302
|
-
/* @__PURE__ */ jsx(Kbd, { "aria-hidden": true, className: "hidden md:inline-flex", children: "Esc" })
|
|
14303
|
-
] });
|
|
14304
|
-
}
|
|
14305
|
-
function DecisionSplitButton({
|
|
14306
|
-
label,
|
|
14307
|
-
onClick,
|
|
14308
|
-
disabled,
|
|
14309
|
-
variant = "default",
|
|
14310
|
-
options,
|
|
14311
|
-
menuLabel,
|
|
14312
|
-
hint = "enter",
|
|
14313
|
-
className,
|
|
14314
|
-
"aria-label": ariaLabel
|
|
14315
|
-
}) {
|
|
14316
|
-
const { t } = useTranslation();
|
|
14317
|
-
const hasMenu = !!options && options.length > 0;
|
|
14318
|
-
const kbdClass = variant === "default" || variant === "default-neutral" ? "hidden md:inline-flex border-primary-foreground/30 bg-transparent text-primary-foreground/80" : "hidden md:inline-flex bg-transparent";
|
|
14319
|
-
const main = /* @__PURE__ */ jsxs(
|
|
14320
|
-
Button,
|
|
14321
|
-
{
|
|
14322
|
-
size: "sm",
|
|
14323
|
-
variant,
|
|
14324
|
-
disabled,
|
|
14325
|
-
onClick,
|
|
14326
|
-
"aria-label": ariaLabel,
|
|
14327
|
-
className: cn(hasMenu && "rounded-r-none", className),
|
|
14328
|
-
"data-slot": "decision-primary",
|
|
14329
|
-
children: [
|
|
14330
|
-
label,
|
|
14331
|
-
hint === "enter" && /* @__PURE__ */ jsx(Kbd, { "aria-hidden": true, className: kbdClass, children: "\u23CE" })
|
|
14332
|
-
]
|
|
14333
|
-
}
|
|
14334
|
-
);
|
|
14335
|
-
if (!hasMenu) return main;
|
|
14336
|
-
return /* @__PURE__ */ jsxs("div", { className: "inline-flex items-stretch", "data-slot": "decision-split-button", children: [
|
|
14337
|
-
main,
|
|
14338
|
-
/* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
14339
|
-
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
14340
|
-
Button,
|
|
14341
|
-
{
|
|
14342
|
-
size: "sm",
|
|
14343
|
-
variant,
|
|
14344
|
-
disabled,
|
|
14345
|
-
"aria-label": menuLabel ?? t("desktopAccess.action.moreOptions"),
|
|
14346
|
-
className: "rounded-l-none border-l border-l-background/25 px-1.5",
|
|
14347
|
-
"data-slot": "decision-menu-trigger",
|
|
14348
|
-
children: /* @__PURE__ */ jsx(ChevronDownMediumIcon, { "aria-hidden": true })
|
|
14349
|
-
}
|
|
14350
|
-
) }),
|
|
14351
|
-
/* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", className: "min-w-56", children: /* @__PURE__ */ jsx(TooltipProvider, { children: options.map(
|
|
14352
|
-
(option) => option.disabled && option.disabledReason != null ? /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
14353
|
-
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("span", { className: "block", children: /* @__PURE__ */ jsx(DropdownMenuItem, { disabled: true, "data-selected": option.selected ? "" : void 0, children: option.label }) }) }),
|
|
14354
|
-
/* @__PURE__ */ jsx(TooltipContent, { side: "left", children: option.disabledReason })
|
|
14355
|
-
] }, option.id) : /* @__PURE__ */ jsx(
|
|
14356
|
-
DropdownMenuItem,
|
|
14357
|
-
{
|
|
14358
|
-
disabled: option.disabled,
|
|
14359
|
-
"data-selected": option.selected ? "" : void 0,
|
|
14360
|
-
className: "data-[selected]:font-medium",
|
|
14361
|
-
onSelect: () => option.onSelect(),
|
|
14362
|
-
children: option.label
|
|
14363
|
-
},
|
|
14364
|
-
option.id
|
|
14365
|
-
)
|
|
14366
|
-
) }) })
|
|
14367
|
-
] })
|
|
14368
|
-
] });
|
|
14369
|
-
}
|
|
14370
|
-
var registry = [];
|
|
14371
|
-
var listening = false;
|
|
14372
|
-
function isTypingTarget(target) {
|
|
14373
|
-
if (!(target instanceof HTMLElement)) return false;
|
|
14374
|
-
if (target.isContentEditable) return true;
|
|
14375
|
-
const tag = target.tagName;
|
|
14376
|
-
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT") return true;
|
|
14377
|
-
return !!target.closest('[role="menu"], [role="dialog"], [role="listbox"], [contenteditable="true"]');
|
|
14378
|
-
}
|
|
14379
|
-
function onKeyDown(event) {
|
|
14380
|
-
if (event.defaultPrevented || event.isComposing) return;
|
|
14381
|
-
if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) return;
|
|
14382
|
-
if (event.key !== "Enter" && event.key !== "Escape") return;
|
|
14383
|
-
const owner = registry[registry.length - 1];
|
|
14384
|
-
if (!owner) return;
|
|
14385
|
-
if (isTypingTarget(event.target) || isTypingTarget(document.activeElement)) return;
|
|
14386
|
-
const handler = event.key === "Enter" ? owner.handlers.current.onPrimary : owner.handlers.current.onSecondary;
|
|
14387
|
-
if (!handler) return;
|
|
14388
|
-
event.preventDefault();
|
|
14389
|
-
handler();
|
|
14390
|
-
}
|
|
14391
|
-
function ensureListener() {
|
|
14392
|
-
if (listening || typeof window === "undefined") return;
|
|
14393
|
-
listening = true;
|
|
14394
|
-
window.addEventListener("keydown", onKeyDown);
|
|
14395
|
-
}
|
|
14396
|
-
function releaseListener() {
|
|
14397
|
-
if (!listening || registry.length > 0) return;
|
|
14398
|
-
listening = false;
|
|
14399
|
-
window.removeEventListener("keydown", onKeyDown);
|
|
14400
|
-
}
|
|
14401
|
-
function useDecisionShortcuts({
|
|
14402
|
-
active,
|
|
14403
|
-
onPrimary,
|
|
14404
|
-
onSecondary
|
|
14405
|
-
}) {
|
|
14406
|
-
const id = useId();
|
|
14407
|
-
const handlers = useRef({ onPrimary, onSecondary });
|
|
14408
|
-
handlers.current = { onPrimary, onSecondary };
|
|
14409
|
-
useEffect(() => {
|
|
14410
|
-
if (!active) return;
|
|
14411
|
-
const entry = { id, handlers };
|
|
14412
|
-
registry.push(entry);
|
|
14413
|
-
ensureListener();
|
|
14414
|
-
return () => {
|
|
14415
|
-
const at = registry.indexOf(entry);
|
|
14416
|
-
if (at !== -1) registry.splice(at, 1);
|
|
14417
|
-
releaseListener();
|
|
14418
|
-
};
|
|
14419
|
-
}, [active, id]);
|
|
13861
|
+
function useDecisionShortcuts({
|
|
13862
|
+
active,
|
|
13863
|
+
onPrimary,
|
|
13864
|
+
onSecondary
|
|
13865
|
+
}) {
|
|
13866
|
+
const id = useId();
|
|
13867
|
+
const handlers = useRef({ onPrimary, onSecondary });
|
|
13868
|
+
handlers.current = { onPrimary, onSecondary };
|
|
13869
|
+
useEffect(() => {
|
|
13870
|
+
if (!active) return;
|
|
13871
|
+
const entry = { id, handlers };
|
|
13872
|
+
registry.push(entry);
|
|
13873
|
+
ensureListener();
|
|
13874
|
+
return () => {
|
|
13875
|
+
const at = registry.indexOf(entry);
|
|
13876
|
+
if (at !== -1) registry.splice(at, 1);
|
|
13877
|
+
releaseListener();
|
|
13878
|
+
};
|
|
13879
|
+
}, [active, id]);
|
|
14420
13880
|
}
|
|
14421
13881
|
|
|
14422
13882
|
// src/vendor/ui/chat/desktop-access/utils/grant-scope-options.ts
|
|
@@ -15100,9 +14560,7 @@ function MessageDecisionCards({
|
|
|
15100
14560
|
items,
|
|
15101
14561
|
conversationId,
|
|
15102
14562
|
isStreamingMessage,
|
|
15103
|
-
hasLaterStepsGroup = false
|
|
15104
|
-
onToolApproval,
|
|
15105
|
-
showInlineToolApprovals = false
|
|
14563
|
+
hasLaterStepsGroup = false
|
|
15106
14564
|
}) {
|
|
15107
14565
|
const toolItems = items.filter(
|
|
15108
14566
|
(i) => i.type === "tool"
|
|
@@ -15110,22 +14568,6 @@ function MessageDecisionCards({
|
|
|
15110
14568
|
const { data: pendingStatuses } = useSessionPendingStatuses(conversationId);
|
|
15111
14569
|
const showLiveDesktopApprovals = isStreamingMessage && !hasLaterStepsGroup && !!conversationId;
|
|
15112
14570
|
const desktopAccessStatus = useDesktopStatus(conversationId, { enabled: showLiveDesktopApprovals });
|
|
15113
|
-
const renderToolApprovals = showInlineToolApprovals && !!onToolApproval;
|
|
15114
|
-
const autoApprovedRef = useRef(/* @__PURE__ */ new Set());
|
|
15115
|
-
useEffect(() => {
|
|
15116
|
-
if (!renderToolApprovals || !onToolApproval) return;
|
|
15117
|
-
for (const item of toolItems) {
|
|
15118
|
-
if (!isApprovalRequested(item.part)) continue;
|
|
15119
|
-
const approvalId = getApprovalId(item.part);
|
|
15120
|
-
const toolName = getToolName(item.part);
|
|
15121
|
-
if (approvalId && isToolAlwaysAllowed(toolName) && !autoApprovedRef.current.has(approvalId)) {
|
|
15122
|
-
autoApprovedRef.current.add(approvalId);
|
|
15123
|
-
void onToolApproval(approvalId, true).catch(() => {
|
|
15124
|
-
autoApprovedRef.current.delete(approvalId);
|
|
15125
|
-
});
|
|
15126
|
-
}
|
|
15127
|
-
}
|
|
15128
|
-
}, [toolItems, onToolApproval, renderToolApprovals]);
|
|
15129
14571
|
const seenInstalls = /* @__PURE__ */ new Set();
|
|
15130
14572
|
const seenPendingCalls = /* @__PURE__ */ new Set();
|
|
15131
14573
|
const seenDesktopRequests = /* @__PURE__ */ new Set();
|
|
@@ -15137,23 +14579,6 @@ function MessageDecisionCards({
|
|
|
15137
14579
|
seenRoutines.add(signal.routineId);
|
|
15138
14580
|
return /* @__PURE__ */ jsx(AgentRoutineDraftCard, { ...signal }, `${messageId}-routine-${signal.routineId}`);
|
|
15139
14581
|
}),
|
|
15140
|
-
renderToolApprovals && onToolApproval && toolItems.map((item) => {
|
|
15141
|
-
if (!isApprovalRequested(item.part)) return null;
|
|
15142
|
-
if (isRequestHumanTool(getToolName(item.part))) return null;
|
|
15143
|
-
const aid = getApprovalId(item.part);
|
|
15144
|
-
if (!aid || autoApprovedRef.current.has(aid)) return null;
|
|
15145
|
-
return /* @__PURE__ */ jsx(
|
|
15146
|
-
ToolApprovalCard,
|
|
15147
|
-
{
|
|
15148
|
-
part: item.part,
|
|
15149
|
-
conversationId,
|
|
15150
|
-
onApprove: (id) => onToolApproval(id, true),
|
|
15151
|
-
onDeny: (id) => onToolApproval(id, false),
|
|
15152
|
-
onAlwaysAllow: (toolName) => addAlwaysAllowedTool(toolName)
|
|
15153
|
-
},
|
|
15154
|
-
`${messageId}-approval-${item.index}`
|
|
15155
|
-
);
|
|
15156
|
-
}),
|
|
15157
14582
|
toolItems.map((item) => {
|
|
15158
14583
|
const nc = getNeedsConnect(item.part);
|
|
15159
14584
|
if (!nc?.pendingToolCallId || !nc.installId || !nc.capabilityId) return null;
|
|
@@ -16002,113 +15427,527 @@ function ChatImageLightbox({
|
|
|
16002
15427
|
}
|
|
16003
15428
|
);
|
|
16004
15429
|
}
|
|
16005
|
-
function getHost(url) {
|
|
16006
|
-
try {
|
|
16007
|
-
return new URL(url).hostname.replace(/^www\./, "");
|
|
16008
|
-
} catch {
|
|
16009
|
-
return "source";
|
|
16010
|
-
}
|
|
15430
|
+
function getHost(url) {
|
|
15431
|
+
try {
|
|
15432
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
15433
|
+
} catch {
|
|
15434
|
+
return "source";
|
|
15435
|
+
}
|
|
15436
|
+
}
|
|
15437
|
+
function getImageView(image, failedImageUrls) {
|
|
15438
|
+
const linkUrl = image.sourceUrl ?? image.url;
|
|
15439
|
+
const label = image.title ?? image.sourceName ?? getHost(linkUrl);
|
|
15440
|
+
const imageUrl = image.thumbnailUrl && !failedImageUrls.has(image.thumbnailUrl) ? image.thumbnailUrl : !failedImageUrls.has(image.url) ? image.url : null;
|
|
15441
|
+
if (!imageUrl) return null;
|
|
15442
|
+
return {
|
|
15443
|
+
image,
|
|
15444
|
+
imageUrl,
|
|
15445
|
+
fullImageUrl: failedImageUrls.has(image.url) ? imageUrl : image.url,
|
|
15446
|
+
label
|
|
15447
|
+
};
|
|
15448
|
+
}
|
|
15449
|
+
function ImageResultsGallery({
|
|
15450
|
+
images,
|
|
15451
|
+
className,
|
|
15452
|
+
label = "Image results",
|
|
15453
|
+
size = "regular"
|
|
15454
|
+
}) {
|
|
15455
|
+
const [selectedIndex, setSelectedIndex] = useState(null);
|
|
15456
|
+
const [failedImageUrls, setFailedImageUrls] = useState(() => /* @__PURE__ */ new Set());
|
|
15457
|
+
const visible = images.slice(0, 6);
|
|
15458
|
+
const imageViews = visible.flatMap((image) => {
|
|
15459
|
+
const imageView = getImageView(image, failedImageUrls);
|
|
15460
|
+
return imageView ? [imageView] : [];
|
|
15461
|
+
});
|
|
15462
|
+
const lightboxItems = imageViews.map((view, index) => ({
|
|
15463
|
+
kind: "remote",
|
|
15464
|
+
id: `image-result-${index}-${view.image.url}`,
|
|
15465
|
+
title: view.label,
|
|
15466
|
+
imageUrl: view.fullImageUrl,
|
|
15467
|
+
thumbnailUrl: view.imageUrl
|
|
15468
|
+
}));
|
|
15469
|
+
const selectedId = selectedIndex === null ? null : lightboxItems[selectedIndex]?.id ?? null;
|
|
15470
|
+
const isCompact = size === "compact";
|
|
15471
|
+
if (imageViews.length === 0) return null;
|
|
15472
|
+
function markImageFailed(url) {
|
|
15473
|
+
setFailedImageUrls((current2) => {
|
|
15474
|
+
if (current2.has(url)) return current2;
|
|
15475
|
+
const next = new Set(current2);
|
|
15476
|
+
next.add(url);
|
|
15477
|
+
return next;
|
|
15478
|
+
});
|
|
15479
|
+
}
|
|
15480
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("not-prose mt-3 mb-5", className), children: [
|
|
15481
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2 text-xs font-medium text-muted-foreground", children: [
|
|
15482
|
+
/* @__PURE__ */ jsx(Images1Icon, { className: "size-3.5" }),
|
|
15483
|
+
/* @__PURE__ */ jsx("span", { children: label })
|
|
15484
|
+
] }),
|
|
15485
|
+
/* @__PURE__ */ jsx(
|
|
15486
|
+
"div",
|
|
15487
|
+
{
|
|
15488
|
+
className: cn(
|
|
15489
|
+
"grid gap-2",
|
|
15490
|
+
isCompact ? "grid-cols-[repeat(auto-fill,minmax(112px,160px))]" : "grid-cols-2 md:grid-cols-3"
|
|
15491
|
+
),
|
|
15492
|
+
children: imageViews.map(({ image, imageUrl, label: imageLabel }, index) => /* @__PURE__ */ jsx(
|
|
15493
|
+
"button",
|
|
15494
|
+
{
|
|
15495
|
+
type: "button",
|
|
15496
|
+
"aria-label": `Preview image: ${imageLabel}`,
|
|
15497
|
+
onClick: (event) => {
|
|
15498
|
+
event.stopPropagation();
|
|
15499
|
+
setSelectedIndex(index);
|
|
15500
|
+
},
|
|
15501
|
+
className: cn(
|
|
15502
|
+
"group/image-result cursor-pointer overflow-hidden border border-border bg-surface-raised text-left text-foreground transition-colors hover:border-primary/50 hover:bg-surface-raised-hover focus-visible:border-ring focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
15503
|
+
isCompact ? "rounded-md" : "rounded-lg"
|
|
15504
|
+
),
|
|
15505
|
+
children: /* @__PURE__ */ jsx("div", { className: "aspect-[4/3] overflow-hidden bg-surface-inset", children: /* @__PURE__ */ jsx(
|
|
15506
|
+
"img",
|
|
15507
|
+
{
|
|
15508
|
+
src: imageUrl,
|
|
15509
|
+
alt: imageLabel,
|
|
15510
|
+
loading: "lazy",
|
|
15511
|
+
onError: () => markImageFailed(imageUrl),
|
|
15512
|
+
className: "image-checker h-full w-full object-cover transition-transform [--image-checker-tile:8px] group-hover/image-result:scale-[1.02]"
|
|
15513
|
+
}
|
|
15514
|
+
) })
|
|
15515
|
+
},
|
|
15516
|
+
`${image.url}-${index}`
|
|
15517
|
+
))
|
|
15518
|
+
}
|
|
15519
|
+
),
|
|
15520
|
+
/* @__PURE__ */ jsx(
|
|
15521
|
+
ChatImageLightbox,
|
|
15522
|
+
{
|
|
15523
|
+
items: lightboxItems,
|
|
15524
|
+
selectedId,
|
|
15525
|
+
onSelectedIdChange: (id) => {
|
|
15526
|
+
if (id === null) {
|
|
15527
|
+
setSelectedIndex(null);
|
|
15528
|
+
return;
|
|
15529
|
+
}
|
|
15530
|
+
const index = lightboxItems.findIndex((item) => item.id === id);
|
|
15531
|
+
setSelectedIndex(index >= 0 ? index : null);
|
|
15532
|
+
},
|
|
15533
|
+
onRemoteImageError: markImageFailed
|
|
15534
|
+
}
|
|
15535
|
+
)
|
|
15536
|
+
] });
|
|
15537
|
+
}
|
|
15538
|
+
var DOMAIN7 = "conversation-desktop";
|
|
15539
|
+
var conversationDesktopKeys = {
|
|
15540
|
+
all: [DOMAIN7],
|
|
15541
|
+
status: (conversationId) => [DOMAIN7, "status", conversationId]
|
|
15542
|
+
};
|
|
15543
|
+
function conversationDesktop(client, conversationId) {
|
|
15544
|
+
return client.v1.conversations({ conversationId });
|
|
15545
|
+
}
|
|
15546
|
+
async function fetchDesktopStatus(client, conversationId, signal) {
|
|
15547
|
+
const { data, error } = await conversationDesktop(client, conversationId).desktop.get({
|
|
15548
|
+
fetch: { signal }
|
|
15549
|
+
});
|
|
15550
|
+
if (error) throw error;
|
|
15551
|
+
return unwrapData(data);
|
|
15552
|
+
}
|
|
15553
|
+
async function fetchDesktopScreenshot(client, conversationId, maxDim, signal) {
|
|
15554
|
+
const res = await conversationDesktop(client, conversationId).desktop.screenshot.get({
|
|
15555
|
+
query: { maxDim: String(maxDim) },
|
|
15556
|
+
fetch: { signal }
|
|
15557
|
+
});
|
|
15558
|
+
if (res.error) {
|
|
15559
|
+
const status = res.error.status;
|
|
15560
|
+
const value = res.error.value;
|
|
15561
|
+
if (status === 503 || isWakingBody(value) || isWakingBody(res.data)) {
|
|
15562
|
+
return { ok: false, waking: true };
|
|
15563
|
+
}
|
|
15564
|
+
throw res.error;
|
|
15565
|
+
}
|
|
15566
|
+
const payload = res.data;
|
|
15567
|
+
if (isWakingBody(payload)) return { ok: false, waking: true };
|
|
15568
|
+
const blob = desktopScreenshotBlob(payload);
|
|
15569
|
+
return { ok: true, blob };
|
|
15570
|
+
}
|
|
15571
|
+
function isWakingBody(value) {
|
|
15572
|
+
return Boolean(
|
|
15573
|
+
value && typeof value === "object" && "waking" in value && value.waking === true
|
|
15574
|
+
);
|
|
15575
|
+
}
|
|
15576
|
+
function desktopScreenshotBlob(payload) {
|
|
15577
|
+
if (payload instanceof Blob) return payload;
|
|
15578
|
+
if (payload instanceof ArrayBuffer) {
|
|
15579
|
+
return new Blob([payload], { type: "image/png" });
|
|
15580
|
+
}
|
|
15581
|
+
if (ArrayBuffer.isView(payload)) {
|
|
15582
|
+
const view = payload;
|
|
15583
|
+
const copy3 = new Uint8Array(view.byteLength);
|
|
15584
|
+
copy3.set(new Uint8Array(view.buffer, view.byteOffset, view.byteLength));
|
|
15585
|
+
return new Blob([copy3], { type: "image/png" });
|
|
15586
|
+
}
|
|
15587
|
+
throw new Error("Desktop screenshot was not an image");
|
|
15588
|
+
}
|
|
15589
|
+
function useConversationDesktopStatus(conversationId) {
|
|
15590
|
+
const client = useClient();
|
|
15591
|
+
return useQuery({
|
|
15592
|
+
queryKey: conversationDesktopKeys.status(conversationId ?? ""),
|
|
15593
|
+
queryFn: () => fetchDesktopStatus(client, conversationId),
|
|
15594
|
+
enabled: !!conversationId,
|
|
15595
|
+
staleTime: Infinity,
|
|
15596
|
+
gcTime: 5 * 60 * 1e3,
|
|
15597
|
+
retry: false,
|
|
15598
|
+
refetchOnWindowFocus: false,
|
|
15599
|
+
refetchOnReconnect: false
|
|
15600
|
+
});
|
|
15601
|
+
}
|
|
15602
|
+
var useDesktopScreenStore = create((set2, get3) => ({
|
|
15603
|
+
openConversationId: null,
|
|
15604
|
+
lightboxOpen: false,
|
|
15605
|
+
agentDisplayName: null,
|
|
15606
|
+
open: (conversationId) => set2({ openConversationId: conversationId, lightboxOpen: false }),
|
|
15607
|
+
close: () => set2({ openConversationId: null, lightboxOpen: false }),
|
|
15608
|
+
toggle: (conversationId) => {
|
|
15609
|
+
if (get3().openConversationId === conversationId) {
|
|
15610
|
+
set2({ openConversationId: null, lightboxOpen: false });
|
|
15611
|
+
return;
|
|
15612
|
+
}
|
|
15613
|
+
set2({ openConversationId: conversationId, lightboxOpen: false });
|
|
15614
|
+
},
|
|
15615
|
+
setLightboxOpen: (lightboxOpen) => set2({ lightboxOpen }),
|
|
15616
|
+
setAgentDisplayName: (agentDisplayName) => set2({ agentDisplayName })
|
|
15617
|
+
}));
|
|
15618
|
+
function DesktopScreenThumbnail({
|
|
15619
|
+
imageUrl,
|
|
15620
|
+
state,
|
|
15621
|
+
onOpen
|
|
15622
|
+
}) {
|
|
15623
|
+
const { t } = useTranslation();
|
|
15624
|
+
const agentDisplayName = useDesktopScreenStore((s2) => s2.agentDisplayName);
|
|
15625
|
+
const caption = agentDisplayName ? t("chat.desktop.agentsScreen", { name: agentDisplayName }) : null;
|
|
15626
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
15627
|
+
/* @__PURE__ */ jsxs("div", { className: "group relative aspect-video overflow-hidden rounded-xl", children: [
|
|
15628
|
+
imageUrl ? (
|
|
15629
|
+
// eslint-disable-next-line @next/next/no-img-element -- blob: screenshot URLs
|
|
15630
|
+
/* @__PURE__ */ jsx(
|
|
15631
|
+
"img",
|
|
15632
|
+
{
|
|
15633
|
+
src: imageUrl,
|
|
15634
|
+
alt: caption ?? t("chat.desktop.screen"),
|
|
15635
|
+
className: "absolute inset-0 size-full object-cover"
|
|
15636
|
+
}
|
|
15637
|
+
)
|
|
15638
|
+
) : /* @__PURE__ */ jsx(Skeleton, { className: "absolute inset-0 size-full rounded-none" }),
|
|
15639
|
+
/* @__PURE__ */ jsx(
|
|
15640
|
+
"div",
|
|
15641
|
+
{
|
|
15642
|
+
className: cn(
|
|
15643
|
+
"absolute inset-0 flex items-center justify-center bg-scrim/30 opacity-0 transition-opacity duration-150 group-hover:opacity-100",
|
|
15644
|
+
"focus-within:opacity-100"
|
|
15645
|
+
),
|
|
15646
|
+
children: /* @__PURE__ */ jsx(
|
|
15647
|
+
Button,
|
|
15648
|
+
{
|
|
15649
|
+
type: "button",
|
|
15650
|
+
variant: "default-neutral",
|
|
15651
|
+
size: "sm",
|
|
15652
|
+
className: "rounded-full px-4",
|
|
15653
|
+
onClick: onOpen,
|
|
15654
|
+
children: t("chat.desktop.open")
|
|
15655
|
+
}
|
|
15656
|
+
)
|
|
15657
|
+
}
|
|
15658
|
+
),
|
|
15659
|
+
state === "off" && !imageUrl ? /* @__PURE__ */ jsx("span", { className: "sr-only", children: t("chat.desktop.asleep") }) : null
|
|
15660
|
+
] }),
|
|
15661
|
+
caption ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-center text-xs text-muted-foreground", children: caption }) : null
|
|
15662
|
+
] });
|
|
15663
|
+
}
|
|
15664
|
+
|
|
15665
|
+
// src/vendor/ui/chat/desktop-screen-panel/types.ts
|
|
15666
|
+
var DESKTOP_SCREEN_POLL_MS = 2500;
|
|
15667
|
+
var DESKTOP_THUMBNAIL_MAX_DIM = 640;
|
|
15668
|
+
|
|
15669
|
+
// src/vendor/ui/chat/desktop-screen-panel/hooks/use-desktop-screen-poll.ts
|
|
15670
|
+
function tabIsVisible() {
|
|
15671
|
+
if (typeof document === "undefined") return true;
|
|
15672
|
+
return document.visibilityState === "visible";
|
|
15673
|
+
}
|
|
15674
|
+
function useDesktopScreenPoll({
|
|
15675
|
+
conversationId,
|
|
15676
|
+
open,
|
|
15677
|
+
maxDim,
|
|
15678
|
+
fetchers,
|
|
15679
|
+
pollIntervalMs = DESKTOP_SCREEN_POLL_MS
|
|
15680
|
+
}) {
|
|
15681
|
+
const [state, setState] = useState("off");
|
|
15682
|
+
const [imageUrl, setImageUrl] = useState(null);
|
|
15683
|
+
const [reconnecting, setReconnecting] = useState(false);
|
|
15684
|
+
const [display, setDisplay] = useState();
|
|
15685
|
+
const [detail, setDetail] = useState();
|
|
15686
|
+
const imageUrlRef = useRef(null);
|
|
15687
|
+
const fetchersRef = useRef(fetchers);
|
|
15688
|
+
fetchersRef.current = fetchers;
|
|
15689
|
+
useEffect(() => {
|
|
15690
|
+
imageUrlRef.current = imageUrl;
|
|
15691
|
+
}, [imageUrl]);
|
|
15692
|
+
useEffect(() => {
|
|
15693
|
+
if (!open) {
|
|
15694
|
+
setState("off");
|
|
15695
|
+
setReconnecting(false);
|
|
15696
|
+
setDisplay(void 0);
|
|
15697
|
+
const previous = imageUrlRef.current;
|
|
15698
|
+
if (previous) {
|
|
15699
|
+
URL.revokeObjectURL(previous);
|
|
15700
|
+
imageUrlRef.current = null;
|
|
15701
|
+
setImageUrl(null);
|
|
15702
|
+
}
|
|
15703
|
+
}
|
|
15704
|
+
}, [open]);
|
|
15705
|
+
useEffect(() => {
|
|
15706
|
+
if (!open || !conversationId) return;
|
|
15707
|
+
let cancelled2 = false;
|
|
15708
|
+
let inFlight = false;
|
|
15709
|
+
const controller = new AbortController();
|
|
15710
|
+
const tick = async () => {
|
|
15711
|
+
if (cancelled2 || inFlight || !tabIsVisible()) return;
|
|
15712
|
+
inFlight = true;
|
|
15713
|
+
try {
|
|
15714
|
+
const status = await fetchersRef.current.fetchStatus(
|
|
15715
|
+
conversationId,
|
|
15716
|
+
controller.signal
|
|
15717
|
+
);
|
|
15718
|
+
if (cancelled2) return;
|
|
15719
|
+
setDisplay(status.display);
|
|
15720
|
+
setDetail(status.detail);
|
|
15721
|
+
if (!status.enabled) {
|
|
15722
|
+
setState("off");
|
|
15723
|
+
setReconnecting(false);
|
|
15724
|
+
return;
|
|
15725
|
+
}
|
|
15726
|
+
if (status.state === "unavailable" || status.state === "upgradable") {
|
|
15727
|
+
setState(status.state);
|
|
15728
|
+
setReconnecting(false);
|
|
15729
|
+
return;
|
|
15730
|
+
}
|
|
15731
|
+
const shot = await fetchersRef.current.fetchScreenshot(
|
|
15732
|
+
conversationId,
|
|
15733
|
+
maxDim,
|
|
15734
|
+
controller.signal
|
|
15735
|
+
);
|
|
15736
|
+
if (cancelled2) return;
|
|
15737
|
+
if (!shot.ok) {
|
|
15738
|
+
setState("waking");
|
|
15739
|
+
setReconnecting(false);
|
|
15740
|
+
return;
|
|
15741
|
+
}
|
|
15742
|
+
const nextUrl = URL.createObjectURL(shot.blob);
|
|
15743
|
+
const previous = imageUrlRef.current;
|
|
15744
|
+
imageUrlRef.current = nextUrl;
|
|
15745
|
+
setImageUrl(nextUrl);
|
|
15746
|
+
if (previous) URL.revokeObjectURL(previous);
|
|
15747
|
+
setState("live");
|
|
15748
|
+
setReconnecting(false);
|
|
15749
|
+
} catch (error) {
|
|
15750
|
+
if (cancelled2) return;
|
|
15751
|
+
if (controller.signal.aborted) return;
|
|
15752
|
+
if (error instanceof DOMException && error.name === "AbortError") return;
|
|
15753
|
+
if (imageUrlRef.current) {
|
|
15754
|
+
setReconnecting(true);
|
|
15755
|
+
} else {
|
|
15756
|
+
setState("off");
|
|
15757
|
+
}
|
|
15758
|
+
} finally {
|
|
15759
|
+
inFlight = false;
|
|
15760
|
+
}
|
|
15761
|
+
};
|
|
15762
|
+
const onVisibility = () => {
|
|
15763
|
+
if (tabIsVisible()) void tick();
|
|
15764
|
+
};
|
|
15765
|
+
void tick();
|
|
15766
|
+
const interval = setInterval(() => {
|
|
15767
|
+
void tick();
|
|
15768
|
+
}, pollIntervalMs);
|
|
15769
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
15770
|
+
return () => {
|
|
15771
|
+
cancelled2 = true;
|
|
15772
|
+
controller.abort();
|
|
15773
|
+
clearInterval(interval);
|
|
15774
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
15775
|
+
};
|
|
15776
|
+
}, [open, conversationId, maxDim, pollIntervalMs]);
|
|
15777
|
+
useEffect(() => {
|
|
15778
|
+
return () => {
|
|
15779
|
+
const previous = imageUrlRef.current;
|
|
15780
|
+
if (previous) URL.revokeObjectURL(previous);
|
|
15781
|
+
};
|
|
15782
|
+
}, []);
|
|
15783
|
+
return { state, imageUrl, reconnecting, display, detail };
|
|
15784
|
+
}
|
|
15785
|
+
var CARD_POLL_MS = 5e3;
|
|
15786
|
+
function RequestHumanApprovalCard({
|
|
15787
|
+
conversationId,
|
|
15788
|
+
title,
|
|
15789
|
+
phase,
|
|
15790
|
+
onApprove,
|
|
15791
|
+
onDeny
|
|
15792
|
+
}) {
|
|
15793
|
+
const { t } = useTranslation();
|
|
15794
|
+
const client = useClient();
|
|
15795
|
+
const desktop = useConversationDesktopStatus(conversationId);
|
|
15796
|
+
const setLightboxOpen = useDesktopScreenStore((s2) => s2.setLightboxOpen);
|
|
15797
|
+
const openPanel = useDesktopScreenStore((s2) => s2.open);
|
|
15798
|
+
const fetchers = useMemo(
|
|
15799
|
+
() => ({
|
|
15800
|
+
fetchStatus: (id, signal) => fetchDesktopStatus(client, id, signal),
|
|
15801
|
+
fetchScreenshot: (id, maxDim, signal) => fetchDesktopScreenshot(client, id, maxDim, signal)
|
|
15802
|
+
}),
|
|
15803
|
+
[client]
|
|
15804
|
+
);
|
|
15805
|
+
const poll = useDesktopScreenPoll({
|
|
15806
|
+
conversationId,
|
|
15807
|
+
open: phase === "pending" && !!conversationId && desktop.data?.enabled === true,
|
|
15808
|
+
maxDim: DESKTOP_THUMBNAIL_MAX_DIM,
|
|
15809
|
+
fetchers,
|
|
15810
|
+
pollIntervalMs: CARD_POLL_MS
|
|
15811
|
+
});
|
|
15812
|
+
const heading = t("chat.desktop.computer");
|
|
15813
|
+
const badge = phase === "pending" ? {
|
|
15814
|
+
label: t("chat.desktop.actionNeeded"),
|
|
15815
|
+
className: "bg-warning/10 text-warning"} : phase === "done" ? {
|
|
15816
|
+
label: t("chat.desktop.done"),
|
|
15817
|
+
className: "bg-success/10 text-success"} : {
|
|
15818
|
+
label: t("chat.desktop.skipped"),
|
|
15819
|
+
className: "bg-surface-inset text-muted-foreground"};
|
|
15820
|
+
if (phase !== "pending") {
|
|
15821
|
+
return /* @__PURE__ */ jsxs(
|
|
15822
|
+
"div",
|
|
15823
|
+
{
|
|
15824
|
+
"data-slot": "request-human-approval-card",
|
|
15825
|
+
"data-phase": phase,
|
|
15826
|
+
className: "relative my-2 flex items-center gap-2 rounded-xl border border-border bg-surface px-4 py-2",
|
|
15827
|
+
children: [
|
|
15828
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-sm font-semibold text-foreground", children: heading }),
|
|
15829
|
+
/* @__PURE__ */ jsx(
|
|
15830
|
+
"span",
|
|
15831
|
+
{
|
|
15832
|
+
className: cn(
|
|
15833
|
+
"shrink-0 rounded-full px-2 py-0.5 text-xs font-medium",
|
|
15834
|
+
badge.className
|
|
15835
|
+
),
|
|
15836
|
+
children: badge.label
|
|
15837
|
+
}
|
|
15838
|
+
),
|
|
15839
|
+
title ? /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: title }) : /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1" }),
|
|
15840
|
+
/* @__PURE__ */ jsxs(
|
|
15841
|
+
Button,
|
|
15842
|
+
{
|
|
15843
|
+
type: "button",
|
|
15844
|
+
variant: "outline",
|
|
15845
|
+
size: "sm",
|
|
15846
|
+
className: "shrink-0",
|
|
15847
|
+
onClick: () => {
|
|
15848
|
+
if (conversationId) openPanel(conversationId);
|
|
15849
|
+
setLightboxOpen(true);
|
|
15850
|
+
},
|
|
15851
|
+
children: [
|
|
15852
|
+
/* @__PURE__ */ jsx(DeviceDesktopIcon, { className: "size-3.5" }),
|
|
15853
|
+
t("chat.desktop.openComputer")
|
|
15854
|
+
]
|
|
15855
|
+
}
|
|
15856
|
+
)
|
|
15857
|
+
]
|
|
15858
|
+
}
|
|
15859
|
+
);
|
|
15860
|
+
}
|
|
15861
|
+
return /* @__PURE__ */ jsxs(
|
|
15862
|
+
"div",
|
|
15863
|
+
{
|
|
15864
|
+
"data-slot": "request-human-approval-card",
|
|
15865
|
+
"data-phase": phase,
|
|
15866
|
+
className: "relative my-2 rounded-xl border border-border bg-surface p-4",
|
|
15867
|
+
children: [
|
|
15868
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2", children: [
|
|
15869
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground", children: heading }),
|
|
15870
|
+
/* @__PURE__ */ jsxs(
|
|
15871
|
+
"span",
|
|
15872
|
+
{
|
|
15873
|
+
className: cn(
|
|
15874
|
+
"ml-auto inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium",
|
|
15875
|
+
badge.className
|
|
15876
|
+
),
|
|
15877
|
+
children: [
|
|
15878
|
+
/* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-warning animate-pulse", "aria-hidden": true }),
|
|
15879
|
+
badge.label
|
|
15880
|
+
]
|
|
15881
|
+
}
|
|
15882
|
+
)
|
|
15883
|
+
] }),
|
|
15884
|
+
title ? /* @__PURE__ */ jsx("p", { className: "mb-2 truncate text-sm text-foreground", children: title }) : null,
|
|
15885
|
+
/* @__PURE__ */ jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsx(
|
|
15886
|
+
DesktopScreenThumbnail,
|
|
15887
|
+
{
|
|
15888
|
+
imageUrl: poll.imageUrl,
|
|
15889
|
+
state: poll.state,
|
|
15890
|
+
onOpen: () => setLightboxOpen(true)
|
|
15891
|
+
}
|
|
15892
|
+
) }),
|
|
15893
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
15894
|
+
/* @__PURE__ */ jsx(
|
|
15895
|
+
Button,
|
|
15896
|
+
{
|
|
15897
|
+
type: "button",
|
|
15898
|
+
variant: "default",
|
|
15899
|
+
onClick: () => setLightboxOpen(true),
|
|
15900
|
+
children: t("chat.desktop.takeOver")
|
|
15901
|
+
}
|
|
15902
|
+
),
|
|
15903
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", onClick: onApprove, children: t("chat.desktop.imDone") }),
|
|
15904
|
+
/* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", className: "ml-auto", onClick: onDeny, children: t("chat.desktop.skip") })
|
|
15905
|
+
] })
|
|
15906
|
+
]
|
|
15907
|
+
}
|
|
15908
|
+
);
|
|
15909
|
+
}
|
|
15910
|
+
|
|
15911
|
+
// src/vendor/ui/chat/request-human-approval-card/utils.ts
|
|
15912
|
+
var REQUEST_HUMAN_TOOL = "request_human";
|
|
15913
|
+
function isRequestHumanTool(name) {
|
|
15914
|
+
return name === REQUEST_HUMAN_TOOL;
|
|
16011
15915
|
}
|
|
16012
|
-
function
|
|
16013
|
-
|
|
16014
|
-
|
|
16015
|
-
|
|
16016
|
-
|
|
16017
|
-
|
|
16018
|
-
|
|
16019
|
-
|
|
16020
|
-
|
|
16021
|
-
label
|
|
16022
|
-
};
|
|
15916
|
+
function requestHumanTitle(input, fallback = "") {
|
|
15917
|
+
if (input && typeof input === "object") {
|
|
15918
|
+
const record = input;
|
|
15919
|
+
for (const key of ["title", "message", "reason", "prompt"]) {
|
|
15920
|
+
const value = record[key];
|
|
15921
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
15922
|
+
}
|
|
15923
|
+
}
|
|
15924
|
+
return fallback;
|
|
16023
15925
|
}
|
|
16024
|
-
function
|
|
16025
|
-
|
|
16026
|
-
|
|
16027
|
-
|
|
16028
|
-
|
|
16029
|
-
|
|
16030
|
-
|
|
16031
|
-
const [failedImageUrls, setFailedImageUrls] = useState(() => /* @__PURE__ */ new Set());
|
|
16032
|
-
const visible = images.slice(0, 6);
|
|
16033
|
-
const imageViews = visible.flatMap((image) => {
|
|
16034
|
-
const imageView = getImageView(image, failedImageUrls);
|
|
16035
|
-
return imageView ? [imageView] : [];
|
|
16036
|
-
});
|
|
16037
|
-
const lightboxItems = imageViews.map((view, index) => ({
|
|
16038
|
-
kind: "remote",
|
|
16039
|
-
id: `image-result-${index}-${view.image.url}`,
|
|
16040
|
-
title: view.label,
|
|
16041
|
-
imageUrl: view.fullImageUrl,
|
|
16042
|
-
thumbnailUrl: view.imageUrl
|
|
16043
|
-
}));
|
|
16044
|
-
const selectedId = selectedIndex === null ? null : lightboxItems[selectedIndex]?.id ?? null;
|
|
16045
|
-
const isCompact = size === "compact";
|
|
16046
|
-
if (imageViews.length === 0) return null;
|
|
16047
|
-
function markImageFailed(url) {
|
|
16048
|
-
setFailedImageUrls((current2) => {
|
|
16049
|
-
if (current2.has(url)) return current2;
|
|
16050
|
-
const next = new Set(current2);
|
|
16051
|
-
next.add(url);
|
|
16052
|
-
return next;
|
|
16053
|
-
});
|
|
15926
|
+
function requestHumanPhaseFromPart(part) {
|
|
15927
|
+
const state = typeof part.state === "string" ? part.state : "";
|
|
15928
|
+
if (state === "approval-requested") return "pending";
|
|
15929
|
+
const approval = part.approval;
|
|
15930
|
+
if (approval && approval.approved === false) return "skipped";
|
|
15931
|
+
if (state === "output-error" || state === "output-denied" || typeof part.errorText === "string") {
|
|
15932
|
+
return "skipped";
|
|
16054
15933
|
}
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
|
|
16058
|
-
|
|
16059
|
-
|
|
16060
|
-
|
|
16061
|
-
|
|
16062
|
-
|
|
16063
|
-
|
|
16064
|
-
|
|
16065
|
-
|
|
16066
|
-
|
|
16067
|
-
|
|
16068
|
-
|
|
16069
|
-
|
|
16070
|
-
|
|
16071
|
-
|
|
16072
|
-
onClick: (event) => {
|
|
16073
|
-
event.stopPropagation();
|
|
16074
|
-
setSelectedIndex(index);
|
|
16075
|
-
},
|
|
16076
|
-
className: cn(
|
|
16077
|
-
"group/image-result cursor-pointer overflow-hidden border border-border bg-surface-raised text-left text-foreground transition-colors hover:border-primary/50 hover:bg-surface-raised-hover focus-visible:border-ring focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
16078
|
-
isCompact ? "rounded-md" : "rounded-lg"
|
|
16079
|
-
),
|
|
16080
|
-
children: /* @__PURE__ */ jsx("div", { className: "aspect-[4/3] overflow-hidden bg-surface-inset", children: /* @__PURE__ */ jsx(
|
|
16081
|
-
"img",
|
|
16082
|
-
{
|
|
16083
|
-
src: imageUrl,
|
|
16084
|
-
alt: imageLabel,
|
|
16085
|
-
loading: "lazy",
|
|
16086
|
-
onError: () => markImageFailed(imageUrl),
|
|
16087
|
-
className: "image-checker h-full w-full object-cover transition-transform [--image-checker-tile:8px] group-hover/image-result:scale-[1.02]"
|
|
16088
|
-
}
|
|
16089
|
-
) })
|
|
16090
|
-
},
|
|
16091
|
-
`${image.url}-${index}`
|
|
16092
|
-
))
|
|
16093
|
-
}
|
|
16094
|
-
),
|
|
16095
|
-
/* @__PURE__ */ jsx(
|
|
16096
|
-
ChatImageLightbox,
|
|
16097
|
-
{
|
|
16098
|
-
items: lightboxItems,
|
|
16099
|
-
selectedId,
|
|
16100
|
-
onSelectedIdChange: (id) => {
|
|
16101
|
-
if (id === null) {
|
|
16102
|
-
setSelectedIndex(null);
|
|
16103
|
-
return;
|
|
16104
|
-
}
|
|
16105
|
-
const index = lightboxItems.findIndex((item) => item.id === id);
|
|
16106
|
-
setSelectedIndex(index >= 0 ? index : null);
|
|
16107
|
-
},
|
|
16108
|
-
onRemoteImageError: markImageFailed
|
|
16109
|
-
}
|
|
16110
|
-
)
|
|
16111
|
-
] });
|
|
15934
|
+
const output = part.output ?? part.result;
|
|
15935
|
+
if (output && typeof output === "object") {
|
|
15936
|
+
const record = output;
|
|
15937
|
+
if (record.skipped === true || record.denied === true || record.approved === false) {
|
|
15938
|
+
return "skipped";
|
|
15939
|
+
}
|
|
15940
|
+
}
|
|
15941
|
+
if (state === "output-available" || state === "result" || output != null) return "done";
|
|
15942
|
+
if (state === "input-available" || state === "input-streaming" || state === "call" || state === "partial-call") {
|
|
15943
|
+
return "pending";
|
|
15944
|
+
}
|
|
15945
|
+
return "done";
|
|
15946
|
+
}
|
|
15947
|
+
function requestHumanThreadPhase(part, pendingStatus) {
|
|
15948
|
+
if (pendingStatus === "pending") return "pending";
|
|
15949
|
+
if (pendingStatus === "abandoned") return "skipped";
|
|
15950
|
+
return requestHumanPhaseFromPart(part);
|
|
16112
15951
|
}
|
|
16113
15952
|
function GridSpinner({ className, ...props }) {
|
|
16114
15953
|
return /* @__PURE__ */ jsxs(
|
|
@@ -17085,7 +16924,6 @@ var MessageStepsGroup = memo(function MessageStepsGroup2({
|
|
|
17085
16924
|
isStreamingMessage,
|
|
17086
16925
|
hasLaterStepsGroup = false,
|
|
17087
16926
|
onToolApproval,
|
|
17088
|
-
showInlineToolApprovals = true,
|
|
17089
16927
|
conversationId,
|
|
17090
16928
|
hasResponseImageGroup = false
|
|
17091
16929
|
}) {
|
|
@@ -17173,21 +17011,6 @@ var MessageStepsGroup = memo(function MessageStepsGroup2({
|
|
|
17173
17011
|
const input = getToolInput(imageGenStep.part);
|
|
17174
17012
|
return input?.aspectRatio ? input.aspectRatio.replace(":", " / ") : "1 / 1";
|
|
17175
17013
|
})();
|
|
17176
|
-
const autoApprovedRef = useRef(/* @__PURE__ */ new Set());
|
|
17177
|
-
useEffect(() => {
|
|
17178
|
-
if (!showInlineToolApprovals || !onToolApproval) return;
|
|
17179
|
-
for (const item of toolItems) {
|
|
17180
|
-
if (!isApprovalRequested(item.part)) continue;
|
|
17181
|
-
const approvalId = getApprovalId(item.part);
|
|
17182
|
-
const toolName = getToolName(item.part);
|
|
17183
|
-
if (approvalId && isToolAlwaysAllowed(toolName) && !autoApprovedRef.current.has(approvalId)) {
|
|
17184
|
-
autoApprovedRef.current.add(approvalId);
|
|
17185
|
-
void onToolApproval(approvalId, true).catch(() => {
|
|
17186
|
-
autoApprovedRef.current.delete(approvalId);
|
|
17187
|
-
});
|
|
17188
|
-
}
|
|
17189
|
-
}
|
|
17190
|
-
}, [toolItems, onToolApproval, showInlineToolApprovals]);
|
|
17191
17014
|
const AUTO_CLOSE_DELAY = 1e3;
|
|
17192
17015
|
const expandedByDefault = useChatOptInEnabled("expandedWorkDetails");
|
|
17193
17016
|
const [collapsed, setCollapsed] = useState(!expandedByDefault);
|
|
@@ -17294,34 +17117,6 @@ var MessageStepsGroup = memo(function MessageStepsGroup2({
|
|
|
17294
17117
|
);
|
|
17295
17118
|
}
|
|
17296
17119
|
if (isRequestHumanTool(getToolName(item.part))) return null;
|
|
17297
|
-
if (showInlineToolApprovals && isApprovalRequested(item.part) && onToolApproval) {
|
|
17298
|
-
const aid = getApprovalId(item.part);
|
|
17299
|
-
if (aid && autoApprovedRef.current.has(aid)) {
|
|
17300
|
-
return /* @__PURE__ */ jsx(
|
|
17301
|
-
ToolCallItem,
|
|
17302
|
-
{
|
|
17303
|
-
toolName: getToolName(item.part),
|
|
17304
|
-
state: "input-available",
|
|
17305
|
-
input: getToolInput(item.part),
|
|
17306
|
-
output: getToolOutput(item.part),
|
|
17307
|
-
errorText: getToolErrorText(item.part),
|
|
17308
|
-
isMcp: isMcpToolPart(item.part)
|
|
17309
|
-
},
|
|
17310
|
-
`${messageId}-tc-${item.index}`
|
|
17311
|
-
);
|
|
17312
|
-
}
|
|
17313
|
-
return /* @__PURE__ */ jsx(
|
|
17314
|
-
ToolApprovalCard,
|
|
17315
|
-
{
|
|
17316
|
-
part: item.part,
|
|
17317
|
-
conversationId,
|
|
17318
|
-
onApprove: (id) => onToolApproval(id, true),
|
|
17319
|
-
onDeny: (id) => onToolApproval(id, false),
|
|
17320
|
-
onAlwaysAllow: (toolName) => addAlwaysAllowedTool(toolName)
|
|
17321
|
-
},
|
|
17322
|
-
`${messageId}-approval-${item.index}`
|
|
17323
|
-
);
|
|
17324
|
-
}
|
|
17325
17120
|
if (getToolName(item.part) === "skill") {
|
|
17326
17121
|
return /* @__PURE__ */ jsx(
|
|
17327
17122
|
SkillToolItem,
|
|
@@ -17465,19 +17260,6 @@ var MessageStepsGroup = memo(function MessageStepsGroup2({
|
|
|
17465
17260
|
const partApprovalId = getApprovalId(item.part);
|
|
17466
17261
|
return partApprovalId != null && row.id === partApprovalId;
|
|
17467
17262
|
});
|
|
17468
|
-
if (showInlineToolApprovals && isApprovalRequested(item.part) && onToolApproval) {
|
|
17469
|
-
return /* @__PURE__ */ jsx(
|
|
17470
|
-
ToolApprovalCard,
|
|
17471
|
-
{
|
|
17472
|
-
part: item.part,
|
|
17473
|
-
conversationId,
|
|
17474
|
-
onApprove: (id) => onToolApproval(id, true),
|
|
17475
|
-
onDeny: (id) => onToolApproval(id, false),
|
|
17476
|
-
onAlwaysAllow: (toolName) => addAlwaysAllowedTool(toolName)
|
|
17477
|
-
},
|
|
17478
|
-
`${messageId}-approval-${item.index}`
|
|
17479
|
-
);
|
|
17480
|
-
}
|
|
17481
17263
|
const phase = requestHumanThreadPhase(item.part, pendingRow?.status);
|
|
17482
17264
|
if (phase === "pending" && !desktop.data?.enabled) return null;
|
|
17483
17265
|
const approvalId = pendingRow?.id ?? getApprovalId(item.part);
|