@adecore/agents-react 0.37.2 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat/chat-client.d.ts +1 -0
- package/dist/chat/chat-client.js +2 -1
- package/dist/chat/chat-references.d.ts +16 -1
- package/dist/chat/chat-references.js +29 -3
- package/dist/chat/drafts.d.ts +2 -0
- package/dist/chat/drafts.js +21 -5
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/logic/visual-height.d.ts +1 -0
- package/dist/chat/logic/visual-height.js +1 -1
- package/dist/chat/mentions.d.ts +31 -14
- package/dist/chat/mentions.js +186 -41
- package/dist/chat/stash.d.ts +1 -0
- package/dist/chat/stash.js +4 -2
- package/dist/chat/ui/Composer.js +438 -429
- package/dist/chat/ui/ComposerInput.d.ts +1 -0
- package/dist/chat/ui/ComposerInput.js +2 -0
- package/dist/chat/ui/HostMenuItems.d.ts +4 -0
- package/dist/chat/ui/HostMenuItems.js +15 -0
- package/dist/chat/ui/Markdown.d.ts +3 -1
- package/dist/chat/ui/Markdown.js +194 -120
- package/dist/chat/ui/MessageActions.js +70 -66
- package/dist/chat/ui/ReferenceChip.d.ts +15 -0
- package/dist/chat/ui/ReferenceChip.js +255 -0
- package/dist/chat/ui/Timeline.js +52 -29
- package/dist/chat/ui/TimelineMenu.js +84 -78
- package/dist/chat/ui/VisualFrame.d.ts +8 -0
- package/dist/chat/ui/VisualFrame.js +217 -115
- package/dist/chat/ui/chip-clipboard.d.ts +9 -0
- package/dist/chat/ui/chip-clipboard.js +105 -0
- package/dist/chat/ui/chips.d.ts +5 -0
- package/dist/chat/ui/chips.js +15 -1
- package/dist/chat/ui/composer/ComposerMenu.js +140 -79
- package/dist/chat/ui/composer/DraftParts.d.ts +0 -4
- package/dist/chat/ui/composer/DraftParts.js +0 -41
- package/dist/chat/ui/composer/chip-paste.d.ts +15 -0
- package/dist/chat/ui/composer/chip-paste.js +104 -0
- package/dist/chat/ui/composer/chips.d.ts +5 -0
- package/dist/chat/ui/composer/chips.js +59 -9
- package/dist/chat/ui/composer/key-handler.js +9 -0
- package/dist/chat/ui/composer/use-composer-draft.d.ts +0 -1
- package/dist/chat/ui/composer/use-composer-draft.js +2 -10
- package/dist/chat/ui/composer/use-composer-menus.d.ts +12 -2
- package/dist/chat/ui/composer/use-composer-menus.js +192 -149
- package/dist/chat/ui/composer/use-composer-submit.js +17 -12
- package/dist/chat/ui/composer/use-draft-files.d.ts +7 -1
- package/dist/chat/ui/composer/use-draft-files.js +90 -58
- package/dist/chat/ui/composer/use-take-back.js +2 -1
- package/dist/chat/ui/index.d.ts +1 -1
- package/dist/chat/ui/index.js +1 -1
- package/dist/chat/ui/reference-icons.d.ts +3 -0
- package/dist/chat/ui/reference-icons.js +15 -0
- package/dist/chat/ui/reference-lookup.d.ts +7 -0
- package/dist/chat/ui/reference-lookup.js +6 -0
- package/dist/chat/ui/rehype-chips.d.ts +8 -1
- package/dist/chat/ui/rehype-chips.js +35 -11
- package/dist/chat/ui/rows/GeneratedImageRow.js +8 -4
- package/dist/chat/ui/rows/MessageRows.js +218 -158
- package/dist/chat/ui/rows/VisualRow.js +184 -142
- package/dist/chat/ui/rows/row-rhythm.js +6 -4
- package/dist/chat/ui/thread-references.d.ts +4 -0
- package/dist/chat/ui/thread-references.js +78 -0
- package/dist/host-hooks.d.ts +2 -0
- package/dist/host-hooks.js +7 -0
- package/dist/host.d.ts +14 -1
- package/dist/index.d.ts +1 -1
- package/dist/locales/en/agent-chat.d.ts +20 -3
- package/dist/locales/en/agent-chat.js +24 -7
- package/dist/locales/nl/agent-chat.d.ts +20 -3
- package/dist/locales/nl/agent-chat.js +24 -7
- package/package.json +8 -8
- package/src/chat/chat-client.ts +4 -1
- package/src/chat/chat-references.ts +44 -3
- package/src/chat/drafts.ts +24 -6
- package/src/chat/index.ts +1 -1
- package/src/chat/logic/visual-height.ts +1 -1
- package/src/chat/mentions.ts +202 -36
- package/src/chat/stash.ts +6 -2
- package/src/chat/ui/Composer.tsx +14 -4
- package/src/chat/ui/ComposerInput.tsx +4 -0
- package/src/chat/ui/HostMenuItems.tsx +11 -0
- package/src/chat/ui/Markdown.tsx +57 -25
- package/src/chat/ui/MessageActions.tsx +5 -2
- package/src/chat/ui/ReferenceChip.tsx +74 -0
- package/src/chat/ui/Timeline.tsx +24 -2
- package/src/chat/ui/TimelineMenu.tsx +7 -3
- package/src/chat/ui/VisualFrame.tsx +68 -21
- package/src/chat/ui/chip-clipboard.ts +115 -0
- package/src/chat/ui/chips.ts +20 -1
- package/src/chat/ui/composer/ComposerMenu.tsx +53 -37
- package/src/chat/ui/composer/DraftParts.tsx +0 -12
- package/src/chat/ui/composer/chip-paste.ts +122 -0
- package/src/chat/ui/composer/chips.ts +60 -10
- package/src/chat/ui/composer/key-handler.ts +9 -0
- package/src/chat/ui/composer/use-composer-draft.ts +1 -7
- package/src/chat/ui/composer/use-composer-menus.ts +68 -29
- package/src/chat/ui/composer/use-composer-submit.ts +13 -6
- package/src/chat/ui/composer/use-draft-files.ts +39 -5
- package/src/chat/ui/composer/use-take-back.ts +2 -1
- package/src/chat/ui/index.ts +1 -1
- package/src/chat/ui/reference-icons.ts +17 -0
- package/src/chat/ui/reference-lookup.ts +13 -0
- package/src/chat/ui/rehype-chips.ts +38 -13
- package/src/chat/ui/rows/GeneratedImageRow.tsx +9 -4
- package/src/chat/ui/rows/MessageRows.tsx +88 -64
- package/src/chat/ui/rows/VisualRow.tsx +5 -1
- package/src/chat/ui/rows/row-rhythm.ts +6 -4
- package/src/chat/ui/thread-references.ts +47 -0
- package/src/host-hooks.ts +9 -0
- package/src/host.ts +24 -1
- package/src/index.ts +1 -0
- package/src/locales/en/agent-chat.ts +24 -7
- package/src/locales/nl/agent-chat.ts +24 -7
- package/dist/chat/ui/ChatReferenceChip.d.ts +0 -4
- package/dist/chat/ui/ChatReferenceChip.js +0 -110
- package/src/chat/ui/ChatReferenceChip.tsx +0 -26
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { c as _c } from "react/compiler-runtime";
|
|
2
|
-
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
-
import { visualThemeFragment } from '@adecore/agent-contracts/visual';
|
|
5
|
+
import { VISUAL_LIMITS, visualThemeFragment } from '@adecore/agent-contracts/visual';
|
|
6
6
|
import { Spinner, useMeasuredWidth } from '@adecore/ui';
|
|
7
7
|
import { useChatHost } from '../../host.js';
|
|
8
8
|
import { useChatScope } from '../../scope.js';
|
|
9
|
-
import { initialVisualContentHeight, rememberVisualHeight } from '../logic/visual-height.js';
|
|
9
|
+
import { DEFAULT_HEIGHT_PX, initialVisualContentHeight, rememberVisualHeight } from '../logic/visual-height.js';
|
|
10
10
|
import { VisualBridge } from '../visual-bridge.js';
|
|
11
11
|
import { VisualViewportController } from '../visual-viewport.js';
|
|
12
12
|
import { useVisualTheme } from './visual-theme.js';
|
|
@@ -19,13 +19,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
19
19
|
function personActsIn(frame) {
|
|
20
20
|
return frame.ownerDocument.activeElement === frame && navigator.userActivation?.isActive !== false;
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* the theme. The frame never gets `allow-same-origin`, which keeps the page on an opaque origin even
|
|
25
|
-
* when the host page is served on the app's own. Its box keeps one height while it loads or fails.
|
|
26
|
-
*/
|
|
22
|
+
const defaultHeight = () => DEFAULT_HEIGHT_PX;
|
|
23
|
+
/* A visual of a chat, its page read from the chat's attachments under the visual's id. */
|
|
27
24
|
export function VisualFrame(t0) {
|
|
28
|
-
const $ = _c(
|
|
25
|
+
const $ = _c(17);
|
|
29
26
|
const {
|
|
30
27
|
chatId,
|
|
31
28
|
visual,
|
|
@@ -34,13 +31,123 @@ export function VisualFrame(t0) {
|
|
|
34
31
|
} = t0;
|
|
35
32
|
const fill = t1 === undefined ? false : t1;
|
|
36
33
|
const {
|
|
37
|
-
visuals,
|
|
38
34
|
attachments
|
|
39
35
|
} = useChatHost();
|
|
36
|
+
const scope = useChatScope();
|
|
37
|
+
let t2;
|
|
38
|
+
if ($[0] !== attachments || $[1] !== chatId || $[2] !== scope.id || $[3] !== visual.id) {
|
|
39
|
+
t2 = () => attachments.read(scope.id, chatId, visual.id).then(_temp);
|
|
40
|
+
$[0] = attachments;
|
|
41
|
+
$[1] = chatId;
|
|
42
|
+
$[2] = scope.id;
|
|
43
|
+
$[3] = visual.id;
|
|
44
|
+
$[4] = t2;
|
|
45
|
+
} else {
|
|
46
|
+
t2 = $[4];
|
|
47
|
+
}
|
|
48
|
+
const page = t2;
|
|
49
|
+
let t3;
|
|
50
|
+
if ($[5] !== visual) {
|
|
51
|
+
t3 = width => initialVisualContentHeight(visual, width);
|
|
52
|
+
$[5] = visual;
|
|
53
|
+
$[6] = t3;
|
|
54
|
+
} else {
|
|
55
|
+
t3 = $[6];
|
|
56
|
+
}
|
|
57
|
+
let t4;
|
|
58
|
+
if ($[7] !== visual.id) {
|
|
59
|
+
t4 = (width_0, height) => rememberVisualHeight(visual.id, width_0, height);
|
|
60
|
+
$[7] = visual.id;
|
|
61
|
+
$[8] = t4;
|
|
62
|
+
} else {
|
|
63
|
+
t4 = $[8];
|
|
64
|
+
}
|
|
65
|
+
let t5;
|
|
66
|
+
if ($[9] !== className || $[10] !== fill || $[11] !== page || $[12] !== t3 || $[13] !== t4 || $[14] !== visual.maxHeight || $[15] !== visual.title) {
|
|
67
|
+
t5 = /*#__PURE__*/_jsx(PageFrame, {
|
|
68
|
+
page: page,
|
|
69
|
+
title: visual.title,
|
|
70
|
+
maxHeight: visual.maxHeight,
|
|
71
|
+
fill: fill,
|
|
72
|
+
className: className,
|
|
73
|
+
initialHeight: t3,
|
|
74
|
+
onHeight: t4
|
|
75
|
+
});
|
|
76
|
+
$[9] = className;
|
|
77
|
+
$[10] = fill;
|
|
78
|
+
$[11] = page;
|
|
79
|
+
$[12] = t3;
|
|
80
|
+
$[13] = t4;
|
|
81
|
+
$[14] = visual.maxHeight;
|
|
82
|
+
$[15] = visual.title;
|
|
83
|
+
$[16] = t5;
|
|
84
|
+
} else {
|
|
85
|
+
t5 = $[16];
|
|
86
|
+
}
|
|
87
|
+
return t5;
|
|
88
|
+
}
|
|
89
|
+
/*
|
|
90
|
+
* A visual's page outside a chat thread, such as one an app kept: the same sandboxed frame, theme and
|
|
91
|
+
* links as in a thread, with the page read through `page`. Draws nothing while the host has no `visuals`.
|
|
92
|
+
*/
|
|
93
|
+
function _temp(blob) {
|
|
94
|
+
return blob.text();
|
|
95
|
+
}
|
|
96
|
+
export function VisualPageFrame(t0) {
|
|
97
|
+
const $ = _c(6);
|
|
98
|
+
let props;
|
|
99
|
+
let t1;
|
|
100
|
+
if ($[0] !== t0) {
|
|
101
|
+
({
|
|
102
|
+
maxHeight: t1,
|
|
103
|
+
...props
|
|
104
|
+
} = t0);
|
|
105
|
+
$[0] = t0;
|
|
106
|
+
$[1] = props;
|
|
107
|
+
$[2] = t1;
|
|
108
|
+
} else {
|
|
109
|
+
props = $[1];
|
|
110
|
+
t1 = $[2];
|
|
111
|
+
}
|
|
112
|
+
const maxHeight = t1 === undefined ? VISUAL_LIMITS.maxHeight : t1;
|
|
113
|
+
let t2;
|
|
114
|
+
if ($[3] !== maxHeight || $[4] !== props) {
|
|
115
|
+
t2 = /*#__PURE__*/_jsx(PageFrame, {
|
|
116
|
+
...props,
|
|
117
|
+
maxHeight: maxHeight,
|
|
118
|
+
initialHeight: defaultHeight
|
|
119
|
+
});
|
|
120
|
+
$[3] = maxHeight;
|
|
121
|
+
$[4] = props;
|
|
122
|
+
$[5] = t2;
|
|
123
|
+
} else {
|
|
124
|
+
t2 = $[5];
|
|
125
|
+
}
|
|
126
|
+
return t2;
|
|
127
|
+
}
|
|
128
|
+
/*
|
|
129
|
+
* One page in a frame that loads the app's sandbox host page; the bridge hands it the page and the
|
|
130
|
+
* theme. The frame never gets `allow-same-origin`, which keeps the page on an opaque origin even when
|
|
131
|
+
* the host page is served on the app's own. Its box keeps one height while it loads or fails.
|
|
132
|
+
*/
|
|
133
|
+
function PageFrame(t0) {
|
|
134
|
+
const $ = _c(61);
|
|
135
|
+
const {
|
|
136
|
+
page,
|
|
137
|
+
title,
|
|
138
|
+
maxHeight,
|
|
139
|
+
fill: t1,
|
|
140
|
+
className,
|
|
141
|
+
initialHeight,
|
|
142
|
+
onHeight
|
|
143
|
+
} = t0;
|
|
144
|
+
const fill = t1 === undefined ? false : t1;
|
|
145
|
+
const {
|
|
146
|
+
visuals
|
|
147
|
+
} = useChatHost();
|
|
40
148
|
const {
|
|
41
149
|
t
|
|
42
150
|
} = useTranslation("agent-chat");
|
|
43
|
-
const scope = useChatScope();
|
|
44
151
|
const frameUrl = visuals?.frameUrl ?? null;
|
|
45
152
|
const boxRef = useRef(null);
|
|
46
153
|
const frameRef = useRef(null);
|
|
@@ -63,6 +170,7 @@ export function VisualFrame(t0) {
|
|
|
63
170
|
const setBox = t2;
|
|
64
171
|
const theme = useVisualTheme(boxRef);
|
|
65
172
|
const widthRef = useRef(width);
|
|
173
|
+
const onHeightRef = useRef(onHeight);
|
|
66
174
|
const [reported, setReported] = useState(null);
|
|
67
175
|
const [drawn, setDrawn] = useState(null);
|
|
68
176
|
const [failed, setFailed] = useState(false);
|
|
@@ -74,11 +182,11 @@ export function VisualFrame(t0) {
|
|
|
74
182
|
});
|
|
75
183
|
}
|
|
76
184
|
let t3;
|
|
77
|
-
if ($[2] !== fill || $[3] !==
|
|
78
|
-
t3 = fill || width === 0 ? undefined : reported ??
|
|
185
|
+
if ($[2] !== fill || $[3] !== initialHeight || $[4] !== reported || $[5] !== width) {
|
|
186
|
+
t3 = fill || width === 0 ? undefined : reported ?? initialHeight(width);
|
|
79
187
|
$[2] = fill;
|
|
80
|
-
$[3] =
|
|
81
|
-
$[4] =
|
|
188
|
+
$[3] = initialHeight;
|
|
189
|
+
$[4] = reported;
|
|
82
190
|
$[5] = width;
|
|
83
191
|
$[6] = t3;
|
|
84
192
|
} else {
|
|
@@ -87,22 +195,24 @@ export function VisualFrame(t0) {
|
|
|
87
195
|
const height = t3;
|
|
88
196
|
let t4;
|
|
89
197
|
let t5;
|
|
90
|
-
if ($[7] !== width) {
|
|
198
|
+
if ($[7] !== onHeight || $[8] !== width) {
|
|
91
199
|
t4 = () => {
|
|
92
200
|
widthRef.current = width;
|
|
201
|
+
onHeightRef.current = onHeight;
|
|
93
202
|
};
|
|
94
|
-
t5 = [width];
|
|
95
|
-
$[7] =
|
|
96
|
-
$[8] =
|
|
97
|
-
$[9] =
|
|
203
|
+
t5 = [width, onHeight];
|
|
204
|
+
$[7] = onHeight;
|
|
205
|
+
$[8] = width;
|
|
206
|
+
$[9] = t4;
|
|
207
|
+
$[10] = t5;
|
|
98
208
|
} else {
|
|
99
|
-
t4 = $[
|
|
100
|
-
t5 = $[
|
|
209
|
+
t4 = $[9];
|
|
210
|
+
t5 = $[10];
|
|
101
211
|
}
|
|
102
212
|
useLayoutEffect(t4, t5);
|
|
103
213
|
let t6;
|
|
104
214
|
let t7;
|
|
105
|
-
if ($[
|
|
215
|
+
if ($[11] !== fill || $[12] !== maxHeight || $[13] !== opening || $[14] !== page || $[15] !== visuals) {
|
|
106
216
|
t6 = () => {
|
|
107
217
|
const frame = frameRef.current;
|
|
108
218
|
if (opening === null || frame === null) {
|
|
@@ -111,9 +221,9 @@ export function VisualFrame(t0) {
|
|
|
111
221
|
const bridge = new VisualBridge({
|
|
112
222
|
frame: () => frame.contentWindow,
|
|
113
223
|
visual: {
|
|
114
|
-
maxHeight
|
|
224
|
+
maxHeight
|
|
115
225
|
},
|
|
116
|
-
page:
|
|
226
|
+
page: page(),
|
|
117
227
|
theme: opening.theme,
|
|
118
228
|
mayOpenLink: () => personActsIn(frame),
|
|
119
229
|
openLink: url => visuals?.openLink(url),
|
|
@@ -122,7 +232,7 @@ export function VisualFrame(t0) {
|
|
|
122
232
|
return;
|
|
123
233
|
}
|
|
124
234
|
setReported(next);
|
|
125
|
-
|
|
235
|
+
onHeightRef.current?.(widthRef.current, next);
|
|
126
236
|
},
|
|
127
237
|
...(!fill ? {
|
|
128
238
|
onViewportReady: () => setViewportReady(true),
|
|
@@ -141,24 +251,21 @@ export function VisualFrame(t0) {
|
|
|
141
251
|
bridgeRef.current = null;
|
|
142
252
|
};
|
|
143
253
|
};
|
|
144
|
-
t7 = [opening,
|
|
145
|
-
$[
|
|
146
|
-
$[
|
|
147
|
-
$[12] = fill;
|
|
254
|
+
t7 = [opening, page, maxHeight, fill, visuals];
|
|
255
|
+
$[11] = fill;
|
|
256
|
+
$[12] = maxHeight;
|
|
148
257
|
$[13] = opening;
|
|
149
|
-
$[14] =
|
|
150
|
-
$[15] =
|
|
151
|
-
$[16] =
|
|
152
|
-
$[17] =
|
|
153
|
-
$[18] = t6;
|
|
154
|
-
$[19] = t7;
|
|
258
|
+
$[14] = page;
|
|
259
|
+
$[15] = visuals;
|
|
260
|
+
$[16] = t6;
|
|
261
|
+
$[17] = t7;
|
|
155
262
|
} else {
|
|
156
|
-
t6 = $[
|
|
157
|
-
t7 = $[
|
|
263
|
+
t6 = $[16];
|
|
264
|
+
t7 = $[17];
|
|
158
265
|
}
|
|
159
266
|
useLayoutEffect(t6, t7);
|
|
160
267
|
let t8;
|
|
161
|
-
if ($[
|
|
268
|
+
if ($[18] !== fill || $[19] !== viewportReady) {
|
|
162
269
|
t8 = () => {
|
|
163
270
|
const box = boxRef.current;
|
|
164
271
|
const viewport = viewportRef.current;
|
|
@@ -174,98 +281,96 @@ export function VisualFrame(t0) {
|
|
|
174
281
|
controllerRef.current = null;
|
|
175
282
|
};
|
|
176
283
|
};
|
|
177
|
-
$[
|
|
178
|
-
$[
|
|
179
|
-
$[
|
|
284
|
+
$[18] = fill;
|
|
285
|
+
$[19] = viewportReady;
|
|
286
|
+
$[20] = t8;
|
|
180
287
|
} else {
|
|
181
|
-
t8 = $[
|
|
288
|
+
t8 = $[20];
|
|
182
289
|
}
|
|
183
290
|
let t9;
|
|
184
|
-
if ($[
|
|
185
|
-
t9 = [fill, viewportReady, opening,
|
|
186
|
-
$[
|
|
187
|
-
$[
|
|
188
|
-
$[
|
|
189
|
-
$[
|
|
190
|
-
$[
|
|
191
|
-
$[
|
|
192
|
-
$[29] = visual.maxHeight;
|
|
193
|
-
$[30] = t9;
|
|
291
|
+
if ($[21] !== fill || $[22] !== maxHeight || $[23] !== opening || $[24] !== page || $[25] !== viewportReady) {
|
|
292
|
+
t9 = [fill, viewportReady, opening, page, maxHeight];
|
|
293
|
+
$[21] = fill;
|
|
294
|
+
$[22] = maxHeight;
|
|
295
|
+
$[23] = opening;
|
|
296
|
+
$[24] = page;
|
|
297
|
+
$[25] = viewportReady;
|
|
298
|
+
$[26] = t9;
|
|
194
299
|
} else {
|
|
195
|
-
t9 = $[
|
|
300
|
+
t9 = $[26];
|
|
196
301
|
}
|
|
197
302
|
useLayoutEffect(t8, t9);
|
|
198
303
|
let t10;
|
|
199
|
-
if ($[
|
|
304
|
+
if ($[27] === Symbol.for("react.memo_cache_sentinel")) {
|
|
200
305
|
t10 = () => controllerRef.current?.refresh();
|
|
201
|
-
$[
|
|
306
|
+
$[27] = t10;
|
|
202
307
|
} else {
|
|
203
|
-
t10 = $[
|
|
308
|
+
t10 = $[27];
|
|
204
309
|
}
|
|
205
310
|
let t11;
|
|
206
|
-
if ($[
|
|
311
|
+
if ($[28] !== height || $[29] !== width) {
|
|
207
312
|
t11 = [height, width];
|
|
208
|
-
$[
|
|
209
|
-
$[
|
|
210
|
-
$[
|
|
313
|
+
$[28] = height;
|
|
314
|
+
$[29] = width;
|
|
315
|
+
$[30] = t11;
|
|
211
316
|
} else {
|
|
212
|
-
t11 = $[
|
|
317
|
+
t11 = $[30];
|
|
213
318
|
}
|
|
214
319
|
useLayoutEffect(t10, t11);
|
|
215
320
|
let t12;
|
|
216
321
|
let t13;
|
|
217
|
-
if ($[
|
|
322
|
+
if ($[31] !== theme) {
|
|
218
323
|
t12 = () => {
|
|
219
324
|
if (theme !== null) {
|
|
220
325
|
bridgeRef.current?.setTheme(theme);
|
|
221
326
|
}
|
|
222
327
|
};
|
|
223
328
|
t13 = [theme];
|
|
224
|
-
$[
|
|
225
|
-
$[
|
|
226
|
-
$[
|
|
329
|
+
$[31] = theme;
|
|
330
|
+
$[32] = t12;
|
|
331
|
+
$[33] = t13;
|
|
227
332
|
} else {
|
|
228
|
-
t12 = $[
|
|
229
|
-
t13 = $[
|
|
333
|
+
t12 = $[32];
|
|
334
|
+
t13 = $[33];
|
|
230
335
|
}
|
|
231
336
|
useEffect(t12, t13);
|
|
232
337
|
const t14 = fill ? "absolute inset-0" : "relative w-full";
|
|
233
338
|
let t15;
|
|
234
|
-
if ($[
|
|
339
|
+
if ($[34] !== className || $[35] !== t14) {
|
|
235
340
|
t15 = clsx(t14, className);
|
|
236
|
-
$[
|
|
237
|
-
$[
|
|
238
|
-
$[
|
|
341
|
+
$[34] = className;
|
|
342
|
+
$[35] = t14;
|
|
343
|
+
$[36] = t15;
|
|
239
344
|
} else {
|
|
240
|
-
t15 = $[
|
|
345
|
+
t15 = $[36];
|
|
241
346
|
}
|
|
242
347
|
let t16;
|
|
243
|
-
if ($[
|
|
348
|
+
if ($[37] !== height) {
|
|
244
349
|
t16 = {
|
|
245
350
|
height
|
|
246
351
|
};
|
|
247
|
-
$[
|
|
248
|
-
$[
|
|
352
|
+
$[37] = height;
|
|
353
|
+
$[38] = t16;
|
|
249
354
|
} else {
|
|
250
|
-
t16 = $[
|
|
355
|
+
t16 = $[38];
|
|
251
356
|
}
|
|
252
357
|
const t17 = fill ? "absolute inset-0" : "sticky top-0 w-full";
|
|
253
358
|
let t18;
|
|
254
|
-
if ($[
|
|
359
|
+
if ($[39] !== fill) {
|
|
255
360
|
t18 = fill ? undefined : {
|
|
256
361
|
height: "100%"
|
|
257
362
|
};
|
|
258
|
-
$[
|
|
259
|
-
$[
|
|
363
|
+
$[39] = fill;
|
|
364
|
+
$[40] = t18;
|
|
260
365
|
} else {
|
|
261
|
-
t18 = $[
|
|
366
|
+
t18 = $[40];
|
|
262
367
|
}
|
|
263
368
|
let t19;
|
|
264
|
-
if ($[
|
|
369
|
+
if ($[41] !== drawn || $[42] !== failed || $[43] !== opening || $[44] !== title) {
|
|
265
370
|
t19 = opening !== null && /*#__PURE__*/_jsx("iframe", {
|
|
266
371
|
ref: frameRef,
|
|
267
372
|
src: opening.src,
|
|
268
|
-
title:
|
|
373
|
+
title: title,
|
|
269
374
|
loading: "lazy",
|
|
270
375
|
sandbox: "allow-scripts allow-forms",
|
|
271
376
|
className: clsx("block size-full border-0", failed && "invisible"),
|
|
@@ -274,72 +379,69 @@ export function VisualFrame(t0) {
|
|
|
274
379
|
},
|
|
275
380
|
onLoad: () => bridgeRef.current?.loaded()
|
|
276
381
|
});
|
|
277
|
-
$[
|
|
278
|
-
$[
|
|
279
|
-
$[
|
|
280
|
-
$[
|
|
281
|
-
$[
|
|
382
|
+
$[41] = drawn;
|
|
383
|
+
$[42] = failed;
|
|
384
|
+
$[43] = opening;
|
|
385
|
+
$[44] = title;
|
|
386
|
+
$[45] = t19;
|
|
282
387
|
} else {
|
|
283
|
-
t19 = $[
|
|
388
|
+
t19 = $[45];
|
|
284
389
|
}
|
|
285
390
|
let t20;
|
|
286
|
-
if ($[
|
|
391
|
+
if ($[46] !== drawn || $[47] !== failed || $[48] !== t || $[49] !== title) {
|
|
287
392
|
t20 = failed ? /*#__PURE__*/_jsx("p", {
|
|
288
393
|
className: "absolute inset-0 grid place-items-center px-4 text-center text-xs text-text-muted",
|
|
289
394
|
children: t("visuals.failed", {
|
|
290
|
-
title
|
|
395
|
+
title
|
|
291
396
|
})
|
|
292
397
|
}) : drawn === null && /*#__PURE__*/_jsx("span", {
|
|
293
398
|
className: "chat-visual-wait pointer-events-none absolute inset-0 grid place-items-center text-text-faint",
|
|
294
399
|
children: /*#__PURE__*/_jsx(Spinner, {
|
|
295
400
|
size: 16,
|
|
296
401
|
label: t("visuals.loading", {
|
|
297
|
-
title
|
|
402
|
+
title
|
|
298
403
|
})
|
|
299
404
|
})
|
|
300
405
|
});
|
|
301
|
-
$[
|
|
302
|
-
$[
|
|
303
|
-
$[
|
|
304
|
-
$[
|
|
305
|
-
$[
|
|
406
|
+
$[46] = drawn;
|
|
407
|
+
$[47] = failed;
|
|
408
|
+
$[48] = t;
|
|
409
|
+
$[49] = title;
|
|
410
|
+
$[50] = t20;
|
|
306
411
|
} else {
|
|
307
|
-
t20 = $[
|
|
412
|
+
t20 = $[50];
|
|
308
413
|
}
|
|
309
414
|
let t21;
|
|
310
|
-
if ($[
|
|
415
|
+
if ($[51] !== t17 || $[52] !== t18 || $[53] !== t19 || $[54] !== t20) {
|
|
311
416
|
t21 = /*#__PURE__*/_jsxs("div", {
|
|
312
417
|
ref: viewportRef,
|
|
313
418
|
className: t17,
|
|
314
419
|
style: t18,
|
|
315
420
|
children: [t19, t20]
|
|
316
421
|
});
|
|
317
|
-
$[
|
|
318
|
-
$[
|
|
319
|
-
$[
|
|
320
|
-
$[
|
|
321
|
-
$[
|
|
422
|
+
$[51] = t17;
|
|
423
|
+
$[52] = t18;
|
|
424
|
+
$[53] = t19;
|
|
425
|
+
$[54] = t20;
|
|
426
|
+
$[55] = t21;
|
|
322
427
|
} else {
|
|
323
|
-
t21 = $[
|
|
428
|
+
t21 = $[55];
|
|
324
429
|
}
|
|
325
430
|
let t22;
|
|
326
|
-
if ($[
|
|
431
|
+
if ($[56] !== setBox || $[57] !== t15 || $[58] !== t16 || $[59] !== t21) {
|
|
327
432
|
t22 = /*#__PURE__*/_jsx("div", {
|
|
328
433
|
ref: setBox,
|
|
329
434
|
className: t15,
|
|
330
435
|
style: t16,
|
|
331
436
|
children: t21
|
|
332
437
|
});
|
|
333
|
-
$[
|
|
334
|
-
$[
|
|
335
|
-
$[
|
|
336
|
-
$[
|
|
337
|
-
$[
|
|
438
|
+
$[56] = setBox;
|
|
439
|
+
$[57] = t15;
|
|
440
|
+
$[58] = t16;
|
|
441
|
+
$[59] = t21;
|
|
442
|
+
$[60] = t22;
|
|
338
443
|
} else {
|
|
339
|
-
t22 = $[
|
|
444
|
+
t22 = $[60];
|
|
340
445
|
}
|
|
341
446
|
return t22;
|
|
342
|
-
}
|
|
343
|
-
function _temp(blob) {
|
|
344
|
-
return blob.text();
|
|
345
447
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChatAssistantItem, ChatUserItem } from '@adecore/agent-contracts';
|
|
2
|
+
import { type ClipboardChips } from '../mentions.js';
|
|
3
|
+
import type { TimelineRow } from '../logic/timeline.js';
|
|
4
|
+
import type { ReferenceLookup } from './reference-lookup.js';
|
|
5
|
+
export declare function messageClipboardChips(item: ChatUserItem | ChatAssistantItem, text: string, lookup: Pick<ReferenceLookup, 'items' | 'referenced'>): ClipboardChips;
|
|
6
|
+
export declare function rowClipboardChips(row: TimelineRow, text: string, lookup: Pick<ReferenceLookup, 'items' | 'referenced'>): ClipboardChips;
|
|
7
|
+
export declare function selectionChips(selection: Selection): ClipboardChips;
|
|
8
|
+
export declare function copySelectionWithChips(event: ClipboardEvent): void;
|
|
9
|
+
export declare function copyWithChips(chips: ClipboardChips): void;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { copyText } from '@adecore/ui';
|
|
2
|
+
import { referenceTokens } from '../chat-references.js';
|
|
3
|
+
import { clipboardChipsOf, hasClipboardChips, tokenizeChips, tokenizeNamedReferences, writeClipboardChips } from '../mentions.js';
|
|
4
|
+
/* The chips a copy of a whole message carries: what the person picked, or what a reply names. */
|
|
5
|
+
export function messageClipboardChips(item, text, lookup) {
|
|
6
|
+
if (item.kind === 'assistant') {
|
|
7
|
+
return clipboardChipsOf(text, tokenizeNamedReferences(text, lookup.items, lookup.referenced));
|
|
8
|
+
}
|
|
9
|
+
const tokens = referenceTokens([...(item.chats ?? []), ...(item.references ?? [])], lookup.items);
|
|
10
|
+
return clipboardChipsOf(text, tokenizeChips(text, item.mentions ?? [], item.skills ?? [], tokens));
|
|
11
|
+
}
|
|
12
|
+
/* The chips a copy of a row of the thread carries; only a message has any. */
|
|
13
|
+
export function rowClipboardChips(row, text, lookup) {
|
|
14
|
+
if (row.kind === 'user' || row.kind === 'assistant') {
|
|
15
|
+
return messageClipboardChips(row.item, text, lookup);
|
|
16
|
+
}
|
|
17
|
+
return clipboardChipsOf(text, []);
|
|
18
|
+
}
|
|
19
|
+
/* What a chip the transcript drew stands for, read back from the attributes `TokenChip` writes. */
|
|
20
|
+
function segmentOf(chip) {
|
|
21
|
+
const value = chip.getAttribute('data-chip-value');
|
|
22
|
+
if (value === null) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
switch (chip.getAttribute('data-chip')) {
|
|
26
|
+
case 'mention':
|
|
27
|
+
return {
|
|
28
|
+
kind: 'mention',
|
|
29
|
+
path: value
|
|
30
|
+
};
|
|
31
|
+
case 'skill':
|
|
32
|
+
return {
|
|
33
|
+
kind: 'skill',
|
|
34
|
+
name: value
|
|
35
|
+
};
|
|
36
|
+
case 'reference':
|
|
37
|
+
{
|
|
38
|
+
const name = chip.getAttribute('data-chip-name');
|
|
39
|
+
return name === null || name === '' ? null : {
|
|
40
|
+
kind: 'reference',
|
|
41
|
+
id: value,
|
|
42
|
+
name
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
default:
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/* The chips a selection holds whole, beside the text it copies; a chip cut in half is only text. */
|
|
50
|
+
export function selectionChips(selection) {
|
|
51
|
+
const segments = [];
|
|
52
|
+
for (let i = 0; i < selection.rangeCount; i++) {
|
|
53
|
+
const container = selection.getRangeAt(i).commonAncestorContainer;
|
|
54
|
+
const root = container instanceof Element ? container : container.parentElement;
|
|
55
|
+
const own = root?.closest('[data-chip]');
|
|
56
|
+
const candidates = own ? [own] : [...(root?.querySelectorAll('[data-chip]') ?? [])];
|
|
57
|
+
for (const chip of candidates) {
|
|
58
|
+
const segment = selection.containsNode(chip, false) ? segmentOf(chip) : null;
|
|
59
|
+
if (segment !== null) {
|
|
60
|
+
segments.push(segment);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return clipboardChipsOf(selection.toString(), segments);
|
|
65
|
+
}
|
|
66
|
+
/* A copy of a selection in the thread, which carries the chips in it as well when it holds any. */
|
|
67
|
+
export function copySelectionWithChips(event) {
|
|
68
|
+
const selection = document.getSelection();
|
|
69
|
+
if (event.defaultPrevented || event.clipboardData === null || selection === null || selection.isCollapsed) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const chips = selectionChips(selection);
|
|
73
|
+
if (!hasClipboardChips(chips)) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
writeClipboardChips(event.clipboardData, chips);
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
}
|
|
79
|
+
/*
|
|
80
|
+
* Copies a text and its chips. The asynchronous clipboard writes no type of an app's own that a paste
|
|
81
|
+
* can read, so the copy goes through a copy event, which only a page with the user's gesture gets.
|
|
82
|
+
*/
|
|
83
|
+
export function copyWithChips(chips) {
|
|
84
|
+
if (!hasClipboardChips(chips) || typeof document.execCommand !== 'function') {
|
|
85
|
+
void copyText(chips.text);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
let written = false;
|
|
89
|
+
const write = event => {
|
|
90
|
+
if (event.clipboardData !== null) {
|
|
91
|
+
writeClipboardChips(event.clipboardData, chips);
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
written = true;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
document.addEventListener('copy', write, true);
|
|
97
|
+
try {
|
|
98
|
+
document.execCommand('copy');
|
|
99
|
+
} finally {
|
|
100
|
+
document.removeEventListener('copy', write, true);
|
|
101
|
+
}
|
|
102
|
+
if (!written) {
|
|
103
|
+
void copyText(chips.text);
|
|
104
|
+
}
|
|
105
|
+
}
|
package/dist/chat/ui/chips.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
export declare const MENTION_TONE = "bg-accent-soft text-accent shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--accent)_25%,transparent)]";
|
|
2
2
|
export declare const SKILL_TONE = "bg-skill-soft text-skill shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--skill)_25%,transparent)]";
|
|
3
|
+
export declare const REFERENCE_TONE = "bg-text/8 text-text shadow-[inset_0_0_0_1px_var(--border-strong)]";
|
|
4
|
+
export declare const REFERENCE_GONE_TONE = "bg-text/4 text-text-faint shadow-[inset_0_0_0_1px_var(--border)]";
|
|
3
5
|
export declare const CHIP_IN_EDITOR = "box-decoration-clone rounded-md px-1 py-0.5";
|
|
6
|
+
export declare const TOKEN_IN_MESSAGE = "box-decoration-clone rounded-md px-1.5 py-0.5 text-xs font-medium";
|
|
7
|
+
export declare const TOKEN_ICON = "mr-1 inline align-[calc(0.5cap-7px)]!";
|
|
8
|
+
export declare const TOKEN_ICON_IN_EDITOR = "mr-1 inline-block align-[calc(0.5cap-6px)]";
|
|
4
9
|
export declare const CHIP_IN_MESSAGE = "inline-flex h-5 max-w-full items-center gap-1 rounded-md px-1.5 align-[-3px] text-xs/none font-medium";
|
package/dist/chat/ui/chips.js
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
|
-
/* An `@file` or
|
|
1
|
+
/* An `@file`, `$skill` or `#reference` token drawn as a pill: the tone says which it is, the shape
|
|
2
2
|
says where it is drawn. */
|
|
3
3
|
export const MENTION_TONE = 'bg-accent-soft text-accent shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--accent)_25%,transparent)]';
|
|
4
4
|
/* A skill is the same token shape as a file mention, in its own hue. */
|
|
5
5
|
export const SKILL_TONE = 'bg-skill-soft text-skill shadow-[inset_0_0_0_1px_color-mix(in_srgb,var(--skill)_25%,transparent)]';
|
|
6
|
+
/* A `#` to a view, node or chat is neutral, so it never reads as a file or a skill. */
|
|
7
|
+
export const REFERENCE_TONE = 'bg-text/8 text-text shadow-[inset_0_0_0_1px_var(--border-strong)]';
|
|
8
|
+
/* A `#` whose view or node is no longer in the project. */
|
|
9
|
+
export const REFERENCE_GONE_TONE = 'bg-text/4 text-text-faint shadow-[inset_0_0_0_1px_var(--border)]';
|
|
6
10
|
/* The pill in the composer's editor, around the token's own characters: the editor places the caret
|
|
7
11
|
from what it drew, so padding is safe, and a chip that wraps keeps it on every fragment. */
|
|
8
12
|
export const CHIP_IN_EDITOR = 'box-decoration-clone rounded-md px-1 py-0.5';
|
|
13
|
+
/* A picked or named token in a message or a reply, a shade smaller than the text around it. Inline like
|
|
14
|
+
the editor's pill, so its name sits on the baseline of the sentence, and a selection copies it on the
|
|
15
|
+
same line as the words around it, where a flex box would put it on lines of its own. */
|
|
16
|
+
export const TOKEN_IN_MESSAGE = 'box-decoration-clone rounded-md px-1.5 py-0.5 text-xs font-medium';
|
|
17
|
+
/* The mark in place of the sigil, a 14px icon. Inline, since the base styles make an svg a block of its
|
|
18
|
+
own. Its middle goes on the middle of the name's capitals, where a mark reads as centered; the middle
|
|
19
|
+
of the x-height `Icon` aligns on sits low next to a capital. */
|
|
20
|
+
export const TOKEN_ICON = 'mr-1 inline align-[calc(0.5cap-7px)]!';
|
|
21
|
+
/* The same middle for the 12px mark the composer draws, in a box whose bottom edge is its baseline. */
|
|
22
|
+
export const TOKEN_ICON_IN_EDITOR = 'mr-1 inline-block align-[calc(0.5cap-6px)]';
|
|
9
23
|
/* The same pill in the transcript: a real inline box a shade smaller than the text around it, with
|
|
10
24
|
the icon in place of the sigil. */
|
|
11
25
|
export const CHIP_IN_MESSAGE = 'inline-flex h-5 max-w-full items-center gap-1 rounded-md px-1.5 align-[-3px] text-xs/none font-medium';
|