@pactor-app/chat 1.1.0 → 1.3.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/README.md +3 -2
- package/dist/index.cjs +152 -96
- package/dist/index.d.cts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +135 -80
- package/package.json +6 -6
- package/styles.css +65 -39
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
applyChatEvent: () => applyChatEvent,
|
|
46
46
|
buildChatScope: () => buildChatScope,
|
|
47
47
|
collectMessageText: () => collectMessageText,
|
|
48
|
+
createChatComponentRegistry: () => createChatComponentRegistry,
|
|
48
49
|
createChatId: () => createChatId,
|
|
49
50
|
createChatRuntime: () => createChatRuntime,
|
|
50
51
|
createChatWorkspace: () => createChatWorkspace,
|
|
@@ -499,6 +500,16 @@ function pairToolTraces(parts) {
|
|
|
499
500
|
}
|
|
500
501
|
|
|
501
502
|
// src/transport.ts
|
|
503
|
+
function markCancelled(store, messageId) {
|
|
504
|
+
const message = store.getMessage(messageId);
|
|
505
|
+
if (!message) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
const parts = message.parts.map(
|
|
509
|
+
(part) => "status" in part && (part.status === "streaming" || part.status === "pending") ? { ...part, status: "ready" } : part
|
|
510
|
+
);
|
|
511
|
+
store.updateMessage(messageId, { status: "cancelled", parts });
|
|
512
|
+
}
|
|
502
513
|
async function runChatTurn(store, transport, input, options = {}) {
|
|
503
514
|
const userMessageId = options.userMessageId ?? createChatId("msg");
|
|
504
515
|
const assistantMessageId = options.assistantMessageId ?? createChatId("msg");
|
|
@@ -521,15 +532,15 @@ async function runChatTurn(store, transport, input, options = {}) {
|
|
|
521
532
|
createdAt: Date.now()
|
|
522
533
|
});
|
|
523
534
|
try {
|
|
524
|
-
for await (const event of transport.send(input)) {
|
|
535
|
+
for await (const event of transport.send(input, { signal: options.signal })) {
|
|
525
536
|
if (options.signal?.aborted) {
|
|
526
|
-
store
|
|
537
|
+
markCancelled(store, assistantMessageId);
|
|
527
538
|
return { userMessageId, assistantMessageId };
|
|
528
539
|
}
|
|
529
540
|
applyChatEvent(store, { ...event, messageId: assistantMessageId });
|
|
530
541
|
}
|
|
531
542
|
if (options.signal?.aborted) {
|
|
532
|
-
store
|
|
543
|
+
markCancelled(store, assistantMessageId);
|
|
533
544
|
return { userMessageId, assistantMessageId };
|
|
534
545
|
}
|
|
535
546
|
const message = store.getMessage(assistantMessageId);
|
|
@@ -857,7 +868,7 @@ function useChatAutoScroll({
|
|
|
857
868
|
|
|
858
869
|
// src/chat-composition.tsx
|
|
859
870
|
var import_runtime5 = require("@pactor-app/runtime");
|
|
860
|
-
var
|
|
871
|
+
var import_react17 = require("react");
|
|
861
872
|
|
|
862
873
|
// src/hooks/use-chat-model.ts
|
|
863
874
|
var import_react3 = require("react");
|
|
@@ -915,13 +926,50 @@ var import_components4 = require("@pactor-app/ui/components");
|
|
|
915
926
|
var import_core3 = require("@pactor-app/core");
|
|
916
927
|
var import_markdown2 = require("@pactor-app/markdown");
|
|
917
928
|
var import_runtime4 = require("@pactor-app/runtime");
|
|
918
|
-
var
|
|
929
|
+
var import_react6 = require("react");
|
|
919
930
|
|
|
920
931
|
// src/view/PartRenderer.tsx
|
|
921
932
|
var import_components2 = require("@pactor-app/ui/components");
|
|
922
933
|
var import_markdown = require("@pactor-app/markdown");
|
|
923
934
|
var import_runtime3 = require("@pactor-app/runtime");
|
|
924
935
|
|
|
936
|
+
// src/hooks/use-throttled-value.ts
|
|
937
|
+
var import_react4 = require("react");
|
|
938
|
+
function useThrottledValue(value, intervalMs, enabled) {
|
|
939
|
+
const [shown, setShown] = (0, import_react4.useState)(value);
|
|
940
|
+
const lastUpdateRef = (0, import_react4.useRef)(0);
|
|
941
|
+
const timerRef = (0, import_react4.useRef)(void 0);
|
|
942
|
+
(0, import_react4.useEffect)(() => {
|
|
943
|
+
if (!enabled) {
|
|
944
|
+
if (timerRef.current) {
|
|
945
|
+
clearTimeout(timerRef.current);
|
|
946
|
+
timerRef.current = void 0;
|
|
947
|
+
}
|
|
948
|
+
setShown(value);
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
const now = Date.now();
|
|
952
|
+
const elapsed = now - lastUpdateRef.current;
|
|
953
|
+
if (elapsed >= intervalMs) {
|
|
954
|
+
lastUpdateRef.current = now;
|
|
955
|
+
setShown(value);
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
timerRef.current = setTimeout(() => {
|
|
959
|
+
lastUpdateRef.current = Date.now();
|
|
960
|
+
setShown(value);
|
|
961
|
+
timerRef.current = void 0;
|
|
962
|
+
}, intervalMs - elapsed);
|
|
963
|
+
return () => {
|
|
964
|
+
if (timerRef.current) {
|
|
965
|
+
clearTimeout(timerRef.current);
|
|
966
|
+
timerRef.current = void 0;
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
}, [value, intervalMs, enabled]);
|
|
970
|
+
return enabled ? shown : value;
|
|
971
|
+
}
|
|
972
|
+
|
|
925
973
|
// src/view/chrome/artifact-card.tsx
|
|
926
974
|
function buildArtifactCardFragment(artifact) {
|
|
927
975
|
return {
|
|
@@ -976,7 +1024,7 @@ function buildArtifactCardFragment(artifact) {
|
|
|
976
1024
|
|
|
977
1025
|
// src/view/chrome/ChromeSlot.tsx
|
|
978
1026
|
var import_runtime2 = require("@pactor-app/runtime");
|
|
979
|
-
var
|
|
1027
|
+
var import_react5 = require("react");
|
|
980
1028
|
|
|
981
1029
|
// src/view/chrome/actions.ts
|
|
982
1030
|
var handlers = {};
|
|
@@ -1110,7 +1158,7 @@ function ChromeSlotInner({
|
|
|
1110
1158
|
const rendered = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "pactor-chat-chrome", children: renderer.renderChildren([fragment.node]) });
|
|
1111
1159
|
return wrap ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: wrap(rendered) }) : rendered;
|
|
1112
1160
|
}
|
|
1113
|
-
var ChromeSlotGuard = class extends
|
|
1161
|
+
var ChromeSlotGuard = class extends import_react5.Component {
|
|
1114
1162
|
constructor() {
|
|
1115
1163
|
super(...arguments);
|
|
1116
1164
|
this.state = { failed: false };
|
|
@@ -1168,7 +1216,8 @@ function SmoothText({ content, streaming }) {
|
|
|
1168
1216
|
}
|
|
1169
1217
|
function SmoothMarkdown({ content, streaming }) {
|
|
1170
1218
|
const shown = useSmoothStreamText(content, streaming);
|
|
1171
|
-
|
|
1219
|
+
const throttled = useThrottledValue(shown, 100, streaming);
|
|
1220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_markdown.MarkdownRenderer, { content: throttled });
|
|
1172
1221
|
}
|
|
1173
1222
|
function PartRenderer({ part, runtime, scope, streaming = false, onOpenArtifact }) {
|
|
1174
1223
|
switch (part.type) {
|
|
@@ -1309,7 +1358,7 @@ function buildPanelHeaderFragment(props) {
|
|
|
1309
1358
|
// src/view/ArtifactPanel.tsx
|
|
1310
1359
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1311
1360
|
function useArtifactRuntime(safeRegistry, user) {
|
|
1312
|
-
return (0,
|
|
1361
|
+
return (0, import_react6.useMemo)(() => {
|
|
1313
1362
|
if (!safeRegistry) {
|
|
1314
1363
|
return void 0;
|
|
1315
1364
|
}
|
|
@@ -1321,7 +1370,7 @@ function useArtifactRuntime(safeRegistry, user) {
|
|
|
1321
1370
|
return createChatRuntime({ safeRegistry: components, user });
|
|
1322
1371
|
}, [safeRegistry, user]);
|
|
1323
1372
|
}
|
|
1324
|
-
var ArtifactDslGuard = class extends
|
|
1373
|
+
var ArtifactDslGuard = class extends import_react6.Component {
|
|
1325
1374
|
constructor() {
|
|
1326
1375
|
super(...arguments);
|
|
1327
1376
|
this.state = { failed: false };
|
|
@@ -1380,13 +1429,13 @@ function ArtifactPanel({
|
|
|
1380
1429
|
className
|
|
1381
1430
|
}) {
|
|
1382
1431
|
const runtime = useArtifactRuntime(safeRegistry, user);
|
|
1383
|
-
const closeRef = (0,
|
|
1432
|
+
const closeRef = (0, import_react6.useRef)(onClose);
|
|
1384
1433
|
closeRef.current = onClose;
|
|
1385
|
-
(0,
|
|
1434
|
+
(0, import_react6.useEffect)(() => {
|
|
1386
1435
|
setChatChromeHandlers({ panelClose: () => closeRef.current?.() });
|
|
1387
1436
|
}, []);
|
|
1388
|
-
const panelRef = (0,
|
|
1389
|
-
const [width, setWidth] = (0,
|
|
1437
|
+
const panelRef = (0, import_react6.useRef)(null);
|
|
1438
|
+
const [width, setWidth] = (0, import_react6.useState)(null);
|
|
1390
1439
|
const handleResizeStart = (event) => {
|
|
1391
1440
|
event.preventDefault();
|
|
1392
1441
|
const panel = panelRef.current;
|
|
@@ -1463,14 +1512,14 @@ function ArtifactPanel({
|
|
|
1463
1512
|
// src/view/ChatView.tsx
|
|
1464
1513
|
var import_components10 = require("@pactor-app/ui/components");
|
|
1465
1514
|
var import_core4 = require("@pactor-app/core");
|
|
1466
|
-
var
|
|
1515
|
+
var import_react15 = require("react");
|
|
1467
1516
|
|
|
1468
1517
|
// src/view/Composer.tsx
|
|
1469
1518
|
var import_components7 = require("@pactor-app/ui/components");
|
|
1470
|
-
var
|
|
1519
|
+
var import_react11 = require("react");
|
|
1471
1520
|
|
|
1472
1521
|
// src/view/AnchoredPopover.tsx
|
|
1473
|
-
var
|
|
1522
|
+
var import_react7 = require("react");
|
|
1474
1523
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1475
1524
|
function AnchoredPopover({
|
|
1476
1525
|
anchorRect,
|
|
@@ -1480,9 +1529,9 @@ function AnchoredPopover({
|
|
|
1480
1529
|
role = "dialog",
|
|
1481
1530
|
sideOffset = 8
|
|
1482
1531
|
}) {
|
|
1483
|
-
const ref = (0,
|
|
1484
|
-
const [position, setPosition] = (0,
|
|
1485
|
-
(0,
|
|
1532
|
+
const ref = (0, import_react7.useRef)(null);
|
|
1533
|
+
const [position, setPosition] = (0, import_react7.useState)(null);
|
|
1534
|
+
(0, import_react7.useLayoutEffect)(() => {
|
|
1486
1535
|
const element = ref.current;
|
|
1487
1536
|
if (!element) return;
|
|
1488
1537
|
const height = element.offsetHeight;
|
|
@@ -1500,7 +1549,7 @@ function AnchoredPopover({
|
|
|
1500
1549
|
}
|
|
1501
1550
|
);
|
|
1502
1551
|
}, [anchorRect, sideOffset]);
|
|
1503
|
-
(0,
|
|
1552
|
+
(0, import_react7.useEffect)(() => {
|
|
1504
1553
|
const onKeyDown = (event) => {
|
|
1505
1554
|
if (event.key !== "Escape") return;
|
|
1506
1555
|
const element = ref.current;
|
|
@@ -1548,7 +1597,7 @@ function AnchoredPopover({
|
|
|
1548
1597
|
|
|
1549
1598
|
// src/view/ModelChip.tsx
|
|
1550
1599
|
var import_components5 = require("@pactor-app/ui/components");
|
|
1551
|
-
var
|
|
1600
|
+
var import_react8 = require("react");
|
|
1552
1601
|
|
|
1553
1602
|
// src/view/chrome/model-select.tsx
|
|
1554
1603
|
function buildModelSelectFragment(props) {
|
|
@@ -1580,8 +1629,8 @@ function ModelChip({
|
|
|
1580
1629
|
model,
|
|
1581
1630
|
onModelChange
|
|
1582
1631
|
}) {
|
|
1583
|
-
const chipRef = (0,
|
|
1584
|
-
const [anchor, setAnchor] = (0,
|
|
1632
|
+
const chipRef = (0, import_react8.useRef)(null);
|
|
1633
|
+
const [anchor, setAnchor] = (0, import_react8.useState)(null);
|
|
1585
1634
|
const currentOption = models.find((option) => option.value === model) ?? models[0];
|
|
1586
1635
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1587
1636
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
@@ -1632,9 +1681,9 @@ function ModelSelect({
|
|
|
1632
1681
|
model,
|
|
1633
1682
|
onModelChange
|
|
1634
1683
|
}) {
|
|
1635
|
-
const changeRef = (0,
|
|
1684
|
+
const changeRef = (0, import_react8.useRef)(onModelChange);
|
|
1636
1685
|
changeRef.current = onModelChange;
|
|
1637
|
-
(0,
|
|
1686
|
+
(0, import_react8.useEffect)(() => {
|
|
1638
1687
|
setChatChromeHandlers({
|
|
1639
1688
|
modelChange: (value) => changeRef.current?.(value)
|
|
1640
1689
|
});
|
|
@@ -1650,13 +1699,13 @@ function ModelSelect({
|
|
|
1650
1699
|
|
|
1651
1700
|
// src/view/chrome/composer.tsx
|
|
1652
1701
|
var import_components6 = require("@pactor-app/ui/components");
|
|
1653
|
-
var
|
|
1702
|
+
var import_react9 = require("react");
|
|
1654
1703
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1655
|
-
var ComposerBridgeContext = (0,
|
|
1704
|
+
var ComposerBridgeContext = (0, import_react9.createContext)(
|
|
1656
1705
|
null
|
|
1657
1706
|
);
|
|
1658
1707
|
function useComposerBridge() {
|
|
1659
|
-
const bridge = (0,
|
|
1708
|
+
const bridge = (0, import_react9.useContext)(ComposerBridgeContext);
|
|
1660
1709
|
if (!bridge) {
|
|
1661
1710
|
throw new Error(
|
|
1662
1711
|
"[@pactor-app/chat] ChatComposer* \u5185\u90E8\u7EC4\u4EF6\u4EC5\u53EF\u5728 Composer chrome \u7247\u6BB5\u5185\u6E32\u67D3"
|
|
@@ -1862,7 +1911,7 @@ function buildComposerFragment(props) {
|
|
|
1862
1911
|
}
|
|
1863
1912
|
|
|
1864
1913
|
// src/view/context-sources.tsx
|
|
1865
|
-
var
|
|
1914
|
+
var import_react10 = require("react");
|
|
1866
1915
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1867
1916
|
function sourceCacheKey(source) {
|
|
1868
1917
|
return `${source.service ?? ""}:${JSON.stringify(source.params ?? {})}`;
|
|
@@ -1898,8 +1947,8 @@ function ContextSourceList({
|
|
|
1898
1947
|
cache,
|
|
1899
1948
|
onSelect
|
|
1900
1949
|
}) {
|
|
1901
|
-
const [resolutions, setResolutions] = (0,
|
|
1902
|
-
(0,
|
|
1950
|
+
const [resolutions, setResolutions] = (0, import_react10.useState)([]);
|
|
1951
|
+
(0, import_react10.useEffect)(() => {
|
|
1903
1952
|
let cancelled = false;
|
|
1904
1953
|
const initial = sources.map(
|
|
1905
1954
|
(source) => source.items ? { status: "ready", items: source.items } : { status: "loading" }
|
|
@@ -1999,26 +2048,26 @@ function Composer({
|
|
|
1999
2048
|
composerFooter,
|
|
2000
2049
|
hideToolbar = false
|
|
2001
2050
|
}) {
|
|
2002
|
-
const [text, setText] = (0,
|
|
2003
|
-
const [dragOver, setDragOver] = (0,
|
|
2004
|
-
const inputRef = (0,
|
|
2005
|
-
const fileInputRef = (0,
|
|
2006
|
-
const plusButtonRef = (0,
|
|
2007
|
-
const composingRef = (0,
|
|
2051
|
+
const [text, setText] = (0, import_react11.useState)("");
|
|
2052
|
+
const [dragOver, setDragOver] = (0, import_react11.useState)(false);
|
|
2053
|
+
const inputRef = (0, import_react11.useRef)(null);
|
|
2054
|
+
const fileInputRef = (0, import_react11.useRef)(null);
|
|
2055
|
+
const plusButtonRef = (0, import_react11.useRef)(null);
|
|
2056
|
+
const composingRef = (0, import_react11.useRef)(false);
|
|
2008
2057
|
const modelChipEnabled = models !== void 0 && models.length > 0;
|
|
2009
|
-
const mentionSources = (0,
|
|
2058
|
+
const mentionSources = (0, import_react11.useMemo)(
|
|
2010
2059
|
() => contextSources?.filter((source) => source.trigger === "@") ?? [],
|
|
2011
2060
|
[contextSources]
|
|
2012
2061
|
);
|
|
2013
|
-
const plusSources = (0,
|
|
2062
|
+
const plusSources = (0, import_react11.useMemo)(
|
|
2014
2063
|
() => contextSources?.filter((source) => source.trigger === "+") ?? [],
|
|
2015
2064
|
[contextSources]
|
|
2016
2065
|
);
|
|
2017
2066
|
const builtinMentionEnabled = onMentionTrigger === void 0 && mentionSources.length > 0;
|
|
2018
2067
|
const builtinPlusEnabled = onPlusMenu === void 0 && plusSources.length > 0;
|
|
2019
|
-
const [mentionState, setMentionState] = (0,
|
|
2020
|
-
const [plusAnchor, setPlusAnchor] = (0,
|
|
2021
|
-
const sourceCacheRef = (0,
|
|
2068
|
+
const [mentionState, setMentionState] = (0, import_react11.useState)(null);
|
|
2069
|
+
const [plusAnchor, setPlusAnchor] = (0, import_react11.useState)(null);
|
|
2070
|
+
const sourceCacheRef = (0, import_react11.useRef)(null);
|
|
2022
2071
|
if (sourceCacheRef.current === null) {
|
|
2023
2072
|
sourceCacheRef.current = /* @__PURE__ */ new Map();
|
|
2024
2073
|
}
|
|
@@ -2037,7 +2086,7 @@ function Composer({
|
|
|
2037
2086
|
setMentionState(null);
|
|
2038
2087
|
setPlusAnchor(null);
|
|
2039
2088
|
};
|
|
2040
|
-
(0,
|
|
2089
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
2041
2090
|
const input = inputRef.current;
|
|
2042
2091
|
if (input) {
|
|
2043
2092
|
input.style.height = "auto";
|
|
@@ -2052,9 +2101,9 @@ function Composer({
|
|
|
2052
2101
|
onSend?.(value);
|
|
2053
2102
|
setText("");
|
|
2054
2103
|
};
|
|
2055
|
-
const sendRef = (0,
|
|
2104
|
+
const sendRef = (0, import_react11.useRef)(send);
|
|
2056
2105
|
sendRef.current = send;
|
|
2057
|
-
(0,
|
|
2106
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
2058
2107
|
setChatChromeHandlers({ composerSubmit: () => sendRef.current() });
|
|
2059
2108
|
}, []);
|
|
2060
2109
|
const syncText = (value, caret, rect) => {
|
|
@@ -2471,15 +2520,15 @@ function EmptyState({
|
|
|
2471
2520
|
}
|
|
2472
2521
|
|
|
2473
2522
|
// src/view/MessageBubble.tsx
|
|
2474
|
-
var
|
|
2523
|
+
var import_react14 = require("react");
|
|
2475
2524
|
|
|
2476
2525
|
// src/view/ActivityTrace.tsx
|
|
2477
2526
|
var import_components8 = require("@pactor-app/ui/components");
|
|
2478
2527
|
var import_markdown3 = require("@pactor-app/markdown");
|
|
2479
|
-
var
|
|
2528
|
+
var import_react12 = require("react");
|
|
2480
2529
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2481
2530
|
function usePinnedCollapse(autoOpen) {
|
|
2482
|
-
const [state, setState] = (0,
|
|
2531
|
+
const [state, setState] = (0, import_react12.useState)("auto");
|
|
2483
2532
|
const open = state === "auto" ? autoOpen : state === "pinned-open";
|
|
2484
2533
|
const toggle = () => {
|
|
2485
2534
|
setState(open ? "pinned-closed" : "pinned-open");
|
|
@@ -2505,8 +2554,8 @@ function statusText(message, mode, toolCount) {
|
|
|
2505
2554
|
}
|
|
2506
2555
|
function useElapsedSeconds(startedAt, active) {
|
|
2507
2556
|
const compute = () => Math.max(0, Math.floor((Date.now() - startedAt) / 1e3));
|
|
2508
|
-
const [elapsed, setElapsed] = (0,
|
|
2509
|
-
(0,
|
|
2557
|
+
const [elapsed, setElapsed] = (0, import_react12.useState)(compute);
|
|
2558
|
+
(0, import_react12.useEffect)(() => {
|
|
2510
2559
|
if (!active) {
|
|
2511
2560
|
setElapsed(compute());
|
|
2512
2561
|
return;
|
|
@@ -2557,7 +2606,7 @@ function formatDetail(value) {
|
|
|
2557
2606
|
}
|
|
2558
2607
|
}
|
|
2559
2608
|
function TraceRow({ entry }) {
|
|
2560
|
-
const [open, setOpen] = (0,
|
|
2609
|
+
const [open, setOpen] = (0, import_react12.useState)(false);
|
|
2561
2610
|
const summary = summarizeArgs(entry.args);
|
|
2562
2611
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2563
2612
|
"div",
|
|
@@ -2594,6 +2643,7 @@ function ThinkingCard({
|
|
|
2594
2643
|
answerPhase
|
|
2595
2644
|
}) {
|
|
2596
2645
|
const partStreaming = part.status === "streaming";
|
|
2646
|
+
const shown = useThrottledValue(part.content, 120, partStreaming);
|
|
2597
2647
|
const { open, toggle } = usePinnedCollapse(partStreaming && !answerPhase);
|
|
2598
2648
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2599
2649
|
"div",
|
|
@@ -2616,7 +2666,7 @@ function ThinkingCard({
|
|
|
2616
2666
|
]
|
|
2617
2667
|
}
|
|
2618
2668
|
),
|
|
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 }) })
|
|
2669
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pactor-chat-thinking__body", children: partStreaming ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pactor-chat-thinking__text", children: shown }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_markdown3.MarkdownRenderer, { content: part.content }) })
|
|
2620
2670
|
]
|
|
2621
2671
|
}
|
|
2622
2672
|
);
|
|
@@ -2630,7 +2680,7 @@ function ActivityTrace({ message }) {
|
|
|
2630
2680
|
);
|
|
2631
2681
|
const answerPhase = mode === "responding" || !streaming;
|
|
2632
2682
|
const { open, toggle } = usePinnedCollapse(!answerPhase);
|
|
2633
|
-
const mountTimeRef = (0,
|
|
2683
|
+
const mountTimeRef = (0, import_react12.useRef)(0);
|
|
2634
2684
|
if (mountTimeRef.current === 0) {
|
|
2635
2685
|
mountTimeRef.current = Date.now();
|
|
2636
2686
|
}
|
|
@@ -2678,7 +2728,7 @@ function ActivityTrace({ message }) {
|
|
|
2678
2728
|
|
|
2679
2729
|
// src/view/MessageActions.tsx
|
|
2680
2730
|
var import_components9 = require("@pactor-app/ui/components");
|
|
2681
|
-
var
|
|
2731
|
+
var import_react13 = require("react");
|
|
2682
2732
|
|
|
2683
2733
|
// src/view/chrome/message-actions.tsx
|
|
2684
2734
|
function buildMessageActionsFragment(args) {
|
|
@@ -2804,13 +2854,13 @@ function MessageActions({
|
|
|
2804
2854
|
callService,
|
|
2805
2855
|
onMessageAction
|
|
2806
2856
|
}) {
|
|
2807
|
-
const [copied, setCopied] = (0,
|
|
2808
|
-
const dispatchRef = (0,
|
|
2857
|
+
const [copied, setCopied] = (0, import_react13.useState)(false);
|
|
2858
|
+
const dispatchRef = (0, import_react13.useRef)(
|
|
2809
2859
|
() => {
|
|
2810
2860
|
}
|
|
2811
2861
|
);
|
|
2812
|
-
const visibleActionsRef = (0,
|
|
2813
|
-
(0,
|
|
2862
|
+
const visibleActionsRef = (0, import_react13.useRef)([]);
|
|
2863
|
+
(0, import_react13.useEffect)(() => {
|
|
2814
2864
|
setMessageActionDispatcher(message.id, (actionId) => {
|
|
2815
2865
|
const action = visibleActionsRef.current.find((a) => a.id === actionId);
|
|
2816
2866
|
if (action) {
|
|
@@ -2924,7 +2974,7 @@ function MessageEditForm({
|
|
|
2924
2974
|
onConfirm,
|
|
2925
2975
|
onCancel
|
|
2926
2976
|
}) {
|
|
2927
|
-
const [text, setText] = (0,
|
|
2977
|
+
const [text, setText] = (0, import_react14.useState)(initialText);
|
|
2928
2978
|
const confirm = () => {
|
|
2929
2979
|
const value = text.trim();
|
|
2930
2980
|
if (!value) {
|
|
@@ -2988,7 +3038,7 @@ function MessageBubble({
|
|
|
2988
3038
|
onMessageAction,
|
|
2989
3039
|
onOpenArtifact
|
|
2990
3040
|
}) {
|
|
2991
|
-
const [editing, setEditing] = (0,
|
|
3041
|
+
const [editing, setEditing] = (0, import_react14.useState)(false);
|
|
2992
3042
|
const bubbleScope = {
|
|
2993
3043
|
conversation: scope?.conversation ?? {},
|
|
2994
3044
|
message: { id: message.id },
|
|
@@ -2996,7 +3046,7 @@ function MessageBubble({
|
|
|
2996
3046
|
};
|
|
2997
3047
|
const streaming = message.status === "streaming";
|
|
2998
3048
|
const live = message.status === "pending" || message.status === "streaming";
|
|
2999
|
-
const wasLiveRef = (0,
|
|
3049
|
+
const wasLiveRef = (0, import_react14.useRef)(live);
|
|
3000
3050
|
if (live) {
|
|
3001
3051
|
wasLiveRef.current = true;
|
|
3002
3052
|
}
|
|
@@ -3103,14 +3153,14 @@ function ChatView({
|
|
|
3103
3153
|
onMessageAction,
|
|
3104
3154
|
composerBottom
|
|
3105
3155
|
}) {
|
|
3106
|
-
const messages = (0,
|
|
3156
|
+
const messages = (0, import_react15.useSyncExternalStore)(
|
|
3107
3157
|
(listener) => store.subscribe(listener),
|
|
3108
3158
|
() => store.getMessages()
|
|
3109
3159
|
);
|
|
3110
3160
|
const isStreaming = messages.some(
|
|
3111
3161
|
(message) => message.status === "pending" || message.status === "streaming"
|
|
3112
3162
|
);
|
|
3113
|
-
const runtime = (0,
|
|
3163
|
+
const runtime = (0, import_react15.useMemo)(() => {
|
|
3114
3164
|
if (!safeRegistry) {
|
|
3115
3165
|
return void 0;
|
|
3116
3166
|
}
|
|
@@ -3127,12 +3177,12 @@ function ChatView({
|
|
|
3127
3177
|
user
|
|
3128
3178
|
});
|
|
3129
3179
|
}, [safeRegistry, capabilities, permission, confirm, user]);
|
|
3130
|
-
const scope = (0,
|
|
3180
|
+
const scope = (0, import_react15.useMemo)(
|
|
3131
3181
|
() => ({ conversation: { id: conversationId }, params }),
|
|
3132
3182
|
[conversationId, params]
|
|
3133
3183
|
);
|
|
3134
|
-
const notifiedArtifactsRef = (0,
|
|
3135
|
-
(0,
|
|
3184
|
+
const notifiedArtifactsRef = (0, import_react15.useRef)(/* @__PURE__ */ new Set());
|
|
3185
|
+
(0, import_react15.useEffect)(() => {
|
|
3136
3186
|
if (!onArtifact) {
|
|
3137
3187
|
return;
|
|
3138
3188
|
}
|
|
@@ -3151,7 +3201,7 @@ function ChatView({
|
|
|
3151
3201
|
});
|
|
3152
3202
|
}
|
|
3153
3203
|
}, [messages, onArtifact]);
|
|
3154
|
-
const abortRef = (0,
|
|
3204
|
+
const abortRef = (0, import_react15.useRef)(null);
|
|
3155
3205
|
const { containerRef, isFollowing, scrollToBottom } = useChatAutoScroll({
|
|
3156
3206
|
messageCount: messages.length,
|
|
3157
3207
|
lastContentLength: lastContentLength(messages),
|
|
@@ -3162,7 +3212,7 @@ function ChatView({
|
|
|
3162
3212
|
model,
|
|
3163
3213
|
onModelChange
|
|
3164
3214
|
});
|
|
3165
|
-
const [contextChips, setContextChips] = (0,
|
|
3215
|
+
const [contextChips, setContextChips] = (0, import_react15.useState)([]);
|
|
3166
3216
|
const handleContextChipsChange = (chips) => {
|
|
3167
3217
|
setContextChips(chips);
|
|
3168
3218
|
onContextsChange?.(chips);
|
|
@@ -3194,11 +3244,11 @@ function ChatView({
|
|
|
3194
3244
|
abortRef.current?.abort();
|
|
3195
3245
|
abortRef.current = null;
|
|
3196
3246
|
};
|
|
3197
|
-
const handleSendRef = (0,
|
|
3247
|
+
const handleSendRef = (0, import_react15.useRef)(handleSend);
|
|
3198
3248
|
handleSendRef.current = handleSend;
|
|
3199
|
-
const onOpenArtifactRef = (0,
|
|
3249
|
+
const onOpenArtifactRef = (0, import_react15.useRef)(onOpenArtifact);
|
|
3200
3250
|
onOpenArtifactRef.current = onOpenArtifact;
|
|
3201
|
-
(0,
|
|
3251
|
+
(0, import_react15.useEffect)(() => {
|
|
3202
3252
|
setChatChromeHandlers({
|
|
3203
3253
|
sendSuggestion: (text) => handleSendRef.current(text),
|
|
3204
3254
|
openArtifact: (artifact) => onOpenArtifactRef.current?.(artifact)
|
|
@@ -3305,7 +3355,7 @@ function ChatView({
|
|
|
3305
3355
|
|
|
3306
3356
|
// src/view/WorkspaceHeader.tsx
|
|
3307
3357
|
var import_components11 = require("@pactor-app/ui/components");
|
|
3308
|
-
var
|
|
3358
|
+
var import_react16 = require("react");
|
|
3309
3359
|
|
|
3310
3360
|
// src/export-markdown.ts
|
|
3311
3361
|
var ROLE_LABELS = {
|
|
@@ -3402,10 +3452,10 @@ function WorkspaceHeader({
|
|
|
3402
3452
|
onTitleChange
|
|
3403
3453
|
}) {
|
|
3404
3454
|
const hasActions = headerActions !== void 0 && headerActions.length > 0;
|
|
3405
|
-
const [overrideTitle, setOverrideTitle] = (0,
|
|
3406
|
-
const [editing, setEditing] = (0,
|
|
3407
|
-
const [draft, setDraft] = (0,
|
|
3408
|
-
const prevTitleRef = (0,
|
|
3455
|
+
const [overrideTitle, setOverrideTitle] = (0, import_react16.useState)(null);
|
|
3456
|
+
const [editing, setEditing] = (0, import_react16.useState)(false);
|
|
3457
|
+
const [draft, setDraft] = (0, import_react16.useState)("");
|
|
3458
|
+
const prevTitleRef = (0, import_react16.useRef)(title);
|
|
3409
3459
|
if (prevTitleRef.current !== title) {
|
|
3410
3460
|
prevTitleRef.current = title;
|
|
3411
3461
|
if (overrideTitle !== null) {
|
|
@@ -3413,7 +3463,7 @@ function WorkspaceHeader({
|
|
|
3413
3463
|
}
|
|
3414
3464
|
}
|
|
3415
3465
|
const displayTitle = overrideTitle ?? title;
|
|
3416
|
-
const [theme, setTheme] = (0,
|
|
3466
|
+
const [theme, setTheme] = (0, import_react16.useState)(readCurrentTheme);
|
|
3417
3467
|
const commitTitle = () => {
|
|
3418
3468
|
setEditing(false);
|
|
3419
3469
|
const next = draft.trim();
|
|
@@ -3440,9 +3490,9 @@ function WorkspaceHeader({
|
|
|
3440
3490
|
store.clear();
|
|
3441
3491
|
onClear?.();
|
|
3442
3492
|
};
|
|
3443
|
-
const handlersRef = (0,
|
|
3493
|
+
const handlersRef = (0, import_react16.useRef)({ handleExport, handleTheme, handleClear });
|
|
3444
3494
|
handlersRef.current = { handleExport, handleTheme, handleClear };
|
|
3445
|
-
(0,
|
|
3495
|
+
(0, import_react16.useEffect)(() => {
|
|
3446
3496
|
setChatChromeHandlers({
|
|
3447
3497
|
headerAction: (name) => {
|
|
3448
3498
|
const handlers2 = handlersRef.current;
|
|
@@ -3554,7 +3604,7 @@ function DslNodeSlotInner({ node }) {
|
|
|
3554
3604
|
const { renderChildren } = (0, import_runtime5.useRenderer)();
|
|
3555
3605
|
return renderChildren([node]);
|
|
3556
3606
|
}
|
|
3557
|
-
var DslSlotGuard = class extends
|
|
3607
|
+
var DslSlotGuard = class extends import_react17.Component {
|
|
3558
3608
|
constructor() {
|
|
3559
3609
|
super(...arguments);
|
|
3560
3610
|
this.state = { failed: false };
|
|
@@ -3575,7 +3625,7 @@ function DslNodeSlot({ node }) {
|
|
|
3575
3625
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DslSlotGuard, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(DslNodeSlotInner, { node }) });
|
|
3576
3626
|
}
|
|
3577
3627
|
function isDslNodeValue(value) {
|
|
3578
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && !(0,
|
|
3628
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && !(0, import_react17.isValidElement)(value) && typeof value.type === "string";
|
|
3579
3629
|
}
|
|
3580
3630
|
function resolveSlot(slot) {
|
|
3581
3631
|
if (slot === void 0 || slot === null) {
|
|
@@ -3626,18 +3676,18 @@ function ChatComposition({
|
|
|
3626
3676
|
onArtifact,
|
|
3627
3677
|
onOpenArtifact
|
|
3628
3678
|
}) {
|
|
3629
|
-
const storeRef = (0,
|
|
3679
|
+
const storeRef = (0, import_react17.useRef)(null);
|
|
3630
3680
|
if (storeRef.current === null) {
|
|
3631
3681
|
storeRef.current = services.store ?? services.storeFactory?.() ?? new ConversationStore();
|
|
3632
3682
|
}
|
|
3633
3683
|
const store = storeRef.current;
|
|
3634
|
-
const artifactStoreRef = (0,
|
|
3684
|
+
const artifactStoreRef = (0, import_react17.useRef)(null);
|
|
3635
3685
|
if (artifactStoreRef.current === null) {
|
|
3636
3686
|
artifactStoreRef.current = services.artifactStore ?? new ArtifactStore();
|
|
3637
3687
|
}
|
|
3638
3688
|
const artifactStore = artifactStoreRef.current;
|
|
3639
3689
|
const panelControlled = panelOpen !== void 0 || artifact !== void 0;
|
|
3640
|
-
const storeArtifact = (0,
|
|
3690
|
+
const storeArtifact = (0, import_react17.useSyncExternalStore)(
|
|
3641
3691
|
(listener) => artifactStore.subscribe(listener),
|
|
3642
3692
|
() => artifactStore.get()
|
|
3643
3693
|
);
|
|
@@ -3655,7 +3705,7 @@ function ChatComposition({
|
|
|
3655
3705
|
artifactStore.open(next);
|
|
3656
3706
|
}
|
|
3657
3707
|
};
|
|
3658
|
-
const [attachments, setAttachments] = (0,
|
|
3708
|
+
const [attachments, setAttachments] = (0, import_react17.useState)([]);
|
|
3659
3709
|
const handleAttachFiles = services.onAttachFiles ? (files) => {
|
|
3660
3710
|
void Promise.resolve(services.onAttachFiles(files)).then(
|
|
3661
3711
|
(created) => {
|
|
@@ -3795,9 +3845,9 @@ function ChatComposition({
|
|
|
3795
3845
|
}
|
|
3796
3846
|
|
|
3797
3847
|
// src/chat-services.tsx
|
|
3798
|
-
var
|
|
3848
|
+
var import_react18 = require("react");
|
|
3799
3849
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3800
|
-
var ChatServicesContext = (0,
|
|
3850
|
+
var ChatServicesContext = (0, import_react18.createContext)(null);
|
|
3801
3851
|
function ChatServicesProvider({
|
|
3802
3852
|
value,
|
|
3803
3853
|
children
|
|
@@ -3805,7 +3855,7 @@ function ChatServicesProvider({
|
|
|
3805
3855
|
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ChatServicesContext.Provider, { value, children });
|
|
3806
3856
|
}
|
|
3807
3857
|
function useChatServices() {
|
|
3808
|
-
return (0,
|
|
3858
|
+
return (0, import_react18.useContext)(ChatServicesContext);
|
|
3809
3859
|
}
|
|
3810
3860
|
|
|
3811
3861
|
// src/chat-workspace.tsx
|
|
@@ -3892,7 +3942,7 @@ function createChatWorkspace(services) {
|
|
|
3892
3942
|
|
|
3893
3943
|
// src/view/Chat.tsx
|
|
3894
3944
|
var import_components12 = require("@pactor-app/ui/components");
|
|
3895
|
-
var
|
|
3945
|
+
var import_react19 = require("react");
|
|
3896
3946
|
|
|
3897
3947
|
// src/view/chrome/menu.tsx
|
|
3898
3948
|
function buildSidebarMenuFragment(props) {
|
|
@@ -3980,13 +4030,13 @@ function ChatSidebarMenu({
|
|
|
3980
4030
|
onMenuSelect
|
|
3981
4031
|
}) {
|
|
3982
4032
|
const drawer = useSidebarDrawer();
|
|
3983
|
-
const menuRef = (0,
|
|
4033
|
+
const menuRef = (0, import_react19.useRef)(menu);
|
|
3984
4034
|
menuRef.current = menu;
|
|
3985
|
-
const selectRef = (0,
|
|
4035
|
+
const selectRef = (0, import_react19.useRef)(onMenuSelect);
|
|
3986
4036
|
selectRef.current = onMenuSelect;
|
|
3987
|
-
const drawerRef = (0,
|
|
4037
|
+
const drawerRef = (0, import_react19.useRef)(drawer);
|
|
3988
4038
|
drawerRef.current = drawer;
|
|
3989
|
-
(0,
|
|
4039
|
+
(0, import_react19.useEffect)(() => {
|
|
3990
4040
|
setChatChromeHandlers({
|
|
3991
4041
|
menuSelect: (key) => {
|
|
3992
4042
|
const item = menuRef.current.find((entry) => entry.key === key);
|
|
@@ -4027,7 +4077,7 @@ function ChatSidebarMenu({
|
|
|
4027
4077
|
]
|
|
4028
4078
|
}
|
|
4029
4079
|
);
|
|
4030
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4080
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react19.Fragment, { children: [
|
|
4031
4081
|
groupLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "pactor-chat-menu__group", children: groupLabel }) : null,
|
|
4032
4082
|
collapsed ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_components12.RailTooltip, { label: item.label, children: button }) : button
|
|
4033
4083
|
] }, item.key);
|
|
@@ -4084,7 +4134,7 @@ function Chat({
|
|
|
4084
4134
|
onMenuSelect
|
|
4085
4135
|
}) {
|
|
4086
4136
|
const services = useChatServices();
|
|
4087
|
-
(0,
|
|
4137
|
+
(0, import_react19.useEffect)(() => {
|
|
4088
4138
|
if (!services) {
|
|
4089
4139
|
console.warn(
|
|
4090
4140
|
"[@pactor-app/chat] Chat \u672A\u68C0\u6D4B\u5230 ChatServicesProvider\uFF1A\u8BF7\u5728\u5E94\u7528\u6839\u90E8\u4EE5 <ChatServicesProvider> \u6CE8\u5165 transport \u7B49\u670D\u52A1"
|
|
@@ -4188,6 +4238,11 @@ function registerChatComponent(registry) {
|
|
|
4188
4238
|
}
|
|
4189
4239
|
registerChatShellComponent(registry);
|
|
4190
4240
|
}
|
|
4241
|
+
function createChatComponentRegistry() {
|
|
4242
|
+
const registry = (0, import_components12.createComponentRegistry)();
|
|
4243
|
+
registerChatComponent(registry);
|
|
4244
|
+
return registry;
|
|
4245
|
+
}
|
|
4191
4246
|
|
|
4192
4247
|
// src/view/ChatLayout.tsx
|
|
4193
4248
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
@@ -4230,6 +4285,7 @@ function registerChatLayout(layoutRegistry) {
|
|
|
4230
4285
|
applyChatEvent,
|
|
4231
4286
|
buildChatScope,
|
|
4232
4287
|
collectMessageText,
|
|
4288
|
+
createChatComponentRegistry,
|
|
4233
4289
|
createChatId,
|
|
4234
4290
|
createChatRuntime,
|
|
4235
4291
|
createChatWorkspace,
|