@ykurilov/agent-chat-react 0.62.0 → 0.63.1
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/CHANGELOG.md +11 -0
- package/dist/{chunk-7DVTSVKQ.js → chunk-Y5HL6THS.js} +260 -182
- package/dist/chunk-Y5HL6THS.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/panel.js +1 -1
- package/dist/types/message-editing/use-message-editing.d.ts +32 -0
- package/dist/types/message-feed.d.ts +3 -1
- package/package.json +1 -1
- package/dist/chunk-7DVTSVKQ.js.map +0 -1
|
@@ -3983,7 +3983,7 @@ function useThinkingStatus(active = true) {
|
|
|
3983
3983
|
|
|
3984
3984
|
// src/agent-chat.tsx
|
|
3985
3985
|
import { getToolName as getToolName5, isToolUIPart as isToolUIPart3 } from "ai";
|
|
3986
|
-
import { Fragment, memo as memo4, useCallback as
|
|
3986
|
+
import { Fragment, memo as memo4, useCallback as useCallback17, useEffect as useEffect14, useId as useId2, useMemo as useMemo16, useRef as useRef17, useState as useState18 } from "react";
|
|
3987
3987
|
|
|
3988
3988
|
// src/expanded-parts.ts
|
|
3989
3989
|
import { useCallback as useCallback6, useMemo as useMemo5, useSyncExternalStore as useSyncExternalStore2 } from "react";
|
|
@@ -4121,7 +4121,7 @@ function isTextField(target) {
|
|
|
4121
4121
|
if (!(target instanceof Element)) return false;
|
|
4122
4122
|
return target.closest("textarea, input, select, [contenteditable]:not([contenteditable='false'])") !== null;
|
|
4123
4123
|
}
|
|
4124
|
-
function MessageFeedView({ scrollRef, messages, renderMessage, keepLastMounted, openAtMessageId, ref }) {
|
|
4124
|
+
function MessageFeedView({ scrollRef, messages, renderMessage, keepLastMounted, openAtMessageId, keepMountedMessageId, ref }) {
|
|
4125
4125
|
const rootRef = useRef7(null);
|
|
4126
4126
|
const virtualizerRef = useRef7(null);
|
|
4127
4127
|
const stuck = useRef7(true);
|
|
@@ -4312,11 +4312,14 @@ function MessageFeedView({ scrollRef, messages, renderMessage, keepLastMounted,
|
|
|
4312
4312
|
}, [scrollRef, stick]);
|
|
4313
4313
|
useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);
|
|
4314
4314
|
const virtualizer = virtualizerRef.current;
|
|
4315
|
+
const editedIndex = keepMountedMessageId === void 0 ? -1 : messages.findIndex((message) => message.id === keepMountedMessageId);
|
|
4315
4316
|
const tailStart = positioned && followingBottom && virtualizer && lastIndex >= 0 ? Math.min(lastIndex, Math.max(0, virtualizer.findItemIndex(virtualizer.scrollOffset - BUFFER_PX))) : lastIndex + 1;
|
|
4316
4317
|
const keepMounted = useMemo6(() => {
|
|
4317
|
-
const kept = Array.from({ length: Math.max(0, lastIndex + 1 - tailStart) }, (_, offset) => tailStart + offset);
|
|
4318
|
-
|
|
4319
|
-
|
|
4318
|
+
const kept = new Set(Array.from({ length: Math.max(0, lastIndex + 1 - tailStart) }, (_, offset) => tailStart + offset));
|
|
4319
|
+
if (keepLastMounted && lastIndex >= 0) kept.add(lastIndex);
|
|
4320
|
+
if (editedIndex >= 0) kept.add(editedIndex);
|
|
4321
|
+
return [...kept].sort((a, b) => a - b);
|
|
4322
|
+
}, [editedIndex, keepLastMounted, lastIndex, tailStart]);
|
|
4320
4323
|
return /* @__PURE__ */ jsx3("div", { ref: rootRef, children: scrollerReady && /* @__PURE__ */ jsx3(
|
|
4321
4324
|
Virtualizer,
|
|
4322
4325
|
{
|
|
@@ -4334,6 +4337,68 @@ function MessageFeedView({ scrollRef, messages, renderMessage, keepLastMounted,
|
|
|
4334
4337
|
}
|
|
4335
4338
|
var MessageFeed = memo(MessageFeedView);
|
|
4336
4339
|
|
|
4340
|
+
// src/message-editing/use-message-editing.ts
|
|
4341
|
+
import { useCallback as useCallback8, useLayoutEffect as useLayoutEffect2, useMemo as useMemo7, useRef as useRef8, useState as useState8 } from "react";
|
|
4342
|
+
function useMessageEditing(messages, { saving, onDraftLost }) {
|
|
4343
|
+
const [editor, setEditor] = useState8(null);
|
|
4344
|
+
const draft = useRef8(null);
|
|
4345
|
+
const messagesRef = useRef8(messages);
|
|
4346
|
+
messagesRef.current = messages;
|
|
4347
|
+
const reportLost = useRef8(onDraftLost);
|
|
4348
|
+
reportLost.current = onDraftLost;
|
|
4349
|
+
useLayoutEffect2(() => {
|
|
4350
|
+
if (!editor || saving.current || messages.some((message) => message.id === editor.id)) return;
|
|
4351
|
+
const same = sameMessage(messages, editor);
|
|
4352
|
+
if (same) {
|
|
4353
|
+
setEditor({ ...editor, id: same.id });
|
|
4354
|
+
return;
|
|
4355
|
+
}
|
|
4356
|
+
const typed = draft.current;
|
|
4357
|
+
draft.current = null;
|
|
4358
|
+
setEditor(null);
|
|
4359
|
+
if (typed !== null && typed.trim().length > 0 && typed !== editor.original) reportLost.current(typed);
|
|
4360
|
+
}, [editor, messages, saving]);
|
|
4361
|
+
const open = useCallback8((messageId) => {
|
|
4362
|
+
const index = messagesRef.current.findIndex((message2) => message2.id === messageId);
|
|
4363
|
+
const message = messagesRef.current[index];
|
|
4364
|
+
if (!message) return;
|
|
4365
|
+
draft.current = null;
|
|
4366
|
+
setEditor({ id: messageId, attempt: 0, original: messageText(message), index });
|
|
4367
|
+
}, []);
|
|
4368
|
+
const close = useCallback8(() => {
|
|
4369
|
+
draft.current = null;
|
|
4370
|
+
setEditor(null);
|
|
4371
|
+
}, []);
|
|
4372
|
+
const type = useCallback8((text) => {
|
|
4373
|
+
draft.current = text;
|
|
4374
|
+
}, []);
|
|
4375
|
+
const refuse = useCallback8((messageId, text, error) => {
|
|
4376
|
+
draft.current = text;
|
|
4377
|
+
setEditor((current) => current && { ...current, id: messageId, attempt: current.attempt + 1, error });
|
|
4378
|
+
}, []);
|
|
4379
|
+
const draftOf = useCallback8((message) => draft.current ?? messageText(message), []);
|
|
4380
|
+
return useMemo7(
|
|
4381
|
+
() => ({
|
|
4382
|
+
id: editor?.id ?? null,
|
|
4383
|
+
attempt: editor?.attempt ?? 0,
|
|
4384
|
+
...editor?.error !== void 0 && { error: editor.error },
|
|
4385
|
+
draftOf,
|
|
4386
|
+
open,
|
|
4387
|
+
type,
|
|
4388
|
+
close,
|
|
4389
|
+
refuse
|
|
4390
|
+
}),
|
|
4391
|
+
[close, draftOf, editor, open, refuse, type]
|
|
4392
|
+
);
|
|
4393
|
+
}
|
|
4394
|
+
function sameMessage(messages, editor) {
|
|
4395
|
+
const isSame = (message) => message?.role === "user" && messageText(message) === editor.original;
|
|
4396
|
+
const atPlace = messages[editor.index];
|
|
4397
|
+
if (isSame(atPlace)) return atPlace;
|
|
4398
|
+
const matches = messages.filter(isSame);
|
|
4399
|
+
return matches.length === 1 ? matches[0] : void 0;
|
|
4400
|
+
}
|
|
4401
|
+
|
|
4337
4402
|
// src/answer-editing/answer-editing.ts
|
|
4338
4403
|
function answerEdited(mark) {
|
|
4339
4404
|
return mark !== void 0 && (mark.textEdited || mark.editedToolCallIds.length > 0);
|
|
@@ -4367,7 +4432,7 @@ ${source}`;
|
|
|
4367
4432
|
}
|
|
4368
4433
|
|
|
4369
4434
|
// src/diagrams/use-diagram-blocks.ts
|
|
4370
|
-
import { useCallback as
|
|
4435
|
+
import { useCallback as useCallback9, useEffect as useEffect7, useId, useMemo as useMemo8, useState as useState9 } from "react";
|
|
4371
4436
|
|
|
4372
4437
|
// src/diagrams/unique-svg-ids.ts
|
|
4373
4438
|
var ID_ATTRIBUTE = /\sid="([^"]+)"/g;
|
|
@@ -4385,11 +4450,11 @@ function withUniqueIds(svg, suffix) {
|
|
|
4385
4450
|
// src/diagrams/use-diagram-blocks.ts
|
|
4386
4451
|
var countMermaidBlocks = (markdown) => splitMermaidBlocks(markdown).filter((segment) => segment.kind === "mermaid").length;
|
|
4387
4452
|
function useDiagramBlocks({ markdown, streaming, messageId, firstBlock, renders, colors, open }) {
|
|
4388
|
-
const blocks =
|
|
4453
|
+
const blocks = useMemo8(
|
|
4389
4454
|
() => splitMermaidBlocks(markdown).flatMap((segment) => segment.kind === "mermaid" ? [segment] : []),
|
|
4390
4455
|
[markdown]
|
|
4391
4456
|
);
|
|
4392
|
-
const [version, setVersion] =
|
|
4457
|
+
const [version, setVersion] = useState9(0);
|
|
4393
4458
|
const insertion = useId();
|
|
4394
4459
|
useEffect7(() => {
|
|
4395
4460
|
let alive = true;
|
|
@@ -4402,7 +4467,7 @@ function useDiagramBlocks({ markdown, streaming, messageId, firstBlock, renders,
|
|
|
4402
4467
|
alive = false;
|
|
4403
4468
|
};
|
|
4404
4469
|
}, [blocks, colors, renders, streaming]);
|
|
4405
|
-
const renderDiagram =
|
|
4470
|
+
const renderDiagram = useCallback9(
|
|
4406
4471
|
(source, blockIndex) => {
|
|
4407
4472
|
const block = blocks[blockIndex];
|
|
4408
4473
|
if (streaming && block && !block.closed) return { state: "streaming" };
|
|
@@ -4413,7 +4478,7 @@ function useDiagramBlocks({ markdown, streaming, messageId, firstBlock, renders,
|
|
|
4413
4478
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- `version`: готов новый рисунок, функция новая, скин рисует блок заново
|
|
4414
4479
|
[blocks, colors, insertion, renders, streaming, version]
|
|
4415
4480
|
);
|
|
4416
|
-
const onOpenDiagram =
|
|
4481
|
+
const onOpenDiagram = useCallback9(
|
|
4417
4482
|
(blockIndex, trigger) => {
|
|
4418
4483
|
const block = blocks[blockIndex];
|
|
4419
4484
|
const result = block && renders.get(block.source, colors);
|
|
@@ -4428,7 +4493,7 @@ function useDiagramBlocks({ markdown, streaming, messageId, firstBlock, renders,
|
|
|
4428
4493
|
}
|
|
4429
4494
|
|
|
4430
4495
|
// src/diagrams/use-diagram-colors.ts
|
|
4431
|
-
import { useMemo as
|
|
4496
|
+
import { useMemo as useMemo9, useSyncExternalStore as useSyncExternalStore3 } from "react";
|
|
4432
4497
|
var FALLBACK_COLORS = {
|
|
4433
4498
|
light: { background: "#ffffff", text: "#1f2328", line: "#6e7781", node: "#f3f4f6", accent: "#0969da", dark: false },
|
|
4434
4499
|
dark: { background: "#16181b", text: "#e6e8eb", line: "#8b949e", node: "#24282d", accent: "#58a6ff", dark: true }
|
|
@@ -4458,21 +4523,21 @@ function usePageDark(enabled) {
|
|
|
4458
4523
|
}
|
|
4459
4524
|
function useDiagramColors(skin, enabled) {
|
|
4460
4525
|
const dark = usePageDark(enabled);
|
|
4461
|
-
return
|
|
4526
|
+
return useMemo9(() => {
|
|
4462
4527
|
if (!enabled) return void 0;
|
|
4463
4528
|
return skin.diagramColors?.(dark) ?? FALLBACK_COLORS[dark ? "dark" : "light"];
|
|
4464
4529
|
}, [dark, enabled, skin]);
|
|
4465
4530
|
}
|
|
4466
4531
|
|
|
4467
4532
|
// src/live-demos/use-live-demo-blocks.tsx
|
|
4468
|
-
import { useCallback as
|
|
4533
|
+
import { useCallback as useCallback10, useMemo as useMemo11, useState as useState11 } from "react";
|
|
4469
4534
|
|
|
4470
4535
|
// src/live-demos/live-demo-frame.tsx
|
|
4471
|
-
import { memo as memo2, useEffect as useEffect8, useMemo as
|
|
4536
|
+
import { memo as memo2, useEffect as useEffect8, useMemo as useMemo10, useRef as useRef9, useState as useState10 } from "react";
|
|
4472
4537
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
4473
4538
|
var INITIAL_HEIGHT = 160;
|
|
4474
4539
|
function useTwoThirdsOfScreen() {
|
|
4475
|
-
const [limit, setLimit] =
|
|
4540
|
+
const [limit, setLimit] = useState10(() => Math.round(window.innerHeight * 2 / 3));
|
|
4476
4541
|
useEffect8(() => {
|
|
4477
4542
|
const update = () => setLimit(Math.round(window.innerHeight * 2 / 3));
|
|
4478
4543
|
window.addEventListener("resize", update);
|
|
@@ -4481,15 +4546,15 @@ function useTwoThirdsOfScreen() {
|
|
|
4481
4546
|
return limit;
|
|
4482
4547
|
}
|
|
4483
4548
|
var LiveDemoFrame = memo2(function LiveDemoFrame2({ source, colors, title, onLeftPage }) {
|
|
4484
|
-
const srcDoc =
|
|
4549
|
+
const srcDoc = useMemo10(() => liveDemoDocument(source, colors), [source, colors]);
|
|
4485
4550
|
return /* @__PURE__ */ jsx4(Frame, { srcDoc, dark: colors.dark, title, onLeftPage }, srcDoc);
|
|
4486
4551
|
});
|
|
4487
4552
|
function Frame({ srcDoc, dark, title, onLeftPage }) {
|
|
4488
|
-
const frame =
|
|
4489
|
-
const loads =
|
|
4490
|
-
const [height, setHeight] =
|
|
4553
|
+
const frame = useRef9(null);
|
|
4554
|
+
const loads = useRef9(0);
|
|
4555
|
+
const [height, setHeight] = useState10(INITIAL_HEIGHT);
|
|
4491
4556
|
const limit = useTwoThirdsOfScreen();
|
|
4492
|
-
const leftPage =
|
|
4557
|
+
const leftPage = useRef9(onLeftPage);
|
|
4493
4558
|
leftPage.current = onLeftPage;
|
|
4494
4559
|
useEffect8(() => {
|
|
4495
4560
|
const onMessage = (event) => {
|
|
@@ -4522,19 +4587,19 @@ function Frame({ srcDoc, dark, title, onLeftPage }) {
|
|
|
4522
4587
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
4523
4588
|
function useDemoColors(skin, enabled) {
|
|
4524
4589
|
const dark = usePageDark(enabled);
|
|
4525
|
-
return
|
|
4590
|
+
return useMemo11(() => {
|
|
4526
4591
|
if (!enabled) return void 0;
|
|
4527
4592
|
return skin.demoColors?.(dark) ?? FALLBACK_DEMO_COLORS[dark ? "dark" : "light"];
|
|
4528
4593
|
}, [dark, enabled, skin]);
|
|
4529
4594
|
}
|
|
4530
4595
|
function useLiveDemoBlocks({ markdown, streaming, colors, blocked }) {
|
|
4531
4596
|
const labels = useChatLabels();
|
|
4532
|
-
const blocks =
|
|
4597
|
+
const blocks = useMemo11(
|
|
4533
4598
|
() => colors ? splitAnswerFences(markdown, { demos: true }).flatMap((segment) => segment.kind === "demo" ? [segment] : []) : [],
|
|
4534
4599
|
[colors, markdown]
|
|
4535
4600
|
);
|
|
4536
|
-
const [leftPage, setLeftPage] =
|
|
4537
|
-
const renderDemo =
|
|
4601
|
+
const [leftPage, setLeftPage] = useState11(() => /* @__PURE__ */ new Set());
|
|
4602
|
+
const renderDemo = useCallback10(
|
|
4538
4603
|
(source, blockIndex) => {
|
|
4539
4604
|
if (blocks[blockIndex]?.closed === false) return streaming ? { state: "streaming" } : { state: "code", source, reason: "unfinished" };
|
|
4540
4605
|
if (!liveDemoFits(source)) return { state: "code", source, reason: "tooLarge" };
|
|
@@ -4607,12 +4672,12 @@ function escapeLinkText(text) {
|
|
|
4607
4672
|
}
|
|
4608
4673
|
|
|
4609
4674
|
// src/subject-chat/subject-chat-loading.tsx
|
|
4610
|
-
import { useRef as
|
|
4675
|
+
import { useRef as useRef10 } from "react";
|
|
4611
4676
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
4612
4677
|
var nothing = () => {
|
|
4613
4678
|
};
|
|
4614
4679
|
function SubjectChatLoading({ skin }) {
|
|
4615
|
-
const scrollRef =
|
|
4680
|
+
const scrollRef = useRef10(null);
|
|
4616
4681
|
return /* @__PURE__ */ jsx6(
|
|
4617
4682
|
skin.Layout,
|
|
4618
4683
|
{
|
|
@@ -4625,15 +4690,15 @@ function SubjectChatLoading({ skin }) {
|
|
|
4625
4690
|
}
|
|
4626
4691
|
|
|
4627
4692
|
// src/subject-chat/use-subject-chat-id.ts
|
|
4628
|
-
import { useCallback as
|
|
4693
|
+
import { useCallback as useCallback11, useEffect as useEffect9, useRef as useRef11, useState as useState12 } from "react";
|
|
4629
4694
|
function useSubjectChatId(api, subject, onAppRefusal) {
|
|
4630
|
-
const [attempt, setAttempt] =
|
|
4631
|
-
const onAppRefusalRef =
|
|
4695
|
+
const [attempt, setAttempt] = useState12(0);
|
|
4696
|
+
const onAppRefusalRef = useRef11(onAppRefusal);
|
|
4632
4697
|
onAppRefusalRef.current = onAppRefusal;
|
|
4633
4698
|
const request2 = `${attempt}
|
|
4634
4699
|
${api}
|
|
4635
4700
|
${subject}`;
|
|
4636
|
-
const [found, setFound] =
|
|
4701
|
+
const [found, setFound] = useState12(null);
|
|
4637
4702
|
useEffect9(() => {
|
|
4638
4703
|
const controller = new AbortController();
|
|
4639
4704
|
const settle = (state) => {
|
|
@@ -4662,7 +4727,7 @@ ${subject}`;
|
|
|
4662
4727
|
})();
|
|
4663
4728
|
return () => controller.abort();
|
|
4664
4729
|
}, [api, subject, request2]);
|
|
4665
|
-
const retry =
|
|
4730
|
+
const retry = useCallback11(() => setAttempt((value) => value + 1), []);
|
|
4666
4731
|
return { ...found?.request === request2 ? found.state : { state: "loading" }, retry };
|
|
4667
4732
|
}
|
|
4668
4733
|
|
|
@@ -4709,20 +4774,20 @@ function generatedViewerItems(describe) {
|
|
|
4709
4774
|
}
|
|
4710
4775
|
|
|
4711
4776
|
// src/media-viewer/use-media-viewer.ts
|
|
4712
|
-
import { useCallback as
|
|
4777
|
+
import { useCallback as useCallback12, useEffect as useEffect10, useMemo as useMemo12, useRef as useRef12, useState as useState13 } from "react";
|
|
4713
4778
|
var ENTRY_FIELD = "agentChatViewer";
|
|
4714
4779
|
var entryCounter = 0;
|
|
4715
4780
|
var currentEntry = () => history.state?.[ENTRY_FIELD];
|
|
4716
4781
|
function useMediaViewer({ getItems, resetKey }) {
|
|
4717
|
-
const [opened, setOpened] =
|
|
4718
|
-
const trigger =
|
|
4719
|
-
const openedRef =
|
|
4782
|
+
const [opened, setOpened] = useState13(null);
|
|
4783
|
+
const trigger = useRef12(null);
|
|
4784
|
+
const openedRef = useRef12(opened);
|
|
4720
4785
|
openedRef.current = opened;
|
|
4721
|
-
const getItemsRef =
|
|
4786
|
+
const getItemsRef = useRef12(getItems);
|
|
4722
4787
|
getItemsRef.current = getItems;
|
|
4723
|
-
const items =
|
|
4788
|
+
const items = useMemo12(() => opened ? opened.items ?? getItems() : [], [opened, getItems]);
|
|
4724
4789
|
const index = opened ? items.findIndex((item) => item.key === opened.key) : -1;
|
|
4725
|
-
const close =
|
|
4790
|
+
const close = useCallback12((fromHistory, returnFocus) => {
|
|
4726
4791
|
const current = openedRef.current;
|
|
4727
4792
|
if (!current) return;
|
|
4728
4793
|
openedRef.current = null;
|
|
@@ -4732,7 +4797,7 @@ function useMediaViewer({ getItems, resetKey }) {
|
|
|
4732
4797
|
trigger.current = null;
|
|
4733
4798
|
if (returnFocus && source?.isConnected) source.focus();
|
|
4734
4799
|
}, []);
|
|
4735
|
-
const open =
|
|
4800
|
+
const open = useCallback12(
|
|
4736
4801
|
(key, source, own) => {
|
|
4737
4802
|
if (!(own ?? getItemsRef.current()).some((item) => item.key === key)) return;
|
|
4738
4803
|
trigger.current = source;
|
|
@@ -4758,14 +4823,14 @@ function useMediaViewer({ getItems, resetKey }) {
|
|
|
4758
4823
|
useEffect10(() => {
|
|
4759
4824
|
if (gone) close(false, true);
|
|
4760
4825
|
}, [gone, close]);
|
|
4761
|
-
const shownFor =
|
|
4826
|
+
const shownFor = useRef12(resetKey);
|
|
4762
4827
|
useEffect10(() => {
|
|
4763
4828
|
if (shownFor.current === resetKey) return;
|
|
4764
4829
|
shownFor.current = resetKey;
|
|
4765
4830
|
close(false, false);
|
|
4766
4831
|
}, [resetKey, close]);
|
|
4767
4832
|
useEffect10(() => () => close(false, false), [close]);
|
|
4768
|
-
const onIndexChange =
|
|
4833
|
+
const onIndexChange = useCallback12(
|
|
4769
4834
|
(next) => {
|
|
4770
4835
|
const item = items[next];
|
|
4771
4836
|
const current = openedRef.current;
|
|
@@ -4776,8 +4841,8 @@ function useMediaViewer({ getItems, resetKey }) {
|
|
|
4776
4841
|
},
|
|
4777
4842
|
[items]
|
|
4778
4843
|
);
|
|
4779
|
-
const onClose =
|
|
4780
|
-
const viewer =
|
|
4844
|
+
const onClose = useCallback12(() => close(false, true), [close]);
|
|
4845
|
+
const viewer = useMemo12(
|
|
4781
4846
|
() => opened && index >= 0 ? { items, index, onIndexChange, onClose } : null,
|
|
4782
4847
|
[opened, index, items, onIndexChange, onClose]
|
|
4783
4848
|
);
|
|
@@ -5034,7 +5099,7 @@ function suggestedRepliesOf(messages, busy) {
|
|
|
5034
5099
|
}
|
|
5035
5100
|
|
|
5036
5101
|
// src/widgets/widget-part.tsx
|
|
5037
|
-
import { memo as memo3, useCallback as
|
|
5102
|
+
import { memo as memo3, useCallback as useCallback13, useMemo as useMemo13, useState as useState14 } from "react";
|
|
5038
5103
|
|
|
5039
5104
|
// src/widgets/custom-widget-guard.tsx
|
|
5040
5105
|
import { Component } from "react";
|
|
@@ -5063,12 +5128,12 @@ var WidgetPart = memo3(function WidgetPart2({
|
|
|
5063
5128
|
onAnswer
|
|
5064
5129
|
}) {
|
|
5065
5130
|
const labels = useChatLabels();
|
|
5066
|
-
const messages =
|
|
5067
|
-
const [fieldErrors, setFieldErrors] =
|
|
5131
|
+
const messages = useMemo13(() => formCheckMessages(labels.widgets), [labels.widgets]);
|
|
5132
|
+
const [fieldErrors, setFieldErrors] = useState14({});
|
|
5068
5133
|
const toolCallId = call.toolCallId;
|
|
5069
|
-
const answer =
|
|
5070
|
-
const [crashed, setCrashed] =
|
|
5071
|
-
const onCrash =
|
|
5134
|
+
const answer = useCallback13((value) => onAnswer(toolCallId, value), [onAnswer, toolCallId]);
|
|
5135
|
+
const [crashed, setCrashed] = useState14(false);
|
|
5136
|
+
const onCrash = useCallback13(() => setCrashed(true), []);
|
|
5072
5137
|
const active = call.state === "pending";
|
|
5073
5138
|
const content = Custom && !crashed && /* @__PURE__ */ jsx7(CustomWidgetGuard, { onCrash, children: /* @__PURE__ */ jsx7(
|
|
5074
5139
|
Custom,
|
|
@@ -5096,7 +5161,7 @@ var WidgetPart = memo3(function WidgetPart2({
|
|
|
5096
5161
|
});
|
|
5097
5162
|
|
|
5098
5163
|
// src/use-voice-dictation.ts
|
|
5099
|
-
import { useCallback as
|
|
5164
|
+
import { useCallback as useCallback14, useEffect as useEffect11, useRef as useRef13, useState as useState15 } from "react";
|
|
5100
5165
|
|
|
5101
5166
|
// src/dictation-field.ts
|
|
5102
5167
|
function createDictationField(startValue) {
|
|
@@ -5147,17 +5212,17 @@ function createDictationField(startValue) {
|
|
|
5147
5212
|
// src/use-voice-dictation.ts
|
|
5148
5213
|
function useVoiceDictation({ voice, value, setValue, chatId }) {
|
|
5149
5214
|
const labels = useChatLabels();
|
|
5150
|
-
const [state, setState] =
|
|
5151
|
-
const [error, setError] =
|
|
5152
|
-
const [polishing, setPolishing] =
|
|
5153
|
-
const session =
|
|
5154
|
-
const field =
|
|
5155
|
-
const run =
|
|
5156
|
-
const latestValue =
|
|
5157
|
-
const knownValue =
|
|
5158
|
-
const pendingWrites =
|
|
5215
|
+
const [state, setState] = useState15("idle");
|
|
5216
|
+
const [error, setError] = useState15();
|
|
5217
|
+
const [polishing, setPolishing] = useState15(false);
|
|
5218
|
+
const session = useRef13(null);
|
|
5219
|
+
const field = useRef13(null);
|
|
5220
|
+
const run = useRef13(0);
|
|
5221
|
+
const latestValue = useRef13(value);
|
|
5222
|
+
const knownValue = useRef13(value);
|
|
5223
|
+
const pendingWrites = useRef13([]);
|
|
5159
5224
|
latestValue.current = value;
|
|
5160
|
-
const drop =
|
|
5225
|
+
const drop = useCallback14(() => {
|
|
5161
5226
|
run.current += 1;
|
|
5162
5227
|
session.current?.cancel();
|
|
5163
5228
|
session.current = null;
|
|
@@ -5178,7 +5243,7 @@ function useVoiceDictation({ voice, value, setValue, chatId }) {
|
|
|
5178
5243
|
setError(void 0);
|
|
5179
5244
|
}, [value]);
|
|
5180
5245
|
useEffect11(() => drop, [chatId, drop]);
|
|
5181
|
-
const start =
|
|
5246
|
+
const start = useCallback14(() => {
|
|
5182
5247
|
if (!voice) return;
|
|
5183
5248
|
const mine = ++run.current;
|
|
5184
5249
|
const dictation = createDictationField(latestValue.current);
|
|
@@ -5224,7 +5289,7 @@ function useVoiceDictation({ voice, value, setValue, chatId }) {
|
|
|
5224
5289
|
{ chatId, ...labels.locale && { language: labels.locale } }
|
|
5225
5290
|
);
|
|
5226
5291
|
}, [voice, setValue, chatId, labels.locale]);
|
|
5227
|
-
const onToggle =
|
|
5292
|
+
const onToggle = useCallback14(() => {
|
|
5228
5293
|
if (state === "idle") start();
|
|
5229
5294
|
else if (state === "connecting") drop();
|
|
5230
5295
|
else if (state === "listening") {
|
|
@@ -5232,7 +5297,7 @@ function useVoiceDictation({ voice, value, setValue, chatId }) {
|
|
|
5232
5297
|
session.current?.stop();
|
|
5233
5298
|
}
|
|
5234
5299
|
}, [state, start, drop]);
|
|
5235
|
-
const cancel =
|
|
5300
|
+
const cancel = useCallback14(() => {
|
|
5236
5301
|
if (session.current) drop();
|
|
5237
5302
|
}, [drop]);
|
|
5238
5303
|
const view = voice ? { state, onToggle, ...polishing && { polishing }, ...error && { error: voiceErrorText(labels.voiceErrors, error.kind, error.details) } } : void 0;
|
|
@@ -5241,33 +5306,33 @@ function useVoiceDictation({ voice, value, setValue, chatId }) {
|
|
|
5241
5306
|
|
|
5242
5307
|
// src/use-voice-dialog.ts
|
|
5243
5308
|
import { getToolName as getToolName4, isToolUIPart as isToolUIPart2 } from "ai";
|
|
5244
|
-
import { useCallback as
|
|
5309
|
+
import { useCallback as useCallback15, useEffect as useEffect12, useMemo as useMemo14, useRef as useRef14, useState as useState16 } from "react";
|
|
5245
5310
|
var finished = (view) => view.state === "off" || view.state === "error";
|
|
5246
5311
|
function useVoiceDialog({ engine, chatId, chat, videos }) {
|
|
5247
5312
|
const labels = useChatLabels();
|
|
5248
|
-
const labelsRef =
|
|
5313
|
+
const labelsRef = useRef14(labels);
|
|
5249
5314
|
labelsRef.current = labels;
|
|
5250
|
-
const [engineView, setEngineView] =
|
|
5251
|
-
const chatRef =
|
|
5315
|
+
const [engineView, setEngineView] = useState16(null);
|
|
5316
|
+
const chatRef = useRef14(chat);
|
|
5252
5317
|
chatRef.current = chat;
|
|
5253
|
-
const active =
|
|
5254
|
-
const generation =
|
|
5255
|
-
const textListeners =
|
|
5256
|
-
const endListeners =
|
|
5257
|
-
const delivered =
|
|
5258
|
-
const spokenWidgets =
|
|
5259
|
-
const spokenVideos =
|
|
5260
|
-
const videosRef =
|
|
5318
|
+
const active = useRef14(false);
|
|
5319
|
+
const generation = useRef14(0);
|
|
5320
|
+
const textListeners = useRef14(/* @__PURE__ */ new Set());
|
|
5321
|
+
const endListeners = useRef14(/* @__PURE__ */ new Set());
|
|
5322
|
+
const delivered = useRef14(/* @__PURE__ */ new Map());
|
|
5323
|
+
const spokenWidgets = useRef14(/* @__PURE__ */ new Set());
|
|
5324
|
+
const spokenVideos = useRef14(/* @__PURE__ */ new Set());
|
|
5325
|
+
const videosRef = useRef14(videos);
|
|
5261
5326
|
videosRef.current = videos;
|
|
5262
|
-
const activityListeners =
|
|
5263
|
-
const announced =
|
|
5264
|
-
const emitActivity =
|
|
5327
|
+
const activityListeners = useRef14(/* @__PURE__ */ new Set());
|
|
5328
|
+
const announced = useRef14(/* @__PURE__ */ new Map());
|
|
5329
|
+
const emitActivity = useCallback15((activity) => {
|
|
5265
5330
|
for (const listener of [...activityListeners.current]) listener(activity);
|
|
5266
5331
|
}, []);
|
|
5267
|
-
const emitEnd =
|
|
5332
|
+
const emitEnd = useCallback15((end) => {
|
|
5268
5333
|
for (const listener of [...endListeners.current]) listener(end);
|
|
5269
5334
|
}, []);
|
|
5270
|
-
const bridge =
|
|
5335
|
+
const bridge = useMemo14(
|
|
5271
5336
|
() => ({
|
|
5272
5337
|
send: (text, options) => {
|
|
5273
5338
|
if (!chatRef.current.sendVoiceMessage(text, options)) queueMicrotask(() => emitEnd({ messageId: "", status: "error" }));
|
|
@@ -5349,7 +5414,7 @@ function useVoiceDialog({ engine, chatId, chat, videos }) {
|
|
|
5349
5414
|
}
|
|
5350
5415
|
if (parts.size > 0) known.set(last.id, parts);
|
|
5351
5416
|
}, [chat.messages, emitActivity]);
|
|
5352
|
-
const wasBusy =
|
|
5417
|
+
const wasBusy = useRef14(chat.busy);
|
|
5353
5418
|
useEffect12(() => {
|
|
5354
5419
|
const ended = wasBusy.current && !chat.busy;
|
|
5355
5420
|
wasBusy.current = chat.busy;
|
|
@@ -5373,7 +5438,7 @@ function useVoiceDialog({ engine, chatId, chat, videos }) {
|
|
|
5373
5438
|
},
|
|
5374
5439
|
[engine, chatId]
|
|
5375
5440
|
);
|
|
5376
|
-
const toggle =
|
|
5441
|
+
const toggle = useCallback15(() => {
|
|
5377
5442
|
if (!engine) return;
|
|
5378
5443
|
if (engineView?.state === "error") {
|
|
5379
5444
|
generation.current += 1;
|
|
@@ -5407,7 +5472,7 @@ function useVoiceDialog({ engine, chatId, chat, videos }) {
|
|
|
5407
5472
|
engine.close();
|
|
5408
5473
|
setEngineView(null);
|
|
5409
5474
|
}, [bridge, chatId, engine, engineView]);
|
|
5410
|
-
return
|
|
5475
|
+
return useMemo14(() => {
|
|
5411
5476
|
if (!engine) return void 0;
|
|
5412
5477
|
const view = engineView ?? { state: "off", speechAvailable: true, onToggle: toggle };
|
|
5413
5478
|
return { ...view, onToggle: toggle };
|
|
@@ -5481,11 +5546,11 @@ function widgetPhrase(call, labels) {
|
|
|
5481
5546
|
}
|
|
5482
5547
|
|
|
5483
5548
|
// src/message-actions.ts
|
|
5484
|
-
import { useCallback as
|
|
5549
|
+
import { useCallback as useCallback16, useMemo as useMemo15, useRef as useRef15, useState as useState17 } from "react";
|
|
5485
5550
|
function useMessageActionRuns(chatId) {
|
|
5486
|
-
const [running, setRunning] =
|
|
5487
|
-
const runningRef =
|
|
5488
|
-
const run =
|
|
5551
|
+
const [running, setRunning] = useState17(() => /* @__PURE__ */ new Map());
|
|
5552
|
+
const runningRef = useRef15(/* @__PURE__ */ new Set());
|
|
5553
|
+
const run = useCallback16(
|
|
5489
5554
|
(action, message, text) => {
|
|
5490
5555
|
const key = `${message.id}
|
|
5491
5556
|
${action.id}`;
|
|
@@ -5507,7 +5572,7 @@ ${action.id}`;
|
|
|
5507
5572
|
},
|
|
5508
5573
|
[chatId]
|
|
5509
5574
|
);
|
|
5510
|
-
return
|
|
5575
|
+
return useMemo15(() => ({ running, run }), [running, run]);
|
|
5511
5576
|
}
|
|
5512
5577
|
function withRunning(current, messageId, actionId, on) {
|
|
5513
5578
|
const ids = current.get(messageId) ?? [];
|
|
@@ -5525,14 +5590,14 @@ function renderComposerActions(actions, helper) {
|
|
|
5525
5590
|
}
|
|
5526
5591
|
|
|
5527
5592
|
// src/turn-finished.ts
|
|
5528
|
-
import { useEffect as useEffect13, useRef as
|
|
5593
|
+
import { useEffect as useEffect13, useRef as useRef16 } from "react";
|
|
5529
5594
|
function useTurnFinishedReport(chatId, busy, messages, onTurnFinished) {
|
|
5530
|
-
const report =
|
|
5595
|
+
const report = useRef16(onTurnFinished);
|
|
5531
5596
|
report.current = onTurnFinished;
|
|
5532
|
-
const turnRunning =
|
|
5533
|
-
const latest =
|
|
5597
|
+
const turnRunning = useRef16(false);
|
|
5598
|
+
const latest = useRef16(messages);
|
|
5534
5599
|
latest.current = messages;
|
|
5535
|
-
const finishedBefore =
|
|
5600
|
+
const finishedBefore = useRef16(/* @__PURE__ */ new Set());
|
|
5536
5601
|
const last = messages.at(-1);
|
|
5537
5602
|
const answerId = last?.role === "assistant" ? last.id : void 0;
|
|
5538
5603
|
const answerStatus = last?.role === "assistant" ? last.metadata?.status : void 0;
|
|
@@ -5743,7 +5808,7 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
|
|
|
5743
5808
|
const attachments = attachmentsPlugin?.useController({ api, chatId, modelSeesImages: chatModelSeesImages });
|
|
5744
5809
|
const describeFiles = attachments?.describe;
|
|
5745
5810
|
const imageClients = useSameList(imageClientsOf(images));
|
|
5746
|
-
const extensions =
|
|
5811
|
+
const extensions = useMemo16(
|
|
5747
5812
|
() => ({
|
|
5748
5813
|
...widgets && { widgets },
|
|
5749
5814
|
...diagrams && { diagrams },
|
|
@@ -5756,59 +5821,59 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
|
|
|
5756
5821
|
}),
|
|
5757
5822
|
[widgets, diagrams, liveDemos, imageClients, videos, appEvents, workView, stepPhrases]
|
|
5758
5823
|
);
|
|
5759
|
-
const scrollRef =
|
|
5760
|
-
const feedRef =
|
|
5824
|
+
const scrollRef = useRef17(null);
|
|
5825
|
+
const feedRef = useRef17(null);
|
|
5761
5826
|
const labels = useChatLabels();
|
|
5762
5827
|
const expanded = useExpandedParts(chatId);
|
|
5763
5828
|
const announcement = useFeedAnnouncement(chat.messages, chat.busy, chatId);
|
|
5764
5829
|
const { busy, canRetry, retry, canEdit, canRegenerate, regenerate, edit, selectBranch, respondToApproval, approvalPendingId, approvalFailure } = chat;
|
|
5765
5830
|
const { answerWidget, widgetPendingId, widgetFailure, sendReply, capabilities, closed } = chat;
|
|
5766
5831
|
const chatClosed = closed !== null;
|
|
5767
|
-
const reportAccess =
|
|
5832
|
+
const reportAccess = useRef17(onChatAccessChange);
|
|
5768
5833
|
reportAccess.current = onChatAccessChange;
|
|
5769
5834
|
useEffect14(() => {
|
|
5770
5835
|
if (chat.loaded) reportAccess.current?.({ capabilities, closed });
|
|
5771
5836
|
}, [capabilities, chat.loaded, closed]);
|
|
5772
5837
|
const { chatState } = chat;
|
|
5773
|
-
const reportState =
|
|
5838
|
+
const reportState = useRef17(onStateChange);
|
|
5774
5839
|
reportState.current = onStateChange;
|
|
5775
5840
|
useEffect14(() => {
|
|
5776
5841
|
if (chat.loaded) reportState.current?.(chatState);
|
|
5777
5842
|
}, [chat.loaded, chatState]);
|
|
5778
|
-
const reportUnavailable =
|
|
5843
|
+
const reportUnavailable = useRef17(onChatUnavailable);
|
|
5779
5844
|
reportUnavailable.current = onChatUnavailable;
|
|
5780
5845
|
const unavailable2 = chat.notFound || chat.loadFailed || chat.accessRefusal !== null;
|
|
5781
5846
|
useEffect14(() => {
|
|
5782
5847
|
if (unavailable2) reportUnavailable.current?.();
|
|
5783
5848
|
}, [unavailable2]);
|
|
5784
|
-
const [widgetAnnouncement, setWidgetAnnouncement] =
|
|
5849
|
+
const [widgetAnnouncement, setWidgetAnnouncement] = useState18(null);
|
|
5785
5850
|
const announced = widgetAnnouncement && widgetAnnouncement.chatId === chatId && (announcement === "" || announcement === widgetAnnouncement.feed) ? widgetAnnouncement.text : announcement;
|
|
5786
|
-
const announcementRef =
|
|
5851
|
+
const announcementRef = useRef17(announcement);
|
|
5787
5852
|
announcementRef.current = announcement;
|
|
5788
|
-
const onWidgetAnswer =
|
|
5853
|
+
const onWidgetAnswer = useCallback17(
|
|
5789
5854
|
(toolCallId, answer) => void answerWidget(toolCallId, answer, () => setWidgetAnnouncement({ text: labels.widgets.answerSent, feed: announcementRef.current, chatId })),
|
|
5790
5855
|
[answerWidget, chatId, labels]
|
|
5791
5856
|
);
|
|
5792
|
-
const suggestedReplies =
|
|
5857
|
+
const suggestedReplies = useMemo16(() => suggestedRepliesOf(chat.messages, busy), [busy, chat.messages]);
|
|
5793
5858
|
const exhaustedSpending = chat.spending?.state === "exhausted";
|
|
5794
|
-
const pickReply =
|
|
5859
|
+
const pickReply = useCallback17(
|
|
5795
5860
|
(text) => {
|
|
5796
5861
|
if (sendReply(text)) feedRef.current?.scrollToBottom();
|
|
5797
5862
|
},
|
|
5798
5863
|
[sendReply]
|
|
5799
5864
|
);
|
|
5800
|
-
const reportBusy =
|
|
5865
|
+
const reportBusy = useRef17(onBusyChange);
|
|
5801
5866
|
reportBusy.current = onBusyChange;
|
|
5802
5867
|
useEffect14(() => {
|
|
5803
5868
|
reportBusy.current?.(busy);
|
|
5804
5869
|
}, [busy, chatId]);
|
|
5805
5870
|
const lastIndex = chat.messages.length - 1;
|
|
5806
5871
|
const { corrections } = chat;
|
|
5807
|
-
const feedMessages =
|
|
5808
|
-
const correctionIds =
|
|
5872
|
+
const feedMessages = useMemo16(() => corrections.length > 0 ? [...chat.messages, ...corrections] : chat.messages, [chat.messages, corrections]);
|
|
5873
|
+
const correctionIds = useMemo16(() => new Set(corrections.map((correction) => correction.id)), [corrections]);
|
|
5809
5874
|
const steeredAnswerIdsKey = steeredAnswerIdsOf(feedMessages);
|
|
5810
|
-
const steeredAnswerIds =
|
|
5811
|
-
const reportFeed =
|
|
5875
|
+
const steeredAnswerIds = useMemo16(() => new Set(steeredAnswerIdsKey.split(" ")), [steeredAnswerIdsKey]);
|
|
5876
|
+
const reportFeed = useRef17(onFeedChange);
|
|
5812
5877
|
reportFeed.current = onFeedChange;
|
|
5813
5878
|
useEffect14(() => {
|
|
5814
5879
|
reportFeed.current?.({ messages: chat.messages, busy });
|
|
@@ -5816,45 +5881,54 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
|
|
|
5816
5881
|
useTurnFinishedReport(chatId, busy, chat.messages, onTurnFinished);
|
|
5817
5882
|
const appEventReport = useAppEventReport(chatId, chat.loaded, busy, chat.messages, onAppEvent);
|
|
5818
5883
|
const actionRuns = useMessageActionRuns(chatId);
|
|
5819
|
-
const dividers =
|
|
5884
|
+
const dividers = useMemo16(() => dividersByMessage(chat.compactions), [chat.compactions]);
|
|
5820
5885
|
const voiceAnswers = useVoiceAnswerIds(chat.messages);
|
|
5821
|
-
const forkByMessage =
|
|
5822
|
-
const [
|
|
5823
|
-
const
|
|
5824
|
-
const
|
|
5825
|
-
|
|
5826
|
-
const
|
|
5886
|
+
const forkByMessage = useMemo16(() => new Map(chat.forks.map((fork) => [fork.messageId, fork])), [chat.forks]);
|
|
5887
|
+
const [editingAnswerId, setEditingAnswerId] = useState18(null);
|
|
5888
|
+
const saving = useRef17(false);
|
|
5889
|
+
const composerValue = useRef17(chat.value);
|
|
5890
|
+
composerValue.current = chat.value;
|
|
5891
|
+
const { setValue: setComposerValue } = chat;
|
|
5892
|
+
const draftLost = useCallback17(
|
|
5893
|
+
(text) => setComposerValue(composerValue.current.trim().length > 0 ? `${composerValue.current}
|
|
5894
|
+
|
|
5895
|
+
${text}` : text),
|
|
5896
|
+
[setComposerValue]
|
|
5897
|
+
);
|
|
5898
|
+
const editing = useMessageEditing(chat.messages, { saving, onDraftLost: draftLost });
|
|
5899
|
+
const editingId = editing.id;
|
|
5900
|
+
const [feedView, setFeedView] = useState18({ epoch: 0 });
|
|
5827
5901
|
const imagesShown = imageClients.length > 0 && skin.GeneratedImages ? imageClients : void 0;
|
|
5828
|
-
const viewerImages =
|
|
5829
|
-
const getViewerItems =
|
|
5902
|
+
const viewerImages = useMemo16(() => imagesShown && generatedViewerItems(describeGeneratedImages(imagesShown, { api, chatId })), [imagesShown, api, chatId]);
|
|
5903
|
+
const getViewerItems = useCallback17(
|
|
5830
5904
|
() => collectViewerItems({ messages: chat.messages, describeAttachments: describeFiles, extraItems: viewerImages }),
|
|
5831
5905
|
[chat.messages, describeFiles, viewerImages]
|
|
5832
5906
|
);
|
|
5833
5907
|
const mediaViewer = useMediaViewer({ getItems: getViewerItems, resetKey: `${chatId}:${feedView.epoch}` });
|
|
5834
|
-
const describeImages =
|
|
5908
|
+
const describeImages = useMemo16(
|
|
5835
5909
|
() => imagesShown && describeGeneratedImages(imagesShown, { api, chatId, open: skin.MediaViewer && mediaViewer.open }),
|
|
5836
5910
|
[imagesShown, api, chatId, skin.MediaViewer, mediaViewer.open]
|
|
5837
5911
|
);
|
|
5838
|
-
const describeAttachments =
|
|
5912
|
+
const describeAttachments = useMemo16(
|
|
5839
5913
|
() => describeWithViewer(describeFiles, skin.MediaViewer && mediaViewer.open),
|
|
5840
5914
|
[describeFiles, skin.MediaViewer, mediaViewer.open]
|
|
5841
5915
|
);
|
|
5842
|
-
const diagramRenders =
|
|
5916
|
+
const diagramRenders = useMemo16(() => diagrams && createDiagramRenders(diagrams), [diagrams]);
|
|
5843
5917
|
const diagramColors = useDiagramColors(skin, diagrams !== void 0);
|
|
5844
|
-
const diagramSetup =
|
|
5918
|
+
const diagramSetup = useMemo16(
|
|
5845
5919
|
() => diagramRenders && diagramColors ? { renders: diagramRenders, colors: diagramColors, ...skin.MediaViewer && { open: mediaViewer.open } } : void 0,
|
|
5846
5920
|
[diagramColors, diagramRenders, mediaViewer.open, skin.MediaViewer]
|
|
5847
5921
|
);
|
|
5848
5922
|
const demoColors = useDemoColors(skin, liveDemos === true);
|
|
5849
|
-
const demos =
|
|
5850
|
-
const switchBranch =
|
|
5923
|
+
const demos = useMemo16(() => demoColors && { colors: demoColors, blocked: chat.externalContent }, [demoColors, chat.externalContent]);
|
|
5924
|
+
const switchBranch = useCallback17(
|
|
5851
5925
|
async (messageId) => {
|
|
5852
5926
|
if (await selectBranch(messageId)) setFeedView((view) => ({ epoch: view.epoch + 1, openAtMessageId: messageId }));
|
|
5853
5927
|
},
|
|
5854
5928
|
[selectBranch]
|
|
5855
5929
|
);
|
|
5856
|
-
const switchers =
|
|
5857
|
-
const switcherOf =
|
|
5930
|
+
const switchers = useMemo16(() => /* @__PURE__ */ new Map(), [busy, capabilities.branches, forkByMessage, skin, switchBranch]);
|
|
5931
|
+
const switcherOf = useCallback17(
|
|
5858
5932
|
(messageId) => {
|
|
5859
5933
|
const cached = switchers.get(messageId);
|
|
5860
5934
|
if (cached !== void 0) return cached;
|
|
@@ -5878,33 +5952,33 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
|
|
|
5878
5952
|
},
|
|
5879
5953
|
[busy, capabilities.branches, forkByMessage, skin, switchBranch, switchers]
|
|
5880
5954
|
);
|
|
5881
|
-
const saveEdit =
|
|
5955
|
+
const saveEdit = useCallback17(
|
|
5882
5956
|
async (messageId, text) => {
|
|
5883
5957
|
if (saving.current) return;
|
|
5884
5958
|
saving.current = true;
|
|
5885
5959
|
try {
|
|
5886
5960
|
const outcome = await edit(messageId, text);
|
|
5887
5961
|
if (outcome.status === "started") {
|
|
5888
|
-
|
|
5962
|
+
editing.close();
|
|
5889
5963
|
feedRef.current?.scrollToBottom();
|
|
5890
5964
|
return;
|
|
5891
5965
|
}
|
|
5892
5966
|
const kind = outcome.status === "refused" ? EDIT_REFUSAL_ERRORS[outcome.reason] : outcome.reason === "busy" || outcome.reason === "offline" ? outcome.reason : "rejected";
|
|
5893
5967
|
const messageLimit = outcome.status === "refused" && outcome.reason === "spending_limit" && outcome.unit === "messages";
|
|
5894
5968
|
const error = outcome.status === "refused" && outcome.text || (messageLimit ? labels.editMessageLimit : labels.editErrors[kind]);
|
|
5895
|
-
|
|
5969
|
+
editing.refuse(messageId, text, error);
|
|
5896
5970
|
} finally {
|
|
5897
5971
|
saving.current = false;
|
|
5898
5972
|
}
|
|
5899
5973
|
},
|
|
5900
|
-
[edit, labels]
|
|
5974
|
+
[edit, editing, labels]
|
|
5901
5975
|
);
|
|
5902
5976
|
const { tasks: backgroundTaskList, decisions: taskDecisions, decide: decideTask } = backgroundTasks;
|
|
5903
|
-
const noticeControls =
|
|
5977
|
+
const noticeControls = useMemo16(
|
|
5904
5978
|
() => ({ tasks: backgroundTaskList, decisions: taskDecisions, decide: (taskId, approvalId, decision) => void decideTask(taskId, approvalId, decision), failureText: labels.approvalFailed }),
|
|
5905
5979
|
[backgroundTaskList, decideTask, labels, taskDecisions]
|
|
5906
5980
|
);
|
|
5907
|
-
const renderMessage =
|
|
5981
|
+
const renderMessage = useCallback17(
|
|
5908
5982
|
(message, index) => {
|
|
5909
5983
|
if (correctionIds.has(message.id)) return /* @__PURE__ */ jsx9(UserMessage, { skin, message, describe: describeAttachments, branchSwitcher: void 0, pending: true });
|
|
5910
5984
|
const branchSwitcher = switcherOf(message.id);
|
|
@@ -5918,14 +5992,15 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
|
|
|
5918
5992
|
MessageEditorRow,
|
|
5919
5993
|
{
|
|
5920
5994
|
skin,
|
|
5921
|
-
initialText: editing
|
|
5995
|
+
initialText: editing.draftOf(message),
|
|
5922
5996
|
describe: describeAttachments,
|
|
5923
5997
|
message,
|
|
5924
|
-
...editing
|
|
5998
|
+
...editing.error && { error: editing.error },
|
|
5999
|
+
onDraftChange: editing.type,
|
|
5925
6000
|
onSave: (text) => void saveEdit(message.id, text),
|
|
5926
|
-
onCancel:
|
|
6001
|
+
onCancel: editing.close
|
|
5927
6002
|
},
|
|
5928
|
-
editing
|
|
6003
|
+
editing.attempt
|
|
5929
6004
|
) : /* @__PURE__ */ jsx9(
|
|
5930
6005
|
UserMessage,
|
|
5931
6006
|
{
|
|
@@ -5933,7 +6008,7 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
|
|
|
5933
6008
|
message,
|
|
5934
6009
|
describe: describeAttachments,
|
|
5935
6010
|
branchSwitcher,
|
|
5936
|
-
...canEdit && { onEdit: () =>
|
|
6011
|
+
...canEdit && { onEdit: () => editing.open(message.id) }
|
|
5937
6012
|
}
|
|
5938
6013
|
) : editingAnswerId === message.id && answerEditing ? /* @__PURE__ */ jsx9(Fragment2, { children: answerEditing.renderEditor({
|
|
5939
6014
|
message,
|
|
@@ -6040,6 +6115,7 @@ function AgentChatBody({ api, chatId, skin, liveness, voice, voiceDialog, attach
|
|
|
6040
6115
|
scrollRef,
|
|
6041
6116
|
messages: feedMessages,
|
|
6042
6117
|
keepLastMounted: busy,
|
|
6118
|
+
...editingId !== null && { keepMountedMessageId: editingId },
|
|
6043
6119
|
...feedView.openAtMessageId && { openAtMessageId: feedView.openAtMessageId },
|
|
6044
6120
|
renderMessage
|
|
6045
6121
|
},
|
|
@@ -6193,7 +6269,7 @@ var UserMessage = memo4(function UserMessage2({
|
|
|
6193
6269
|
onEdit,
|
|
6194
6270
|
pending
|
|
6195
6271
|
}) {
|
|
6196
|
-
const files =
|
|
6272
|
+
const files = useMemo16(() => describe?.(message), [describe, message]);
|
|
6197
6273
|
return /* @__PURE__ */ jsx9(
|
|
6198
6274
|
skin.UserMessage,
|
|
6199
6275
|
{
|
|
@@ -6211,12 +6287,13 @@ function MessageEditorRow({
|
|
|
6211
6287
|
initialText,
|
|
6212
6288
|
describe,
|
|
6213
6289
|
error,
|
|
6290
|
+
onDraftChange,
|
|
6214
6291
|
onSave,
|
|
6215
6292
|
onCancel
|
|
6216
6293
|
}) {
|
|
6217
|
-
const [draft, setDraft] =
|
|
6218
|
-
const [shownError, setShownError] =
|
|
6219
|
-
const files =
|
|
6294
|
+
const [draft, setDraft] = useState18(initialText);
|
|
6295
|
+
const [shownError, setShownError] = useState18(error);
|
|
6296
|
+
const files = useMemo16(() => describe?.(message), [describe, message]);
|
|
6220
6297
|
const canSave = draft.trim().length > 0 || files !== void 0;
|
|
6221
6298
|
return /* @__PURE__ */ jsx9(
|
|
6222
6299
|
skin.MessageEditor,
|
|
@@ -6224,6 +6301,7 @@ function MessageEditorRow({
|
|
|
6224
6301
|
value: draft,
|
|
6225
6302
|
onValueChange: (value) => {
|
|
6226
6303
|
setDraft(value);
|
|
6304
|
+
onDraftChange(value);
|
|
6227
6305
|
setShownError(void 0);
|
|
6228
6306
|
},
|
|
6229
6307
|
onSave: () => canSave && onSave(draft),
|
|
@@ -6562,13 +6640,13 @@ function approvalProps(part, controls) {
|
|
|
6562
6640
|
return { approval: { state: approval.reason === ALWAYS_IN_CHAT ? "always" : "allowed" } };
|
|
6563
6641
|
}
|
|
6564
6642
|
function useSameList(list) {
|
|
6565
|
-
const kept =
|
|
6643
|
+
const kept = useRef17(list);
|
|
6566
6644
|
if (kept.current.length !== list.length || kept.current.some((item, index) => item !== list[index])) kept.current = list;
|
|
6567
6645
|
return kept.current;
|
|
6568
6646
|
}
|
|
6569
6647
|
|
|
6570
6648
|
// src/chat-list/use-chat-list.ts
|
|
6571
|
-
import { useCallback as
|
|
6649
|
+
import { useCallback as useCallback18, useEffect as useEffect15, useRef as useRef18, useState as useState19 } from "react";
|
|
6572
6650
|
|
|
6573
6651
|
// src/chat-list/active-chat-memory.ts
|
|
6574
6652
|
var defaultRememberKey = (api) => `agent-chat:active-chat:${api}`;
|
|
@@ -6650,15 +6728,15 @@ var NOTHING_LOADED = {
|
|
|
6650
6728
|
var collapse = (title) => title.trim().replace(/\s+/g, " ");
|
|
6651
6729
|
function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCreateRefused }) {
|
|
6652
6730
|
const memoryKey = rememberKey ?? defaultRememberKey(api);
|
|
6653
|
-
const [status, setStatus] =
|
|
6654
|
-
const [items, setItems] =
|
|
6655
|
-
const [activeChatId, setActiveChatId] =
|
|
6656
|
-
const [error, setError] =
|
|
6657
|
-
const [creationRefusal, setCreationRefusal] =
|
|
6658
|
-
const [creating, setCreating] =
|
|
6659
|
-
const [deleteRequest, setDeleteRequest] =
|
|
6660
|
-
const [deleting, setDeleting] =
|
|
6661
|
-
const [stateKey, setStateKey] =
|
|
6731
|
+
const [status, setStatus] = useState19("loading");
|
|
6732
|
+
const [items, setItems] = useState19([]);
|
|
6733
|
+
const [activeChatId, setActiveChatId] = useState19(null);
|
|
6734
|
+
const [error, setError] = useState19(null);
|
|
6735
|
+
const [creationRefusal, setCreationRefusal] = useState19(null);
|
|
6736
|
+
const [creating, setCreating] = useState19(false);
|
|
6737
|
+
const [deleteRequest, setDeleteRequest] = useState19(null);
|
|
6738
|
+
const [deleting, setDeleting] = useState19(false);
|
|
6739
|
+
const [stateKey, setStateKey] = useState19(memoryKey);
|
|
6662
6740
|
const keyChanged = stateKey !== memoryKey;
|
|
6663
6741
|
if (keyChanged) {
|
|
6664
6742
|
setStateKey(memoryKey);
|
|
@@ -6671,30 +6749,30 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6671
6749
|
setDeleteRequest(null);
|
|
6672
6750
|
setDeleting(false);
|
|
6673
6751
|
}
|
|
6674
|
-
const keyRef =
|
|
6752
|
+
const keyRef = useRef18(memoryKey);
|
|
6675
6753
|
keyRef.current = memoryKey;
|
|
6676
|
-
const fetchRef =
|
|
6754
|
+
const fetchRef = useRef18(customFetch);
|
|
6677
6755
|
fetchRef.current = customFetch;
|
|
6678
|
-
const refusedRef =
|
|
6756
|
+
const refusedRef = useRef18(onCreateRefused);
|
|
6679
6757
|
refusedRef.current = onCreateRefused;
|
|
6680
|
-
const send =
|
|
6681
|
-
const itemsRef =
|
|
6758
|
+
const send = useCallback18((input, init) => (fetchRef.current ?? globalThis.fetch)(input, init), []);
|
|
6759
|
+
const itemsRef = useRef18(items);
|
|
6682
6760
|
itemsRef.current = keyChanged ? [] : items;
|
|
6683
|
-
const activeRef =
|
|
6761
|
+
const activeRef = useRef18(activeChatId);
|
|
6684
6762
|
activeRef.current = keyChanged ? null : activeChatId;
|
|
6685
|
-
const initialRef =
|
|
6686
|
-
const loadRequest =
|
|
6687
|
-
const listRequest =
|
|
6688
|
-
const loadedKey =
|
|
6689
|
-
const alive =
|
|
6763
|
+
const initialRef = useRef18(initialChatId);
|
|
6764
|
+
const loadRequest = useRef18(0);
|
|
6765
|
+
const listRequest = useRef18(0);
|
|
6766
|
+
const loadedKey = useRef18(null);
|
|
6767
|
+
const alive = useRef18(true);
|
|
6690
6768
|
useEffect15(() => {
|
|
6691
6769
|
alive.current = true;
|
|
6692
6770
|
return () => {
|
|
6693
6771
|
alive.current = false;
|
|
6694
6772
|
};
|
|
6695
6773
|
}, []);
|
|
6696
|
-
const stillFor =
|
|
6697
|
-
const failCreate =
|
|
6774
|
+
const stillFor = useCallback18((key) => alive.current && keyRef.current === key, []);
|
|
6775
|
+
const failCreate = useCallback18(
|
|
6698
6776
|
(cause) => {
|
|
6699
6777
|
const refusal = cause instanceof ChatCreationRefusedError ? cause.refusal : null;
|
|
6700
6778
|
setCreationRefusal(refusal);
|
|
@@ -6703,7 +6781,7 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6703
6781
|
},
|
|
6704
6782
|
[]
|
|
6705
6783
|
);
|
|
6706
|
-
const activate =
|
|
6784
|
+
const activate = useCallback18(
|
|
6707
6785
|
(chatId) => {
|
|
6708
6786
|
activeRef.current = chatId;
|
|
6709
6787
|
setActiveChatId(chatId);
|
|
@@ -6711,7 +6789,7 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6711
6789
|
},
|
|
6712
6790
|
[memoryKey]
|
|
6713
6791
|
);
|
|
6714
|
-
const createAndOpen =
|
|
6792
|
+
const createAndOpen = useCallback18(async () => {
|
|
6715
6793
|
const id = await createChatOnServer(api, send);
|
|
6716
6794
|
if (!stillFor(memoryKey)) return false;
|
|
6717
6795
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -6719,7 +6797,7 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6719
6797
|
activate(id);
|
|
6720
6798
|
return true;
|
|
6721
6799
|
}, [activate, api, memoryKey, send, stillFor]);
|
|
6722
|
-
const load =
|
|
6800
|
+
const load = useCallback18(async () => {
|
|
6723
6801
|
if (loadedKey.current !== memoryKey) {
|
|
6724
6802
|
if (loadedKey.current !== null) initialRef.current = void 0;
|
|
6725
6803
|
loadedKey.current = memoryKey;
|
|
@@ -6752,7 +6830,7 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6752
6830
|
useEffect15(() => {
|
|
6753
6831
|
void load();
|
|
6754
6832
|
}, [load]);
|
|
6755
|
-
const refresh =
|
|
6833
|
+
const refresh = useCallback18(async () => {
|
|
6756
6834
|
const request2 = ++listRequest.current;
|
|
6757
6835
|
try {
|
|
6758
6836
|
const loaded = await fetchChatList(api, send);
|
|
@@ -6760,7 +6838,7 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6760
6838
|
} catch {
|
|
6761
6839
|
}
|
|
6762
6840
|
}, [api, memoryKey, send, stillFor]);
|
|
6763
|
-
const create =
|
|
6841
|
+
const create = useCallback18(async () => {
|
|
6764
6842
|
setError(null);
|
|
6765
6843
|
setCreating(true);
|
|
6766
6844
|
try {
|
|
@@ -6778,14 +6856,14 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6778
6856
|
if (stillFor(memoryKey)) setCreating(false);
|
|
6779
6857
|
}
|
|
6780
6858
|
}, [activate, api, createAndOpen, failCreate, memoryKey, send, stillFor]);
|
|
6781
|
-
const select =
|
|
6859
|
+
const select = useCallback18(
|
|
6782
6860
|
(chatId) => {
|
|
6783
6861
|
setError(null);
|
|
6784
6862
|
activate(chatId);
|
|
6785
6863
|
},
|
|
6786
6864
|
[activate]
|
|
6787
6865
|
);
|
|
6788
|
-
const rename =
|
|
6866
|
+
const rename = useCallback18(
|
|
6789
6867
|
async (chatId, title) => {
|
|
6790
6868
|
const normalized = collapse(title);
|
|
6791
6869
|
const current = itemsRef.current.find((item) => item.id === chatId);
|
|
@@ -6804,12 +6882,12 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6804
6882
|
},
|
|
6805
6883
|
[api, memoryKey, send, stillFor]
|
|
6806
6884
|
);
|
|
6807
|
-
const requestDelete =
|
|
6885
|
+
const requestDelete = useCallback18((chatId) => {
|
|
6808
6886
|
const item = itemsRef.current.find((entry) => entry.id === chatId);
|
|
6809
6887
|
if (item) setDeleteRequest({ id: item.id, title: item.title });
|
|
6810
6888
|
}, []);
|
|
6811
|
-
const cancelDelete =
|
|
6812
|
-
const confirmDelete =
|
|
6889
|
+
const cancelDelete = useCallback18(() => setDeleteRequest(null), []);
|
|
6890
|
+
const confirmDelete = useCallback18(async () => {
|
|
6813
6891
|
if (!deleteRequest) return;
|
|
6814
6892
|
const { id } = deleteRequest;
|
|
6815
6893
|
setError(null);
|
|
@@ -6845,7 +6923,7 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6845
6923
|
if (stillFor(memoryKey)) failCreate(cause);
|
|
6846
6924
|
}
|
|
6847
6925
|
}, [activate, api, createAndOpen, deleteRequest, failCreate, memoryKey, send, stillFor]);
|
|
6848
|
-
const reload =
|
|
6926
|
+
const reload = useCallback18(() => void load(), [load]);
|
|
6849
6927
|
return {
|
|
6850
6928
|
...keyChanged ? NOTHING_LOADED : { status, items, activeChatId, error, creationRefusal, creating, deleteRequest, deleting },
|
|
6851
6929
|
select,
|
|
@@ -6860,18 +6938,18 @@ function useChatList({ api, initialChatId, fetch: customFetch, rememberKey, onCr
|
|
|
6860
6938
|
}
|
|
6861
6939
|
|
|
6862
6940
|
// src/chat-list/use-chat-list-view.ts
|
|
6863
|
-
import { useCallback as
|
|
6941
|
+
import { useCallback as useCallback19 } from "react";
|
|
6864
6942
|
function useChatListView(list, onChosen) {
|
|
6865
6943
|
const labels = useChatLabels();
|
|
6866
6944
|
const { select, create: createChat } = list;
|
|
6867
|
-
const onSelect =
|
|
6945
|
+
const onSelect = useCallback19(
|
|
6868
6946
|
(chatId) => {
|
|
6869
6947
|
select(chatId);
|
|
6870
6948
|
onChosen();
|
|
6871
6949
|
},
|
|
6872
6950
|
[onChosen, select]
|
|
6873
6951
|
);
|
|
6874
|
-
const onCreate =
|
|
6952
|
+
const onCreate = useCallback19(() => {
|
|
6875
6953
|
void createChat().then((opened) => opened && onChosen());
|
|
6876
6954
|
}, [createChat, onChosen]);
|
|
6877
6955
|
const deleteRequest = list.deleteRequest && {
|
|
@@ -6915,11 +6993,11 @@ var CHAT_ORIGINS = /* @__PURE__ */ new Set(["telegram", "vk", "max"]);
|
|
|
6915
6993
|
var chatOriginOf = (origin) => origin !== void 0 && CHAT_ORIGINS.has(origin) ? origin : void 0;
|
|
6916
6994
|
|
|
6917
6995
|
// src/chat-list/use-workspace-list-sync.ts
|
|
6918
|
-
import { useEffect as useEffect16, useRef as
|
|
6996
|
+
import { useEffect as useEffect16, useRef as useRef19 } from "react";
|
|
6919
6997
|
var TITLE_POLL_MS = 1e3;
|
|
6920
6998
|
function useWorkspaceListSync(list, busy, enabled = true) {
|
|
6921
6999
|
const { items, activeChatId, refresh } = list;
|
|
6922
|
-
const previousBusy =
|
|
7000
|
+
const previousBusy = useRef19(null);
|
|
6923
7001
|
useEffect16(() => {
|
|
6924
7002
|
const before = previousBusy.current;
|
|
6925
7003
|
previousBusy.current = busy;
|
|
@@ -6964,4 +7042,4 @@ export {
|
|
|
6964
7042
|
activeChatTitle,
|
|
6965
7043
|
useWorkspaceListSync
|
|
6966
7044
|
};
|
|
6967
|
-
//# sourceMappingURL=chunk-
|
|
7045
|
+
//# sourceMappingURL=chunk-Y5HL6THS.js.map
|