@pactor-app/chat 1.0.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 +1461 -592
- package/dist/index.d.cts +97 -23
- package/dist/index.d.ts +97 -23
- package/dist/index.js +1435 -596
- package/package.json +7 -8
- package/styles.css +188 -176
package/dist/index.js
CHANGED
|
@@ -792,12 +792,12 @@ function useChatAutoScroll({
|
|
|
792
792
|
}
|
|
793
793
|
|
|
794
794
|
// src/chat-composition.tsx
|
|
795
|
-
import { useRenderer as
|
|
795
|
+
import { useRenderer as useRenderer4 } from "@pactor-app/runtime";
|
|
796
796
|
import {
|
|
797
|
-
Component as
|
|
797
|
+
Component as Component3,
|
|
798
798
|
isValidElement,
|
|
799
|
-
useRef as
|
|
800
|
-
useState as
|
|
799
|
+
useRef as useRef12,
|
|
800
|
+
useState as useState14,
|
|
801
801
|
useSyncExternalStore as useSyncExternalStore2
|
|
802
802
|
} from "react";
|
|
803
803
|
|
|
@@ -824,132 +824,283 @@ function useChatModel({
|
|
|
824
824
|
}
|
|
825
825
|
|
|
826
826
|
// src/view/AppShell.tsx
|
|
827
|
-
import { Menu, PanelLeft } from "lucide-react";
|
|
828
827
|
import {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
useState as useState4
|
|
834
|
-
} from "react";
|
|
835
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
836
|
-
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";
|
|
837
832
|
function useSidebarDrawer() {
|
|
838
|
-
return
|
|
833
|
+
return useUiSidebarDrawer();
|
|
839
834
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
function AppShell({ sidebar, brand, locationKey, sidebarFooter, collapsible = false, children, className }) {
|
|
860
|
-
const [drawerOpen, setDrawerOpen] = useState4(false);
|
|
861
|
-
const isMobile = useIsMobileViewport();
|
|
862
|
-
const close = useCallback2(() => setDrawerOpen(false), []);
|
|
863
|
-
const [collapsed, setCollapsed] = useState4(false);
|
|
864
|
-
const collapsedEffective = collapsible && collapsed && !isMobile;
|
|
865
|
-
const framed = brand !== void 0 || sidebarFooter !== void 0;
|
|
866
|
-
const [trackedLocationKey, setTrackedLocationKey] = useState4(locationKey);
|
|
867
|
-
if (trackedLocationKey !== locationKey) {
|
|
868
|
-
setTrackedLocationKey(locationKey);
|
|
869
|
-
setDrawerOpen(false);
|
|
870
|
-
}
|
|
871
|
-
useEffect2(() => {
|
|
872
|
-
if (!drawerOpen) {
|
|
873
|
-
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
|
|
874
854
|
}
|
|
875
|
-
|
|
876
|
-
if (event.key === "Escape") {
|
|
877
|
-
setDrawerOpen(false);
|
|
878
|
-
}
|
|
879
|
-
};
|
|
880
|
-
window.addEventListener("keydown", onKeyDown);
|
|
881
|
-
return () => window.removeEventListener("keydown", onKeyDown);
|
|
882
|
-
}, [drawerOpen]);
|
|
883
|
-
return /* @__PURE__ */ jsx(SidebarDrawerContext.Provider, { value: { close, collapsed: collapsedEffective }, children: /* @__PURE__ */ jsxs("div", { className: `pactor-chat-shell${className ? ` ${className}` : ""}`, children: [
|
|
884
|
-
drawerOpen ? /* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__scrim", "aria-hidden": true, onClick: close }) : null,
|
|
885
|
-
/* @__PURE__ */ jsx(
|
|
886
|
-
"div",
|
|
887
|
-
{
|
|
888
|
-
className: `pactor-chat-shell__sidebar${framed ? " pactor-chat-shell__sidebar--framed" : ""}${collapsedEffective ? " pactor-chat-shell__sidebar--collapsed" : ""}`,
|
|
889
|
-
"data-open": drawerOpen ? "true" : "false",
|
|
890
|
-
inert: isMobile && !drawerOpen ? true : void 0,
|
|
891
|
-
children: framed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
892
|
-
brand !== void 0 && // 桌面品牌行(决策 D3):brand 左、折叠钮右;移动端由
|
|
893
|
-
// CSS 隐藏(品牌维持顶栏现状)
|
|
894
|
-
/* @__PURE__ */ jsxs("div", { className: "pactor-chat-shell__sidebar-header", children: [
|
|
895
|
-
/* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__brand", children: brand }),
|
|
896
|
-
collapsible && !isMobile && /* @__PURE__ */ jsx(
|
|
897
|
-
"button",
|
|
898
|
-
{
|
|
899
|
-
type: "button",
|
|
900
|
-
className: "pactor-chat-icon-button pactor-chat-shell__collapse",
|
|
901
|
-
"aria-label": collapsedEffective ? "\u5C55\u5F00\u4FA7\u680F" : "\u6298\u53E0\u4FA7\u680F",
|
|
902
|
-
"aria-expanded": !collapsedEffective,
|
|
903
|
-
title: collapsedEffective ? "\u5C55\u5F00\u4FA7\u680F" : "\u6298\u53E0\u4FA7\u680F",
|
|
904
|
-
onClick: () => setCollapsed((value) => !value),
|
|
905
|
-
children: /* @__PURE__ */ jsx(PanelLeft, { size: 16, strokeWidth: 1.7 })
|
|
906
|
-
}
|
|
907
|
-
)
|
|
908
|
-
] }),
|
|
909
|
-
/* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__sidebar-body", children: sidebar }),
|
|
910
|
-
sidebarFooter !== void 0 && /* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__sidebar-footer", children: sidebarFooter })
|
|
911
|
-
] }) : sidebar
|
|
912
|
-
}
|
|
913
|
-
),
|
|
914
|
-
/* @__PURE__ */ jsxs("main", { className: "pactor-chat-shell__main", children: [
|
|
915
|
-
/* @__PURE__ */ jsxs("div", { className: "pactor-chat-shell__topbar", children: [
|
|
916
|
-
/* @__PURE__ */ jsx(
|
|
917
|
-
"button",
|
|
918
|
-
{
|
|
919
|
-
type: "button",
|
|
920
|
-
className: "pactor-chat-icon-button pactor-chat-shell__menu",
|
|
921
|
-
"aria-label": "\u6253\u5F00\u5BFC\u822A",
|
|
922
|
-
"aria-expanded": drawerOpen,
|
|
923
|
-
onClick: () => setDrawerOpen(true),
|
|
924
|
-
children: /* @__PURE__ */ jsx(Menu, { size: 18, strokeWidth: 1.7 })
|
|
925
|
-
}
|
|
926
|
-
),
|
|
927
|
-
brand
|
|
928
|
-
] }),
|
|
929
|
-
/* @__PURE__ */ jsx("div", { className: "pactor-chat-shell__content", children })
|
|
930
|
-
] })
|
|
931
|
-
] }) });
|
|
855
|
+
);
|
|
932
856
|
}
|
|
933
857
|
|
|
934
858
|
// src/view/ArtifactPanel.tsx
|
|
935
|
-
import {
|
|
859
|
+
import { Icon as Icon3 } from "@pactor-app/ui/components";
|
|
936
860
|
import { Registry as Registry2 } from "@pactor-app/core";
|
|
937
861
|
import { MarkdownRenderer as MarkdownRenderer2 } from "@pactor-app/markdown";
|
|
938
|
-
import { DslRenderer as DslRenderer2, useRenderer as
|
|
862
|
+
import { DslRenderer as DslRenderer2, useRenderer as useRenderer3 } from "@pactor-app/runtime";
|
|
939
863
|
import {
|
|
940
|
-
Component,
|
|
864
|
+
Component as Component2,
|
|
865
|
+
useEffect as useEffect2,
|
|
941
866
|
useMemo,
|
|
942
867
|
useRef as useRef3,
|
|
943
|
-
useState as
|
|
868
|
+
useState as useState4
|
|
944
869
|
} from "react";
|
|
945
870
|
|
|
946
871
|
// src/view/PartRenderer.tsx
|
|
947
|
-
import {
|
|
872
|
+
import { Icon } from "@pactor-app/ui/components";
|
|
948
873
|
import { MarkdownRenderer } from "@pactor-app/markdown";
|
|
949
|
-
import { DslRenderer, useRenderer } from "@pactor-app/runtime";
|
|
950
|
-
|
|
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";
|
|
951
1102
|
function ChatDenied({ deniedType }) {
|
|
952
|
-
return /* @__PURE__ */
|
|
1103
|
+
return /* @__PURE__ */ jsxs("div", { className: "pactor-chat-denied", "data-pactor-chat-denied": deniedType, children: [
|
|
953
1104
|
"\u8BE5\u7EC4\u4EF6\u4E0D\u5141\u8BB8\u5728 Chat \u4E2D\u4F7F\u7528",
|
|
954
1105
|
deniedType ? `\uFF1A${deniedType}` : ""
|
|
955
1106
|
] });
|
|
@@ -958,64 +1109,90 @@ function ChatDslNode({
|
|
|
958
1109
|
node,
|
|
959
1110
|
scope
|
|
960
1111
|
}) {
|
|
961
|
-
const renderer =
|
|
1112
|
+
const renderer = useRenderer2();
|
|
962
1113
|
const extraScope = scope ? buildChatScope(scope) : void 0;
|
|
963
|
-
return /* @__PURE__ */
|
|
1114
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children: renderer.renderChildren([node], extraScope) });
|
|
964
1115
|
}
|
|
965
1116
|
function SmoothText({ content, streaming }) {
|
|
966
1117
|
const shown = useSmoothStreamText(content, streaming);
|
|
967
|
-
return /* @__PURE__ */
|
|
1118
|
+
return /* @__PURE__ */ jsx3("div", { className: "pactor-chat-text", children: shown });
|
|
968
1119
|
}
|
|
969
1120
|
function SmoothMarkdown({ content, streaming }) {
|
|
970
1121
|
const shown = useSmoothStreamText(content, streaming);
|
|
971
|
-
return /* @__PURE__ */
|
|
1122
|
+
return /* @__PURE__ */ jsx3(MarkdownRenderer, { content: shown });
|
|
972
1123
|
}
|
|
973
1124
|
function PartRenderer({ part, runtime, scope, streaming = false, onOpenArtifact }) {
|
|
974
1125
|
switch (part.type) {
|
|
975
1126
|
case "text":
|
|
976
|
-
return /* @__PURE__ */
|
|
1127
|
+
return /* @__PURE__ */ jsx3(SmoothText, { content: part.content, streaming });
|
|
977
1128
|
case "markdown":
|
|
978
|
-
return /* @__PURE__ */
|
|
1129
|
+
return /* @__PURE__ */ jsx3(SmoothMarkdown, { content: part.content, streaming });
|
|
979
1130
|
case "thinking":
|
|
980
1131
|
case "tool-call":
|
|
981
1132
|
case "tool-result":
|
|
982
1133
|
return null;
|
|
983
1134
|
case "dsl": {
|
|
984
1135
|
if (!part.schema || !runtime) {
|
|
985
|
-
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
|
+
);
|
|
986
1145
|
}
|
|
987
1146
|
const guarded = guardChatDsl(part.schema, runtime.context.components);
|
|
988
|
-
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 }) }) });
|
|
989
1148
|
}
|
|
990
1149
|
case "error":
|
|
991
|
-
return /* @__PURE__ */
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
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
|
+
);
|
|
995
1160
|
case "status":
|
|
996
|
-
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
|
+
);
|
|
997
1168
|
case "artifact":
|
|
998
|
-
return /* @__PURE__ */
|
|
999
|
-
|
|
1169
|
+
return /* @__PURE__ */ jsx3(
|
|
1170
|
+
ChromeSlot,
|
|
1000
1171
|
{
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
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
|
+
)
|
|
1019
1196
|
}
|
|
1020
1197
|
);
|
|
1021
1198
|
default:
|
|
@@ -1023,8 +1200,65 @@ function PartRenderer({ part, runtime, scope, streaming = false, onOpenArtifact
|
|
|
1023
1200
|
}
|
|
1024
1201
|
}
|
|
1025
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
|
+
|
|
1026
1260
|
// src/view/ArtifactPanel.tsx
|
|
1027
|
-
import { Fragment as Fragment3, jsx as
|
|
1261
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1028
1262
|
function useArtifactRuntime(safeRegistry, user) {
|
|
1029
1263
|
return useMemo(() => {
|
|
1030
1264
|
if (!safeRegistry) {
|
|
@@ -1038,7 +1272,7 @@ function useArtifactRuntime(safeRegistry, user) {
|
|
|
1038
1272
|
return createChatRuntime({ safeRegistry: components, user });
|
|
1039
1273
|
}, [safeRegistry, user]);
|
|
1040
1274
|
}
|
|
1041
|
-
var ArtifactDslGuard = class extends
|
|
1275
|
+
var ArtifactDslGuard = class extends Component2 {
|
|
1042
1276
|
constructor() {
|
|
1043
1277
|
super(...arguments);
|
|
1044
1278
|
this.state = { failed: false };
|
|
@@ -1050,12 +1284,12 @@ var ArtifactDslGuard = class extends Component {
|
|
|
1050
1284
|
console.warn("[@pactor-app/chat] DSL \u4EA7\u51FA\u7269\u6E32\u67D3\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u5C55\u793A", error);
|
|
1051
1285
|
}
|
|
1052
1286
|
render() {
|
|
1053
|
-
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;
|
|
1054
1288
|
}
|
|
1055
1289
|
};
|
|
1056
1290
|
function ArtifactDslNode({ node }) {
|
|
1057
|
-
const { renderChildren } =
|
|
1058
|
-
return /* @__PURE__ */
|
|
1291
|
+
const { renderChildren } = useRenderer3();
|
|
1292
|
+
return /* @__PURE__ */ jsx5(Fragment3, { children: renderChildren([node]) });
|
|
1059
1293
|
}
|
|
1060
1294
|
function ArtifactDslContent({
|
|
1061
1295
|
content,
|
|
@@ -1063,10 +1297,10 @@ function ArtifactDslContent({
|
|
|
1063
1297
|
}) {
|
|
1064
1298
|
const node = typeof content === "object" && content !== null && !Array.isArray(content) && typeof content.type === "string" ? content : void 0;
|
|
1065
1299
|
if (!node || !runtime) {
|
|
1066
|
-
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" });
|
|
1067
1301
|
}
|
|
1068
1302
|
const guarded = guardChatDsl(node, runtime.context.components);
|
|
1069
|
-
return /* @__PURE__ */
|
|
1303
|
+
return /* @__PURE__ */ jsx5(DslRenderer2, { context: runtime.context, engine: runtime.engine, children: /* @__PURE__ */ jsx5(ArtifactDslGuard, { children: /* @__PURE__ */ jsx5(ArtifactDslNode, { node: guarded }) }) });
|
|
1070
1304
|
}
|
|
1071
1305
|
function ArtifactContent({
|
|
1072
1306
|
artifact,
|
|
@@ -1074,16 +1308,16 @@ function ArtifactContent({
|
|
|
1074
1308
|
}) {
|
|
1075
1309
|
switch (artifact.kind) {
|
|
1076
1310
|
case "markdown":
|
|
1077
|
-
return /* @__PURE__ */
|
|
1311
|
+
return /* @__PURE__ */ jsx5(MarkdownRenderer2, { content: String(artifact.content) });
|
|
1078
1312
|
case "code":
|
|
1079
|
-
return /* @__PURE__ */
|
|
1080
|
-
artifact.language ? /* @__PURE__ */
|
|
1081
|
-
/* @__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) }) })
|
|
1082
1316
|
] });
|
|
1083
1317
|
case "text":
|
|
1084
|
-
return /* @__PURE__ */
|
|
1318
|
+
return /* @__PURE__ */ jsx5("pre", { className: "pactor-chat-inspector__text", children: String(artifact.content) });
|
|
1085
1319
|
case "dsl":
|
|
1086
|
-
return /* @__PURE__ */
|
|
1320
|
+
return /* @__PURE__ */ jsx5(ArtifactDslContent, { content: artifact.content, runtime });
|
|
1087
1321
|
default:
|
|
1088
1322
|
return null;
|
|
1089
1323
|
}
|
|
@@ -1097,8 +1331,13 @@ function ArtifactPanel({
|
|
|
1097
1331
|
className
|
|
1098
1332
|
}) {
|
|
1099
1333
|
const runtime = useArtifactRuntime(safeRegistry, user);
|
|
1334
|
+
const closeRef = useRef3(onClose);
|
|
1335
|
+
closeRef.current = onClose;
|
|
1336
|
+
useEffect2(() => {
|
|
1337
|
+
setChatChromeHandlers({ panelClose: () => closeRef.current?.() });
|
|
1338
|
+
}, []);
|
|
1100
1339
|
const panelRef = useRef3(null);
|
|
1101
|
-
const [width, setWidth] =
|
|
1340
|
+
const [width, setWidth] = useState4(null);
|
|
1102
1341
|
const handleResizeStart = (event) => {
|
|
1103
1342
|
event.preventDefault();
|
|
1104
1343
|
const panel = panelRef.current;
|
|
@@ -1124,7 +1363,7 @@ function ArtifactPanel({
|
|
|
1124
1363
|
document.addEventListener("pointermove", onMove);
|
|
1125
1364
|
document.addEventListener("pointerup", onUp);
|
|
1126
1365
|
};
|
|
1127
|
-
return /* @__PURE__ */
|
|
1366
|
+
return /* @__PURE__ */ jsxs2(
|
|
1128
1367
|
"aside",
|
|
1129
1368
|
{
|
|
1130
1369
|
ref: panelRef,
|
|
@@ -1132,7 +1371,7 @@ function ArtifactPanel({
|
|
|
1132
1371
|
"data-kind": artifact?.kind,
|
|
1133
1372
|
style: width !== null ? { width: `${width}px` } : void 0,
|
|
1134
1373
|
children: [
|
|
1135
|
-
/* @__PURE__ */
|
|
1374
|
+
/* @__PURE__ */ jsx5(
|
|
1136
1375
|
"div",
|
|
1137
1376
|
{
|
|
1138
1377
|
className: "pactor-chat-inspector__resize",
|
|
@@ -1142,43 +1381,53 @@ function ArtifactPanel({
|
|
|
1142
1381
|
onPointerDown: handleResizeStart
|
|
1143
1382
|
}
|
|
1144
1383
|
),
|
|
1145
|
-
/* @__PURE__ */
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
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 })
|
|
1160
1409
|
]
|
|
1161
1410
|
}
|
|
1162
1411
|
);
|
|
1163
1412
|
}
|
|
1164
1413
|
|
|
1165
1414
|
// src/view/ChatView.tsx
|
|
1166
|
-
import {
|
|
1415
|
+
import { Icon as Icon9 } from "@pactor-app/ui/components";
|
|
1167
1416
|
import { Registry as Registry3 } from "@pactor-app/core";
|
|
1168
|
-
import { useEffect as
|
|
1417
|
+
import { useEffect as useEffect8, useMemo as useMemo3, useRef as useRef10, useState as useState12, useSyncExternalStore } from "react";
|
|
1169
1418
|
|
|
1170
1419
|
// src/view/Composer.tsx
|
|
1171
|
-
import {
|
|
1172
|
-
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";
|
|
1173
1422
|
|
|
1174
1423
|
// src/view/AnchoredPopover.tsx
|
|
1175
1424
|
import {
|
|
1176
1425
|
useEffect as useEffect3,
|
|
1177
1426
|
useLayoutEffect as useLayoutEffect2,
|
|
1178
1427
|
useRef as useRef4,
|
|
1179
|
-
useState as
|
|
1428
|
+
useState as useState5
|
|
1180
1429
|
} from "react";
|
|
1181
|
-
import { jsx as
|
|
1430
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1182
1431
|
function AnchoredPopover({
|
|
1183
1432
|
anchorRect,
|
|
1184
1433
|
onClose,
|
|
@@ -1188,7 +1437,7 @@ function AnchoredPopover({
|
|
|
1188
1437
|
sideOffset = 8
|
|
1189
1438
|
}) {
|
|
1190
1439
|
const ref = useRef4(null);
|
|
1191
|
-
const [position, setPosition] =
|
|
1440
|
+
const [position, setPosition] = useState5(null);
|
|
1192
1441
|
useLayoutEffect2(() => {
|
|
1193
1442
|
const element = ref.current;
|
|
1194
1443
|
if (!element) return;
|
|
@@ -1235,7 +1484,7 @@ function AnchoredPopover({
|
|
|
1235
1484
|
position?.below ? "pactor-chat-popover--below" : "",
|
|
1236
1485
|
className ?? ""
|
|
1237
1486
|
].filter(Boolean).join(" ");
|
|
1238
|
-
return /* @__PURE__ */
|
|
1487
|
+
return /* @__PURE__ */ jsx6(
|
|
1239
1488
|
"div",
|
|
1240
1489
|
{
|
|
1241
1490
|
ref,
|
|
@@ -1254,19 +1503,44 @@ function AnchoredPopover({
|
|
|
1254
1503
|
}
|
|
1255
1504
|
|
|
1256
1505
|
// src/view/ModelChip.tsx
|
|
1257
|
-
import {
|
|
1258
|
-
import { useRef as useRef5, useState as
|
|
1259
|
-
|
|
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";
|
|
1260
1534
|
function ModelChip({
|
|
1261
1535
|
models,
|
|
1262
1536
|
model,
|
|
1263
1537
|
onModelChange
|
|
1264
1538
|
}) {
|
|
1265
1539
|
const chipRef = useRef5(null);
|
|
1266
|
-
const [anchor, setAnchor] =
|
|
1540
|
+
const [anchor, setAnchor] = useState6(null);
|
|
1267
1541
|
const currentOption = models.find((option) => option.value === model) ?? models[0];
|
|
1268
|
-
return /* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
1542
|
+
return /* @__PURE__ */ jsxs3(Fragment4, { children: [
|
|
1543
|
+
/* @__PURE__ */ jsxs3(
|
|
1270
1544
|
"button",
|
|
1271
1545
|
{
|
|
1272
1546
|
ref: chipRef,
|
|
@@ -1276,18 +1550,18 @@ function ModelChip({
|
|
|
1276
1550
|
"aria-label": "\u9009\u62E9\u6A21\u578B",
|
|
1277
1551
|
onClick: () => setAnchor(chipRef.current.getBoundingClientRect()),
|
|
1278
1552
|
children: [
|
|
1279
|
-
/* @__PURE__ */
|
|
1280
|
-
/* @__PURE__ */
|
|
1553
|
+
/* @__PURE__ */ jsx7("span", { className: "pactor-chat-model-chip__label", children: currentOption.label }),
|
|
1554
|
+
/* @__PURE__ */ jsx7(Icon4, { name: "chevrons-up-down", size: 12 })
|
|
1281
1555
|
]
|
|
1282
1556
|
}
|
|
1283
1557
|
),
|
|
1284
|
-
anchor && /* @__PURE__ */
|
|
1558
|
+
anchor && /* @__PURE__ */ jsx7(
|
|
1285
1559
|
AnchoredPopover,
|
|
1286
1560
|
{
|
|
1287
1561
|
anchorRect: anchor,
|
|
1288
1562
|
onClose: () => setAnchor(null),
|
|
1289
1563
|
role: "listbox",
|
|
1290
|
-
children: models.map((option) => /* @__PURE__ */
|
|
1564
|
+
children: models.map((option) => /* @__PURE__ */ jsxs3(
|
|
1291
1565
|
"button",
|
|
1292
1566
|
{
|
|
1293
1567
|
type: "button",
|
|
@@ -1299,8 +1573,8 @@ function ModelChip({
|
|
|
1299
1573
|
setAnchor(null);
|
|
1300
1574
|
},
|
|
1301
1575
|
children: [
|
|
1302
|
-
/* @__PURE__ */
|
|
1303
|
-
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" })
|
|
1304
1578
|
]
|
|
1305
1579
|
},
|
|
1306
1580
|
option.value
|
|
@@ -1309,10 +1583,243 @@ function ModelChip({
|
|
|
1309
1583
|
)
|
|
1310
1584
|
] });
|
|
1311
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
|
+
}
|
|
1312
1819
|
|
|
1313
1820
|
// src/view/context-sources.tsx
|
|
1314
|
-
import { useEffect as
|
|
1315
|
-
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";
|
|
1316
1823
|
function sourceCacheKey(source) {
|
|
1317
1824
|
return `${source.service ?? ""}:${JSON.stringify(source.params ?? {})}`;
|
|
1318
1825
|
}
|
|
@@ -1347,8 +1854,8 @@ function ContextSourceList({
|
|
|
1347
1854
|
cache,
|
|
1348
1855
|
onSelect
|
|
1349
1856
|
}) {
|
|
1350
|
-
const [resolutions, setResolutions] =
|
|
1351
|
-
|
|
1857
|
+
const [resolutions, setResolutions] = useState7([]);
|
|
1858
|
+
useEffect5(() => {
|
|
1352
1859
|
let cancelled = false;
|
|
1353
1860
|
const initial = sources.map(
|
|
1354
1861
|
(source) => source.items ? { status: "ready", items: source.items } : { status: "loading" }
|
|
@@ -1395,10 +1902,10 @@ function ContextSourceList({
|
|
|
1395
1902
|
});
|
|
1396
1903
|
return /* @__PURE__ */ jsxs5("div", { className: "pactor-chat-source-list", children: [
|
|
1397
1904
|
groups.map(({ source, resolution, items }) => /* @__PURE__ */ jsxs5("div", { className: "pactor-chat-source-list__group", children: [
|
|
1398
|
-
sources.length > 1 && /* @__PURE__ */
|
|
1399
|
-
resolution.status === "loading" && /* @__PURE__ */
|
|
1400
|
-
resolution.status === "error" && /* @__PURE__ */
|
|
1401
|
-
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(
|
|
1402
1909
|
"button",
|
|
1403
1910
|
{
|
|
1404
1911
|
type: "button",
|
|
@@ -1409,22 +1916,13 @@ function ContextSourceList({
|
|
|
1409
1916
|
item.id
|
|
1410
1917
|
))
|
|
1411
1918
|
] }, `${source.trigger}:${source.label}`)),
|
|
1412
|
-
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" })
|
|
1413
1920
|
] });
|
|
1414
1921
|
}
|
|
1415
1922
|
|
|
1416
1923
|
// src/view/Composer.tsx
|
|
1417
|
-
import { jsx as
|
|
1924
|
+
import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1418
1925
|
var MAX_INPUT_HEIGHT = 200;
|
|
1419
|
-
function formatSize(bytes) {
|
|
1420
|
-
if (bytes < 1024) {
|
|
1421
|
-
return `${bytes} B`;
|
|
1422
|
-
}
|
|
1423
|
-
if (bytes < 1024 * 1024) {
|
|
1424
|
-
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1425
|
-
}
|
|
1426
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1427
|
-
}
|
|
1428
1926
|
function detectMention(text, caret) {
|
|
1429
1927
|
const beforeCaret = text.slice(0, caret);
|
|
1430
1928
|
const match = /(?:^|\s)@([^\s@]*)$/.exec(beforeCaret);
|
|
@@ -1453,10 +1951,12 @@ function Composer({
|
|
|
1453
1951
|
contextSources,
|
|
1454
1952
|
contextChips,
|
|
1455
1953
|
onContextChipsChange,
|
|
1456
|
-
callService
|
|
1954
|
+
callService,
|
|
1955
|
+
composerFooter,
|
|
1956
|
+
hideToolbar = false
|
|
1457
1957
|
}) {
|
|
1458
|
-
const [text, setText] =
|
|
1459
|
-
const [dragOver, setDragOver] =
|
|
1958
|
+
const [text, setText] = useState8("");
|
|
1959
|
+
const [dragOver, setDragOver] = useState8(false);
|
|
1460
1960
|
const inputRef = useRef6(null);
|
|
1461
1961
|
const fileInputRef = useRef6(null);
|
|
1462
1962
|
const plusButtonRef = useRef6(null);
|
|
@@ -1472,8 +1972,8 @@ function Composer({
|
|
|
1472
1972
|
);
|
|
1473
1973
|
const builtinMentionEnabled = onMentionTrigger === void 0 && mentionSources.length > 0;
|
|
1474
1974
|
const builtinPlusEnabled = onPlusMenu === void 0 && plusSources.length > 0;
|
|
1475
|
-
const [mentionState, setMentionState] =
|
|
1476
|
-
const [plusAnchor, setPlusAnchor] =
|
|
1975
|
+
const [mentionState, setMentionState] = useState8(null);
|
|
1976
|
+
const [plusAnchor, setPlusAnchor] = useState8(null);
|
|
1477
1977
|
const sourceCacheRef = useRef6(null);
|
|
1478
1978
|
if (sourceCacheRef.current === null) {
|
|
1479
1979
|
sourceCacheRef.current = /* @__PURE__ */ new Map();
|
|
@@ -1508,105 +2008,147 @@ function Composer({
|
|
|
1508
2008
|
onSend?.(value);
|
|
1509
2009
|
setText("");
|
|
1510
2010
|
};
|
|
1511
|
-
const
|
|
1512
|
-
|
|
2011
|
+
const sendRef = useRef6(send);
|
|
2012
|
+
sendRef.current = send;
|
|
2013
|
+
useLayoutEffect3(() => {
|
|
2014
|
+
setChatChromeHandlers({ composerSubmit: () => sendRef.current() });
|
|
2015
|
+
}, []);
|
|
2016
|
+
const syncText = (value, caret, rect) => {
|
|
1513
2017
|
setText(value);
|
|
1514
2018
|
if (onMentionTrigger || builtinMentionEnabled) {
|
|
1515
|
-
const caret = event.target.selectionStart ?? value.length;
|
|
1516
2019
|
const query = detectMention(value, caret);
|
|
1517
2020
|
if (onMentionTrigger) {
|
|
1518
2021
|
if (query !== null) {
|
|
1519
|
-
onMentionTrigger(query,
|
|
2022
|
+
onMentionTrigger(query, rect);
|
|
1520
2023
|
}
|
|
1521
2024
|
} else {
|
|
1522
|
-
setMentionState(
|
|
1523
|
-
|
|
1524
|
-
|
|
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);
|
|
1525
2067
|
}
|
|
1526
2068
|
}
|
|
1527
2069
|
};
|
|
1528
|
-
const showToolbar = toolbarStart !== void 0 || toolbarEnd !== void 0 || onPlusMenu !== void 0 || builtinPlusEnabled || onAttachFiles !== void 0 || modelChipEnabled;
|
|
1529
|
-
|
|
1530
|
-
"
|
|
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",
|
|
1531
2073
|
{
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
event.preventDefault();
|
|
1540
|
-
setDragOver(false);
|
|
1541
|
-
const files = collectDropFiles(event);
|
|
1542
|
-
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) {
|
|
1543
2081
|
onAttachFiles(files);
|
|
1544
2082
|
}
|
|
1545
|
-
|
|
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,
|
|
1546
2130
|
children: [
|
|
1547
|
-
attachments !== void 0 &&
|
|
1548
|
-
|
|
1549
|
-
return /* @__PURE__ */ jsxs6(
|
|
1550
|
-
"div",
|
|
1551
|
-
{
|
|
1552
|
-
className: "pactor-chat-composer__attachment",
|
|
1553
|
-
"data-attachment-id": attachment.id,
|
|
1554
|
-
onClick: () => onAttachmentClick?.(attachment),
|
|
1555
|
-
children: [
|
|
1556
|
-
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: [
|
|
1557
|
-
/* @__PURE__ */ jsx7(FileText, { size: 14 }),
|
|
1558
|
-
/* @__PURE__ */ jsx7("span", { className: "pactor-chat-composer__attachment-name", children: attachment.name }),
|
|
1559
|
-
attachment.size !== void 0 && /* @__PURE__ */ jsx7("span", { className: "pactor-chat-composer__attachment-size", children: formatSize(attachment.size) })
|
|
1560
|
-
] }),
|
|
1561
|
-
/* @__PURE__ */ jsx7(
|
|
1562
|
-
"button",
|
|
1563
|
-
{
|
|
1564
|
-
type: "button",
|
|
1565
|
-
className: "pactor-chat-icon-button pactor-chat-composer__attachment-remove",
|
|
1566
|
-
title: "\u79FB\u9664\u9644\u4EF6",
|
|
1567
|
-
"aria-label": "\u79FB\u9664\u9644\u4EF6",
|
|
1568
|
-
onClick: (event) => {
|
|
1569
|
-
event.stopPropagation();
|
|
1570
|
-
onAttachmentsChange?.(
|
|
1571
|
-
attachments.filter((item) => item.id !== attachment.id)
|
|
1572
|
-
);
|
|
1573
|
-
},
|
|
1574
|
-
children: /* @__PURE__ */ jsx7(X2, { size: 12 })
|
|
1575
|
-
}
|
|
1576
|
-
)
|
|
1577
|
-
]
|
|
1578
|
-
},
|
|
1579
|
-
attachment.id
|
|
1580
|
-
);
|
|
1581
|
-
}) }),
|
|
1582
|
-
contextChips !== void 0 && contextChips.length > 0 && /* @__PURE__ */ jsx7("div", { className: "pactor-chat-composer__contexts", children: contextChips.map((chip) => /* @__PURE__ */ jsxs6(
|
|
1583
|
-
"span",
|
|
2131
|
+
attachments !== void 0 && /* @__PURE__ */ jsx10(
|
|
2132
|
+
ComposerAttachments,
|
|
1584
2133
|
{
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
contextChips.filter(
|
|
1598
|
-
(existing) => !(existing.id === chip.id && existing.trigger === chip.trigger)
|
|
1599
|
-
)
|
|
1600
|
-
),
|
|
1601
|
-
children: /* @__PURE__ */ jsx7(X2, { size: 12 })
|
|
1602
|
-
}
|
|
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)
|
|
1603
2146
|
)
|
|
1604
|
-
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
)) }),
|
|
2147
|
+
)
|
|
2148
|
+
}
|
|
2149
|
+
),
|
|
1608
2150
|
/* @__PURE__ */ jsxs6("div", { className: "pactor-chat-composer__row", children: [
|
|
1609
|
-
/* @__PURE__ */
|
|
2151
|
+
/* @__PURE__ */ jsx10(
|
|
1610
2152
|
"textarea",
|
|
1611
2153
|
{
|
|
1612
2154
|
ref: inputRef,
|
|
@@ -1623,10 +2165,8 @@ function Composer({
|
|
|
1623
2165
|
composingRef.current = false;
|
|
1624
2166
|
},
|
|
1625
2167
|
onPaste: (event) => {
|
|
1626
|
-
|
|
1627
|
-
if (files.length > 0 && onAttachFiles) {
|
|
2168
|
+
if (handlePasteFiles(event.clipboardData)) {
|
|
1628
2169
|
event.preventDefault();
|
|
1629
|
-
onAttachFiles(files);
|
|
1630
2170
|
}
|
|
1631
2171
|
},
|
|
1632
2172
|
onKeyDown: (event) => {
|
|
@@ -1640,7 +2180,7 @@ function Composer({
|
|
|
1640
2180
|
}
|
|
1641
2181
|
}
|
|
1642
2182
|
),
|
|
1643
|
-
/* @__PURE__ */
|
|
2183
|
+
hideToolbar ? null : /* @__PURE__ */ jsx10(
|
|
1644
2184
|
"button",
|
|
1645
2185
|
{
|
|
1646
2186
|
type: "button",
|
|
@@ -1649,14 +2189,14 @@ function Composer({
|
|
|
1649
2189
|
"aria-label": streaming ? "\u505C\u6B62\u751F\u6210" : "\u53D1\u9001",
|
|
1650
2190
|
disabled: streaming ? false : disabled || !text.trim(),
|
|
1651
2191
|
onClick: streaming ? onStop : send,
|
|
1652
|
-
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 })
|
|
1653
2193
|
}
|
|
1654
2194
|
)
|
|
1655
2195
|
] }),
|
|
1656
2196
|
showToolbar && /* @__PURE__ */ jsxs6("div", { className: "pactor-chat-composer__toolbar", children: [
|
|
1657
2197
|
toolbarStart,
|
|
1658
|
-
/* @__PURE__ */
|
|
1659
|
-
(onPlusMenu || builtinPlusEnabled) && /* @__PURE__ */
|
|
2198
|
+
/* @__PURE__ */ jsx10("span", { className: "pactor-chat-composer__toolbar-spacer" }),
|
|
2199
|
+
(onPlusMenu || builtinPlusEnabled) && /* @__PURE__ */ jsx10(
|
|
1660
2200
|
"button",
|
|
1661
2201
|
{
|
|
1662
2202
|
ref: plusButtonRef,
|
|
@@ -1672,10 +2212,10 @@ function Composer({
|
|
|
1672
2212
|
setPlusAnchor(rect);
|
|
1673
2213
|
}
|
|
1674
2214
|
},
|
|
1675
|
-
children: /* @__PURE__ */
|
|
2215
|
+
children: /* @__PURE__ */ jsx10(Icon6, { name: "plus", size: 14 })
|
|
1676
2216
|
}
|
|
1677
2217
|
),
|
|
1678
|
-
onAttachFiles && /* @__PURE__ */
|
|
2218
|
+
onAttachFiles && /* @__PURE__ */ jsx10(
|
|
1679
2219
|
"button",
|
|
1680
2220
|
{
|
|
1681
2221
|
type: "button",
|
|
@@ -1683,11 +2223,11 @@ function Composer({
|
|
|
1683
2223
|
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
1684
2224
|
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
1685
2225
|
onClick: () => fileInputRef.current?.click(),
|
|
1686
|
-
children: /* @__PURE__ */
|
|
2226
|
+
children: /* @__PURE__ */ jsx10(Icon6, { name: "paperclip", size: 14 })
|
|
1687
2227
|
}
|
|
1688
2228
|
),
|
|
1689
|
-
modelChipEnabled && /* @__PURE__ */
|
|
1690
|
-
|
|
2229
|
+
modelChipEnabled && /* @__PURE__ */ jsx10(
|
|
2230
|
+
ModelSelect,
|
|
1691
2231
|
{
|
|
1692
2232
|
models,
|
|
1693
2233
|
model,
|
|
@@ -1696,111 +2236,206 @@ function Composer({
|
|
|
1696
2236
|
),
|
|
1697
2237
|
toolbarEnd
|
|
1698
2238
|
] }),
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
ref: fileInputRef,
|
|
1703
|
-
type: "file",
|
|
1704
|
-
multiple: true,
|
|
1705
|
-
hidden: true,
|
|
1706
|
-
onChange: (event) => {
|
|
1707
|
-
const files = event.target.files ? Array.from(event.target.files) : [];
|
|
1708
|
-
if (files.length > 0) {
|
|
1709
|
-
onAttachFiles(files);
|
|
1710
|
-
}
|
|
1711
|
-
event.target.value = "";
|
|
1712
|
-
}
|
|
1713
|
-
}
|
|
1714
|
-
),
|
|
1715
|
-
builtinMentionEnabled && mentionState && /* @__PURE__ */ jsx7(
|
|
1716
|
-
AnchoredPopover,
|
|
1717
|
-
{
|
|
1718
|
-
anchorRect: mentionState.anchorRect,
|
|
1719
|
-
onClose: () => setMentionState(null),
|
|
1720
|
-
role: "listbox",
|
|
1721
|
-
children: /* @__PURE__ */ jsx7(
|
|
1722
|
-
ContextSourceList,
|
|
1723
|
-
{
|
|
1724
|
-
sources: mentionSources,
|
|
1725
|
-
query: mentionState.query,
|
|
1726
|
-
callService,
|
|
1727
|
-
cache: sourceCacheRef.current,
|
|
1728
|
-
onSelect: handleSelectContext
|
|
1729
|
-
}
|
|
1730
|
-
)
|
|
1731
|
-
}
|
|
1732
|
-
),
|
|
1733
|
-
builtinPlusEnabled && plusAnchor && /* @__PURE__ */ jsx7(
|
|
1734
|
-
AnchoredPopover,
|
|
1735
|
-
{
|
|
1736
|
-
anchorRect: plusAnchor,
|
|
1737
|
-
onClose: () => setPlusAnchor(null),
|
|
1738
|
-
role: "listbox",
|
|
1739
|
-
children: /* @__PURE__ */ jsx7(
|
|
1740
|
-
ContextSourceList,
|
|
1741
|
-
{
|
|
1742
|
-
sources: plusSources,
|
|
1743
|
-
query: "",
|
|
1744
|
-
callService,
|
|
1745
|
-
cache: sourceCacheRef.current,
|
|
1746
|
-
onSelect: handleSelectContext
|
|
1747
|
-
}
|
|
1748
|
-
)
|
|
1749
|
-
}
|
|
1750
|
-
)
|
|
2239
|
+
composerFooter !== void 0 && composerFooter !== null ? /* @__PURE__ */ jsx10("div", { className: "pactor-chat-composer__footer", children: composerFooter }) : null,
|
|
2240
|
+
fileInputNode,
|
|
2241
|
+
popoverNodes
|
|
1751
2242
|
]
|
|
1752
2243
|
}
|
|
1753
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
|
+
);
|
|
1754
2309
|
}
|
|
1755
2310
|
|
|
1756
|
-
// src/view/
|
|
1757
|
-
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1758
|
-
var DEFAULT_CHAT_GREETING = "\u4F60\u597D\uFF0C\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F";
|
|
2311
|
+
// src/view/chrome/empty-state.tsx
|
|
1759
2312
|
function suggestionLabel(suggestion) {
|
|
1760
2313
|
return typeof suggestion === "string" ? suggestion : suggestion.label;
|
|
1761
2314
|
}
|
|
1762
2315
|
function suggestionPrompt(suggestion) {
|
|
1763
2316
|
return typeof suggestion === "string" ? suggestion : suggestion.prompt ?? suggestion.label;
|
|
1764
2317
|
}
|
|
1765
|
-
function
|
|
1766
|
-
|
|
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({
|
|
1767
2386
|
subtitle,
|
|
1768
2387
|
suggestions,
|
|
1769
|
-
onSuggestionClick
|
|
2388
|
+
onSuggestionClick,
|
|
2389
|
+
greeting
|
|
1770
2390
|
}) {
|
|
1771
|
-
return /* @__PURE__ */ jsxs7(
|
|
1772
|
-
/* @__PURE__ */
|
|
1773
|
-
subtitle && /* @__PURE__ */
|
|
1774
|
-
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(
|
|
1775
2395
|
"button",
|
|
1776
2396
|
{
|
|
1777
2397
|
type: "button",
|
|
1778
2398
|
className: "pactor-chat-empty__suggestion",
|
|
1779
|
-
onClick: () => onSuggestionClick?.(
|
|
1780
|
-
children:
|
|
2399
|
+
onClick: () => onSuggestionClick?.(suggestionPrompt2(suggestion)),
|
|
2400
|
+
children: suggestionLabel2(suggestion)
|
|
1781
2401
|
},
|
|
1782
|
-
|
|
2402
|
+
suggestionLabel2(suggestion)
|
|
1783
2403
|
)) })
|
|
1784
2404
|
] });
|
|
1785
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
|
+
}
|
|
1786
2428
|
|
|
1787
2429
|
// src/view/MessageBubble.tsx
|
|
1788
|
-
import { useRef as
|
|
2430
|
+
import { useRef as useRef9, useState as useState11 } from "react";
|
|
1789
2431
|
|
|
1790
2432
|
// src/view/ActivityTrace.tsx
|
|
1791
|
-
import {
|
|
1792
|
-
Brain,
|
|
1793
|
-
CheckCircle2,
|
|
1794
|
-
ChevronRight,
|
|
1795
|
-
Clock,
|
|
1796
|
-
Loader2,
|
|
1797
|
-
XCircle
|
|
1798
|
-
} from "lucide-react";
|
|
2433
|
+
import { Icon as Icon7 } from "@pactor-app/ui/components";
|
|
1799
2434
|
import { MarkdownRenderer as MarkdownRenderer3 } from "@pactor-app/markdown";
|
|
1800
|
-
import { useEffect as
|
|
1801
|
-
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";
|
|
1802
2437
|
function usePinnedCollapse(autoOpen) {
|
|
1803
|
-
const [state, setState] =
|
|
2438
|
+
const [state, setState] = useState9("auto");
|
|
1804
2439
|
const open = state === "auto" ? autoOpen : state === "pinned-open";
|
|
1805
2440
|
const toggle = () => {
|
|
1806
2441
|
setState(open ? "pinned-closed" : "pinned-open");
|
|
@@ -1826,8 +2461,8 @@ function statusText(message, mode, toolCount) {
|
|
|
1826
2461
|
}
|
|
1827
2462
|
function useElapsedSeconds(startedAt, active) {
|
|
1828
2463
|
const compute = () => Math.max(0, Math.floor((Date.now() - startedAt) / 1e3));
|
|
1829
|
-
const [elapsed, setElapsed] =
|
|
1830
|
-
|
|
2464
|
+
const [elapsed, setElapsed] = useState9(compute);
|
|
2465
|
+
useEffect6(() => {
|
|
1831
2466
|
if (!active) {
|
|
1832
2467
|
setElapsed(compute());
|
|
1833
2468
|
return;
|
|
@@ -1841,15 +2476,15 @@ function useElapsedSeconds(startedAt, active) {
|
|
|
1841
2476
|
}
|
|
1842
2477
|
function TraceStatusIcon({ status }) {
|
|
1843
2478
|
if (status === "running") {
|
|
1844
|
-
return /* @__PURE__ */
|
|
2479
|
+
return /* @__PURE__ */ jsx12(Icon7, { name: "loading", size: 13, className: "pactor-chat-spin" });
|
|
1845
2480
|
}
|
|
1846
2481
|
if (status === "success") {
|
|
1847
|
-
return /* @__PURE__ */
|
|
2482
|
+
return /* @__PURE__ */ jsx12(Icon7, { name: "check-circle", size: 13 });
|
|
1848
2483
|
}
|
|
1849
2484
|
if (status === "failed") {
|
|
1850
|
-
return /* @__PURE__ */
|
|
2485
|
+
return /* @__PURE__ */ jsx12(Icon7, { name: "x-circle", size: 13 });
|
|
1851
2486
|
}
|
|
1852
|
-
return /* @__PURE__ */
|
|
2487
|
+
return /* @__PURE__ */ jsx12(Icon7, { name: "clock", size: 13 });
|
|
1853
2488
|
}
|
|
1854
2489
|
function summarizeArgs(args) {
|
|
1855
2490
|
if (args === void 0) {
|
|
@@ -1878,7 +2513,7 @@ function formatDetail(value) {
|
|
|
1878
2513
|
}
|
|
1879
2514
|
}
|
|
1880
2515
|
function TraceRow({ entry }) {
|
|
1881
|
-
const [open, setOpen] =
|
|
2516
|
+
const [open, setOpen] = useState9(false);
|
|
1882
2517
|
const summary = summarizeArgs(entry.args);
|
|
1883
2518
|
return /* @__PURE__ */ jsxs8(
|
|
1884
2519
|
"div",
|
|
@@ -1895,16 +2530,16 @@ function TraceRow({ entry }) {
|
|
|
1895
2530
|
"aria-expanded": open,
|
|
1896
2531
|
onClick: () => setOpen((value) => !value),
|
|
1897
2532
|
children: [
|
|
1898
|
-
/* @__PURE__ */
|
|
1899
|
-
/* @__PURE__ */
|
|
1900
|
-
/* @__PURE__ */
|
|
1901
|
-
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 })
|
|
1902
2537
|
]
|
|
1903
2538
|
}
|
|
1904
2539
|
),
|
|
1905
2540
|
open && /* @__PURE__ */ jsxs8("div", { className: "pactor-chat-trace__entry-body", children: [
|
|
1906
|
-
entry.args !== void 0 && /* @__PURE__ */
|
|
1907
|
-
/* @__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) })
|
|
1908
2543
|
] })
|
|
1909
2544
|
]
|
|
1910
2545
|
}
|
|
@@ -1931,13 +2566,13 @@ function ThinkingCard({
|
|
|
1931
2566
|
"aria-expanded": open,
|
|
1932
2567
|
onClick: toggle,
|
|
1933
2568
|
children: [
|
|
1934
|
-
/* @__PURE__ */
|
|
1935
|
-
/* @__PURE__ */
|
|
1936
|
-
/* @__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" })
|
|
1937
2572
|
]
|
|
1938
2573
|
}
|
|
1939
2574
|
),
|
|
1940
|
-
open && /* @__PURE__ */
|
|
2575
|
+
open && /* @__PURE__ */ jsx12("div", { className: "pactor-chat-thinking__body", children: /* @__PURE__ */ jsx12(MarkdownRenderer3, { content: part.content }) })
|
|
1941
2576
|
]
|
|
1942
2577
|
}
|
|
1943
2578
|
);
|
|
@@ -1959,9 +2594,9 @@ function ActivityTrace({ message }) {
|
|
|
1959
2594
|
message.createdAt ?? mountTimeRef.current,
|
|
1960
2595
|
streaming
|
|
1961
2596
|
);
|
|
1962
|
-
const header = /* @__PURE__ */ jsxs8(
|
|
1963
|
-
/* @__PURE__ */
|
|
1964
|
-
/* @__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(
|
|
1965
2600
|
"span",
|
|
1966
2601
|
{
|
|
1967
2602
|
className: `pactor-chat-trace__status-text${streaming ? " pactor-chat-trace__status-text--breathing" : ""}`,
|
|
@@ -1972,10 +2607,10 @@ function ActivityTrace({ message }) {
|
|
|
1972
2607
|
elapsed,
|
|
1973
2608
|
"s"
|
|
1974
2609
|
] }),
|
|
1975
|
-
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 }) })
|
|
1976
2611
|
] });
|
|
1977
2612
|
return /* @__PURE__ */ jsxs8("div", { className: "pactor-chat-trace", "data-open": open, children: [
|
|
1978
|
-
entries.length > 0 ? /* @__PURE__ */
|
|
2613
|
+
entries.length > 0 ? /* @__PURE__ */ jsx12(
|
|
1979
2614
|
"button",
|
|
1980
2615
|
{
|
|
1981
2616
|
type: "button",
|
|
@@ -1984,8 +2619,8 @@ function ActivityTrace({ message }) {
|
|
|
1984
2619
|
onClick: toggle,
|
|
1985
2620
|
children: header
|
|
1986
2621
|
}
|
|
1987
|
-
) : /* @__PURE__ */
|
|
1988
|
-
thinkingParts.map((part, index) => /* @__PURE__ */
|
|
2622
|
+
) : /* @__PURE__ */ jsx12("div", { className: "pactor-chat-trace__header", children: header }),
|
|
2623
|
+
thinkingParts.map((part, index) => /* @__PURE__ */ jsx12(
|
|
1989
2624
|
ThinkingCard,
|
|
1990
2625
|
{
|
|
1991
2626
|
part,
|
|
@@ -1993,36 +2628,66 @@ function ActivityTrace({ message }) {
|
|
|
1993
2628
|
},
|
|
1994
2629
|
part.id ?? index
|
|
1995
2630
|
)),
|
|
1996
|
-
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)) })
|
|
1997
2632
|
] });
|
|
1998
2633
|
}
|
|
1999
2634
|
|
|
2000
2635
|
// src/view/MessageActions.tsx
|
|
2001
|
-
import {
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
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";
|
|
2026
2691
|
var BUILTIN_ACTION_DEFAULTS = {
|
|
2027
2692
|
copy: {
|
|
2028
2693
|
label: "\u590D\u5236",
|
|
@@ -2095,7 +2760,21 @@ function MessageActions({
|
|
|
2095
2760
|
callService,
|
|
2096
2761
|
onMessageAction
|
|
2097
2762
|
}) {
|
|
2098
|
-
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]);
|
|
2099
2778
|
const copy = async () => {
|
|
2100
2779
|
try {
|
|
2101
2780
|
await navigator.clipboard.writeText(collectMessageText(message));
|
|
@@ -2155,41 +2834,53 @@ function MessageActions({
|
|
|
2155
2834
|
}
|
|
2156
2835
|
onMessageAction?.(action.id, message);
|
|
2157
2836
|
};
|
|
2158
|
-
|
|
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(
|
|
2159
2858
|
"div",
|
|
2160
2859
|
{
|
|
2161
2860
|
className: `pactor-chat-message__actions${forceVisible ? " pactor-chat-message__actions--visible" : ""}`,
|
|
2162
|
-
children:
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
"aria-label": label,
|
|
2174
|
-
"data-message-action": action.id,
|
|
2175
|
-
onClick: () => dispatch(action),
|
|
2176
|
-
children: Icon ? /* @__PURE__ */ jsx10(Icon, { size: 14 }) : /* @__PURE__ */ jsx10(HelpCircle, { size: 14, "data-icon-placeholder": "true" })
|
|
2177
|
-
},
|
|
2178
|
-
action.id
|
|
2179
|
-
);
|
|
2180
|
-
})
|
|
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
|
+
)
|
|
2181
2872
|
}
|
|
2182
2873
|
);
|
|
2183
2874
|
}
|
|
2184
2875
|
|
|
2185
2876
|
// src/view/MessageBubble.tsx
|
|
2186
|
-
import { jsx as
|
|
2877
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2187
2878
|
function MessageEditForm({
|
|
2188
2879
|
initialText,
|
|
2189
2880
|
onConfirm,
|
|
2190
2881
|
onCancel
|
|
2191
2882
|
}) {
|
|
2192
|
-
const [text, setText] =
|
|
2883
|
+
const [text, setText] = useState11(initialText);
|
|
2193
2884
|
const confirm = () => {
|
|
2194
2885
|
const value = text.trim();
|
|
2195
2886
|
if (!value) {
|
|
@@ -2198,7 +2889,7 @@ function MessageEditForm({
|
|
|
2198
2889
|
onConfirm(value);
|
|
2199
2890
|
};
|
|
2200
2891
|
return /* @__PURE__ */ jsxs9("div", { className: "pactor-chat-message__edit", children: [
|
|
2201
|
-
/* @__PURE__ */
|
|
2892
|
+
/* @__PURE__ */ jsx14(
|
|
2202
2893
|
"textarea",
|
|
2203
2894
|
{
|
|
2204
2895
|
className: "pactor-chat-message__edit-input",
|
|
@@ -2217,7 +2908,7 @@ function MessageEditForm({
|
|
|
2217
2908
|
}
|
|
2218
2909
|
),
|
|
2219
2910
|
/* @__PURE__ */ jsxs9("div", { className: "pactor-chat-message__edit-actions", children: [
|
|
2220
|
-
/* @__PURE__ */
|
|
2911
|
+
/* @__PURE__ */ jsx14(
|
|
2221
2912
|
"button",
|
|
2222
2913
|
{
|
|
2223
2914
|
type: "button",
|
|
@@ -2227,7 +2918,7 @@ function MessageEditForm({
|
|
|
2227
2918
|
children: "\u53D1\u9001"
|
|
2228
2919
|
}
|
|
2229
2920
|
),
|
|
2230
|
-
/* @__PURE__ */
|
|
2921
|
+
/* @__PURE__ */ jsx14(
|
|
2231
2922
|
"button",
|
|
2232
2923
|
{
|
|
2233
2924
|
type: "button",
|
|
@@ -2253,7 +2944,7 @@ function MessageBubble({
|
|
|
2253
2944
|
onMessageAction,
|
|
2254
2945
|
onOpenArtifact
|
|
2255
2946
|
}) {
|
|
2256
|
-
const [editing, setEditing] =
|
|
2947
|
+
const [editing, setEditing] = useState11(false);
|
|
2257
2948
|
const bubbleScope = {
|
|
2258
2949
|
conversation: scope?.conversation ?? {},
|
|
2259
2950
|
message: { id: message.id },
|
|
@@ -2261,7 +2952,7 @@ function MessageBubble({
|
|
|
2261
2952
|
};
|
|
2262
2953
|
const streaming = message.status === "streaming";
|
|
2263
2954
|
const live = message.status === "pending" || message.status === "streaming";
|
|
2264
|
-
const wasLiveRef =
|
|
2955
|
+
const wasLiveRef = useRef9(live);
|
|
2265
2956
|
if (live) {
|
|
2266
2957
|
wasLiveRef.current = true;
|
|
2267
2958
|
}
|
|
@@ -2275,7 +2966,7 @@ function MessageBubble({
|
|
|
2275
2966
|
"data-message-id": message.id,
|
|
2276
2967
|
"data-message-status": message.status,
|
|
2277
2968
|
children: [
|
|
2278
|
-
editing ? /* @__PURE__ */
|
|
2969
|
+
editing ? /* @__PURE__ */ jsx14(
|
|
2279
2970
|
MessageEditForm,
|
|
2280
2971
|
{
|
|
2281
2972
|
initialText: collectMessageText(message),
|
|
@@ -2286,8 +2977,8 @@ function MessageBubble({
|
|
|
2286
2977
|
onCancel: () => setEditing(false)
|
|
2287
2978
|
}
|
|
2288
2979
|
) : /* @__PURE__ */ jsxs9("div", { className: "pactor-chat-message__body", children: [
|
|
2289
|
-
showTrace && /* @__PURE__ */
|
|
2290
|
-
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(
|
|
2291
2982
|
PartRenderer,
|
|
2292
2983
|
{
|
|
2293
2984
|
part,
|
|
@@ -2299,7 +2990,7 @@ function MessageBubble({
|
|
|
2299
2990
|
part.id ?? index
|
|
2300
2991
|
))
|
|
2301
2992
|
] }),
|
|
2302
|
-
!editing && /* @__PURE__ */
|
|
2993
|
+
!editing && /* @__PURE__ */ jsx14(
|
|
2303
2994
|
MessageActions,
|
|
2304
2995
|
{
|
|
2305
2996
|
message,
|
|
@@ -2319,7 +3010,7 @@ function MessageBubble({
|
|
|
2319
3010
|
}
|
|
2320
3011
|
|
|
2321
3012
|
// src/view/ChatView.tsx
|
|
2322
|
-
import { jsx as
|
|
3013
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2323
3014
|
function lastContentLength(messages) {
|
|
2324
3015
|
const last = messages[messages.length - 1];
|
|
2325
3016
|
if (!last) {
|
|
@@ -2353,6 +3044,8 @@ function ChatView({
|
|
|
2353
3044
|
onAttachmentClick,
|
|
2354
3045
|
toolbarStart,
|
|
2355
3046
|
toolbarEnd,
|
|
3047
|
+
composerFooter,
|
|
3048
|
+
hideToolbar,
|
|
2356
3049
|
onMentionTrigger,
|
|
2357
3050
|
onPlusMenu,
|
|
2358
3051
|
models,
|
|
@@ -2363,7 +3056,8 @@ function ChatView({
|
|
|
2363
3056
|
onContextsChange,
|
|
2364
3057
|
callService,
|
|
2365
3058
|
messageActions,
|
|
2366
|
-
onMessageAction
|
|
3059
|
+
onMessageAction,
|
|
3060
|
+
composerBottom
|
|
2367
3061
|
}) {
|
|
2368
3062
|
const messages = useSyncExternalStore(
|
|
2369
3063
|
(listener) => store.subscribe(listener),
|
|
@@ -2393,8 +3087,8 @@ function ChatView({
|
|
|
2393
3087
|
() => ({ conversation: { id: conversationId }, params }),
|
|
2394
3088
|
[conversationId, params]
|
|
2395
3089
|
);
|
|
2396
|
-
const notifiedArtifactsRef =
|
|
2397
|
-
|
|
3090
|
+
const notifiedArtifactsRef = useRef10(/* @__PURE__ */ new Set());
|
|
3091
|
+
useEffect8(() => {
|
|
2398
3092
|
if (!onArtifact) {
|
|
2399
3093
|
return;
|
|
2400
3094
|
}
|
|
@@ -2413,7 +3107,7 @@ function ChatView({
|
|
|
2413
3107
|
});
|
|
2414
3108
|
}
|
|
2415
3109
|
}, [messages, onArtifact]);
|
|
2416
|
-
const abortRef =
|
|
3110
|
+
const abortRef = useRef10(null);
|
|
2417
3111
|
const { containerRef, isFollowing, scrollToBottom } = useChatAutoScroll({
|
|
2418
3112
|
messageCount: messages.length,
|
|
2419
3113
|
lastContentLength: lastContentLength(messages),
|
|
@@ -2424,7 +3118,7 @@ function ChatView({
|
|
|
2424
3118
|
model,
|
|
2425
3119
|
onModelChange
|
|
2426
3120
|
});
|
|
2427
|
-
const [contextChips, setContextChips] =
|
|
3121
|
+
const [contextChips, setContextChips] = useState12([]);
|
|
2428
3122
|
const handleContextChipsChange = (chips) => {
|
|
2429
3123
|
setContextChips(chips);
|
|
2430
3124
|
onContextsChange?.(chips);
|
|
@@ -2456,6 +3150,16 @@ function ChatView({
|
|
|
2456
3150
|
abortRef.current?.abort();
|
|
2457
3151
|
abortRef.current = null;
|
|
2458
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
|
+
}, []);
|
|
2459
3163
|
const handleRegenerate = () => {
|
|
2460
3164
|
if (!transport) {
|
|
2461
3165
|
return;
|
|
@@ -2473,7 +3177,7 @@ function ChatView({
|
|
|
2473
3177
|
const lastMessage = messages[messages.length - 1];
|
|
2474
3178
|
const regenerableMessageId = lastMessage?.role === "assistant" && lastMessage.status === "completed" ? lastMessage.id : void 0;
|
|
2475
3179
|
const isEmpty = messages.length === 0;
|
|
2476
|
-
const composerNode = /* @__PURE__ */
|
|
3180
|
+
const composerNode = /* @__PURE__ */ jsx15(
|
|
2477
3181
|
Composer,
|
|
2478
3182
|
{
|
|
2479
3183
|
onSend: handleSend,
|
|
@@ -2485,6 +3189,8 @@ function ChatView({
|
|
|
2485
3189
|
onAttachmentClick,
|
|
2486
3190
|
toolbarStart,
|
|
2487
3191
|
toolbarEnd,
|
|
3192
|
+
composerFooter,
|
|
3193
|
+
hideToolbar,
|
|
2488
3194
|
onMentionTrigger,
|
|
2489
3195
|
onPlusMenu,
|
|
2490
3196
|
models: modelPlacement === "header" ? void 0 : models,
|
|
@@ -2496,6 +3202,10 @@ function ChatView({
|
|
|
2496
3202
|
callService
|
|
2497
3203
|
}
|
|
2498
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
|
+
] });
|
|
2499
3209
|
return /* @__PURE__ */ jsxs10(
|
|
2500
3210
|
"div",
|
|
2501
3211
|
{
|
|
@@ -2503,7 +3213,7 @@ function ChatView({
|
|
|
2503
3213
|
children: [
|
|
2504
3214
|
/* @__PURE__ */ jsxs10("div", { className: "pactor-chat-messages", ref: containerRef, children: [
|
|
2505
3215
|
isEmpty ? /* @__PURE__ */ jsxs10("div", { className: "pactor-chat-view__empty-stack", children: [
|
|
2506
|
-
/* @__PURE__ */
|
|
3216
|
+
/* @__PURE__ */ jsx15(
|
|
2507
3217
|
EmptyState,
|
|
2508
3218
|
{
|
|
2509
3219
|
greeting,
|
|
@@ -2512,8 +3222,8 @@ function ChatView({
|
|
|
2512
3222
|
onSuggestionClick: handleSend
|
|
2513
3223
|
}
|
|
2514
3224
|
),
|
|
2515
|
-
|
|
2516
|
-
] }) : messages.map((message) => /* @__PURE__ */
|
|
3225
|
+
composerDock
|
|
3226
|
+
] }) : messages.map((message) => /* @__PURE__ */ jsx15(
|
|
2517
3227
|
MessageBubble,
|
|
2518
3228
|
{
|
|
2519
3229
|
message,
|
|
@@ -2537,21 +3247,21 @@ function ChatView({
|
|
|
2537
3247
|
className: "pactor-chat-scroll-bottom",
|
|
2538
3248
|
onClick: scrollToBottom,
|
|
2539
3249
|
children: [
|
|
2540
|
-
/* @__PURE__ */
|
|
3250
|
+
/* @__PURE__ */ jsx15(Icon9, { name: "arrow-down", size: 13 }),
|
|
2541
3251
|
"\u56DE\u5230\u5E95\u90E8"
|
|
2542
3252
|
]
|
|
2543
3253
|
}
|
|
2544
3254
|
)
|
|
2545
3255
|
] }),
|
|
2546
|
-
!isEmpty &&
|
|
3256
|
+
!isEmpty && composerDock
|
|
2547
3257
|
]
|
|
2548
3258
|
}
|
|
2549
3259
|
);
|
|
2550
3260
|
}
|
|
2551
3261
|
|
|
2552
3262
|
// src/view/WorkspaceHeader.tsx
|
|
2553
|
-
import {
|
|
2554
|
-
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";
|
|
2555
3265
|
|
|
2556
3266
|
// src/export-markdown.ts
|
|
2557
3267
|
var ROLE_LABELS = {
|
|
@@ -2583,8 +3293,52 @@ function downloadMessagesAsMarkdown(title, messages) {
|
|
|
2583
3293
|
URL.revokeObjectURL(url);
|
|
2584
3294
|
}
|
|
2585
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
|
+
|
|
2586
3340
|
// src/view/WorkspaceHeader.tsx
|
|
2587
|
-
import { jsx as
|
|
3341
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2588
3342
|
function readCurrentTheme() {
|
|
2589
3343
|
if (typeof document === "undefined") {
|
|
2590
3344
|
return "light";
|
|
@@ -2604,10 +3358,10 @@ function WorkspaceHeader({
|
|
|
2604
3358
|
onTitleChange
|
|
2605
3359
|
}) {
|
|
2606
3360
|
const hasActions = headerActions !== void 0 && headerActions.length > 0;
|
|
2607
|
-
const [overrideTitle, setOverrideTitle] =
|
|
2608
|
-
const [editing, setEditing] =
|
|
2609
|
-
const [draft, setDraft] =
|
|
2610
|
-
const prevTitleRef =
|
|
3361
|
+
const [overrideTitle, setOverrideTitle] = useState13(null);
|
|
3362
|
+
const [editing, setEditing] = useState13(false);
|
|
3363
|
+
const [draft, setDraft] = useState13("");
|
|
3364
|
+
const prevTitleRef = useRef11(title);
|
|
2611
3365
|
if (prevTitleRef.current !== title) {
|
|
2612
3366
|
prevTitleRef.current = title;
|
|
2613
3367
|
if (overrideTitle !== null) {
|
|
@@ -2615,7 +3369,7 @@ function WorkspaceHeader({
|
|
|
2615
3369
|
}
|
|
2616
3370
|
}
|
|
2617
3371
|
const displayTitle = overrideTitle ?? title;
|
|
2618
|
-
const [theme, setTheme] =
|
|
3372
|
+
const [theme, setTheme] = useState13(readCurrentTheme);
|
|
2619
3373
|
const commitTitle = () => {
|
|
2620
3374
|
setEditing(false);
|
|
2621
3375
|
const next = draft.trim();
|
|
@@ -2642,8 +3396,24 @@ function WorkspaceHeader({
|
|
|
2642
3396
|
store.clear();
|
|
2643
3397
|
onClear?.();
|
|
2644
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
|
+
}, []);
|
|
2645
3415
|
const actionButtons = {
|
|
2646
|
-
export: /* @__PURE__ */
|
|
3416
|
+
export: /* @__PURE__ */ jsx16(
|
|
2647
3417
|
"button",
|
|
2648
3418
|
{
|
|
2649
3419
|
type: "button",
|
|
@@ -2651,11 +3421,11 @@ function WorkspaceHeader({
|
|
|
2651
3421
|
title: "\u5BFC\u51FA Markdown",
|
|
2652
3422
|
"aria-label": "\u5BFC\u51FA Markdown",
|
|
2653
3423
|
onClick: handleExport,
|
|
2654
|
-
children: /* @__PURE__ */
|
|
3424
|
+
children: /* @__PURE__ */ jsx16(Icon10, { name: "download", size: 15 })
|
|
2655
3425
|
},
|
|
2656
3426
|
"export"
|
|
2657
3427
|
),
|
|
2658
|
-
theme: /* @__PURE__ */
|
|
3428
|
+
theme: /* @__PURE__ */ jsx16(
|
|
2659
3429
|
"button",
|
|
2660
3430
|
{
|
|
2661
3431
|
type: "button",
|
|
@@ -2663,11 +3433,11 @@ function WorkspaceHeader({
|
|
|
2663
3433
|
title: theme === "dark" ? "\u5207\u6362\u4E3A\u6D45\u8272" : "\u5207\u6362\u4E3A\u6DF1\u8272",
|
|
2664
3434
|
"aria-label": "\u5207\u6362\u660E\u6697\u4E3B\u9898",
|
|
2665
3435
|
onClick: handleTheme,
|
|
2666
|
-
children: theme === "dark" ? /* @__PURE__ */
|
|
3436
|
+
children: theme === "dark" ? /* @__PURE__ */ jsx16(Icon10, { name: "sun", size: 15 }) : /* @__PURE__ */ jsx16(Icon10, { name: "moon", size: 15 })
|
|
2667
3437
|
},
|
|
2668
3438
|
"theme"
|
|
2669
3439
|
),
|
|
2670
|
-
clear: /* @__PURE__ */
|
|
3440
|
+
clear: /* @__PURE__ */ jsx16(
|
|
2671
3441
|
"button",
|
|
2672
3442
|
{
|
|
2673
3443
|
type: "button",
|
|
@@ -2675,12 +3445,12 @@ function WorkspaceHeader({
|
|
|
2675
3445
|
title: "\u6E05\u7A7A\u4F1A\u8BDD",
|
|
2676
3446
|
"aria-label": "\u6E05\u7A7A\u4F1A\u8BDD",
|
|
2677
3447
|
onClick: handleClear,
|
|
2678
|
-
children: /* @__PURE__ */
|
|
3448
|
+
children: /* @__PURE__ */ jsx16(Icon10, { name: "trash", size: 15 })
|
|
2679
3449
|
},
|
|
2680
3450
|
"clear"
|
|
2681
3451
|
)
|
|
2682
3452
|
};
|
|
2683
|
-
const titleNode = editableTitle ? editing ? /* @__PURE__ */
|
|
3453
|
+
const titleNode = editableTitle ? editing ? /* @__PURE__ */ jsx16(
|
|
2684
3454
|
"input",
|
|
2685
3455
|
{
|
|
2686
3456
|
className: "pactor-chat-workspace__title-input",
|
|
@@ -2697,7 +3467,7 @@ function WorkspaceHeader({
|
|
|
2697
3467
|
}
|
|
2698
3468
|
}
|
|
2699
3469
|
}
|
|
2700
|
-
) : /* @__PURE__ */
|
|
3470
|
+
) : /* @__PURE__ */ jsx16(
|
|
2701
3471
|
"button",
|
|
2702
3472
|
{
|
|
2703
3473
|
type: "button",
|
|
@@ -2709,7 +3479,7 @@ function WorkspaceHeader({
|
|
|
2709
3479
|
},
|
|
2710
3480
|
children: displayTitle
|
|
2711
3481
|
}
|
|
2712
|
-
) : /* @__PURE__ */
|
|
3482
|
+
) : /* @__PURE__ */ jsx16("div", { className: "pactor-chat-workspace__title", children: title });
|
|
2713
3483
|
return /* @__PURE__ */ jsxs11("header", { className: "pactor-chat-workspace__header", children: [
|
|
2714
3484
|
headerStart !== void 0 ? (
|
|
2715
3485
|
// header 位模型 chip(决策 D2):与 title 组成左端组,chip 在前
|
|
@@ -2719,19 +3489,28 @@ function WorkspaceHeader({
|
|
|
2719
3489
|
] })
|
|
2720
3490
|
) : titleNode,
|
|
2721
3491
|
hasActions ? /* @__PURE__ */ jsxs11("div", { className: "pactor-chat-workspace__header-right", children: [
|
|
2722
|
-
/* @__PURE__ */
|
|
2723
|
-
|
|
2724
|
-
|
|
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
|
|
2725
3504
|
] });
|
|
2726
3505
|
}
|
|
2727
3506
|
|
|
2728
3507
|
// src/chat-composition.tsx
|
|
2729
|
-
import { Fragment as
|
|
3508
|
+
import { Fragment as Fragment9, jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2730
3509
|
function DslNodeSlotInner({ node }) {
|
|
2731
|
-
const { renderChildren } =
|
|
3510
|
+
const { renderChildren } = useRenderer4();
|
|
2732
3511
|
return renderChildren([node]);
|
|
2733
3512
|
}
|
|
2734
|
-
var DslSlotGuard = class extends
|
|
3513
|
+
var DslSlotGuard = class extends Component3 {
|
|
2735
3514
|
constructor() {
|
|
2736
3515
|
super(...arguments);
|
|
2737
3516
|
this.state = { failed: false };
|
|
@@ -2749,7 +3528,7 @@ var DslSlotGuard = class extends Component2 {
|
|
|
2749
3528
|
}
|
|
2750
3529
|
};
|
|
2751
3530
|
function DslNodeSlot({ node }) {
|
|
2752
|
-
return /* @__PURE__ */
|
|
3531
|
+
return /* @__PURE__ */ jsx17(DslSlotGuard, { children: /* @__PURE__ */ jsx17(DslNodeSlotInner, { node }) });
|
|
2753
3532
|
}
|
|
2754
3533
|
function isDslNodeValue(value) {
|
|
2755
3534
|
return typeof value === "object" && value !== null && !Array.isArray(value) && !isValidElement(value) && typeof value.type === "string";
|
|
@@ -2759,7 +3538,7 @@ function resolveSlot(slot) {
|
|
|
2759
3538
|
return void 0;
|
|
2760
3539
|
}
|
|
2761
3540
|
if (isDslNodeValue(slot)) {
|
|
2762
|
-
return /* @__PURE__ */
|
|
3541
|
+
return /* @__PURE__ */ jsx17(DslNodeSlot, { node: slot });
|
|
2763
3542
|
}
|
|
2764
3543
|
return slot;
|
|
2765
3544
|
}
|
|
@@ -2789,7 +3568,11 @@ function ChatComposition({
|
|
|
2789
3568
|
messageActions,
|
|
2790
3569
|
onMessageAction,
|
|
2791
3570
|
sidebar,
|
|
3571
|
+
toolbarStart,
|
|
2792
3572
|
toolbarEnd,
|
|
3573
|
+
composerFooter,
|
|
3574
|
+
composerBottom,
|
|
3575
|
+
hideToolbar,
|
|
2793
3576
|
className,
|
|
2794
3577
|
onSend,
|
|
2795
3578
|
artifact,
|
|
@@ -2799,12 +3582,12 @@ function ChatComposition({
|
|
|
2799
3582
|
onArtifact,
|
|
2800
3583
|
onOpenArtifact
|
|
2801
3584
|
}) {
|
|
2802
|
-
const storeRef =
|
|
3585
|
+
const storeRef = useRef12(null);
|
|
2803
3586
|
if (storeRef.current === null) {
|
|
2804
3587
|
storeRef.current = services.store ?? services.storeFactory?.() ?? new ConversationStore();
|
|
2805
3588
|
}
|
|
2806
3589
|
const store = storeRef.current;
|
|
2807
|
-
const artifactStoreRef =
|
|
3590
|
+
const artifactStoreRef = useRef12(null);
|
|
2808
3591
|
if (artifactStoreRef.current === null) {
|
|
2809
3592
|
artifactStoreRef.current = services.artifactStore ?? new ArtifactStore();
|
|
2810
3593
|
}
|
|
@@ -2828,7 +3611,7 @@ function ChatComposition({
|
|
|
2828
3611
|
artifactStore.open(next);
|
|
2829
3612
|
}
|
|
2830
3613
|
};
|
|
2831
|
-
const [attachments, setAttachments] =
|
|
3614
|
+
const [attachments, setAttachments] = useState14([]);
|
|
2832
3615
|
const handleAttachFiles = services.onAttachFiles ? (files) => {
|
|
2833
3616
|
void Promise.resolve(services.onAttachFiles(files)).then(
|
|
2834
3617
|
(created) => {
|
|
@@ -2848,24 +3631,38 @@ function ChatComposition({
|
|
|
2848
3631
|
model,
|
|
2849
3632
|
onModelChange
|
|
2850
3633
|
});
|
|
2851
|
-
const headerModelChip = modelPlacement === "header" && modelsEnabled ? /* @__PURE__ */
|
|
2852
|
-
|
|
3634
|
+
const headerModelChip = modelPlacement === "header" && modelsEnabled ? /* @__PURE__ */ jsx17(
|
|
3635
|
+
ModelSelect,
|
|
2853
3636
|
{
|
|
2854
3637
|
models,
|
|
2855
3638
|
model: currentModel,
|
|
2856
3639
|
onModelChange: handleModelChange
|
|
2857
3640
|
}
|
|
2858
3641
|
) : void 0;
|
|
2859
|
-
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: [
|
|
2860
3643
|
services.toolbarEnd,
|
|
2861
3644
|
toolbarEnd
|
|
2862
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;
|
|
2863
3660
|
const workspace = /* @__PURE__ */ jsxs12(
|
|
2864
3661
|
"div",
|
|
2865
3662
|
{
|
|
2866
3663
|
className: `pactor-chat-workspace${className ? ` ${className}` : ""}`,
|
|
2867
3664
|
children: [
|
|
2868
|
-
|
|
3665
|
+
renderHeader ? header ?? /* @__PURE__ */ jsx17(
|
|
2869
3666
|
WorkspaceHeader,
|
|
2870
3667
|
{
|
|
2871
3668
|
title,
|
|
@@ -2880,7 +3677,7 @@ function ChatComposition({
|
|
|
2880
3677
|
onTitleChange
|
|
2881
3678
|
}
|
|
2882
3679
|
) : null,
|
|
2883
|
-
/* @__PURE__ */
|
|
3680
|
+
/* @__PURE__ */ jsx17(
|
|
2884
3681
|
ChatView,
|
|
2885
3682
|
{
|
|
2886
3683
|
store,
|
|
@@ -2900,8 +3697,11 @@ function ChatComposition({
|
|
|
2900
3697
|
onAttachmentsChange: setAttachments,
|
|
2901
3698
|
onAttachFiles: handleAttachFiles,
|
|
2902
3699
|
onAttachmentClick: services.onAttachmentClick,
|
|
2903
|
-
toolbarStart:
|
|
3700
|
+
toolbarStart: mergedToolbarStart,
|
|
2904
3701
|
toolbarEnd: mergedToolbarEnd,
|
|
3702
|
+
composerFooter: mergedComposerFooter,
|
|
3703
|
+
composerBottom: mergedComposerBottom,
|
|
3704
|
+
hideToolbar,
|
|
2905
3705
|
onMentionTrigger: services.onMentionTrigger,
|
|
2906
3706
|
onPlusMenu: services.onPlusMenu,
|
|
2907
3707
|
onArtifact,
|
|
@@ -2920,15 +3720,15 @@ function ChatComposition({
|
|
|
2920
3720
|
]
|
|
2921
3721
|
}
|
|
2922
3722
|
);
|
|
2923
|
-
const main = sidebar ? /* @__PURE__ */
|
|
3723
|
+
const main = sidebar ? /* @__PURE__ */ jsx17(AppShell, { sidebar, children: workspace }) : workspace;
|
|
2924
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;
|
|
2925
3725
|
if (!panelFeatureUsed && !effectivePanelOpen) {
|
|
2926
3726
|
return main;
|
|
2927
3727
|
}
|
|
2928
3728
|
return /* @__PURE__ */ jsxs12("div", { className: "pactor-chat-inspector-host", children: [
|
|
2929
3729
|
main,
|
|
2930
|
-
effectivePanelOpen ? /* @__PURE__ */ jsxs12(
|
|
2931
|
-
/* @__PURE__ */
|
|
3730
|
+
effectivePanelOpen ? /* @__PURE__ */ jsxs12(Fragment9, { children: [
|
|
3731
|
+
/* @__PURE__ */ jsx17(
|
|
2932
3732
|
"div",
|
|
2933
3733
|
{
|
|
2934
3734
|
className: "pactor-chat-inspector__scrim",
|
|
@@ -2936,7 +3736,7 @@ function ChatComposition({
|
|
|
2936
3736
|
onClick: handlePanelClose
|
|
2937
3737
|
}
|
|
2938
3738
|
),
|
|
2939
|
-
/* @__PURE__ */
|
|
3739
|
+
/* @__PURE__ */ jsx17(
|
|
2940
3740
|
ArtifactPanel,
|
|
2941
3741
|
{
|
|
2942
3742
|
artifact: effectiveArtifact,
|
|
@@ -2952,20 +3752,20 @@ function ChatComposition({
|
|
|
2952
3752
|
|
|
2953
3753
|
// src/chat-services.tsx
|
|
2954
3754
|
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
2955
|
-
import { jsx as
|
|
3755
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2956
3756
|
var ChatServicesContext = createContext2(null);
|
|
2957
3757
|
function ChatServicesProvider({
|
|
2958
3758
|
value,
|
|
2959
3759
|
children
|
|
2960
3760
|
}) {
|
|
2961
|
-
return /* @__PURE__ */
|
|
3761
|
+
return /* @__PURE__ */ jsx18(ChatServicesContext.Provider, { value, children });
|
|
2962
3762
|
}
|
|
2963
3763
|
function useChatServices() {
|
|
2964
3764
|
return useContext2(ChatServicesContext);
|
|
2965
3765
|
}
|
|
2966
3766
|
|
|
2967
3767
|
// src/chat-workspace.tsx
|
|
2968
|
-
import { jsx as
|
|
3768
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2969
3769
|
function createChatWorkspace(services) {
|
|
2970
3770
|
function ChatWorkspace({
|
|
2971
3771
|
title,
|
|
@@ -2975,7 +3775,11 @@ function createChatWorkspace(services) {
|
|
|
2975
3775
|
conversationId,
|
|
2976
3776
|
params,
|
|
2977
3777
|
sidebar,
|
|
3778
|
+
toolbarStart,
|
|
2978
3779
|
toolbarEnd,
|
|
3780
|
+
composerFooter,
|
|
3781
|
+
composerBottom,
|
|
3782
|
+
hideToolbar,
|
|
2979
3783
|
artifact,
|
|
2980
3784
|
panelOpen,
|
|
2981
3785
|
onPanelClose,
|
|
@@ -2998,7 +3802,7 @@ function createChatWorkspace(services) {
|
|
|
2998
3802
|
onMessageAction,
|
|
2999
3803
|
className
|
|
3000
3804
|
}) {
|
|
3001
|
-
return /* @__PURE__ */
|
|
3805
|
+
return /* @__PURE__ */ jsx19(ChatServicesProvider, { value: services, children: /* @__PURE__ */ jsx19(
|
|
3002
3806
|
ChatComposition,
|
|
3003
3807
|
{
|
|
3004
3808
|
services,
|
|
@@ -3009,15 +3813,17 @@ function createChatWorkspace(services) {
|
|
|
3009
3813
|
conversationId,
|
|
3010
3814
|
params,
|
|
3011
3815
|
className,
|
|
3012
|
-
showHeader: title !== void 0 || services.headerExtra !== void 0 || // header 位模型 chip(决策 D2):仅配置 models 也渲染极简头部
|
|
3013
|
-
modelPlacement === "header" && models !== void 0 && models.length > 0,
|
|
3014
3816
|
headerExtra: services.headerExtra,
|
|
3015
|
-
sidebar: sidebar ? /* @__PURE__ */
|
|
3016
|
-
|
|
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,
|
|
3017
3823
|
artifact,
|
|
3018
3824
|
panelOpen,
|
|
3019
3825
|
onPanelClose,
|
|
3020
|
-
inspector: inspector ? /* @__PURE__ */
|
|
3826
|
+
inspector: inspector ? /* @__PURE__ */ jsx19(DslNodeSlot, { node: inspector }) : void 0,
|
|
3021
3827
|
onArtifact,
|
|
3022
3828
|
onOpenArtifact,
|
|
3023
3829
|
headerActions,
|
|
@@ -3041,23 +3847,37 @@ function createChatWorkspace(services) {
|
|
|
3041
3847
|
}
|
|
3042
3848
|
|
|
3043
3849
|
// src/view/Chat.tsx
|
|
3044
|
-
import {
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
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
|
+
}
|
|
3058
3878
|
|
|
3059
3879
|
// src/view/ChatShell.tsx
|
|
3060
|
-
import { jsx as
|
|
3880
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
3061
3881
|
function ChatShell({
|
|
3062
3882
|
menu,
|
|
3063
3883
|
activeMenuKey,
|
|
@@ -3069,7 +3889,7 @@ function ChatShell({
|
|
|
3069
3889
|
className,
|
|
3070
3890
|
onMenuSelect
|
|
3071
3891
|
}) {
|
|
3072
|
-
const sidebarContent = resolveSlot(sidebar) ?? (menu && menu.length > 0 ? /* @__PURE__ */
|
|
3892
|
+
const sidebarContent = resolveSlot(sidebar) ?? (menu && menu.length > 0 ? /* @__PURE__ */ jsx20(
|
|
3073
3893
|
ChatSidebarMenu,
|
|
3074
3894
|
{
|
|
3075
3895
|
menu,
|
|
@@ -3077,7 +3897,7 @@ function ChatShell({
|
|
|
3077
3897
|
onMenuSelect
|
|
3078
3898
|
}
|
|
3079
3899
|
) : null);
|
|
3080
|
-
return /* @__PURE__ */
|
|
3900
|
+
return /* @__PURE__ */ jsx20(
|
|
3081
3901
|
AppShell,
|
|
3082
3902
|
{
|
|
3083
3903
|
sidebar: sidebarContent,
|
|
@@ -3094,7 +3914,7 @@ function ChatShellDslAdapter({
|
|
|
3094
3914
|
onMenuSelect,
|
|
3095
3915
|
...rest
|
|
3096
3916
|
}) {
|
|
3097
|
-
return /* @__PURE__ */
|
|
3917
|
+
return /* @__PURE__ */ jsx20(
|
|
3098
3918
|
ChatShell,
|
|
3099
3919
|
{
|
|
3100
3920
|
...rest,
|
|
@@ -3109,39 +3929,45 @@ function registerChatShellComponent(registry) {
|
|
|
3109
3929
|
}
|
|
3110
3930
|
|
|
3111
3931
|
// src/view/Chat.tsx
|
|
3112
|
-
import { jsx as
|
|
3113
|
-
var MENU_ICONS = {
|
|
3114
|
-
plus: Plus2,
|
|
3115
|
-
chat: MessageSquare,
|
|
3116
|
-
history: History,
|
|
3117
|
-
settings: Settings,
|
|
3118
|
-
star: Star,
|
|
3119
|
-
search: Search,
|
|
3120
|
-
user: User,
|
|
3121
|
-
folder: Folder
|
|
3122
|
-
};
|
|
3932
|
+
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3123
3933
|
function ChatSidebarMenu({
|
|
3124
3934
|
menu,
|
|
3125
3935
|
activeMenuKey,
|
|
3126
3936
|
onMenuSelect
|
|
3127
3937
|
}) {
|
|
3128
3938
|
const drawer = useSidebarDrawer();
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
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(
|
|
3138
3965
|
"button",
|
|
3139
3966
|
{
|
|
3140
3967
|
type: "button",
|
|
3141
3968
|
className: `pactor-chat-menu__item${active ? " pactor-chat-menu__item--active" : ""}`,
|
|
3142
3969
|
disabled: item.disabled === true,
|
|
3143
3970
|
"aria-current": active ? "true" : void 0,
|
|
3144
|
-
title: drawer?.collapsed ? item.label : void 0,
|
|
3145
3971
|
onClick: () => {
|
|
3146
3972
|
if (item.disabled) {
|
|
3147
3973
|
return;
|
|
@@ -3150,21 +3976,26 @@ function ChatSidebarMenu({
|
|
|
3150
3976
|
drawer?.close();
|
|
3151
3977
|
},
|
|
3152
3978
|
children: [
|
|
3153
|
-
item.icon !== void 0 ?
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
"aria-hidden": true
|
|
3158
|
-
}
|
|
3159
|
-
) : null,
|
|
3160
|
-
/* @__PURE__ */ jsx18("span", { className: "pactor-chat-menu__label", children: item.label }),
|
|
3161
|
-
item.dot === true ? /* @__PURE__ */ jsx18("span", { className: "pactor-chat-menu__dot", "aria-hidden": true }) : null,
|
|
3162
|
-
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
|
|
3163
3983
|
]
|
|
3164
3984
|
}
|
|
3165
|
-
)
|
|
3166
|
-
|
|
3167
|
-
|
|
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
|
+
);
|
|
3168
3999
|
}
|
|
3169
4000
|
function Chat({
|
|
3170
4001
|
title,
|
|
@@ -3177,6 +4008,11 @@ function Chat({
|
|
|
3177
4008
|
menu,
|
|
3178
4009
|
activeMenuKey,
|
|
3179
4010
|
sidebar,
|
|
4011
|
+
toolbarStart,
|
|
4012
|
+
toolbarEnd,
|
|
4013
|
+
composerFooter,
|
|
4014
|
+
composerBottom,
|
|
4015
|
+
hideToolbar,
|
|
3180
4016
|
headerExtra,
|
|
3181
4017
|
header,
|
|
3182
4018
|
headerActions,
|
|
@@ -3204,7 +4040,7 @@ function Chat({
|
|
|
3204
4040
|
onMenuSelect
|
|
3205
4041
|
}) {
|
|
3206
4042
|
const services = useChatServices();
|
|
3207
|
-
|
|
4043
|
+
useEffect10(() => {
|
|
3208
4044
|
if (!services) {
|
|
3209
4045
|
console.warn(
|
|
3210
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"
|
|
@@ -3212,10 +4048,10 @@ function Chat({
|
|
|
3212
4048
|
}
|
|
3213
4049
|
}, [services]);
|
|
3214
4050
|
if (!services) {
|
|
3215
|
-
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" });
|
|
3216
4052
|
}
|
|
3217
4053
|
const sidebarSlot = resolveSlot(sidebar);
|
|
3218
|
-
const sidebarContent = sidebarSlot ?? (menu && menu.length > 0 ? /* @__PURE__ */
|
|
4054
|
+
const sidebarContent = sidebarSlot ?? (menu && menu.length > 0 ? /* @__PURE__ */ jsx21(
|
|
3219
4055
|
ChatSidebarMenu,
|
|
3220
4056
|
{
|
|
3221
4057
|
menu,
|
|
@@ -3223,7 +4059,7 @@ function Chat({
|
|
|
3223
4059
|
onMenuSelect
|
|
3224
4060
|
}
|
|
3225
4061
|
) : void 0);
|
|
3226
|
-
return /* @__PURE__ */
|
|
4062
|
+
return /* @__PURE__ */ jsx21(
|
|
3227
4063
|
ChatComposition,
|
|
3228
4064
|
{
|
|
3229
4065
|
services,
|
|
@@ -3234,9 +4070,14 @@ function Chat({
|
|
|
3234
4070
|
conversationId,
|
|
3235
4071
|
params,
|
|
3236
4072
|
className,
|
|
3237
|
-
showHeader
|
|
4073
|
+
showHeader,
|
|
3238
4074
|
header: resolveSlot(header),
|
|
3239
4075
|
headerExtra: resolveSlot(headerExtra) ?? services.headerExtra,
|
|
4076
|
+
toolbarStart: resolveSlot(toolbarStart),
|
|
4077
|
+
toolbarEnd: resolveSlot(toolbarEnd),
|
|
4078
|
+
composerFooter: resolveSlot(composerFooter),
|
|
4079
|
+
composerBottom: resolveSlot(composerBottom),
|
|
4080
|
+
hideToolbar,
|
|
3240
4081
|
headerActions,
|
|
3241
4082
|
editableTitle,
|
|
3242
4083
|
onExport,
|
|
@@ -3278,7 +4119,7 @@ function ChatDslAdapter({
|
|
|
3278
4119
|
onTitleChange,
|
|
3279
4120
|
...rest
|
|
3280
4121
|
}) {
|
|
3281
|
-
return /* @__PURE__ */
|
|
4122
|
+
return /* @__PURE__ */ jsx21(
|
|
3282
4123
|
Chat,
|
|
3283
4124
|
{
|
|
3284
4125
|
...rest,
|
|
@@ -3305,11 +4146,11 @@ function registerChatComponent(registry) {
|
|
|
3305
4146
|
}
|
|
3306
4147
|
|
|
3307
4148
|
// src/view/ChatLayout.tsx
|
|
3308
|
-
import { jsx as
|
|
4149
|
+
import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3309
4150
|
function ChatLayout({ title, children }) {
|
|
3310
4151
|
return /* @__PURE__ */ jsxs14("div", { className: "pactor-chat-layout", children: [
|
|
3311
|
-
/* @__PURE__ */
|
|
3312
|
-
/* @__PURE__ */
|
|
4152
|
+
/* @__PURE__ */ jsx22("header", { className: "pactor-chat-layout__header", children: title ?? "Chat" }),
|
|
4153
|
+
/* @__PURE__ */ jsx22("main", { className: "pactor-chat-layout__main", children })
|
|
3313
4154
|
] });
|
|
3314
4155
|
}
|
|
3315
4156
|
var CHAT_LAYOUT_TYPE = "chat";
|
|
@@ -3338,8 +4179,6 @@ export {
|
|
|
3338
4179
|
ConversationStore,
|
|
3339
4180
|
DEFAULT_CHAT_GREETING,
|
|
3340
4181
|
EmptyState,
|
|
3341
|
-
MENU_ICONS,
|
|
3342
|
-
MESSAGE_ACTION_ICONS,
|
|
3343
4182
|
MessageActions,
|
|
3344
4183
|
MessageBubble,
|
|
3345
4184
|
PartRenderer,
|