@vertesia/ui 1.5.0-dev.20260725.083715Z → 1.5.0-dev.20260804.124748Z
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/lib/core/hooks/useScrollableSearch.d.ts +1 -1
- package/lib/core/hooks/useScrollableSearch.d.ts.map +1 -1
- package/lib/core/hooks/useScrollableSearch.js +15 -2
- package/lib/core/hooks/useScrollableSearch.js.map +1 -1
- package/lib/env/index.d.ts +4 -0
- package/lib/env/index.d.ts.map +1 -1
- package/lib/env/index.js.map +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.d.ts.map +1 -1
- package/lib/features/agent/chat/AgentRequestInputOverlay.js +3 -8
- package/lib/features/agent/chat/AgentRequestInputOverlay.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.d.ts +8 -1
- package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentConversation.js +53 -17
- package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts +2 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js +25 -10
- package/lib/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +24 -9
- package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +15 -3
- package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/Header.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/Header.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts +2 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/MessageInput.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +2 -2
- package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts +9 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.d.ts.map +1 -1
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js +97 -2
- package/lib/features/agent/chat/ModernAgentOutput/requestInputMessages.js.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
- package/lib/features/agent/chat/hooks/useAgentStream.js +12 -3
- package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
- package/lib/features/agent/chat/index.d.ts +1 -1
- package/lib/features/agent/chat/index.d.ts.map +1 -1
- package/lib/features/agent/chat/index.js.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.d.ts +8 -6
- package/lib/features/facets/PromptsFacetsNav.d.ts.map +1 -1
- package/lib/features/facets/PromptsFacetsNav.js +8 -3
- package/lib/features/facets/PromptsFacetsNav.js.map +1 -1
- package/lib/features/store/objects/components/ContentOverview.js +4 -1
- package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts +31 -3
- package/lib/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -1
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts +128 -6
- package/lib/features/store/objects/search/DocumentSearchContext.d.ts.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionContext.d.ts +2 -2
- package/lib/features/store/objects/selection/ObjectsActionContext.d.ts.map +1 -1
- package/lib/features/store/objects/selection/ObjectsActionSpec.d.ts +2 -2
- package/lib/features/store/objects/selection/ObjectsActionSpec.d.ts.map +1 -1
- package/lib/features/store/objects/selection/SelectionActions.d.ts +2 -2
- package/lib/features/store/objects/selection/SelectionActions.d.ts.map +1 -1
- package/lib/features/store/objects/upload/DocumentUploadModal.js.map +1 -1
- package/lib/features/store/types/IntakePolicyEditor.d.ts +2 -2
- package/lib/features/store/types/IntakePolicyEditor.d.ts.map +1 -1
- package/lib/features/store/types/IntakePolicyEditor.js +5 -1
- package/lib/features/store/types/IntakePolicyEditor.js.map +1 -1
- package/lib/features/store/types/IntakePolicyForm.d.ts.map +1 -1
- package/lib/features/store/types/IntakePolicyForm.js +2 -2
- package/lib/features/store/types/IntakePolicyForm.js.map +1 -1
- package/lib/features/store/types/ObjectSchemaEditor.d.ts +2 -2
- package/lib/features/store/types/ObjectSchemaEditor.d.ts.map +1 -1
- package/lib/features/store/types/SelectContentType.d.ts +2 -2
- package/lib/features/store/types/SelectContentType.d.ts.map +1 -1
- package/lib/features/store/types/SelectContentType.js.map +1 -1
- package/lib/features/store/types/SelectContentTypeModal.d.ts +2 -2
- package/lib/features/store/types/SelectContentTypeModal.d.ts.map +1 -1
- package/lib/features/store/types/SelectContentTypeModal.js.map +1 -1
- package/lib/features/store/types/TableLayoutEditor.d.ts +2 -2
- package/lib/features/store/types/TableLayoutEditor.d.ts.map +1 -1
- package/lib/features/store/types/TypeRegistry.d.ts +1267 -6
- package/lib/features/store/types/TypeRegistry.d.ts.map +1 -1
- package/lib/features/store/types/TypeRegistry.js +5 -0
- package/lib/features/store/types/TypeRegistry.js.map +1 -1
- package/lib/features/store/types/intake-policy-editor.logic.d.ts +9 -1
- package/lib/features/store/types/intake-policy-editor.logic.d.ts.map +1 -1
- package/lib/features/store/types/intake-policy-editor.logic.js +9 -1
- package/lib/features/store/types/intake-policy-editor.logic.js.map +1 -1
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts +1251 -1
- package/lib/features/store/types/search/ObjectTypeSearchContext.d.ts.map +1 -1
- package/lib/features/store/types/typeCatalogCache.d.ts +2 -2
- package/lib/features/store/types/typeCatalogCache.d.ts.map +1 -1
- package/lib/features/store/types/typeCatalogCache.js +4 -0
- package/lib/features/store/types/typeCatalogCache.js.map +1 -1
- package/lib/features/user/UserInfo.d.ts +118 -7
- package/lib/features/user/UserInfo.d.ts.map +1 -1
- package/lib/i18n/locales/ar.json +2 -1
- package/lib/i18n/locales/de.json +2 -1
- package/lib/i18n/locales/en.json +5 -1
- package/lib/i18n/locales/es.json +2 -1
- package/lib/i18n/locales/fr.json +2 -1
- package/lib/i18n/locales/it.json +2 -1
- package/lib/i18n/locales/ja.json +2 -1
- package/lib/i18n/locales/ko.json +2 -1
- package/lib/i18n/locales/pt.json +2 -1
- package/lib/i18n/locales/ru.json +2 -1
- package/lib/i18n/locales/tr.json +2 -1
- package/lib/i18n/locales/zh-TW.json +2 -1
- package/lib/i18n/locales/zh.json +2 -1
- package/lib/session/UserSession.d.ts +18 -4
- package/lib/session/UserSession.d.ts.map +1 -1
- package/lib/shell/apps/AppInstallationProvider.d.ts +222 -2
- package/lib/shell/apps/AppInstallationProvider.d.ts.map +1 -1
- package/lib/shell/login/InviteAcceptModal.js.map +1 -1
- package/lib/vertesia-ui-core.js +1 -1
- package/lib/vertesia-ui-core.js.map +1 -1
- package/lib/vertesia-ui-features.js +34 -34
- package/lib/vertesia-ui-features.js.map +1 -1
- package/lib/vertesia-ui-i18n.js +13 -13
- package/lib/vertesia-ui-widgets.js +18 -18
- package/lib/vertesia-ui-widgets.js.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.d.ts +7 -1
- package/lib/widgets/monacoEditor/MonacoEditor.d.ts.map +1 -1
- package/lib/widgets/monacoEditor/MonacoEditor.js +62 -6
- package/lib/widgets/monacoEditor/MonacoEditor.js.map +1 -1
- package/package.json +31 -31
- package/src/core/hooks/useScrollableSearch.test.tsx +139 -0
- package/src/core/hooks/useScrollableSearch.tsx +17 -3
- package/src/env/index.ts +2 -0
- package/src/features/agent/chat/AgentChatPlaybackControls.test.tsx +2 -0
- package/src/features/agent/chat/AgentRequestInputOverlay.test.tsx +51 -6
- package/src/features/agent/chat/AgentRequestInputOverlay.tsx +5 -7
- package/src/features/agent/chat/ModernAgentConversation.test.tsx +195 -3
- package/src/features/agent/chat/ModernAgentConversation.tsx +106 -22
- package/src/features/agent/chat/ModernAgentOutput/ActiveWorkstreamsSummary.tsx +75 -20
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +112 -0
- package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +62 -10
- package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +36 -4
- package/src/features/agent/chat/ModernAgentOutput/Header.tsx +2 -2
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.test.tsx +71 -0
- package/src/features/agent/chat/ModernAgentOutput/MessageInput.tsx +3 -1
- package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +18 -4
- package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.test.ts +95 -0
- package/src/features/agent/chat/ModernAgentOutput/requestInputMessages.ts +111 -1
- package/src/features/agent/chat/hooks/useAgentStream.test.tsx +57 -0
- package/src/features/agent/chat/hooks/useAgentStream.ts +12 -3
- package/src/features/agent/chat/index.ts +1 -0
- package/src/features/facets/PromptsFacetsNav.tsx +17 -9
- package/src/features/store/objects/components/ContentOverview.tsx +4 -1
- package/src/features/store/objects/selection/ObjectsActionContext.tsx +2 -2
- package/src/features/store/objects/selection/ObjectsActionSpec.ts +2 -2
- package/src/features/store/objects/selection/SelectionActions.tsx +2 -2
- package/src/features/store/objects/upload/DocumentUploadModal.tsx +2 -2
- package/src/features/store/types/IntakePolicyEditor.tsx +12 -4
- package/src/features/store/types/IntakePolicyForm.tsx +25 -0
- package/src/features/store/types/ObjectSchemaEditor.tsx +2 -2
- package/src/features/store/types/SelectContentType.tsx +9 -9
- package/src/features/store/types/SelectContentTypeModal.tsx +5 -5
- package/src/features/store/types/TableLayoutEditor.tsx +2 -2
- package/src/features/store/types/TypeRegistry.ts +8 -3
- package/src/features/store/types/intake-policy-editor.logic.ts +10 -2
- package/src/features/store/types/typeCatalogCache.ts +10 -3
- package/src/i18n/locales/ar.json +2 -1
- package/src/i18n/locales/de.json +2 -1
- package/src/i18n/locales/en.json +5 -1
- package/src/i18n/locales/es.json +2 -1
- package/src/i18n/locales/fr.json +2 -1
- package/src/i18n/locales/it.json +2 -1
- package/src/i18n/locales/ja.json +2 -1
- package/src/i18n/locales/ko.json +2 -1
- package/src/i18n/locales/pt.json +2 -1
- package/src/i18n/locales/ru.json +2 -1
- package/src/i18n/locales/tr.json +2 -1
- package/src/i18n/locales/zh-TW.json +2 -1
- package/src/i18n/locales/zh.json +2 -1
- package/src/shell/login/InviteAcceptModal.tsx +4 -4
- package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +13 -9
- package/src/widgets/monacoEditor/MonacoEditor.tsx +83 -7
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { cn } from '@vertesia/ui/core';
|
|
1
|
+
import { Button, cn } from '@vertesia/ui/core';
|
|
2
2
|
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
3
|
-
import { Bot } from 'lucide-react';
|
|
4
|
-
import { useMemo } from 'react';
|
|
3
|
+
import { Bot, ChevronDown, ChevronRight } from 'lucide-react';
|
|
4
|
+
import { useEffect, useId, useMemo, useState } from 'react';
|
|
5
5
|
import {
|
|
6
6
|
formatWorkstreamName,
|
|
7
7
|
getWorkstreamDisplayName,
|
|
@@ -11,17 +11,35 @@ import {
|
|
|
11
11
|
|
|
12
12
|
interface ActiveWorkstreamsSummaryProps {
|
|
13
13
|
activeWorkstreams: WorkstreamInfo[];
|
|
14
|
+
onSelectWorkstream?: (workstreamId: string) => void;
|
|
14
15
|
className?: string;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
const COLLAPSED_WORKSTREAM_COUNT = 3;
|
|
19
|
+
|
|
20
|
+
export function ActiveWorkstreamsSummary({
|
|
21
|
+
activeWorkstreams,
|
|
22
|
+
onSelectWorkstream,
|
|
23
|
+
className,
|
|
24
|
+
}: ActiveWorkstreamsSummaryProps) {
|
|
18
25
|
const { t } = useUITranslation();
|
|
26
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
27
|
+
const listId = useId();
|
|
19
28
|
const runningWorkstreams = useMemo(
|
|
20
29
|
() => activeWorkstreams.filter((ws) => ws.status === 'running' || ws.status === 'canceling'),
|
|
21
30
|
[activeWorkstreams],
|
|
22
31
|
);
|
|
23
|
-
const visibleRunningWorkstreams =
|
|
32
|
+
const visibleRunningWorkstreams = isExpanded
|
|
33
|
+
? runningWorkstreams
|
|
34
|
+
: runningWorkstreams.slice(0, COLLAPSED_WORKSTREAM_COUNT);
|
|
24
35
|
const hiddenRunningWorkstreamCount = Math.max(0, runningWorkstreams.length - visibleRunningWorkstreams.length);
|
|
36
|
+
const canExpand = runningWorkstreams.length > COLLAPSED_WORKSTREAM_COUNT;
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (!canExpand) {
|
|
40
|
+
setIsExpanded(false);
|
|
41
|
+
}
|
|
42
|
+
}, [canExpand]);
|
|
25
43
|
|
|
26
44
|
if (runningWorkstreams.length === 0) return null;
|
|
27
45
|
|
|
@@ -31,23 +49,20 @@ export function ActiveWorkstreamsSummary({ activeWorkstreams, className }: Activ
|
|
|
31
49
|
className="flex flex-col gap-1.5 rounded-2xl border border-border/70 bg-background/95 p-2 text-xs text-muted shadow-lg shadow-black/5"
|
|
32
50
|
aria-live="polite"
|
|
33
51
|
>
|
|
34
|
-
<div className="flex items-center gap-2 px-1 font-medium">
|
|
35
|
-
<Bot className="size-3.5 text-muted" aria-hidden="true" />
|
|
36
|
-
<span
|
|
52
|
+
<div className="flex min-w-0 items-center gap-2 px-1 font-medium">
|
|
53
|
+
<Bot className="size-3.5 shrink-0 text-muted" aria-hidden="true" />
|
|
54
|
+
<span className="truncate">
|
|
55
|
+
{t('agent.activeWorkstreams', { count: runningWorkstreams.length })}
|
|
56
|
+
</span>
|
|
37
57
|
</div>
|
|
38
|
-
<div className="flex flex-col gap-0.5">
|
|
58
|
+
<div id={listId} className="flex flex-col gap-0.5">
|
|
39
59
|
{visibleRunningWorkstreams.map((workstream) => {
|
|
40
60
|
const workstreamName = getWorkstreamDisplayName(
|
|
41
61
|
workstream.workstream_id,
|
|
42
62
|
workstream.interaction,
|
|
43
63
|
);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<span
|
|
47
|
-
key={workstream.launch_id || workstream.workstream_id}
|
|
48
|
-
className="flex min-w-0 items-center gap-2 rounded-lg px-1 py-1 text-sm text-foreground/80"
|
|
49
|
-
title={workstreamName}
|
|
50
|
-
>
|
|
64
|
+
const content = (
|
|
65
|
+
<>
|
|
51
66
|
<span
|
|
52
67
|
className={cn(
|
|
53
68
|
'size-1.5 shrink-0 rounded-full',
|
|
@@ -61,13 +76,53 @@ export function ActiveWorkstreamsSummary({ activeWorkstreams, className }: Activ
|
|
|
61
76
|
{formatWorkstreamName(workstream.phase)}
|
|
62
77
|
</span>
|
|
63
78
|
)}
|
|
64
|
-
|
|
79
|
+
</>
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return onSelectWorkstream ? (
|
|
83
|
+
<Button
|
|
84
|
+
key={workstream.launch_id || workstream.workstream_id}
|
|
85
|
+
type="button"
|
|
86
|
+
variant="ghost"
|
|
87
|
+
className="h-auto min-w-0 justify-start gap-2 rounded-lg px-1 py-1 text-sm text-foreground/80"
|
|
88
|
+
title={workstreamName}
|
|
89
|
+
onClick={() => {
|
|
90
|
+
setIsExpanded(false);
|
|
91
|
+
onSelectWorkstream(workstream.workstream_id);
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
{content}
|
|
95
|
+
<ChevronRight className="ms-auto size-3.5 shrink-0 rtl:rotate-180" aria-hidden="true" />
|
|
96
|
+
</Button>
|
|
97
|
+
) : (
|
|
98
|
+
<div
|
|
99
|
+
key={workstream.launch_id || workstream.workstream_id}
|
|
100
|
+
className="flex min-w-0 items-center gap-2 rounded-lg px-1 py-1 text-sm text-foreground/80"
|
|
101
|
+
title={workstreamName}
|
|
102
|
+
>
|
|
103
|
+
{content}
|
|
104
|
+
</div>
|
|
65
105
|
);
|
|
66
106
|
})}
|
|
67
|
-
{hiddenRunningWorkstreamCount > 0 && (
|
|
68
|
-
<span className="px-1 py-1 text-xs text-muted">+{hiddenRunningWorkstreamCount}</span>
|
|
69
|
-
)}
|
|
70
107
|
</div>
|
|
108
|
+
{canExpand && (
|
|
109
|
+
<Button
|
|
110
|
+
type="button"
|
|
111
|
+
variant="ghost"
|
|
112
|
+
size="sm"
|
|
113
|
+
className="h-8 w-fit shrink-0 gap-1 rounded-xl px-2.5 text-xs text-muted"
|
|
114
|
+
aria-expanded={isExpanded}
|
|
115
|
+
aria-controls={listId}
|
|
116
|
+
onClick={() => setIsExpanded((expanded) => !expanded)}
|
|
117
|
+
>
|
|
118
|
+
{!isExpanded && <span>+{hiddenRunningWorkstreamCount}</span>}
|
|
119
|
+
{isExpanded ? t('agent.showLess') : t('agent.showMore')}
|
|
120
|
+
<ChevronDown
|
|
121
|
+
className={cn('size-3.5 transition-transform', isExpanded && 'rotate-180')}
|
|
122
|
+
aria-hidden="true"
|
|
123
|
+
/>
|
|
124
|
+
</Button>
|
|
125
|
+
)}
|
|
71
126
|
</output>
|
|
72
127
|
</div>
|
|
73
128
|
);
|
|
@@ -258,6 +258,114 @@ describe('AllMessagesMixed summary view', () => {
|
|
|
258
258
|
expect(screen.getByText('Found 5 results')).not.toBeNull();
|
|
259
259
|
});
|
|
260
260
|
|
|
261
|
+
it('does not show post-tool thinking while the latest tool is still running', () => {
|
|
262
|
+
renderSummary(
|
|
263
|
+
[
|
|
264
|
+
makeMessage({
|
|
265
|
+
timestamp: 1_000,
|
|
266
|
+
type: AgentMessageType.QUESTION,
|
|
267
|
+
message: 'Find Japan news.',
|
|
268
|
+
}),
|
|
269
|
+
makeMessage({
|
|
270
|
+
timestamp: 2_000,
|
|
271
|
+
message: 'Searching for Japan news',
|
|
272
|
+
details: {
|
|
273
|
+
tool: 'web_search_serper',
|
|
274
|
+
tool_status: 'running',
|
|
275
|
+
tool_run_id: 'tool-1',
|
|
276
|
+
},
|
|
277
|
+
}),
|
|
278
|
+
],
|
|
279
|
+
false,
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
expect(screen.getAllByRole('button', { name: /Working.*for/ })).toHaveLength(1);
|
|
283
|
+
expect(screen.queryByTestId('post-tool-thinking-indicator')).toBeNull();
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
it('shows thinking below the active work group after its latest tool completes', () => {
|
|
287
|
+
renderSummary(
|
|
288
|
+
[
|
|
289
|
+
makeMessage({
|
|
290
|
+
timestamp: 1_000,
|
|
291
|
+
type: AgentMessageType.QUESTION,
|
|
292
|
+
message: 'Find Japan news.',
|
|
293
|
+
}),
|
|
294
|
+
makeMessage({
|
|
295
|
+
timestamp: 2_000,
|
|
296
|
+
message: 'Searching for Japan news',
|
|
297
|
+
details: {
|
|
298
|
+
tool: 'web_search_serper',
|
|
299
|
+
tool_status: 'running',
|
|
300
|
+
tool_run_id: 'tool-1',
|
|
301
|
+
},
|
|
302
|
+
}),
|
|
303
|
+
makeMessage({
|
|
304
|
+
timestamp: 3_000,
|
|
305
|
+
message: 'Found Japan news',
|
|
306
|
+
details: {
|
|
307
|
+
tool: 'web_search_serper',
|
|
308
|
+
tool_status: 'completed',
|
|
309
|
+
tool_run_id: 'tool-1',
|
|
310
|
+
},
|
|
311
|
+
}),
|
|
312
|
+
],
|
|
313
|
+
false,
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
expect(screen.queryByRole('button', { name: /Worked\s*for/ })).toBeNull();
|
|
317
|
+
expect(screen.getAllByRole('button', { name: /Working.*for/ })).toHaveLength(1);
|
|
318
|
+
expect(screen.getByTestId('post-tool-thinking-indicator').textContent).toBe('Thinking...');
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
it('keeps showing thinking when the current display-role marker follows a completed tool', () => {
|
|
322
|
+
renderSummary(
|
|
323
|
+
[
|
|
324
|
+
makeMessage({
|
|
325
|
+
timestamp: 1_000,
|
|
326
|
+
type: AgentMessageType.QUESTION,
|
|
327
|
+
message: 'Find Japan news.',
|
|
328
|
+
}),
|
|
329
|
+
makeMessage({
|
|
330
|
+
timestamp: 2_000,
|
|
331
|
+
message: 'Searching for Japan news',
|
|
332
|
+
details: {
|
|
333
|
+
event_class: 'activity',
|
|
334
|
+
tool: 'web_search_serper',
|
|
335
|
+
tool_status: 'running',
|
|
336
|
+
tool_run_id: 'tool-1',
|
|
337
|
+
activity_group_id: 'activity-1',
|
|
338
|
+
},
|
|
339
|
+
}),
|
|
340
|
+
makeMessage({
|
|
341
|
+
timestamp: 3_000,
|
|
342
|
+
message: 'Found Japan news',
|
|
343
|
+
details: {
|
|
344
|
+
event_class: 'activity',
|
|
345
|
+
tool: 'web_search_serper',
|
|
346
|
+
tool_status: 'completed',
|
|
347
|
+
tool_run_id: 'tool-1',
|
|
348
|
+
activity_group_id: 'activity-1',
|
|
349
|
+
},
|
|
350
|
+
}),
|
|
351
|
+
makeMessage({
|
|
352
|
+
timestamp: 4_000,
|
|
353
|
+
message: 'Thinking...',
|
|
354
|
+
details: {
|
|
355
|
+
event_class: 'activity',
|
|
356
|
+
display_role: 'thinking',
|
|
357
|
+
activity_id: '17',
|
|
358
|
+
activity_group_id: 'activity-1',
|
|
359
|
+
},
|
|
360
|
+
}),
|
|
361
|
+
],
|
|
362
|
+
false,
|
|
363
|
+
);
|
|
364
|
+
|
|
365
|
+
expect(screen.getAllByRole('button', { name: /Working.*for/ })).toHaveLength(1);
|
|
366
|
+
expect(screen.getByTestId('post-tool-thinking-indicator').textContent).toBe('Thinking...');
|
|
367
|
+
});
|
|
368
|
+
|
|
261
369
|
it('replaces a completed tool’s progress title with an immediately visible resource deep link', () => {
|
|
262
370
|
renderSummary(
|
|
263
371
|
[
|
|
@@ -464,6 +572,7 @@ describe('AllMessagesMixed summary view', () => {
|
|
|
464
572
|
type: AgentMessageType.REQUEST_INPUT,
|
|
465
573
|
message: 'Approve Create Document: name News Headlines Today?',
|
|
466
574
|
details: {
|
|
575
|
+
request_id: 'create_document:name:News Headlines Today',
|
|
467
576
|
tool_approval: {
|
|
468
577
|
approval_key: 'create_document:name:News Headlines Today',
|
|
469
578
|
tool_name: 'create_document',
|
|
@@ -499,6 +608,9 @@ describe('AllMessagesMixed summary view', () => {
|
|
|
499
608
|
decision: 'allow_once',
|
|
500
609
|
approval_key: 'create_document:name:News Headlines Today',
|
|
501
610
|
},
|
|
611
|
+
request_input_response: {
|
|
612
|
+
request_id: 'create_document:name:News Headlines Today',
|
|
613
|
+
},
|
|
502
614
|
});
|
|
503
615
|
});
|
|
504
616
|
|
|
@@ -68,6 +68,7 @@ import {
|
|
|
68
68
|
isToolApprovalRequestInput,
|
|
69
69
|
isToolApprovalRequestInputHidden,
|
|
70
70
|
type RequestInputMessageWithUx,
|
|
71
|
+
sendRequestInputResponse,
|
|
71
72
|
} from './requestInputMessages';
|
|
72
73
|
import {
|
|
73
74
|
interleaveTurnSummaries,
|
|
@@ -92,6 +93,7 @@ import {
|
|
|
92
93
|
getWorkstreamId,
|
|
93
94
|
groupMessagesWithStreaming,
|
|
94
95
|
isInProgress,
|
|
96
|
+
isToolActivityMessage,
|
|
95
97
|
isToolPreambleMessage,
|
|
96
98
|
isUserStoppedMessage,
|
|
97
99
|
mergeConsecutiveToolGroups,
|
|
@@ -753,13 +755,22 @@ function SummaryMessage({
|
|
|
753
755
|
variant={uxConfig.variant}
|
|
754
756
|
multiSelect={uxConfig.multiSelect}
|
|
755
757
|
onSelect={(optionId) =>
|
|
756
|
-
|
|
758
|
+
sendRequestInputResponse(
|
|
759
|
+
onSendMessage,
|
|
760
|
+
message,
|
|
761
|
+
optionId,
|
|
762
|
+
getToolApprovalResponseMetadata(message, optionId),
|
|
763
|
+
)
|
|
764
|
+
}
|
|
765
|
+
onMultiSelect={(optionIds) =>
|
|
766
|
+
sendRequestInputResponse(onSendMessage, message, optionIds.join(', '))
|
|
757
767
|
}
|
|
758
|
-
onMultiSelect={(optionIds) => onSendMessage?.(optionIds.join(', '))}
|
|
759
768
|
allowFreeResponse={!uxConfig.options?.length || !!uxConfig.free_response}
|
|
760
769
|
placeholder={uxConfig.free_response?.placeholder}
|
|
761
770
|
submitLabel={uxConfig.free_response?.submit_label}
|
|
762
|
-
onSubmit={(value) =>
|
|
771
|
+
onSubmit={(value) =>
|
|
772
|
+
sendRequestInputResponse(onSendMessage, message, value, uxConfig.free_response?.metadata)
|
|
773
|
+
}
|
|
763
774
|
hideBorder
|
|
764
775
|
compact
|
|
765
776
|
answered={requestInputAnswered}
|
|
@@ -2273,19 +2284,32 @@ function SummaryActivityRow({
|
|
|
2273
2284
|
variant={uxConfig.variant}
|
|
2274
2285
|
multiSelect={uxConfig.multiSelect}
|
|
2275
2286
|
onSelect={(optionId) =>
|
|
2276
|
-
|
|
2287
|
+
sendRequestInputResponse(
|
|
2288
|
+
onSendMessage,
|
|
2289
|
+
message,
|
|
2277
2290
|
optionId,
|
|
2278
2291
|
getToolApprovalResponseMetadata(message, optionId),
|
|
2279
2292
|
)
|
|
2280
2293
|
}
|
|
2281
|
-
onMultiSelect={(optionIds) =>
|
|
2294
|
+
onMultiSelect={(optionIds) =>
|
|
2295
|
+
sendRequestInputResponse(
|
|
2296
|
+
onSendMessage,
|
|
2297
|
+
message,
|
|
2298
|
+
optionIds.join(', '),
|
|
2299
|
+
)
|
|
2300
|
+
}
|
|
2282
2301
|
allowFreeResponse={
|
|
2283
2302
|
!uxConfig.options?.length || !!uxConfig.free_response
|
|
2284
2303
|
}
|
|
2285
2304
|
placeholder={uxConfig.free_response?.placeholder}
|
|
2286
2305
|
submitLabel={uxConfig.free_response?.submit_label}
|
|
2287
2306
|
onSubmit={(value) =>
|
|
2288
|
-
|
|
2307
|
+
sendRequestInputResponse(
|
|
2308
|
+
onSendMessage,
|
|
2309
|
+
message,
|
|
2310
|
+
value,
|
|
2311
|
+
uxConfig.free_response?.metadata,
|
|
2312
|
+
)
|
|
2289
2313
|
}
|
|
2290
2314
|
hideBorder
|
|
2291
2315
|
compact
|
|
@@ -2663,18 +2687,23 @@ function AllMessagesMixedComponent({
|
|
|
2663
2687
|
});
|
|
2664
2688
|
}, []);
|
|
2665
2689
|
|
|
2690
|
+
const previousActiveWorkstreamRef = useRef(activeWorkstream);
|
|
2691
|
+
useEffect(() => {
|
|
2692
|
+
if (previousActiveWorkstreamRef.current === activeWorkstream) return;
|
|
2693
|
+
previousActiveWorkstreamRef.current = activeWorkstream;
|
|
2694
|
+
requestAnimationFrame(scrollToTop);
|
|
2695
|
+
}, [activeWorkstream, scrollToTop]);
|
|
2696
|
+
|
|
2666
2697
|
const handleSelectWorkstream = useCallback(
|
|
2667
2698
|
(workstreamId: string) => {
|
|
2668
2699
|
setActiveWorkstream(workstreamId);
|
|
2669
|
-
requestAnimationFrame(scrollToTop);
|
|
2670
2700
|
},
|
|
2671
|
-
[
|
|
2701
|
+
[setActiveWorkstream],
|
|
2672
2702
|
);
|
|
2673
2703
|
|
|
2674
2704
|
const handleShowMainAgentChat = useCallback(() => {
|
|
2675
2705
|
setActiveWorkstream('all');
|
|
2676
|
-
|
|
2677
|
-
}, [scrollToTop, setActiveWorkstream]);
|
|
2706
|
+
}, [setActiveWorkstream]);
|
|
2678
2707
|
|
|
2679
2708
|
useEffect(() => {
|
|
2680
2709
|
if (activeWorkstream !== 'all' && !workstreams.has(activeWorkstream)) {
|
|
@@ -2945,6 +2974,18 @@ function AllMessagesMixedComponent({
|
|
|
2945
2974
|
return !isDisplayCompleted || hasOpenUserTurn(completionDisplayMessages);
|
|
2946
2975
|
}, [completionDisplayMessages, isDisplayCompleted]);
|
|
2947
2976
|
|
|
2977
|
+
const showPostToolThinking = useMemo(() => {
|
|
2978
|
+
if (!isAgentWorking || incompleteStreaming.length > 0) return false;
|
|
2979
|
+
|
|
2980
|
+
const latestSummaryItem = summaryConversationItems[summaryConversationItems.length - 1];
|
|
2981
|
+
const latestMessage = completionDisplayMessages[completionDisplayMessages.length - 1];
|
|
2982
|
+
const latestMessageShowsThinking =
|
|
2983
|
+
latestMessage !== undefined &&
|
|
2984
|
+
(latestMessage.details?.display_role === 'thinking' ||
|
|
2985
|
+
(isToolActivityMessage(latestMessage) && latestMessage.details?.tool_status === 'completed'));
|
|
2986
|
+
return latestSummaryItem?.type === 'work' && latestSummaryItem.isActive && latestMessageShowsThinking;
|
|
2987
|
+
}, [completionDisplayMessages, incompleteStreaming.length, isAgentWorking, summaryConversationItems]);
|
|
2988
|
+
|
|
2948
2989
|
const showActivityFallback = shouldShowSummaryActivityFallback(
|
|
2949
2990
|
summaryConversationItems,
|
|
2950
2991
|
isAgentWorking,
|
|
@@ -3661,6 +3702,17 @@ function AllMessagesMixedComponent({
|
|
|
3661
3702
|
artifactRunId={artifactRunId}
|
|
3662
3703
|
/>
|
|
3663
3704
|
))}
|
|
3705
|
+
{showPostToolThinking && (
|
|
3706
|
+
<div
|
|
3707
|
+
className={cn(
|
|
3708
|
+
'mx-auto w-full max-w-3xl px-1 text-sm text-muted',
|
|
3709
|
+
workingIndicatorClassName,
|
|
3710
|
+
)}
|
|
3711
|
+
data-testid="post-tool-thinking-indicator"
|
|
3712
|
+
>
|
|
3713
|
+
{t('agent.thinking')}
|
|
3714
|
+
</div>
|
|
3715
|
+
)}
|
|
3664
3716
|
{/* Activity fallback - shown before any tool/thought message has arrived */}
|
|
3665
3717
|
{showActivityFallback && !showInitialRequestWaitingCard && (
|
|
3666
3718
|
<SummaryActivityRow
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Button, cn } from '@vertesia/ui/core';
|
|
2
2
|
import { useUITranslation } from '@vertesia/ui/i18n';
|
|
3
3
|
import { UserSessionContext } from '@vertesia/ui/session';
|
|
4
|
-
import { FileTextIcon, ImageIcon, XIcon } from 'lucide-react';
|
|
4
|
+
import { ChevronDown, FileTextIcon, ImageIcon, XIcon } from 'lucide-react';
|
|
5
5
|
import type React from 'react';
|
|
6
|
-
import { useContext, useEffect, useState } from 'react';
|
|
6
|
+
import { useContext, useEffect, useId, useState } from 'react';
|
|
7
7
|
import { useImageLightbox } from '../ImageLightbox';
|
|
8
8
|
import { getArtifactCacheKey, useArtifactUrlCache } from '../useArtifactUrlCache';
|
|
9
9
|
|
|
@@ -26,6 +26,7 @@ const TEXT_EXTENSIONS = new Set([
|
|
|
26
26
|
'yaml',
|
|
27
27
|
'yml',
|
|
28
28
|
]);
|
|
29
|
+
const DEFAULT_COLLAPSED_ATTACHMENT_COUNT = 3;
|
|
29
30
|
|
|
30
31
|
export interface AttachmentPreviewItem {
|
|
31
32
|
id: string;
|
|
@@ -374,11 +375,24 @@ export function AttachmentPreviewList({
|
|
|
374
375
|
StoreLinkComponent,
|
|
375
376
|
CollectionLinkComponent,
|
|
376
377
|
}: AttachmentPreviewListProps) {
|
|
378
|
+
const { t } = useUITranslation();
|
|
379
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
380
|
+
const attachmentListId = useId();
|
|
381
|
+
const isCollapsible = variant === 'composer' && items.length > DEFAULT_COLLAPSED_ATTACHMENT_COUNT;
|
|
382
|
+
const visibleItems = isCollapsible && !isExpanded ? items.slice(0, DEFAULT_COLLAPSED_ATTACHMENT_COUNT) : items;
|
|
383
|
+
const hiddenItemCount = items.length - DEFAULT_COLLAPSED_ATTACHMENT_COUNT;
|
|
384
|
+
|
|
385
|
+
useEffect(() => {
|
|
386
|
+
if (items.length <= DEFAULT_COLLAPSED_ATTACHMENT_COUNT) {
|
|
387
|
+
setIsExpanded(false);
|
|
388
|
+
}
|
|
389
|
+
}, [items.length]);
|
|
390
|
+
|
|
377
391
|
if (items.length === 0) return null;
|
|
378
392
|
|
|
379
393
|
return (
|
|
380
|
-
<div className={cn('flex flex-wrap gap-2', align === 'end' && 'justify-end', className)}>
|
|
381
|
-
{
|
|
394
|
+
<div id={attachmentListId} className={cn('flex flex-wrap gap-2', align === 'end' && 'justify-end', className)}>
|
|
395
|
+
{visibleItems.map((item) => (
|
|
382
396
|
<AttachmentPreview
|
|
383
397
|
key={item.id}
|
|
384
398
|
item={item}
|
|
@@ -390,6 +404,24 @@ export function AttachmentPreviewList({
|
|
|
390
404
|
CollectionLinkComponent={CollectionLinkComponent}
|
|
391
405
|
/>
|
|
392
406
|
))}
|
|
407
|
+
{isCollapsible && (
|
|
408
|
+
<Button
|
|
409
|
+
type="button"
|
|
410
|
+
variant="ghost"
|
|
411
|
+
size="sm"
|
|
412
|
+
aria-controls={attachmentListId}
|
|
413
|
+
aria-expanded={isExpanded}
|
|
414
|
+
onClick={() => setIsExpanded((expanded) => !expanded)}
|
|
415
|
+
className="h-8 shrink-0 gap-1 rounded-xl px-2.5 text-xs text-muted"
|
|
416
|
+
>
|
|
417
|
+
{!isExpanded && <span>+{hiddenItemCount}</span>}
|
|
418
|
+
{isExpanded ? t('agent.showLess') : t('agent.showMore')}
|
|
419
|
+
<ChevronDown
|
|
420
|
+
className={cn('size-3.5 transition-transform', isExpanded && 'rotate-180')}
|
|
421
|
+
aria-hidden="true"
|
|
422
|
+
/>
|
|
423
|
+
</Button>
|
|
424
|
+
)}
|
|
393
425
|
</div>
|
|
394
426
|
);
|
|
395
427
|
}
|
|
@@ -5,6 +5,7 @@ import { useRouterContext } from '@vertesia/ui/router';
|
|
|
5
5
|
import { useUserSession } from '@vertesia/ui/session';
|
|
6
6
|
import {
|
|
7
7
|
Bot,
|
|
8
|
+
Bug,
|
|
8
9
|
ClipboardList,
|
|
9
10
|
CopyIcon,
|
|
10
11
|
DownloadCloudIcon,
|
|
@@ -13,7 +14,6 @@ import {
|
|
|
13
14
|
InfoIcon,
|
|
14
15
|
MessageSquareText,
|
|
15
16
|
MoreVertical,
|
|
16
|
-
Rewind,
|
|
17
17
|
Rows3,
|
|
18
18
|
XIcon,
|
|
19
19
|
} from 'lucide-react';
|
|
@@ -185,7 +185,7 @@ export default function Header({
|
|
|
185
185
|
variant === 'compact' && 'size-8 rounded-lg',
|
|
186
186
|
)}
|
|
187
187
|
>
|
|
188
|
-
<
|
|
188
|
+
<Bug className={cn('size-4', variant === 'full' && 'me-1.5')} />
|
|
189
189
|
{variant === 'full' ? (
|
|
190
190
|
<span className="font-medium text-xs">{t('agent.rewind.label')}</span>
|
|
191
191
|
) : (
|
|
@@ -201,6 +201,38 @@ describe('MessageInput', () => {
|
|
|
201
201
|
expect(screen.getByText('Ready')).not.toBeNull();
|
|
202
202
|
});
|
|
203
203
|
|
|
204
|
+
it('collapses large attachment lists while preserving attachment actions', () => {
|
|
205
|
+
const onRemoveDocument = vi.fn();
|
|
206
|
+
const selectedDocuments = ['Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon'].map((name, index) => ({
|
|
207
|
+
id: `doc-${index}`,
|
|
208
|
+
name,
|
|
209
|
+
}));
|
|
210
|
+
|
|
211
|
+
renderWithProviders(
|
|
212
|
+
<MessageInput onSend={vi.fn()} selectedDocuments={selectedDocuments} onRemoveDocument={onRemoveDocument} />,
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
expect(screen.getByText('Alpha')).not.toBeNull();
|
|
216
|
+
expect(screen.getByText('Gamma')).not.toBeNull();
|
|
217
|
+
expect(screen.queryByText('Delta')).toBeNull();
|
|
218
|
+
expect(screen.getByText('+2')).not.toBeNull();
|
|
219
|
+
|
|
220
|
+
fireEvent.click(screen.getByRole('button', { name: /show more/i }));
|
|
221
|
+
|
|
222
|
+
expect(screen.getByText('Delta')).not.toBeNull();
|
|
223
|
+
expect(screen.getByText('Epsilon')).not.toBeNull();
|
|
224
|
+
expect(screen.getByRole('button', { name: /show less/i })).not.toBeNull();
|
|
225
|
+
|
|
226
|
+
fireEvent.click(screen.getByRole('button', { name: /Remove Epsilon/i }));
|
|
227
|
+
|
|
228
|
+
expect(onRemoveDocument).toHaveBeenCalledWith('doc-4');
|
|
229
|
+
|
|
230
|
+
fireEvent.click(screen.getByRole('button', { name: /show less/i }));
|
|
231
|
+
|
|
232
|
+
expect(screen.queryByText('Delta')).toBeNull();
|
|
233
|
+
expect(screen.getByText('+2')).not.toBeNull();
|
|
234
|
+
});
|
|
235
|
+
|
|
204
236
|
it('renders context usage and triggers manual compaction', async () => {
|
|
205
237
|
const onCompactContext = vi.fn();
|
|
206
238
|
|
|
@@ -269,4 +301,43 @@ describe('MessageInput', () => {
|
|
|
269
301
|
tray.compareDocumentPosition(screen.getByRole('textbox')) & Node.DOCUMENT_POSITION_FOLLOWING,
|
|
270
302
|
).toBeTruthy();
|
|
271
303
|
});
|
|
304
|
+
|
|
305
|
+
it('collapses large workstream lists and navigates from a selected workstream', () => {
|
|
306
|
+
const onSelectWorkstream = vi.fn();
|
|
307
|
+
const activeWorkstreams = ['alpha', 'beta', 'gamma', 'delta', 'epsilon'].map((workstream_id, index) => ({
|
|
308
|
+
workstream_id,
|
|
309
|
+
launch_id: `launch-${index}`,
|
|
310
|
+
elapsed_ms: 0,
|
|
311
|
+
deadline_ms: 0,
|
|
312
|
+
remaining_ms: 0,
|
|
313
|
+
status: 'running' as const,
|
|
314
|
+
}));
|
|
315
|
+
|
|
316
|
+
renderWithProviders(
|
|
317
|
+
<MessageInput
|
|
318
|
+
onSend={vi.fn()}
|
|
319
|
+
isStreaming
|
|
320
|
+
activeWorkstreams={activeWorkstreams}
|
|
321
|
+
onSelectWorkstream={onSelectWorkstream}
|
|
322
|
+
/>,
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
expect(screen.getByRole('button', { name: 'Alpha' })).not.toBeNull();
|
|
326
|
+
expect(screen.getByRole('button', { name: 'Gamma' })).not.toBeNull();
|
|
327
|
+
expect(screen.queryByRole('button', { name: 'Delta' })).toBeNull();
|
|
328
|
+
expect(screen.getByText('+2')).not.toBeNull();
|
|
329
|
+
expect(screen.getByText('Show more')).not.toBeNull();
|
|
330
|
+
|
|
331
|
+
fireEvent.click(screen.getByRole('button', { name: /show more/i }));
|
|
332
|
+
|
|
333
|
+
expect(screen.getByRole('button', { name: 'Delta' })).not.toBeNull();
|
|
334
|
+
expect(screen.getByRole('button', { name: 'Epsilon' })).not.toBeNull();
|
|
335
|
+
expect(screen.getByRole('button', { name: /show less/i })).not.toBeNull();
|
|
336
|
+
|
|
337
|
+
fireEvent.click(screen.getByRole('button', { name: 'Delta' }));
|
|
338
|
+
|
|
339
|
+
expect(onSelectWorkstream).toHaveBeenCalledWith('delta');
|
|
340
|
+
expect(screen.queryByRole('button', { name: 'Delta' })).toBeNull();
|
|
341
|
+
expect(screen.getByRole('button', { name: /show more/i })).not.toBeNull();
|
|
342
|
+
});
|
|
272
343
|
});
|
|
@@ -66,6 +66,7 @@ interface MessageInputProps {
|
|
|
66
66
|
isCompactingContext?: boolean;
|
|
67
67
|
activeTaskCount?: number;
|
|
68
68
|
activeWorkstreams?: WorkstreamInfo[];
|
|
69
|
+
onSelectWorkstream?: (workstreamId: string) => void;
|
|
69
70
|
placeholder?: string;
|
|
70
71
|
|
|
71
72
|
// File upload props
|
|
@@ -133,6 +134,7 @@ export default function MessageInput({
|
|
|
133
134
|
isCompactingContext = false,
|
|
134
135
|
activeTaskCount = 0,
|
|
135
136
|
activeWorkstreams = [],
|
|
137
|
+
onSelectWorkstream,
|
|
136
138
|
placeholder,
|
|
137
139
|
// File upload props
|
|
138
140
|
onFilesSelected,
|
|
@@ -474,7 +476,7 @@ export default function MessageInput({
|
|
|
474
476
|
/>
|
|
475
477
|
)}
|
|
476
478
|
|
|
477
|
-
<ActiveWorkstreamsSummary activeWorkstreams={activeWorkstreams} />
|
|
479
|
+
<ActiveWorkstreamsSummary activeWorkstreams={activeWorkstreams} onSelectWorkstream={onSelectWorkstream} />
|
|
478
480
|
|
|
479
481
|
{/* Input row */}
|
|
480
482
|
<div className="mx-auto flex max-w-3xl flex-col gap-2 rounded-2xl border border-border/70 bg-mixer-muted/15 p-2.5 shadow-lg shadow-black/5">
|
|
@@ -37,7 +37,7 @@ import { createAgentMarkdownAnchor } from './AgentMarkdownAnchor';
|
|
|
37
37
|
import { AttachmentPreviewList, parseUserMessageAttachments } from './AttachmentPreview';
|
|
38
38
|
import { MessageDeliveryStatus } from './MessageDeliveryStatus';
|
|
39
39
|
import { processContentForMarkdown } from './processContentForMarkdown';
|
|
40
|
-
import { getToolApprovalResponseMetadata } from './requestInputMessages';
|
|
40
|
+
import { getToolApprovalResponseMetadata, sendRequestInputResponse } from './requestInputMessages';
|
|
41
41
|
import { getWorkstreamId } from './utils';
|
|
42
42
|
|
|
43
43
|
/** className overrides for MessageItem — single source of truth for all className overrides. */
|
|
@@ -625,13 +625,27 @@ function MessageItemComponent({
|
|
|
625
625
|
variant={askUserUx.variant}
|
|
626
626
|
multiSelect={askUserUx.multiSelect}
|
|
627
627
|
onSelect={(optionId) =>
|
|
628
|
-
|
|
628
|
+
sendRequestInputResponse(
|
|
629
|
+
onSendMessage,
|
|
630
|
+
message,
|
|
631
|
+
optionId,
|
|
632
|
+
getToolApprovalResponseMetadata(message, optionId),
|
|
633
|
+
)
|
|
634
|
+
}
|
|
635
|
+
onMultiSelect={(optionIds) =>
|
|
636
|
+
sendRequestInputResponse(onSendMessage, message, optionIds.join(', '))
|
|
629
637
|
}
|
|
630
|
-
onMultiSelect={(optionIds) => onSendMessage?.(optionIds.join(', '))}
|
|
631
638
|
allowFreeResponse={!askUserUx.options?.length || !!askUserUx.free_response}
|
|
632
639
|
placeholder={askUserUx.free_response?.placeholder}
|
|
633
640
|
submitLabel={askUserUx.free_response?.submit_label}
|
|
634
|
-
onSubmit={(value) =>
|
|
641
|
+
onSubmit={(value) =>
|
|
642
|
+
sendRequestInputResponse(
|
|
643
|
+
onSendMessage,
|
|
644
|
+
message,
|
|
645
|
+
value,
|
|
646
|
+
askUserUx.free_response?.metadata,
|
|
647
|
+
)
|
|
648
|
+
}
|
|
635
649
|
hideBorder
|
|
636
650
|
compact
|
|
637
651
|
answered={requestInputAnswered}
|