@steerable/agent-ui 0.2.3 → 0.2.4
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/cards/ActionSegmentCard.d.ts +18 -0
- package/dist/cards/ActionSegmentCard.d.ts.map +1 -0
- package/dist/cards/ActionSegmentCard.js +26 -0
- package/dist/cards/ActionSegmentCard.js.map +1 -0
- package/dist/cards/AnalysisDocumentCard.d.ts +33 -0
- package/dist/cards/AnalysisDocumentCard.d.ts.map +1 -0
- package/dist/cards/AnalysisDocumentCard.js +11 -0
- package/dist/cards/AnalysisDocumentCard.js.map +1 -0
- package/dist/cards/AskUserQuestionsCard.d.ts +43 -0
- package/dist/cards/AskUserQuestionsCard.d.ts.map +1 -0
- package/dist/cards/AskUserQuestionsCard.js +171 -0
- package/dist/cards/AskUserQuestionsCard.js.map +1 -0
- package/dist/cards/CoverageReportCard.d.ts +41 -0
- package/dist/cards/CoverageReportCard.d.ts.map +1 -0
- package/dist/cards/CoverageReportCard.js +55 -0
- package/dist/cards/CoverageReportCard.js.map +1 -0
- package/dist/cards/OrchestrationPlanCard.d.ts +60 -0
- package/dist/cards/OrchestrationPlanCard.d.ts.map +1 -0
- package/dist/cards/OrchestrationPlanCard.js +103 -0
- package/dist/cards/OrchestrationPlanCard.js.map +1 -0
- package/dist/cards/PlanSelectorCard.d.ts +40 -0
- package/dist/cards/PlanSelectorCard.d.ts.map +1 -0
- package/dist/cards/PlanSelectorCard.js +106 -0
- package/dist/cards/PlanSelectorCard.js.map +1 -0
- package/dist/cards/PlanStepsCard.d.ts +18 -0
- package/dist/cards/PlanStepsCard.d.ts.map +1 -0
- package/dist/cards/PlanStepsCard.js +25 -0
- package/dist/cards/PlanStepsCard.js.map +1 -0
- package/dist/cards/QuizCard.d.ts +44 -0
- package/dist/cards/QuizCard.d.ts.map +1 -0
- package/dist/cards/QuizCard.js +113 -0
- package/dist/cards/QuizCard.js.map +1 -0
- package/dist/cards/ResearchPlanCard.d.ts +23 -0
- package/dist/cards/ResearchPlanCard.d.ts.map +1 -0
- package/dist/cards/ResearchPlanCard.js +50 -0
- package/dist/cards/ResearchPlanCard.js.map +1 -0
- package/dist/cards/SearchSourcesCard.d.ts +29 -0
- package/dist/cards/SearchSourcesCard.d.ts.map +1 -0
- package/dist/cards/SearchSourcesCard.js +83 -0
- package/dist/cards/SearchSourcesCard.js.map +1 -0
- package/dist/cards/SuggestedRepliesCard.d.ts +18 -0
- package/dist/cards/SuggestedRepliesCard.d.ts.map +1 -0
- package/dist/cards/SuggestedRepliesCard.js +14 -0
- package/dist/cards/SuggestedRepliesCard.js.map +1 -0
- package/dist/cards/SummaryMessageCard.d.ts +40 -0
- package/dist/cards/SummaryMessageCard.d.ts.map +1 -0
- package/dist/cards/SummaryMessageCard.js +56 -0
- package/dist/cards/SummaryMessageCard.js.map +1 -0
- package/dist/cards/ThinkingProcessCard.d.ts +46 -0
- package/dist/cards/ThinkingProcessCard.d.ts.map +1 -0
- package/dist/cards/ThinkingProcessCard.js +79 -0
- package/dist/cards/ThinkingProcessCard.js.map +1 -0
- package/dist/cards/ToolExecutionCard.d.ts +21 -0
- package/dist/cards/ToolExecutionCard.d.ts.map +1 -0
- package/dist/cards/ToolExecutionCard.js +65 -0
- package/dist/cards/ToolExecutionCard.js.map +1 -0
- package/dist/cards/icons.d.ts +38 -0
- package/dist/cards/icons.d.ts.map +1 -0
- package/dist/cards/icons.js +87 -0
- package/dist/cards/icons.js.map +1 -0
- package/dist/cards/index.d.ts +38 -0
- package/dist/cards/index.d.ts.map +1 -0
- package/dist/cards/index.js +24 -0
- package/dist/cards/index.js.map +1 -0
- package/dist/cards/types.d.ts +24 -0
- package/dist/cards/types.d.ts.map +1 -0
- package/dist/cards/types.js +7 -0
- package/dist/cards/types.js.map +1 -0
- package/dist/components/AgentSelector.d.ts +23 -0
- package/dist/components/AgentSelector.d.ts.map +1 -0
- package/dist/components/AgentSelector.js +63 -0
- package/dist/components/AgentSelector.js.map +1 -0
- package/dist/components/AgentSelector.stories.d.ts +12 -0
- package/dist/components/AgentSelector.stories.d.ts.map +1 -0
- package/dist/components/AgentSelector.stories.js +95 -0
- package/dist/components/AgentSelector.stories.js.map +1 -0
- package/dist/components/ChatPanel.d.ts +138 -21
- package/dist/components/ChatPanel.d.ts.map +1 -1
- package/dist/components/ChatPanel.js +181 -26
- package/dist/components/ChatPanel.js.map +1 -1
- package/dist/components/index.d.ts +3 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/state/ChatSessionProvider.d.ts +59 -0
- package/dist/state/ChatSessionProvider.d.ts.map +1 -0
- package/dist/state/ChatSessionProvider.js +71 -0
- package/dist/state/ChatSessionProvider.js.map +1 -0
- package/dist/state/MockChatStreamTransport.d.ts +54 -0
- package/dist/state/MockChatStreamTransport.d.ts.map +1 -0
- package/dist/state/MockChatStreamTransport.js +86 -0
- package/dist/state/MockChatStreamTransport.js.map +1 -0
- package/dist/state/MockChatStreamTransport.stories.d.ts +13 -0
- package/dist/state/MockChatStreamTransport.stories.d.ts.map +1 -0
- package/dist/state/MockChatStreamTransport.stories.js +60 -0
- package/dist/state/MockChatStreamTransport.stories.js.map +1 -0
- package/dist/state/bridgeLegacySSE.d.ts +42 -0
- package/dist/state/bridgeLegacySSE.d.ts.map +1 -0
- package/dist/state/bridgeLegacySSE.js +102 -0
- package/dist/state/bridgeLegacySSE.js.map +1 -0
- package/dist/state/index.d.ts +32 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +24 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/parseSSE.d.ts +50 -0
- package/dist/state/parseSSE.d.ts.map +1 -0
- package/dist/state/parseSSE.js +112 -0
- package/dist/state/parseSSE.js.map +1 -0
- package/dist/state/useChatComposer.d.ts +51 -0
- package/dist/state/useChatComposer.d.ts.map +1 -0
- package/dist/state/useChatComposer.js +82 -0
- package/dist/state/useChatComposer.js.map +1 -0
- package/dist/state/useChatList.d.ts +71 -0
- package/dist/state/useChatList.d.ts.map +1 -0
- package/dist/state/useChatList.js +158 -0
- package/dist/state/useChatList.js.map +1 -0
- package/dist/state/useChatSession.d.ts +29 -0
- package/dist/state/useChatSession.d.ts.map +1 -0
- package/dist/state/useChatSession.js +37 -0
- package/dist/state/useChatSession.js.map +1 -0
- package/dist/state/useScrollLock.d.ts +35 -0
- package/dist/state/useScrollLock.d.ts.map +1 -0
- package/dist/state/useScrollLock.js +74 -0
- package/dist/state/useScrollLock.js.map +1 -0
- package/dist/state/useToolCallStream.d.ts +38 -0
- package/dist/state/useToolCallStream.d.ts.map +1 -0
- package/dist/state/useToolCallStream.js +74 -0
- package/dist/state/useToolCallStream.js.map +1 -0
- package/package.json +10 -2
- package/src/cards/ActionSegmentCard.tsx +60 -0
- package/src/cards/AnalysisDocumentCard.tsx +81 -0
- package/src/cards/AskUserQuestionsCard.tsx +354 -0
- package/src/cards/CoverageReportCard.tsx +215 -0
- package/src/cards/OrchestrationPlanCard.tsx +328 -0
- package/src/cards/PlanSelectorCard.tsx +312 -0
- package/src/cards/PlanStepsCard.tsx +52 -0
- package/src/cards/QuizCard.tsx +309 -0
- package/src/cards/ResearchPlanCard.tsx +169 -0
- package/src/cards/SearchSourcesCard.tsx +244 -0
- package/src/cards/SuggestedRepliesCard.tsx +48 -0
- package/src/cards/SummaryMessageCard.tsx +145 -0
- package/src/cards/ThinkingProcessCard.tsx +155 -0
- package/src/cards/ToolExecutionCard.tsx +152 -0
- package/src/cards/cards.test.tsx +492 -0
- package/src/cards/icons.tsx +249 -0
- package/src/cards/index.ts +53 -0
- package/src/cards/types.ts +27 -0
- package/src/components/AgentSelector.stories.tsx +113 -0
- package/src/components/AgentSelector.test.tsx +70 -0
- package/src/components/AgentSelector.tsx +147 -0
- package/src/components/ChatPanel.test.tsx +130 -0
- package/src/components/ChatPanel.tsx +612 -138
- package/src/components/index.ts +13 -1
- package/src/index.ts +43 -0
- package/src/state/ChatSessionProvider.test.tsx +85 -0
- package/src/state/ChatSessionProvider.tsx +98 -0
- package/src/state/MockChatStreamTransport.stories.tsx +95 -0
- package/src/state/MockChatStreamTransport.test.ts +163 -0
- package/src/state/MockChatStreamTransport.ts +123 -0
- package/src/state/bridgeLegacySSE.test.ts +134 -0
- package/src/state/bridgeLegacySSE.ts +134 -0
- package/src/state/index.ts +82 -0
- package/src/state/parseSSE.test.ts +123 -0
- package/src/state/parseSSE.ts +123 -0
- package/src/state/useChatComposer.test.ts +145 -0
- package/src/state/useChatComposer.ts +117 -0
- package/src/state/useChatList.test.ts +135 -0
- package/src/state/useChatList.ts +217 -0
- package/src/state/useChatSession.test.ts +61 -0
- package/src/state/useChatSession.ts +64 -0
- package/src/state/useScrollLock.test.ts +99 -0
- package/src/state/useScrollLock.ts +105 -0
- package/src/state/useToolCallStream.test.ts +86 -0
- package/src/state/useToolCallStream.ts +110 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for the compound `ChatPanel` API.
|
|
3
|
+
*
|
|
4
|
+
* The structural test surface is small — the heavy lifting is in MessageList
|
|
5
|
+
* and the state hooks — but we want to lock in the contract that the
|
|
6
|
+
* compound parts hang off `ChatPanel` AND that the monolithic alias still
|
|
7
|
+
* renders messages + a draftable input.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
11
|
+
import { useState } from 'react';
|
|
12
|
+
import { render, screen, fireEvent } from '@testing-library/react';
|
|
13
|
+
import type { ChatMessage } from '@steerable/agent-protocol';
|
|
14
|
+
import { ChatPanel } from './ChatPanel';
|
|
15
|
+
|
|
16
|
+
const NOW = '2026-05-15T00:00:00Z';
|
|
17
|
+
const sample: ChatMessage[] = [
|
|
18
|
+
{ id: 'u1', role: 'user', content: 'hello', createdAt: NOW },
|
|
19
|
+
{ id: 'a1', role: 'assistant', content: 'hi there', createdAt: NOW },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
function CompoundDemo({ onSubmit }: { onSubmit: () => void }) {
|
|
23
|
+
const [draft, setDraft] = useState('');
|
|
24
|
+
return (
|
|
25
|
+
<ChatPanel.Root>
|
|
26
|
+
<ChatPanel.Messages messages={sample} />
|
|
27
|
+
<ChatPanel.Input
|
|
28
|
+
value={draft}
|
|
29
|
+
onChange={setDraft}
|
|
30
|
+
onSubmit={() => {
|
|
31
|
+
onSubmit();
|
|
32
|
+
setDraft('');
|
|
33
|
+
}}
|
|
34
|
+
/>
|
|
35
|
+
</ChatPanel.Root>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe('ChatPanel compound', () => {
|
|
40
|
+
it('exposes Root, Header, Messages, Input, Empty, StreamingStatus as attached subs', () => {
|
|
41
|
+
// forwardRef components are objects with a render fn; plain components
|
|
42
|
+
// are functions. We assert "callable-ish" rather than pinning the kind.
|
|
43
|
+
for (const sub of [
|
|
44
|
+
ChatPanel.Root,
|
|
45
|
+
ChatPanel.Header,
|
|
46
|
+
ChatPanel.Messages,
|
|
47
|
+
ChatPanel.Input,
|
|
48
|
+
ChatPanel.Empty,
|
|
49
|
+
ChatPanel.StreamingStatus,
|
|
50
|
+
]) {
|
|
51
|
+
expect(sub).toBeDefined();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('Root + Messages + Input compose into a working shell', () => {
|
|
56
|
+
render(<CompoundDemo onSubmit={() => {}} />);
|
|
57
|
+
expect(screen.getByText('hello')).toBeTruthy();
|
|
58
|
+
expect(screen.getByText('hi there')).toBeTruthy();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('Empty slot renders prompts and fires onSelectPrompt on click', () => {
|
|
62
|
+
const onSelectPrompt = vi.fn();
|
|
63
|
+
render(
|
|
64
|
+
<ChatPanel.Empty
|
|
65
|
+
title="Try a prompt"
|
|
66
|
+
prompts={['plan my day', 'summarise']}
|
|
67
|
+
onSelectPrompt={onSelectPrompt}
|
|
68
|
+
/>,
|
|
69
|
+
);
|
|
70
|
+
expect(screen.getByText('Try a prompt')).toBeTruthy();
|
|
71
|
+
fireEvent.click(screen.getByText('plan my day'));
|
|
72
|
+
expect(onSelectPrompt).toHaveBeenCalledWith('plan my day');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('StreamingStatus hides when hasContent=true and renders text otherwise', () => {
|
|
76
|
+
const { rerender, queryByText } = render(
|
|
77
|
+
<ChatPanel.StreamingStatus hasContent={true} round={1} actionCount={0} />,
|
|
78
|
+
);
|
|
79
|
+
expect(queryByText('Thinking…')).toBeNull();
|
|
80
|
+
rerender(
|
|
81
|
+
<ChatPanel.StreamingStatus hasContent={false} round={1} actionCount={0} />,
|
|
82
|
+
);
|
|
83
|
+
expect(queryByText('Thinking…')).toBeTruthy();
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('monolithic alias still renders messages + accepts onSubmit prop', () => {
|
|
87
|
+
const onSubmit = vi.fn();
|
|
88
|
+
render(<ChatPanel messages={sample} onSubmit={onSubmit} />);
|
|
89
|
+
expect(screen.getByText('hello')).toBeTruthy();
|
|
90
|
+
expect(screen.getByText('hi there')).toBeTruthy();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('Input with keyMode=enter sends on plain Enter and inserts newline on Shift+Enter', () => {
|
|
94
|
+
const onSubmit = vi.fn();
|
|
95
|
+
function Demo() {
|
|
96
|
+
const [draft, setDraft] = useState('ping');
|
|
97
|
+
return (
|
|
98
|
+
<ChatPanel.Input
|
|
99
|
+
value={draft}
|
|
100
|
+
onChange={setDraft}
|
|
101
|
+
onSubmit={() => onSubmit()}
|
|
102
|
+
keyMode="enter"
|
|
103
|
+
/>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
render(<Demo />);
|
|
107
|
+
const textarea = screen.getByRole('textbox') as HTMLTextAreaElement;
|
|
108
|
+
fireEvent.keyDown(textarea, { key: 'Enter' });
|
|
109
|
+
expect(onSubmit).toHaveBeenCalledOnce();
|
|
110
|
+
onSubmit.mockClear();
|
|
111
|
+
fireEvent.keyDown(textarea, { key: 'Enter', shiftKey: true });
|
|
112
|
+
expect(onSubmit).not.toHaveBeenCalled();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('Input toggles to a Stop button while streaming, fires onCancel on click', () => {
|
|
116
|
+
const onCancel = vi.fn();
|
|
117
|
+
render(
|
|
118
|
+
<ChatPanel.Input
|
|
119
|
+
value=""
|
|
120
|
+
onChange={() => {}}
|
|
121
|
+
onSubmit={() => {}}
|
|
122
|
+
onCancel={onCancel}
|
|
123
|
+
isStreaming
|
|
124
|
+
/>,
|
|
125
|
+
);
|
|
126
|
+
const stopBtn = screen.getByLabelText('Stop generating');
|
|
127
|
+
fireEvent.click(stopBtn);
|
|
128
|
+
expect(onCancel).toHaveBeenCalledOnce();
|
|
129
|
+
});
|
|
130
|
+
});
|