Skip to content

Commit 5662f12

Browse files
author
ci-bot
committed
fixes and e2e
1 parent 8ed0264 commit 5662f12

File tree

9 files changed

+426
-135
lines changed

9 files changed

+426
-135
lines changed

apps/remix-ide-e2e/src/tests/chatHistory.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module.exports = {
2121
})
2222
.waitForElementVisible('*[data-id="toggle-history-btn"]', 10000)
2323
.click('*[data-id="toggle-history-btn"]')
24-
.assert.containsText('*[data-id="chat-history-sidebar"]', 'Chat history')
24+
.assert.containsText('*[data-id="chat-history-sidebar-title"]', 'Chat history')
2525
.waitForElementVisible('.text-center.text-muted', 5000)
2626
.assert.containsText('.text-center.text-muted', 'No conversations yet')
2727
.pause()
@@ -32,8 +32,8 @@ module.exports = {
3232
.waitForElementVisible('*[data-id="new-conversation-btn"]', 5000)
3333
.click('*[data-id="new-conversation-btn"]')
3434
.pause(1000)
35-
.waitForElementVisible('*[data-id="remix-ai-composer-input"]', 10000)
36-
.setValue('*[data-id="remix-ai-composer-input"]', 'Hello, this is my first message')
35+
.waitForElementVisible('*[data-id="remix-ai-prompt-input"]', 10000)
36+
.setValue('*[data-id="remix-ai-prompt-input"]', 'Hello, this is my first message')
3737
.click('*[data-id="remix-ai-composer-send-btn"]')
3838
.waitForElementPresent({
3939
selector: "//*[@data-id='remix-ai-streaming' and @data-streaming='false']",
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import React from 'react'
2+
import GroupListMenu from './contextOptMenu'
3+
import { PromptArea } from './prompt'
4+
5+
interface AiChatPromptAreaProps {
6+
themeTracker: any
7+
showHistorySidebar: boolean
8+
isMaximized: boolean
9+
showAssistantOptions: boolean
10+
modelOpt: { top: number, left: number }
11+
menuRef: React.RefObject<HTMLDivElement>
12+
setShowAssistantOptions: React.Dispatch<React.SetStateAction<boolean>>
13+
assistantChoice: any
14+
setAssistantChoice: React.Dispatch<React.SetStateAction<any>>
15+
aiAssistantGroupList: any[]
16+
mcpEnabled: boolean
17+
mcpEnhanced: boolean
18+
setMcpEnhanced: React.Dispatch<React.SetStateAction<boolean>>
19+
availableModels: string[]
20+
selectedModel: string | null
21+
handleModelSelection: (modelName: string) => void
22+
input: string
23+
setInput: React.Dispatch<React.SetStateAction<string>>
24+
isStreaming: boolean
25+
handleSend: () => void
26+
stopRequest: () => void
27+
showModelOptions: boolean
28+
setShowModelOptions: React.Dispatch<React.SetStateAction<boolean>>
29+
handleSetAssistant: () => void
30+
handleSetModel: () => void
31+
handleGenerateWorkspace: () => void
32+
handleRecord: () => void
33+
isRecording: boolean
34+
dispatchActivity: (type: string, payload?: any) => void
35+
modelBtnRef: React.RefObject<HTMLButtonElement>
36+
modelSelectorBtnRef: React.RefObject<HTMLButtonElement>
37+
textareaRef?: React.RefObject<HTMLTextAreaElement>
38+
maximizePanel: () => Promise<void>
39+
}
40+
41+
export default function AiChatPromptArea(props: AiChatPromptAreaProps) {
42+
43+
{/* Prompt area - fixed at bottom */}
44+
return (
45+
<section
46+
id="remix-ai-prompt-area"
47+
className="ai-assistant-prompt-bg"
48+
style={{ flexShrink: 0, minHeight: '140px', backgroundColor: props.showHistorySidebar && props.isMaximized === false ? (props.themeTracker?.name.toLowerCase() === 'dark' ? 'var(--bs-dark)' : 'var(--bs-light)') : 'transparent' }}
49+
data-theme={props.themeTracker && props.themeTracker?.name.toLowerCase()}
50+
>
51+
{props.showAssistantOptions && (
52+
<div
53+
className="pt-2 mb-2 z-3 bg-light border border-text position-fixed"
54+
style={{ borderRadius: '8px', top: props.modelOpt.top, left: props.modelOpt.left, zIndex: 1000, minWidth: '300px', maxWidth: '400px' }}
55+
ref={props.menuRef}
56+
>
57+
<div className="text-uppercase ms-2 mb-2 small">AI Assistant Provider</div>
58+
<GroupListMenu
59+
setChoice={props.setAssistantChoice}
60+
setShowOptions={props.setShowAssistantOptions}
61+
choice={props.assistantChoice}
62+
groupList={props.aiAssistantGroupList}
63+
/>
64+
{props.mcpEnabled && (
65+
<div className="border-top mt-2 pt-2">
66+
<div className="text-uppercase ms-2 mb-2 small">MCP Enhancement</div>
67+
<div className="form-check ms-2 mb-2">
68+
<input
69+
className="form-check-input"
70+
type="checkbox"
71+
id="mcpEnhancementToggle"
72+
checked={props.mcpEnhanced}
73+
onChange={(e) => props.setMcpEnhanced(e.target.checked)}
74+
/>
75+
<label className="form-check-label small" htmlFor="mcpEnhancementToggle">
76+
Enable MCP context enhancement
77+
</label>
78+
</div>
79+
<div className="small text-muted ms-2">
80+
Adds relevant context from configured MCP servers to AI requests
81+
</div>
82+
</div>
83+
)}
84+
</div>
85+
)}
86+
{props.showModelOptions && props.assistantChoice === 'ollama' && (
87+
<div
88+
className="pt-2 mb-2 z-3 bg-light border border-text w-75 position-absolute"
89+
style={{ borderRadius: '8px' }}
90+
>
91+
<div className="text-uppercase ml-2 mb-2 small">Ollama Model</div>
92+
<GroupListMenu
93+
setChoice={props.handleModelSelection}
94+
setShowOptions={props.setShowModelOptions}
95+
choice={props.selectedModel}
96+
groupList={props.availableModels.map(model => ({
97+
label: model,
98+
bodyText: `Use ${model} model`,
99+
icon: 'fa-solid fa-check',
100+
stateValue: model,
101+
dataId: `ollama-model-${model.replace(/[^a-zA-Z0-9]/g, '-')}`
102+
}))}
103+
/>
104+
</div>
105+
)}
106+
<PromptArea
107+
input={props.input}
108+
maximizePanel={props.maximizePanel}
109+
setInput={props.setInput}
110+
isStreaming={props.isStreaming}
111+
handleSend={props.handleSend}
112+
handleStop={props.stopRequest}
113+
showContextOptions={false}
114+
setShowContextOptions={() => {}}
115+
showAssistantOptions={props.showAssistantOptions}
116+
setShowAssistantOptions={props.setShowAssistantOptions}
117+
showModelOptions={props.showModelOptions}
118+
setShowModelOptions={props.setShowModelOptions}
119+
assistantChoice={props.assistantChoice}
120+
setAssistantChoice={props.setAssistantChoice}
121+
availableModels={props.availableModels}
122+
selectedModel={props.selectedModel}
123+
handleSetAssistant={props.handleSetAssistant}
124+
handleSetModel={props.handleSetModel}
125+
handleModelSelection={props.handleModelSelection}
126+
handleGenerateWorkspace={props.handleGenerateWorkspace}
127+
handleRecord={props.handleRecord}
128+
isRecording={props.isRecording}
129+
dispatchActivity={props.dispatchActivity}
130+
modelBtnRef={props.modelBtnRef}
131+
modelSelectorBtnRef={props.modelSelectorBtnRef}
132+
textareaRef={props.textareaRef}
133+
isMaximized={props.isMaximized || false}
134+
themeTracker={props.themeTracker}
135+
/>
136+
</section>
137+
)
138+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import React from 'react'
2+
import GroupListMenu from './contextOptMenu'
3+
import { PromptArea } from './prompt'
4+
5+
interface AiChatPromptAreaForHistoryProps {
6+
themeTracker: any
7+
showHistorySidebar: boolean
8+
isMaximized: boolean
9+
showAssistantOptions: boolean
10+
modelOpt: { top: number, left: number }
11+
menuRef: React.RefObject<HTMLDivElement>
12+
setShowAssistantOptions: React.Dispatch<React.SetStateAction<boolean>>
13+
assistantChoice: any
14+
setAssistantChoice: React.Dispatch<React.SetStateAction<any>>
15+
aiAssistantGroupList: any[]
16+
mcpEnabled: boolean
17+
mcpEnhanced: boolean
18+
setMcpEnhanced: React.Dispatch<React.SetStateAction<boolean>>
19+
availableModels: string[]
20+
selectedModel: any
21+
handleModelSelection: (modelName: string) => void
22+
input: string
23+
setInput: React.Dispatch<React.SetStateAction<string>>
24+
isStreaming: boolean
25+
handleSend: () => void
26+
stopRequest: () => void
27+
showModelOptions: boolean
28+
setShowModelOptions: React.Dispatch<React.SetStateAction<boolean>>
29+
handleSetAssistant: () => void
30+
handleSetModel: () => void
31+
handleGenerateWorkspace: () => void
32+
handleRecord: () => void
33+
isRecording: boolean
34+
dispatchActivity: (type: string, payload?: any) => void
35+
modelBtnRef: React.RefObject<HTMLButtonElement>
36+
modelSelectorBtnRef: React.RefObject<HTMLButtonElement>
37+
textareaRef?: React.RefObject<HTMLTextAreaElement>
38+
maximizePanel: () => Promise<void>
39+
}
40+
41+
export default function AiChatPromptAreaForHistory(props: AiChatPromptAreaForHistoryProps) {
42+
43+
return (
44+
<section
45+
id="remix-ai-prompt-area"
46+
className=""
47+
style={{ flexShrink: 0, minHeight: '140px', backgroundColor: props.showHistorySidebar && props.isMaximized === false ? (props.themeTracker?.name.toLowerCase() === 'dark' ? '#222336' : '#eff1f5') : 'transparent' }}
48+
data-theme={props.themeTracker && props.themeTracker?.name.toLowerCase()}
49+
>
50+
{props.showAssistantOptions && (
51+
<div
52+
className="pt-2 mb-2 z-3 bg-light border border-text position-fixed"
53+
style={{ borderRadius: '8px', top: props.modelOpt.top, left: props.modelOpt.left, zIndex: 1000, minWidth: '300px', maxWidth: '400px' }}
54+
ref={props.menuRef}
55+
>
56+
<div className="text-uppercase ms-2 mb-2 small">AI Assistant Provider</div>
57+
<GroupListMenu
58+
setChoice={props.setAssistantChoice}
59+
setShowOptions={props.setShowAssistantOptions}
60+
choice={props.assistantChoice}
61+
groupList={props.aiAssistantGroupList}
62+
/>
63+
{props.mcpEnabled && (
64+
<div className="border-top mt-2 pt-2">
65+
<div className="text-uppercase ms-2 mb-2 small">MCP Enhancement</div>
66+
<div className="form-check ms-2 mb-2">
67+
<input
68+
className="form-check-input"
69+
type="checkbox"
70+
id="mcpEnhancementToggle"
71+
checked={props.mcpEnhanced}
72+
onChange={(e) => props.setMcpEnhanced(e.target.checked)}
73+
/>
74+
<label className="form-check-label small" htmlFor="mcpEnhancementToggle">
75+
Enable MCP context enhancement
76+
</label>
77+
</div>
78+
<div className="small text-muted ms-2">
79+
Adds relevant context from configured MCP servers to AI requests
80+
</div>
81+
</div>
82+
)}
83+
</div>
84+
)}
85+
{props.showModelOptions && props.assistantChoice === 'ollama' && (
86+
<div
87+
className="pt-2 mb-2 z-3 bg-light border border-text w-75 position-absolute"
88+
style={{ borderRadius: '8px' }}
89+
>
90+
<div className="text-uppercase ml-2 mb-2 small">Ollama Model</div>
91+
<GroupListMenu
92+
setChoice={props.handleModelSelection}
93+
setShowOptions={props.setShowModelOptions}
94+
choice={props.selectedModel}
95+
groupList={props.availableModels.map(model => ({
96+
label: model,
97+
bodyText: `Use ${model} model`,
98+
icon: 'fa-solid fa-check',
99+
stateValue: model,
100+
dataId: `ollama-model-${model.replace(/[^a-zA-Z0-9]/g, '-')}`
101+
}))}
102+
/>
103+
</div>
104+
)}
105+
<PromptArea
106+
input={props.input}
107+
maximizePanel={props.maximizePanel}
108+
setInput={props.setInput}
109+
isStreaming={props.isStreaming}
110+
handleSend={props.handleSend}
111+
handleStop={props.stopRequest}
112+
showContextOptions={false}
113+
setShowContextOptions={() => {}}
114+
showAssistantOptions={props.showAssistantOptions}
115+
setShowAssistantOptions={props.setShowAssistantOptions}
116+
showModelOptions={props.showModelOptions}
117+
setShowModelOptions={props.setShowModelOptions}
118+
assistantChoice={props.assistantChoice}
119+
setAssistantChoice={props.setAssistantChoice}
120+
availableModels={props.availableModels}
121+
selectedModel={props.selectedModel}
122+
handleSetAssistant={props.handleSetAssistant}
123+
handleSetModel={props.handleSetModel}
124+
handleModelSelection={props.handleModelSelection}
125+
handleGenerateWorkspace={props.handleGenerateWorkspace}
126+
handleRecord={props.handleRecord}
127+
isRecording={props.isRecording}
128+
dispatchActivity={props.dispatchActivity}
129+
modelBtnRef={props.modelBtnRef}
130+
modelSelectorBtnRef={props.modelSelectorBtnRef}
131+
textareaRef={props.textareaRef}
132+
isMaximized={props.isMaximized || false}
133+
themeTracker={props.themeTracker}
134+
/>
135+
</section>
136+
)
137+
}

libs/remix-ui/remix-ai-assistant/src/components/chatHistoryHeading.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ interface ChatHistoryHeadingProps {
99
currentConversationId?: string | null
1010
showButton: boolean
1111
setShowButton: (show: boolean) => void
12+
theme?: string
1213
}
1314

1415
export default function ChatHistoryHeading({
@@ -17,11 +18,13 @@ export default function ChatHistoryHeading({
1718
showHistorySidebar,
1819
archiveChat,
1920
currentConversationId,
20-
showButton
21+
showButton,
22+
theme
2123
}: ChatHistoryHeadingProps) {
2224

2325
return (
24-
<section className="d-flex flex-row justify-content-between align-items-center p-2 border-0 border-bottom">
26+
<section className={`d-flex flex-row justify-content-between align-items-center p-2 border-0`} data-theme={theme?.toLowerCase()}
27+
style={{ backgroundColor: theme && theme.toLowerCase() === 'dark' ? '#222336' : '#eff1f5' }}>
2528
<div>
2629
<CustomTooltip
2730
tooltipText={'Start a new chat'}

0 commit comments

Comments
 (0)