@burdenoff/fe-libs 2026.1007.5 → 2026.1007.6
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/shared/assistant/api.d.ts +11 -0
- package/dist/shared/assistant/api.d.ts.map +1 -1
- package/dist/shared/assistant/api.js +6 -2
- package/dist/shared/assistant/conversation.d.ts +14 -0
- package/dist/shared/assistant/conversation.d.ts.map +1 -1
- package/dist/shared/assistant/createSandboxAssistantTransport.d.ts +8 -1
- package/dist/shared/assistant/createSandboxAssistantTransport.d.ts.map +1 -1
- package/dist/shared/assistant/createSandboxAssistantTransport.js +70 -51
- package/dist/shared/assistant/history/historyMapping.d.ts.map +1 -1
- package/dist/shared/assistant/history/historyMapping.js +19 -12
- package/dist/shared/assistant/i18nManifest.d.ts +9 -0
- package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
- package/dist/shared/assistant/i18nManifest.js +9 -0
- package/dist/shared/assistant/index.d.ts +6 -0
- package/dist/shared/assistant/index.d.ts.map +1 -1
- package/dist/shared/assistant/localUiCommandCopy.d.ts +23 -0
- package/dist/shared/assistant/localUiCommandCopy.d.ts.map +1 -1
- package/dist/shared/assistant/localUiCommandCopy.js +60 -23
- package/dist/shared/assistant/localUiCommands.d.ts +29 -0
- package/dist/shared/assistant/localUiCommands.d.ts.map +1 -1
- package/dist/shared/assistant/localUiCommands.js +18 -7
- package/dist/shared/assistant/types.d.ts +19 -8
- package/dist/shared/assistant/types.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantChatArea.js +1479 -1140
- package/dist/shared/assistant/ui/AssistantMarkdownRenderer.d.ts +18 -3
- package/dist/shared/assistant/ui/AssistantMarkdownRenderer.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantMarkdownRenderer.js +1 -1
- package/dist/shared/assistant/ui/AssistantMessageItem.d.ts +5 -0
- package/dist/shared/assistant/ui/AssistantMessageItem.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantMessageItem.js +89 -84
- package/dist/shared/assistant/ui/AssistantMessageList.d.ts +5 -0
- package/dist/shared/assistant/ui/AssistantMessageList.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantMessageList.js +26 -25
- package/dist/shared/assistant/ui/AssistantUiOfferLink.d.ts +45 -0
- package/dist/shared/assistant/ui/AssistantUiOfferLink.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantUiOfferLink.js +56 -0
- package/dist/shared/assistant/ui/assistantOverlayState.d.ts +9 -0
- package/dist/shared/assistant/ui/assistantOverlayState.d.ts.map +1 -1
- package/dist/shared/assistant/ui/assistantOverlayState.js +37 -28
- package/dist/shared/assistant/ui/composer/AssistantConnectSourceItem.d.ts.map +1 -1
- package/dist/shared/assistant/ui/composer/AssistantConnectSourceItem.js +1 -1
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +5 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +12 -11
- package/dist/shared/assistant/ui/voice/VoiceConversationView.d.ts +6 -1
- package/dist/shared/assistant/ui/voice/VoiceConversationView.d.ts.map +1 -1
- package/dist/shared/assistant/ui/voice/VoiceConversationView.js +7 -7
- package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts +6 -1
- package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts.map +1 -1
- package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.js +15 -12
- package/dist/shared/assistant/uiActions/actOnResolve.d.ts +108 -0
- package/dist/shared/assistant/uiActions/actOnResolve.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/actOnResolve.js +51 -0
- package/dist/shared/assistant/uiActions/linkContext.d.ts +29 -0
- package/dist/shared/assistant/uiActions/linkContext.d.ts.map +1 -1
- package/dist/shared/assistant/uiActions/linkContext.js +37 -10
- package/dist/shared/assistant/uiActions/navIntent.d.ts +58 -0
- package/dist/shared/assistant/uiActions/navIntent.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/navIntent.js +79 -0
- package/dist/shared/assistant/uiActions/navigateAction.d.ts +6 -1
- package/dist/shared/assistant/uiActions/navigateAction.d.ts.map +1 -1
- package/dist/shared/assistant/uiActions/navigateAction.js +18 -14
- package/dist/shared/assistant/uiActions/navigationOutcome.d.ts +16 -2
- package/dist/shared/assistant/uiActions/navigationOutcome.d.ts.map +1 -1
- package/dist/shared/assistant/uiActions/navigationOutcome.js +6 -2
- package/dist/shared/assistant/uiActions/offerYesOnSurface.d.ts +39 -0
- package/dist/shared/assistant/uiActions/offerYesOnSurface.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/offerYesOnSurface.js +34 -0
- package/dist/shared/assistant/uiActions/uiCatalogue.d.ts +14 -0
- package/dist/shared/assistant/uiActions/uiCatalogue.d.ts.map +1 -1
- package/dist/shared/assistant/uiActions/uiCatalogue.js +23 -3
- package/dist/shared/assistant/uiActions/uiOffers.d.ts +249 -0
- package/dist/shared/assistant/uiActions/uiOffers.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/uiOffers.js +195 -0
- package/dist/shared/assistant/writeProposals.d.ts +6 -0
- package/dist/shared/assistant/writeProposals.d.ts.map +1 -1
- package/dist/shared/assistant/writeReplyBinder.d.ts +40 -0
- package/dist/shared/assistant/writeReplyBinder.d.ts.map +1 -1
- package/dist/shared/assistant/writeReplyBinder.js +100 -83
- package/dist/shared/assistant/writeReplySend.d.ts +14 -0
- package/dist/shared/assistant/writeReplySend.d.ts.map +1 -1
- package/dist/shared/assistant/writeReplySend.js +32 -29
- package/dist/shared/hooks/index.d.ts +2 -0
- package/dist/shared/hooks/index.d.ts.map +1 -1
- package/dist/shared/navigation/unsavedChanges.d.ts +83 -0
- package/dist/shared/navigation/unsavedChanges.d.ts.map +1 -0
- package/dist/shared/navigation/unsavedChanges.js +46 -0
- package/dist/shared-assistant.js +244 -238
- package/dist/shared-hooks.js +10 -9
- package/dist/shared.js +20 -19
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FC, MouseEvent, ReactNode } from 'react';
|
|
2
2
|
import { assistantRoutePath, assistantUrlTransform, classifyAssistantHref, AssistantLinkKind } from '../uiActions/assistantHref';
|
|
3
|
+
import { NavigationInitiator, UnsavedChange } from '../../navigation/unsavedChanges';
|
|
3
4
|
interface Props {
|
|
4
5
|
content: string;
|
|
5
6
|
}
|
|
@@ -18,15 +19,29 @@ export type AssistantNavigateResult =
|
|
|
18
19
|
/** A shell-less target: opened in a new tab, which cannot be verified. */
|
|
19
20
|
| {
|
|
20
21
|
kind: "new-tab";
|
|
21
|
-
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* ★ BOFF-8060 (N4): not routed. `unsaved-changes` names what is unsaved, for
|
|
25
|
+
* the "You have unsaved changes in {label}" reply.
|
|
26
|
+
*/
|
|
27
|
+
| {
|
|
22
28
|
kind: "refused";
|
|
23
29
|
reason: "unsaved-changes" | "not-routable";
|
|
30
|
+
unsaved?: readonly UnsavedChange[];
|
|
24
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* ★ BOFF-8060 (N4): who started this navigation. The person's own (a link they
|
|
34
|
+
* clicked in a reply) is at sidebar parity; the assistant's (a typed or spoken
|
|
35
|
+
* command, a "yes", act-on-resolve) is refused while the page holds unsaved
|
|
36
|
+
* changes. A navigator that does not say is treated as the assistant's.
|
|
37
|
+
*/
|
|
38
|
+
export type AssistantNavigateInitiator = NavigationInitiator;
|
|
25
39
|
/**
|
|
26
40
|
* Route an in-app PATH — `/fields?crop=42#yield`, never a full URL. Supplied by
|
|
27
|
-
* the product; absent means "no SPA routing".
|
|
41
|
+
* the product; absent means "no SPA routing". A product navigator may ignore
|
|
42
|
+
* `initiator`; `createAssistantNavigate` reads it.
|
|
28
43
|
*/
|
|
29
|
-
export type AssistantNavigate = (path: string) => AssistantNavigateResult | void;
|
|
44
|
+
export type AssistantNavigate = (path: string, initiator?: AssistantNavigateInitiator) => AssistantNavigateResult | void;
|
|
30
45
|
/**
|
|
31
46
|
* ★★ The cases where the BROWSER must win, not the router. Losing these is how
|
|
32
47
|
* "open in new tab", "copy link" and middle-click quietly stop working — the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantMarkdownRenderer.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMarkdownRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAIL,KAAK,EAAE,EACP,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAYf,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,iBAAiB,EACvB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"AssistantMarkdownRenderer.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMarkdownRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAIL,KAAK,EAAE,EACP,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAYf,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,iBAAiB,EACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACd,MAAM,iCAAiC,CAAC;AAEzC,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAsCD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,CAAC;AAC5E,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC;;;;GAIG;AACH,MAAM,MAAM,uBAAuB;AACjC,6DAA6D;AAC3D;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,0EAA0E;GACxE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE;AACrB;;;GAGG;GACD;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,iBAAiB,GAAG,cAAc,CAAC;IAC3C,OAAO,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CACpC,CAAC;AAEN;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,CAAC;AAE7D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC9B,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,0BAA0B,KACnC,uBAAuB,GAAG,IAAI,CAAC;AAEpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,OAAO,CASjF;AAID;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC;IACzC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;CACrB,CAIA,CAAC;AAEF,wBAAgB,oBAAoB,IAAI,iBAAiB,GAAG,IAAI,CAE/D;AAwTD,eAAO,MAAM,yBAAyB,EAAE,EAAE,CAAC,KAAK,CAiB/C,CAAC"}
|
|
@@ -34,7 +34,7 @@ var C = "text-action-primary-bg underline-offset-2 hover:underline", w = ({ href
|
|
|
34
34
|
className: C,
|
|
35
35
|
"data-testid": "assistant-markdown-link",
|
|
36
36
|
onClick: (e) => {
|
|
37
|
-
y(e) || (e.preventDefault(), n(i));
|
|
37
|
+
y(e) || (e.preventDefault(), n(i, "person"));
|
|
38
38
|
},
|
|
39
39
|
children: t
|
|
40
40
|
}) : r === "internal" || r === "fragment" ? /* @__PURE__ */ g("a", {
|
|
@@ -60,6 +60,11 @@ interface Props {
|
|
|
60
60
|
legacyWriteCardHidden?: boolean;
|
|
61
61
|
/** ★ BOFF-7803 5a (FE7): this reply's write-proposal cards, if any. */
|
|
62
62
|
writeProposals?: ReactNode;
|
|
63
|
+
/**
|
|
64
|
+
* ★ BOFF-8060 (N3): the page the model offered, as an "Open {page}" link,
|
|
65
|
+
* drawn directly under the reply's text. Absent, nothing is drawn.
|
|
66
|
+
*/
|
|
67
|
+
uiOffers?: ReactNode;
|
|
63
68
|
}
|
|
64
69
|
/**
|
|
65
70
|
* Purely decorative "still typing" caret: hidden from assistive tech (the list's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantMessageItem.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMessageItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAyB3E,OAAO,KAAK,EACV,+BAA+B,EAG/B,OAAO,EACR,MAAM,iBAAiB,CAAC;AAMzB,UAAU,KAAK;IACb,mEAAmE;IACnE,qBAAqB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,+BAA+B,GAAG,IAAI,CAAC;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uEAAuE;IACvE,cAAc,CAAC,EAAE,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"AssistantMessageItem.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMessageItem.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAyB3E,OAAO,KAAK,EACV,+BAA+B,EAG/B,OAAO,EACR,MAAM,iBAAiB,CAAC;AAMzB,UAAU,KAAK;IACb,mEAAmE;IACnE,qBAAqB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,6EAA6E;IAC7E,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,+BAA+B,GAAG,IAAI,CAAC;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uEAAuE;IACvE,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAyCD;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,EAAE,EAY5B,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,KAAK,CA4X1C,CAAC"}
|
|
@@ -8,103 +8,107 @@ import { AssistantMarkdownRenderer as a } from "./AssistantMarkdownRenderer.js";
|
|
|
8
8
|
import { downloadAssistantArtifact as o } from "../api.js";
|
|
9
9
|
import { languageConfirmationCopy as s } from "../appControls/languageReply.js";
|
|
10
10
|
import { getAssistantDisplayContent as ee } from "../displayContent.js";
|
|
11
|
-
import { AssistantToolActivity as te, parseToolActivity as
|
|
12
|
-
import { usePrefersReducedMotion as
|
|
13
|
-
import { AssistantAvatar as
|
|
14
|
-
import { useAssistantSpeech as
|
|
11
|
+
import { AssistantToolActivity as te, parseToolActivity as c } from "./AssistantToolActivity.js";
|
|
12
|
+
import { usePrefersReducedMotion as l } from "./usePrefersReducedMotion.js";
|
|
13
|
+
import { AssistantAvatar as ne } from "./AssistantAvatar.js";
|
|
14
|
+
import { useAssistantSpeech as re } from "./AssistantSpeechProvider.js";
|
|
15
15
|
import { AssistantMessageAttachments as ie } from "./AssistantMessageAttachments.js";
|
|
16
|
-
import { AssistantPendingWriteCard as
|
|
17
|
-
import { AssistantSpeakButton as
|
|
18
|
-
import { SaveToFilesButton as
|
|
16
|
+
import { AssistantPendingWriteCard as ae } from "./AssistantPendingWriteCard.js";
|
|
17
|
+
import { AssistantSpeakButton as oe } from "./AssistantSpeakButton.js";
|
|
18
|
+
import { SaveToFilesButton as u } from "../../../storage/SaveToFilesButton.js";
|
|
19
19
|
import "../../../storage/index.js";
|
|
20
|
-
import { AssistantTurnActivity as
|
|
21
|
-
import { useMemo as
|
|
22
|
-
import { Check as
|
|
23
|
-
import { Fragment as
|
|
20
|
+
import { AssistantTurnActivity as se } from "./AssistantTurnActivity.js";
|
|
21
|
+
import { useMemo as d, useRef as f, useState as p } from "react";
|
|
22
|
+
import { Check as ce, Copy as m, RotateCcw as h } from "lucide-react";
|
|
23
|
+
import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
24
24
|
//#region src/shared/assistant/ui/AssistantMessageItem.tsx
|
|
25
|
-
function
|
|
25
|
+
function le(e) {
|
|
26
26
|
return e.role === "assistant" ? e.metadata : void 0;
|
|
27
27
|
}
|
|
28
|
-
function
|
|
28
|
+
function y(e) {
|
|
29
29
|
return e?.artifacts ?? [];
|
|
30
30
|
}
|
|
31
|
-
function
|
|
31
|
+
function b(e) {
|
|
32
32
|
return window.atob(e);
|
|
33
33
|
}
|
|
34
|
-
function
|
|
35
|
-
let r =
|
|
34
|
+
function x(e, t, n) {
|
|
35
|
+
let r = b(e), i = new Uint8Array(r.length);
|
|
36
36
|
for (let e = 0; e < r.length; e += 1) i[e] = r.charCodeAt(e);
|
|
37
37
|
let a = new Blob([i], { type: n }), o = URL.createObjectURL(a), s = document.createElement("a");
|
|
38
38
|
s.href = o, s.download = t, document.body.appendChild(s), s.click(), document.body.removeChild(s), URL.revokeObjectURL(o);
|
|
39
39
|
}
|
|
40
|
-
var
|
|
40
|
+
var S = () => /* @__PURE__ */ _("span", {
|
|
41
41
|
"aria-hidden": "true",
|
|
42
42
|
"data-testid": "assistant-streaming-caret",
|
|
43
|
-
className: "ml-0.5 inline-block h-4 w-1.5 rounded-sm bg-text-secondary align-middle" + (
|
|
44
|
-
}),
|
|
45
|
-
let P = r(), { locale: F } = e(), I = s(
|
|
43
|
+
className: "ml-0.5 inline-block h-4 w-1.5 rounded-sm bg-text-secondary align-middle" + (l() ? "" : " motion-safe:animate-pulse")
|
|
44
|
+
}), C = ({ onApprovePendingWrite: l, approvingWriteRef: b = null, pendingWriteExpired: C = !1, pendingWriteApproved: ue = !1, pendingWriteGoAheadSent: de = !1, message: w, processing: T, isStreaming: E, isFailed: D, isLastAssistant: O, isNewestAssistant: k, onRetry: A, legacyWriteCardHidden: j = !1, writeProposals: M, uiOffers: N }) => {
|
|
45
|
+
let P = r(), { locale: F } = e(), I = s(w, P), L = I ? I.translated ? F : "en" : w.metadata?.lang, R = I ? `${w.id}:language:${L}` : w.id, z = f(R), B = n(), { getAccessToken: V, getWorkspaceToken: fe } = t(), H = re(), [pe, U] = p(null), [W, G] = p(!1), K = w.role === "user", q = d(() => le(w), [w]), J = d(() => y(q), [q]), Y = T === void 0 ? E ? {
|
|
46
46
|
status: "streaming",
|
|
47
|
-
messageId:
|
|
48
|
-
updatedAt:
|
|
49
|
-
} : null :
|
|
47
|
+
messageId: w.id,
|
|
48
|
+
updatedAt: w.timestamp
|
|
49
|
+
} : null : T, X = ee(w, Y, P), { steps: Z, text: Q } = d(() => K ? {
|
|
50
50
|
steps: [],
|
|
51
|
-
text:
|
|
52
|
-
} : X.kind === "output" ?
|
|
51
|
+
text: w.content
|
|
52
|
+
} : X.kind === "output" ? c(X.text) : {
|
|
53
53
|
steps: [],
|
|
54
54
|
text: ""
|
|
55
55
|
}, [
|
|
56
56
|
K,
|
|
57
|
-
|
|
57
|
+
w.content,
|
|
58
58
|
X.kind,
|
|
59
59
|
X.text
|
|
60
|
-
]),
|
|
60
|
+
]), me = () => {
|
|
61
61
|
i(Q).then((e) => {
|
|
62
62
|
e && (G(!0), setTimeout(() => G(!1), 2e3));
|
|
63
63
|
});
|
|
64
|
-
},
|
|
64
|
+
}, he = async (e) => {
|
|
65
65
|
if (!q?.sandboxId || !q.sessionId) return;
|
|
66
66
|
let t = new URLSearchParams(window.location.search).get("workspace") ?? "";
|
|
67
67
|
if (t) {
|
|
68
|
-
|
|
68
|
+
U(e.path);
|
|
69
69
|
try {
|
|
70
70
|
let n = await o(q.sandboxId, t, q.sessionId, e.path, q.mode, {
|
|
71
71
|
accessToken: V(),
|
|
72
|
-
workspaceToken:
|
|
72
|
+
workspaceToken: fe()
|
|
73
73
|
});
|
|
74
|
-
|
|
74
|
+
x(n.contentBase64, n.filename, n.mimeType);
|
|
75
75
|
} finally {
|
|
76
|
-
|
|
76
|
+
U(null);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
-
}, $ = new Date(
|
|
79
|
+
}, $ = new Date(w.timestamp).toLocaleTimeString([], {
|
|
80
80
|
hour: "2-digit",
|
|
81
81
|
minute: "2-digit"
|
|
82
82
|
});
|
|
83
|
-
if (
|
|
83
|
+
if (w.role === "system") return /* @__PURE__ */ _("div", {
|
|
84
84
|
className: "flex justify-center px-2 py-1",
|
|
85
85
|
"data-testid": "assistant-message-system",
|
|
86
|
-
children: /* @__PURE__ */
|
|
86
|
+
children: w.metadata?.localAction?.kind === "navigate" ? /* @__PURE__ */ _("div", {
|
|
87
|
+
className: "max-w-[90%] break-words rounded-lg border border-border-subtle bg-bg-sunken/60 px-3 py-2 text-center text-xs leading-relaxed text-text-muted",
|
|
88
|
+
"data-testid": "assistant-message-system-navigation",
|
|
89
|
+
children: /* @__PURE__ */ _(a, { content: w.content })
|
|
90
|
+
}) : /* @__PURE__ */ _("p", {
|
|
87
91
|
className: "max-w-[90%] whitespace-pre-wrap break-words rounded-lg border border-border-subtle bg-bg-sunken/60 px-3 py-2 text-center text-xs leading-relaxed text-text-muted",
|
|
88
|
-
children:
|
|
92
|
+
children: w.content
|
|
89
93
|
})
|
|
90
94
|
});
|
|
91
95
|
if (K) {
|
|
92
|
-
let e =
|
|
93
|
-
return /* @__PURE__ */
|
|
96
|
+
let e = w.metadata?.attachments ?? [];
|
|
97
|
+
return /* @__PURE__ */ _("div", {
|
|
94
98
|
className: "flex justify-end",
|
|
95
99
|
"data-testid": "assistant-message-user",
|
|
96
|
-
children: /* @__PURE__ */
|
|
100
|
+
children: /* @__PURE__ */ v("div", {
|
|
97
101
|
className: "max-w-[85%]",
|
|
98
102
|
children: [
|
|
99
|
-
|
|
103
|
+
w.content && /* @__PURE__ */ _("div", {
|
|
100
104
|
className: "rounded-2xl rounded-br-md bg-action-primary-bg/12 px-3.5 py-2.5 text-[15px] leading-relaxed text-text-primary",
|
|
101
|
-
children: /* @__PURE__ */
|
|
105
|
+
children: /* @__PURE__ */ _("p", {
|
|
102
106
|
className: "whitespace-pre-wrap",
|
|
103
|
-
children:
|
|
107
|
+
children: w.content
|
|
104
108
|
})
|
|
105
109
|
}),
|
|
106
|
-
/* @__PURE__ */
|
|
107
|
-
/* @__PURE__ */
|
|
110
|
+
/* @__PURE__ */ _(ie, { attachments: e }),
|
|
111
|
+
/* @__PURE__ */ _("div", {
|
|
108
112
|
className: "mt-1 pr-1 text-right text-[10px] text-text-muted",
|
|
109
113
|
children: $
|
|
110
114
|
})
|
|
@@ -112,46 +116,47 @@ var C = () => /* @__PURE__ */ v("span", {
|
|
|
112
116
|
})
|
|
113
117
|
});
|
|
114
118
|
}
|
|
115
|
-
return /* @__PURE__ */
|
|
119
|
+
return /* @__PURE__ */ v("div", {
|
|
116
120
|
className: "flex gap-2.5",
|
|
117
121
|
"data-testid": "assistant-message-assistant",
|
|
118
|
-
children: [/* @__PURE__ */
|
|
122
|
+
children: [/* @__PURE__ */ _(ne, { active: E }), /* @__PURE__ */ v("div", {
|
|
119
123
|
className: "min-w-0 flex-1",
|
|
120
124
|
children: [
|
|
121
|
-
Z.length > 0 && /* @__PURE__ */
|
|
122
|
-
q?.pendingWrite && !
|
|
125
|
+
Z.length > 0 && /* @__PURE__ */ _(te, { steps: Z }),
|
|
126
|
+
q?.pendingWrite && !j ? /* @__PURE__ */ _(ae, {
|
|
123
127
|
pendingWrite: q.pendingWrite,
|
|
124
|
-
onApprove:
|
|
125
|
-
approving:
|
|
126
|
-
expired:
|
|
127
|
-
approved:
|
|
128
|
-
goAheadSent:
|
|
129
|
-
awaitingTurn: !!
|
|
128
|
+
onApprove: l,
|
|
129
|
+
approving: b !== null && b === q.pendingWrite.reference,
|
|
130
|
+
expired: C,
|
|
131
|
+
approved: ue,
|
|
132
|
+
goAheadSent: de,
|
|
133
|
+
awaitingTurn: !!E
|
|
130
134
|
}) : null,
|
|
131
|
-
|
|
132
|
-
Q && /* @__PURE__ */
|
|
135
|
+
M,
|
|
136
|
+
Q && /* @__PURE__ */ _("div", {
|
|
133
137
|
className: "text-[15px] leading-relaxed text-text-primary",
|
|
134
|
-
children: /* @__PURE__ */
|
|
138
|
+
children: /* @__PURE__ */ _(a, { content: Q })
|
|
135
139
|
}),
|
|
136
|
-
X.kind === "working" && /* @__PURE__ */
|
|
137
|
-
X.kind === "stopped" && /* @__PURE__ */
|
|
140
|
+
X.kind === "working" && /* @__PURE__ */ _(se, { processing: Y }),
|
|
141
|
+
X.kind === "stopped" && /* @__PURE__ */ _("p", {
|
|
138
142
|
className: "text-[15px] leading-relaxed text-text-secondary",
|
|
139
143
|
"data-testid": "assistant-turn-stopped",
|
|
140
144
|
children: X.text
|
|
141
145
|
}),
|
|
142
|
-
|
|
143
|
-
|
|
146
|
+
E && /* @__PURE__ */ _(S, {}),
|
|
147
|
+
N,
|
|
148
|
+
J.length > 0 && q?.sandboxId && q.sessionId && /* @__PURE__ */ v("div", {
|
|
144
149
|
className: "mt-3 space-y-2 border-t border-border-subtle pt-2",
|
|
145
|
-
children: [/* @__PURE__ */
|
|
150
|
+
children: [/* @__PURE__ */ _("p", {
|
|
146
151
|
className: "text-[10px] font-medium uppercase tracking-wide text-text-muted",
|
|
147
152
|
children: P("message.downloads", "Downloads")
|
|
148
|
-
}), /* @__PURE__ */
|
|
153
|
+
}), /* @__PURE__ */ _("div", {
|
|
149
154
|
className: "flex flex-wrap gap-2",
|
|
150
155
|
children: J.map((e) => {
|
|
151
156
|
let t = `${e.name}${e.type === "directory" ? ".tar.gz" : ""}`;
|
|
152
|
-
return /* @__PURE__ */
|
|
157
|
+
return /* @__PURE__ */ _(u, {
|
|
153
158
|
label: t,
|
|
154
|
-
disabled:
|
|
159
|
+
disabled: pe === e.path,
|
|
155
160
|
testId: `assistant-artifact-${e.name}`,
|
|
156
161
|
source: {
|
|
157
162
|
kind: "sandbox-artifact",
|
|
@@ -161,58 +166,58 @@ var C = () => /* @__PURE__ */ v("span", {
|
|
|
161
166
|
filename: t
|
|
162
167
|
},
|
|
163
168
|
defaultFolderPath: B.artifacts,
|
|
164
|
-
onDownload: () =>
|
|
169
|
+
onDownload: () => he(e)
|
|
165
170
|
}, e.path);
|
|
166
171
|
})
|
|
167
172
|
})]
|
|
168
173
|
}),
|
|
169
|
-
!
|
|
174
|
+
!E && (Q || D || O) && /* @__PURE__ */ v("div", {
|
|
170
175
|
className: "mt-1.5 flex items-center gap-1",
|
|
171
176
|
children: [
|
|
172
|
-
Q && /* @__PURE__ */
|
|
177
|
+
Q && /* @__PURE__ */ _("button", {
|
|
173
178
|
type: "button",
|
|
174
|
-
onClick:
|
|
179
|
+
onClick: me,
|
|
175
180
|
className: "flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-text-muted transition-colors hover:bg-bg-elevated hover:text-text-secondary",
|
|
176
181
|
"aria-label": P("message.copy", "Copy message"),
|
|
177
182
|
"data-testid": "assistant-message-copy",
|
|
178
|
-
children:
|
|
183
|
+
children: W ? /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _(ce, { className: "size-3 text-status-success-text" }), /* @__PURE__ */ _("span", { children: P("message.copied", "Copied") })] }) : /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _(m, { className: "size-3" }), /* @__PURE__ */ _("span", { children: P("message.copyShort", "Copy") })] })
|
|
179
184
|
}),
|
|
180
|
-
Q &&
|
|
181
|
-
let e =
|
|
182
|
-
return /* @__PURE__ */
|
|
185
|
+
Q && H.isSupported && (() => {
|
|
186
|
+
let e = H.blockedFor(R) ?? H.disabledReason, t = H.isSpeaking(w.id) || H.isSpeaking(z.current), n = !!e && !!k, r = n ? `speak-reason-${w.id}` : void 0;
|
|
187
|
+
return /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ _(oe, {
|
|
183
188
|
isSpeaking: t,
|
|
184
189
|
disabled: e !== null,
|
|
185
190
|
disabledReason: e,
|
|
186
191
|
describedById: r,
|
|
187
192
|
onClick: () => {
|
|
188
193
|
if (t) {
|
|
189
|
-
|
|
194
|
+
H.stop();
|
|
190
195
|
return;
|
|
191
196
|
}
|
|
192
|
-
z.current = R,
|
|
197
|
+
z.current = R, H.toggle(R, Q, L);
|
|
193
198
|
}
|
|
194
|
-
}), n && /* @__PURE__ */
|
|
199
|
+
}), n && /* @__PURE__ */ _("span", {
|
|
195
200
|
id: r,
|
|
196
201
|
className: "text-[11px] text-text-muted",
|
|
197
202
|
"data-testid": "assistant-speak-reason",
|
|
198
203
|
children: e
|
|
199
204
|
})] });
|
|
200
205
|
})(),
|
|
201
|
-
(
|
|
206
|
+
(D || O) && A && !w.metadata?.localAction && /* @__PURE__ */ v("button", {
|
|
202
207
|
type: "button",
|
|
203
|
-
onClick:
|
|
204
|
-
className: `flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] transition-colors hover:bg-bg-elevated ${
|
|
208
|
+
onClick: A,
|
|
209
|
+
className: `flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] transition-colors hover:bg-bg-elevated ${D ? "text-status-error-text" : "text-text-muted hover:text-text-secondary"}`,
|
|
205
210
|
"aria-label": P("message.retry", "Retry"),
|
|
206
211
|
"data-testid": "assistant-message-retry",
|
|
207
|
-
children: [/* @__PURE__ */
|
|
212
|
+
children: [/* @__PURE__ */ _(h, { className: "size-3" }), /* @__PURE__ */ _("span", { children: P("message.retry", "Retry") })]
|
|
208
213
|
})
|
|
209
214
|
]
|
|
210
215
|
}),
|
|
211
|
-
/* @__PURE__ */
|
|
216
|
+
/* @__PURE__ */ v("div", {
|
|
212
217
|
className: "mt-1 text-[10px] text-text-muted",
|
|
213
|
-
children: [$,
|
|
218
|
+
children: [$, w.tokens && /* @__PURE__ */ v("span", {
|
|
214
219
|
className: "ml-2",
|
|
215
|
-
children: [
|
|
220
|
+
children: [w.tokens.input + w.tokens.output, " tokens"]
|
|
216
221
|
})]
|
|
217
222
|
})
|
|
218
223
|
]
|
|
@@ -220,4 +225,4 @@ var C = () => /* @__PURE__ */ v("span", {
|
|
|
220
225
|
});
|
|
221
226
|
};
|
|
222
227
|
//#endregion
|
|
223
|
-
export {
|
|
228
|
+
export { C as AssistantMessageItem, S as StreamingCaret };
|
|
@@ -48,6 +48,11 @@ interface Props {
|
|
|
48
48
|
* Approve (and no "go ahead") can come from it. Absent, nothing is hidden.
|
|
49
49
|
*/
|
|
50
50
|
hidesLegacyWriteCard?: (message: Message) => boolean;
|
|
51
|
+
/**
|
|
52
|
+
* ★ BOFF-8060 (N3): a reply's "Open {page}" offer link, drawn under its
|
|
53
|
+
* text. Absent, none are drawn.
|
|
54
|
+
*/
|
|
55
|
+
renderUiOffers?: (message: Message) => ReactNode;
|
|
51
56
|
}
|
|
52
57
|
/** At most one auto-scroll per this long while a reply is streaming in live. */
|
|
53
58
|
export declare const LIVE_SCROLL_GAP_MS = 250;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantMessageList.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGnE,OAAO,KAAK,EAAE,+BAA+B,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAShF,UAAU,KAAK;IACb;;;OAGG;IACH,qBAAqB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,+BAA+B,GAAG,IAAI,CAAC;IACpD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACvD;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AssistantMessageList.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGnE,OAAO,KAAK,EAAE,+BAA+B,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAShF,UAAU,KAAK;IACb;;;OAGG;IACH,qBAAqB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB;;;;OAIG;IACH,UAAU,CAAC,EAAE,+BAA+B,GAAG,IAAI,CAAC;IACpD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;IACvD;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;IACrD;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC;CAClD;AAED,gFAAgF;AAChF,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,KAAK,CA2J1C,CAAC"}
|
|
@@ -6,61 +6,62 @@ import { useLiveOverlay as o } from "../liveOverlay.js";
|
|
|
6
6
|
import { useEffect as s, useRef as c } from "react";
|
|
7
7
|
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
8
|
//#region src/shared/assistant/ui/AssistantMessageList.tsx
|
|
9
|
-
var d = 250, f = ({ onApprovePendingWrite: d, approvingWriteRef: f = null, approvableMessageId: p = null, retryableMessageId: m = null, messages: h, processing: g, streamingMessageId: _, failedMessageId: v, onRetry: y, renderWriteProposals: b, hidesLegacyWriteCard: x }) => {
|
|
10
|
-
let
|
|
9
|
+
var d = 250, f = ({ onApprovePendingWrite: d, approvingWriteRef: f = null, approvableMessageId: p = null, retryableMessageId: m = null, messages: h, processing: g, streamingMessageId: _, failedMessageId: v, onRetry: y, renderWriteProposals: b, hidesLegacyWriteCard: x, renderUiOffers: S }) => {
|
|
10
|
+
let C = e(), w = (() => {
|
|
11
11
|
for (let e = h.length - 1; e >= 0; --e) if (h[e].role === "assistant") return h[e].id;
|
|
12
12
|
return null;
|
|
13
|
-
})(),
|
|
13
|
+
})(), T = n(h), E = r(h), D = t(h), O = c(null), k = c(null);
|
|
14
14
|
s(() => {
|
|
15
|
-
let e =
|
|
15
|
+
let e = k.current;
|
|
16
16
|
if (e && e.scrollHeight - e.scrollTop - e.clientHeight < 100) {
|
|
17
17
|
let e = i();
|
|
18
|
-
|
|
18
|
+
O.current?.scrollIntoView({ behavior: e ? "auto" : "smooth" });
|
|
19
19
|
}
|
|
20
20
|
}, [h, _]);
|
|
21
|
-
let
|
|
21
|
+
let A = o((e) => e.byMessageId), j = _ === null ? null : A[_]?.content ?? null, M = c(0), N = c(null);
|
|
22
22
|
return s(() => {
|
|
23
|
-
if (
|
|
23
|
+
if (j === null) return;
|
|
24
24
|
let e = () => {
|
|
25
|
-
|
|
26
|
-
let e =
|
|
27
|
-
e && e.scrollHeight - e.scrollTop - e.clientHeight < 100 &&
|
|
28
|
-
}, t =
|
|
29
|
-
t <= 0 ? e() :
|
|
30
|
-
}, [
|
|
31
|
-
|
|
25
|
+
N.current = null, M.current = Date.now();
|
|
26
|
+
let e = k.current;
|
|
27
|
+
e && e.scrollHeight - e.scrollTop - e.clientHeight < 100 && O.current?.scrollIntoView({ behavior: "auto" });
|
|
28
|
+
}, t = M.current + 250 - Date.now();
|
|
29
|
+
t <= 0 ? e() : N.current === null && (N.current = setTimeout(e, t));
|
|
30
|
+
}, [j]), s(() => () => {
|
|
31
|
+
N.current !== null && clearTimeout(N.current);
|
|
32
32
|
}, []), s(() => {
|
|
33
|
-
|
|
33
|
+
O.current?.scrollIntoView({ behavior: "instant" });
|
|
34
34
|
}, []), /* @__PURE__ */ u("div", {
|
|
35
|
-
ref:
|
|
35
|
+
ref: k,
|
|
36
36
|
className: "scrollbar-slim flex-1 space-y-4 overflow-y-auto p-3",
|
|
37
37
|
role: "log",
|
|
38
38
|
"aria-live": "polite",
|
|
39
39
|
"aria-relevant": "additions",
|
|
40
40
|
"aria-busy": _ !== null,
|
|
41
|
-
"aria-label":
|
|
41
|
+
"aria-label": C("messageList.ariaLabel", "Conversation messages"),
|
|
42
42
|
children: [h.map((e) => {
|
|
43
|
-
let t =
|
|
43
|
+
let t = T.has(e.id), n = !t && (e.id === p || e.id === _);
|
|
44
44
|
return /* @__PURE__ */ l(a, {
|
|
45
45
|
onApprovePendingWrite: n ? d : void 0,
|
|
46
46
|
approvingWriteRef: f,
|
|
47
47
|
pendingWriteApproved: t,
|
|
48
|
-
pendingWriteGoAheadSent:
|
|
48
|
+
pendingWriteGoAheadSent: E.has(e.id),
|
|
49
49
|
pendingWriteExpired: !t && !n,
|
|
50
|
-
message: e.id === _ &&
|
|
50
|
+
message: e.id === _ && j !== null ? {
|
|
51
51
|
...e,
|
|
52
|
-
content:
|
|
52
|
+
content: j
|
|
53
53
|
} : e,
|
|
54
54
|
processing: g,
|
|
55
55
|
isStreaming: e.id === _,
|
|
56
56
|
isFailed: e.id === v,
|
|
57
57
|
isLastAssistant: e.id === m,
|
|
58
|
-
isNewestAssistant: e.id ===
|
|
59
|
-
onRetry:
|
|
58
|
+
isNewestAssistant: e.id === w,
|
|
59
|
+
onRetry: D.has(e.id) ? void 0 : y,
|
|
60
60
|
legacyWriteCardHidden: x?.(e) ?? !1,
|
|
61
|
-
writeProposals: b?.(e)
|
|
61
|
+
writeProposals: b?.(e),
|
|
62
|
+
uiOffers: S?.(e)
|
|
62
63
|
}, e.id);
|
|
63
|
-
}), /* @__PURE__ */ l("div", { ref:
|
|
64
|
+
}), /* @__PURE__ */ l("div", { ref: O })]
|
|
64
65
|
});
|
|
65
66
|
};
|
|
66
67
|
//#endregion
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { FC, MouseEvent } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* ★ BOFF-8060 (N3, design §4): the page the model offered, as a link under the
|
|
4
|
+
* reply — never a confirm button.
|
|
5
|
+
*
|
|
6
|
+
* - A real `<a href>` to the REGISTRY path: middle-click and Ctrl/Cmd/Shift/Alt
|
|
7
|
+
* click open it the browser's own way, at sidebar parity, and are not
|
|
8
|
+
* intercepted (nor recorded).
|
|
9
|
+
* - A plain click is handed to the panel (`onOpen`), which re-validates the
|
|
10
|
+
* offer against the live registry and navigates through its registered
|
|
11
|
+
* handler (`runNavigation`). This component never navigates by itself.
|
|
12
|
+
* - The text is "Open {page}" with the REGISTRY label, never the model's words.
|
|
13
|
+
* - Announced once through a polite live region; focus is never moved, and
|
|
14
|
+
* nothing animates.
|
|
15
|
+
* - Semantic tokens only (rule 7); logical padding; the arrow mirrors in RTL.
|
|
16
|
+
*/
|
|
17
|
+
export interface AssistantUiOfferLinkItem {
|
|
18
|
+
offerId: string;
|
|
19
|
+
/** The registry label. */
|
|
20
|
+
label: string;
|
|
21
|
+
/** The registry path (`navTargetPath`). */
|
|
22
|
+
path: string;
|
|
23
|
+
}
|
|
24
|
+
export interface AssistantUiOfferLinkProps extends AssistantUiOfferLinkItem {
|
|
25
|
+
/** A plain, unmodified primary click, with the label the link showed. */
|
|
26
|
+
onOpen: (offerId: string, label: string) => void;
|
|
27
|
+
}
|
|
28
|
+
/** A click the browser should handle itself: new tab, new window, download. */
|
|
29
|
+
export declare function isModifiedClick(event: Pick<MouseEvent, "button" | "metaKey" | "ctrlKey" | "shiftKey" | "altKey">): boolean;
|
|
30
|
+
export declare const UI_OFFER_LINK_CLASS = "inline-flex items-center gap-2 min-h-11 ps-3 pe-3 rounded-md bg-bg-elevated text-text-link border border-border-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-strong";
|
|
31
|
+
export declare const AssistantUiOfferLink: FC<AssistantUiOfferLinkProps>;
|
|
32
|
+
export interface AssistantUiOfferLinksProps {
|
|
33
|
+
offers: readonly AssistantUiOfferLinkItem[];
|
|
34
|
+
/** `read`: "…or “yes”" may be said; `link`: tap or "take me there" only. */
|
|
35
|
+
hint: "read" | "link";
|
|
36
|
+
onOpen: (offerId: string, label: string) => void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The reply's offers and the hint under them. Renders nothing for no offer.
|
|
40
|
+
*
|
|
41
|
+
* The live region starts empty and is filled once after mount, so a screen
|
|
42
|
+
* reader announces it once; it is never changed again for the same offers.
|
|
43
|
+
*/
|
|
44
|
+
export declare const AssistantUiOfferLinks: FC<AssistantUiOfferLinksProps>;
|
|
45
|
+
//# sourceMappingURL=AssistantUiOfferLink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssistantUiOfferLink.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantUiOfferLink.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,EAAE,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAUtE;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IACzE,yEAAyE;IACzE,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAC7B,KAAK,EAAE,IAAI,CACT,UAAU,EACV,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CACzD,GACA,OAAO,CAQT;AAED,eAAO,MAAM,mBAAmB,6MAC4K,CAAC;AAE7M,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CAuB9D,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC5C,4EAA4E;IAC5E,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAClD;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CA+ChE,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useAssistantTr as e } from "../i18n.js";
|
|
2
|
+
import { offerAnnounceText as t, offerHintText as n, offerOpenText as r } from "../localUiCommandCopy.js";
|
|
3
|
+
import { useEffect as i, useState as a } from "react";
|
|
4
|
+
import { ArrowRight as o } from "lucide-react";
|
|
5
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
6
|
+
//#region src/shared/assistant/ui/AssistantUiOfferLink.tsx
|
|
7
|
+
function l(e) {
|
|
8
|
+
return e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey;
|
|
9
|
+
}
|
|
10
|
+
var u = "inline-flex items-center gap-2 min-h-11 ps-3 pe-3 rounded-md bg-bg-elevated text-text-link border border-border-default focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-strong", d = ({ offerId: t, label: n, path: i, onOpen: a }) => /* @__PURE__ */ c("a", {
|
|
11
|
+
href: i,
|
|
12
|
+
className: u,
|
|
13
|
+
"data-testid": "assistant-ui-offer-link",
|
|
14
|
+
"data-offer-id": t,
|
|
15
|
+
onClick: (e) => {
|
|
16
|
+
e.defaultPrevented || l(e) || (e.preventDefault(), a(t, n));
|
|
17
|
+
},
|
|
18
|
+
children: [/* @__PURE__ */ s("span", { children: r(e(), n) }), /* @__PURE__ */ s(o, {
|
|
19
|
+
className: "size-4 rtl:rotate-180",
|
|
20
|
+
"aria-hidden": "true"
|
|
21
|
+
})]
|
|
22
|
+
}), f = ({ offers: r, hint: o, onOpen: l }) => {
|
|
23
|
+
let u = e(), f = r[0], p = f ? t(u, f.label) : "", m = f?.offerId ?? "", [h, g] = a({
|
|
24
|
+
key: "",
|
|
25
|
+
text: ""
|
|
26
|
+
});
|
|
27
|
+
return i(() => {
|
|
28
|
+
m && g((e) => e.key === m ? e : {
|
|
29
|
+
key: m,
|
|
30
|
+
text: p
|
|
31
|
+
});
|
|
32
|
+
}, [m, p]), f ? /* @__PURE__ */ c("div", {
|
|
33
|
+
className: "mt-2 flex flex-col items-start gap-1",
|
|
34
|
+
"data-testid": "assistant-ui-offers",
|
|
35
|
+
children: [
|
|
36
|
+
r.map((e) => /* @__PURE__ */ s(d, {
|
|
37
|
+
...e,
|
|
38
|
+
onOpen: l
|
|
39
|
+
}, e.offerId)),
|
|
40
|
+
/* @__PURE__ */ s("p", {
|
|
41
|
+
className: "text-xs text-text-secondary",
|
|
42
|
+
"data-testid": "assistant-ui-offer-hint",
|
|
43
|
+
children: n(u, o)
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ s("span", {
|
|
46
|
+
className: "sr-only",
|
|
47
|
+
role: "status",
|
|
48
|
+
"aria-live": "polite",
|
|
49
|
+
"data-testid": "assistant-ui-offer-announce",
|
|
50
|
+
children: h.key === m ? h.text : ""
|
|
51
|
+
})
|
|
52
|
+
]
|
|
53
|
+
}) : null;
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
export { d as AssistantUiOfferLink, f as AssistantUiOfferLinks, u as UI_OFFER_LINK_CLASS, l as isModifiedClick };
|
|
@@ -235,6 +235,15 @@ export interface AssistantNavigateOptions {
|
|
|
235
235
|
* for renders beneath the sheet, so it steps aside — but closing unmounts the
|
|
236
236
|
* panel, and collapsing is a class swap on the same node. On desktop the panel
|
|
237
237
|
* sits beside the page and nothing moves.
|
|
238
|
+
*
|
|
239
|
+
* ★★ BOFF-8060 (N4, the leave-page guard): a navigation the ASSISTANT started
|
|
240
|
+
* is refused while the page holds unsaved changes (`useUnsavedChanges`), and
|
|
241
|
+
* the refusal names them so the panel can say where. Nothing is routed, so the
|
|
242
|
+
* draft stays exactly as it was. The person's own navigation (`initiator:
|
|
243
|
+
* "person"`, a link they clicked) is never refused here — sidebar parity — and
|
|
244
|
+
* neither is a shell-less target, which opens in a new tab and leaves this
|
|
245
|
+
* page, and its draft, alone. A caller that does not say who started it is
|
|
246
|
+
* treated as the assistant.
|
|
238
247
|
*/
|
|
239
248
|
export declare function createAssistantNavigate(options: AssistantNavigateOptions): AssistantNavigate;
|
|
240
249
|
/** The quota wall a `<product>:quota-exhausted` event names. */
|