@pactor-app/chat 0.1.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1483 -600
- package/dist/index.d.cts +97 -23
- package/dist/index.d.ts +97 -23
- package/dist/index.js +1453 -600
- package/package.json +7 -8
- package/styles.css +188 -176
package/dist/index.cjs
CHANGED
|
@@ -39,8 +39,6 @@ __export(index_exports, {
|
|
|
39
39
|
ConversationStore: () => ConversationStore,
|
|
40
40
|
DEFAULT_CHAT_GREETING: () => DEFAULT_CHAT_GREETING,
|
|
41
41
|
EmptyState: () => EmptyState,
|
|
42
|
-
MENU_ICONS: () => MENU_ICONS,
|
|
43
|
-
MESSAGE_ACTION_ICONS: () => MESSAGE_ACTION_ICONS,
|
|
44
42
|
MessageActions: () => MessageActions,
|
|
45
43
|
MessageBubble: () => MessageBubble,
|
|
46
44
|
PartRenderer: () => PartRenderer,
|
|
@@ -719,20 +717,34 @@ function createChatRuntime(options = {}) {
|
|
|
719
717
|
}
|
|
720
718
|
|
|
721
719
|
// src/dsl-guard.ts
|
|
720
|
+
var import_core2 = require("@pactor-app/core");
|
|
722
721
|
var CHAT_DENIED_TYPE = "ChatDenied";
|
|
723
722
|
function guardChatDsl(node, registry) {
|
|
724
|
-
|
|
723
|
+
const type = node.type ?? "(reference)";
|
|
724
|
+
if (type !== CHAT_DENIED_TYPE && !registry.has(type)) {
|
|
725
|
+
return {
|
|
726
|
+
type: CHAT_DENIED_TYPE,
|
|
727
|
+
props: { deniedType: type }
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
if (node.children === void 0) {
|
|
731
|
+
return node;
|
|
732
|
+
}
|
|
733
|
+
if (!Array.isArray(node.children)) {
|
|
725
734
|
return {
|
|
726
735
|
type: CHAT_DENIED_TYPE,
|
|
727
|
-
props: { deniedType:
|
|
736
|
+
props: { deniedType: `${type}(remote)` }
|
|
728
737
|
};
|
|
729
738
|
}
|
|
730
|
-
if (
|
|
739
|
+
if (node.children.length === 0) {
|
|
731
740
|
return node;
|
|
732
741
|
}
|
|
733
742
|
return {
|
|
734
743
|
...node,
|
|
735
|
-
|
|
744
|
+
// 数组中混排的引用元素同样无法静态过白名单:替换为受控占位
|
|
745
|
+
children: node.children.map(
|
|
746
|
+
(child) => (0, import_core2.isDslSourceRef)(child) ? { type: CHAT_DENIED_TYPE, props: { deniedType: "(remote)" } } : guardChatDsl(child, registry)
|
|
747
|
+
)
|
|
736
748
|
};
|
|
737
749
|
}
|
|
738
750
|
|
|
@@ -844,8 +856,8 @@ function useChatAutoScroll({
|
|
|
844
856
|
}
|
|
845
857
|
|
|
846
858
|
// src/chat-composition.tsx
|
|
847
|
-
var
|
|
848
|
-
var
|
|
859
|
+
var import_runtime5 = require("@pactor-app/runtime");
|
|
860
|
+
var import_react16 = require("react");
|
|
849
861
|
|
|
850
862
|
// src/hooks/use-chat-model.ts
|
|
851
863
|
var import_react3 = require("react");
|
|
@@ -870,121 +882,274 @@ function useChatModel({
|
|
|
870
882
|
}
|
|
871
883
|
|
|
872
884
|
// src/view/AppShell.tsx
|
|
873
|
-
var
|
|
874
|
-
var import_react4 = require("react");
|
|
885
|
+
var import_components = require("@pactor-app/ui/components");
|
|
875
886
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
876
|
-
var SidebarDrawerContext = (0, import_react4.createContext)(null);
|
|
877
887
|
function useSidebarDrawer() {
|
|
878
|
-
return (0,
|
|
888
|
+
return (0, import_components.useSidebarDrawer)();
|
|
879
889
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
function AppShell({ sidebar, brand, locationKey, sidebarFooter, collapsible = false, children, className }) {
|
|
900
|
-
const [drawerOpen, setDrawerOpen] = (0, import_react4.useState)(false);
|
|
901
|
-
const isMobile = useIsMobileViewport();
|
|
902
|
-
const close = (0, import_react4.useCallback)(() => setDrawerOpen(false), []);
|
|
903
|
-
const [collapsed, setCollapsed] = (0, import_react4.useState)(false);
|
|
904
|
-
const collapsedEffective = collapsible && collapsed && !isMobile;
|
|
905
|
-
const framed = brand !== void 0 || sidebarFooter !== void 0;
|
|
906
|
-
const [trackedLocationKey, setTrackedLocationKey] = (0, import_react4.useState)(locationKey);
|
|
907
|
-
if (trackedLocationKey !== locationKey) {
|
|
908
|
-
setTrackedLocationKey(locationKey);
|
|
909
|
-
setDrawerOpen(false);
|
|
910
|
-
}
|
|
911
|
-
(0, import_react4.useEffect)(() => {
|
|
912
|
-
if (!drawerOpen) {
|
|
913
|
-
return;
|
|
890
|
+
function AppShell({
|
|
891
|
+
sidebar,
|
|
892
|
+
brand,
|
|
893
|
+
locationKey,
|
|
894
|
+
sidebarFooter,
|
|
895
|
+
collapsible = false,
|
|
896
|
+
children,
|
|
897
|
+
className
|
|
898
|
+
}) {
|
|
899
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
900
|
+
import_components.Sidebar,
|
|
901
|
+
{
|
|
902
|
+
content: sidebar,
|
|
903
|
+
brand,
|
|
904
|
+
locationKey,
|
|
905
|
+
sidebarFooter,
|
|
906
|
+
collapsible,
|
|
907
|
+
className: `pactor-chat-shell h-full min-h-0${className ? ` ${className}` : ""}`,
|
|
908
|
+
children
|
|
914
909
|
}
|
|
915
|
-
|
|
916
|
-
if (event.key === "Escape") {
|
|
917
|
-
setDrawerOpen(false);
|
|
918
|
-
}
|
|
919
|
-
};
|
|
920
|
-
window.addEventListener("keydown", onKeyDown);
|
|
921
|
-
return () => window.removeEventListener("keydown", onKeyDown);
|
|
922
|
-
}, [drawerOpen]);
|
|
923
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SidebarDrawerContext.Provider, { value: { close, collapsed: collapsedEffective }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: `pactor-chat-shell${className ? ` ${className}` : ""}`, children: [
|
|
924
|
-
drawerOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pactor-chat-shell__scrim", "aria-hidden": true, onClick: close }) : null,
|
|
925
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
926
|
-
"div",
|
|
927
|
-
{
|
|
928
|
-
className: `pactor-chat-shell__sidebar${framed ? " pactor-chat-shell__sidebar--framed" : ""}${collapsedEffective ? " pactor-chat-shell__sidebar--collapsed" : ""}`,
|
|
929
|
-
"data-open": drawerOpen ? "true" : "false",
|
|
930
|
-
inert: isMobile && !drawerOpen ? true : void 0,
|
|
931
|
-
children: framed ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
932
|
-
brand !== void 0 && // 桌面品牌行(决策 D3):brand 左、折叠钮右;移动端由
|
|
933
|
-
// CSS 隐藏(品牌维持顶栏现状)
|
|
934
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "pactor-chat-shell__sidebar-header", children: [
|
|
935
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pactor-chat-shell__brand", children: brand }),
|
|
936
|
-
collapsible && !isMobile && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
937
|
-
"button",
|
|
938
|
-
{
|
|
939
|
-
type: "button",
|
|
940
|
-
className: "pactor-chat-icon-button pactor-chat-shell__collapse",
|
|
941
|
-
"aria-label": collapsedEffective ? "\u5C55\u5F00\u4FA7\u680F" : "\u6298\u53E0\u4FA7\u680F",
|
|
942
|
-
"aria-expanded": !collapsedEffective,
|
|
943
|
-
title: collapsedEffective ? "\u5C55\u5F00\u4FA7\u680F" : "\u6298\u53E0\u4FA7\u680F",
|
|
944
|
-
onClick: () => setCollapsed((value) => !value),
|
|
945
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.PanelLeft, { size: 16, strokeWidth: 1.7 })
|
|
946
|
-
}
|
|
947
|
-
)
|
|
948
|
-
] }),
|
|
949
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pactor-chat-shell__sidebar-body", children: sidebar }),
|
|
950
|
-
sidebarFooter !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pactor-chat-shell__sidebar-footer", children: sidebarFooter })
|
|
951
|
-
] }) : sidebar
|
|
952
|
-
}
|
|
953
|
-
),
|
|
954
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("main", { className: "pactor-chat-shell__main", children: [
|
|
955
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "pactor-chat-shell__topbar", children: [
|
|
956
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
957
|
-
"button",
|
|
958
|
-
{
|
|
959
|
-
type: "button",
|
|
960
|
-
className: "pactor-chat-icon-button pactor-chat-shell__menu",
|
|
961
|
-
"aria-label": "\u6253\u5F00\u5BFC\u822A",
|
|
962
|
-
"aria-expanded": drawerOpen,
|
|
963
|
-
onClick: () => setDrawerOpen(true),
|
|
964
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Menu, { size: 18, strokeWidth: 1.7 })
|
|
965
|
-
}
|
|
966
|
-
),
|
|
967
|
-
brand
|
|
968
|
-
] }),
|
|
969
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pactor-chat-shell__content", children })
|
|
970
|
-
] })
|
|
971
|
-
] }) });
|
|
910
|
+
);
|
|
972
911
|
}
|
|
973
912
|
|
|
974
913
|
// src/view/ArtifactPanel.tsx
|
|
975
|
-
var
|
|
976
|
-
var
|
|
914
|
+
var import_components4 = require("@pactor-app/ui/components");
|
|
915
|
+
var import_core3 = require("@pactor-app/core");
|
|
977
916
|
var import_markdown2 = require("@pactor-app/markdown");
|
|
978
|
-
var
|
|
917
|
+
var import_runtime4 = require("@pactor-app/runtime");
|
|
979
918
|
var import_react5 = require("react");
|
|
980
919
|
|
|
981
920
|
// src/view/PartRenderer.tsx
|
|
982
|
-
var
|
|
921
|
+
var import_components2 = require("@pactor-app/ui/components");
|
|
983
922
|
var import_markdown = require("@pactor-app/markdown");
|
|
923
|
+
var import_runtime3 = require("@pactor-app/runtime");
|
|
924
|
+
|
|
925
|
+
// src/view/chrome/artifact-card.tsx
|
|
926
|
+
function buildArtifactCardFragment(artifact) {
|
|
927
|
+
return {
|
|
928
|
+
requires: ["Card", "Flex", "Text", "Badge", "Button"],
|
|
929
|
+
node: {
|
|
930
|
+
type: "Card",
|
|
931
|
+
props: { className: "pactor-chat-artifact-card" },
|
|
932
|
+
children: [
|
|
933
|
+
{
|
|
934
|
+
type: "Flex",
|
|
935
|
+
props: { justify: "space-between", align: "center", gap: "small" },
|
|
936
|
+
children: [
|
|
937
|
+
{
|
|
938
|
+
type: "Text",
|
|
939
|
+
props: {
|
|
940
|
+
text: artifact.title,
|
|
941
|
+
strong: true,
|
|
942
|
+
className: "pactor-chat-artifact-card__title"
|
|
943
|
+
}
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
type: "Badge",
|
|
947
|
+
props: {
|
|
948
|
+
text: artifact.kind,
|
|
949
|
+
variant: "secondary",
|
|
950
|
+
className: "pactor-chat-artifact-card__kind"
|
|
951
|
+
}
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
type: "Button",
|
|
955
|
+
props: {
|
|
956
|
+
text: "\u5728\u9762\u677F\u4E2D\u6253\u5F00",
|
|
957
|
+
variant: "default",
|
|
958
|
+
size: "small",
|
|
959
|
+
className: "pactor-chat-artifact-card__open"
|
|
960
|
+
},
|
|
961
|
+
events: {
|
|
962
|
+
onClick: [
|
|
963
|
+
{
|
|
964
|
+
action: "chat.openArtifact",
|
|
965
|
+
params: { artifact }
|
|
966
|
+
}
|
|
967
|
+
]
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
]
|
|
971
|
+
}
|
|
972
|
+
]
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// src/view/chrome/ChromeSlot.tsx
|
|
984
978
|
var import_runtime2 = require("@pactor-app/runtime");
|
|
979
|
+
var import_react4 = require("react");
|
|
980
|
+
|
|
981
|
+
// src/view/chrome/actions.ts
|
|
982
|
+
var handlers = {};
|
|
983
|
+
function setChatChromeHandlers(next) {
|
|
984
|
+
handlers = { ...handlers, ...next };
|
|
985
|
+
}
|
|
986
|
+
var messageActionDispatchers = /* @__PURE__ */ new Map();
|
|
987
|
+
function setMessageActionDispatcher(token, dispatch) {
|
|
988
|
+
messageActionDispatchers.set(token, dispatch);
|
|
989
|
+
}
|
|
990
|
+
function clearMessageActionDispatcher(token) {
|
|
991
|
+
messageActionDispatchers.delete(token);
|
|
992
|
+
}
|
|
993
|
+
var CHROME_ACTION_HANDLERS = {
|
|
994
|
+
"chat.sendSuggestion": (action) => {
|
|
995
|
+
const text = action.params?.["text"];
|
|
996
|
+
if (typeof text === "string") {
|
|
997
|
+
handlers.sendSuggestion?.(text);
|
|
998
|
+
}
|
|
999
|
+
return { ok: true };
|
|
1000
|
+
},
|
|
1001
|
+
"chat.openArtifact": (action) => {
|
|
1002
|
+
const artifact = action.params?.["artifact"];
|
|
1003
|
+
if (artifact) {
|
|
1004
|
+
handlers.openArtifact?.(artifact);
|
|
1005
|
+
}
|
|
1006
|
+
return { ok: true };
|
|
1007
|
+
},
|
|
1008
|
+
"chat.messageAction": (action) => {
|
|
1009
|
+
const token = action.params?.["token"];
|
|
1010
|
+
const actionId = action.params?.["actionId"];
|
|
1011
|
+
if (typeof token === "string" && typeof actionId === "string") {
|
|
1012
|
+
messageActionDispatchers.get(token)?.(actionId);
|
|
1013
|
+
}
|
|
1014
|
+
return { ok: true };
|
|
1015
|
+
},
|
|
1016
|
+
"chat.composerSubmit": (action) => {
|
|
1017
|
+
const value = action.params?.["value"];
|
|
1018
|
+
if (typeof value === "string") {
|
|
1019
|
+
handlers.composerSubmit?.(value);
|
|
1020
|
+
}
|
|
1021
|
+
return { ok: true };
|
|
1022
|
+
},
|
|
1023
|
+
"chat.menuSelect": (action) => {
|
|
1024
|
+
const key = action.params?.["key"];
|
|
1025
|
+
if (typeof key === "string") {
|
|
1026
|
+
handlers.menuSelect?.(key);
|
|
1027
|
+
}
|
|
1028
|
+
return { ok: true };
|
|
1029
|
+
},
|
|
1030
|
+
"chat.modelChange": (action) => {
|
|
1031
|
+
const value = action.params?.["value"];
|
|
1032
|
+
if (typeof value === "string") {
|
|
1033
|
+
handlers.modelChange?.(value);
|
|
1034
|
+
}
|
|
1035
|
+
return { ok: true };
|
|
1036
|
+
},
|
|
1037
|
+
"chat.headerAction": (action) => {
|
|
1038
|
+
const name = action.params?.["action"];
|
|
1039
|
+
if (typeof name === "string") {
|
|
1040
|
+
handlers.headerAction?.(name);
|
|
1041
|
+
}
|
|
1042
|
+
return { ok: true };
|
|
1043
|
+
},
|
|
1044
|
+
"chat.panelClose": () => {
|
|
1045
|
+
handlers.panelClose?.();
|
|
1046
|
+
return { ok: true };
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
function ensureChatChromeActions(actions) {
|
|
1050
|
+
for (const [name, handler] of Object.entries(CHROME_ACTION_HANDLERS)) {
|
|
1051
|
+
if (!actions.has(name)) {
|
|
1052
|
+
actions.register(name, handler);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
function invokeChatPanelClose() {
|
|
1057
|
+
handlers.panelClose?.();
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
// src/view/chrome/ChromeSlot.tsx
|
|
985
1061
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1062
|
+
var warnedMissing = /* @__PURE__ */ new Set();
|
|
1063
|
+
function warnMissingOnce(key, detail) {
|
|
1064
|
+
if (!warnedMissing.has(key)) {
|
|
1065
|
+
warnedMissing.add(key);
|
|
1066
|
+
console.warn(`[@pactor-app/chat] ${detail}`);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
function ChromeSlotInner({
|
|
1070
|
+
fragment,
|
|
1071
|
+
fallback,
|
|
1072
|
+
components,
|
|
1073
|
+
wrap
|
|
1074
|
+
}) {
|
|
1075
|
+
let renderer;
|
|
1076
|
+
try {
|
|
1077
|
+
renderer = (0, import_runtime2.useRenderer)();
|
|
1078
|
+
} catch {
|
|
1079
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: fallback });
|
|
1080
|
+
}
|
|
1081
|
+
ensureChatChromeActions(renderer.context.actions);
|
|
1082
|
+
if (components) {
|
|
1083
|
+
for (const [name, component] of Object.entries(components)) {
|
|
1084
|
+
const existing = renderer.context.components.get(name);
|
|
1085
|
+
if (existing !== void 0 && existing !== component) {
|
|
1086
|
+
warnMissingOnce(
|
|
1087
|
+
`conflict:${name}`,
|
|
1088
|
+
`[@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`
|
|
1089
|
+
);
|
|
1090
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: fallback });
|
|
1091
|
+
}
|
|
1092
|
+
if (existing === void 0) {
|
|
1093
|
+
renderer.context.components.register(
|
|
1094
|
+
name,
|
|
1095
|
+
component
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
const missing = fragment.requires.filter(
|
|
1101
|
+
(type) => !renderer.context.components.has(type)
|
|
1102
|
+
);
|
|
1103
|
+
if (missing.length > 0) {
|
|
1104
|
+
warnMissingOnce(
|
|
1105
|
+
`${fragment.node.type}:${missing.join(",")}`,
|
|
1106
|
+
`[@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`
|
|
1107
|
+
);
|
|
1108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: fallback });
|
|
1109
|
+
}
|
|
1110
|
+
const rendered = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "pactor-chat-chrome", children: renderer.renderChildren([fragment.node]) });
|
|
1111
|
+
return wrap ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: wrap(rendered) }) : rendered;
|
|
1112
|
+
}
|
|
1113
|
+
var ChromeSlotGuard = class extends import_react4.Component {
|
|
1114
|
+
constructor() {
|
|
1115
|
+
super(...arguments);
|
|
1116
|
+
this.state = { failed: false };
|
|
1117
|
+
}
|
|
1118
|
+
static getDerivedStateFromError() {
|
|
1119
|
+
return { failed: true };
|
|
1120
|
+
}
|
|
1121
|
+
render() {
|
|
1122
|
+
return this.state.failed ? this.props.fallback : this.props.children;
|
|
1123
|
+
}
|
|
1124
|
+
};
|
|
1125
|
+
function ChromeSlot(props) {
|
|
1126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChromeSlotGuard, { fallback: props.fallback, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ChromeSlotInner, { ...props }) });
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
// src/view/chrome/feedback.tsx
|
|
1130
|
+
function buildErrorFragment(message) {
|
|
1131
|
+
return {
|
|
1132
|
+
requires: ["Alert"],
|
|
1133
|
+
node: {
|
|
1134
|
+
type: "Alert",
|
|
1135
|
+
props: { variant: "error", message }
|
|
1136
|
+
}
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
function buildStatusFragment(text) {
|
|
1140
|
+
return {
|
|
1141
|
+
requires: ["Text"],
|
|
1142
|
+
node: {
|
|
1143
|
+
type: "Text",
|
|
1144
|
+
props: { type: "secondary", text }
|
|
1145
|
+
}
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
// src/view/PartRenderer.tsx
|
|
1150
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
986
1151
|
function ChatDenied({ deniedType }) {
|
|
987
|
-
return /* @__PURE__ */ (0,
|
|
1152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "pactor-chat-denied", "data-pactor-chat-denied": deniedType, children: [
|
|
988
1153
|
"\u8BE5\u7EC4\u4EF6\u4E0D\u5141\u8BB8\u5728 Chat \u4E2D\u4F7F\u7528",
|
|
989
1154
|
deniedType ? `\uFF1A${deniedType}` : ""
|
|
990
1155
|
] });
|
|
@@ -993,64 +1158,90 @@ function ChatDslNode({
|
|
|
993
1158
|
node,
|
|
994
1159
|
scope
|
|
995
1160
|
}) {
|
|
996
|
-
const renderer = (0,
|
|
1161
|
+
const renderer = (0, import_runtime3.useRenderer)();
|
|
997
1162
|
const extraScope = scope ? buildChatScope(scope) : void 0;
|
|
998
|
-
return /* @__PURE__ */ (0,
|
|
1163
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: renderer.renderChildren([node], extraScope) });
|
|
999
1164
|
}
|
|
1000
1165
|
function SmoothText({ content, streaming }) {
|
|
1001
1166
|
const shown = useSmoothStreamText(content, streaming);
|
|
1002
|
-
return /* @__PURE__ */ (0,
|
|
1167
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pactor-chat-text", children: shown });
|
|
1003
1168
|
}
|
|
1004
1169
|
function SmoothMarkdown({ content, streaming }) {
|
|
1005
1170
|
const shown = useSmoothStreamText(content, streaming);
|
|
1006
|
-
return /* @__PURE__ */ (0,
|
|
1171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_markdown.MarkdownRenderer, { content: shown });
|
|
1007
1172
|
}
|
|
1008
1173
|
function PartRenderer({ part, runtime, scope, streaming = false, onOpenArtifact }) {
|
|
1009
1174
|
switch (part.type) {
|
|
1010
1175
|
case "text":
|
|
1011
|
-
return /* @__PURE__ */ (0,
|
|
1176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SmoothText, { content: part.content, streaming });
|
|
1012
1177
|
case "markdown":
|
|
1013
|
-
return /* @__PURE__ */ (0,
|
|
1178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SmoothMarkdown, { content: part.content, streaming });
|
|
1014
1179
|
case "thinking":
|
|
1015
1180
|
case "tool-call":
|
|
1016
1181
|
case "tool-result":
|
|
1017
1182
|
return null;
|
|
1018
1183
|
case "dsl": {
|
|
1019
1184
|
if (!part.schema || !runtime) {
|
|
1020
|
-
return /* @__PURE__ */ (0,
|
|
1185
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1186
|
+
ChromeSlot,
|
|
1187
|
+
{
|
|
1188
|
+
fragment: buildStatusFragment(
|
|
1189
|
+
part.schema ? "DSL \u6E32\u67D3\u4E0D\u53EF\u7528\uFF08\u672A\u6CE8\u5165 Safe Registry\uFF09" : "\u5185\u5BB9\u751F\u6210\u4E2D\u2026"
|
|
1190
|
+
),
|
|
1191
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("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" })
|
|
1192
|
+
}
|
|
1193
|
+
);
|
|
1021
1194
|
}
|
|
1022
1195
|
const guarded = guardChatDsl(part.schema, runtime.context.components);
|
|
1023
|
-
return /* @__PURE__ */ (0,
|
|
1196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pactor-chat-dsl", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_runtime3.DslRenderer, { context: runtime.context, engine: runtime.engine, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ChatDslNode, { node: guarded, scope }) }) });
|
|
1024
1197
|
}
|
|
1025
1198
|
case "error":
|
|
1026
|
-
return /* @__PURE__ */ (0,
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1200
|
+
ChromeSlot,
|
|
1201
|
+
{
|
|
1202
|
+
fragment: buildErrorFragment(part.message),
|
|
1203
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "pactor-chat-error", role: "alert", children: [
|
|
1204
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components2.Icon, { name: "error", size: 14 }),
|
|
1205
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: part.message })
|
|
1206
|
+
] })
|
|
1207
|
+
}
|
|
1208
|
+
);
|
|
1030
1209
|
case "status":
|
|
1031
|
-
return /* @__PURE__ */ (0,
|
|
1210
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1211
|
+
ChromeSlot,
|
|
1212
|
+
{
|
|
1213
|
+
fragment: buildStatusFragment(part.text),
|
|
1214
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pactor-chat-status", children: part.text })
|
|
1215
|
+
}
|
|
1216
|
+
);
|
|
1032
1217
|
case "artifact":
|
|
1033
|
-
return /* @__PURE__ */ (0,
|
|
1034
|
-
|
|
1218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1219
|
+
ChromeSlot,
|
|
1035
1220
|
{
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1221
|
+
fragment: buildArtifactCardFragment(part.artifact),
|
|
1222
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1223
|
+
"div",
|
|
1224
|
+
{
|
|
1225
|
+
className: "pactor-chat-artifact-card",
|
|
1226
|
+
"data-artifact-kind": part.artifact.kind,
|
|
1227
|
+
children: [
|
|
1228
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "pactor-chat-artifact-card__title", children: part.artifact.title }),
|
|
1229
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "pactor-chat-artifact-card__kind", children: part.artifact.kind }),
|
|
1230
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1231
|
+
"button",
|
|
1232
|
+
{
|
|
1233
|
+
type: "button",
|
|
1234
|
+
className: "pactor-chat-artifact-card__open",
|
|
1235
|
+
onClick: () => onOpenArtifact?.(part.artifact),
|
|
1236
|
+
children: [
|
|
1237
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_components2.Icon, { name: "panel-right-open", size: 13, strokeWidth: 1.7 }),
|
|
1238
|
+
"\u5728\u9762\u677F\u4E2D\u6253\u5F00"
|
|
1239
|
+
]
|
|
1240
|
+
}
|
|
1241
|
+
)
|
|
1242
|
+
]
|
|
1243
|
+
}
|
|
1244
|
+
)
|
|
1054
1245
|
}
|
|
1055
1246
|
);
|
|
1056
1247
|
default:
|
|
@@ -1058,14 +1249,71 @@ function PartRenderer({ part, runtime, scope, streaming = false, onOpenArtifact
|
|
|
1058
1249
|
}
|
|
1059
1250
|
}
|
|
1060
1251
|
|
|
1252
|
+
// src/view/chrome/panel-header.tsx
|
|
1253
|
+
var import_components3 = require("@pactor-app/ui/components");
|
|
1254
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1255
|
+
function ChatPanelCloseButton() {
|
|
1256
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1257
|
+
"button",
|
|
1258
|
+
{
|
|
1259
|
+
type: "button",
|
|
1260
|
+
className: "pactor-chat-icon-button pactor-chat-inspector__close",
|
|
1261
|
+
title: "\u5173\u95ED\u9762\u677F",
|
|
1262
|
+
"aria-label": "\u5173\u95ED\u9762\u677F",
|
|
1263
|
+
onClick: () => invokeChatPanelClose(),
|
|
1264
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_components3.Icon, { name: "x", size: 16 })
|
|
1265
|
+
}
|
|
1266
|
+
);
|
|
1267
|
+
}
|
|
1268
|
+
var PANEL_HEADER_INTERNAL_COMPONENTS = { ChatPanelCloseButton };
|
|
1269
|
+
function buildPanelHeaderFragment(props) {
|
|
1270
|
+
return {
|
|
1271
|
+
requires: ["Flex", "Text", "Badge", "ChatPanelCloseButton"],
|
|
1272
|
+
node: {
|
|
1273
|
+
type: "Flex",
|
|
1274
|
+
props: {
|
|
1275
|
+
justify: "space-between",
|
|
1276
|
+
align: "center",
|
|
1277
|
+
gap: "small",
|
|
1278
|
+
className: "pactor-chat-inspector__header-dsl"
|
|
1279
|
+
},
|
|
1280
|
+
children: [
|
|
1281
|
+
{
|
|
1282
|
+
type: "Flex",
|
|
1283
|
+
props: { align: "center", gap: "small" },
|
|
1284
|
+
children: [
|
|
1285
|
+
{
|
|
1286
|
+
type: "Text",
|
|
1287
|
+
props: {
|
|
1288
|
+
text: props.title,
|
|
1289
|
+
strong: true,
|
|
1290
|
+
className: "pactor-chat-inspector__title"
|
|
1291
|
+
}
|
|
1292
|
+
},
|
|
1293
|
+
{
|
|
1294
|
+
type: "Badge",
|
|
1295
|
+
props: {
|
|
1296
|
+
text: props.kind,
|
|
1297
|
+
variant: "secondary",
|
|
1298
|
+
className: "pactor-chat-inspector__kind"
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
]
|
|
1302
|
+
},
|
|
1303
|
+
{ type: "ChatPanelCloseButton" }
|
|
1304
|
+
]
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1061
1309
|
// src/view/ArtifactPanel.tsx
|
|
1062
|
-
var
|
|
1310
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1063
1311
|
function useArtifactRuntime(safeRegistry, user) {
|
|
1064
1312
|
return (0, import_react5.useMemo)(() => {
|
|
1065
1313
|
if (!safeRegistry) {
|
|
1066
1314
|
return void 0;
|
|
1067
1315
|
}
|
|
1068
|
-
const components = new
|
|
1316
|
+
const components = new import_core3.Registry("ChatArtifactRegistry");
|
|
1069
1317
|
components.register(CHAT_DENIED_TYPE, ChatDenied);
|
|
1070
1318
|
for (const name of safeRegistry.list()) {
|
|
1071
1319
|
components.register(name, safeRegistry.get(name));
|
|
@@ -1085,12 +1333,12 @@ var ArtifactDslGuard = class extends import_react5.Component {
|
|
|
1085
1333
|
console.warn("[@pactor-app/chat] DSL \u4EA7\u51FA\u7269\u6E32\u67D3\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u5C55\u793A", error);
|
|
1086
1334
|
}
|
|
1087
1335
|
render() {
|
|
1088
|
-
return this.state.failed ? /* @__PURE__ */ (0,
|
|
1336
|
+
return this.state.failed ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "pactor-chat-denied", children: "DSL \u4EA7\u51FA\u7269\u6E32\u67D3\u5931\u8D25\uFF0C\u5DF2\u964D\u7EA7\u5C55\u793A" }) : this.props.children;
|
|
1089
1337
|
}
|
|
1090
1338
|
};
|
|
1091
1339
|
function ArtifactDslNode({ node }) {
|
|
1092
|
-
const { renderChildren } = (0,
|
|
1093
|
-
return /* @__PURE__ */ (0,
|
|
1340
|
+
const { renderChildren } = (0, import_runtime4.useRenderer)();
|
|
1341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_jsx_runtime5.Fragment, { children: renderChildren([node]) });
|
|
1094
1342
|
}
|
|
1095
1343
|
function ArtifactDslContent({
|
|
1096
1344
|
content,
|
|
@@ -1098,10 +1346,10 @@ function ArtifactDslContent({
|
|
|
1098
1346
|
}) {
|
|
1099
1347
|
const node = typeof content === "object" && content !== null && !Array.isArray(content) && typeof content.type === "string" ? content : void 0;
|
|
1100
1348
|
if (!node || !runtime) {
|
|
1101
|
-
return /* @__PURE__ */ (0,
|
|
1349
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("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" });
|
|
1102
1350
|
}
|
|
1103
1351
|
const guarded = guardChatDsl(node, runtime.context.components);
|
|
1104
|
-
return /* @__PURE__ */ (0,
|
|
1352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_runtime4.DslRenderer, { context: runtime.context, engine: runtime.engine, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ArtifactDslGuard, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ArtifactDslNode, { node: guarded }) }) });
|
|
1105
1353
|
}
|
|
1106
1354
|
function ArtifactContent({
|
|
1107
1355
|
artifact,
|
|
@@ -1109,16 +1357,16 @@ function ArtifactContent({
|
|
|
1109
1357
|
}) {
|
|
1110
1358
|
switch (artifact.kind) {
|
|
1111
1359
|
case "markdown":
|
|
1112
|
-
return /* @__PURE__ */ (0,
|
|
1360
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_markdown2.MarkdownRenderer, { content: String(artifact.content) });
|
|
1113
1361
|
case "code":
|
|
1114
|
-
return /* @__PURE__ */ (0,
|
|
1115
|
-
artifact.language ? /* @__PURE__ */ (0,
|
|
1116
|
-
/* @__PURE__ */ (0,
|
|
1362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "pactor-chat-inspector__code", children: [
|
|
1363
|
+
artifact.language ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "pactor-chat-inspector__code-lang", children: artifact.language }) : null,
|
|
1364
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("pre", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: String(artifact.content) }) })
|
|
1117
1365
|
] });
|
|
1118
1366
|
case "text":
|
|
1119
|
-
return /* @__PURE__ */ (0,
|
|
1367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("pre", { className: "pactor-chat-inspector__text", children: String(artifact.content) });
|
|
1120
1368
|
case "dsl":
|
|
1121
|
-
return /* @__PURE__ */ (0,
|
|
1369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ArtifactDslContent, { content: artifact.content, runtime });
|
|
1122
1370
|
default:
|
|
1123
1371
|
return null;
|
|
1124
1372
|
}
|
|
@@ -1132,6 +1380,11 @@ function ArtifactPanel({
|
|
|
1132
1380
|
className
|
|
1133
1381
|
}) {
|
|
1134
1382
|
const runtime = useArtifactRuntime(safeRegistry, user);
|
|
1383
|
+
const closeRef = (0, import_react5.useRef)(onClose);
|
|
1384
|
+
closeRef.current = onClose;
|
|
1385
|
+
(0, import_react5.useEffect)(() => {
|
|
1386
|
+
setChatChromeHandlers({ panelClose: () => closeRef.current?.() });
|
|
1387
|
+
}, []);
|
|
1135
1388
|
const panelRef = (0, import_react5.useRef)(null);
|
|
1136
1389
|
const [width, setWidth] = (0, import_react5.useState)(null);
|
|
1137
1390
|
const handleResizeStart = (event) => {
|
|
@@ -1159,7 +1412,7 @@ function ArtifactPanel({
|
|
|
1159
1412
|
document.addEventListener("pointermove", onMove);
|
|
1160
1413
|
document.addEventListener("pointerup", onUp);
|
|
1161
1414
|
};
|
|
1162
|
-
return /* @__PURE__ */ (0,
|
|
1415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1163
1416
|
"aside",
|
|
1164
1417
|
{
|
|
1165
1418
|
ref: panelRef,
|
|
@@ -1167,7 +1420,7 @@ function ArtifactPanel({
|
|
|
1167
1420
|
"data-kind": artifact?.kind,
|
|
1168
1421
|
style: width !== null ? { width: `${width}px` } : void 0,
|
|
1169
1422
|
children: [
|
|
1170
|
-
/* @__PURE__ */ (0,
|
|
1423
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1171
1424
|
"div",
|
|
1172
1425
|
{
|
|
1173
1426
|
className: "pactor-chat-inspector__resize",
|
|
@@ -1177,38 +1430,48 @@ function ArtifactPanel({
|
|
|
1177
1430
|
onPointerDown: handleResizeStart
|
|
1178
1431
|
}
|
|
1179
1432
|
),
|
|
1180
|
-
/* @__PURE__ */ (0,
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1433
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "pactor-chat-inspector__header", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1434
|
+
ChromeSlot,
|
|
1435
|
+
{
|
|
1436
|
+
fragment: buildPanelHeaderFragment({
|
|
1437
|
+
title: artifact?.title ?? "\u4EA7\u51FA\u7269",
|
|
1438
|
+
kind: artifact?.kind ?? "text"
|
|
1439
|
+
}),
|
|
1440
|
+
components: PANEL_HEADER_INTERNAL_COMPONENTS,
|
|
1441
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
1442
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "pactor-chat-inspector__title", children: artifact?.title ?? "\u4EA7\u51FA\u7269" }),
|
|
1443
|
+
artifact ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "pactor-chat-inspector__kind", children: artifact.kind }) : null,
|
|
1444
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1445
|
+
"button",
|
|
1446
|
+
{
|
|
1447
|
+
type: "button",
|
|
1448
|
+
className: "pactor-chat-icon-button pactor-chat-inspector__close",
|
|
1449
|
+
"aria-label": "\u5173\u95ED\u9762\u677F",
|
|
1450
|
+
onClick: onClose,
|
|
1451
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_components4.Icon, { name: "x", size: 16, strokeWidth: 1.7 })
|
|
1452
|
+
}
|
|
1453
|
+
)
|
|
1454
|
+
] })
|
|
1455
|
+
}
|
|
1456
|
+
) }),
|
|
1457
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "pactor-chat-inspector__body", children: inspector !== void 0 && inspector !== null ? inspector : artifact ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ArtifactContent, { artifact, runtime }) : null })
|
|
1195
1458
|
]
|
|
1196
1459
|
}
|
|
1197
1460
|
);
|
|
1198
1461
|
}
|
|
1199
1462
|
|
|
1200
1463
|
// src/view/ChatView.tsx
|
|
1201
|
-
var
|
|
1202
|
-
var
|
|
1203
|
-
var
|
|
1464
|
+
var import_components10 = require("@pactor-app/ui/components");
|
|
1465
|
+
var import_core4 = require("@pactor-app/core");
|
|
1466
|
+
var import_react14 = require("react");
|
|
1204
1467
|
|
|
1205
1468
|
// src/view/Composer.tsx
|
|
1206
|
-
var
|
|
1207
|
-
var
|
|
1469
|
+
var import_components7 = require("@pactor-app/ui/components");
|
|
1470
|
+
var import_react10 = require("react");
|
|
1208
1471
|
|
|
1209
1472
|
// src/view/AnchoredPopover.tsx
|
|
1210
1473
|
var import_react6 = require("react");
|
|
1211
|
-
var
|
|
1474
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1212
1475
|
function AnchoredPopover({
|
|
1213
1476
|
anchorRect,
|
|
1214
1477
|
onClose,
|
|
@@ -1265,7 +1528,7 @@ function AnchoredPopover({
|
|
|
1265
1528
|
position?.below ? "pactor-chat-popover--below" : "",
|
|
1266
1529
|
className ?? ""
|
|
1267
1530
|
].filter(Boolean).join(" ");
|
|
1268
|
-
return /* @__PURE__ */ (0,
|
|
1531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1269
1532
|
"div",
|
|
1270
1533
|
{
|
|
1271
1534
|
ref,
|
|
@@ -1284,9 +1547,34 @@ function AnchoredPopover({
|
|
|
1284
1547
|
}
|
|
1285
1548
|
|
|
1286
1549
|
// src/view/ModelChip.tsx
|
|
1287
|
-
var
|
|
1550
|
+
var import_components5 = require("@pactor-app/ui/components");
|
|
1288
1551
|
var import_react7 = require("react");
|
|
1289
|
-
|
|
1552
|
+
|
|
1553
|
+
// src/view/chrome/model-select.tsx
|
|
1554
|
+
function buildModelSelectFragment(props) {
|
|
1555
|
+
return {
|
|
1556
|
+
requires: ["Select"],
|
|
1557
|
+
node: {
|
|
1558
|
+
type: "Select",
|
|
1559
|
+
props: {
|
|
1560
|
+
options: props.models.map((option) => ({
|
|
1561
|
+
value: option.value,
|
|
1562
|
+
label: option.label
|
|
1563
|
+
})),
|
|
1564
|
+
value: props.model,
|
|
1565
|
+
className: "pactor-chat-model-select"
|
|
1566
|
+
},
|
|
1567
|
+
events: {
|
|
1568
|
+
onChange: [
|
|
1569
|
+
{ action: "chat.modelChange", params: { value: "${event}" } }
|
|
1570
|
+
]
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
// src/view/ModelChip.tsx
|
|
1577
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1290
1578
|
function ModelChip({
|
|
1291
1579
|
models,
|
|
1292
1580
|
model,
|
|
@@ -1295,8 +1583,8 @@ function ModelChip({
|
|
|
1295
1583
|
const chipRef = (0, import_react7.useRef)(null);
|
|
1296
1584
|
const [anchor, setAnchor] = (0, import_react7.useState)(null);
|
|
1297
1585
|
const currentOption = models.find((option) => option.value === model) ?? models[0];
|
|
1298
|
-
return /* @__PURE__ */ (0,
|
|
1299
|
-
/* @__PURE__ */ (0,
|
|
1586
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1587
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1300
1588
|
"button",
|
|
1301
1589
|
{
|
|
1302
1590
|
ref: chipRef,
|
|
@@ -1306,18 +1594,18 @@ function ModelChip({
|
|
|
1306
1594
|
"aria-label": "\u9009\u62E9\u6A21\u578B",
|
|
1307
1595
|
onClick: () => setAnchor(chipRef.current.getBoundingClientRect()),
|
|
1308
1596
|
children: [
|
|
1309
|
-
/* @__PURE__ */ (0,
|
|
1310
|
-
/* @__PURE__ */ (0,
|
|
1597
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "pactor-chat-model-chip__label", children: currentOption.label }),
|
|
1598
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_components5.Icon, { name: "chevrons-up-down", size: 12 })
|
|
1311
1599
|
]
|
|
1312
1600
|
}
|
|
1313
1601
|
),
|
|
1314
|
-
anchor && /* @__PURE__ */ (0,
|
|
1602
|
+
anchor && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1315
1603
|
AnchoredPopover,
|
|
1316
1604
|
{
|
|
1317
1605
|
anchorRect: anchor,
|
|
1318
1606
|
onClose: () => setAnchor(null),
|
|
1319
1607
|
role: "listbox",
|
|
1320
|
-
children: models.map((option) => /* @__PURE__ */ (0,
|
|
1608
|
+
children: models.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1321
1609
|
"button",
|
|
1322
1610
|
{
|
|
1323
1611
|
type: "button",
|
|
@@ -1329,8 +1617,8 @@ function ModelChip({
|
|
|
1329
1617
|
setAnchor(null);
|
|
1330
1618
|
},
|
|
1331
1619
|
children: [
|
|
1332
|
-
/* @__PURE__ */ (0,
|
|
1333
|
-
option.value === currentOption.value && /* @__PURE__ */ (0,
|
|
1620
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "pactor-chat-popover__item-label", children: option.label }),
|
|
1621
|
+
option.value === currentOption.value && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_components5.Icon, { name: "check", size: 13, className: "pactor-chat-popover__item-check" })
|
|
1334
1622
|
]
|
|
1335
1623
|
},
|
|
1336
1624
|
option.value
|
|
@@ -1339,10 +1627,243 @@ function ModelChip({
|
|
|
1339
1627
|
)
|
|
1340
1628
|
] });
|
|
1341
1629
|
}
|
|
1630
|
+
function ModelSelect({
|
|
1631
|
+
models,
|
|
1632
|
+
model,
|
|
1633
|
+
onModelChange
|
|
1634
|
+
}) {
|
|
1635
|
+
const changeRef = (0, import_react7.useRef)(onModelChange);
|
|
1636
|
+
changeRef.current = onModelChange;
|
|
1637
|
+
(0, import_react7.useEffect)(() => {
|
|
1638
|
+
setChatChromeHandlers({
|
|
1639
|
+
modelChange: (value) => changeRef.current?.(value)
|
|
1640
|
+
});
|
|
1641
|
+
}, []);
|
|
1642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1643
|
+
ChromeSlot,
|
|
1644
|
+
{
|
|
1645
|
+
fragment: buildModelSelectFragment({ models, model }),
|
|
1646
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ModelChip, { models, model, onModelChange })
|
|
1647
|
+
}
|
|
1648
|
+
);
|
|
1649
|
+
}
|
|
1342
1650
|
|
|
1343
|
-
// src/view/
|
|
1651
|
+
// src/view/chrome/composer.tsx
|
|
1652
|
+
var import_components6 = require("@pactor-app/ui/components");
|
|
1344
1653
|
var import_react8 = require("react");
|
|
1345
|
-
var
|
|
1654
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1655
|
+
var ComposerBridgeContext = (0, import_react8.createContext)(
|
|
1656
|
+
null
|
|
1657
|
+
);
|
|
1658
|
+
function useComposerBridge() {
|
|
1659
|
+
const bridge = (0, import_react8.useContext)(ComposerBridgeContext);
|
|
1660
|
+
if (!bridge) {
|
|
1661
|
+
throw new Error(
|
|
1662
|
+
"[@pactor-app/chat] ChatComposer* \u5185\u90E8\u7EC4\u4EF6\u4EC5\u53EF\u5728 Composer chrome \u7247\u6BB5\u5185\u6E32\u67D3"
|
|
1663
|
+
);
|
|
1664
|
+
}
|
|
1665
|
+
return bridge;
|
|
1666
|
+
}
|
|
1667
|
+
function formatSize(bytes) {
|
|
1668
|
+
if (bytes < 1024) {
|
|
1669
|
+
return `${bytes} B`;
|
|
1670
|
+
}
|
|
1671
|
+
if (bytes < 1024 * 1024) {
|
|
1672
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1673
|
+
}
|
|
1674
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1675
|
+
}
|
|
1676
|
+
function ComposerAttachments({
|
|
1677
|
+
attachments,
|
|
1678
|
+
onRemove,
|
|
1679
|
+
onClick
|
|
1680
|
+
}) {
|
|
1681
|
+
if (attachments.length === 0) {
|
|
1682
|
+
return null;
|
|
1683
|
+
}
|
|
1684
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "pactor-chat-composer__attachments", children: attachments.map((attachment) => {
|
|
1685
|
+
const isImage = attachment.mimeType.startsWith("image/");
|
|
1686
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1687
|
+
"div",
|
|
1688
|
+
{
|
|
1689
|
+
className: "pactor-chat-composer__attachment",
|
|
1690
|
+
"data-attachment-id": attachment.id,
|
|
1691
|
+
onClick: () => onClick?.(attachment),
|
|
1692
|
+
children: [
|
|
1693
|
+
isImage && attachment.url ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "pactor-chat-composer__attachment-thumb", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: attachment.url, alt: attachment.name }) }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "pactor-chat-composer__attachment-info", children: [
|
|
1694
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components6.Icon, { name: "file-text", size: 14 }),
|
|
1695
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "pactor-chat-composer__attachment-name", children: attachment.name }),
|
|
1696
|
+
attachment.size !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "pactor-chat-composer__attachment-size", children: formatSize(attachment.size) })
|
|
1697
|
+
] }),
|
|
1698
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1699
|
+
"button",
|
|
1700
|
+
{
|
|
1701
|
+
type: "button",
|
|
1702
|
+
className: "pactor-chat-icon-button pactor-chat-composer__attachment-remove",
|
|
1703
|
+
title: "\u79FB\u9664\u9644\u4EF6",
|
|
1704
|
+
"aria-label": "\u79FB\u9664\u9644\u4EF6",
|
|
1705
|
+
onClick: (event) => {
|
|
1706
|
+
event.stopPropagation();
|
|
1707
|
+
onRemove(attachment.id);
|
|
1708
|
+
},
|
|
1709
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components6.Icon, { name: "x", size: 12 })
|
|
1710
|
+
}
|
|
1711
|
+
)
|
|
1712
|
+
]
|
|
1713
|
+
},
|
|
1714
|
+
attachment.id
|
|
1715
|
+
);
|
|
1716
|
+
}) });
|
|
1717
|
+
}
|
|
1718
|
+
function ComposerContextChips({
|
|
1719
|
+
chips,
|
|
1720
|
+
onRemove
|
|
1721
|
+
}) {
|
|
1722
|
+
if (chips.length === 0) {
|
|
1723
|
+
return null;
|
|
1724
|
+
}
|
|
1725
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "pactor-chat-composer__contexts", children: chips.map((chip) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1726
|
+
"span",
|
|
1727
|
+
{
|
|
1728
|
+
className: "pactor-chat-context-chip",
|
|
1729
|
+
"data-context-id": chip.id,
|
|
1730
|
+
children: [
|
|
1731
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "pactor-chat-context-chip__label", children: chip.label }),
|
|
1732
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1733
|
+
"button",
|
|
1734
|
+
{
|
|
1735
|
+
type: "button",
|
|
1736
|
+
className: "pactor-chat-icon-button pactor-chat-context-chip__remove",
|
|
1737
|
+
title: `\u79FB\u9664\u4E0A\u4E0B\u6587 ${chip.label}`,
|
|
1738
|
+
"aria-label": `\u79FB\u9664\u4E0A\u4E0B\u6587 ${chip.label}`,
|
|
1739
|
+
onClick: () => onRemove(chip),
|
|
1740
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components6.Icon, { name: "x", size: 12 })
|
|
1741
|
+
}
|
|
1742
|
+
)
|
|
1743
|
+
]
|
|
1744
|
+
},
|
|
1745
|
+
`${chip.trigger ?? ""}:${chip.id}`
|
|
1746
|
+
)) });
|
|
1747
|
+
}
|
|
1748
|
+
function ChatComposerHeader() {
|
|
1749
|
+
const bridge = useComposerBridge();
|
|
1750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1751
|
+
bridge.attachments !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1752
|
+
ComposerAttachments,
|
|
1753
|
+
{
|
|
1754
|
+
attachments: bridge.attachments,
|
|
1755
|
+
onRemove: bridge.removeAttachment,
|
|
1756
|
+
onClick: bridge.attachmentClick
|
|
1757
|
+
}
|
|
1758
|
+
),
|
|
1759
|
+
bridge.contextChips !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1760
|
+
ComposerContextChips,
|
|
1761
|
+
{
|
|
1762
|
+
chips: bridge.contextChips,
|
|
1763
|
+
onRemove: bridge.removeChip
|
|
1764
|
+
}
|
|
1765
|
+
)
|
|
1766
|
+
] });
|
|
1767
|
+
}
|
|
1768
|
+
function ChatComposerToolbarStart() {
|
|
1769
|
+
const bridge = useComposerBridge();
|
|
1770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1771
|
+
bridge.toolbarStart,
|
|
1772
|
+
bridge.showPlus && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1773
|
+
"button",
|
|
1774
|
+
{
|
|
1775
|
+
type: "button",
|
|
1776
|
+
className: "pactor-chat-icon-button",
|
|
1777
|
+
title: "\u66F4\u591A\u529F\u80FD",
|
|
1778
|
+
"aria-label": "\u66F4\u591A\u529F\u80FD",
|
|
1779
|
+
onClick: (event) => bridge.plusClick(event.currentTarget.getBoundingClientRect()),
|
|
1780
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components6.Icon, { name: "plus", size: 14 })
|
|
1781
|
+
}
|
|
1782
|
+
),
|
|
1783
|
+
bridge.showAttach && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1784
|
+
"button",
|
|
1785
|
+
{
|
|
1786
|
+
type: "button",
|
|
1787
|
+
className: "pactor-chat-icon-button",
|
|
1788
|
+
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
1789
|
+
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
1790
|
+
onClick: bridge.openFilePicker,
|
|
1791
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components6.Icon, { name: "paperclip", size: 14 })
|
|
1792
|
+
}
|
|
1793
|
+
)
|
|
1794
|
+
] });
|
|
1795
|
+
}
|
|
1796
|
+
function ChatComposerToolbarEnd() {
|
|
1797
|
+
const bridge = useComposerBridge();
|
|
1798
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
1799
|
+
bridge.modelChipEnabled && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1800
|
+
ModelSelect,
|
|
1801
|
+
{
|
|
1802
|
+
models: bridge.models,
|
|
1803
|
+
model: bridge.model,
|
|
1804
|
+
onModelChange: bridge.modelChange
|
|
1805
|
+
}
|
|
1806
|
+
),
|
|
1807
|
+
bridge.toolbarEnd,
|
|
1808
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1809
|
+
"button",
|
|
1810
|
+
{
|
|
1811
|
+
type: "button",
|
|
1812
|
+
className: `pactor-chat-composer__button${bridge.streaming ? " pactor-chat-composer__button--stop" : ""}`,
|
|
1813
|
+
title: bridge.streaming ? "\u505C\u6B62\u751F\u6210" : "\u53D1\u9001",
|
|
1814
|
+
"aria-label": bridge.streaming ? "\u505C\u6B62\u751F\u6210" : "\u53D1\u9001",
|
|
1815
|
+
disabled: bridge.streaming ? false : bridge.disabled || !bridge.text.trim(),
|
|
1816
|
+
onClick: bridge.streaming ? bridge.stop : bridge.send,
|
|
1817
|
+
children: bridge.streaming ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components6.Icon, { name: "square", size: 14, className: "pactor-chat-icon-fill" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_components6.Icon, { name: "arrow-up", size: 16 })
|
|
1818
|
+
}
|
|
1819
|
+
)
|
|
1820
|
+
] });
|
|
1821
|
+
}
|
|
1822
|
+
function ChatComposerFooter() {
|
|
1823
|
+
const bridge = useComposerBridge();
|
|
1824
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_jsx_runtime8.Fragment, { children: bridge.composerFooter });
|
|
1825
|
+
}
|
|
1826
|
+
var COMPOSER_INTERNAL_COMPONENTS = {
|
|
1827
|
+
ChatComposerHeader,
|
|
1828
|
+
ChatComposerToolbarStart,
|
|
1829
|
+
ChatComposerToolbarEnd,
|
|
1830
|
+
ChatComposerFooter
|
|
1831
|
+
};
|
|
1832
|
+
function buildComposerFragment(props) {
|
|
1833
|
+
const hideToolbar = props.hideToolbar === true;
|
|
1834
|
+
return {
|
|
1835
|
+
requires: [
|
|
1836
|
+
"ChatInput",
|
|
1837
|
+
"ChatComposerHeader",
|
|
1838
|
+
...hideToolbar ? [] : ["ChatComposerToolbarStart", "ChatComposerToolbarEnd"],
|
|
1839
|
+
"ChatComposerFooter"
|
|
1840
|
+
],
|
|
1841
|
+
node: {
|
|
1842
|
+
type: "ChatInput",
|
|
1843
|
+
props: {
|
|
1844
|
+
placeholder: props.placeholder,
|
|
1845
|
+
disabled: props.disabled,
|
|
1846
|
+
rows: 1,
|
|
1847
|
+
hideSend: true,
|
|
1848
|
+
header: { type: "ChatComposerHeader" },
|
|
1849
|
+
...hideToolbar ? {} : {
|
|
1850
|
+
toolbarStart: { type: "ChatComposerToolbarStart" },
|
|
1851
|
+
toolbarEnd: { type: "ChatComposerToolbarEnd" }
|
|
1852
|
+
},
|
|
1853
|
+
...props.hasFooter === true ? { footer: { type: "ChatComposerFooter" } } : {}
|
|
1854
|
+
},
|
|
1855
|
+
events: {
|
|
1856
|
+
onSubmit: [
|
|
1857
|
+
{ action: "chat.composerSubmit", params: { value: "${event}" } }
|
|
1858
|
+
]
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
};
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
// src/view/context-sources.tsx
|
|
1865
|
+
var import_react9 = require("react");
|
|
1866
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1346
1867
|
function sourceCacheKey(source) {
|
|
1347
1868
|
return `${source.service ?? ""}:${JSON.stringify(source.params ?? {})}`;
|
|
1348
1869
|
}
|
|
@@ -1377,8 +1898,8 @@ function ContextSourceList({
|
|
|
1377
1898
|
cache,
|
|
1378
1899
|
onSelect
|
|
1379
1900
|
}) {
|
|
1380
|
-
const [resolutions, setResolutions] = (0,
|
|
1381
|
-
(0,
|
|
1901
|
+
const [resolutions, setResolutions] = (0, import_react9.useState)([]);
|
|
1902
|
+
(0, import_react9.useEffect)(() => {
|
|
1382
1903
|
let cancelled = false;
|
|
1383
1904
|
const initial = sources.map(
|
|
1384
1905
|
(source) => source.items ? { status: "ready", items: source.items } : { status: "loading" }
|
|
@@ -1423,12 +1944,12 @@ function ContextSourceList({
|
|
|
1423
1944
|
totalMatched += items.length;
|
|
1424
1945
|
return { source, resolution, items };
|
|
1425
1946
|
});
|
|
1426
|
-
return /* @__PURE__ */ (0,
|
|
1427
|
-
groups.map(({ source, resolution, items }) => /* @__PURE__ */ (0,
|
|
1428
|
-
sources.length > 1 && /* @__PURE__ */ (0,
|
|
1429
|
-
resolution.status === "loading" && /* @__PURE__ */ (0,
|
|
1430
|
-
resolution.status === "error" && /* @__PURE__ */ (0,
|
|
1431
|
-
items.map((item) => /* @__PURE__ */ (0,
|
|
1947
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "pactor-chat-source-list", children: [
|
|
1948
|
+
groups.map(({ source, resolution, items }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "pactor-chat-source-list__group", children: [
|
|
1949
|
+
sources.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "pactor-chat-source-list__group-label", children: source.label }),
|
|
1950
|
+
resolution.status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "pactor-chat-source-list__hint", children: "\u52A0\u8F7D\u4E2D\u2026" }),
|
|
1951
|
+
resolution.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "pactor-chat-source-list__error", role: "alert", children: resolution.message }),
|
|
1952
|
+
items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1432
1953
|
"button",
|
|
1433
1954
|
{
|
|
1434
1955
|
type: "button",
|
|
@@ -1439,22 +1960,13 @@ function ContextSourceList({
|
|
|
1439
1960
|
item.id
|
|
1440
1961
|
))
|
|
1441
1962
|
] }, `${source.trigger}:${source.label}`)),
|
|
1442
|
-
totalMatched === 0 && groups.every(({ resolution }) => resolution.status === "ready") && /* @__PURE__ */ (0,
|
|
1963
|
+
totalMatched === 0 && groups.every(({ resolution }) => resolution.status === "ready") && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "pactor-chat-source-list__hint", children: "\u65E0\u5339\u914D\u9879" })
|
|
1443
1964
|
] });
|
|
1444
1965
|
}
|
|
1445
1966
|
|
|
1446
1967
|
// src/view/Composer.tsx
|
|
1447
|
-
var
|
|
1968
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1448
1969
|
var MAX_INPUT_HEIGHT = 200;
|
|
1449
|
-
function formatSize(bytes) {
|
|
1450
|
-
if (bytes < 1024) {
|
|
1451
|
-
return `${bytes} B`;
|
|
1452
|
-
}
|
|
1453
|
-
if (bytes < 1024 * 1024) {
|
|
1454
|
-
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1455
|
-
}
|
|
1456
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1457
|
-
}
|
|
1458
1970
|
function detectMention(text, caret) {
|
|
1459
1971
|
const beforeCaret = text.slice(0, caret);
|
|
1460
1972
|
const match = /(?:^|\s)@([^\s@]*)$/.exec(beforeCaret);
|
|
@@ -1483,28 +1995,30 @@ function Composer({
|
|
|
1483
1995
|
contextSources,
|
|
1484
1996
|
contextChips,
|
|
1485
1997
|
onContextChipsChange,
|
|
1486
|
-
callService
|
|
1998
|
+
callService,
|
|
1999
|
+
composerFooter,
|
|
2000
|
+
hideToolbar = false
|
|
1487
2001
|
}) {
|
|
1488
|
-
const [text, setText] = (0,
|
|
1489
|
-
const [dragOver, setDragOver] = (0,
|
|
1490
|
-
const inputRef = (0,
|
|
1491
|
-
const fileInputRef = (0,
|
|
1492
|
-
const plusButtonRef = (0,
|
|
1493
|
-
const composingRef = (0,
|
|
2002
|
+
const [text, setText] = (0, import_react10.useState)("");
|
|
2003
|
+
const [dragOver, setDragOver] = (0, import_react10.useState)(false);
|
|
2004
|
+
const inputRef = (0, import_react10.useRef)(null);
|
|
2005
|
+
const fileInputRef = (0, import_react10.useRef)(null);
|
|
2006
|
+
const plusButtonRef = (0, import_react10.useRef)(null);
|
|
2007
|
+
const composingRef = (0, import_react10.useRef)(false);
|
|
1494
2008
|
const modelChipEnabled = models !== void 0 && models.length > 0;
|
|
1495
|
-
const mentionSources = (0,
|
|
2009
|
+
const mentionSources = (0, import_react10.useMemo)(
|
|
1496
2010
|
() => contextSources?.filter((source) => source.trigger === "@") ?? [],
|
|
1497
2011
|
[contextSources]
|
|
1498
2012
|
);
|
|
1499
|
-
const plusSources = (0,
|
|
2013
|
+
const plusSources = (0, import_react10.useMemo)(
|
|
1500
2014
|
() => contextSources?.filter((source) => source.trigger === "+") ?? [],
|
|
1501
2015
|
[contextSources]
|
|
1502
2016
|
);
|
|
1503
2017
|
const builtinMentionEnabled = onMentionTrigger === void 0 && mentionSources.length > 0;
|
|
1504
2018
|
const builtinPlusEnabled = onPlusMenu === void 0 && plusSources.length > 0;
|
|
1505
|
-
const [mentionState, setMentionState] = (0,
|
|
1506
|
-
const [plusAnchor, setPlusAnchor] = (0,
|
|
1507
|
-
const sourceCacheRef = (0,
|
|
2019
|
+
const [mentionState, setMentionState] = (0, import_react10.useState)(null);
|
|
2020
|
+
const [plusAnchor, setPlusAnchor] = (0, import_react10.useState)(null);
|
|
2021
|
+
const sourceCacheRef = (0, import_react10.useRef)(null);
|
|
1508
2022
|
if (sourceCacheRef.current === null) {
|
|
1509
2023
|
sourceCacheRef.current = /* @__PURE__ */ new Map();
|
|
1510
2024
|
}
|
|
@@ -1523,7 +2037,7 @@ function Composer({
|
|
|
1523
2037
|
setMentionState(null);
|
|
1524
2038
|
setPlusAnchor(null);
|
|
1525
2039
|
};
|
|
1526
|
-
(0,
|
|
2040
|
+
(0, import_react10.useLayoutEffect)(() => {
|
|
1527
2041
|
const input = inputRef.current;
|
|
1528
2042
|
if (input) {
|
|
1529
2043
|
input.style.height = "auto";
|
|
@@ -1538,105 +2052,147 @@ function Composer({
|
|
|
1538
2052
|
onSend?.(value);
|
|
1539
2053
|
setText("");
|
|
1540
2054
|
};
|
|
1541
|
-
const
|
|
1542
|
-
|
|
2055
|
+
const sendRef = (0, import_react10.useRef)(send);
|
|
2056
|
+
sendRef.current = send;
|
|
2057
|
+
(0, import_react10.useLayoutEffect)(() => {
|
|
2058
|
+
setChatChromeHandlers({ composerSubmit: () => sendRef.current() });
|
|
2059
|
+
}, []);
|
|
2060
|
+
const syncText = (value, caret, rect) => {
|
|
1543
2061
|
setText(value);
|
|
1544
2062
|
if (onMentionTrigger || builtinMentionEnabled) {
|
|
1545
|
-
const caret = event.target.selectionStart ?? value.length;
|
|
1546
2063
|
const query = detectMention(value, caret);
|
|
1547
2064
|
if (onMentionTrigger) {
|
|
1548
2065
|
if (query !== null) {
|
|
1549
|
-
onMentionTrigger(query,
|
|
2066
|
+
onMentionTrigger(query, rect);
|
|
1550
2067
|
}
|
|
1551
2068
|
} else {
|
|
1552
|
-
setMentionState(
|
|
1553
|
-
|
|
1554
|
-
|
|
2069
|
+
setMentionState(query !== null ? { query, anchorRect: rect } : null);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
};
|
|
2073
|
+
const handleChange = (event) => {
|
|
2074
|
+
syncText(
|
|
2075
|
+
event.target.value,
|
|
2076
|
+
event.target.selectionStart ?? event.target.value.length,
|
|
2077
|
+
event.target.getBoundingClientRect()
|
|
2078
|
+
);
|
|
2079
|
+
};
|
|
2080
|
+
const handleBubbleChange = (event) => {
|
|
2081
|
+
const target = event.target;
|
|
2082
|
+
if (!(target instanceof HTMLTextAreaElement)) {
|
|
2083
|
+
return;
|
|
2084
|
+
}
|
|
2085
|
+
syncText(
|
|
2086
|
+
target.value,
|
|
2087
|
+
target.selectionStart ?? target.value.length,
|
|
2088
|
+
target.getBoundingClientRect()
|
|
2089
|
+
);
|
|
2090
|
+
};
|
|
2091
|
+
const handlePasteFiles = (clipboardData) => {
|
|
2092
|
+
const files = Array.from(clipboardData.files);
|
|
2093
|
+
if (files.length > 0 && onAttachFiles) {
|
|
2094
|
+
onAttachFiles(files);
|
|
2095
|
+
return true;
|
|
2096
|
+
}
|
|
2097
|
+
return false;
|
|
2098
|
+
};
|
|
2099
|
+
const dragHandlers = {
|
|
2100
|
+
onDragOver: (event) => {
|
|
2101
|
+
event.preventDefault();
|
|
2102
|
+
setDragOver(true);
|
|
2103
|
+
},
|
|
2104
|
+
onDragLeave: () => setDragOver(false),
|
|
2105
|
+
onDrop: (event) => {
|
|
2106
|
+
event.preventDefault();
|
|
2107
|
+
setDragOver(false);
|
|
2108
|
+
const files = collectDropFiles(event);
|
|
2109
|
+
if (files.length > 0 && onAttachFiles) {
|
|
2110
|
+
onAttachFiles(files);
|
|
1555
2111
|
}
|
|
1556
2112
|
}
|
|
1557
2113
|
};
|
|
1558
|
-
const showToolbar = toolbarStart !== void 0 || toolbarEnd !== void 0 || onPlusMenu !== void 0 || builtinPlusEnabled || onAttachFiles !== void 0 || modelChipEnabled;
|
|
1559
|
-
|
|
2114
|
+
const showToolbar = !hideToolbar && (toolbarStart !== void 0 || toolbarEnd !== void 0 || onPlusMenu !== void 0 || builtinPlusEnabled || onAttachFiles !== void 0 || modelChipEnabled);
|
|
2115
|
+
const fileInputNode = onAttachFiles ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2116
|
+
"input",
|
|
2117
|
+
{
|
|
2118
|
+
ref: fileInputRef,
|
|
2119
|
+
type: "file",
|
|
2120
|
+
multiple: true,
|
|
2121
|
+
hidden: true,
|
|
2122
|
+
onChange: (event) => {
|
|
2123
|
+
const files = event.target.files ? Array.from(event.target.files) : [];
|
|
2124
|
+
if (files.length > 0) {
|
|
2125
|
+
onAttachFiles(files);
|
|
2126
|
+
}
|
|
2127
|
+
event.target.value = "";
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
) : null;
|
|
2131
|
+
const popoverNodes = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
2132
|
+
builtinMentionEnabled && mentionState && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2133
|
+
AnchoredPopover,
|
|
2134
|
+
{
|
|
2135
|
+
anchorRect: mentionState.anchorRect,
|
|
2136
|
+
onClose: () => setMentionState(null),
|
|
2137
|
+
role: "listbox",
|
|
2138
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2139
|
+
ContextSourceList,
|
|
2140
|
+
{
|
|
2141
|
+
sources: mentionSources,
|
|
2142
|
+
query: mentionState.query,
|
|
2143
|
+
callService,
|
|
2144
|
+
cache: sourceCacheRef.current,
|
|
2145
|
+
onSelect: handleSelectContext
|
|
2146
|
+
}
|
|
2147
|
+
)
|
|
2148
|
+
}
|
|
2149
|
+
),
|
|
2150
|
+
builtinPlusEnabled && plusAnchor && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2151
|
+
AnchoredPopover,
|
|
2152
|
+
{
|
|
2153
|
+
anchorRect: plusAnchor,
|
|
2154
|
+
onClose: () => setPlusAnchor(null),
|
|
2155
|
+
role: "listbox",
|
|
2156
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2157
|
+
ContextSourceList,
|
|
2158
|
+
{
|
|
2159
|
+
sources: plusSources,
|
|
2160
|
+
query: "",
|
|
2161
|
+
callService,
|
|
2162
|
+
cache: sourceCacheRef.current,
|
|
2163
|
+
onSelect: handleSelectContext
|
|
2164
|
+
}
|
|
2165
|
+
)
|
|
2166
|
+
}
|
|
2167
|
+
)
|
|
2168
|
+
] });
|
|
2169
|
+
const fallback = /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1560
2170
|
"div",
|
|
1561
2171
|
{
|
|
1562
2172
|
className: `pactor-chat-composer${dragOver ? " pactor-chat-composer--dragover" : ""}`,
|
|
1563
|
-
|
|
1564
|
-
event.preventDefault();
|
|
1565
|
-
setDragOver(true);
|
|
1566
|
-
},
|
|
1567
|
-
onDragLeave: () => setDragOver(false),
|
|
1568
|
-
onDrop: (event) => {
|
|
1569
|
-
event.preventDefault();
|
|
1570
|
-
setDragOver(false);
|
|
1571
|
-
const files = collectDropFiles(event);
|
|
1572
|
-
if (files.length > 0 && onAttachFiles) {
|
|
1573
|
-
onAttachFiles(files);
|
|
1574
|
-
}
|
|
1575
|
-
},
|
|
2173
|
+
...dragHandlers,
|
|
1576
2174
|
children: [
|
|
1577
|
-
attachments !== void 0 &&
|
|
1578
|
-
|
|
1579
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1580
|
-
"div",
|
|
1581
|
-
{
|
|
1582
|
-
className: "pactor-chat-composer__attachment",
|
|
1583
|
-
"data-attachment-id": attachment.id,
|
|
1584
|
-
onClick: () => onAttachmentClick?.(attachment),
|
|
1585
|
-
children: [
|
|
1586
|
-
isImage && attachment.url ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "pactor-chat-composer__attachment-thumb", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: attachment.url, alt: attachment.name }) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "pactor-chat-composer__attachment-info", children: [
|
|
1587
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react5.FileText, { size: 14 }),
|
|
1588
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "pactor-chat-composer__attachment-name", children: attachment.name }),
|
|
1589
|
-
attachment.size !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "pactor-chat-composer__attachment-size", children: formatSize(attachment.size) })
|
|
1590
|
-
] }),
|
|
1591
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1592
|
-
"button",
|
|
1593
|
-
{
|
|
1594
|
-
type: "button",
|
|
1595
|
-
className: "pactor-chat-icon-button pactor-chat-composer__attachment-remove",
|
|
1596
|
-
title: "\u79FB\u9664\u9644\u4EF6",
|
|
1597
|
-
"aria-label": "\u79FB\u9664\u9644\u4EF6",
|
|
1598
|
-
onClick: (event) => {
|
|
1599
|
-
event.stopPropagation();
|
|
1600
|
-
onAttachmentsChange?.(
|
|
1601
|
-
attachments.filter((item) => item.id !== attachment.id)
|
|
1602
|
-
);
|
|
1603
|
-
},
|
|
1604
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react5.X, { size: 12 })
|
|
1605
|
-
}
|
|
1606
|
-
)
|
|
1607
|
-
]
|
|
1608
|
-
},
|
|
1609
|
-
attachment.id
|
|
1610
|
-
);
|
|
1611
|
-
}) }),
|
|
1612
|
-
contextChips !== void 0 && contextChips.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "pactor-chat-composer__contexts", children: contextChips.map((chip) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1613
|
-
"span",
|
|
2175
|
+
attachments !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2176
|
+
ComposerAttachments,
|
|
1614
2177
|
{
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
contextChips.filter(
|
|
1628
|
-
(existing) => !(existing.id === chip.id && existing.trigger === chip.trigger)
|
|
1629
|
-
)
|
|
1630
|
-
),
|
|
1631
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react5.X, { size: 12 })
|
|
1632
|
-
}
|
|
2178
|
+
attachments,
|
|
2179
|
+
onRemove: (id) => onAttachmentsChange?.(attachments.filter((a) => a.id !== id)),
|
|
2180
|
+
onClick: onAttachmentClick
|
|
2181
|
+
}
|
|
2182
|
+
),
|
|
2183
|
+
contextChips !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2184
|
+
ComposerContextChips,
|
|
2185
|
+
{
|
|
2186
|
+
chips: contextChips,
|
|
2187
|
+
onRemove: (chip) => onContextChipsChange?.(
|
|
2188
|
+
contextChips.filter(
|
|
2189
|
+
(existing) => !(existing.id === chip.id && existing.trigger === chip.trigger)
|
|
1633
2190
|
)
|
|
1634
|
-
|
|
1635
|
-
}
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2191
|
+
)
|
|
2192
|
+
}
|
|
2193
|
+
),
|
|
2194
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "pactor-chat-composer__row", children: [
|
|
2195
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1640
2196
|
"textarea",
|
|
1641
2197
|
{
|
|
1642
2198
|
ref: inputRef,
|
|
@@ -1653,10 +2209,8 @@ function Composer({
|
|
|
1653
2209
|
composingRef.current = false;
|
|
1654
2210
|
},
|
|
1655
2211
|
onPaste: (event) => {
|
|
1656
|
-
|
|
1657
|
-
if (files.length > 0 && onAttachFiles) {
|
|
2212
|
+
if (handlePasteFiles(event.clipboardData)) {
|
|
1658
2213
|
event.preventDefault();
|
|
1659
|
-
onAttachFiles(files);
|
|
1660
2214
|
}
|
|
1661
2215
|
},
|
|
1662
2216
|
onKeyDown: (event) => {
|
|
@@ -1670,7 +2224,7 @@ function Composer({
|
|
|
1670
2224
|
}
|
|
1671
2225
|
}
|
|
1672
2226
|
),
|
|
1673
|
-
/* @__PURE__ */ (0,
|
|
2227
|
+
hideToolbar ? null : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1674
2228
|
"button",
|
|
1675
2229
|
{
|
|
1676
2230
|
type: "button",
|
|
@@ -1679,14 +2233,14 @@ function Composer({
|
|
|
1679
2233
|
"aria-label": streaming ? "\u505C\u6B62\u751F\u6210" : "\u53D1\u9001",
|
|
1680
2234
|
disabled: streaming ? false : disabled || !text.trim(),
|
|
1681
2235
|
onClick: streaming ? onStop : send,
|
|
1682
|
-
children: streaming ? /* @__PURE__ */ (0,
|
|
2236
|
+
children: streaming ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_components7.Icon, { name: "square", size: 14, className: "pactor-chat-icon-fill" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_components7.Icon, { name: "arrow-up", size: 16 })
|
|
1683
2237
|
}
|
|
1684
2238
|
)
|
|
1685
2239
|
] }),
|
|
1686
|
-
showToolbar && /* @__PURE__ */ (0,
|
|
2240
|
+
showToolbar && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "pactor-chat-composer__toolbar", children: [
|
|
1687
2241
|
toolbarStart,
|
|
1688
|
-
/* @__PURE__ */ (0,
|
|
1689
|
-
(onPlusMenu || builtinPlusEnabled) && /* @__PURE__ */ (0,
|
|
2242
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "pactor-chat-composer__toolbar-spacer" }),
|
|
2243
|
+
(onPlusMenu || builtinPlusEnabled) && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1690
2244
|
"button",
|
|
1691
2245
|
{
|
|
1692
2246
|
ref: plusButtonRef,
|
|
@@ -1702,10 +2256,10 @@ function Composer({
|
|
|
1702
2256
|
setPlusAnchor(rect);
|
|
1703
2257
|
}
|
|
1704
2258
|
},
|
|
1705
|
-
children: /* @__PURE__ */ (0,
|
|
2259
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_components7.Icon, { name: "plus", size: 14 })
|
|
1706
2260
|
}
|
|
1707
2261
|
),
|
|
1708
|
-
onAttachFiles && /* @__PURE__ */ (0,
|
|
2262
|
+
onAttachFiles && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1709
2263
|
"button",
|
|
1710
2264
|
{
|
|
1711
2265
|
type: "button",
|
|
@@ -1713,11 +2267,11 @@ function Composer({
|
|
|
1713
2267
|
title: "\u6DFB\u52A0\u9644\u4EF6",
|
|
1714
2268
|
"aria-label": "\u6DFB\u52A0\u9644\u4EF6",
|
|
1715
2269
|
onClick: () => fileInputRef.current?.click(),
|
|
1716
|
-
children: /* @__PURE__ */ (0,
|
|
2270
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_components7.Icon, { name: "paperclip", size: 14 })
|
|
1717
2271
|
}
|
|
1718
2272
|
),
|
|
1719
|
-
modelChipEnabled && /* @__PURE__ */ (0,
|
|
1720
|
-
|
|
2273
|
+
modelChipEnabled && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2274
|
+
ModelSelect,
|
|
1721
2275
|
{
|
|
1722
2276
|
models,
|
|
1723
2277
|
model,
|
|
@@ -1726,104 +2280,206 @@ function Composer({
|
|
|
1726
2280
|
),
|
|
1727
2281
|
toolbarEnd
|
|
1728
2282
|
] }),
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
ref: fileInputRef,
|
|
1733
|
-
type: "file",
|
|
1734
|
-
multiple: true,
|
|
1735
|
-
hidden: true,
|
|
1736
|
-
onChange: (event) => {
|
|
1737
|
-
const files = event.target.files ? Array.from(event.target.files) : [];
|
|
1738
|
-
if (files.length > 0) {
|
|
1739
|
-
onAttachFiles(files);
|
|
1740
|
-
}
|
|
1741
|
-
event.target.value = "";
|
|
1742
|
-
}
|
|
1743
|
-
}
|
|
1744
|
-
),
|
|
1745
|
-
builtinMentionEnabled && mentionState && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1746
|
-
AnchoredPopover,
|
|
1747
|
-
{
|
|
1748
|
-
anchorRect: mentionState.anchorRect,
|
|
1749
|
-
onClose: () => setMentionState(null),
|
|
1750
|
-
role: "listbox",
|
|
1751
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1752
|
-
ContextSourceList,
|
|
1753
|
-
{
|
|
1754
|
-
sources: mentionSources,
|
|
1755
|
-
query: mentionState.query,
|
|
1756
|
-
callService,
|
|
1757
|
-
cache: sourceCacheRef.current,
|
|
1758
|
-
onSelect: handleSelectContext
|
|
1759
|
-
}
|
|
1760
|
-
)
|
|
1761
|
-
}
|
|
1762
|
-
),
|
|
1763
|
-
builtinPlusEnabled && plusAnchor && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1764
|
-
AnchoredPopover,
|
|
1765
|
-
{
|
|
1766
|
-
anchorRect: plusAnchor,
|
|
1767
|
-
onClose: () => setPlusAnchor(null),
|
|
1768
|
-
role: "listbox",
|
|
1769
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1770
|
-
ContextSourceList,
|
|
1771
|
-
{
|
|
1772
|
-
sources: plusSources,
|
|
1773
|
-
query: "",
|
|
1774
|
-
callService,
|
|
1775
|
-
cache: sourceCacheRef.current,
|
|
1776
|
-
onSelect: handleSelectContext
|
|
1777
|
-
}
|
|
1778
|
-
)
|
|
1779
|
-
}
|
|
1780
|
-
)
|
|
2283
|
+
composerFooter !== void 0 && composerFooter !== null ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "pactor-chat-composer__footer", children: composerFooter }) : null,
|
|
2284
|
+
fileInputNode,
|
|
2285
|
+
popoverNodes
|
|
1781
2286
|
]
|
|
1782
2287
|
}
|
|
1783
2288
|
);
|
|
2289
|
+
const bridge = {
|
|
2290
|
+
text,
|
|
2291
|
+
streaming,
|
|
2292
|
+
disabled,
|
|
2293
|
+
attachments,
|
|
2294
|
+
contextChips,
|
|
2295
|
+
toolbarStart,
|
|
2296
|
+
toolbarEnd,
|
|
2297
|
+
composerFooter,
|
|
2298
|
+
models,
|
|
2299
|
+
model,
|
|
2300
|
+
showPlus: onPlusMenu !== void 0 || builtinPlusEnabled,
|
|
2301
|
+
showAttach: onAttachFiles !== void 0,
|
|
2302
|
+
modelChipEnabled,
|
|
2303
|
+
send,
|
|
2304
|
+
stop: onStop,
|
|
2305
|
+
openFilePicker: () => fileInputRef.current?.click(),
|
|
2306
|
+
plusClick: (rect) => {
|
|
2307
|
+
if (onPlusMenu) {
|
|
2308
|
+
onPlusMenu(rect);
|
|
2309
|
+
} else {
|
|
2310
|
+
setPlusAnchor(rect);
|
|
2311
|
+
}
|
|
2312
|
+
},
|
|
2313
|
+
removeAttachment: (id) => onAttachmentsChange?.((attachments ?? []).filter((a) => a.id !== id)),
|
|
2314
|
+
attachmentClick: onAttachmentClick,
|
|
2315
|
+
removeChip: (chip) => onContextChipsChange?.(
|
|
2316
|
+
(contextChips ?? []).filter(
|
|
2317
|
+
(existing) => !(existing.id === chip.id && existing.trigger === chip.trigger)
|
|
2318
|
+
)
|
|
2319
|
+
),
|
|
2320
|
+
modelChange: onModelChange
|
|
2321
|
+
};
|
|
2322
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2323
|
+
ChromeSlot,
|
|
2324
|
+
{
|
|
2325
|
+
fragment: buildComposerFragment({
|
|
2326
|
+
placeholder,
|
|
2327
|
+
disabled,
|
|
2328
|
+
hasFooter: composerFooter !== void 0 && composerFooter !== null,
|
|
2329
|
+
hideToolbar
|
|
2330
|
+
}),
|
|
2331
|
+
components: COMPOSER_INTERNAL_COMPONENTS,
|
|
2332
|
+
fallback,
|
|
2333
|
+
wrap: (children) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ComposerBridgeContext.Provider, { value: bridge, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
2334
|
+
"div",
|
|
2335
|
+
{
|
|
2336
|
+
className: `pactor-chat-composer pactor-chat-composer--dsl${dragOver ? " pactor-chat-composer--dragover" : ""}`,
|
|
2337
|
+
...dragHandlers,
|
|
2338
|
+
onChange: handleBubbleChange,
|
|
2339
|
+
onPaste: (event) => {
|
|
2340
|
+
if (handlePasteFiles(event.clipboardData)) {
|
|
2341
|
+
event.preventDefault();
|
|
2342
|
+
}
|
|
2343
|
+
},
|
|
2344
|
+
children: [
|
|
2345
|
+
children,
|
|
2346
|
+
fileInputNode,
|
|
2347
|
+
popoverNodes
|
|
2348
|
+
]
|
|
2349
|
+
}
|
|
2350
|
+
) })
|
|
2351
|
+
}
|
|
2352
|
+
);
|
|
1784
2353
|
}
|
|
1785
2354
|
|
|
1786
|
-
// src/view/
|
|
1787
|
-
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1788
|
-
var DEFAULT_CHAT_GREETING = "\u4F60\u597D\uFF0C\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F";
|
|
2355
|
+
// src/view/chrome/empty-state.tsx
|
|
1789
2356
|
function suggestionLabel(suggestion) {
|
|
1790
2357
|
return typeof suggestion === "string" ? suggestion : suggestion.label;
|
|
1791
2358
|
}
|
|
1792
2359
|
function suggestionPrompt(suggestion) {
|
|
1793
2360
|
return typeof suggestion === "string" ? suggestion : suggestion.prompt ?? suggestion.label;
|
|
1794
2361
|
}
|
|
1795
|
-
function
|
|
1796
|
-
|
|
2362
|
+
function buildEmptyStateFragment(props) {
|
|
2363
|
+
const children = [
|
|
2364
|
+
{
|
|
2365
|
+
type: "Typography",
|
|
2366
|
+
props: {
|
|
2367
|
+
variant: "h3",
|
|
2368
|
+
text: props.greeting,
|
|
2369
|
+
className: "pactor-chat-empty__greeting"
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
];
|
|
2373
|
+
if (props.subtitle) {
|
|
2374
|
+
children.push({
|
|
2375
|
+
type: "Text",
|
|
2376
|
+
props: {
|
|
2377
|
+
type: "secondary",
|
|
2378
|
+
text: props.subtitle,
|
|
2379
|
+
className: "pactor-chat-empty__subtitle"
|
|
2380
|
+
}
|
|
2381
|
+
});
|
|
2382
|
+
}
|
|
2383
|
+
if (props.suggestions && props.suggestions.length > 0) {
|
|
2384
|
+
children.push({
|
|
2385
|
+
type: "Flex",
|
|
2386
|
+
props: {
|
|
2387
|
+
gap: "small",
|
|
2388
|
+
justify: "center",
|
|
2389
|
+
className: "pactor-chat-empty__suggestions"
|
|
2390
|
+
},
|
|
2391
|
+
children: props.suggestions.map((suggestion) => ({
|
|
2392
|
+
type: "Button",
|
|
2393
|
+
props: {
|
|
2394
|
+
text: suggestionLabel(suggestion),
|
|
2395
|
+
variant: "default",
|
|
2396
|
+
size: "middle",
|
|
2397
|
+
className: "pactor-chat-empty__suggestion"
|
|
2398
|
+
},
|
|
2399
|
+
events: {
|
|
2400
|
+
onClick: [
|
|
2401
|
+
{
|
|
2402
|
+
action: "chat.sendSuggestion",
|
|
2403
|
+
params: { text: suggestionPrompt(suggestion) }
|
|
2404
|
+
}
|
|
2405
|
+
]
|
|
2406
|
+
}
|
|
2407
|
+
}))
|
|
2408
|
+
});
|
|
2409
|
+
}
|
|
2410
|
+
return {
|
|
2411
|
+
requires: ["Flex", "Typography", "Text", "Button"],
|
|
2412
|
+
node: {
|
|
2413
|
+
type: "Flex",
|
|
2414
|
+
props: { direction: "vertical", align: "center", gap: "middle" },
|
|
2415
|
+
children
|
|
2416
|
+
}
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
// src/view/EmptyState.tsx
|
|
2421
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2422
|
+
var DEFAULT_CHAT_GREETING = "\u4F60\u597D\uFF0C\u6709\u4EC0\u4E48\u53EF\u4EE5\u5E2E\u4F60\uFF1F";
|
|
2423
|
+
function suggestionLabel2(suggestion) {
|
|
2424
|
+
return typeof suggestion === "string" ? suggestion : suggestion.label;
|
|
2425
|
+
}
|
|
2426
|
+
function suggestionPrompt2(suggestion) {
|
|
2427
|
+
return typeof suggestion === "string" ? suggestion : suggestion.prompt ?? suggestion.label;
|
|
2428
|
+
}
|
|
2429
|
+
function EmptyStateFallback({
|
|
1797
2430
|
subtitle,
|
|
1798
2431
|
suggestions,
|
|
1799
|
-
onSuggestionClick
|
|
2432
|
+
onSuggestionClick,
|
|
2433
|
+
greeting
|
|
1800
2434
|
}) {
|
|
1801
|
-
return /* @__PURE__ */ (0,
|
|
1802
|
-
/* @__PURE__ */ (0,
|
|
1803
|
-
subtitle && /* @__PURE__ */ (0,
|
|
1804
|
-
suggestions && suggestions.length > 0 && /* @__PURE__ */ (0,
|
|
2435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2436
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pactor-chat-empty__greeting", children: greeting }),
|
|
2437
|
+
subtitle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pactor-chat-empty__subtitle", children: subtitle }),
|
|
2438
|
+
suggestions && suggestions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pactor-chat-empty__suggestions", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1805
2439
|
"button",
|
|
1806
2440
|
{
|
|
1807
2441
|
type: "button",
|
|
1808
2442
|
className: "pactor-chat-empty__suggestion",
|
|
1809
|
-
onClick: () => onSuggestionClick?.(
|
|
1810
|
-
children:
|
|
2443
|
+
onClick: () => onSuggestionClick?.(suggestionPrompt2(suggestion)),
|
|
2444
|
+
children: suggestionLabel2(suggestion)
|
|
1811
2445
|
},
|
|
1812
|
-
|
|
2446
|
+
suggestionLabel2(suggestion)
|
|
1813
2447
|
)) })
|
|
1814
2448
|
] });
|
|
1815
2449
|
}
|
|
2450
|
+
function EmptyState({
|
|
2451
|
+
greeting = DEFAULT_CHAT_GREETING,
|
|
2452
|
+
subtitle,
|
|
2453
|
+
suggestions,
|
|
2454
|
+
onSuggestionClick
|
|
2455
|
+
}) {
|
|
2456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pactor-chat-empty", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2457
|
+
ChromeSlot,
|
|
2458
|
+
{
|
|
2459
|
+
fragment: buildEmptyStateFragment({ greeting, subtitle, suggestions }),
|
|
2460
|
+
fallback: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2461
|
+
EmptyStateFallback,
|
|
2462
|
+
{
|
|
2463
|
+
greeting,
|
|
2464
|
+
subtitle,
|
|
2465
|
+
suggestions,
|
|
2466
|
+
onSuggestionClick
|
|
2467
|
+
}
|
|
2468
|
+
)
|
|
2469
|
+
}
|
|
2470
|
+
) });
|
|
2471
|
+
}
|
|
1816
2472
|
|
|
1817
2473
|
// src/view/MessageBubble.tsx
|
|
1818
|
-
var
|
|
2474
|
+
var import_react13 = require("react");
|
|
1819
2475
|
|
|
1820
2476
|
// src/view/ActivityTrace.tsx
|
|
1821
|
-
var
|
|
2477
|
+
var import_components8 = require("@pactor-app/ui/components");
|
|
1822
2478
|
var import_markdown3 = require("@pactor-app/markdown");
|
|
1823
|
-
var
|
|
1824
|
-
var
|
|
2479
|
+
var import_react11 = require("react");
|
|
2480
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1825
2481
|
function usePinnedCollapse(autoOpen) {
|
|
1826
|
-
const [state, setState] = (0,
|
|
2482
|
+
const [state, setState] = (0, import_react11.useState)("auto");
|
|
1827
2483
|
const open = state === "auto" ? autoOpen : state === "pinned-open";
|
|
1828
2484
|
const toggle = () => {
|
|
1829
2485
|
setState(open ? "pinned-closed" : "pinned-open");
|
|
@@ -1849,8 +2505,8 @@ function statusText(message, mode, toolCount) {
|
|
|
1849
2505
|
}
|
|
1850
2506
|
function useElapsedSeconds(startedAt, active) {
|
|
1851
2507
|
const compute = () => Math.max(0, Math.floor((Date.now() - startedAt) / 1e3));
|
|
1852
|
-
const [elapsed, setElapsed] = (0,
|
|
1853
|
-
(0,
|
|
2508
|
+
const [elapsed, setElapsed] = (0, import_react11.useState)(compute);
|
|
2509
|
+
(0, import_react11.useEffect)(() => {
|
|
1854
2510
|
if (!active) {
|
|
1855
2511
|
setElapsed(compute());
|
|
1856
2512
|
return;
|
|
@@ -1864,15 +2520,15 @@ function useElapsedSeconds(startedAt, active) {
|
|
|
1864
2520
|
}
|
|
1865
2521
|
function TraceStatusIcon({ status }) {
|
|
1866
2522
|
if (status === "running") {
|
|
1867
|
-
return /* @__PURE__ */ (0,
|
|
2523
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "loading", size: 13, className: "pactor-chat-spin" });
|
|
1868
2524
|
}
|
|
1869
2525
|
if (status === "success") {
|
|
1870
|
-
return /* @__PURE__ */ (0,
|
|
2526
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "check-circle", size: 13 });
|
|
1871
2527
|
}
|
|
1872
2528
|
if (status === "failed") {
|
|
1873
|
-
return /* @__PURE__ */ (0,
|
|
2529
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "x-circle", size: 13 });
|
|
1874
2530
|
}
|
|
1875
|
-
return /* @__PURE__ */ (0,
|
|
2531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "clock", size: 13 });
|
|
1876
2532
|
}
|
|
1877
2533
|
function summarizeArgs(args) {
|
|
1878
2534
|
if (args === void 0) {
|
|
@@ -1901,16 +2557,16 @@ function formatDetail(value) {
|
|
|
1901
2557
|
}
|
|
1902
2558
|
}
|
|
1903
2559
|
function TraceRow({ entry }) {
|
|
1904
|
-
const [open, setOpen] = (0,
|
|
2560
|
+
const [open, setOpen] = (0, import_react11.useState)(false);
|
|
1905
2561
|
const summary = summarizeArgs(entry.args);
|
|
1906
|
-
return /* @__PURE__ */ (0,
|
|
2562
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1907
2563
|
"div",
|
|
1908
2564
|
{
|
|
1909
2565
|
className: "pactor-chat-trace__entry",
|
|
1910
2566
|
"data-status": entry.status,
|
|
1911
2567
|
"data-open": open,
|
|
1912
2568
|
children: [
|
|
1913
|
-
/* @__PURE__ */ (0,
|
|
2569
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1914
2570
|
"button",
|
|
1915
2571
|
{
|
|
1916
2572
|
type: "button",
|
|
@@ -1918,16 +2574,16 @@ function TraceRow({ entry }) {
|
|
|
1918
2574
|
"aria-expanded": open,
|
|
1919
2575
|
onClick: () => setOpen((value) => !value),
|
|
1920
2576
|
children: [
|
|
1921
|
-
/* @__PURE__ */ (0,
|
|
1922
|
-
/* @__PURE__ */ (0,
|
|
1923
|
-
/* @__PURE__ */ (0,
|
|
1924
|
-
summary && /* @__PURE__ */ (0,
|
|
2577
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "chevron-right", size: 12 }) }),
|
|
2578
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "pactor-chat-trace__entry-icon", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TraceStatusIcon, { status: entry.status }) }),
|
|
2579
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "pactor-chat-trace__entry-title", children: entry.title ?? entry.name }),
|
|
2580
|
+
summary && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "pactor-chat-trace__entry-args", children: summary })
|
|
1925
2581
|
]
|
|
1926
2582
|
}
|
|
1927
2583
|
),
|
|
1928
|
-
open && /* @__PURE__ */ (0,
|
|
1929
|
-
entry.args !== void 0 && /* @__PURE__ */ (0,
|
|
1930
|
-
/* @__PURE__ */ (0,
|
|
2584
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "pactor-chat-trace__entry-body", children: [
|
|
2585
|
+
entry.args !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("pre", { className: "pactor-chat-trace__entry-detail", children: formatDetail(entry.args) }),
|
|
2586
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("pre", { className: "pactor-chat-trace__entry-detail", children: entry.status === "failed" ? entry.error ?? "\u6267\u884C\u5931\u8D25" : formatDetail(entry.result) })
|
|
1931
2587
|
] })
|
|
1932
2588
|
]
|
|
1933
2589
|
}
|
|
@@ -1939,14 +2595,14 @@ function ThinkingCard({
|
|
|
1939
2595
|
}) {
|
|
1940
2596
|
const partStreaming = part.status === "streaming";
|
|
1941
2597
|
const { open, toggle } = usePinnedCollapse(partStreaming && !answerPhase);
|
|
1942
|
-
return /* @__PURE__ */ (0,
|
|
2598
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1943
2599
|
"div",
|
|
1944
2600
|
{
|
|
1945
2601
|
className: "pactor-chat-thinking",
|
|
1946
2602
|
"data-open": open,
|
|
1947
2603
|
"data-streaming": partStreaming,
|
|
1948
2604
|
children: [
|
|
1949
|
-
/* @__PURE__ */ (0,
|
|
2605
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
1950
2606
|
"button",
|
|
1951
2607
|
{
|
|
1952
2608
|
type: "button",
|
|
@@ -1954,13 +2610,13 @@ function ThinkingCard({
|
|
|
1954
2610
|
"aria-expanded": open,
|
|
1955
2611
|
onClick: toggle,
|
|
1956
2612
|
children: [
|
|
1957
|
-
/* @__PURE__ */ (0,
|
|
1958
|
-
/* @__PURE__ */ (0,
|
|
1959
|
-
/* @__PURE__ */ (0,
|
|
2613
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "chevron-right", size: 12 }) }),
|
|
2614
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "pactor-chat-thinking__icon", children: partStreaming ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "loading", size: 13, className: "pactor-chat-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "brain", size: 13 }) }),
|
|
2615
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "\u601D\u8003\u8FC7\u7A0B" })
|
|
1960
2616
|
]
|
|
1961
2617
|
}
|
|
1962
2618
|
),
|
|
1963
|
-
open && /* @__PURE__ */ (0,
|
|
2619
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pactor-chat-thinking__body", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_markdown3.MarkdownRenderer, { content: part.content }) })
|
|
1964
2620
|
]
|
|
1965
2621
|
}
|
|
1966
2622
|
);
|
|
@@ -1974,7 +2630,7 @@ function ActivityTrace({ message }) {
|
|
|
1974
2630
|
);
|
|
1975
2631
|
const answerPhase = mode === "responding" || !streaming;
|
|
1976
2632
|
const { open, toggle } = usePinnedCollapse(!answerPhase);
|
|
1977
|
-
const mountTimeRef = (0,
|
|
2633
|
+
const mountTimeRef = (0, import_react11.useRef)(0);
|
|
1978
2634
|
if (mountTimeRef.current === 0) {
|
|
1979
2635
|
mountTimeRef.current = Date.now();
|
|
1980
2636
|
}
|
|
@@ -1982,23 +2638,23 @@ function ActivityTrace({ message }) {
|
|
|
1982
2638
|
message.createdAt ?? mountTimeRef.current,
|
|
1983
2639
|
streaming
|
|
1984
2640
|
);
|
|
1985
|
-
const header = /* @__PURE__ */ (0,
|
|
1986
|
-
/* @__PURE__ */ (0,
|
|
1987
|
-
/* @__PURE__ */ (0,
|
|
2641
|
+
const header = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
2642
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "pactor-chat-trace__status-icon", children: streaming ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "loading", size: 13, className: "pactor-chat-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "check-circle", size: 13 }) }),
|
|
2643
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1988
2644
|
"span",
|
|
1989
2645
|
{
|
|
1990
2646
|
className: `pactor-chat-trace__status-text${streaming ? " pactor-chat-trace__status-text--breathing" : ""}`,
|
|
1991
2647
|
children: statusText(message, mode, entries.length)
|
|
1992
2648
|
}
|
|
1993
2649
|
),
|
|
1994
|
-
/* @__PURE__ */ (0,
|
|
2650
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "pactor-chat-trace__elapsed", children: [
|
|
1995
2651
|
elapsed,
|
|
1996
2652
|
"s"
|
|
1997
2653
|
] }),
|
|
1998
|
-
entries.length > 0 && /* @__PURE__ */ (0,
|
|
2654
|
+
entries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "pactor-chat-trace__chevron", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_components8.Icon, { name: "chevron-right", size: 12 }) })
|
|
1999
2655
|
] });
|
|
2000
|
-
return /* @__PURE__ */ (0,
|
|
2001
|
-
entries.length > 0 ? /* @__PURE__ */ (0,
|
|
2656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "pactor-chat-trace", "data-open": open, children: [
|
|
2657
|
+
entries.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2002
2658
|
"button",
|
|
2003
2659
|
{
|
|
2004
2660
|
type: "button",
|
|
@@ -2007,8 +2663,8 @@ function ActivityTrace({ message }) {
|
|
|
2007
2663
|
onClick: toggle,
|
|
2008
2664
|
children: header
|
|
2009
2665
|
}
|
|
2010
|
-
) : /* @__PURE__ */ (0,
|
|
2011
|
-
thinkingParts.map((part, index) => /* @__PURE__ */ (0,
|
|
2666
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pactor-chat-trace__header", children: header }),
|
|
2667
|
+
thinkingParts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2012
2668
|
ThinkingCard,
|
|
2013
2669
|
{
|
|
2014
2670
|
part,
|
|
@@ -2016,25 +2672,66 @@ function ActivityTrace({ message }) {
|
|
|
2016
2672
|
},
|
|
2017
2673
|
part.id ?? index
|
|
2018
2674
|
)),
|
|
2019
|
-
open && entries.length > 0 && /* @__PURE__ */ (0,
|
|
2675
|
+
open && entries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pactor-chat-trace__entries", children: entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TraceRow, { entry }, entry.callIndex)) })
|
|
2020
2676
|
] });
|
|
2021
2677
|
}
|
|
2022
2678
|
|
|
2023
2679
|
// src/view/MessageActions.tsx
|
|
2024
|
-
var
|
|
2025
|
-
var
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2680
|
+
var import_components9 = require("@pactor-app/ui/components");
|
|
2681
|
+
var import_react12 = require("react");
|
|
2682
|
+
|
|
2683
|
+
// src/view/chrome/message-actions.tsx
|
|
2684
|
+
function buildMessageActionsFragment(args) {
|
|
2685
|
+
const { actions, copied, token } = args;
|
|
2686
|
+
return {
|
|
2687
|
+
requires: ["Flex", "Tooltip", "Button", "Icon"],
|
|
2688
|
+
node: {
|
|
2689
|
+
type: "Flex",
|
|
2690
|
+
props: { gap: "small" },
|
|
2691
|
+
children: actions.map((action) => {
|
|
2692
|
+
const copiedFeedback = action.builtin === "copy" && copied;
|
|
2693
|
+
const label = copiedFeedback ? "\u5DF2\u590D\u5236" : action.label;
|
|
2694
|
+
const iconName = copiedFeedback ? "check" : action.icon;
|
|
2695
|
+
return {
|
|
2696
|
+
type: "Tooltip",
|
|
2697
|
+
props: { content: label },
|
|
2698
|
+
children: [
|
|
2699
|
+
{
|
|
2700
|
+
type: "Button",
|
|
2701
|
+
props: {
|
|
2702
|
+
variant: "text",
|
|
2703
|
+
size: "small",
|
|
2704
|
+
className: "pactor-chat-icon-button"
|
|
2705
|
+
},
|
|
2706
|
+
events: {
|
|
2707
|
+
onClick: [
|
|
2708
|
+
{
|
|
2709
|
+
action: "chat.messageAction",
|
|
2710
|
+
params: { token, actionId: action.id }
|
|
2711
|
+
}
|
|
2712
|
+
]
|
|
2713
|
+
},
|
|
2714
|
+
children: [
|
|
2715
|
+
{
|
|
2716
|
+
type: "Icon",
|
|
2717
|
+
props: {
|
|
2718
|
+
// 契约图标名直通 ui Icon 白名单(spec: chat-icon-convergence;
|
|
2719
|
+
// 未知名由 ui Icon 渲染占位)
|
|
2720
|
+
name: iconName ?? "help-circle",
|
|
2721
|
+
size: 14
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
]
|
|
2725
|
+
}
|
|
2726
|
+
]
|
|
2727
|
+
};
|
|
2728
|
+
})
|
|
2729
|
+
}
|
|
2730
|
+
};
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
// src/view/MessageActions.tsx
|
|
2734
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2038
2735
|
var BUILTIN_ACTION_DEFAULTS = {
|
|
2039
2736
|
copy: {
|
|
2040
2737
|
label: "\u590D\u5236",
|
|
@@ -2107,7 +2804,21 @@ function MessageActions({
|
|
|
2107
2804
|
callService,
|
|
2108
2805
|
onMessageAction
|
|
2109
2806
|
}) {
|
|
2110
|
-
const [copied, setCopied] = (0,
|
|
2807
|
+
const [copied, setCopied] = (0, import_react12.useState)(false);
|
|
2808
|
+
const dispatchRef = (0, import_react12.useRef)(
|
|
2809
|
+
() => {
|
|
2810
|
+
}
|
|
2811
|
+
);
|
|
2812
|
+
const visibleActionsRef = (0, import_react12.useRef)([]);
|
|
2813
|
+
(0, import_react12.useEffect)(() => {
|
|
2814
|
+
setMessageActionDispatcher(message.id, (actionId) => {
|
|
2815
|
+
const action = visibleActionsRef.current.find((a) => a.id === actionId);
|
|
2816
|
+
if (action) {
|
|
2817
|
+
dispatchRef.current(action);
|
|
2818
|
+
}
|
|
2819
|
+
});
|
|
2820
|
+
return () => clearMessageActionDispatcher(message.id);
|
|
2821
|
+
}, [message.id]);
|
|
2111
2822
|
const copy = async () => {
|
|
2112
2823
|
try {
|
|
2113
2824
|
await navigator.clipboard.writeText(collectMessageText(message));
|
|
@@ -2167,41 +2878,53 @@ function MessageActions({
|
|
|
2167
2878
|
}
|
|
2168
2879
|
onMessageAction?.(action.id, message);
|
|
2169
2880
|
};
|
|
2170
|
-
|
|
2881
|
+
dispatchRef.current = dispatch;
|
|
2882
|
+
visibleActionsRef.current = visibleActions;
|
|
2883
|
+
const buttons = visibleActions.map((action) => {
|
|
2884
|
+
const copiedFeedback = action.builtin === "copy" && copied;
|
|
2885
|
+
const label = copiedFeedback ? "\u5DF2\u590D\u5236" : action.label;
|
|
2886
|
+
const iconName = copiedFeedback ? "check" : action.icon;
|
|
2887
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2888
|
+
"button",
|
|
2889
|
+
{
|
|
2890
|
+
type: "button",
|
|
2891
|
+
className: "pactor-chat-icon-button",
|
|
2892
|
+
title: label,
|
|
2893
|
+
"aria-label": label,
|
|
2894
|
+
"data-message-action": action.id,
|
|
2895
|
+
onClick: () => dispatch(action),
|
|
2896
|
+
children: iconName !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: iconName, size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_components9.Icon, { name: "help-circle", size: 14 })
|
|
2897
|
+
},
|
|
2898
|
+
action.id
|
|
2899
|
+
);
|
|
2900
|
+
});
|
|
2901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2171
2902
|
"div",
|
|
2172
2903
|
{
|
|
2173
2904
|
className: `pactor-chat-message__actions${forceVisible ? " pactor-chat-message__actions--visible" : ""}`,
|
|
2174
|
-
children:
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
"aria-label": label,
|
|
2186
|
-
"data-message-action": action.id,
|
|
2187
|
-
onClick: () => dispatch(action),
|
|
2188
|
-
children: Icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react7.HelpCircle, { size: 14, "data-icon-placeholder": "true" })
|
|
2189
|
-
},
|
|
2190
|
-
action.id
|
|
2191
|
-
);
|
|
2192
|
-
})
|
|
2905
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2906
|
+
ChromeSlot,
|
|
2907
|
+
{
|
|
2908
|
+
fragment: buildMessageActionsFragment({
|
|
2909
|
+
actions: visibleActions,
|
|
2910
|
+
copied,
|
|
2911
|
+
token: message.id
|
|
2912
|
+
}),
|
|
2913
|
+
fallback: buttons
|
|
2914
|
+
}
|
|
2915
|
+
)
|
|
2193
2916
|
}
|
|
2194
2917
|
);
|
|
2195
2918
|
}
|
|
2196
2919
|
|
|
2197
2920
|
// src/view/MessageBubble.tsx
|
|
2198
|
-
var
|
|
2921
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2199
2922
|
function MessageEditForm({
|
|
2200
2923
|
initialText,
|
|
2201
2924
|
onConfirm,
|
|
2202
2925
|
onCancel
|
|
2203
2926
|
}) {
|
|
2204
|
-
const [text, setText] = (0,
|
|
2927
|
+
const [text, setText] = (0, import_react13.useState)(initialText);
|
|
2205
2928
|
const confirm = () => {
|
|
2206
2929
|
const value = text.trim();
|
|
2207
2930
|
if (!value) {
|
|
@@ -2209,8 +2932,8 @@ function MessageEditForm({
|
|
|
2209
2932
|
}
|
|
2210
2933
|
onConfirm(value);
|
|
2211
2934
|
};
|
|
2212
|
-
return /* @__PURE__ */ (0,
|
|
2213
|
-
/* @__PURE__ */ (0,
|
|
2935
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "pactor-chat-message__edit", children: [
|
|
2936
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2214
2937
|
"textarea",
|
|
2215
2938
|
{
|
|
2216
2939
|
className: "pactor-chat-message__edit-input",
|
|
@@ -2228,8 +2951,8 @@ function MessageEditForm({
|
|
|
2228
2951
|
}
|
|
2229
2952
|
}
|
|
2230
2953
|
),
|
|
2231
|
-
/* @__PURE__ */ (0,
|
|
2232
|
-
/* @__PURE__ */ (0,
|
|
2954
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "pactor-chat-message__edit-actions", children: [
|
|
2955
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2233
2956
|
"button",
|
|
2234
2957
|
{
|
|
2235
2958
|
type: "button",
|
|
@@ -2239,7 +2962,7 @@ function MessageEditForm({
|
|
|
2239
2962
|
children: "\u53D1\u9001"
|
|
2240
2963
|
}
|
|
2241
2964
|
),
|
|
2242
|
-
/* @__PURE__ */ (0,
|
|
2965
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2243
2966
|
"button",
|
|
2244
2967
|
{
|
|
2245
2968
|
type: "button",
|
|
@@ -2265,7 +2988,7 @@ function MessageBubble({
|
|
|
2265
2988
|
onMessageAction,
|
|
2266
2989
|
onOpenArtifact
|
|
2267
2990
|
}) {
|
|
2268
|
-
const [editing, setEditing] = (0,
|
|
2991
|
+
const [editing, setEditing] = (0, import_react13.useState)(false);
|
|
2269
2992
|
const bubbleScope = {
|
|
2270
2993
|
conversation: scope?.conversation ?? {},
|
|
2271
2994
|
message: { id: message.id },
|
|
@@ -2273,21 +2996,21 @@ function MessageBubble({
|
|
|
2273
2996
|
};
|
|
2274
2997
|
const streaming = message.status === "streaming";
|
|
2275
2998
|
const live = message.status === "pending" || message.status === "streaming";
|
|
2276
|
-
const wasLiveRef = (0,
|
|
2999
|
+
const wasLiveRef = (0, import_react13.useRef)(live);
|
|
2277
3000
|
if (live) {
|
|
2278
3001
|
wasLiveRef.current = true;
|
|
2279
3002
|
}
|
|
2280
3003
|
const showTrace = message.role === "assistant" && (wasLiveRef.current || message.parts.some(
|
|
2281
3004
|
(part) => part.type === "thinking" || part.type === "tool-call" || part.type === "tool-result"
|
|
2282
3005
|
));
|
|
2283
|
-
return /* @__PURE__ */ (0,
|
|
3006
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2284
3007
|
"div",
|
|
2285
3008
|
{
|
|
2286
3009
|
className: `pactor-chat-message pactor-chat-message--${message.role}`,
|
|
2287
3010
|
"data-message-id": message.id,
|
|
2288
3011
|
"data-message-status": message.status,
|
|
2289
3012
|
children: [
|
|
2290
|
-
editing ? /* @__PURE__ */ (0,
|
|
3013
|
+
editing ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2291
3014
|
MessageEditForm,
|
|
2292
3015
|
{
|
|
2293
3016
|
initialText: collectMessageText(message),
|
|
@@ -2297,9 +3020,9 @@ function MessageBubble({
|
|
|
2297
3020
|
},
|
|
2298
3021
|
onCancel: () => setEditing(false)
|
|
2299
3022
|
}
|
|
2300
|
-
) : /* @__PURE__ */ (0,
|
|
2301
|
-
showTrace && /* @__PURE__ */ (0,
|
|
2302
|
-
message.parts.length === 0 && message.status === "pending" && message.role !== "assistant" ? /* @__PURE__ */ (0,
|
|
3023
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "pactor-chat-message__body", children: [
|
|
3024
|
+
showTrace && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ActivityTrace, { message }),
|
|
3025
|
+
message.parts.length === 0 && message.status === "pending" && message.role !== "assistant" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "pactor-chat-message__pending", children: "\u2026" }) : message.parts.map((part, index) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2303
3026
|
PartRenderer,
|
|
2304
3027
|
{
|
|
2305
3028
|
part,
|
|
@@ -2311,7 +3034,7 @@ function MessageBubble({
|
|
|
2311
3034
|
part.id ?? index
|
|
2312
3035
|
))
|
|
2313
3036
|
] }),
|
|
2314
|
-
!editing && /* @__PURE__ */ (0,
|
|
3037
|
+
!editing && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2315
3038
|
MessageActions,
|
|
2316
3039
|
{
|
|
2317
3040
|
message,
|
|
@@ -2331,7 +3054,7 @@ function MessageBubble({
|
|
|
2331
3054
|
}
|
|
2332
3055
|
|
|
2333
3056
|
// src/view/ChatView.tsx
|
|
2334
|
-
var
|
|
3057
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2335
3058
|
function lastContentLength(messages) {
|
|
2336
3059
|
const last = messages[messages.length - 1];
|
|
2337
3060
|
if (!last) {
|
|
@@ -2365,6 +3088,8 @@ function ChatView({
|
|
|
2365
3088
|
onAttachmentClick,
|
|
2366
3089
|
toolbarStart,
|
|
2367
3090
|
toolbarEnd,
|
|
3091
|
+
composerFooter,
|
|
3092
|
+
hideToolbar,
|
|
2368
3093
|
onMentionTrigger,
|
|
2369
3094
|
onPlusMenu,
|
|
2370
3095
|
models,
|
|
@@ -2375,20 +3100,21 @@ function ChatView({
|
|
|
2375
3100
|
onContextsChange,
|
|
2376
3101
|
callService,
|
|
2377
3102
|
messageActions,
|
|
2378
|
-
onMessageAction
|
|
3103
|
+
onMessageAction,
|
|
3104
|
+
composerBottom
|
|
2379
3105
|
}) {
|
|
2380
|
-
const messages = (0,
|
|
3106
|
+
const messages = (0, import_react14.useSyncExternalStore)(
|
|
2381
3107
|
(listener) => store.subscribe(listener),
|
|
2382
3108
|
() => store.getMessages()
|
|
2383
3109
|
);
|
|
2384
3110
|
const isStreaming = messages.some(
|
|
2385
3111
|
(message) => message.status === "pending" || message.status === "streaming"
|
|
2386
3112
|
);
|
|
2387
|
-
const runtime = (0,
|
|
3113
|
+
const runtime = (0, import_react14.useMemo)(() => {
|
|
2388
3114
|
if (!safeRegistry) {
|
|
2389
3115
|
return void 0;
|
|
2390
3116
|
}
|
|
2391
|
-
const components = new
|
|
3117
|
+
const components = new import_core4.Registry("ChatComponentRegistry");
|
|
2392
3118
|
components.register(CHAT_DENIED_TYPE, ChatDenied);
|
|
2393
3119
|
for (const name of safeRegistry.list()) {
|
|
2394
3120
|
components.register(name, safeRegistry.get(name));
|
|
@@ -2401,12 +3127,12 @@ function ChatView({
|
|
|
2401
3127
|
user
|
|
2402
3128
|
});
|
|
2403
3129
|
}, [safeRegistry, capabilities, permission, confirm, user]);
|
|
2404
|
-
const scope = (0,
|
|
3130
|
+
const scope = (0, import_react14.useMemo)(
|
|
2405
3131
|
() => ({ conversation: { id: conversationId }, params }),
|
|
2406
3132
|
[conversationId, params]
|
|
2407
3133
|
);
|
|
2408
|
-
const notifiedArtifactsRef = (0,
|
|
2409
|
-
(0,
|
|
3134
|
+
const notifiedArtifactsRef = (0, import_react14.useRef)(/* @__PURE__ */ new Set());
|
|
3135
|
+
(0, import_react14.useEffect)(() => {
|
|
2410
3136
|
if (!onArtifact) {
|
|
2411
3137
|
return;
|
|
2412
3138
|
}
|
|
@@ -2425,7 +3151,7 @@ function ChatView({
|
|
|
2425
3151
|
});
|
|
2426
3152
|
}
|
|
2427
3153
|
}, [messages, onArtifact]);
|
|
2428
|
-
const abortRef = (0,
|
|
3154
|
+
const abortRef = (0, import_react14.useRef)(null);
|
|
2429
3155
|
const { containerRef, isFollowing, scrollToBottom } = useChatAutoScroll({
|
|
2430
3156
|
messageCount: messages.length,
|
|
2431
3157
|
lastContentLength: lastContentLength(messages),
|
|
@@ -2436,7 +3162,7 @@ function ChatView({
|
|
|
2436
3162
|
model,
|
|
2437
3163
|
onModelChange
|
|
2438
3164
|
});
|
|
2439
|
-
const [contextChips, setContextChips] = (0,
|
|
3165
|
+
const [contextChips, setContextChips] = (0, import_react14.useState)([]);
|
|
2440
3166
|
const handleContextChipsChange = (chips) => {
|
|
2441
3167
|
setContextChips(chips);
|
|
2442
3168
|
onContextsChange?.(chips);
|
|
@@ -2468,6 +3194,16 @@ function ChatView({
|
|
|
2468
3194
|
abortRef.current?.abort();
|
|
2469
3195
|
abortRef.current = null;
|
|
2470
3196
|
};
|
|
3197
|
+
const handleSendRef = (0, import_react14.useRef)(handleSend);
|
|
3198
|
+
handleSendRef.current = handleSend;
|
|
3199
|
+
const onOpenArtifactRef = (0, import_react14.useRef)(onOpenArtifact);
|
|
3200
|
+
onOpenArtifactRef.current = onOpenArtifact;
|
|
3201
|
+
(0, import_react14.useEffect)(() => {
|
|
3202
|
+
setChatChromeHandlers({
|
|
3203
|
+
sendSuggestion: (text) => handleSendRef.current(text),
|
|
3204
|
+
openArtifact: (artifact) => onOpenArtifactRef.current?.(artifact)
|
|
3205
|
+
});
|
|
3206
|
+
}, []);
|
|
2471
3207
|
const handleRegenerate = () => {
|
|
2472
3208
|
if (!transport) {
|
|
2473
3209
|
return;
|
|
@@ -2485,7 +3221,7 @@ function ChatView({
|
|
|
2485
3221
|
const lastMessage = messages[messages.length - 1];
|
|
2486
3222
|
const regenerableMessageId = lastMessage?.role === "assistant" && lastMessage.status === "completed" ? lastMessage.id : void 0;
|
|
2487
3223
|
const isEmpty = messages.length === 0;
|
|
2488
|
-
const composerNode = /* @__PURE__ */ (0,
|
|
3224
|
+
const composerNode = /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2489
3225
|
Composer,
|
|
2490
3226
|
{
|
|
2491
3227
|
onSend: handleSend,
|
|
@@ -2497,6 +3233,8 @@ function ChatView({
|
|
|
2497
3233
|
onAttachmentClick,
|
|
2498
3234
|
toolbarStart,
|
|
2499
3235
|
toolbarEnd,
|
|
3236
|
+
composerFooter,
|
|
3237
|
+
hideToolbar,
|
|
2500
3238
|
onMentionTrigger,
|
|
2501
3239
|
onPlusMenu,
|
|
2502
3240
|
models: modelPlacement === "header" ? void 0 : models,
|
|
@@ -2508,14 +3246,18 @@ function ChatView({
|
|
|
2508
3246
|
callService
|
|
2509
3247
|
}
|
|
2510
3248
|
);
|
|
2511
|
-
|
|
3249
|
+
const composerDock = /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "pactor-chat-view__composer-dock", children: [
|
|
3250
|
+
composerNode,
|
|
3251
|
+
composerBottom !== void 0 && composerBottom !== null ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "pactor-chat-view__composer-bottom", children: composerBottom }) : null
|
|
3252
|
+
] });
|
|
3253
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2512
3254
|
"div",
|
|
2513
3255
|
{
|
|
2514
3256
|
className: `pactor-chat-view${isEmpty ? " pactor-chat-view--empty" : ""}${className ? ` ${className}` : ""}`,
|
|
2515
3257
|
children: [
|
|
2516
|
-
/* @__PURE__ */ (0,
|
|
2517
|
-
isEmpty ? /* @__PURE__ */ (0,
|
|
2518
|
-
/* @__PURE__ */ (0,
|
|
3258
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "pactor-chat-messages", ref: containerRef, children: [
|
|
3259
|
+
isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "pactor-chat-view__empty-stack", children: [
|
|
3260
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2519
3261
|
EmptyState,
|
|
2520
3262
|
{
|
|
2521
3263
|
greeting,
|
|
@@ -2524,8 +3266,8 @@ function ChatView({
|
|
|
2524
3266
|
onSuggestionClick: handleSend
|
|
2525
3267
|
}
|
|
2526
3268
|
),
|
|
2527
|
-
|
|
2528
|
-
] }) : messages.map((message) => /* @__PURE__ */ (0,
|
|
3269
|
+
composerDock
|
|
3270
|
+
] }) : messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2529
3271
|
MessageBubble,
|
|
2530
3272
|
{
|
|
2531
3273
|
message,
|
|
@@ -2542,28 +3284,28 @@ function ChatView({
|
|
|
2542
3284
|
},
|
|
2543
3285
|
message.id
|
|
2544
3286
|
)),
|
|
2545
|
-
!isFollowing && /* @__PURE__ */ (0,
|
|
3287
|
+
!isFollowing && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2546
3288
|
"button",
|
|
2547
3289
|
{
|
|
2548
3290
|
type: "button",
|
|
2549
3291
|
className: "pactor-chat-scroll-bottom",
|
|
2550
3292
|
onClick: scrollToBottom,
|
|
2551
3293
|
children: [
|
|
2552
|
-
/* @__PURE__ */ (0,
|
|
3294
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_components10.Icon, { name: "arrow-down", size: 13 }),
|
|
2553
3295
|
"\u56DE\u5230\u5E95\u90E8"
|
|
2554
3296
|
]
|
|
2555
3297
|
}
|
|
2556
3298
|
)
|
|
2557
3299
|
] }),
|
|
2558
|
-
!isEmpty &&
|
|
3300
|
+
!isEmpty && composerDock
|
|
2559
3301
|
]
|
|
2560
3302
|
}
|
|
2561
3303
|
);
|
|
2562
3304
|
}
|
|
2563
3305
|
|
|
2564
3306
|
// src/view/WorkspaceHeader.tsx
|
|
2565
|
-
var
|
|
2566
|
-
var
|
|
3307
|
+
var import_components11 = require("@pactor-app/ui/components");
|
|
3308
|
+
var import_react15 = require("react");
|
|
2567
3309
|
|
|
2568
3310
|
// src/export-markdown.ts
|
|
2569
3311
|
var ROLE_LABELS = {
|
|
@@ -2595,8 +3337,52 @@ function downloadMessagesAsMarkdown(title, messages) {
|
|
|
2595
3337
|
URL.revokeObjectURL(url);
|
|
2596
3338
|
}
|
|
2597
3339
|
|
|
3340
|
+
// src/view/chrome/header-actions.tsx
|
|
3341
|
+
function buildHeaderActionsFragment(props) {
|
|
3342
|
+
const meta = {
|
|
3343
|
+
export: { label: "\u5BFC\u51FA Markdown", icon: "download" },
|
|
3344
|
+
theme: {
|
|
3345
|
+
label: props.theme === "dark" ? "\u5207\u6362\u4E3A\u6D45\u8272" : "\u5207\u6362\u4E3A\u6DF1\u8272",
|
|
3346
|
+
icon: props.theme === "dark" ? "sun" : "moon"
|
|
3347
|
+
},
|
|
3348
|
+
clear: { label: "\u6E05\u7A7A\u4F1A\u8BDD", icon: "trash2" }
|
|
3349
|
+
};
|
|
3350
|
+
return {
|
|
3351
|
+
requires: ["Flex", "Tooltip", "Button", "Icon"],
|
|
3352
|
+
node: {
|
|
3353
|
+
type: "Flex",
|
|
3354
|
+
props: { gap: "small", align: "center" },
|
|
3355
|
+
children: props.actions.map((action) => ({
|
|
3356
|
+
type: "Tooltip",
|
|
3357
|
+
props: { content: meta[action].label },
|
|
3358
|
+
children: [
|
|
3359
|
+
{
|
|
3360
|
+
type: "Button",
|
|
3361
|
+
props: {
|
|
3362
|
+
variant: "text",
|
|
3363
|
+
size: "small",
|
|
3364
|
+
className: "pactor-chat-icon-button"
|
|
3365
|
+
},
|
|
3366
|
+
events: {
|
|
3367
|
+
onClick: [
|
|
3368
|
+
{ action: "chat.headerAction", params: { action } }
|
|
3369
|
+
]
|
|
3370
|
+
},
|
|
3371
|
+
children: [
|
|
3372
|
+
{
|
|
3373
|
+
type: "Icon",
|
|
3374
|
+
props: { name: meta[action].icon, size: 15 }
|
|
3375
|
+
}
|
|
3376
|
+
]
|
|
3377
|
+
}
|
|
3378
|
+
]
|
|
3379
|
+
}))
|
|
3380
|
+
}
|
|
3381
|
+
};
|
|
3382
|
+
}
|
|
3383
|
+
|
|
2598
3384
|
// src/view/WorkspaceHeader.tsx
|
|
2599
|
-
var
|
|
3385
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2600
3386
|
function readCurrentTheme() {
|
|
2601
3387
|
if (typeof document === "undefined") {
|
|
2602
3388
|
return "light";
|
|
@@ -2616,10 +3402,10 @@ function WorkspaceHeader({
|
|
|
2616
3402
|
onTitleChange
|
|
2617
3403
|
}) {
|
|
2618
3404
|
const hasActions = headerActions !== void 0 && headerActions.length > 0;
|
|
2619
|
-
const [overrideTitle, setOverrideTitle] = (0,
|
|
2620
|
-
const [editing, setEditing] = (0,
|
|
2621
|
-
const [draft, setDraft] = (0,
|
|
2622
|
-
const prevTitleRef = (0,
|
|
3405
|
+
const [overrideTitle, setOverrideTitle] = (0, import_react15.useState)(null);
|
|
3406
|
+
const [editing, setEditing] = (0, import_react15.useState)(false);
|
|
3407
|
+
const [draft, setDraft] = (0, import_react15.useState)("");
|
|
3408
|
+
const prevTitleRef = (0, import_react15.useRef)(title);
|
|
2623
3409
|
if (prevTitleRef.current !== title) {
|
|
2624
3410
|
prevTitleRef.current = title;
|
|
2625
3411
|
if (overrideTitle !== null) {
|
|
@@ -2627,7 +3413,7 @@ function WorkspaceHeader({
|
|
|
2627
3413
|
}
|
|
2628
3414
|
}
|
|
2629
3415
|
const displayTitle = overrideTitle ?? title;
|
|
2630
|
-
const [theme, setTheme] = (0,
|
|
3416
|
+
const [theme, setTheme] = (0, import_react15.useState)(readCurrentTheme);
|
|
2631
3417
|
const commitTitle = () => {
|
|
2632
3418
|
setEditing(false);
|
|
2633
3419
|
const next = draft.trim();
|
|
@@ -2654,8 +3440,24 @@ function WorkspaceHeader({
|
|
|
2654
3440
|
store.clear();
|
|
2655
3441
|
onClear?.();
|
|
2656
3442
|
};
|
|
3443
|
+
const handlersRef = (0, import_react15.useRef)({ handleExport, handleTheme, handleClear });
|
|
3444
|
+
handlersRef.current = { handleExport, handleTheme, handleClear };
|
|
3445
|
+
(0, import_react15.useEffect)(() => {
|
|
3446
|
+
setChatChromeHandlers({
|
|
3447
|
+
headerAction: (name) => {
|
|
3448
|
+
const handlers2 = handlersRef.current;
|
|
3449
|
+
if (name === "export") {
|
|
3450
|
+
handlers2.handleExport();
|
|
3451
|
+
} else if (name === "theme") {
|
|
3452
|
+
handlers2.handleTheme();
|
|
3453
|
+
} else if (name === "clear") {
|
|
3454
|
+
handlers2.handleClear();
|
|
3455
|
+
}
|
|
3456
|
+
}
|
|
3457
|
+
});
|
|
3458
|
+
}, []);
|
|
2657
3459
|
const actionButtons = {
|
|
2658
|
-
export: /* @__PURE__ */ (0,
|
|
3460
|
+
export: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2659
3461
|
"button",
|
|
2660
3462
|
{
|
|
2661
3463
|
type: "button",
|
|
@@ -2663,11 +3465,11 @@ function WorkspaceHeader({
|
|
|
2663
3465
|
title: "\u5BFC\u51FA Markdown",
|
|
2664
3466
|
"aria-label": "\u5BFC\u51FA Markdown",
|
|
2665
3467
|
onClick: handleExport,
|
|
2666
|
-
children: /* @__PURE__ */ (0,
|
|
3468
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components11.Icon, { name: "download", size: 15 })
|
|
2667
3469
|
},
|
|
2668
3470
|
"export"
|
|
2669
3471
|
),
|
|
2670
|
-
theme: /* @__PURE__ */ (0,
|
|
3472
|
+
theme: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2671
3473
|
"button",
|
|
2672
3474
|
{
|
|
2673
3475
|
type: "button",
|
|
@@ -2675,11 +3477,11 @@ function WorkspaceHeader({
|
|
|
2675
3477
|
title: theme === "dark" ? "\u5207\u6362\u4E3A\u6D45\u8272" : "\u5207\u6362\u4E3A\u6DF1\u8272",
|
|
2676
3478
|
"aria-label": "\u5207\u6362\u660E\u6697\u4E3B\u9898",
|
|
2677
3479
|
onClick: handleTheme,
|
|
2678
|
-
children: theme === "dark" ? /* @__PURE__ */ (0,
|
|
3480
|
+
children: theme === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components11.Icon, { name: "sun", size: 15 }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components11.Icon, { name: "moon", size: 15 })
|
|
2679
3481
|
},
|
|
2680
3482
|
"theme"
|
|
2681
3483
|
),
|
|
2682
|
-
clear: /* @__PURE__ */ (0,
|
|
3484
|
+
clear: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2683
3485
|
"button",
|
|
2684
3486
|
{
|
|
2685
3487
|
type: "button",
|
|
@@ -2687,12 +3489,12 @@ function WorkspaceHeader({
|
|
|
2687
3489
|
title: "\u6E05\u7A7A\u4F1A\u8BDD",
|
|
2688
3490
|
"aria-label": "\u6E05\u7A7A\u4F1A\u8BDD",
|
|
2689
3491
|
onClick: handleClear,
|
|
2690
|
-
children: /* @__PURE__ */ (0,
|
|
3492
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_components11.Icon, { name: "trash", size: 15 })
|
|
2691
3493
|
},
|
|
2692
3494
|
"clear"
|
|
2693
3495
|
)
|
|
2694
3496
|
};
|
|
2695
|
-
const titleNode = editableTitle ? editing ? /* @__PURE__ */ (0,
|
|
3497
|
+
const titleNode = editableTitle ? editing ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2696
3498
|
"input",
|
|
2697
3499
|
{
|
|
2698
3500
|
className: "pactor-chat-workspace__title-input",
|
|
@@ -2709,7 +3511,7 @@ function WorkspaceHeader({
|
|
|
2709
3511
|
}
|
|
2710
3512
|
}
|
|
2711
3513
|
}
|
|
2712
|
-
) : /* @__PURE__ */ (0,
|
|
3514
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2713
3515
|
"button",
|
|
2714
3516
|
{
|
|
2715
3517
|
type: "button",
|
|
@@ -2721,29 +3523,38 @@ function WorkspaceHeader({
|
|
|
2721
3523
|
},
|
|
2722
3524
|
children: displayTitle
|
|
2723
3525
|
}
|
|
2724
|
-
) : /* @__PURE__ */ (0,
|
|
2725
|
-
return /* @__PURE__ */ (0,
|
|
3526
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "pactor-chat-workspace__title", children: title });
|
|
3527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("header", { className: "pactor-chat-workspace__header", children: [
|
|
2726
3528
|
headerStart !== void 0 ? (
|
|
2727
3529
|
// header 位模型 chip(决策 D2):与 title 组成左端组,chip 在前
|
|
2728
|
-
/* @__PURE__ */ (0,
|
|
3530
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "pactor-chat-workspace__header-left", children: [
|
|
2729
3531
|
headerStart,
|
|
2730
3532
|
titleNode
|
|
2731
3533
|
] })
|
|
2732
3534
|
) : titleNode,
|
|
2733
|
-
hasActions ? /* @__PURE__ */ (0,
|
|
2734
|
-
/* @__PURE__ */ (0,
|
|
2735
|
-
|
|
2736
|
-
|
|
3535
|
+
hasActions ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "pactor-chat-workspace__header-right", children: [
|
|
3536
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "pactor-chat-workspace__header-actions", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3537
|
+
ChromeSlot,
|
|
3538
|
+
{
|
|
3539
|
+
fragment: buildHeaderActionsFragment({
|
|
3540
|
+
actions: headerActions,
|
|
3541
|
+
theme
|
|
3542
|
+
}),
|
|
3543
|
+
fallback: headerActions.map((action) => actionButtons[action])
|
|
3544
|
+
}
|
|
3545
|
+
) }),
|
|
3546
|
+
headerExtra !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "pactor-chat-workspace__header-extra", children: headerExtra }) : null
|
|
3547
|
+
] }) : headerExtra !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "pactor-chat-workspace__header-extra", children: headerExtra }) : null
|
|
2737
3548
|
] });
|
|
2738
3549
|
}
|
|
2739
3550
|
|
|
2740
3551
|
// src/chat-composition.tsx
|
|
2741
|
-
var
|
|
3552
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2742
3553
|
function DslNodeSlotInner({ node }) {
|
|
2743
|
-
const { renderChildren } = (0,
|
|
3554
|
+
const { renderChildren } = (0, import_runtime5.useRenderer)();
|
|
2744
3555
|
return renderChildren([node]);
|
|
2745
3556
|
}
|
|
2746
|
-
var DslSlotGuard = class extends
|
|
3557
|
+
var DslSlotGuard = class extends import_react16.Component {
|
|
2747
3558
|
constructor() {
|
|
2748
3559
|
super(...arguments);
|
|
2749
3560
|
this.state = { failed: false };
|
|
@@ -2761,17 +3572,17 @@ var DslSlotGuard = class extends import_react15.Component {
|
|
|
2761
3572
|
}
|
|
2762
3573
|
};
|
|
2763
3574
|
function DslNodeSlot({ node }) {
|
|
2764
|
-
return /* @__PURE__ */ (0,
|
|
3575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DslSlotGuard, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DslNodeSlotInner, { node }) });
|
|
2765
3576
|
}
|
|
2766
3577
|
function isDslNodeValue(value) {
|
|
2767
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && !(0,
|
|
3578
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && !(0, import_react16.isValidElement)(value) && typeof value.type === "string";
|
|
2768
3579
|
}
|
|
2769
3580
|
function resolveSlot(slot) {
|
|
2770
3581
|
if (slot === void 0 || slot === null) {
|
|
2771
3582
|
return void 0;
|
|
2772
3583
|
}
|
|
2773
3584
|
if (isDslNodeValue(slot)) {
|
|
2774
|
-
return /* @__PURE__ */ (0,
|
|
3585
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DslNodeSlot, { node: slot });
|
|
2775
3586
|
}
|
|
2776
3587
|
return slot;
|
|
2777
3588
|
}
|
|
@@ -2801,7 +3612,11 @@ function ChatComposition({
|
|
|
2801
3612
|
messageActions,
|
|
2802
3613
|
onMessageAction,
|
|
2803
3614
|
sidebar,
|
|
3615
|
+
toolbarStart,
|
|
2804
3616
|
toolbarEnd,
|
|
3617
|
+
composerFooter,
|
|
3618
|
+
composerBottom,
|
|
3619
|
+
hideToolbar,
|
|
2805
3620
|
className,
|
|
2806
3621
|
onSend,
|
|
2807
3622
|
artifact,
|
|
@@ -2811,18 +3626,18 @@ function ChatComposition({
|
|
|
2811
3626
|
onArtifact,
|
|
2812
3627
|
onOpenArtifact
|
|
2813
3628
|
}) {
|
|
2814
|
-
const storeRef = (0,
|
|
3629
|
+
const storeRef = (0, import_react16.useRef)(null);
|
|
2815
3630
|
if (storeRef.current === null) {
|
|
2816
3631
|
storeRef.current = services.store ?? services.storeFactory?.() ?? new ConversationStore();
|
|
2817
3632
|
}
|
|
2818
3633
|
const store = storeRef.current;
|
|
2819
|
-
const artifactStoreRef = (0,
|
|
3634
|
+
const artifactStoreRef = (0, import_react16.useRef)(null);
|
|
2820
3635
|
if (artifactStoreRef.current === null) {
|
|
2821
3636
|
artifactStoreRef.current = services.artifactStore ?? new ArtifactStore();
|
|
2822
3637
|
}
|
|
2823
3638
|
const artifactStore = artifactStoreRef.current;
|
|
2824
3639
|
const panelControlled = panelOpen !== void 0 || artifact !== void 0;
|
|
2825
|
-
const storeArtifact = (0,
|
|
3640
|
+
const storeArtifact = (0, import_react16.useSyncExternalStore)(
|
|
2826
3641
|
(listener) => artifactStore.subscribe(listener),
|
|
2827
3642
|
() => artifactStore.get()
|
|
2828
3643
|
);
|
|
@@ -2840,7 +3655,7 @@ function ChatComposition({
|
|
|
2840
3655
|
artifactStore.open(next);
|
|
2841
3656
|
}
|
|
2842
3657
|
};
|
|
2843
|
-
const [attachments, setAttachments] = (0,
|
|
3658
|
+
const [attachments, setAttachments] = (0, import_react16.useState)([]);
|
|
2844
3659
|
const handleAttachFiles = services.onAttachFiles ? (files) => {
|
|
2845
3660
|
void Promise.resolve(services.onAttachFiles(files)).then(
|
|
2846
3661
|
(created) => {
|
|
@@ -2860,24 +3675,38 @@ function ChatComposition({
|
|
|
2860
3675
|
model,
|
|
2861
3676
|
onModelChange
|
|
2862
3677
|
});
|
|
2863
|
-
const headerModelChip = modelPlacement === "header" && modelsEnabled ? /* @__PURE__ */ (0,
|
|
2864
|
-
|
|
3678
|
+
const headerModelChip = modelPlacement === "header" && modelsEnabled ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3679
|
+
ModelSelect,
|
|
2865
3680
|
{
|
|
2866
3681
|
models,
|
|
2867
3682
|
model: currentModel,
|
|
2868
3683
|
onModelChange: handleModelChange
|
|
2869
3684
|
}
|
|
2870
3685
|
) : void 0;
|
|
2871
|
-
const mergedToolbarEnd = services.toolbarEnd !== void 0 || toolbarEnd !== void 0 ? /* @__PURE__ */ (0,
|
|
3686
|
+
const mergedToolbarEnd = services.toolbarEnd !== void 0 || toolbarEnd !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
2872
3687
|
services.toolbarEnd,
|
|
2873
3688
|
toolbarEnd
|
|
2874
3689
|
] }) : void 0;
|
|
2875
|
-
const
|
|
3690
|
+
const mergedToolbarStart = services.toolbarStart !== void 0 || toolbarStart !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
3691
|
+
services.toolbarStart,
|
|
3692
|
+
toolbarStart
|
|
3693
|
+
] }) : void 0;
|
|
3694
|
+
const mergedComposerFooter = services.composerFooter !== void 0 || composerFooter !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
3695
|
+
services.composerFooter,
|
|
3696
|
+
composerFooter
|
|
3697
|
+
] }) : void 0;
|
|
3698
|
+
const mergedComposerBottom = services.composerBottom !== void 0 || composerBottom !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
3699
|
+
services.composerBottom,
|
|
3700
|
+
composerBottom
|
|
3701
|
+
] }) : void 0;
|
|
3702
|
+
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;
|
|
3703
|
+
const renderHeader = showHeader !== false && hasHeaderContent;
|
|
3704
|
+
const workspace = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2876
3705
|
"div",
|
|
2877
3706
|
{
|
|
2878
3707
|
className: `pactor-chat-workspace${className ? ` ${className}` : ""}`,
|
|
2879
3708
|
children: [
|
|
2880
|
-
|
|
3709
|
+
renderHeader ? header ?? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2881
3710
|
WorkspaceHeader,
|
|
2882
3711
|
{
|
|
2883
3712
|
title,
|
|
@@ -2892,7 +3721,7 @@ function ChatComposition({
|
|
|
2892
3721
|
onTitleChange
|
|
2893
3722
|
}
|
|
2894
3723
|
) : null,
|
|
2895
|
-
/* @__PURE__ */ (0,
|
|
3724
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2896
3725
|
ChatView,
|
|
2897
3726
|
{
|
|
2898
3727
|
store,
|
|
@@ -2912,8 +3741,11 @@ function ChatComposition({
|
|
|
2912
3741
|
onAttachmentsChange: setAttachments,
|
|
2913
3742
|
onAttachFiles: handleAttachFiles,
|
|
2914
3743
|
onAttachmentClick: services.onAttachmentClick,
|
|
2915
|
-
toolbarStart:
|
|
3744
|
+
toolbarStart: mergedToolbarStart,
|
|
2916
3745
|
toolbarEnd: mergedToolbarEnd,
|
|
3746
|
+
composerFooter: mergedComposerFooter,
|
|
3747
|
+
composerBottom: mergedComposerBottom,
|
|
3748
|
+
hideToolbar,
|
|
2917
3749
|
onMentionTrigger: services.onMentionTrigger,
|
|
2918
3750
|
onPlusMenu: services.onPlusMenu,
|
|
2919
3751
|
onArtifact,
|
|
@@ -2932,15 +3764,15 @@ function ChatComposition({
|
|
|
2932
3764
|
]
|
|
2933
3765
|
}
|
|
2934
3766
|
);
|
|
2935
|
-
const main = sidebar ? /* @__PURE__ */ (0,
|
|
3767
|
+
const main = sidebar ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(AppShell, { sidebar, children: workspace }) : workspace;
|
|
2936
3768
|
const panelFeatureUsed = artifact !== void 0 || panelOpen !== void 0 || inspector !== void 0 || onPanelClose !== void 0 || onArtifact !== void 0 || onOpenArtifact !== void 0 || services.artifactStore !== void 0;
|
|
2937
3769
|
if (!panelFeatureUsed && !effectivePanelOpen) {
|
|
2938
3770
|
return main;
|
|
2939
3771
|
}
|
|
2940
|
-
return /* @__PURE__ */ (0,
|
|
3772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "pactor-chat-inspector-host", children: [
|
|
2941
3773
|
main,
|
|
2942
|
-
effectivePanelOpen ? /* @__PURE__ */ (0,
|
|
2943
|
-
/* @__PURE__ */ (0,
|
|
3774
|
+
effectivePanelOpen ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
3775
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2944
3776
|
"div",
|
|
2945
3777
|
{
|
|
2946
3778
|
className: "pactor-chat-inspector__scrim",
|
|
@@ -2948,7 +3780,7 @@ function ChatComposition({
|
|
|
2948
3780
|
onClick: handlePanelClose
|
|
2949
3781
|
}
|
|
2950
3782
|
),
|
|
2951
|
-
/* @__PURE__ */ (0,
|
|
3783
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2952
3784
|
ArtifactPanel,
|
|
2953
3785
|
{
|
|
2954
3786
|
artifact: effectiveArtifact,
|
|
@@ -2963,21 +3795,21 @@ function ChatComposition({
|
|
|
2963
3795
|
}
|
|
2964
3796
|
|
|
2965
3797
|
// src/chat-services.tsx
|
|
2966
|
-
var
|
|
2967
|
-
var
|
|
2968
|
-
var ChatServicesContext = (0,
|
|
3798
|
+
var import_react17 = require("react");
|
|
3799
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3800
|
+
var ChatServicesContext = (0, import_react17.createContext)(null);
|
|
2969
3801
|
function ChatServicesProvider({
|
|
2970
3802
|
value,
|
|
2971
3803
|
children
|
|
2972
3804
|
}) {
|
|
2973
|
-
return /* @__PURE__ */ (0,
|
|
3805
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatServicesContext.Provider, { value, children });
|
|
2974
3806
|
}
|
|
2975
3807
|
function useChatServices() {
|
|
2976
|
-
return (0,
|
|
3808
|
+
return (0, import_react17.useContext)(ChatServicesContext);
|
|
2977
3809
|
}
|
|
2978
3810
|
|
|
2979
3811
|
// src/chat-workspace.tsx
|
|
2980
|
-
var
|
|
3812
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
2981
3813
|
function createChatWorkspace(services) {
|
|
2982
3814
|
function ChatWorkspace({
|
|
2983
3815
|
title,
|
|
@@ -2987,7 +3819,11 @@ function createChatWorkspace(services) {
|
|
|
2987
3819
|
conversationId,
|
|
2988
3820
|
params,
|
|
2989
3821
|
sidebar,
|
|
3822
|
+
toolbarStart,
|
|
2990
3823
|
toolbarEnd,
|
|
3824
|
+
composerFooter,
|
|
3825
|
+
composerBottom,
|
|
3826
|
+
hideToolbar,
|
|
2991
3827
|
artifact,
|
|
2992
3828
|
panelOpen,
|
|
2993
3829
|
onPanelClose,
|
|
@@ -3010,7 +3846,7 @@ function createChatWorkspace(services) {
|
|
|
3010
3846
|
onMessageAction,
|
|
3011
3847
|
className
|
|
3012
3848
|
}) {
|
|
3013
|
-
return /* @__PURE__ */ (0,
|
|
3849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ChatServicesProvider, { value: services, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3014
3850
|
ChatComposition,
|
|
3015
3851
|
{
|
|
3016
3852
|
services,
|
|
@@ -3021,15 +3857,17 @@ function createChatWorkspace(services) {
|
|
|
3021
3857
|
conversationId,
|
|
3022
3858
|
params,
|
|
3023
3859
|
className,
|
|
3024
|
-
showHeader: title !== void 0 || services.headerExtra !== void 0 || // header 位模型 chip(决策 D2):仅配置 models 也渲染极简头部
|
|
3025
|
-
modelPlacement === "header" && models !== void 0 && models.length > 0,
|
|
3026
3860
|
headerExtra: services.headerExtra,
|
|
3027
|
-
sidebar: sidebar ? /* @__PURE__ */ (0,
|
|
3028
|
-
|
|
3861
|
+
sidebar: sidebar ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DslNodeSlot, { node: sidebar }) : void 0,
|
|
3862
|
+
toolbarStart: toolbarStart ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DslNodeSlot, { node: toolbarStart }) : void 0,
|
|
3863
|
+
toolbarEnd: toolbarEnd ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DslNodeSlot, { node: toolbarEnd }) : void 0,
|
|
3864
|
+
composerFooter: composerFooter ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DslNodeSlot, { node: composerFooter }) : void 0,
|
|
3865
|
+
composerBottom: composerBottom ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DslNodeSlot, { node: composerBottom }) : void 0,
|
|
3866
|
+
hideToolbar,
|
|
3029
3867
|
artifact,
|
|
3030
3868
|
panelOpen,
|
|
3031
3869
|
onPanelClose,
|
|
3032
|
-
inspector: inspector ? /* @__PURE__ */ (0,
|
|
3870
|
+
inspector: inspector ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DslNodeSlot, { node: inspector }) : void 0,
|
|
3033
3871
|
onArtifact,
|
|
3034
3872
|
onOpenArtifact,
|
|
3035
3873
|
headerActions,
|
|
@@ -3053,11 +3891,37 @@ function createChatWorkspace(services) {
|
|
|
3053
3891
|
}
|
|
3054
3892
|
|
|
3055
3893
|
// src/view/Chat.tsx
|
|
3056
|
-
var
|
|
3057
|
-
var
|
|
3894
|
+
var import_components12 = require("@pactor-app/ui/components");
|
|
3895
|
+
var import_react18 = require("react");
|
|
3896
|
+
|
|
3897
|
+
// src/view/chrome/menu.tsx
|
|
3898
|
+
function buildSidebarMenuFragment(props) {
|
|
3899
|
+
return {
|
|
3900
|
+
requires: ["Menu"],
|
|
3901
|
+
node: {
|
|
3902
|
+
type: "Menu",
|
|
3903
|
+
props: {
|
|
3904
|
+
mode: "inline",
|
|
3905
|
+
selectedKey: props.activeMenuKey,
|
|
3906
|
+
items: props.menu.map((item) => ({
|
|
3907
|
+
key: item.key,
|
|
3908
|
+
label: item.label,
|
|
3909
|
+
...item.icon !== void 0 ? { icon: item.icon } : {},
|
|
3910
|
+
...item.badge !== void 0 ? { badge: item.badge } : {},
|
|
3911
|
+
...item.dot === true ? { dot: true } : {},
|
|
3912
|
+
...item.group !== void 0 ? { group: item.group } : {},
|
|
3913
|
+
...item.disabled === true ? { disabled: true } : {}
|
|
3914
|
+
}))
|
|
3915
|
+
},
|
|
3916
|
+
events: {
|
|
3917
|
+
onSelect: [{ action: "chat.menuSelect", params: { key: "${event}" } }]
|
|
3918
|
+
}
|
|
3919
|
+
}
|
|
3920
|
+
};
|
|
3921
|
+
}
|
|
3058
3922
|
|
|
3059
3923
|
// src/view/ChatShell.tsx
|
|
3060
|
-
var
|
|
3924
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3061
3925
|
function ChatShell({
|
|
3062
3926
|
menu,
|
|
3063
3927
|
activeMenuKey,
|
|
@@ -3069,7 +3933,7 @@ function ChatShell({
|
|
|
3069
3933
|
className,
|
|
3070
3934
|
onMenuSelect
|
|
3071
3935
|
}) {
|
|
3072
|
-
const sidebarContent = resolveSlot(sidebar) ?? (menu && menu.length > 0 ? /* @__PURE__ */ (0,
|
|
3936
|
+
const sidebarContent = resolveSlot(sidebar) ?? (menu && menu.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3073
3937
|
ChatSidebarMenu,
|
|
3074
3938
|
{
|
|
3075
3939
|
menu,
|
|
@@ -3077,7 +3941,7 @@ function ChatShell({
|
|
|
3077
3941
|
onMenuSelect
|
|
3078
3942
|
}
|
|
3079
3943
|
) : null);
|
|
3080
|
-
return /* @__PURE__ */ (0,
|
|
3944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3081
3945
|
AppShell,
|
|
3082
3946
|
{
|
|
3083
3947
|
sidebar: sidebarContent,
|
|
@@ -3094,7 +3958,7 @@ function ChatShellDslAdapter({
|
|
|
3094
3958
|
onMenuSelect,
|
|
3095
3959
|
...rest
|
|
3096
3960
|
}) {
|
|
3097
|
-
return /* @__PURE__ */ (0,
|
|
3961
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3098
3962
|
ChatShell,
|
|
3099
3963
|
{
|
|
3100
3964
|
...rest,
|
|
@@ -3109,39 +3973,45 @@ function registerChatShellComponent(registry) {
|
|
|
3109
3973
|
}
|
|
3110
3974
|
|
|
3111
3975
|
// src/view/Chat.tsx
|
|
3112
|
-
var
|
|
3113
|
-
var MENU_ICONS = {
|
|
3114
|
-
plus: import_lucide_react10.Plus,
|
|
3115
|
-
chat: import_lucide_react10.MessageSquare,
|
|
3116
|
-
history: import_lucide_react10.History,
|
|
3117
|
-
settings: import_lucide_react10.Settings,
|
|
3118
|
-
star: import_lucide_react10.Star,
|
|
3119
|
-
search: import_lucide_react10.Search,
|
|
3120
|
-
user: import_lucide_react10.User,
|
|
3121
|
-
folder: import_lucide_react10.Folder
|
|
3122
|
-
};
|
|
3976
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3123
3977
|
function ChatSidebarMenu({
|
|
3124
3978
|
menu,
|
|
3125
3979
|
activeMenuKey,
|
|
3126
3980
|
onMenuSelect
|
|
3127
3981
|
}) {
|
|
3128
3982
|
const drawer = useSidebarDrawer();
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3983
|
+
const menuRef = (0, import_react18.useRef)(menu);
|
|
3984
|
+
menuRef.current = menu;
|
|
3985
|
+
const selectRef = (0, import_react18.useRef)(onMenuSelect);
|
|
3986
|
+
selectRef.current = onMenuSelect;
|
|
3987
|
+
const drawerRef = (0, import_react18.useRef)(drawer);
|
|
3988
|
+
drawerRef.current = drawer;
|
|
3989
|
+
(0, import_react18.useEffect)(() => {
|
|
3990
|
+
setChatChromeHandlers({
|
|
3991
|
+
menuSelect: (key) => {
|
|
3992
|
+
const item = menuRef.current.find((entry) => entry.key === key);
|
|
3993
|
+
if (item === void 0 || item.disabled === true) {
|
|
3994
|
+
return;
|
|
3995
|
+
}
|
|
3996
|
+
selectRef.current?.(key, item);
|
|
3997
|
+
drawerRef.current?.close();
|
|
3998
|
+
}
|
|
3999
|
+
});
|
|
4000
|
+
}, []);
|
|
4001
|
+
const fallback = (() => {
|
|
4002
|
+
let lastGroup;
|
|
4003
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("nav", { className: "pactor-chat-menu", "aria-label": "\u4F1A\u8BDD\u5BFC\u822A", children: menu.map((item) => {
|
|
4004
|
+
const groupLabel = item.group !== void 0 && item.group !== lastGroup ? item.group : void 0;
|
|
4005
|
+
lastGroup = item.group;
|
|
4006
|
+
const active = item.key === activeMenuKey;
|
|
4007
|
+
const collapsed = drawer?.collapsed === true;
|
|
4008
|
+
const button = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
3138
4009
|
"button",
|
|
3139
4010
|
{
|
|
3140
4011
|
type: "button",
|
|
3141
4012
|
className: `pactor-chat-menu__item${active ? " pactor-chat-menu__item--active" : ""}`,
|
|
3142
4013
|
disabled: item.disabled === true,
|
|
3143
4014
|
"aria-current": active ? "true" : void 0,
|
|
3144
|
-
title: drawer?.collapsed ? item.label : void 0,
|
|
3145
4015
|
onClick: () => {
|
|
3146
4016
|
if (item.disabled) {
|
|
3147
4017
|
return;
|
|
@@ -3150,21 +4020,26 @@ function ChatSidebarMenu({
|
|
|
3150
4020
|
drawer?.close();
|
|
3151
4021
|
},
|
|
3152
4022
|
children: [
|
|
3153
|
-
item.icon !== void 0 ?
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
"aria-hidden": true
|
|
3158
|
-
}
|
|
3159
|
-
) : null,
|
|
3160
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "pactor-chat-menu__label", children: item.label }),
|
|
3161
|
-
item.dot === true ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "pactor-chat-menu__dot", "aria-hidden": true }) : null,
|
|
3162
|
-
item.badge !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "pactor-chat-menu__badge", children: item.badge }) : null
|
|
4023
|
+
item.icon !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "pactor-chat-menu__icon", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_components12.Icon, { name: item.icon, size: 15, strokeWidth: 1.7 }) }) : null,
|
|
4024
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "pactor-chat-menu__label", children: item.label }),
|
|
4025
|
+
item.dot === true ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "pactor-chat-menu__dot", "aria-hidden": true }) : null,
|
|
4026
|
+
item.badge !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "pactor-chat-menu__badge", children: item.badge }) : null
|
|
3163
4027
|
]
|
|
3164
4028
|
}
|
|
3165
|
-
)
|
|
3166
|
-
|
|
3167
|
-
|
|
4029
|
+
);
|
|
4030
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react18.Fragment, { children: [
|
|
4031
|
+
groupLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "pactor-chat-menu__group", children: groupLabel }) : null,
|
|
4032
|
+
collapsed ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_components12.RailTooltip, { label: item.label, children: button }) : button
|
|
4033
|
+
] }, item.key);
|
|
4034
|
+
}) });
|
|
4035
|
+
})();
|
|
4036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4037
|
+
ChromeSlot,
|
|
4038
|
+
{
|
|
4039
|
+
fragment: buildSidebarMenuFragment({ menu, activeMenuKey }),
|
|
4040
|
+
fallback
|
|
4041
|
+
}
|
|
4042
|
+
);
|
|
3168
4043
|
}
|
|
3169
4044
|
function Chat({
|
|
3170
4045
|
title,
|
|
@@ -3177,6 +4052,11 @@ function Chat({
|
|
|
3177
4052
|
menu,
|
|
3178
4053
|
activeMenuKey,
|
|
3179
4054
|
sidebar,
|
|
4055
|
+
toolbarStart,
|
|
4056
|
+
toolbarEnd,
|
|
4057
|
+
composerFooter,
|
|
4058
|
+
composerBottom,
|
|
4059
|
+
hideToolbar,
|
|
3180
4060
|
headerExtra,
|
|
3181
4061
|
header,
|
|
3182
4062
|
headerActions,
|
|
@@ -3204,7 +4084,7 @@ function Chat({
|
|
|
3204
4084
|
onMenuSelect
|
|
3205
4085
|
}) {
|
|
3206
4086
|
const services = useChatServices();
|
|
3207
|
-
(0,
|
|
4087
|
+
(0, import_react18.useEffect)(() => {
|
|
3208
4088
|
if (!services) {
|
|
3209
4089
|
console.warn(
|
|
3210
4090
|
"[@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 +4092,10 @@ function Chat({
|
|
|
3212
4092
|
}
|
|
3213
4093
|
}, [services]);
|
|
3214
4094
|
if (!services) {
|
|
3215
|
-
return /* @__PURE__ */ (0,
|
|
4095
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("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
4096
|
}
|
|
3217
4097
|
const sidebarSlot = resolveSlot(sidebar);
|
|
3218
|
-
const sidebarContent = sidebarSlot ?? (menu && menu.length > 0 ? /* @__PURE__ */ (0,
|
|
4098
|
+
const sidebarContent = sidebarSlot ?? (menu && menu.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3219
4099
|
ChatSidebarMenu,
|
|
3220
4100
|
{
|
|
3221
4101
|
menu,
|
|
@@ -3223,7 +4103,7 @@ function Chat({
|
|
|
3223
4103
|
onMenuSelect
|
|
3224
4104
|
}
|
|
3225
4105
|
) : void 0);
|
|
3226
|
-
return /* @__PURE__ */ (0,
|
|
4106
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3227
4107
|
ChatComposition,
|
|
3228
4108
|
{
|
|
3229
4109
|
services,
|
|
@@ -3234,9 +4114,14 @@ function Chat({
|
|
|
3234
4114
|
conversationId,
|
|
3235
4115
|
params,
|
|
3236
4116
|
className,
|
|
3237
|
-
showHeader
|
|
4117
|
+
showHeader,
|
|
3238
4118
|
header: resolveSlot(header),
|
|
3239
4119
|
headerExtra: resolveSlot(headerExtra) ?? services.headerExtra,
|
|
4120
|
+
toolbarStart: resolveSlot(toolbarStart),
|
|
4121
|
+
toolbarEnd: resolveSlot(toolbarEnd),
|
|
4122
|
+
composerFooter: resolveSlot(composerFooter),
|
|
4123
|
+
composerBottom: resolveSlot(composerBottom),
|
|
4124
|
+
hideToolbar,
|
|
3240
4125
|
headerActions,
|
|
3241
4126
|
editableTitle,
|
|
3242
4127
|
onExport,
|
|
@@ -3278,7 +4163,7 @@ function ChatDslAdapter({
|
|
|
3278
4163
|
onTitleChange,
|
|
3279
4164
|
...rest
|
|
3280
4165
|
}) {
|
|
3281
|
-
return /* @__PURE__ */ (0,
|
|
4166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3282
4167
|
Chat,
|
|
3283
4168
|
{
|
|
3284
4169
|
...rest,
|
|
@@ -3305,11 +4190,11 @@ function registerChatComponent(registry) {
|
|
|
3305
4190
|
}
|
|
3306
4191
|
|
|
3307
4192
|
// src/view/ChatLayout.tsx
|
|
3308
|
-
var
|
|
4193
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3309
4194
|
function ChatLayout({ title, children }) {
|
|
3310
|
-
return /* @__PURE__ */ (0,
|
|
3311
|
-
/* @__PURE__ */ (0,
|
|
3312
|
-
/* @__PURE__ */ (0,
|
|
4195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "pactor-chat-layout", children: [
|
|
4196
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("header", { className: "pactor-chat-layout__header", children: title ?? "Chat" }),
|
|
4197
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("main", { className: "pactor-chat-layout__main", children })
|
|
3313
4198
|
] });
|
|
3314
4199
|
}
|
|
3315
4200
|
var CHAT_LAYOUT_TYPE = "chat";
|
|
@@ -3339,8 +4224,6 @@ function registerChatLayout(layoutRegistry) {
|
|
|
3339
4224
|
ConversationStore,
|
|
3340
4225
|
DEFAULT_CHAT_GREETING,
|
|
3341
4226
|
EmptyState,
|
|
3342
|
-
MENU_ICONS,
|
|
3343
|
-
MESSAGE_ACTION_ICONS,
|
|
3344
4227
|
MessageActions,
|
|
3345
4228
|
MessageBubble,
|
|
3346
4229
|
PartRenderer,
|