@pactor-app/chat 0.1.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1483 -600
- package/dist/index.d.cts +97 -23
- package/dist/index.d.ts +97 -23
- package/dist/index.js +1453 -600
- package/package.json +7 -8
- package/styles.css +188 -176
package/dist/index.js
CHANGED
|
@@ -653,20 +653,34 @@ function createChatRuntime(options = {}) {
|
|
|
653
653
|
}
|
|
654
654
|
|
|
655
655
|
// src/dsl-guard.ts
|
|
656
|
+
import { isDslSourceRef } from "@pactor-app/core";
|
|
656
657
|
var CHAT_DENIED_TYPE = "ChatDenied";
|
|
657
658
|
function guardChatDsl(node, registry) {
|
|
658
|
-
|
|
659
|
+
const type = node.type ?? "(reference)";
|
|
660
|
+
if (type !== CHAT_DENIED_TYPE && !registry.has(type)) {
|
|
659
661
|
return {
|
|
660
662
|
type: CHAT_DENIED_TYPE,
|
|
661
|
-
props: { deniedType:
|
|
663
|
+
props: { deniedType: type }
|
|
662
664
|
};
|
|
663
665
|
}
|
|
664
|
-
if (
|
|
666
|
+
if (node.children === void 0) {
|
|
667
|
+
return node;
|
|
668
|
+
}
|
|
669
|
+
if (!Array.isArray(node.children)) {
|
|
670
|
+
return {
|
|
671
|
+
type: CHAT_DENIED_TYPE,
|
|
672
|
+
props: { deniedType: `${type}(remote)` }
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
if (node.children.length === 0) {
|
|
665
676
|
return node;
|
|
666
677
|
}
|
|
667
678
|
return {
|
|
668
679
|
...node,
|
|
669
|
-
|
|
680
|
+
// 数组中混排的引用元素同样无法静态过白名单:替换为受控占位
|
|
681
|
+
children: node.children.map(
|
|
682
|
+
(child) => isDslSourceRef(child) ? { type: CHAT_DENIED_TYPE, props: { deniedType: "(remote)" } } : guardChatDsl(child, registry)
|
|
683
|
+
)
|
|
670
684
|
};
|
|
671
685
|
}
|
|
672
686
|
|
|
@@ -778,12 +792,12 @@ function useChatAutoScroll({
|
|
|
778
792
|
}
|
|
779
793
|
|
|
780
794
|
// src/chat-composition.tsx
|
|
781
|
-
import { useRenderer as
|
|
795
|
+
import { useRenderer as useRenderer4 } from "@pactor-app/runtime";
|
|
782
796
|
import {
|
|
783
|
-
Component as
|
|
797
|
+
Component as Component3,
|
|
784
798
|
isValidElement,
|
|
785
|
-
useRef as
|
|
786
|
-
useState as
|
|
799
|
+
useRef as useRef12,
|
|
800
|
+
useState as useState14,
|
|
787
801
|
useSyncExternalStore as useSyncExternalStore2
|
|
788
802
|
} from "react";
|
|
789
803
|
|
|
@@ -810,132 +824,283 @@ function useChatModel({
|
|
|
810
824
|
}
|
|
811
825
|
|
|
812
826
|
// src/view/AppShell.tsx
|
|
813
|
-
import { Menu, PanelLeft } from "lucide-react";
|
|
814
827
|
import {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
useState as useState4
|
|
820
|
-
} from "react";
|
|
821
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
822
|
-
var SidebarDrawerContext = createContext(null);
|
|
828
|
+
Sidebar as UiSidebar,
|
|
829
|
+
useSidebarDrawer as useUiSidebarDrawer
|
|
830
|
+
} from "@pactor-app/ui/components";
|
|
831
|
+
import { jsx } from "react/jsx-runtime";
|
|
823
832
|
function useSidebarDrawer() {
|
|
824
|
-
return
|
|
833
|
+
return useUiSidebarDrawer();
|
|
825
834
|
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
function AppShell({ sidebar, brand, locationKey, sidebarFooter, collapsible = false, children, className }) {
|
|
846
|
-
const [drawerOpen, setDrawerOpen] = useState4(false);
|
|
847
|
-
const isMobile = useIsMobileViewport();
|
|
848
|
-
const close = useCallback2(() => setDrawerOpen(false), []);
|
|
849
|
-
const [collapsed, setCollapsed] = useState4(false);
|
|
850
|
-
const collapsedEffective = collapsible && collapsed && !isMobile;
|
|
851
|
-
const framed = brand !== void 0 || sidebarFooter !== void 0;
|
|
852
|
-
const [trackedLocationKey, setTrackedLocationKey] = useState4(locationKey);
|
|
853
|
-
if (trackedLocationKey !== locationKey) {
|
|
854
|
-
setTrackedLocationKey(locationKey);
|
|
855
|
-
setDrawerOpen(false);
|
|
856
|
-
}
|
|
857
|
-
useEffect2(() => {
|
|
858
|
-
if (!drawerOpen) {
|
|
859
|
-
return;
|
|
835
|
+
function AppShell({
|
|
836
|
+
sidebar,
|
|
837
|
+
brand,
|
|
838
|
+
locationKey,
|
|
839
|
+
sidebarFooter,
|
|
840
|
+
collapsible = false,
|
|
841
|
+
children,
|
|
842
|
+
className
|
|
843
|
+
}) {
|
|
844
|
+
return /* @__PURE__ */ jsx(
|
|
845
|
+
UiSidebar,
|
|
846
|
+
{
|
|
847
|
+
content: sidebar,
|
|
848
|
+
brand,
|
|
849
|
+
locationKey,
|
|
850
|
+
sidebarFooter,
|
|
851
|
+
collapsible,
|
|
852
|
+
className: `pactor-chat-shell h-full min-h-0${className ? ` ${className}` : ""}`,
|
|
853
|
+
children
|
|
860
854
|
}
|
|
861
|
-
|
|
862
|
-
if (event.key === "Escape") {
|
|
863
|
-
setDrawerOpen(false);
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
window.addEventListener("keydown", onKeyDown);
|
|
867
|
-
return () => window.removeEventListener("keydown", onKeyDown);
|
|
868
|
-
}, [drawerOpen]);
|
|
869
|
-
return /* @__PURE__ */ jsx(SidebarDrawerContext.Provider, { value: { close, collapsed: collapsedEffective }, children: /* @__PURE__ */ jsxs("div", { className: `pactor-chat-shell${className ? ` ${className}` : ""}`, children: [
|
|
870
|
-
drawerOpen ? /* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__scrim", "aria-hidden": true, onClick: close }) : null,
|
|
871
|
-
/* @__PURE__ */ jsx(
|
|
872
|
-
"div",
|
|
873
|
-
{
|
|
874
|
-
className: `pactor-chat-shell__sidebar${framed ? " pactor-chat-shell__sidebar--framed" : ""}${collapsedEffective ? " pactor-chat-shell__sidebar--collapsed" : ""}`,
|
|
875
|
-
"data-open": drawerOpen ? "true" : "false",
|
|
876
|
-
inert: isMobile && !drawerOpen ? true : void 0,
|
|
877
|
-
children: framed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
878
|
-
brand !== void 0 && // 桌面品牌行(决策 D3):brand 左、折叠钮右;移动端由
|
|
879
|
-
// CSS 隐藏(品牌维持顶栏现状)
|
|
880
|
-
/* @__PURE__ */ jsxs("div", { className: "pactor-chat-shell__sidebar-header", children: [
|
|
881
|
-
/* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__brand", children: brand }),
|
|
882
|
-
collapsible && !isMobile && /* @__PURE__ */ jsx(
|
|
883
|
-
"button",
|
|
884
|
-
{
|
|
885
|
-
type: "button",
|
|
886
|
-
className: "pactor-chat-icon-button pactor-chat-shell__collapse",
|
|
887
|
-
"aria-label": collapsedEffective ? "\u5C55\u5F00\u4FA7\u680F" : "\u6298\u53E0\u4FA7\u680F",
|
|
888
|
-
"aria-expanded": !collapsedEffective,
|
|
889
|
-
title: collapsedEffective ? "\u5C55\u5F00\u4FA7\u680F" : "\u6298\u53E0\u4FA7\u680F",
|
|
890
|
-
onClick: () => setCollapsed((value) => !value),
|
|
891
|
-
children: /* @__PURE__ */ jsx(PanelLeft, { size: 16, strokeWidth: 1.7 })
|
|
892
|
-
}
|
|
893
|
-
)
|
|
894
|
-
] }),
|
|
895
|
-
/* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__sidebar-body", children: sidebar }),
|
|
896
|
-
sidebarFooter !== void 0 && /* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__sidebar-footer", children: sidebarFooter })
|
|
897
|
-
] }) : sidebar
|
|
898
|
-
}
|
|
899
|
-
),
|
|
900
|
-
/* @__PURE__ */ jsxs("main", { className: "pactor-chat-shell__main", children: [
|
|
901
|
-
/* @__PURE__ */ jsxs("div", { className: "pactor-chat-shell__topbar", children: [
|
|
902
|
-
/* @__PURE__ */ jsx(
|
|
903
|
-
"button",
|
|
904
|
-
{
|
|
905
|
-
type: "button",
|
|
906
|
-
className: "pactor-chat-icon-button pactor-chat-shell__menu",
|
|
907
|
-
"aria-label": "\u6253\u5F00\u5BFC\u822A",
|
|
908
|
-
"aria-expanded": drawerOpen,
|
|
909
|
-
onClick: () => setDrawerOpen(true),
|
|
910
|
-
children: /* @__PURE__ */ jsx(Menu, { size: 18, strokeWidth: 1.7 })
|
|
911
|
-
}
|
|
912
|
-
),
|
|
913
|
-
brand
|
|
914
|
-
] }),
|
|
915
|
-
/* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__content", children })
|
|
916
|
-
] })
|
|
917
|
-
] }) });
|
|
855
|
+
);
|
|
918
856
|
}
|
|
919
857
|
|
|
920
858
|
// src/view/ArtifactPanel.tsx
|
|
921
|
-
import {
|
|
859
|
+
import { Icon as Icon3 } from "@pactor-app/ui/components";
|
|
922
860
|
import { Registry as Registry2 } from "@pactor-app/core";
|
|
923
861
|
import { MarkdownRenderer as MarkdownRenderer2 } from "@pactor-app/markdown";
|
|
924
|
-
import { DslRenderer as DslRenderer2, useRenderer as
|
|
862
|
+
import { DslRenderer as DslRenderer2, useRenderer as useRenderer3 } from "@pactor-app/runtime";
|
|
925
863
|
import {
|
|
926
|
-
Component,
|
|
864
|
+
Component as Component2,
|
|
865
|
+
useEffect as useEffect2,
|
|
927
866
|
useMemo,
|
|
928
867
|
useRef as useRef3,
|
|
929
|
-
useState as
|
|
868
|
+
useState as useState4
|
|
930
869
|
} from "react";
|
|
931
870
|
|
|
932
871
|
// src/view/PartRenderer.tsx
|
|
933
|
-
import {
|
|
872
|
+
import { Icon } from "@pactor-app/ui/components";
|
|
934
873
|
import { MarkdownRenderer } from "@pactor-app/markdown";
|
|
935
|
-
import { DslRenderer, useRenderer } from "@pactor-app/runtime";
|
|
936
|
-
|
|
874
|
+
import { DslRenderer, useRenderer as useRenderer2 } from "@pactor-app/runtime";
|
|
875
|
+
|
|
876
|
+
// src/view/chrome/artifact-card.tsx
|
|
877
|
+
function buildArtifactCardFragment(artifact) {
|
|
878
|
+
return {
|
|
879
|
+
requires: ["Card", "Flex", "Text", "Badge", "Button"],
|
|
880
|
+
node: {
|
|
881
|
+
type: "Card",
|
|
882
|
+
props: { className: "pactor-chat-artifact-card" },
|
|
883
|
+
children: [
|
|
884
|
+
{
|
|
885
|
+
type: "Flex",
|
|
886
|
+
props: { justify: "space-between", align: "center", gap: "small" },
|
|
887
|
+
children: [
|
|
888
|
+
{
|
|
889
|
+
type: "Text",
|
|
890
|
+
props: {
|
|
891
|
+
text: artifact.title,
|
|
892
|
+
strong: true,
|
|
893
|
+
className: "pactor-chat-artifact-card__title"
|
|
894
|
+
}
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
type: "Badge",
|
|
898
|
+
props: {
|
|
899
|
+
text: artifact.kind,
|
|
900
|
+
variant: "secondary",
|
|
901
|
+
className: "pactor-chat-artifact-card__kind"
|
|
902
|
+
}
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
type: "Button",
|
|
906
|
+
props: {
|
|
907
|
+
text: "\u5728\u9762\u677F\u4E2D\u6253\u5F00",
|
|
908
|
+
variant: "default",
|
|
909
|
+
size: "small",
|
|
910
|
+
className: "pactor-chat-artifact-card__open"
|
|
911
|
+
},
|
|
912
|
+
events: {
|
|
913
|
+
onClick: [
|
|
914
|
+
{
|
|
915
|
+
action: "chat.openArtifact",
|
|
916
|
+
params: { artifact }
|
|
917
|
+
}
|
|
918
|
+
]
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
]
|
|
922
|
+
}
|
|
923
|
+
]
|
|
924
|
+
}
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
// src/view/chrome/ChromeSlot.tsx
|
|
929
|
+
import { useRenderer } from "@pactor-app/runtime";
|
|
930
|
+
import { Component } from "react";
|
|
931
|
+
|
|
932
|
+
// src/view/chrome/actions.ts
|
|
933
|
+
var handlers = {};
|
|
934
|
+
function setChatChromeHandlers(next) {
|
|
935
|
+
handlers = { ...handlers, ...next };
|
|
936
|
+
}
|
|
937
|
+
var messageActionDispatchers = /* @__PURE__ */ new Map();
|
|
938
|
+
function setMessageActionDispatcher(token, dispatch) {
|
|
939
|
+
messageActionDispatchers.set(token, dispatch);
|
|
940
|
+
}
|
|
941
|
+
function clearMessageActionDispatcher(token) {
|
|
942
|
+
messageActionDispatchers.delete(token);
|
|
943
|
+
}
|
|
944
|
+
var CHROME_ACTION_HANDLERS = {
|
|
945
|
+
"chat.sendSuggestion": (action) => {
|
|
946
|
+
const text = action.params?.["text"];
|
|
947
|
+
if (typeof text === "string") {
|
|
948
|
+
handlers.sendSuggestion?.(text);
|
|
949
|
+
}
|
|
950
|
+
return { ok: true };
|
|
951
|
+
},
|
|
952
|
+
"chat.openArtifact": (action) => {
|
|
953
|
+
const artifact = action.params?.["artifact"];
|
|
954
|
+
if (artifact) {
|
|
955
|
+
handlers.openArtifact?.(artifact);
|
|
956
|
+
}
|
|
957
|
+
return { ok: true };
|
|
958
|
+
},
|
|
959
|
+
"chat.messageAction": (action) => {
|
|
960
|
+
const token = action.params?.["token"];
|
|
961
|
+
const actionId = action.params?.["actionId"];
|
|
962
|
+
if (typeof token === "string" && typeof actionId === "string") {
|
|
963
|
+
messageActionDispatchers.get(token)?.(actionId);
|
|
964
|
+
}
|
|
965
|
+
return { ok: true };
|
|
966
|
+
},
|
|
967
|
+
"chat.composerSubmit": (action) => {
|
|
968
|
+
const value = action.params?.["value"];
|
|
969
|
+
if (typeof value === "string") {
|
|
970
|
+
handlers.composerSubmit?.(value);
|
|
971
|
+
}
|
|
972
|
+
return { ok: true };
|
|
973
|
+
},
|
|
974
|
+
"chat.menuSelect": (action) => {
|
|
975
|
+
const key = action.params?.["key"];
|
|
976
|
+
if (typeof key === "string") {
|
|
977
|
+
handlers.menuSelect?.(key);
|
|
978
|
+
}
|
|
979
|
+
return { ok: true };
|
|
980
|
+
},
|
|
981
|
+
"chat.modelChange": (action) => {
|
|
982
|
+
const value = action.params?.["value"];
|
|
983
|
+
if (typeof value === "string") {
|
|
984
|
+
handlers.modelChange?.(value);
|
|
985
|
+
}
|
|
986
|
+
return { ok: true };
|
|
987
|
+
},
|
|
988
|
+
"chat.headerAction": (action) => {
|
|
989
|
+
const name = action.params?.["action"];
|
|
990
|
+
if (typeof name === "string") {
|
|
991
|
+
handlers.headerAction?.(name);
|
|
992
|
+
}
|
|
993
|
+
return { ok: true };
|
|
994
|
+
},
|
|
995
|
+
"chat.panelClose": () => {
|
|
996
|
+
handlers.panelClose?.();
|
|
997
|
+
return { ok: true };
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
function ensureChatChromeActions(actions) {
|
|
1001
|
+
for (const [name, handler] of Object.entries(CHROME_ACTION_HANDLERS)) {
|
|
1002
|
+
if (!actions.has(name)) {
|
|
1003
|
+
actions.register(name, handler);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
function invokeChatPanelClose() {
|
|
1008
|
+
handlers.panelClose?.();
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
// src/view/chrome/ChromeSlot.tsx
|
|
1012
|
+
import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
|
|
1013
|
+
var warnedMissing = /* @__PURE__ */ new Set();
|
|
1014
|
+
function warnMissingOnce(key, detail) {
|
|
1015
|
+
if (!warnedMissing.has(key)) {
|
|
1016
|
+
warnedMissing.add(key);
|
|
1017
|
+
console.warn(`[@pactor-app/chat] ${detail}`);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
function ChromeSlotInner({
|
|
1021
|
+
fragment,
|
|
1022
|
+
fallback,
|
|
1023
|
+
components,
|
|
1024
|
+
wrap
|
|
1025
|
+
}) {
|
|
1026
|
+
let renderer;
|
|
1027
|
+
try {
|
|
1028
|
+
renderer = useRenderer();
|
|
1029
|
+
} catch {
|
|
1030
|
+
return /* @__PURE__ */ jsx2(Fragment, { children: fallback });
|
|
1031
|
+
}
|
|
1032
|
+
ensureChatChromeActions(renderer.context.actions);
|
|
1033
|
+
if (components) {
|
|
1034
|
+
for (const [name, component] of Object.entries(components)) {
|
|
1035
|
+
const existing = renderer.context.components.get(name);
|
|
1036
|
+
if (existing !== void 0 && existing !== component) {
|
|
1037
|
+
warnMissingOnce(
|
|
1038
|
+
`conflict:${name}`,
|
|
1039
|
+
`[@pactor-app/chat] chrome \u5185\u90E8\u7EC4\u4EF6\u540D\u300C${name}\u300D\u88AB\u5BBF\u4E3B\u5360\u7528\uFF0C\u5DF2\u56DE\u9000\u5185\u5EFA\u5B9E\u73B0`
|
|
1040
|
+
);
|
|
1041
|
+
return /* @__PURE__ */ jsx2(Fragment, { children: fallback });
|
|
1042
|
+
}
|
|
1043
|
+
if (existing === void 0) {
|
|
1044
|
+
renderer.context.components.register(
|
|
1045
|
+
name,
|
|
1046
|
+
component
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
const missing = fragment.requires.filter(
|
|
1052
|
+
(type) => !renderer.context.components.has(type)
|
|
1053
|
+
);
|
|
1054
|
+
if (missing.length > 0) {
|
|
1055
|
+
warnMissingOnce(
|
|
1056
|
+
`${fragment.node.type}:${missing.join(",")}`,
|
|
1057
|
+
`[@pactor-app/chat] chrome DSL \u7247\u6BB5\u6240\u9700\u7EC4\u4EF6\u7C7B\u578B\u7F3A\u5931\uFF08${missing.join(" / ")}\uFF09\uFF0C\u5DF2\u56DE\u9000\u5185\u5EFA\u5B9E\u73B0`
|
|
1058
|
+
);
|
|
1059
|
+
return /* @__PURE__ */ jsx2(Fragment, { children: fallback });
|
|
1060
|
+
}
|
|
1061
|
+
const rendered = /* @__PURE__ */ jsx2("div", { className: "pactor-chat-chrome", children: renderer.renderChildren([fragment.node]) });
|
|
1062
|
+
return wrap ? /* @__PURE__ */ jsx2(Fragment, { children: wrap(rendered) }) : rendered;
|
|
1063
|
+
}
|
|
1064
|
+
var ChromeSlotGuard = class extends Component {
|
|
1065
|
+
constructor() {
|
|
1066
|
+
super(...arguments);
|
|
1067
|
+
this.state = { failed: false };
|
|
1068
|
+
}
|
|
1069
|
+
static getDerivedStateFromError() {
|
|
1070
|
+
return { failed: true };
|
|
1071
|
+
}
|
|
1072
|
+
render() {
|
|
1073
|
+
return this.state.failed ? this.props.fallback : this.props.children;
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
1076
|
+
function ChromeSlot(props) {
|
|
1077
|
+
return /* @__PURE__ */ jsx2(ChromeSlotGuard, { fallback: props.fallback, children: /* @__PURE__ */ jsx2(ChromeSlotInner, { ...props }) });
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
// src/view/chrome/feedback.tsx
|
|
1081
|
+
function buildErrorFragment(message) {
|
|
1082
|
+
return {
|
|
1083
|
+
requires: ["Alert"],
|
|
1084
|
+
node: {
|
|
1085
|
+
type: "Alert",
|
|
1086
|
+
props: { variant: "error", message }
|
|
1087
|
+
}
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
function buildStatusFragment(text) {
|
|
1091
|
+
return {
|
|
1092
|
+
requires: ["Text"],
|
|
1093
|
+
node: {
|
|
1094
|
+
type: "Text",
|
|
1095
|
+
props: { type: "secondary", text }
|
|
1096
|
+
}
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
// src/view/PartRenderer.tsx
|
|
1101
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
937
1102
|
function ChatDenied({ deniedType }) {
|
|
938
|
-
return /* @__PURE__ */
|
|
1103
|
+
return /* @__PURE__ */ jsxs("div", { className: "pactor-chat-denied", "data-pactor-chat-denied": deniedType, children: [
|
|
939
1104
|
"\u8BE5\u7EC4\u4EF6\u4E0D\u5141\u8BB8\u5728 Chat \u4E2D\u4F7F\u7528",
|
|
940
1105
|
deniedType ? `\uFF1A${deniedType}` : ""
|
|
941
1106
|
] });
|
|
@@ -944,64 +1109,90 @@ function ChatDslNode({
|
|
|
944
1109
|
node,
|
|
945
1110
|
scope
|
|
946
1111
|
}) {
|
|
947
|
-
const renderer =
|
|
1112
|
+
const renderer = useRenderer2();
|
|
948
1113
|
const extraScope = scope ? buildChatScope(scope) : void 0;
|
|
949
|
-
return /* @__PURE__ */
|
|
1114
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children: renderer.renderChildren([node], extraScope) });
|
|
950
1115
|
}
|
|
951
1116
|
function SmoothText({ content, streaming }) {
|
|
952
1117
|
const shown = useSmoothStreamText(content, streaming);
|
|
953
|
-
return /* @__PURE__ */
|
|
1118
|
+
return /* @__PURE__ */ jsx3("div", { className: "pactor-chat-text", children: shown });
|
|
954
1119
|
}
|
|
955
1120
|
function SmoothMarkdown({ content, streaming }) {
|
|
956
1121
|
const shown = useSmoothStreamText(content, streaming);
|
|
957
|
-
return /* @__PURE__ */
|
|
1122
|
+
return /* @__PURE__ */ jsx3(MarkdownRenderer, { content: shown });
|
|
958
1123
|
}
|
|
959
1124
|
function PartRenderer({ part, runtime, scope, streaming = false, onOpenArtifact }) {
|
|
960
1125
|
switch (part.type) {
|
|
961
1126
|
case "text":
|
|
962
|
-
return /* @__PURE__ */
|
|
1127
|
+
return /* @__PURE__ */ jsx3(SmoothText, { content: part.content, streaming });
|
|
963
1128
|
case "markdown":
|
|
964
|
-
return /* @__PURE__ */
|
|
1129
|
+
return /* @__PURE__ */ jsx3(SmoothMarkdown, { content: part.content, streaming });
|
|
965
1130
|
case "thinking":
|
|
966
1131
|
case "tool-call":
|
|
967
1132
|
case "tool-result":
|
|
968
1133
|
return null;
|
|
969
1134
|
case "dsl": {
|
|
970
1135
|
if (!part.schema || !runtime) {
|
|
971
|
-
return /* @__PURE__ */
|
|
1136
|
+
return /* @__PURE__ */ jsx3(
|
|
1137
|
+
ChromeSlot,
|
|
1138
|
+
{
|
|
1139
|
+
fragment: buildStatusFragment(
|
|
1140
|
+
part.schema ? "DSL \u6E32\u67D3\u4E0D\u53EF\u7528\uFF08\u672A\u6CE8\u5165 Safe Registry\uFF09" : "\u5185\u5BB9\u751F\u6210\u4E2D\u2026"
|
|
1141
|
+
),
|
|
1142
|
+
fallback: /* @__PURE__ */ jsx3("div", { className: "pactor-chat-dsl-pending", children: part.schema ? "DSL \u6E32\u67D3\u4E0D\u53EF\u7528\uFF08\u672A\u6CE8\u5165 Safe Registry\uFF09" : "\u5185\u5BB9\u751F\u6210\u4E2D\u2026" })
|
|
1143
|
+
}
|
|
1144
|
+
);
|
|
972
1145
|
}
|
|
973
1146
|
const guarded = guardChatDsl(part.schema, runtime.context.components);
|
|
974
|
-
return /* @__PURE__ */
|
|
1147
|
+
return /* @__PURE__ */ jsx3("div", { className: "pactor-chat-dsl", children: /* @__PURE__ */ jsx3(DslRenderer, { context: runtime.context, engine: runtime.engine, children: /* @__PURE__ */ jsx3(ChatDslNode, { node: guarded, scope }) }) });
|
|
975
1148
|
}
|
|
976
1149
|
case "error":
|
|
977
|
-
return /* @__PURE__ */
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1150
|
+
return /* @__PURE__ */ jsx3(
|
|
1151
|
+
ChromeSlot,
|
|
1152
|
+
{
|
|
1153
|
+
fragment: buildErrorFragment(part.message),
|
|
1154
|
+
fallback: /* @__PURE__ */ jsxs("div", { className: "pactor-chat-error", role: "alert", children: [
|
|
1155
|
+
/* @__PURE__ */ jsx3(Icon, { name: "error", size: 14 }),
|
|
1156
|
+
/* @__PURE__ */ jsx3("span", { children: part.message })
|
|
1157
|
+
] })
|
|
1158
|
+
}
|
|
1159
|
+
);
|
|
981
1160
|
case "status":
|
|
982
|
-
return /* @__PURE__ */
|
|
1161
|
+
return /* @__PURE__ */ jsx3(
|
|
1162
|
+
ChromeSlot,
|
|
1163
|
+
{
|
|
1164
|
+
fragment: buildStatusFragment(part.text),
|
|
1165
|
+
fallback: /* @__PURE__ */ jsx3("div", { className: "pactor-chat-status", children: part.text })
|
|
1166
|
+
}
|
|
1167
|
+
);
|
|
983
1168
|
case "artifact":
|
|
984
|
-
return /* @__PURE__ */
|
|
985
|
-
|
|
1169
|
+
return /* @__PURE__ */ jsx3(
|
|
1170
|
+
ChromeSlot,
|
|
986
1171
|
{
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1172
|
+
fragment: buildArtifactCardFragment(part.artifact),
|
|
1173
|
+
fallback: /* @__PURE__ */ jsxs(
|
|
1174
|
+
"div",
|
|
1175
|
+
{
|
|
1176
|
+
className: "pactor-chat-artifact-card",
|
|
1177
|
+
"data-artifact-kind": part.artifact.kind,
|
|
1178
|
+
children: [
|
|
1179
|
+
/* @__PURE__ */ jsx3("span", { className: "pactor-chat-artifact-card__title", children: part.artifact.title }),
|
|
1180
|
+
/* @__PURE__ */ jsx3("span", { className: "pactor-chat-artifact-card__kind", children: part.artifact.kind }),
|
|
1181
|
+
/* @__PURE__ */ jsxs(
|
|
1182
|
+
"button",
|
|
1183
|
+
{
|
|
1184
|
+
type: "button",
|
|
1185
|
+
className: "pactor-chat-artifact-card__open",
|
|
1186
|
+
onClick: () => onOpenArtifact?.(part.artifact),
|
|
1187
|
+
children: [
|
|
1188
|
+
/* @__PURE__ */ jsx3(Icon, { name: "panel-right-open", size: 13, strokeWidth: 1.7 }),
|
|
1189
|
+
"\u5728\u9762\u677F\u4E2D\u6253\u5F00"
|
|
1190
|
+
]
|
|
1191
|
+
}
|
|
1192
|
+
)
|
|
1193
|
+
]
|
|
1194
|
+
}
|
|
1195
|
+
)
|
|
1005
1196
|
}
|
|
1006
1197
|
);
|
|
1007
1198
|
default:
|
|
@@ -1009,8 +1200,65 @@ function PartRenderer({ part, runtime, scope, streaming = false, onOpenArtifact
|
|
|
1009
1200
|
}
|
|
1010
1201
|
}
|
|
1011
1202
|
|
|
1203
|
+
// src/view/chrome/panel-header.tsx
|
|
1204
|
+
import { Icon as Icon2 } from "@pactor-app/ui/components";
|
|
1205
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1206
|
+
function ChatPanelCloseButton() {
|
|
1207
|
+
return /* @__PURE__ */ jsx4(
|
|
1208
|
+
"button",
|
|
1209
|
+
{
|
|
1210
|
+
type: "button",
|
|
1211
|
+
className: "pactor-chat-icon-button pactor-chat-inspector__close",
|
|
1212
|
+
title: "\u5173\u95ED\u9762\u677F",
|
|
1213
|
+
"aria-label": "\u5173\u95ED\u9762\u677F",
|
|
1214
|
+
onClick: () => invokeChatPanelClose(),
|
|
1215
|
+
children: /* @__PURE__ */ jsx4(Icon2, { name: "x", size: 16 })
|
|
1216
|
+
}
|
|
1217
|
+
);
|
|
1218
|
+
}
|
|
1219
|
+
var PANEL_HEADER_INTERNAL_COMPONENTS = { ChatPanelCloseButton };
|
|
1220
|
+
function buildPanelHeaderFragment(props) {
|
|
1221
|
+
return {
|
|
1222
|
+
requires: ["Flex", "Text", "Badge", "ChatPanelCloseButton"],
|
|
1223
|
+
node: {
|
|
1224
|
+
type: "Flex",
|
|
1225
|
+
props: {
|
|
1226
|
+
justify: "space-between",
|
|
1227
|
+
align: "center",
|
|
1228
|
+
gap: "small",
|
|
1229
|
+
className: "pactor-chat-inspector__header-dsl"
|
|
1230
|
+
},
|
|
1231
|
+
children: [
|
|
1232
|
+
{
|
|
1233
|
+
type: "Flex",
|
|
1234
|
+
props: { align: "center", gap: "small" },
|
|
1235
|
+
children: [
|
|
1236
|
+
{
|
|
1237
|
+
type: "Text",
|
|
1238
|
+
props: {
|
|
1239
|
+
text: props.title,
|
|
1240
|
+
strong: true,
|
|
1241
|
+
className: "pactor-chat-inspector__title"
|
|
1242
|
+
}
|
|
1243
|
+
},
|
|
1244
|
+
{
|
|
1245
|
+
type: "Badge",
|
|
1246
|
+
props: {
|
|
1247
|
+
text: props.kind,
|
|
1248
|
+
variant: "secondary",
|
|
1249
|
+
className: "pactor-chat-inspector__kind"
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
]
|
|
1253
|
+
},
|
|
1254
|
+
{ type: "ChatPanelCloseButton" }
|
|
1255
|
+
]
|
|
1256
|
+
}
|
|
1257
|
+
};
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1012
1260
|
// src/view/ArtifactPanel.tsx
|
|
1013
|
-
import { Fragment as Fragment3, jsx as
|
|
1261
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1014
1262
|
function useArtifactRuntime(safeRegistry, user) {
|
|
1015
1263
|
return useMemo(() => {
|
|
1016
1264
|
if (!safeRegistry) {
|
|
@@ -1024,7 +1272,7 @@ function useArtifactRuntime(safeRegistry, user) {
|
|
|
1024
1272
|
return createChatRuntime({ safeRegistry: components, user });
|
|
1025
1273
|
}, [safeRegistry, user]);
|
|
1026
1274
|
}
|
|
1027
|
-
var ArtifactDslGuard = class extends
|
|
1275
|
+
var ArtifactDslGuard = class extends Component2 {
|
|
1028
1276
|
constructor() {
|
|
1029
1277
|
super(...arguments);
|
|
1030
1278
|
this.state = { failed: false };
|
|
@@ -1036,12 +1284,12 @@ var ArtifactDslGuard = class extends Component {
|
|
|
1036
1284
|
console.warn("[@pactor-app/chat] DSL \u4EA7\u51FA\u7269\u6E32\u67D3\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u5C55\u793A", error);
|
|
1037
1285
|
}
|
|
1038
1286
|
render() {
|
|
1039
|
-
return this.state.failed ? /* @__PURE__ */
|
|
1287
|
+
return this.state.failed ? /* @__PURE__ */ jsx5("div", { className: "pactor-chat-denied", children: "DSL \u4EA7\u51FA\u7269\u6E32\u67D3\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u5C55\u793A" }) : this.props.children;
|
|
1040
1288
|
}
|
|
1041
1289
|
};
|
|
1042
1290
|
function ArtifactDslNode({ node }) {
|
|
1043
|
-
const { renderChildren } =
|
|
1044
|
-
return /* @__PURE__ */
|
|
1291
|
+
const { renderChildren } = useRenderer3();
|
|
1292
|
+
return /* @__PURE__ */ jsx5(Fragment3, { children: renderChildren([node]) });
|
|
1045
1293
|
}
|
|
1046
1294
|
function ArtifactDslContent({
|
|
1047
1295
|
content,
|
|
@@ -1049,10 +1297,10 @@ function ArtifactDslContent({
|
|
|
1049
1297
|
}) {
|
|
1050
1298
|
const node = typeof content === "object" && content !== null && !Array.isArray(content) && typeof content.type === "string" ? content : void 0;
|
|
1051
1299
|
if (!node || !runtime) {
|
|
1052
|
-
return /* @__PURE__ */
|
|
1300
|
+
return /* @__PURE__ */ jsx5("div", { className: "pactor-chat-denied", children: node ? "DSL \u9884\u89C8\u4E0D\u53EF\u7528\uFF08\u672A\u6CE8\u5165 Safe Registry\uFF09" : "DSL \u4EA7\u51FA\u7269\u5185\u5BB9\u65E0\u6548" });
|
|
1053
1301
|
}
|
|
1054
1302
|
const guarded = guardChatDsl(node, runtime.context.components);
|
|
1055
|
-
return /* @__PURE__ */
|
|
1303
|
+
return /* @__PURE__ */ jsx5(DslRenderer2, { context: runtime.context, engine: runtime.engine, children: /* @__PURE__ */ jsx5(ArtifactDslGuard, { children: /* @__PURE__ */ jsx5(ArtifactDslNode, { node: guarded }) }) });
|
|
1056
1304
|
}
|
|
1057
1305
|
function ArtifactContent({
|
|
1058
1306
|
artifact,
|
|
@@ -1060,16 +1308,16 @@ function ArtifactContent({
|
|
|
1060
1308
|
}) {
|
|
1061
1309
|
switch (artifact.kind) {
|
|
1062
1310
|
case "markdown":
|
|
1063
|
-
return /* @__PURE__ */
|
|
1311
|
+
return /* @__PURE__ */ jsx5(MarkdownRenderer2, { content: String(artifact.content) });
|
|
1064
1312
|
case "code":
|
|
1065
|
-
return /* @__PURE__ */
|
|
1066
|
-
artifact.language ? /* @__PURE__ */
|
|
1067
|
-
/* @__PURE__ */
|
|
1313
|
+
return /* @__PURE__ */ jsxs2("div", { className: "pactor-chat-inspector__code", children: [
|
|
1314
|
+
artifact.language ? /* @__PURE__ */ jsx5("span", { className: "pactor-chat-inspector__code-lang", children: artifact.language }) : null,
|
|
1315
|
+
/* @__PURE__ */ jsx5("pre", { children: /* @__PURE__ */ jsx5("code", { children: String(artifact.content) }) })
|
|
1068
1316
|
] });
|
|
1069
1317
|
case "text":
|
|
1070
|
-
return /* @__PURE__ */
|
|
1318
|
+
return /* @__PURE__ */ jsx5("pre", { className: "pactor-chat-inspector__text", children: String(artifact.content) });
|
|
1071
1319
|
case "dsl":
|
|
1072
|
-
return /* @__PURE__ */
|
|
1320
|
+
return /* @__PURE__ */ jsx5(ArtifactDslContent, { content: artifact.content, runtime });
|
|
1073
1321
|
default:
|
|
1074
1322
|
return null;
|
|
1075
1323
|
}
|
|
@@ -1083,8 +1331,13 @@ function ArtifactPanel({
|
|
|
1083
1331
|
className
|
|
1084
1332
|
}) {
|
|
1085
1333
|
const runtime = useArtifactRuntime(safeRegistry, user);
|
|
1334
|
+
const closeRef = useRef3(onClose);
|
|
1335
|
+
closeRef.current = onClose;
|
|
1336
|
+
useEffect2(() => {
|
|
1337
|
+
setChatChromeHandlers({ panelClose: () => closeRef.current?.() });
|
|
1338
|
+
}, []);
|
|
1086
1339
|
const panelRef = useRef3(null);
|
|
1087
|
-
const [width, setWidth] =
|
|
1340
|
+
const [width, setWidth] = useState4(null);
|
|
1088
1341
|
const handleResizeStart = (event) => {
|
|
1089
1342
|
event.preventDefault();
|
|
1090
1343
|
const panel = panelRef.current;
|
|
@@ -1110,7 +1363,7 @@ function ArtifactPanel({
|
|
|
1110
1363
|
document.addEventListener("pointermove", onMove);
|
|
1111
1364
|
document.addEventListener("pointerup", onUp);
|
|
1112
1365
|
};
|
|
1113
|
-
return /* @__PURE__ */
|
|
1366
|
+
return /* @__PURE__ */ jsxs2(
|
|
1114
1367
|
"aside",
|
|
1115
1368
|
{
|
|
1116
1369
|
ref: panelRef,
|
|
@@ -1118,7 +1371,7 @@ function ArtifactPanel({
|
|
|
1118
1371
|
"data-kind": artifact?.kind,
|
|
1119
1372
|
style: width !== null ? { width: `${width}px` } : void 0,
|
|
1120
1373
|
children: [
|
|
1121
|
-
/* @__PURE__ */
|
|
1374
|
+
/* @__PURE__ */ jsx5(
|
|
1122
1375
|
"div",
|
|
1123
1376
|
{
|
|
1124
1377
|
className: "pactor-chat-inspector__resize",
|
|
@@ -1128,43 +1381,53 @@ function ArtifactPanel({
|
|
|
1128
1381
|
onPointerDown: handleResizeStart
|
|
1129
1382
|
}
|
|
1130
1383
|
),
|
|
1131
|
-
/* @__PURE__ */
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1384
|
+
/* @__PURE__ */ jsx5("div", { className: "pactor-chat-inspector__header", children: /* @__PURE__ */ jsx5(
|
|
1385
|
+
ChromeSlot,
|
|
1386
|
+
{
|
|
1387
|
+
fragment: buildPanelHeaderFragment({
|
|
1388
|
+
title: artifact?.title ?? "\u4EA7\u51FA\u7269",
|
|
1389
|
+
kind: artifact?.kind ?? "text"
|
|
1390
|
+
}),
|
|
1391
|
+
components: PANEL_HEADER_INTERNAL_COMPONENTS,
|
|
1392
|
+
fallback: /* @__PURE__ */ jsxs2(Fragment3, { children: [
|
|
1393
|
+
/* @__PURE__ */ jsx5("span", { className: "pactor-chat-inspector__title", children: artifact?.title ?? "\u4EA7\u51FA\u7269" }),
|
|
1394
|
+
artifact ? /* @__PURE__ */ jsx5("span", { className: "pactor-chat-inspector__kind", children: artifact.kind }) : null,
|
|
1395
|
+
/* @__PURE__ */ jsx5(
|
|
1396
|
+
"button",
|
|
1397
|
+
{
|
|
1398
|
+
type: "button",
|
|
1399
|
+
className: "pactor-chat-icon-button pactor-chat-inspector__close",
|
|
1400
|
+
"aria-label": "\u5173\u95ED\u9762\u677F",
|
|
1401
|
+
onClick: onClose,
|
|
1402
|
+
children: /* @__PURE__ */ jsx5(Icon3, { name: "x", size: 16, strokeWidth: 1.7 })
|
|
1403
|
+
}
|
|
1404
|
+
)
|
|
1405
|
+
] })
|
|
1406
|
+
}
|
|
1407
|
+
) }),
|
|
1408
|
+
/* @__PURE__ */ jsx5("div", { className: "pactor-chat-inspector__body", children: inspector !== void 0 && inspector !== null ? inspector : artifact ? /* @__PURE__ */ jsx5(ArtifactContent, { artifact, runtime }) : null })
|
|
1146
1409
|
]
|
|
1147
1410
|
}
|
|
1148
1411
|
);
|
|
1149
1412
|
}
|
|
1150
1413
|
|
|
1151
1414
|
// src/view/ChatView.tsx
|
|
1152
|
-
import {
|
|
1415
|
+
import { Icon as Icon9 } from "@pactor-app/ui/components";
|
|
1153
1416
|
import { Registry as Registry3 } from "@pactor-app/core";
|
|
1154
|
-
import { useEffect as
|
|
1417
|
+
import { useEffect as useEffect8, useMemo as useMemo3, useRef as useRef10, useState as useState12, useSyncExternalStore } from "react";
|
|
1155
1418
|
|
|
1156
1419
|
// src/view/Composer.tsx
|
|
1157
|
-
import {
|
|
1158
|
-
import { useLayoutEffect as useLayoutEffect3, useMemo as useMemo2, useRef as useRef6, useState as
|
|
1420
|
+
import { Icon as Icon6 } from "@pactor-app/ui/components";
|
|
1421
|
+
import { useLayoutEffect as useLayoutEffect3, useMemo as useMemo2, useRef as useRef6, useState as useState8 } from "react";
|
|
1159
1422
|
|
|
1160
1423
|
// src/view/AnchoredPopover.tsx
|
|
1161
1424
|
import {
|
|
1162
1425
|
useEffect as useEffect3,
|
|
1163
1426
|
useLayoutEffect as useLayoutEffect2,
|
|
1164
1427
|
useRef as useRef4,
|
|
1165
|
-
useState as
|
|
1428
|
+
useState as useState5
|
|
1166
1429
|
} from "react";
|
|
1167
|
-
import { jsx as
|
|
1430
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1168
1431
|
function AnchoredPopover({
|
|
1169
1432
|
anchorRect,
|
|
1170
1433
|
onClose,
|
|
@@ -1174,7 +1437,7 @@ function AnchoredPopover({
|
|
|
1174
1437
|
sideOffset = 8
|
|
1175
1438
|
}) {
|
|
1176
1439
|
const ref = useRef4(null);
|
|
1177
|
-
const [position, setPosition] =
|
|
1440
|
+
const [position, setPosition] = useState5(null);
|
|
1178
1441
|
useLayoutEffect2(() => {
|
|
1179
1442
|
const element = ref.current;
|
|
1180
1443
|
if (!element) return;
|
|
@@ -1221,7 +1484,7 @@ function AnchoredPopover({
|
|
|
1221
1484
|
position?.below ? "pactor-chat-popover--below" : "",
|
|
1222
1485
|
className ?? ""
|
|
1223
1486
|
].filter(Boolean).join(" ");
|
|
1224
|
-
return /* @__PURE__ */
|
|
1487
|
+
return /* @__PURE__ */ jsx6(
|
|
1225
1488
|
"div",
|
|
1226
1489
|
{
|
|
1227
1490
|
ref,
|
|
@@ -1240,19 +1503,44 @@ function AnchoredPopover({
|
|
|
1240
1503
|
}
|
|
1241
1504
|
|
|
1242
1505
|
// src/view/ModelChip.tsx
|
|
1243
|
-
import {
|
|
1244
|
-
import { useRef as useRef5, useState as
|
|
1245
|
-
|
|
1506
|
+
import { Icon as Icon4 } from "@pactor-app/ui/components";
|
|
1507
|
+
import { useEffect as useEffect4, useRef as useRef5, useState as useState6 } from "react";
|
|
1508
|
+
|
|
1509
|
+
// src/view/chrome/model-select.tsx
|
|
1510
|
+
function buildModelSelectFragment(props) {
|
|
1511
|
+
return {
|
|
1512
|
+
requires: ["Select"],
|
|
1513
|
+
node: {
|
|
1514
|
+
type: "Select",
|
|
1515
|
+
props: {
|
|
1516
|
+
options: props.models.map((option) => ({
|
|
1517
|
+
value: option.value,
|
|
1518
|
+
label: option.label
|
|
1519
|
+
})),
|
|
1520
|
+
value: props.model,
|
|
1521
|
+
className: "pactor-chat-model-select"
|
|
1522
|
+
},
|
|
1523
|
+
events: {
|
|
1524
|
+
onChange: [
|
|
1525
|
+
{ action: "chat.modelChange", params: { value: "${event}" } }
|
|
1526
|
+
]
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
};
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
// src/view/ModelChip.tsx
|
|
1533
|
+
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1246
1534
|
function ModelChip({
|
|
1247
1535
|
models,
|
|
1248
1536
|
model,
|
|
1249
1537
|
onModelChange
|
|
1250
1538
|
}) {
|
|
1251
1539
|
const chipRef = useRef5(null);
|
|
1252
|
-
const [anchor, setAnchor] =
|
|
1540
|
+
const [anchor, setAnchor] = useState6(null);
|
|
1253
1541
|
const currentOption = models.find((option) => option.value === model) ?? models[0];
|
|
1254
|
-
return /* @__PURE__ */
|
|
1255
|
-
/* @__PURE__ */
|
|
1542
|
+
return /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
1543
|
+
/* @__PURE__ */ jsxs3(
|
|
1256
1544
|
"button",
|
|
1257
1545
|
{
|
|
1258
1546
|
ref: chipRef,
|
|
@@ -1262,18 +1550,18 @@ function ModelChip({
|
|
|
1262
1550
|
"aria-label": "\u9009\u62E9\u6A21\u578B",
|
|
1263
1551
|
onClick: () => setAnchor(chipRef.current.getBoundingClientRect()),
|
|
1264
1552
|
children: [
|
|
1265
|
-
/* @__PURE__ */
|
|
1266
|
-
/* @__PURE__ */
|
|
1553
|
+
/* @__PURE__ */ jsx7("span", { className: "pactor-chat-model-chip__label", children: currentOption.label }),
|
|
1554
|
+
/* @__PURE__ */ jsx7(Icon4, { name: "chevrons-up-down", size: 12 })
|
|
1267
1555
|
]
|
|
1268
1556
|
}
|
|
1269
1557
|
),
|
|
1270
|
-
anchor && /* @__PURE__ */
|
|
1558
|
+
anchor && /* @__PURE__ */ jsx7(
|
|
1271
1559
|
AnchoredPopover,
|
|
1272
1560
|
{
|
|
1273
1561
|
anchorRect: anchor,
|
|
1274
1562
|
onClose: () => setAnchor(null),
|
|
1275
1563
|
role: "listbox",
|
|
1276
|
-
children: models.map((option) => /* @__PURE__ */
|
|
1564
|
+
children: models.map((option) => /* @__PURE__ */ jsxs3(
|
|
1277
1565
|
"button",
|
|
1278
1566
|
{
|
|
1279
1567
|
type: "button",
|
|
@@ -1285,8 +1573,8 @@ function ModelChip({
|
|
|
1285
1573
|
setAnchor(null);
|
|
1286
1574
|
},
|
|
1287
1575
|
children: [
|
|
1288
|
-
/* @__PURE__ */
|
|
1289
|
-
option.value === currentOption.value && /* @__PURE__ */
|
|
1576
|
+
/* @__PURE__ */ jsx7("span", { className: "pactor-chat-popover__item-label", children: option.label }),
|
|
1577
|
+
option.value === currentOption.value && /* @__PURE__ */ jsx7(Icon4, { name: "check", size: 13, className: "pactor-chat-popover__item-check" })
|
|
1290
1578
|
]
|
|
1291
1579
|
},
|
|
1292
1580
|
option.value
|
|
@@ -1295,10 +1583,243 @@ function ModelChip({
|
|
|
1295
1583
|
)
|
|
1296
1584
|
] });
|
|
1297
1585
|
}
|
|
1586
|
+
function ModelSelect({
|
|
1587
|
+
models,
|
|
1588
|
+
model,
|
|
1589
|
+
onModelChange
|
|
1590
|
+
}) {
|
|
1591
|
+
const changeRef = useRef5(onModelChange);
|
|
1592
|
+
changeRef.current = onModelChange;
|
|
1593
|
+
useEffect4(() => {
|
|
1594
|
+
setChatChromeHandlers({
|
|
1595
|
+
modelChange: (value) => changeRef.current?.(value)
|
|
1596
|
+
});
|
|
1597
|
+
}, []);
|
|
1598
|
+
return /* @__PURE__ */ jsx7(
|
|
1599
|
+
ChromeSlot,
|
|
1600
|
+
{
|
|
1601
|
+
fragment: buildModelSelectFragment({ models, model }),
|
|
1602
|
+
fallback: /* @__PURE__ */ jsx7(ModelChip, { models, model, onModelChange })
|
|
1603
|
+
}
|
|
1604
|
+
);
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
// src/view/chrome/composer.tsx
|
|
1608
|
+
import { Icon as Icon5 } from "@pactor-app/ui/components";
|
|
1609
|
+
import { createContext, useContext } from "react";
|
|
1610
|
+
import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1611
|
+
var ComposerBridgeContext = createContext(
|
|
1612
|
+
null
|
|
1613
|
+
);
|
|
1614
|
+
function useComposerBridge() {
|
|
1615
|
+
const bridge = useContext(ComposerBridgeContext);
|
|
1616
|
+
if (!bridge) {
|
|
1617
|
+
throw new Error(
|
|
1618
|
+
"[@pactor-app/chat] ChatComposer* \u5185\u90E8\u7EC4\u4EF6\u4EC5\u53EF\u5728 Composer chrome \u7247\u6BB5\u5185\u6E32\u67D3"
|
|
1619
|
+
);
|
|
1620
|
+
}
|
|
1621
|
+
return bridge;
|
|
1622
|
+
}
|
|
1623
|
+
function formatSize(bytes) {
|
|
1624
|
+
if (bytes < 1024) {
|
|
1625
|
+
return `${bytes} B`;
|
|
1626
|
+
}
|
|
1627
|
+
if (bytes < 1024 * 1024) {
|
|
1628
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1629
|
+
}
|
|
1630
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1631
|
+
}
|
|
1632
|
+
function ComposerAttachments({
|
|
1633
|
+
attachments,
|
|
1634
|
+
onRemove,
|
|
1635
|
+
onClick
|
|
1636
|
+
}) {
|
|
1637
|
+
if (attachments.length === 0) {
|
|
1638
|
+
return null;
|
|
1639
|
+
}
|
|
1640
|
+
return /* @__PURE__ */ jsx8("div", { className: "pactor-chat-composer__attachments", children: attachments.map((attachment) => {
|
|
1641
|
+
const isImage = attachment.mimeType.startsWith("image/");
|
|
1642
|
+
return /* @__PURE__ */ jsxs4(
|
|
1643
|
+
"div",
|
|
1644
|
+
{
|
|
1645
|
+
className: "pactor-chat-composer__attachment",
|
|
1646
|
+
"data-attachment-id": attachment.id,
|
|
1647
|
+
onClick: () => onClick?.(attachment),
|
|
1648
|
+
children: [
|
|
1649
|
+
isImage && attachment.url ? /* @__PURE__ */ jsx8("span", { className: "pactor-chat-composer__attachment-thumb", children: /* @__PURE__ */ jsx8("img", { src: attachment.url, alt: attachment.name }) }) : /* @__PURE__ */ jsxs4("span", { className: "pactor-chat-composer__attachment-info", children: [
|
|
1650
|
+
/* @__PURE__ */ jsx8(Icon5, { name: "file-text", size: 14 }),
|
|
1651
|
+
/* @__PURE__ */ jsx8("span", { className: "pactor-chat-composer__attachment-name", children: attachment.name }),
|
|
1652
|
+
attachment.size !== void 0 && /* @__PURE__ */ jsx8("span", { className: "pactor-chat-composer__attachment-size", children: formatSize(attachment.size) })
|
|
1653
|
+
] }),
|
|
1654
|
+
/* @__PURE__ */ jsx8(
|
|
1655
|
+
"button",
|
|
1656
|
+
{
|
|
1657
|
+
type: "button",
|
|
1658
|
+
className: "pactor-chat-icon-button pactor-chat-composer__attachment-remove",
|
|
1659
|
+
title: "\u79FB\u9664\u9644\u4EF6",
|
|
1660
|
+
"aria-label": "\u79FB\u9664\u9644\u4EF6",
|
|
1661
|
+
onClick: (event) => {
|
|
1662
|
+
event.stopPropagation();
|
|
1663
|
+
onRemove(attachment.id);
|
|
1664
|
+
},
|
|
1665
|
+
children: /* @__PURE__ */ jsx8(Icon5, { name: "x", size: 12 })
|
|
1666
|
+
}
|
|
1667
|
+
)
|
|
1668
|
+
]
|
|
1669
|
+
},
|
|
1670
|
+
attachment.id
|
|
1671
|
+
);
|
|
1672
|
+
}) });
|
|
1673
|
+
}
|
|
1674
|
+
function ComposerContextChips({
|
|
1675
|
+
chips,
|
|
1676
|
+
onRemove
|
|
1677
|
+
}) {
|
|
1678
|
+
if (chips.length === 0) {
|
|
1679
|
+
return null;
|
|
1680
|
+
}
|
|
1681
|
+
return /* @__PURE__ */ jsx8("div", { className: "pactor-chat-composer__contexts", children: chips.map((chip) => /* @__PURE__ */ jsxs4(
|
|
1682
|
+
"span",
|
|
1683
|
+
{
|
|
1684
|
+
className: "pactor-chat-context-chip",
|
|
1685
|
+
"data-context-id": chip.id,
|
|
1686
|
+
children: [
|
|
1687
|
+
/* @__PURE__ */ jsx8("span", { className: "pactor-chat-context-chip__label", children: chip.label }),
|
|
1688
|
+
/* @__PURE__ */ jsx8(
|
|
1689
|
+
"button",
|
|
1690
|
+
{
|
|
1691
|
+
type: "button",
|
|
1692
|
+
className: "pactor-chat-icon-button pactor-chat-context-chip__remove",
|
|
1693
|
+
title: `\u79FB\u9664\u4E0A\u4E0B\u6587 ${chip.label}`,
|
|
1694
|
+
"aria-label": `\u79FB\u9664\u4E0A\u4E0B\u6587 ${chip.label}`,
|
|
1695
|
+
onClick: () => onRemove(chip),
|
|
1696
|
+
children: /* @__PURE__ */ jsx8(Icon5, { name: "x", size: 12 })
|
|
1697
|
+
}
|
|
1698
|
+
)
|
|
1699
|
+
]
|
|
1700
|
+
},
|
|
1701
|
+
`${chip.trigger ?? ""}:${chip.id}`
|
|
1702
|
+
)) });
|
|
1703
|
+
}
|
|
1704
|
+
function ChatComposerHeader() {
|
|
1705
|
+
const bridge = useComposerBridge();
|
|
1706
|
+
return /* @__PURE__ */ jsxs4(Fragment5, { children: [
|
|
1707
|
+
bridge.attachments !== void 0 && /* @__PURE__ */ jsx8(
|
|
1708
|
+
ComposerAttachments,
|
|
1709
|
+
{
|
|
1710
|
+
attachments: bridge.attachments,
|
|
1711
|
+
onRemove: bridge.removeAttachment,
|
|
1712
|
+
onClick: bridge.attachmentClick
|
|
1713
|
+
}
|
|
1714
|
+
),
|
|
1715
|
+
bridge.contextChips !== void 0 && /* @__PURE__ */ jsx8(
|
|
1716
|
+
ComposerContextChips,
|
|
1717
|
+
{
|
|
1718
|
+
chips: bridge.contextChips,
|
|
1719
|
+
onRemove: bridge.removeChip
|
|
1720
|
+
}
|
|
1721
|
+
)
|
|
1722
|
+
] });
|
|
1723
|
+
}
|
|
1724
|
+
function ChatComposerToolbarStart() {
|
|
1725
|
+
const bridge = useComposerBridge();
|
|
1726
|
+
return /* @__PURE__ */ jsxs4(Fragment5, { children: [
|
|
1727
|
+
bridge.toolbarStart,
|
|
1728
|
+
bridge.showPlus && /* @__PURE__ */ jsx8(
|
|
1729
|
+
"button",
|
|
1730
|
+
{
|
|
1731
|
+
type: "button",
|
|
1732
|
+
className: "pactor-chat-icon-button",
|
|
1733
|
+
title: "\u66F4\u591A\u529F\u80FD",
|
|
1734
|
+
"aria-label": "\u66F4\u591A\u529F\u80FD",
|
|
1735
|
+
onClick: (event) => bridge.plusClick(event.currentTarget.getBoundingClientRect()),
|
|
1736
|
+
children: /* @__PURE__ */ jsx8(Icon5, { name: "plus", size: 14 })
|
|
1737
|
+
}
|
|
1738
|
+
),
|
|
1739
|
+
bridge.showAttach && /* @__PURE__ */ jsx8(
|
|
1740
|
+
"button",
|
|
1741
|
+
{
|
|
1742
|
+
type: "button",
|
|
1743
|
+
className: "pactor-chat-icon-button",
|
|
1744
|
+
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
1745
|
+
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
1746
|
+
onClick: bridge.openFilePicker,
|
|
1747
|
+
children: /* @__PURE__ */ jsx8(Icon5, { name: "paperclip", size: 14 })
|
|
1748
|
+
}
|
|
1749
|
+
)
|
|
1750
|
+
] });
|
|
1751
|
+
}
|
|
1752
|
+
function ChatComposerToolbarEnd() {
|
|
1753
|
+
const bridge = useComposerBridge();
|
|
1754
|
+
return /* @__PURE__ */ jsxs4(Fragment5, { children: [
|
|
1755
|
+
bridge.modelChipEnabled && /* @__PURE__ */ jsx8(
|
|
1756
|
+
ModelSelect,
|
|
1757
|
+
{
|
|
1758
|
+
models: bridge.models,
|
|
1759
|
+
model: bridge.model,
|
|
1760
|
+
onModelChange: bridge.modelChange
|
|
1761
|
+
}
|
|
1762
|
+
),
|
|
1763
|
+
bridge.toolbarEnd,
|
|
1764
|
+
/* @__PURE__ */ jsx8(
|
|
1765
|
+
"button",
|
|
1766
|
+
{
|
|
1767
|
+
type: "button",
|
|
1768
|
+
className: `pactor-chat-composer__button${bridge.streaming ? " pactor-chat-composer__button--stop" : ""}`,
|
|
1769
|
+
title: bridge.streaming ? "\u505C\u6B62\u751F\u6210" : "\u53D1\u9001",
|
|
1770
|
+
"aria-label": bridge.streaming ? "\u505C\u6B62\u751F\u6210" : "\u53D1\u9001",
|
|
1771
|
+
disabled: bridge.streaming ? false : bridge.disabled || !bridge.text.trim(),
|
|
1772
|
+
onClick: bridge.streaming ? bridge.stop : bridge.send,
|
|
1773
|
+
children: bridge.streaming ? /* @__PURE__ */ jsx8(Icon5, { name: "square", size: 14, className: "pactor-chat-icon-fill" }) : /* @__PURE__ */ jsx8(Icon5, { name: "arrow-up", size: 16 })
|
|
1774
|
+
}
|
|
1775
|
+
)
|
|
1776
|
+
] });
|
|
1777
|
+
}
|
|
1778
|
+
function ChatComposerFooter() {
|
|
1779
|
+
const bridge = useComposerBridge();
|
|
1780
|
+
return /* @__PURE__ */ jsx8(Fragment5, { children: bridge.composerFooter });
|
|
1781
|
+
}
|
|
1782
|
+
var COMPOSER_INTERNAL_COMPONENTS = {
|
|
1783
|
+
ChatComposerHeader,
|
|
1784
|
+
ChatComposerToolbarStart,
|
|
1785
|
+
ChatComposerToolbarEnd,
|
|
1786
|
+
ChatComposerFooter
|
|
1787
|
+
};
|
|
1788
|
+
function buildComposerFragment(props) {
|
|
1789
|
+
const hideToolbar = props.hideToolbar === true;
|
|
1790
|
+
return {
|
|
1791
|
+
requires: [
|
|
1792
|
+
"ChatInput",
|
|
1793
|
+
"ChatComposerHeader",
|
|
1794
|
+
...hideToolbar ? [] : ["ChatComposerToolbarStart", "ChatComposerToolbarEnd"],
|
|
1795
|
+
"ChatComposerFooter"
|
|
1796
|
+
],
|
|
1797
|
+
node: {
|
|
1798
|
+
type: "ChatInput",
|
|
1799
|
+
props: {
|
|
1800
|
+
placeholder: props.placeholder,
|
|
1801
|
+
disabled: props.disabled,
|
|
1802
|
+
rows: 1,
|
|
1803
|
+
hideSend: true,
|
|
1804
|
+
header: { type: "ChatComposerHeader" },
|
|
1805
|
+
...hideToolbar ? {} : {
|
|
1806
|
+
toolbarStart: { type: "ChatComposerToolbarStart" },
|
|
1807
|
+
toolbarEnd: { type: "ChatComposerToolbarEnd" }
|
|
1808
|
+
},
|
|
1809
|
+
...props.hasFooter === true ? { footer: { type: "ChatComposerFooter" } } : {}
|
|
1810
|
+
},
|
|
1811
|
+
events: {
|
|
1812
|
+
onSubmit: [
|
|
1813
|
+
{ action: "chat.composerSubmit", params: { value: "${event}" } }
|
|
1814
|
+
]
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
};
|
|
1818
|
+
}
|
|
1298
1819
|
|
|
1299
1820
|
// src/view/context-sources.tsx
|
|
1300
|
-
import { useEffect as
|
|
1301
|
-
import { jsx as
|
|
1821
|
+
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
1822
|
+
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1302
1823
|
function sourceCacheKey(source) {
|
|
1303
1824
|
return `${source.service ?? ""}:${JSON.stringify(source.params ?? {})}`;
|
|
1304
1825
|
}
|
|
@@ -1333,8 +1854,8 @@ function ContextSourceList({
|
|
|
1333
1854
|
cache,
|
|
1334
1855
|
onSelect
|
|
1335
1856
|
}) {
|
|
1336
|
-
const [resolutions, setResolutions] =
|
|
1337
|
-
|
|
1857
|
+
const [resolutions, setResolutions] = useState7([]);
|
|
1858
|
+
useEffect5(() => {
|
|
1338
1859
|
let cancelled = false;
|
|
1339
1860
|
const initial = sources.map(
|
|
1340
1861
|
(source) => source.items ? { status: "ready", items: source.items } : { status: "loading" }
|
|
@@ -1381,10 +1902,10 @@ function ContextSourceList({
|
|
|
1381
1902
|
});
|
|
1382
1903
|
return /* @__PURE__ */ jsxs5("div", { className: "pactor-chat-source-list", children: [
|
|
1383
1904
|
groups.map(({ source, resolution, items }) => /* @__PURE__ */ jsxs5("div", { className: "pactor-chat-source-list__group", children: [
|
|
1384
|
-
sources.length > 1 && /* @__PURE__ */
|
|
1385
|
-
resolution.status === "loading" && /* @__PURE__ */
|
|
1386
|
-
resolution.status === "error" && /* @__PURE__ */
|
|
1387
|
-
items.map((item) => /* @__PURE__ */
|
|
1905
|
+
sources.length > 1 && /* @__PURE__ */ jsx9("div", { className: "pactor-chat-source-list__group-label", children: source.label }),
|
|
1906
|
+
resolution.status === "loading" && /* @__PURE__ */ jsx9("div", { className: "pactor-chat-source-list__hint", children: "\u52A0\u8F7D\u4E2D\u2026" }),
|
|
1907
|
+
resolution.status === "error" && /* @__PURE__ */ jsx9("div", { className: "pactor-chat-source-list__error", role: "alert", children: resolution.message }),
|
|
1908
|
+
items.map((item) => /* @__PURE__ */ jsx9(
|
|
1388
1909
|
"button",
|
|
1389
1910
|
{
|
|
1390
1911
|
type: "button",
|
|
@@ -1395,22 +1916,13 @@ function ContextSourceList({
|
|
|
1395
1916
|
item.id
|
|
1396
1917
|
))
|
|
1397
1918
|
] }, `${source.trigger}:${source.label}`)),
|
|
1398
|
-
totalMatched === 0 && groups.every(({ resolution }) => resolution.status === "ready") && /* @__PURE__ */
|
|
1919
|
+
totalMatched === 0 && groups.every(({ resolution }) => resolution.status === "ready") && /* @__PURE__ */ jsx9("div", { className: "pactor-chat-source-list__hint", children: "\u65E0\u5339\u914D\u9879" })
|
|
1399
1920
|
] });
|
|
1400
1921
|
}
|
|
1401
1922
|
|
|
1402
1923
|
// src/view/Composer.tsx
|
|
1403
|
-
import { jsx as
|
|
1924
|
+
import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1404
1925
|
var MAX_INPUT_HEIGHT = 200;
|
|
1405
|
-
function formatSize(bytes) {
|
|
1406
|
-
if (bytes < 1024) {
|
|
1407
|
-
return `${bytes} B`;
|
|
1408
|
-
}
|
|
1409
|
-
if (bytes < 1024 * 1024) {
|
|
1410
|
-
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1411
|
-
}
|
|
1412
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1413
|
-
}
|
|
1414
1926
|
function detectMention(text, caret) {
|
|
1415
1927
|
const beforeCaret = text.slice(0, caret);
|
|
1416
1928
|
const match = /(?:^|\s)@([^\s@]*)$/.exec(beforeCaret);
|
|
@@ -1439,10 +1951,12 @@ function Composer({
|
|
|
1439
1951
|
contextSources,
|
|
1440
1952
|
contextChips,
|
|
1441
1953
|
onContextChipsChange,
|
|
1442
|
-
callService
|
|
1954
|
+
callService,
|
|
1955
|
+
composerFooter,
|
|
1956
|
+
hideToolbar = false
|
|
1443
1957
|
}) {
|
|
1444
|
-
const [text, setText] =
|
|
1445
|
-
const [dragOver, setDragOver] =
|
|
1958
|
+
const [text, setText] = useState8("");
|
|
1959
|
+
const [dragOver, setDragOver] = useState8(false);
|
|
1446
1960
|
const inputRef = useRef6(null);
|
|
1447
1961
|
const fileInputRef = useRef6(null);
|
|
1448
1962
|
const plusButtonRef = useRef6(null);
|
|
@@ -1458,8 +1972,8 @@ function Composer({
|
|
|
1458
1972
|
);
|
|
1459
1973
|
const builtinMentionEnabled = onMentionTrigger === void 0 && mentionSources.length > 0;
|
|
1460
1974
|
const builtinPlusEnabled = onPlusMenu === void 0 && plusSources.length > 0;
|
|
1461
|
-
const [mentionState, setMentionState] =
|
|
1462
|
-
const [plusAnchor, setPlusAnchor] =
|
|
1975
|
+
const [mentionState, setMentionState] = useState8(null);
|
|
1976
|
+
const [plusAnchor, setPlusAnchor] = useState8(null);
|
|
1463
1977
|
const sourceCacheRef = useRef6(null);
|
|
1464
1978
|
if (sourceCacheRef.current === null) {
|
|
1465
1979
|
sourceCacheRef.current = /* @__PURE__ */ new Map();
|
|
@@ -1494,105 +2008,147 @@ function Composer({
|
|
|
1494
2008
|
onSend?.(value);
|
|
1495
2009
|
setText("");
|
|
1496
2010
|
};
|
|
1497
|
-
const
|
|
1498
|
-
|
|
2011
|
+
const sendRef = useRef6(send);
|
|
2012
|
+
sendRef.current = send;
|
|
2013
|
+
useLayoutEffect3(() => {
|
|
2014
|
+
setChatChromeHandlers({ composerSubmit: () => sendRef.current() });
|
|
2015
|
+
}, []);
|
|
2016
|
+
const syncText = (value, caret, rect) => {
|
|
1499
2017
|
setText(value);
|
|
1500
2018
|
if (onMentionTrigger || builtinMentionEnabled) {
|
|
1501
|
-
const caret = event.target.selectionStart ?? value.length;
|
|
1502
2019
|
const query = detectMention(value, caret);
|
|
1503
2020
|
if (onMentionTrigger) {
|
|
1504
2021
|
if (query !== null) {
|
|
1505
|
-
onMentionTrigger(query,
|
|
2022
|
+
onMentionTrigger(query, rect);
|
|
1506
2023
|
}
|
|
1507
2024
|
} else {
|
|
1508
|
-
setMentionState(
|
|
1509
|
-
|
|
1510
|
-
|
|
2025
|
+
setMentionState(query !== null ? { query, anchorRect: rect } : null);
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
};
|
|
2029
|
+
const handleChange = (event) => {
|
|
2030
|
+
syncText(
|
|
2031
|
+
event.target.value,
|
|
2032
|
+
event.target.selectionStart ?? event.target.value.length,
|
|
2033
|
+
event.target.getBoundingClientRect()
|
|
2034
|
+
);
|
|
2035
|
+
};
|
|
2036
|
+
const handleBubbleChange = (event) => {
|
|
2037
|
+
const target = event.target;
|
|
2038
|
+
if (!(target instanceof HTMLTextAreaElement)) {
|
|
2039
|
+
return;
|
|
2040
|
+
}
|
|
2041
|
+
syncText(
|
|
2042
|
+
target.value,
|
|
2043
|
+
target.selectionStart ?? target.value.length,
|
|
2044
|
+
target.getBoundingClientRect()
|
|
2045
|
+
);
|
|
2046
|
+
};
|
|
2047
|
+
const handlePasteFiles = (clipboardData) => {
|
|
2048
|
+
const files = Array.from(clipboardData.files);
|
|
2049
|
+
if (files.length > 0 && onAttachFiles) {
|
|
2050
|
+
onAttachFiles(files);
|
|
2051
|
+
return true;
|
|
2052
|
+
}
|
|
2053
|
+
return false;
|
|
2054
|
+
};
|
|
2055
|
+
const dragHandlers = {
|
|
2056
|
+
onDragOver: (event) => {
|
|
2057
|
+
event.preventDefault();
|
|
2058
|
+
setDragOver(true);
|
|
2059
|
+
},
|
|
2060
|
+
onDragLeave: () => setDragOver(false),
|
|
2061
|
+
onDrop: (event) => {
|
|
2062
|
+
event.preventDefault();
|
|
2063
|
+
setDragOver(false);
|
|
2064
|
+
const files = collectDropFiles(event);
|
|
2065
|
+
if (files.length > 0 && onAttachFiles) {
|
|
2066
|
+
onAttachFiles(files);
|
|
1511
2067
|
}
|
|
1512
2068
|
}
|
|
1513
2069
|
};
|
|
1514
|
-
const showToolbar = toolbarStart !== void 0 || toolbarEnd !== void 0 || onPlusMenu !== void 0 || builtinPlusEnabled || onAttachFiles !== void 0 || modelChipEnabled;
|
|
1515
|
-
|
|
1516
|
-
"
|
|
2070
|
+
const showToolbar = !hideToolbar && (toolbarStart !== void 0 || toolbarEnd !== void 0 || onPlusMenu !== void 0 || builtinPlusEnabled || onAttachFiles !== void 0 || modelChipEnabled);
|
|
2071
|
+
const fileInputNode = onAttachFiles ? /* @__PURE__ */ jsx10(
|
|
2072
|
+
"input",
|
|
1517
2073
|
{
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
event.preventDefault();
|
|
1526
|
-
setDragOver(false);
|
|
1527
|
-
const files = collectDropFiles(event);
|
|
1528
|
-
if (files.length > 0 && onAttachFiles) {
|
|
2074
|
+
ref: fileInputRef,
|
|
2075
|
+
type: "file",
|
|
2076
|
+
multiple: true,
|
|
2077
|
+
hidden: true,
|
|
2078
|
+
onChange: (event) => {
|
|
2079
|
+
const files = event.target.files ? Array.from(event.target.files) : [];
|
|
2080
|
+
if (files.length > 0) {
|
|
1529
2081
|
onAttachFiles(files);
|
|
1530
2082
|
}
|
|
1531
|
-
|
|
2083
|
+
event.target.value = "";
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
) : null;
|
|
2087
|
+
const popoverNodes = /* @__PURE__ */ jsxs6(Fragment6, { children: [
|
|
2088
|
+
builtinMentionEnabled && mentionState && /* @__PURE__ */ jsx10(
|
|
2089
|
+
AnchoredPopover,
|
|
2090
|
+
{
|
|
2091
|
+
anchorRect: mentionState.anchorRect,
|
|
2092
|
+
onClose: () => setMentionState(null),
|
|
2093
|
+
role: "listbox",
|
|
2094
|
+
children: /* @__PURE__ */ jsx10(
|
|
2095
|
+
ContextSourceList,
|
|
2096
|
+
{
|
|
2097
|
+
sources: mentionSources,
|
|
2098
|
+
query: mentionState.query,
|
|
2099
|
+
callService,
|
|
2100
|
+
cache: sourceCacheRef.current,
|
|
2101
|
+
onSelect: handleSelectContext
|
|
2102
|
+
}
|
|
2103
|
+
)
|
|
2104
|
+
}
|
|
2105
|
+
),
|
|
2106
|
+
builtinPlusEnabled && plusAnchor && /* @__PURE__ */ jsx10(
|
|
2107
|
+
AnchoredPopover,
|
|
2108
|
+
{
|
|
2109
|
+
anchorRect: plusAnchor,
|
|
2110
|
+
onClose: () => setPlusAnchor(null),
|
|
2111
|
+
role: "listbox",
|
|
2112
|
+
children: /* @__PURE__ */ jsx10(
|
|
2113
|
+
ContextSourceList,
|
|
2114
|
+
{
|
|
2115
|
+
sources: plusSources,
|
|
2116
|
+
query: "",
|
|
2117
|
+
callService,
|
|
2118
|
+
cache: sourceCacheRef.current,
|
|
2119
|
+
onSelect: handleSelectContext
|
|
2120
|
+
}
|
|
2121
|
+
)
|
|
2122
|
+
}
|
|
2123
|
+
)
|
|
2124
|
+
] });
|
|
2125
|
+
const fallback = /* @__PURE__ */ jsxs6(
|
|
2126
|
+
"div",
|
|
2127
|
+
{
|
|
2128
|
+
className: `pactor-chat-composer${dragOver ? " pactor-chat-composer--dragover" : ""}`,
|
|
2129
|
+
...dragHandlers,
|
|
1532
2130
|
children: [
|
|
1533
|
-
attachments !== void 0 &&
|
|
1534
|
-
|
|
1535
|
-
return /* @__PURE__ */ jsxs6(
|
|
1536
|
-
"div",
|
|
1537
|
-
{
|
|
1538
|
-
className: "pactor-chat-composer__attachment",
|
|
1539
|
-
"data-attachment-id": attachment.id,
|
|
1540
|
-
onClick: () => onAttachmentClick?.(attachment),
|
|
1541
|
-
children: [
|
|
1542
|
-
isImage && attachment.url ? /* @__PURE__ */ jsx7("span", { className: "pactor-chat-composer__attachment-thumb", children: /* @__PURE__ */ jsx7("img", { src: attachment.url, alt: attachment.name }) }) : /* @__PURE__ */ jsxs6("span", { className: "pactor-chat-composer__attachment-info", children: [
|
|
1543
|
-
/* @__PURE__ */ jsx7(FileText, { size: 14 }),
|
|
1544
|
-
/* @__PURE__ */ jsx7("span", { className: "pactor-chat-composer__attachment-name", children: attachment.name }),
|
|
1545
|
-
attachment.size !== void 0 && /* @__PURE__ */ jsx7("span", { className: "pactor-chat-composer__attachment-size", children: formatSize(attachment.size) })
|
|
1546
|
-
] }),
|
|
1547
|
-
/* @__PURE__ */ jsx7(
|
|
1548
|
-
"button",
|
|
1549
|
-
{
|
|
1550
|
-
type: "button",
|
|
1551
|
-
className: "pactor-chat-icon-button pactor-chat-composer__attachment-remove",
|
|
1552
|
-
title: "\u79FB\u9664\u9644\u4EF6",
|
|
1553
|
-
"aria-label": "\u79FB\u9664\u9644\u4EF6",
|
|
1554
|
-
onClick: (event) => {
|
|
1555
|
-
event.stopPropagation();
|
|
1556
|
-
onAttachmentsChange?.(
|
|
1557
|
-
attachments.filter((item) => item.id !== attachment.id)
|
|
1558
|
-
);
|
|
1559
|
-
},
|
|
1560
|
-
children: /* @__PURE__ */ jsx7(X2, { size: 12 })
|
|
1561
|
-
}
|
|
1562
|
-
)
|
|
1563
|
-
]
|
|
1564
|
-
},
|
|
1565
|
-
attachment.id
|
|
1566
|
-
);
|
|
1567
|
-
}) }),
|
|
1568
|
-
contextChips !== void 0 && contextChips.length > 0 && /* @__PURE__ */ jsx7("div", { className: "pactor-chat-composer__contexts", children: contextChips.map((chip) => /* @__PURE__ */ jsxs6(
|
|
1569
|
-
"span",
|
|
2131
|
+
attachments !== void 0 && /* @__PURE__ */ jsx10(
|
|
2132
|
+
ComposerAttachments,
|
|
1570
2133
|
{
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
contextChips.filter(
|
|
1584
|
-
(existing) => !(existing.id === chip.id && existing.trigger === chip.trigger)
|
|
1585
|
-
)
|
|
1586
|
-
),
|
|
1587
|
-
children: /* @__PURE__ */ jsx7(X2, { size: 12 })
|
|
1588
|
-
}
|
|
2134
|
+
attachments,
|
|
2135
|
+
onRemove: (id) => onAttachmentsChange?.(attachments.filter((a) => a.id !== id)),
|
|
2136
|
+
onClick: onAttachmentClick
|
|
2137
|
+
}
|
|
2138
|
+
),
|
|
2139
|
+
contextChips !== void 0 && /* @__PURE__ */ jsx10(
|
|
2140
|
+
ComposerContextChips,
|
|
2141
|
+
{
|
|
2142
|
+
chips: contextChips,
|
|
2143
|
+
onRemove: (chip) => onContextChipsChange?.(
|
|
2144
|
+
contextChips.filter(
|
|
2145
|
+
(existing) => !(existing.id === chip.id && existing.trigger === chip.trigger)
|
|
1589
2146
|
)
|
|
1590
|
-
|
|
1591
|
-
}
|
|
1592
|
-
|
|
1593
|
-
)) }),
|
|
2147
|
+
)
|
|
2148
|
+
}
|
|
2149
|
+
),
|
|
1594
2150
|
/* @__PURE__ */ jsxs6("div", { className: "pactor-chat-composer__row", children: [
|
|
1595
|
-
/* @__PURE__ */
|
|
2151
|
+
/* @__PURE__ */ jsx10(
|
|
1596
2152
|
"textarea",
|
|
1597
2153
|
{
|
|
1598
2154
|
ref: inputRef,
|
|
@@ -1609,10 +2165,8 @@ function Composer({
|
|
|
1609
2165
|
composingRef.current = false;
|
|
1610
2166
|
},
|
|
1611
2167
|
onPaste: (event) => {
|
|
1612
|
-
|
|
1613
|
-
if (files.length > 0 && onAttachFiles) {
|
|
2168
|
+
if (handlePasteFiles(event.clipboardData)) {
|
|
1614
2169
|
event.preventDefault();
|
|
1615
|
-
onAttachFiles(files);
|
|
1616
2170
|
}
|
|
1617
2171
|
},
|
|
1618
2172
|
onKeyDown: (event) => {
|
|
@@ -1626,7 +2180,7 @@ function Composer({
|
|
|
1626
2180
|
}
|
|
1627
2181
|
}
|
|
1628
2182
|
),
|
|
1629
|
-
/* @__PURE__ */
|
|
2183
|
+
hideToolbar ? null : /* @__PURE__ */ jsx10(
|
|
1630
2184
|
"button",
|
|
1631
2185
|
{
|
|
1632
2186
|
type: "button",
|
|
@@ -1635,14 +2189,14 @@ function Composer({
|
|
|
1635
2189
|
"aria-label": streaming ? "\u505C\u6B62\u751F\u6210" : "\u53D1\u9001",
|
|
1636
2190
|
disabled: streaming ? false : disabled || !text.trim(),
|
|
1637
2191
|
onClick: streaming ? onStop : send,
|
|
1638
|
-
children: streaming ? /* @__PURE__ */
|
|
2192
|
+
children: streaming ? /* @__PURE__ */ jsx10(Icon6, { name: "square", size: 14, className: "pactor-chat-icon-fill" }) : /* @__PURE__ */ jsx10(Icon6, { name: "arrow-up", size: 16 })
|
|
1639
2193
|
}
|
|
1640
2194
|
)
|
|
1641
2195
|
] }),
|
|
1642
2196
|
showToolbar && /* @__PURE__ */ jsxs6("div", { className: "pactor-chat-composer__toolbar", children: [
|
|
1643
2197
|
toolbarStart,
|
|
1644
|
-
/* @__PURE__ */
|
|
1645
|
-
(onPlusMenu || builtinPlusEnabled) && /* @__PURE__ */
|
|
2198
|
+
/* @__PURE__ */ jsx10("span", { className: "pactor-chat-composer__toolbar-spacer" }),
|
|
2199
|
+
(onPlusMenu || builtinPlusEnabled) && /* @__PURE__ */ jsx10(
|
|
1646
2200
|
"button",
|
|
1647
2201
|
{
|
|
1648
2202
|
ref: plusButtonRef,
|
|
@@ -1658,10 +2212,10 @@ function Composer({
|
|
|
1658
2212
|
setPlusAnchor(rect);
|
|
1659
2213
|
}
|
|
1660
2214
|
},
|
|
1661
|
-
children: /* @__PURE__ */
|
|
2215
|
+
children: /* @__PURE__ */ jsx10(Icon6, { name: "plus", size: 14 })
|
|
1662
2216
|
}
|
|
1663
2217
|
),
|
|
1664
|
-
onAttachFiles && /* @__PURE__ */
|
|
2218
|
+
onAttachFiles && /* @__PURE__ */ jsx10(
|
|
1665
2219
|
"button",
|
|
1666
2220
|
{
|
|
1667
2221
|
type: "button",
|
|
@@ -1669,11 +2223,11 @@ function Composer({
|
|
|
1669
2223
|
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
1670
2224
|
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
1671
2225
|
onClick: () => fileInputRef.current?.click(),
|
|
1672
|
-
children: /* @__PURE__ */
|
|
2226
|
+
children: /* @__PURE__ */ jsx10(Icon6, { name: "paperclip", size: 14 })
|
|
1673
2227
|
}
|
|
1674
2228
|
),
|
|
1675
|
-
modelChipEnabled && /* @__PURE__ */
|
|
1676
|
-
|
|
2229
|
+
modelChipEnabled && /* @__PURE__ */ jsx10(
|
|
2230
|
+
ModelSelect,
|
|
1677
2231
|
{
|
|
1678
2232
|
models,
|
|
1679
2233
|
model,
|
|
@@ -1682,111 +2236,206 @@ function Composer({
|
|
|
1682
2236
|
),
|
|
1683
2237
|
toolbarEnd
|
|
1684
2238
|
] }),
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
ref: fileInputRef,
|
|
1689
|
-
type: "file",
|
|
1690
|
-
multiple: true,
|
|
1691
|
-
hidden: true,
|
|
1692
|
-
onChange: (event) => {
|
|
1693
|
-
const files = event.target.files ? Array.from(event.target.files) : [];
|
|
1694
|
-
if (files.length > 0) {
|
|
1695
|
-
onAttachFiles(files);
|
|
1696
|
-
}
|
|
1697
|
-
event.target.value = "";
|
|
1698
|
-
}
|
|
1699
|
-
}
|
|
1700
|
-
),
|
|
1701
|
-
builtinMentionEnabled && mentionState && /* @__PURE__ */ jsx7(
|
|
1702
|
-
AnchoredPopover,
|
|
1703
|
-
{
|
|
1704
|
-
anchorRect: mentionState.anchorRect,
|
|
1705
|
-
onClose: () => setMentionState(null),
|
|
1706
|
-
role: "listbox",
|
|
1707
|
-
children: /* @__PURE__ */ jsx7(
|
|
1708
|
-
ContextSourceList,
|
|
1709
|
-
{
|
|
1710
|
-
sources: mentionSources,
|
|
1711
|
-
query: mentionState.query,
|
|
1712
|
-
callService,
|
|
1713
|
-
cache: sourceCacheRef.current,
|
|
1714
|
-
onSelect: handleSelectContext
|
|
1715
|
-
}
|
|
1716
|
-
)
|
|
1717
|
-
}
|
|
1718
|
-
),
|
|
1719
|
-
builtinPlusEnabled && plusAnchor && /* @__PURE__ */ jsx7(
|
|
1720
|
-
AnchoredPopover,
|
|
1721
|
-
{
|
|
1722
|
-
anchorRect: plusAnchor,
|
|
1723
|
-
onClose: () => setPlusAnchor(null),
|
|
1724
|
-
role: "listbox",
|
|
1725
|
-
children: /* @__PURE__ */ jsx7(
|
|
1726
|
-
ContextSourceList,
|
|
1727
|
-
{
|
|
1728
|
-
sources: plusSources,
|
|
1729
|
-
query: "",
|
|
1730
|
-
callService,
|
|
1731
|
-
cache: sourceCacheRef.current,
|
|
1732
|
-
onSelect: handleSelectContext
|
|
1733
|
-
}
|
|
1734
|
-
)
|
|
1735
|
-
}
|
|
1736
|
-
)
|
|
2239
|
+
composerFooter !== void 0 && composerFooter !== null ? /* @__PURE__ */ jsx10("div", { className: "pactor-chat-composer__footer", children: composerFooter }) : null,
|
|
2240
|
+
fileInputNode,
|
|
2241
|
+
popoverNodes
|
|
1737
2242
|
]
|
|
1738
2243
|
}
|
|
1739
2244
|
);
|
|
2245
|
+
const bridge = {
|
|
2246
|
+
text,
|
|
2247
|
+
streaming,
|
|
2248
|
+
disabled,
|
|
2249
|
+
attachments,
|
|
2250
|
+
contextChips,
|
|
2251
|
+
toolbarStart,
|
|
2252
|
+
toolbarEnd,
|
|
2253
|
+
composerFooter,
|
|
2254
|
+
models,
|
|
2255
|
+
model,
|
|
2256
|
+
showPlus: onPlusMenu !== void 0 || builtinPlusEnabled,
|
|
2257
|
+
showAttach: onAttachFiles !== void 0,
|
|
2258
|
+
modelChipEnabled,
|
|
2259
|
+
send,
|
|
2260
|
+
stop: onStop,
|
|
2261
|
+
openFilePicker: () => fileInputRef.current?.click(),
|
|
2262
|
+
plusClick: (rect) => {
|
|
2263
|
+
if (onPlusMenu) {
|
|
2264
|
+
onPlusMenu(rect);
|
|
2265
|
+
} else {
|
|
2266
|
+
setPlusAnchor(rect);
|
|
2267
|
+
}
|
|
2268
|
+
},
|
|
2269
|
+
removeAttachment: (id) => onAttachmentsChange?.((attachments ?? []).filter((a) => a.id !== id)),
|
|
2270
|
+
attachmentClick: onAttachmentClick,
|
|
2271
|
+
removeChip: (chip) => onContextChipsChange?.(
|
|
2272
|
+
(contextChips ?? []).filter(
|
|
2273
|
+
(existing) => !(existing.id === chip.id && existing.trigger === chip.trigger)
|
|
2274
|
+
)
|
|
2275
|
+
),
|
|
2276
|
+
modelChange: onModelChange
|
|
2277
|
+
};
|
|
2278
|
+
return /* @__PURE__ */ jsx10(
|
|
2279
|
+
ChromeSlot,
|
|
2280
|
+
{
|
|
2281
|
+
fragment: buildComposerFragment({
|
|
2282
|
+
placeholder,
|
|
2283
|
+
disabled,
|
|
2284
|
+
hasFooter: composerFooter !== void 0 && composerFooter !== null,
|
|
2285
|
+
hideToolbar
|
|
2286
|
+
}),
|
|
2287
|
+
components: COMPOSER_INTERNAL_COMPONENTS,
|
|
2288
|
+
fallback,
|
|
2289
|
+
wrap: (children) => /* @__PURE__ */ jsx10(ComposerBridgeContext.Provider, { value: bridge, children: /* @__PURE__ */ jsxs6(
|
|
2290
|
+
"div",
|
|
2291
|
+
{
|
|
2292
|
+
className: `pactor-chat-composer pactor-chat-composer--dsl${dragOver ? " pactor-chat-composer--dragover" : ""}`,
|
|
2293
|
+
...dragHandlers,
|
|
2294
|
+
onChange: handleBubbleChange,
|
|
2295
|
+
onPaste: (event) => {
|
|
2296
|
+
if (handlePasteFiles(event.clipboardData)) {
|
|
2297
|
+
event.preventDefault();
|
|
2298
|
+
}
|
|
2299
|
+
},
|
|
2300
|
+
children: [
|
|
2301
|
+
children,
|
|
2302
|
+
fileInputNode,
|
|
2303
|
+
popoverNodes
|
|
2304
|
+
]
|
|
2305
|
+
}
|
|
2306
|
+
) })
|
|
2307
|
+
}
|
|
2308
|
+
);
|
|
1740
2309
|
}
|
|
1741
2310
|
|
|
1742
|
-
// src/view/
|
|
1743
|
-
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1744
|
-
var DEFAULT_CHAT_GREETING = "\u4F60\u597D\uFF0C\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F";
|
|
2311
|
+
// src/view/chrome/empty-state.tsx
|
|
1745
2312
|
function suggestionLabel(suggestion) {
|
|
1746
2313
|
return typeof suggestion === "string" ? suggestion : suggestion.label;
|
|
1747
2314
|
}
|
|
1748
2315
|
function suggestionPrompt(suggestion) {
|
|
1749
2316
|
return typeof suggestion === "string" ? suggestion : suggestion.prompt ?? suggestion.label;
|
|
1750
2317
|
}
|
|
1751
|
-
function
|
|
1752
|
-
|
|
2318
|
+
function buildEmptyStateFragment(props) {
|
|
2319
|
+
const children = [
|
|
2320
|
+
{
|
|
2321
|
+
type: "Typography",
|
|
2322
|
+
props: {
|
|
2323
|
+
variant: "h3",
|
|
2324
|
+
text: props.greeting,
|
|
2325
|
+
className: "pactor-chat-empty__greeting"
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
];
|
|
2329
|
+
if (props.subtitle) {
|
|
2330
|
+
children.push({
|
|
2331
|
+
type: "Text",
|
|
2332
|
+
props: {
|
|
2333
|
+
type: "secondary",
|
|
2334
|
+
text: props.subtitle,
|
|
2335
|
+
className: "pactor-chat-empty__subtitle"
|
|
2336
|
+
}
|
|
2337
|
+
});
|
|
2338
|
+
}
|
|
2339
|
+
if (props.suggestions && props.suggestions.length > 0) {
|
|
2340
|
+
children.push({
|
|
2341
|
+
type: "Flex",
|
|
2342
|
+
props: {
|
|
2343
|
+
gap: "small",
|
|
2344
|
+
justify: "center",
|
|
2345
|
+
className: "pactor-chat-empty__suggestions"
|
|
2346
|
+
},
|
|
2347
|
+
children: props.suggestions.map((suggestion) => ({
|
|
2348
|
+
type: "Button",
|
|
2349
|
+
props: {
|
|
2350
|
+
text: suggestionLabel(suggestion),
|
|
2351
|
+
variant: "default",
|
|
2352
|
+
size: "middle",
|
|
2353
|
+
className: "pactor-chat-empty__suggestion"
|
|
2354
|
+
},
|
|
2355
|
+
events: {
|
|
2356
|
+
onClick: [
|
|
2357
|
+
{
|
|
2358
|
+
action: "chat.sendSuggestion",
|
|
2359
|
+
params: { text: suggestionPrompt(suggestion) }
|
|
2360
|
+
}
|
|
2361
|
+
]
|
|
2362
|
+
}
|
|
2363
|
+
}))
|
|
2364
|
+
});
|
|
2365
|
+
}
|
|
2366
|
+
return {
|
|
2367
|
+
requires: ["Flex", "Typography", "Text", "Button"],
|
|
2368
|
+
node: {
|
|
2369
|
+
type: "Flex",
|
|
2370
|
+
props: { direction: "vertical", align: "center", gap: "middle" },
|
|
2371
|
+
children
|
|
2372
|
+
}
|
|
2373
|
+
};
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
// src/view/EmptyState.tsx
|
|
2377
|
+
import { Fragment as Fragment7, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2378
|
+
var DEFAULT_CHAT_GREETING = "\u4F60\u597D\uFF0C\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F";
|
|
2379
|
+
function suggestionLabel2(suggestion) {
|
|
2380
|
+
return typeof suggestion === "string" ? suggestion : suggestion.label;
|
|
2381
|
+
}
|
|
2382
|
+
function suggestionPrompt2(suggestion) {
|
|
2383
|
+
return typeof suggestion === "string" ? suggestion : suggestion.prompt ?? suggestion.label;
|
|
2384
|
+
}
|
|
2385
|
+
function EmptyStateFallback({
|
|
1753
2386
|
subtitle,
|
|
1754
2387
|
suggestions,
|
|
1755
|
-
onSuggestionClick
|
|
2388
|
+
onSuggestionClick,
|
|
2389
|
+
greeting
|
|
1756
2390
|
}) {
|
|
1757
|
-
return /* @__PURE__ */ jsxs7(
|
|
1758
|
-
/* @__PURE__ */
|
|
1759
|
-
subtitle && /* @__PURE__ */
|
|
1760
|
-
suggestions && suggestions.length > 0 && /* @__PURE__ */
|
|
2391
|
+
return /* @__PURE__ */ jsxs7(Fragment7, { children: [
|
|
2392
|
+
/* @__PURE__ */ jsx11("div", { className: "pactor-chat-empty__greeting", children: greeting }),
|
|
2393
|
+
subtitle && /* @__PURE__ */ jsx11("div", { className: "pactor-chat-empty__subtitle", children: subtitle }),
|
|
2394
|
+
suggestions && suggestions.length > 0 && /* @__PURE__ */ jsx11("div", { className: "pactor-chat-empty__suggestions", children: suggestions.map((suggestion) => /* @__PURE__ */ jsx11(
|
|
1761
2395
|
"button",
|
|
1762
2396
|
{
|
|
1763
2397
|
type: "button",
|
|
1764
2398
|
className: "pactor-chat-empty__suggestion",
|
|
1765
|
-
onClick: () => onSuggestionClick?.(
|
|
1766
|
-
children:
|
|
2399
|
+
onClick: () => onSuggestionClick?.(suggestionPrompt2(suggestion)),
|
|
2400
|
+
children: suggestionLabel2(suggestion)
|
|
1767
2401
|
},
|
|
1768
|
-
|
|
2402
|
+
suggestionLabel2(suggestion)
|
|
1769
2403
|
)) })
|
|
1770
2404
|
] });
|
|
1771
2405
|
}
|
|
2406
|
+
function EmptyState({
|
|
2407
|
+
greeting = DEFAULT_CHAT_GREETING,
|
|
2408
|
+
subtitle,
|
|
2409
|
+
suggestions,
|
|
2410
|
+
onSuggestionClick
|
|
2411
|
+
}) {
|
|
2412
|
+
return /* @__PURE__ */ jsx11("div", { className: "pactor-chat-empty", children: /* @__PURE__ */ jsx11(
|
|
2413
|
+
ChromeSlot,
|
|
2414
|
+
{
|
|
2415
|
+
fragment: buildEmptyStateFragment({ greeting, subtitle, suggestions }),
|
|
2416
|
+
fallback: /* @__PURE__ */ jsx11(
|
|
2417
|
+
EmptyStateFallback,
|
|
2418
|
+
{
|
|
2419
|
+
greeting,
|
|
2420
|
+
subtitle,
|
|
2421
|
+
suggestions,
|
|
2422
|
+
onSuggestionClick
|
|
2423
|
+
}
|
|
2424
|
+
)
|
|
2425
|
+
}
|
|
2426
|
+
) });
|
|
2427
|
+
}
|
|
1772
2428
|
|
|
1773
2429
|
// src/view/MessageBubble.tsx
|
|
1774
|
-
import { useRef as
|
|
2430
|
+
import { useRef as useRef9, useState as useState11 } from "react";
|
|
1775
2431
|
|
|
1776
2432
|
// src/view/ActivityTrace.tsx
|
|
1777
|
-
import {
|
|
1778
|
-
Brain,
|
|
1779
|
-
CheckCircle2,
|
|
1780
|
-
ChevronRight,
|
|
1781
|
-
Clock,
|
|
1782
|
-
Loader2,
|
|
1783
|
-
XCircle
|
|
1784
|
-
} from "lucide-react";
|
|
2433
|
+
import { Icon as Icon7 } from "@pactor-app/ui/components";
|
|
1785
2434
|
import { MarkdownRenderer as MarkdownRenderer3 } from "@pactor-app/markdown";
|
|
1786
|
-
import { useEffect as
|
|
1787
|
-
import { Fragment as
|
|
2435
|
+
import { useEffect as useEffect6, useRef as useRef7, useState as useState9 } from "react";
|
|
2436
|
+
import { Fragment as Fragment8, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1788
2437
|
function usePinnedCollapse(autoOpen) {
|
|
1789
|
-
const [state, setState] =
|
|
2438
|
+
const [state, setState] = useState9("auto");
|
|
1790
2439
|
const open = state === "auto" ? autoOpen : state === "pinned-open";
|
|
1791
2440
|
const toggle = () => {
|
|
1792
2441
|
setState(open ? "pinned-closed" : "pinned-open");
|
|
@@ -1812,8 +2461,8 @@ function statusText(message, mode, toolCount) {
|
|
|
1812
2461
|
}
|
|
1813
2462
|
function useElapsedSeconds(startedAt, active) {
|
|
1814
2463
|
const compute = () => Math.max(0, Math.floor((Date.now() - startedAt) / 1e3));
|
|
1815
|
-
const [elapsed, setElapsed] =
|
|
1816
|
-
|
|
2464
|
+
const [elapsed, setElapsed] = useState9(compute);
|
|
2465
|
+
useEffect6(() => {
|
|
1817
2466
|
if (!active) {
|
|
1818
2467
|
setElapsed(compute());
|
|
1819
2468
|
return;
|
|
@@ -1827,15 +2476,15 @@ function useElapsedSeconds(startedAt, active) {
|
|
|
1827
2476
|
}
|
|
1828
2477
|
function TraceStatusIcon({ status }) {
|
|
1829
2478
|
if (status === "running") {
|
|
1830
|
-
return /* @__PURE__ */
|
|
2479
|
+
return /* @__PURE__ */ jsx12(Icon7, { name: "loading", size: 13, className: "pactor-chat-spin" });
|
|
1831
2480
|
}
|
|
1832
2481
|
if (status === "success") {
|
|
1833
|
-
return /* @__PURE__ */
|
|
2482
|
+
return /* @__PURE__ */ jsx12(Icon7, { name: "check-circle", size: 13 });
|
|
1834
2483
|
}
|
|
1835
2484
|
if (status === "failed") {
|
|
1836
|
-
return /* @__PURE__ */
|
|
2485
|
+
return /* @__PURE__ */ jsx12(Icon7, { name: "x-circle", size: 13 });
|
|
1837
2486
|
}
|
|
1838
|
-
return /* @__PURE__ */
|
|
2487
|
+
return /* @__PURE__ */ jsx12(Icon7, { name: "clock", size: 13 });
|
|
1839
2488
|
}
|
|
1840
2489
|
function summarizeArgs(args) {
|
|
1841
2490
|
if (args === void 0) {
|
|
@@ -1864,7 +2513,7 @@ function formatDetail(value) {
|
|
|
1864
2513
|
}
|
|
1865
2514
|
}
|
|
1866
2515
|
function TraceRow({ entry }) {
|
|
1867
|
-
const [open, setOpen] =
|
|
2516
|
+
const [open, setOpen] = useState9(false);
|
|
1868
2517
|
const summary = summarizeArgs(entry.args);
|
|
1869
2518
|
return /* @__PURE__ */ jsxs8(
|
|
1870
2519
|
"div",
|
|
@@ -1881,16 +2530,16 @@ function TraceRow({ entry }) {
|
|
|
1881
2530
|
"aria-expanded": open,
|
|
1882
2531
|
onClick: () => setOpen((value) => !value),
|
|
1883
2532
|
children: [
|
|
1884
|
-
/* @__PURE__ */
|
|
1885
|
-
/* @__PURE__ */
|
|
1886
|
-
/* @__PURE__ */
|
|
1887
|
-
summary && /* @__PURE__ */
|
|
2533
|
+
/* @__PURE__ */ jsx12("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ jsx12(Icon7, { name: "chevron-right", size: 12 }) }),
|
|
2534
|
+
/* @__PURE__ */ jsx12("span", { className: "pactor-chat-trace__entry-icon", children: /* @__PURE__ */ jsx12(TraceStatusIcon, { status: entry.status }) }),
|
|
2535
|
+
/* @__PURE__ */ jsx12("span", { className: "pactor-chat-trace__entry-title", children: entry.title ?? entry.name }),
|
|
2536
|
+
summary && /* @__PURE__ */ jsx12("span", { className: "pactor-chat-trace__entry-args", children: summary })
|
|
1888
2537
|
]
|
|
1889
2538
|
}
|
|
1890
2539
|
),
|
|
1891
2540
|
open && /* @__PURE__ */ jsxs8("div", { className: "pactor-chat-trace__entry-body", children: [
|
|
1892
|
-
entry.args !== void 0 && /* @__PURE__ */
|
|
1893
|
-
/* @__PURE__ */
|
|
2541
|
+
entry.args !== void 0 && /* @__PURE__ */ jsx12("pre", { className: "pactor-chat-trace__entry-detail", children: formatDetail(entry.args) }),
|
|
2542
|
+
/* @__PURE__ */ jsx12("pre", { className: "pactor-chat-trace__entry-detail", children: entry.status === "failed" ? entry.error ?? "\u6267\u884C\u5931\u8D25" : formatDetail(entry.result) })
|
|
1894
2543
|
] })
|
|
1895
2544
|
]
|
|
1896
2545
|
}
|
|
@@ -1917,13 +2566,13 @@ function ThinkingCard({
|
|
|
1917
2566
|
"aria-expanded": open,
|
|
1918
2567
|
onClick: toggle,
|
|
1919
2568
|
children: [
|
|
1920
|
-
/* @__PURE__ */
|
|
1921
|
-
/* @__PURE__ */
|
|
1922
|
-
/* @__PURE__ */
|
|
2569
|
+
/* @__PURE__ */ jsx12("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ jsx12(Icon7, { name: "chevron-right", size: 12 }) }),
|
|
2570
|
+
/* @__PURE__ */ jsx12("span", { className: "pactor-chat-thinking__icon", children: partStreaming ? /* @__PURE__ */ jsx12(Icon7, { name: "loading", size: 13, className: "pactor-chat-spin" }) : /* @__PURE__ */ jsx12(Icon7, { name: "brain", size: 13 }) }),
|
|
2571
|
+
/* @__PURE__ */ jsx12("span", { children: "\u601D\u8003\u8FC7\u7A0B" })
|
|
1923
2572
|
]
|
|
1924
2573
|
}
|
|
1925
2574
|
),
|
|
1926
|
-
open && /* @__PURE__ */
|
|
2575
|
+
open && /* @__PURE__ */ jsx12("div", { className: "pactor-chat-thinking__body", children: /* @__PURE__ */ jsx12(MarkdownRenderer3, { content: part.content }) })
|
|
1927
2576
|
]
|
|
1928
2577
|
}
|
|
1929
2578
|
);
|
|
@@ -1945,9 +2594,9 @@ function ActivityTrace({ message }) {
|
|
|
1945
2594
|
message.createdAt ?? mountTimeRef.current,
|
|
1946
2595
|
streaming
|
|
1947
2596
|
);
|
|
1948
|
-
const header = /* @__PURE__ */ jsxs8(
|
|
1949
|
-
/* @__PURE__ */
|
|
1950
|
-
/* @__PURE__ */
|
|
2597
|
+
const header = /* @__PURE__ */ jsxs8(Fragment8, { children: [
|
|
2598
|
+
/* @__PURE__ */ jsx12("span", { className: "pactor-chat-trace__status-icon", children: streaming ? /* @__PURE__ */ jsx12(Icon7, { name: "loading", size: 13, className: "pactor-chat-spin" }) : /* @__PURE__ */ jsx12(Icon7, { name: "check-circle", size: 13 }) }),
|
|
2599
|
+
/* @__PURE__ */ jsx12(
|
|
1951
2600
|
"span",
|
|
1952
2601
|
{
|
|
1953
2602
|
className: `pactor-chat-trace__status-text${streaming ? " pactor-chat-trace__status-text--breathing" : ""}`,
|
|
@@ -1958,10 +2607,10 @@ function ActivityTrace({ message }) {
|
|
|
1958
2607
|
elapsed,
|
|
1959
2608
|
"s"
|
|
1960
2609
|
] }),
|
|
1961
|
-
entries.length > 0 && /* @__PURE__ */
|
|
2610
|
+
entries.length > 0 && /* @__PURE__ */ jsx12("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ jsx12(Icon7, { name: "chevron-right", size: 12 }) })
|
|
1962
2611
|
] });
|
|
1963
2612
|
return /* @__PURE__ */ jsxs8("div", { className: "pactor-chat-trace", "data-open": open, children: [
|
|
1964
|
-
entries.length > 0 ? /* @__PURE__ */
|
|
2613
|
+
entries.length > 0 ? /* @__PURE__ */ jsx12(
|
|
1965
2614
|
"button",
|
|
1966
2615
|
{
|
|
1967
2616
|
type: "button",
|
|
@@ -1970,8 +2619,8 @@ function ActivityTrace({ message }) {
|
|
|
1970
2619
|
onClick: toggle,
|
|
1971
2620
|
children: header
|
|
1972
2621
|
}
|
|
1973
|
-
) : /* @__PURE__ */
|
|
1974
|
-
thinkingParts.map((part, index) => /* @__PURE__ */
|
|
2622
|
+
) : /* @__PURE__ */ jsx12("div", { className: "pactor-chat-trace__header", children: header }),
|
|
2623
|
+
thinkingParts.map((part, index) => /* @__PURE__ */ jsx12(
|
|
1975
2624
|
ThinkingCard,
|
|
1976
2625
|
{
|
|
1977
2626
|
part,
|
|
@@ -1979,36 +2628,66 @@ function ActivityTrace({ message }) {
|
|
|
1979
2628
|
},
|
|
1980
2629
|
part.id ?? index
|
|
1981
2630
|
)),
|
|
1982
|
-
open && entries.length > 0 && /* @__PURE__ */
|
|
2631
|
+
open && entries.length > 0 && /* @__PURE__ */ jsx12("div", { className: "pactor-chat-trace__entries", children: entries.map((entry) => /* @__PURE__ */ jsx12(TraceRow, { entry }, entry.callIndex)) })
|
|
1983
2632
|
] });
|
|
1984
2633
|
}
|
|
1985
2634
|
|
|
1986
2635
|
// src/view/MessageActions.tsx
|
|
1987
|
-
import {
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2636
|
+
import { Icon as Icon8 } from "@pactor-app/ui/components";
|
|
2637
|
+
import { useEffect as useEffect7, useRef as useRef8, useState as useState10 } from "react";
|
|
2638
|
+
|
|
2639
|
+
// src/view/chrome/message-actions.tsx
|
|
2640
|
+
function buildMessageActionsFragment(args) {
|
|
2641
|
+
const { actions, copied, token } = args;
|
|
2642
|
+
return {
|
|
2643
|
+
requires: ["Flex", "Tooltip", "Button", "Icon"],
|
|
2644
|
+
node: {
|
|
2645
|
+
type: "Flex",
|
|
2646
|
+
props: { gap: "small" },
|
|
2647
|
+
children: actions.map((action) => {
|
|
2648
|
+
const copiedFeedback = action.builtin === "copy" && copied;
|
|
2649
|
+
const label = copiedFeedback ? "\u5DF2\u590D\u5236" : action.label;
|
|
2650
|
+
const iconName = copiedFeedback ? "check" : action.icon;
|
|
2651
|
+
return {
|
|
2652
|
+
type: "Tooltip",
|
|
2653
|
+
props: { content: label },
|
|
2654
|
+
children: [
|
|
2655
|
+
{
|
|
2656
|
+
type: "Button",
|
|
2657
|
+
props: {
|
|
2658
|
+
variant: "text",
|
|
2659
|
+
size: "small",
|
|
2660
|
+
className: "pactor-chat-icon-button"
|
|
2661
|
+
},
|
|
2662
|
+
events: {
|
|
2663
|
+
onClick: [
|
|
2664
|
+
{
|
|
2665
|
+
action: "chat.messageAction",
|
|
2666
|
+
params: { token, actionId: action.id }
|
|
2667
|
+
}
|
|
2668
|
+
]
|
|
2669
|
+
},
|
|
2670
|
+
children: [
|
|
2671
|
+
{
|
|
2672
|
+
type: "Icon",
|
|
2673
|
+
props: {
|
|
2674
|
+
// 契约图标名直通 ui Icon 白名单(spec: chat-icon-convergence;
|
|
2675
|
+
// 未知名由 ui Icon 渲染占位)
|
|
2676
|
+
name: iconName ?? "help-circle",
|
|
2677
|
+
size: 14
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
]
|
|
2681
|
+
}
|
|
2682
|
+
]
|
|
2683
|
+
};
|
|
2684
|
+
})
|
|
2685
|
+
}
|
|
2686
|
+
};
|
|
2687
|
+
}
|
|
2688
|
+
|
|
2689
|
+
// src/view/MessageActions.tsx
|
|
2690
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
2012
2691
|
var BUILTIN_ACTION_DEFAULTS = {
|
|
2013
2692
|
copy: {
|
|
2014
2693
|
label: "\u590D\u5236",
|
|
@@ -2081,7 +2760,21 @@ function MessageActions({
|
|
|
2081
2760
|
callService,
|
|
2082
2761
|
onMessageAction
|
|
2083
2762
|
}) {
|
|
2084
|
-
const [copied, setCopied] =
|
|
2763
|
+
const [copied, setCopied] = useState10(false);
|
|
2764
|
+
const dispatchRef = useRef8(
|
|
2765
|
+
() => {
|
|
2766
|
+
}
|
|
2767
|
+
);
|
|
2768
|
+
const visibleActionsRef = useRef8([]);
|
|
2769
|
+
useEffect7(() => {
|
|
2770
|
+
setMessageActionDispatcher(message.id, (actionId) => {
|
|
2771
|
+
const action = visibleActionsRef.current.find((a) => a.id === actionId);
|
|
2772
|
+
if (action) {
|
|
2773
|
+
dispatchRef.current(action);
|
|
2774
|
+
}
|
|
2775
|
+
});
|
|
2776
|
+
return () => clearMessageActionDispatcher(message.id);
|
|
2777
|
+
}, [message.id]);
|
|
2085
2778
|
const copy = async () => {
|
|
2086
2779
|
try {
|
|
2087
2780
|
await navigator.clipboard.writeText(collectMessageText(message));
|
|
@@ -2141,41 +2834,53 @@ function MessageActions({
|
|
|
2141
2834
|
}
|
|
2142
2835
|
onMessageAction?.(action.id, message);
|
|
2143
2836
|
};
|
|
2144
|
-
|
|
2837
|
+
dispatchRef.current = dispatch;
|
|
2838
|
+
visibleActionsRef.current = visibleActions;
|
|
2839
|
+
const buttons = visibleActions.map((action) => {
|
|
2840
|
+
const copiedFeedback = action.builtin === "copy" && copied;
|
|
2841
|
+
const label = copiedFeedback ? "\u5DF2\u590D\u5236" : action.label;
|
|
2842
|
+
const iconName = copiedFeedback ? "check" : action.icon;
|
|
2843
|
+
return /* @__PURE__ */ jsx13(
|
|
2844
|
+
"button",
|
|
2845
|
+
{
|
|
2846
|
+
type: "button",
|
|
2847
|
+
className: "pactor-chat-icon-button",
|
|
2848
|
+
title: label,
|
|
2849
|
+
"aria-label": label,
|
|
2850
|
+
"data-message-action": action.id,
|
|
2851
|
+
onClick: () => dispatch(action),
|
|
2852
|
+
children: iconName !== void 0 ? /* @__PURE__ */ jsx13(Icon8, { name: iconName, size: 14 }) : /* @__PURE__ */ jsx13(Icon8, { name: "help-circle", size: 14 })
|
|
2853
|
+
},
|
|
2854
|
+
action.id
|
|
2855
|
+
);
|
|
2856
|
+
});
|
|
2857
|
+
return /* @__PURE__ */ jsx13(
|
|
2145
2858
|
"div",
|
|
2146
2859
|
{
|
|
2147
2860
|
className: `pactor-chat-message__actions${forceVisible ? " pactor-chat-message__actions--visible" : ""}`,
|
|
2148
|
-
children:
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
"aria-label": label,
|
|
2160
|
-
"data-message-action": action.id,
|
|
2161
|
-
onClick: () => dispatch(action),
|
|
2162
|
-
children: Icon ? /* @__PURE__ */ jsx10(Icon, { size: 14 }) : /* @__PURE__ */ jsx10(HelpCircle, { size: 14, "data-icon-placeholder": "true" })
|
|
2163
|
-
},
|
|
2164
|
-
action.id
|
|
2165
|
-
);
|
|
2166
|
-
})
|
|
2861
|
+
children: /* @__PURE__ */ jsx13(
|
|
2862
|
+
ChromeSlot,
|
|
2863
|
+
{
|
|
2864
|
+
fragment: buildMessageActionsFragment({
|
|
2865
|
+
actions: visibleActions,
|
|
2866
|
+
copied,
|
|
2867
|
+
token: message.id
|
|
2868
|
+
}),
|
|
2869
|
+
fallback: buttons
|
|
2870
|
+
}
|
|
2871
|
+
)
|
|
2167
2872
|
}
|
|
2168
2873
|
);
|
|
2169
2874
|
}
|
|
2170
2875
|
|
|
2171
2876
|
// src/view/MessageBubble.tsx
|
|
2172
|
-
import { jsx as
|
|
2877
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2173
2878
|
function MessageEditForm({
|
|
2174
2879
|
initialText,
|
|
2175
2880
|
onConfirm,
|
|
2176
2881
|
onCancel
|
|
2177
2882
|
}) {
|
|
2178
|
-
const [text, setText] =
|
|
2883
|
+
const [text, setText] = useState11(initialText);
|
|
2179
2884
|
const confirm = () => {
|
|
2180
2885
|
const value = text.trim();
|
|
2181
2886
|
if (!value) {
|
|
@@ -2184,7 +2889,7 @@ function MessageEditForm({
|
|
|
2184
2889
|
onConfirm(value);
|
|
2185
2890
|
};
|
|
2186
2891
|
return /* @__PURE__ */ jsxs9("div", { className: "pactor-chat-message__edit", children: [
|
|
2187
|
-
/* @__PURE__ */
|
|
2892
|
+
/* @__PURE__ */ jsx14(
|
|
2188
2893
|
"textarea",
|
|
2189
2894
|
{
|
|
2190
2895
|
className: "pactor-chat-message__edit-input",
|
|
@@ -2203,7 +2908,7 @@ function MessageEditForm({
|
|
|
2203
2908
|
}
|
|
2204
2909
|
),
|
|
2205
2910
|
/* @__PURE__ */ jsxs9("div", { className: "pactor-chat-message__edit-actions", children: [
|
|
2206
|
-
/* @__PURE__ */
|
|
2911
|
+
/* @__PURE__ */ jsx14(
|
|
2207
2912
|
"button",
|
|
2208
2913
|
{
|
|
2209
2914
|
type: "button",
|
|
@@ -2213,7 +2918,7 @@ function MessageEditForm({
|
|
|
2213
2918
|
children: "\u53D1\u9001"
|
|
2214
2919
|
}
|
|
2215
2920
|
),
|
|
2216
|
-
/* @__PURE__ */
|
|
2921
|
+
/* @__PURE__ */ jsx14(
|
|
2217
2922
|
"button",
|
|
2218
2923
|
{
|
|
2219
2924
|
type: "button",
|
|
@@ -2239,7 +2944,7 @@ function MessageBubble({
|
|
|
2239
2944
|
onMessageAction,
|
|
2240
2945
|
onOpenArtifact
|
|
2241
2946
|
}) {
|
|
2242
|
-
const [editing, setEditing] =
|
|
2947
|
+
const [editing, setEditing] = useState11(false);
|
|
2243
2948
|
const bubbleScope = {
|
|
2244
2949
|
conversation: scope?.conversation ?? {},
|
|
2245
2950
|
message: { id: message.id },
|
|
@@ -2247,7 +2952,7 @@ function MessageBubble({
|
|
|
2247
2952
|
};
|
|
2248
2953
|
const streaming = message.status === "streaming";
|
|
2249
2954
|
const live = message.status === "pending" || message.status === "streaming";
|
|
2250
|
-
const wasLiveRef =
|
|
2955
|
+
const wasLiveRef = useRef9(live);
|
|
2251
2956
|
if (live) {
|
|
2252
2957
|
wasLiveRef.current = true;
|
|
2253
2958
|
}
|
|
@@ -2261,7 +2966,7 @@ function MessageBubble({
|
|
|
2261
2966
|
"data-message-id": message.id,
|
|
2262
2967
|
"data-message-status": message.status,
|
|
2263
2968
|
children: [
|
|
2264
|
-
editing ? /* @__PURE__ */
|
|
2969
|
+
editing ? /* @__PURE__ */ jsx14(
|
|
2265
2970
|
MessageEditForm,
|
|
2266
2971
|
{
|
|
2267
2972
|
initialText: collectMessageText(message),
|
|
@@ -2272,8 +2977,8 @@ function MessageBubble({
|
|
|
2272
2977
|
onCancel: () => setEditing(false)
|
|
2273
2978
|
}
|
|
2274
2979
|
) : /* @__PURE__ */ jsxs9("div", { className: "pactor-chat-message__body", children: [
|
|
2275
|
-
showTrace && /* @__PURE__ */
|
|
2276
|
-
message.parts.length === 0 && message.status === "pending" && message.role !== "assistant" ? /* @__PURE__ */
|
|
2980
|
+
showTrace && /* @__PURE__ */ jsx14(ActivityTrace, { message }),
|
|
2981
|
+
message.parts.length === 0 && message.status === "pending" && message.role !== "assistant" ? /* @__PURE__ */ jsx14("span", { className: "pactor-chat-message__pending", children: "\u2026" }) : message.parts.map((part, index) => /* @__PURE__ */ jsx14(
|
|
2277
2982
|
PartRenderer,
|
|
2278
2983
|
{
|
|
2279
2984
|
part,
|
|
@@ -2285,7 +2990,7 @@ function MessageBubble({
|
|
|
2285
2990
|
part.id ?? index
|
|
2286
2991
|
))
|
|
2287
2992
|
] }),
|
|
2288
|
-
!editing && /* @__PURE__ */
|
|
2993
|
+
!editing && /* @__PURE__ */ jsx14(
|
|
2289
2994
|
MessageActions,
|
|
2290
2995
|
{
|
|
2291
2996
|
message,
|
|
@@ -2305,7 +3010,7 @@ function MessageBubble({
|
|
|
2305
3010
|
}
|
|
2306
3011
|
|
|
2307
3012
|
// src/view/ChatView.tsx
|
|
2308
|
-
import { jsx as
|
|
3013
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2309
3014
|
function lastContentLength(messages) {
|
|
2310
3015
|
const last = messages[messages.length - 1];
|
|
2311
3016
|
if (!last) {
|
|
@@ -2339,6 +3044,8 @@ function ChatView({
|
|
|
2339
3044
|
onAttachmentClick,
|
|
2340
3045
|
toolbarStart,
|
|
2341
3046
|
toolbarEnd,
|
|
3047
|
+
composerFooter,
|
|
3048
|
+
hideToolbar,
|
|
2342
3049
|
onMentionTrigger,
|
|
2343
3050
|
onPlusMenu,
|
|
2344
3051
|
models,
|
|
@@ -2349,7 +3056,8 @@ function ChatView({
|
|
|
2349
3056
|
onContextsChange,
|
|
2350
3057
|
callService,
|
|
2351
3058
|
messageActions,
|
|
2352
|
-
onMessageAction
|
|
3059
|
+
onMessageAction,
|
|
3060
|
+
composerBottom
|
|
2353
3061
|
}) {
|
|
2354
3062
|
const messages = useSyncExternalStore(
|
|
2355
3063
|
(listener) => store.subscribe(listener),
|
|
@@ -2379,8 +3087,8 @@ function ChatView({
|
|
|
2379
3087
|
() => ({ conversation: { id: conversationId }, params }),
|
|
2380
3088
|
[conversationId, params]
|
|
2381
3089
|
);
|
|
2382
|
-
const notifiedArtifactsRef =
|
|
2383
|
-
|
|
3090
|
+
const notifiedArtifactsRef = useRef10(/* @__PURE__ */ new Set());
|
|
3091
|
+
useEffect8(() => {
|
|
2384
3092
|
if (!onArtifact) {
|
|
2385
3093
|
return;
|
|
2386
3094
|
}
|
|
@@ -2399,7 +3107,7 @@ function ChatView({
|
|
|
2399
3107
|
});
|
|
2400
3108
|
}
|
|
2401
3109
|
}, [messages, onArtifact]);
|
|
2402
|
-
const abortRef =
|
|
3110
|
+
const abortRef = useRef10(null);
|
|
2403
3111
|
const { containerRef, isFollowing, scrollToBottom } = useChatAutoScroll({
|
|
2404
3112
|
messageCount: messages.length,
|
|
2405
3113
|
lastContentLength: lastContentLength(messages),
|
|
@@ -2410,7 +3118,7 @@ function ChatView({
|
|
|
2410
3118
|
model,
|
|
2411
3119
|
onModelChange
|
|
2412
3120
|
});
|
|
2413
|
-
const [contextChips, setContextChips] =
|
|
3121
|
+
const [contextChips, setContextChips] = useState12([]);
|
|
2414
3122
|
const handleContextChipsChange = (chips) => {
|
|
2415
3123
|
setContextChips(chips);
|
|
2416
3124
|
onContextsChange?.(chips);
|
|
@@ -2442,6 +3150,16 @@ function ChatView({
|
|
|
2442
3150
|
abortRef.current?.abort();
|
|
2443
3151
|
abortRef.current = null;
|
|
2444
3152
|
};
|
|
3153
|
+
const handleSendRef = useRef10(handleSend);
|
|
3154
|
+
handleSendRef.current = handleSend;
|
|
3155
|
+
const onOpenArtifactRef = useRef10(onOpenArtifact);
|
|
3156
|
+
onOpenArtifactRef.current = onOpenArtifact;
|
|
3157
|
+
useEffect8(() => {
|
|
3158
|
+
setChatChromeHandlers({
|
|
3159
|
+
sendSuggestion: (text) => handleSendRef.current(text),
|
|
3160
|
+
openArtifact: (artifact) => onOpenArtifactRef.current?.(artifact)
|
|
3161
|
+
});
|
|
3162
|
+
}, []);
|
|
2445
3163
|
const handleRegenerate = () => {
|
|
2446
3164
|
if (!transport) {
|
|
2447
3165
|
return;
|
|
@@ -2459,7 +3177,7 @@ function ChatView({
|
|
|
2459
3177
|
const lastMessage = messages[messages.length - 1];
|
|
2460
3178
|
const regenerableMessageId = lastMessage?.role === "assistant" && lastMessage.status === "completed" ? lastMessage.id : void 0;
|
|
2461
3179
|
const isEmpty = messages.length === 0;
|
|
2462
|
-
const composerNode = /* @__PURE__ */
|
|
3180
|
+
const composerNode = /* @__PURE__ */ jsx15(
|
|
2463
3181
|
Composer,
|
|
2464
3182
|
{
|
|
2465
3183
|
onSend: handleSend,
|
|
@@ -2471,6 +3189,8 @@ function ChatView({
|
|
|
2471
3189
|
onAttachmentClick,
|
|
2472
3190
|
toolbarStart,
|
|
2473
3191
|
toolbarEnd,
|
|
3192
|
+
composerFooter,
|
|
3193
|
+
hideToolbar,
|
|
2474
3194
|
onMentionTrigger,
|
|
2475
3195
|
onPlusMenu,
|
|
2476
3196
|
models: modelPlacement === "header" ? void 0 : models,
|
|
@@ -2482,6 +3202,10 @@ function ChatView({
|
|
|
2482
3202
|
callService
|
|
2483
3203
|
}
|
|
2484
3204
|
);
|
|
3205
|
+
const composerDock = /* @__PURE__ */ jsxs10("div", { className: "pactor-chat-view__composer-dock", children: [
|
|
3206
|
+
composerNode,
|
|
3207
|
+
composerBottom !== void 0 && composerBottom !== null ? /* @__PURE__ */ jsx15("div", { className: "pactor-chat-view__composer-bottom", children: composerBottom }) : null
|
|
3208
|
+
] });
|
|
2485
3209
|
return /* @__PURE__ */ jsxs10(
|
|
2486
3210
|
"div",
|
|
2487
3211
|
{
|
|
@@ -2489,7 +3213,7 @@ function ChatView({
|
|
|
2489
3213
|
children: [
|
|
2490
3214
|
/* @__PURE__ */ jsxs10("div", { className: "pactor-chat-messages", ref: containerRef, children: [
|
|
2491
3215
|
isEmpty ? /* @__PURE__ */ jsxs10("div", { className: "pactor-chat-view__empty-stack", children: [
|
|
2492
|
-
/* @__PURE__ */
|
|
3216
|
+
/* @__PURE__ */ jsx15(
|
|
2493
3217
|
EmptyState,
|
|
2494
3218
|
{
|
|
2495
3219
|
greeting,
|
|
@@ -2498,8 +3222,8 @@ function ChatView({
|
|
|
2498
3222
|
onSuggestionClick: handleSend
|
|
2499
3223
|
}
|
|
2500
3224
|
),
|
|
2501
|
-
|
|
2502
|
-
] }) : messages.map((message) => /* @__PURE__ */
|
|
3225
|
+
composerDock
|
|
3226
|
+
] }) : messages.map((message) => /* @__PURE__ */ jsx15(
|
|
2503
3227
|
MessageBubble,
|
|
2504
3228
|
{
|
|
2505
3229
|
message,
|
|
@@ -2523,21 +3247,21 @@ function ChatView({
|
|
|
2523
3247
|
className: "pactor-chat-scroll-bottom",
|
|
2524
3248
|
onClick: scrollToBottom,
|
|
2525
3249
|
children: [
|
|
2526
|
-
/* @__PURE__ */
|
|
3250
|
+
/* @__PURE__ */ jsx15(Icon9, { name: "arrow-down", size: 13 }),
|
|
2527
3251
|
"\u56DE\u5230\u5E95\u90E8"
|
|
2528
3252
|
]
|
|
2529
3253
|
}
|
|
2530
3254
|
)
|
|
2531
3255
|
] }),
|
|
2532
|
-
!isEmpty &&
|
|
3256
|
+
!isEmpty && composerDock
|
|
2533
3257
|
]
|
|
2534
3258
|
}
|
|
2535
3259
|
);
|
|
2536
3260
|
}
|
|
2537
3261
|
|
|
2538
3262
|
// src/view/WorkspaceHeader.tsx
|
|
2539
|
-
import {
|
|
2540
|
-
import { useRef as
|
|
3263
|
+
import { Icon as Icon10 } from "@pactor-app/ui/components";
|
|
3264
|
+
import { useEffect as useEffect9, useRef as useRef11, useState as useState13 } from "react";
|
|
2541
3265
|
|
|
2542
3266
|
// src/export-markdown.ts
|
|
2543
3267
|
var ROLE_LABELS = {
|
|
@@ -2569,8 +3293,52 @@ function downloadMessagesAsMarkdown(title, messages) {
|
|
|
2569
3293
|
URL.revokeObjectURL(url);
|
|
2570
3294
|
}
|
|
2571
3295
|
|
|
3296
|
+
// src/view/chrome/header-actions.tsx
|
|
3297
|
+
function buildHeaderActionsFragment(props) {
|
|
3298
|
+
const meta = {
|
|
3299
|
+
export: { label: "\u5BFC\u51FA Markdown", icon: "download" },
|
|
3300
|
+
theme: {
|
|
3301
|
+
label: props.theme === "dark" ? "\u5207\u6362\u4E3A\u6D45\u8272" : "\u5207\u6362\u4E3A\u6DF1\u8272",
|
|
3302
|
+
icon: props.theme === "dark" ? "sun" : "moon"
|
|
3303
|
+
},
|
|
3304
|
+
clear: { label: "\u6E05\u7A7A\u4F1A\u8BDD", icon: "trash2" }
|
|
3305
|
+
};
|
|
3306
|
+
return {
|
|
3307
|
+
requires: ["Flex", "Tooltip", "Button", "Icon"],
|
|
3308
|
+
node: {
|
|
3309
|
+
type: "Flex",
|
|
3310
|
+
props: { gap: "small", align: "center" },
|
|
3311
|
+
children: props.actions.map((action) => ({
|
|
3312
|
+
type: "Tooltip",
|
|
3313
|
+
props: { content: meta[action].label },
|
|
3314
|
+
children: [
|
|
3315
|
+
{
|
|
3316
|
+
type: "Button",
|
|
3317
|
+
props: {
|
|
3318
|
+
variant: "text",
|
|
3319
|
+
size: "small",
|
|
3320
|
+
className: "pactor-chat-icon-button"
|
|
3321
|
+
},
|
|
3322
|
+
events: {
|
|
3323
|
+
onClick: [
|
|
3324
|
+
{ action: "chat.headerAction", params: { action } }
|
|
3325
|
+
]
|
|
3326
|
+
},
|
|
3327
|
+
children: [
|
|
3328
|
+
{
|
|
3329
|
+
type: "Icon",
|
|
3330
|
+
props: { name: meta[action].icon, size: 15 }
|
|
3331
|
+
}
|
|
3332
|
+
]
|
|
3333
|
+
}
|
|
3334
|
+
]
|
|
3335
|
+
}))
|
|
3336
|
+
}
|
|
3337
|
+
};
|
|
3338
|
+
}
|
|
3339
|
+
|
|
2572
3340
|
// src/view/WorkspaceHeader.tsx
|
|
2573
|
-
import { jsx as
|
|
3341
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2574
3342
|
function readCurrentTheme() {
|
|
2575
3343
|
if (typeof document === "undefined") {
|
|
2576
3344
|
return "light";
|
|
@@ -2590,10 +3358,10 @@ function WorkspaceHeader({
|
|
|
2590
3358
|
onTitleChange
|
|
2591
3359
|
}) {
|
|
2592
3360
|
const hasActions = headerActions !== void 0 && headerActions.length > 0;
|
|
2593
|
-
const [overrideTitle, setOverrideTitle] =
|
|
2594
|
-
const [editing, setEditing] =
|
|
2595
|
-
const [draft, setDraft] =
|
|
2596
|
-
const prevTitleRef =
|
|
3361
|
+
const [overrideTitle, setOverrideTitle] = useState13(null);
|
|
3362
|
+
const [editing, setEditing] = useState13(false);
|
|
3363
|
+
const [draft, setDraft] = useState13("");
|
|
3364
|
+
const prevTitleRef = useRef11(title);
|
|
2597
3365
|
if (prevTitleRef.current !== title) {
|
|
2598
3366
|
prevTitleRef.current = title;
|
|
2599
3367
|
if (overrideTitle !== null) {
|
|
@@ -2601,7 +3369,7 @@ function WorkspaceHeader({
|
|
|
2601
3369
|
}
|
|
2602
3370
|
}
|
|
2603
3371
|
const displayTitle = overrideTitle ?? title;
|
|
2604
|
-
const [theme, setTheme] =
|
|
3372
|
+
const [theme, setTheme] = useState13(readCurrentTheme);
|
|
2605
3373
|
const commitTitle = () => {
|
|
2606
3374
|
setEditing(false);
|
|
2607
3375
|
const next = draft.trim();
|
|
@@ -2628,8 +3396,24 @@ function WorkspaceHeader({
|
|
|
2628
3396
|
store.clear();
|
|
2629
3397
|
onClear?.();
|
|
2630
3398
|
};
|
|
3399
|
+
const handlersRef = useRef11({ handleExport, handleTheme, handleClear });
|
|
3400
|
+
handlersRef.current = { handleExport, handleTheme, handleClear };
|
|
3401
|
+
useEffect9(() => {
|
|
3402
|
+
setChatChromeHandlers({
|
|
3403
|
+
headerAction: (name) => {
|
|
3404
|
+
const handlers2 = handlersRef.current;
|
|
3405
|
+
if (name === "export") {
|
|
3406
|
+
handlers2.handleExport();
|
|
3407
|
+
} else if (name === "theme") {
|
|
3408
|
+
handlers2.handleTheme();
|
|
3409
|
+
} else if (name === "clear") {
|
|
3410
|
+
handlers2.handleClear();
|
|
3411
|
+
}
|
|
3412
|
+
}
|
|
3413
|
+
});
|
|
3414
|
+
}, []);
|
|
2631
3415
|
const actionButtons = {
|
|
2632
|
-
export: /* @__PURE__ */
|
|
3416
|
+
export: /* @__PURE__ */ jsx16(
|
|
2633
3417
|
"button",
|
|
2634
3418
|
{
|
|
2635
3419
|
type: "button",
|
|
@@ -2637,11 +3421,11 @@ function WorkspaceHeader({
|
|
|
2637
3421
|
title: "\u5BFC\u51FA Markdown",
|
|
2638
3422
|
"aria-label": "\u5BFC\u51FA Markdown",
|
|
2639
3423
|
onClick: handleExport,
|
|
2640
|
-
children: /* @__PURE__ */
|
|
3424
|
+
children: /* @__PURE__ */ jsx16(Icon10, { name: "download", size: 15 })
|
|
2641
3425
|
},
|
|
2642
3426
|
"export"
|
|
2643
3427
|
),
|
|
2644
|
-
theme: /* @__PURE__ */
|
|
3428
|
+
theme: /* @__PURE__ */ jsx16(
|
|
2645
3429
|
"button",
|
|
2646
3430
|
{
|
|
2647
3431
|
type: "button",
|
|
@@ -2649,11 +3433,11 @@ function WorkspaceHeader({
|
|
|
2649
3433
|
title: theme === "dark" ? "\u5207\u6362\u4E3A\u6D45\u8272" : "\u5207\u6362\u4E3A\u6DF1\u8272",
|
|
2650
3434
|
"aria-label": "\u5207\u6362\u660E\u6697\u4E3B\u9898",
|
|
2651
3435
|
onClick: handleTheme,
|
|
2652
|
-
children: theme === "dark" ? /* @__PURE__ */
|
|
3436
|
+
children: theme === "dark" ? /* @__PURE__ */ jsx16(Icon10, { name: "sun", size: 15 }) : /* @__PURE__ */ jsx16(Icon10, { name: "moon", size: 15 })
|
|
2653
3437
|
},
|
|
2654
3438
|
"theme"
|
|
2655
3439
|
),
|
|
2656
|
-
clear: /* @__PURE__ */
|
|
3440
|
+
clear: /* @__PURE__ */ jsx16(
|
|
2657
3441
|
"button",
|
|
2658
3442
|
{
|
|
2659
3443
|
type: "button",
|
|
@@ -2661,12 +3445,12 @@ function WorkspaceHeader({
|
|
|
2661
3445
|
title: "\u6E05\u7A7A\u4F1A\u8BDD",
|
|
2662
3446
|
"aria-label": "\u6E05\u7A7A\u4F1A\u8BDD",
|
|
2663
3447
|
onClick: handleClear,
|
|
2664
|
-
children: /* @__PURE__ */
|
|
3448
|
+
children: /* @__PURE__ */ jsx16(Icon10, { name: "trash", size: 15 })
|
|
2665
3449
|
},
|
|
2666
3450
|
"clear"
|
|
2667
3451
|
)
|
|
2668
3452
|
};
|
|
2669
|
-
const titleNode = editableTitle ? editing ? /* @__PURE__ */
|
|
3453
|
+
const titleNode = editableTitle ? editing ? /* @__PURE__ */ jsx16(
|
|
2670
3454
|
"input",
|
|
2671
3455
|
{
|
|
2672
3456
|
className: "pactor-chat-workspace__title-input",
|
|
@@ -2683,7 +3467,7 @@ function WorkspaceHeader({
|
|
|
2683
3467
|
}
|
|
2684
3468
|
}
|
|
2685
3469
|
}
|
|
2686
|
-
) : /* @__PURE__ */
|
|
3470
|
+
) : /* @__PURE__ */ jsx16(
|
|
2687
3471
|
"button",
|
|
2688
3472
|
{
|
|
2689
3473
|
type: "button",
|
|
@@ -2695,7 +3479,7 @@ function WorkspaceHeader({
|
|
|
2695
3479
|
},
|
|
2696
3480
|
children: displayTitle
|
|
2697
3481
|
}
|
|
2698
|
-
) : /* @__PURE__ */
|
|
3482
|
+
) : /* @__PURE__ */ jsx16("div", { className: "pactor-chat-workspace__title", children: title });
|
|
2699
3483
|
return /* @__PURE__ */ jsxs11("header", { className: "pactor-chat-workspace__header", children: [
|
|
2700
3484
|
headerStart !== void 0 ? (
|
|
2701
3485
|
// header 位模型 chip(决策 D2):与 title 组成左端组,chip 在前
|
|
@@ -2705,19 +3489,28 @@ function WorkspaceHeader({
|
|
|
2705
3489
|
] })
|
|
2706
3490
|
) : titleNode,
|
|
2707
3491
|
hasActions ? /* @__PURE__ */ jsxs11("div", { className: "pactor-chat-workspace__header-right", children: [
|
|
2708
|
-
/* @__PURE__ */
|
|
2709
|
-
|
|
2710
|
-
|
|
3492
|
+
/* @__PURE__ */ jsx16("div", { className: "pactor-chat-workspace__header-actions", children: /* @__PURE__ */ jsx16(
|
|
3493
|
+
ChromeSlot,
|
|
3494
|
+
{
|
|
3495
|
+
fragment: buildHeaderActionsFragment({
|
|
3496
|
+
actions: headerActions,
|
|
3497
|
+
theme
|
|
3498
|
+
}),
|
|
3499
|
+
fallback: headerActions.map((action) => actionButtons[action])
|
|
3500
|
+
}
|
|
3501
|
+
) }),
|
|
3502
|
+
headerExtra !== void 0 ? /* @__PURE__ */ jsx16("div", { className: "pactor-chat-workspace__header-extra", children: headerExtra }) : null
|
|
3503
|
+
] }) : headerExtra !== void 0 ? /* @__PURE__ */ jsx16("div", { className: "pactor-chat-workspace__header-extra", children: headerExtra }) : null
|
|
2711
3504
|
] });
|
|
2712
3505
|
}
|
|
2713
3506
|
|
|
2714
3507
|
// src/chat-composition.tsx
|
|
2715
|
-
import { Fragment as
|
|
3508
|
+
import { Fragment as Fragment9, jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2716
3509
|
function DslNodeSlotInner({ node }) {
|
|
2717
|
-
const { renderChildren } =
|
|
3510
|
+
const { renderChildren } = useRenderer4();
|
|
2718
3511
|
return renderChildren([node]);
|
|
2719
3512
|
}
|
|
2720
|
-
var DslSlotGuard = class extends
|
|
3513
|
+
var DslSlotGuard = class extends Component3 {
|
|
2721
3514
|
constructor() {
|
|
2722
3515
|
super(...arguments);
|
|
2723
3516
|
this.state = { failed: false };
|
|
@@ -2735,7 +3528,7 @@ var DslSlotGuard = class extends Component2 {
|
|
|
2735
3528
|
}
|
|
2736
3529
|
};
|
|
2737
3530
|
function DslNodeSlot({ node }) {
|
|
2738
|
-
return /* @__PURE__ */
|
|
3531
|
+
return /* @__PURE__ */ jsx17(DslSlotGuard, { children: /* @__PURE__ */ jsx17(DslNodeSlotInner, { node }) });
|
|
2739
3532
|
}
|
|
2740
3533
|
function isDslNodeValue(value) {
|
|
2741
3534
|
return typeof value === "object" && value !== null && !Array.isArray(value) && !isValidElement(value) && typeof value.type === "string";
|
|
@@ -2745,7 +3538,7 @@ function resolveSlot(slot) {
|
|
|
2745
3538
|
return void 0;
|
|
2746
3539
|
}
|
|
2747
3540
|
if (isDslNodeValue(slot)) {
|
|
2748
|
-
return /* @__PURE__ */
|
|
3541
|
+
return /* @__PURE__ */ jsx17(DslNodeSlot, { node: slot });
|
|
2749
3542
|
}
|
|
2750
3543
|
return slot;
|
|
2751
3544
|
}
|
|
@@ -2775,7 +3568,11 @@ function ChatComposition({
|
|
|
2775
3568
|
messageActions,
|
|
2776
3569
|
onMessageAction,
|
|
2777
3570
|
sidebar,
|
|
3571
|
+
toolbarStart,
|
|
2778
3572
|
toolbarEnd,
|
|
3573
|
+
composerFooter,
|
|
3574
|
+
composerBottom,
|
|
3575
|
+
hideToolbar,
|
|
2779
3576
|
className,
|
|
2780
3577
|
onSend,
|
|
2781
3578
|
artifact,
|
|
@@ -2785,12 +3582,12 @@ function ChatComposition({
|
|
|
2785
3582
|
onArtifact,
|
|
2786
3583
|
onOpenArtifact
|
|
2787
3584
|
}) {
|
|
2788
|
-
const storeRef =
|
|
3585
|
+
const storeRef = useRef12(null);
|
|
2789
3586
|
if (storeRef.current === null) {
|
|
2790
3587
|
storeRef.current = services.store ?? services.storeFactory?.() ?? new ConversationStore();
|
|
2791
3588
|
}
|
|
2792
3589
|
const store = storeRef.current;
|
|
2793
|
-
const artifactStoreRef =
|
|
3590
|
+
const artifactStoreRef = useRef12(null);
|
|
2794
3591
|
if (artifactStoreRef.current === null) {
|
|
2795
3592
|
artifactStoreRef.current = services.artifactStore ?? new ArtifactStore();
|
|
2796
3593
|
}
|
|
@@ -2814,7 +3611,7 @@ function ChatComposition({
|
|
|
2814
3611
|
artifactStore.open(next);
|
|
2815
3612
|
}
|
|
2816
3613
|
};
|
|
2817
|
-
const [attachments, setAttachments] =
|
|
3614
|
+
const [attachments, setAttachments] = useState14([]);
|
|
2818
3615
|
const handleAttachFiles = services.onAttachFiles ? (files) => {
|
|
2819
3616
|
void Promise.resolve(services.onAttachFiles(files)).then(
|
|
2820
3617
|
(created) => {
|
|
@@ -2834,24 +3631,38 @@ function ChatComposition({
|
|
|
2834
3631
|
model,
|
|
2835
3632
|
onModelChange
|
|
2836
3633
|
});
|
|
2837
|
-
const headerModelChip = modelPlacement === "header" && modelsEnabled ? /* @__PURE__ */
|
|
2838
|
-
|
|
3634
|
+
const headerModelChip = modelPlacement === "header" && modelsEnabled ? /* @__PURE__ */ jsx17(
|
|
3635
|
+
ModelSelect,
|
|
2839
3636
|
{
|
|
2840
3637
|
models,
|
|
2841
3638
|
model: currentModel,
|
|
2842
3639
|
onModelChange: handleModelChange
|
|
2843
3640
|
}
|
|
2844
3641
|
) : void 0;
|
|
2845
|
-
const mergedToolbarEnd = services.toolbarEnd !== void 0 || toolbarEnd !== void 0 ? /* @__PURE__ */ jsxs12(
|
|
3642
|
+
const mergedToolbarEnd = services.toolbarEnd !== void 0 || toolbarEnd !== void 0 ? /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
2846
3643
|
services.toolbarEnd,
|
|
2847
3644
|
toolbarEnd
|
|
2848
3645
|
] }) : void 0;
|
|
3646
|
+
const mergedToolbarStart = services.toolbarStart !== void 0 || toolbarStart !== void 0 ? /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
3647
|
+
services.toolbarStart,
|
|
3648
|
+
toolbarStart
|
|
3649
|
+
] }) : void 0;
|
|
3650
|
+
const mergedComposerFooter = services.composerFooter !== void 0 || composerFooter !== void 0 ? /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
3651
|
+
services.composerFooter,
|
|
3652
|
+
composerFooter
|
|
3653
|
+
] }) : void 0;
|
|
3654
|
+
const mergedComposerBottom = services.composerBottom !== void 0 || composerBottom !== void 0 ? /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
3655
|
+
services.composerBottom,
|
|
3656
|
+
composerBottom
|
|
3657
|
+
] }) : void 0;
|
|
3658
|
+
const hasHeaderContent = header !== void 0 && header !== null ? true : title !== void 0 || headerExtra !== void 0 && headerExtra !== null || headerActions !== void 0 && headerActions.length > 0 || headerModelChip !== void 0;
|
|
3659
|
+
const renderHeader = showHeader !== false && hasHeaderContent;
|
|
2849
3660
|
const workspace = /* @__PURE__ */ jsxs12(
|
|
2850
3661
|
"div",
|
|
2851
3662
|
{
|
|
2852
3663
|
className: `pactor-chat-workspace${className ? ` ${className}` : ""}`,
|
|
2853
3664
|
children: [
|
|
2854
|
-
|
|
3665
|
+
renderHeader ? header ?? /* @__PURE__ */ jsx17(
|
|
2855
3666
|
WorkspaceHeader,
|
|
2856
3667
|
{
|
|
2857
3668
|
title,
|
|
@@ -2866,7 +3677,7 @@ function ChatComposition({
|
|
|
2866
3677
|
onTitleChange
|
|
2867
3678
|
}
|
|
2868
3679
|
) : null,
|
|
2869
|
-
/* @__PURE__ */
|
|
3680
|
+
/* @__PURE__ */ jsx17(
|
|
2870
3681
|
ChatView,
|
|
2871
3682
|
{
|
|
2872
3683
|
store,
|
|
@@ -2886,8 +3697,11 @@ function ChatComposition({
|
|
|
2886
3697
|
onAttachmentsChange: setAttachments,
|
|
2887
3698
|
onAttachFiles: handleAttachFiles,
|
|
2888
3699
|
onAttachmentClick: services.onAttachmentClick,
|
|
2889
|
-
toolbarStart:
|
|
3700
|
+
toolbarStart: mergedToolbarStart,
|
|
2890
3701
|
toolbarEnd: mergedToolbarEnd,
|
|
3702
|
+
composerFooter: mergedComposerFooter,
|
|
3703
|
+
composerBottom: mergedComposerBottom,
|
|
3704
|
+
hideToolbar,
|
|
2891
3705
|
onMentionTrigger: services.onMentionTrigger,
|
|
2892
3706
|
onPlusMenu: services.onPlusMenu,
|
|
2893
3707
|
onArtifact,
|
|
@@ -2906,15 +3720,15 @@ function ChatComposition({
|
|
|
2906
3720
|
]
|
|
2907
3721
|
}
|
|
2908
3722
|
);
|
|
2909
|
-
const main = sidebar ? /* @__PURE__ */
|
|
3723
|
+
const main = sidebar ? /* @__PURE__ */ jsx17(AppShell, { sidebar, children: workspace }) : workspace;
|
|
2910
3724
|
const panelFeatureUsed = artifact !== void 0 || panelOpen !== void 0 || inspector !== void 0 || onPanelClose !== void 0 || onArtifact !== void 0 || onOpenArtifact !== void 0 || services.artifactStore !== void 0;
|
|
2911
3725
|
if (!panelFeatureUsed && !effectivePanelOpen) {
|
|
2912
3726
|
return main;
|
|
2913
3727
|
}
|
|
2914
3728
|
return /* @__PURE__ */ jsxs12("div", { className: "pactor-chat-inspector-host", children: [
|
|
2915
3729
|
main,
|
|
2916
|
-
effectivePanelOpen ? /* @__PURE__ */ jsxs12(
|
|
2917
|
-
/* @__PURE__ */
|
|
3730
|
+
effectivePanelOpen ? /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
3731
|
+
/* @__PURE__ */ jsx17(
|
|
2918
3732
|
"div",
|
|
2919
3733
|
{
|
|
2920
3734
|
className: "pactor-chat-inspector__scrim",
|
|
@@ -2922,7 +3736,7 @@ function ChatComposition({
|
|
|
2922
3736
|
onClick: handlePanelClose
|
|
2923
3737
|
}
|
|
2924
3738
|
),
|
|
2925
|
-
/* @__PURE__ */
|
|
3739
|
+
/* @__PURE__ */ jsx17(
|
|
2926
3740
|
ArtifactPanel,
|
|
2927
3741
|
{
|
|
2928
3742
|
artifact: effectiveArtifact,
|
|
@@ -2938,20 +3752,20 @@ function ChatComposition({
|
|
|
2938
3752
|
|
|
2939
3753
|
// src/chat-services.tsx
|
|
2940
3754
|
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
2941
|
-
import { jsx as
|
|
3755
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2942
3756
|
var ChatServicesContext = createContext2(null);
|
|
2943
3757
|
function ChatServicesProvider({
|
|
2944
3758
|
value,
|
|
2945
3759
|
children
|
|
2946
3760
|
}) {
|
|
2947
|
-
return /* @__PURE__ */
|
|
3761
|
+
return /* @__PURE__ */ jsx18(ChatServicesContext.Provider, { value, children });
|
|
2948
3762
|
}
|
|
2949
3763
|
function useChatServices() {
|
|
2950
3764
|
return useContext2(ChatServicesContext);
|
|
2951
3765
|
}
|
|
2952
3766
|
|
|
2953
3767
|
// src/chat-workspace.tsx
|
|
2954
|
-
import { jsx as
|
|
3768
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2955
3769
|
function createChatWorkspace(services) {
|
|
2956
3770
|
function ChatWorkspace({
|
|
2957
3771
|
title,
|
|
@@ -2961,7 +3775,11 @@ function createChatWorkspace(services) {
|
|
|
2961
3775
|
conversationId,
|
|
2962
3776
|
params,
|
|
2963
3777
|
sidebar,
|
|
3778
|
+
toolbarStart,
|
|
2964
3779
|
toolbarEnd,
|
|
3780
|
+
composerFooter,
|
|
3781
|
+
composerBottom,
|
|
3782
|
+
hideToolbar,
|
|
2965
3783
|
artifact,
|
|
2966
3784
|
panelOpen,
|
|
2967
3785
|
onPanelClose,
|
|
@@ -2984,7 +3802,7 @@ function createChatWorkspace(services) {
|
|
|
2984
3802
|
onMessageAction,
|
|
2985
3803
|
className
|
|
2986
3804
|
}) {
|
|
2987
|
-
return /* @__PURE__ */
|
|
3805
|
+
return /* @__PURE__ */ jsx19(ChatServicesProvider, { value: services, children: /* @__PURE__ */ jsx19(
|
|
2988
3806
|
ChatComposition,
|
|
2989
3807
|
{
|
|
2990
3808
|
services,
|
|
@@ -2995,15 +3813,17 @@ function createChatWorkspace(services) {
|
|
|
2995
3813
|
conversationId,
|
|
2996
3814
|
params,
|
|
2997
3815
|
className,
|
|
2998
|
-
showHeader: title !== void 0 || services.headerExtra !== void 0 || // header 位模型 chip(决策 D2):仅配置 models 也渲染极简头部
|
|
2999
|
-
modelPlacement === "header" && models !== void 0 && models.length > 0,
|
|
3000
3816
|
headerExtra: services.headerExtra,
|
|
3001
|
-
sidebar: sidebar ? /* @__PURE__ */
|
|
3002
|
-
|
|
3817
|
+
sidebar: sidebar ? /* @__PURE__ */ jsx19(DslNodeSlot, { node: sidebar }) : void 0,
|
|
3818
|
+
toolbarStart: toolbarStart ? /* @__PURE__ */ jsx19(DslNodeSlot, { node: toolbarStart }) : void 0,
|
|
3819
|
+
toolbarEnd: toolbarEnd ? /* @__PURE__ */ jsx19(DslNodeSlot, { node: toolbarEnd }) : void 0,
|
|
3820
|
+
composerFooter: composerFooter ? /* @__PURE__ */ jsx19(DslNodeSlot, { node: composerFooter }) : void 0,
|
|
3821
|
+
composerBottom: composerBottom ? /* @__PURE__ */ jsx19(DslNodeSlot, { node: composerBottom }) : void 0,
|
|
3822
|
+
hideToolbar,
|
|
3003
3823
|
artifact,
|
|
3004
3824
|
panelOpen,
|
|
3005
3825
|
onPanelClose,
|
|
3006
|
-
inspector: inspector ? /* @__PURE__ */
|
|
3826
|
+
inspector: inspector ? /* @__PURE__ */ jsx19(DslNodeSlot, { node: inspector }) : void 0,
|
|
3007
3827
|
onArtifact,
|
|
3008
3828
|
onOpenArtifact,
|
|
3009
3829
|
headerActions,
|
|
@@ -3027,23 +3847,37 @@ function createChatWorkspace(services) {
|
|
|
3027
3847
|
}
|
|
3028
3848
|
|
|
3029
3849
|
// src/view/Chat.tsx
|
|
3030
|
-
import {
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3850
|
+
import { Icon as Icon11, RailTooltip } from "@pactor-app/ui/components";
|
|
3851
|
+
import { Fragment as Fragment10, useEffect as useEffect10, useRef as useRef13 } from "react";
|
|
3852
|
+
|
|
3853
|
+
// src/view/chrome/menu.tsx
|
|
3854
|
+
function buildSidebarMenuFragment(props) {
|
|
3855
|
+
return {
|
|
3856
|
+
requires: ["Menu"],
|
|
3857
|
+
node: {
|
|
3858
|
+
type: "Menu",
|
|
3859
|
+
props: {
|
|
3860
|
+
mode: "inline",
|
|
3861
|
+
selectedKey: props.activeMenuKey,
|
|
3862
|
+
items: props.menu.map((item) => ({
|
|
3863
|
+
key: item.key,
|
|
3864
|
+
label: item.label,
|
|
3865
|
+
...item.icon !== void 0 ? { icon: item.icon } : {},
|
|
3866
|
+
...item.badge !== void 0 ? { badge: item.badge } : {},
|
|
3867
|
+
...item.dot === true ? { dot: true } : {},
|
|
3868
|
+
...item.group !== void 0 ? { group: item.group } : {},
|
|
3869
|
+
...item.disabled === true ? { disabled: true } : {}
|
|
3870
|
+
}))
|
|
3871
|
+
},
|
|
3872
|
+
events: {
|
|
3873
|
+
onSelect: [{ action: "chat.menuSelect", params: { key: "${event}" } }]
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
};
|
|
3877
|
+
}
|
|
3044
3878
|
|
|
3045
3879
|
// src/view/ChatShell.tsx
|
|
3046
|
-
import { jsx as
|
|
3880
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
3047
3881
|
function ChatShell({
|
|
3048
3882
|
menu,
|
|
3049
3883
|
activeMenuKey,
|
|
@@ -3055,7 +3889,7 @@ function ChatShell({
|
|
|
3055
3889
|
className,
|
|
3056
3890
|
onMenuSelect
|
|
3057
3891
|
}) {
|
|
3058
|
-
const sidebarContent = resolveSlot(sidebar) ?? (menu && menu.length > 0 ? /* @__PURE__ */
|
|
3892
|
+
const sidebarContent = resolveSlot(sidebar) ?? (menu && menu.length > 0 ? /* @__PURE__ */ jsx20(
|
|
3059
3893
|
ChatSidebarMenu,
|
|
3060
3894
|
{
|
|
3061
3895
|
menu,
|
|
@@ -3063,7 +3897,7 @@ function ChatShell({
|
|
|
3063
3897
|
onMenuSelect
|
|
3064
3898
|
}
|
|
3065
3899
|
) : null);
|
|
3066
|
-
return /* @__PURE__ */
|
|
3900
|
+
return /* @__PURE__ */ jsx20(
|
|
3067
3901
|
AppShell,
|
|
3068
3902
|
{
|
|
3069
3903
|
sidebar: sidebarContent,
|
|
@@ -3080,7 +3914,7 @@ function ChatShellDslAdapter({
|
|
|
3080
3914
|
onMenuSelect,
|
|
3081
3915
|
...rest
|
|
3082
3916
|
}) {
|
|
3083
|
-
return /* @__PURE__ */
|
|
3917
|
+
return /* @__PURE__ */ jsx20(
|
|
3084
3918
|
ChatShell,
|
|
3085
3919
|
{
|
|
3086
3920
|
...rest,
|
|
@@ -3095,39 +3929,45 @@ function registerChatShellComponent(registry) {
|
|
|
3095
3929
|
}
|
|
3096
3930
|
|
|
3097
3931
|
// src/view/Chat.tsx
|
|
3098
|
-
import { jsx as
|
|
3099
|
-
var MENU_ICONS = {
|
|
3100
|
-
plus: Plus2,
|
|
3101
|
-
chat: MessageSquare,
|
|
3102
|
-
history: History,
|
|
3103
|
-
settings: Settings,
|
|
3104
|
-
star: Star,
|
|
3105
|
-
search: Search,
|
|
3106
|
-
user: User,
|
|
3107
|
-
folder: Folder
|
|
3108
|
-
};
|
|
3932
|
+
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3109
3933
|
function ChatSidebarMenu({
|
|
3110
3934
|
menu,
|
|
3111
3935
|
activeMenuKey,
|
|
3112
3936
|
onMenuSelect
|
|
3113
3937
|
}) {
|
|
3114
3938
|
const drawer = useSidebarDrawer();
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3939
|
+
const menuRef = useRef13(menu);
|
|
3940
|
+
menuRef.current = menu;
|
|
3941
|
+
const selectRef = useRef13(onMenuSelect);
|
|
3942
|
+
selectRef.current = onMenuSelect;
|
|
3943
|
+
const drawerRef = useRef13(drawer);
|
|
3944
|
+
drawerRef.current = drawer;
|
|
3945
|
+
useEffect10(() => {
|
|
3946
|
+
setChatChromeHandlers({
|
|
3947
|
+
menuSelect: (key) => {
|
|
3948
|
+
const item = menuRef.current.find((entry) => entry.key === key);
|
|
3949
|
+
if (item === void 0 || item.disabled === true) {
|
|
3950
|
+
return;
|
|
3951
|
+
}
|
|
3952
|
+
selectRef.current?.(key, item);
|
|
3953
|
+
drawerRef.current?.close();
|
|
3954
|
+
}
|
|
3955
|
+
});
|
|
3956
|
+
}, []);
|
|
3957
|
+
const fallback = (() => {
|
|
3958
|
+
let lastGroup;
|
|
3959
|
+
return /* @__PURE__ */ jsx21("nav", { className: "pactor-chat-menu", "aria-label": "\u4F1A\u8BDD\u5BFC\u822A", children: menu.map((item) => {
|
|
3960
|
+
const groupLabel = item.group !== void 0 && item.group !== lastGroup ? item.group : void 0;
|
|
3961
|
+
lastGroup = item.group;
|
|
3962
|
+
const active = item.key === activeMenuKey;
|
|
3963
|
+
const collapsed = drawer?.collapsed === true;
|
|
3964
|
+
const button = /* @__PURE__ */ jsxs13(
|
|
3124
3965
|
"button",
|
|
3125
3966
|
{
|
|
3126
3967
|
type: "button",
|
|
3127
3968
|
className: `pactor-chat-menu__item${active ? " pactor-chat-menu__item--active" : ""}`,
|
|
3128
3969
|
disabled: item.disabled === true,
|
|
3129
3970
|
"aria-current": active ? "true" : void 0,
|
|
3130
|
-
title: drawer?.collapsed ? item.label : void 0,
|
|
3131
3971
|
onClick: () => {
|
|
3132
3972
|
if (item.disabled) {
|
|
3133
3973
|
return;
|
|
@@ -3136,21 +3976,26 @@ function ChatSidebarMenu({
|
|
|
3136
3976
|
drawer?.close();
|
|
3137
3977
|
},
|
|
3138
3978
|
children: [
|
|
3139
|
-
item.icon !== void 0 ?
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
"aria-hidden": true
|
|
3144
|
-
}
|
|
3145
|
-
) : null,
|
|
3146
|
-
/* @__PURE__ */ jsx18("span", { className: "pactor-chat-menu__label", children: item.label }),
|
|
3147
|
-
item.dot === true ? /* @__PURE__ */ jsx18("span", { className: "pactor-chat-menu__dot", "aria-hidden": true }) : null,
|
|
3148
|
-
item.badge !== void 0 ? /* @__PURE__ */ jsx18("span", { className: "pactor-chat-menu__badge", children: item.badge }) : null
|
|
3979
|
+
item.icon !== void 0 ? /* @__PURE__ */ jsx21("span", { className: "pactor-chat-menu__icon", children: /* @__PURE__ */ jsx21(Icon11, { name: item.icon, size: 15, strokeWidth: 1.7 }) }) : null,
|
|
3980
|
+
/* @__PURE__ */ jsx21("span", { className: "pactor-chat-menu__label", children: item.label }),
|
|
3981
|
+
item.dot === true ? /* @__PURE__ */ jsx21("span", { className: "pactor-chat-menu__dot", "aria-hidden": true }) : null,
|
|
3982
|
+
item.badge !== void 0 ? /* @__PURE__ */ jsx21("span", { className: "pactor-chat-menu__badge", children: item.badge }) : null
|
|
3149
3983
|
]
|
|
3150
3984
|
}
|
|
3151
|
-
)
|
|
3152
|
-
|
|
3153
|
-
|
|
3985
|
+
);
|
|
3986
|
+
return /* @__PURE__ */ jsxs13(Fragment10, { children: [
|
|
3987
|
+
groupLabel !== void 0 ? /* @__PURE__ */ jsx21("div", { className: "pactor-chat-menu__group", children: groupLabel }) : null,
|
|
3988
|
+
collapsed ? /* @__PURE__ */ jsx21(RailTooltip, { label: item.label, children: button }) : button
|
|
3989
|
+
] }, item.key);
|
|
3990
|
+
}) });
|
|
3991
|
+
})();
|
|
3992
|
+
return /* @__PURE__ */ jsx21(
|
|
3993
|
+
ChromeSlot,
|
|
3994
|
+
{
|
|
3995
|
+
fragment: buildSidebarMenuFragment({ menu, activeMenuKey }),
|
|
3996
|
+
fallback
|
|
3997
|
+
}
|
|
3998
|
+
);
|
|
3154
3999
|
}
|
|
3155
4000
|
function Chat({
|
|
3156
4001
|
title,
|
|
@@ -3163,6 +4008,11 @@ function Chat({
|
|
|
3163
4008
|
menu,
|
|
3164
4009
|
activeMenuKey,
|
|
3165
4010
|
sidebar,
|
|
4011
|
+
toolbarStart,
|
|
4012
|
+
toolbarEnd,
|
|
4013
|
+
composerFooter,
|
|
4014
|
+
composerBottom,
|
|
4015
|
+
hideToolbar,
|
|
3166
4016
|
headerExtra,
|
|
3167
4017
|
header,
|
|
3168
4018
|
headerActions,
|
|
@@ -3190,7 +4040,7 @@ function Chat({
|
|
|
3190
4040
|
onMenuSelect
|
|
3191
4041
|
}) {
|
|
3192
4042
|
const services = useChatServices();
|
|
3193
|
-
|
|
4043
|
+
useEffect10(() => {
|
|
3194
4044
|
if (!services) {
|
|
3195
4045
|
console.warn(
|
|
3196
4046
|
"[@pactor-app/chat] Chat \u672A\u68C0\u6D4B\u5230 ChatServicesProvider\uFF1A\u8BF7\u5728\u5E94\u7528\u6839\u90E8\u4EE5 <ChatServicesProvider> \u6CE8\u5165 transport \u7B49\u670D\u52A1"
|
|
@@ -3198,10 +4048,10 @@ function Chat({
|
|
|
3198
4048
|
}
|
|
3199
4049
|
}, [services]);
|
|
3200
4050
|
if (!services) {
|
|
3201
|
-
return /* @__PURE__ */
|
|
4051
|
+
return /* @__PURE__ */ jsx21("div", { className: "pactor-chat-notice", role: "note", children: "\u672A\u914D\u7F6E\u804A\u5929\u670D\u52A1\uFF1A\u8BF7\u5728 Chat \u5916\u5C42\u4F7F\u7528 ChatServicesProvider \u6CE8\u5165 transport \u7B49\u670D\u52A1\u540E\u91CD\u8BD5\u3002" });
|
|
3202
4052
|
}
|
|
3203
4053
|
const sidebarSlot = resolveSlot(sidebar);
|
|
3204
|
-
const sidebarContent = sidebarSlot ?? (menu && menu.length > 0 ? /* @__PURE__ */
|
|
4054
|
+
const sidebarContent = sidebarSlot ?? (menu && menu.length > 0 ? /* @__PURE__ */ jsx21(
|
|
3205
4055
|
ChatSidebarMenu,
|
|
3206
4056
|
{
|
|
3207
4057
|
menu,
|
|
@@ -3209,7 +4059,7 @@ function Chat({
|
|
|
3209
4059
|
onMenuSelect
|
|
3210
4060
|
}
|
|
3211
4061
|
) : void 0);
|
|
3212
|
-
return /* @__PURE__ */
|
|
4062
|
+
return /* @__PURE__ */ jsx21(
|
|
3213
4063
|
ChatComposition,
|
|
3214
4064
|
{
|
|
3215
4065
|
services,
|
|
@@ -3220,9 +4070,14 @@ function Chat({
|
|
|
3220
4070
|
conversationId,
|
|
3221
4071
|
params,
|
|
3222
4072
|
className,
|
|
3223
|
-
showHeader
|
|
4073
|
+
showHeader,
|
|
3224
4074
|
header: resolveSlot(header),
|
|
3225
4075
|
headerExtra: resolveSlot(headerExtra) ?? services.headerExtra,
|
|
4076
|
+
toolbarStart: resolveSlot(toolbarStart),
|
|
4077
|
+
toolbarEnd: resolveSlot(toolbarEnd),
|
|
4078
|
+
composerFooter: resolveSlot(composerFooter),
|
|
4079
|
+
composerBottom: resolveSlot(composerBottom),
|
|
4080
|
+
hideToolbar,
|
|
3226
4081
|
headerActions,
|
|
3227
4082
|
editableTitle,
|
|
3228
4083
|
onExport,
|
|
@@ -3264,7 +4119,7 @@ function ChatDslAdapter({
|
|
|
3264
4119
|
onTitleChange,
|
|
3265
4120
|
...rest
|
|
3266
4121
|
}) {
|
|
3267
|
-
return /* @__PURE__ */
|
|
4122
|
+
return /* @__PURE__ */ jsx21(
|
|
3268
4123
|
Chat,
|
|
3269
4124
|
{
|
|
3270
4125
|
...rest,
|
|
@@ -3291,11 +4146,11 @@ function registerChatComponent(registry) {
|
|
|
3291
4146
|
}
|
|
3292
4147
|
|
|
3293
4148
|
// src/view/ChatLayout.tsx
|
|
3294
|
-
import { jsx as
|
|
4149
|
+
import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3295
4150
|
function ChatLayout({ title, children }) {
|
|
3296
4151
|
return /* @__PURE__ */ jsxs14("div", { className: "pactor-chat-layout", children: [
|
|
3297
|
-
/* @__PURE__ */
|
|
3298
|
-
/* @__PURE__ */
|
|
4152
|
+
/* @__PURE__ */ jsx22("header", { className: "pactor-chat-layout__header", children: title ?? "Chat" }),
|
|
4153
|
+
/* @__PURE__ */ jsx22("main", { className: "pactor-chat-layout__main", children })
|
|
3299
4154
|
] });
|
|
3300
4155
|
}
|
|
3301
4156
|
var CHAT_LAYOUT_TYPE = "chat";
|
|
@@ -3324,8 +4179,6 @@ export {
|
|
|
3324
4179
|
ConversationStore,
|
|
3325
4180
|
DEFAULT_CHAT_GREETING,
|
|
3326
4181
|
EmptyState,
|
|
3327
|
-
MENU_ICONS,
|
|
3328
|
-
MESSAGE_ACTION_ICONS,
|
|
3329
4182
|
MessageActions,
|
|
3330
4183
|
MessageBubble,
|
|
3331
4184
|
PartRenderer,
|