Skip to content

Commit 659aaec

Browse files
tylerpayneTyler Paynehusseinmozannar
authored
Fix syntax error causing build failure (#374)
Co-authored-by: Tyler Payne <[email protected]> Co-authored-by: Hussein Mozannar <[email protected]>
1 parent 02d5a95 commit 659aaec

File tree

3 files changed

+118
-109
lines changed

3 files changed

+118
-109
lines changed

frontend/src/components/features/McpServerSelector/McpServerSelector.css

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,12 @@
1414

1515
.mcp-selector .ant-select-selection-wrap {
1616
align-items: center;
17-
padding: 5px;
17+
padding: 0px;
1818
}
1919

2020
/* Style the prefix with semi-transparent border */
2121
.mcp-selector-prefix {
22-
padding: 5px;
2322
border-style: solid;
24-
border-width: 1px;
25-
border-radius: 5px;
2623
border-color: transparent !important;
2724
transition: border-color 0.2s ease;
2825
display: inline-flex;

frontend/src/components/features/McpServerSelector/McpServerSelector.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export const McpServerSelector: React.FC<McpServerSelectorProps> = ({ servers, o
3838
}))
3939
}, [servers])
4040

41-
4241
const selectComponent = (
4342
<Select
4443
mode="multiple"
@@ -48,15 +47,16 @@ export const McpServerSelector: React.FC<McpServerSelectorProps> = ({ servers, o
4847
onChange={handleChange}
4948
options={options}
5049
className="mcp-selector"
51-
prefix={<Flex gap={4} className={mcpSelectorPrefixClassNames}><WrenchScrewdriverIcon width={20} /><Typography>Tools</Typography></Flex>}
50+
prefix={<WrenchScrewdriverIcon width={22} />}
5251
suffixIcon={null}
5352
popupMatchSelectWidth={false}
53+
maxTagCount={0}
5454
popupRender={(menu) => (
5555
<>
5656
{menu}
5757
<Divider style={{ margin: '8px 0' }} />
58-
<Button
59-
type="text"
58+
<Button
59+
type="text"
6060
onClick={handleAddServer}
6161
style={{ width: '100%', padding: '0px 12px', marginBottom: "6px" }}
6262
className="mcp-selector-add-mcp-server-button"

frontend/src/components/views/chat/chatinput.tsx

Lines changed: 113 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import PlanView from "./plan";
3333
import { McpServerSelector } from "../../features/McpServerSelector/McpServerSelector";
3434
import { MCPAgentConfig, MCPServerInfo } from "../../features/McpServersConfig/types";
3535
import { extractMcpServers } from "../../features/McpServersConfig/McpServersList";
36-
3736
// Threshold for large text files (in characters)
3837
const LARGE_TEXT_THRESHOLD = 1500;
3938

@@ -105,9 +104,7 @@ const ChatInput = React.forwardRef<{ focus: () => void }, ChatInputProps>(
105104
runStatus === "active" ||
106105
runStatus === "pausing" ||
107106
inputRequest?.input_type === "approval";
108-
109107
const [mcpServers, setMcpServers] = React.useState<MCPServerInfo[]>([]);
110-
111108
// Handle textarea auto-resize
112109
React.useEffect(() => {
113110
if (textAreaRef.current) {
@@ -156,19 +153,18 @@ const ChatInput = React.forwardRef<{ focus: () => void }, ChatInputProps>(
156153
setIsLoading(false);
157154
}
158155
};
159-
160156
const fetchMCPServers = async () => {
161157
if (!user?.email) {
162158
console.error("User not authenticated");
163159
setIsLoading(false);
164160
return;
165161
}
166-
162+
167163
try {
168164
setIsLoading(true);
169-
165+
170166
// Get user's latest settings from database
171-
const settings = await settingsAPI.getSettings(user.email);
167+
const settings = await settingsAPI.getSettings(user.email);
172168
const mcpAgentConfigs: MCPAgentConfig[] = settings.mcp_agent_configs || [];
173169
const mcpServers = extractMcpServers(mcpAgentConfigs);
174170
setMcpServers(mcpServers);
@@ -178,10 +174,10 @@ const ChatInput = React.forwardRef<{ focus: () => void }, ChatInputProps>(
178174
setIsLoading(false);
179175
}
180176
};
181-
177+
182178
fetchMCPServers();
183179
fetchAllPlans();
184-
}, [userId, user?.email]); // Added user?.email to properly track when user changes
180+
}, [userId, user?.email]);
185181

186182
// Add paste event listener for images and large text
187183
const handlePaste = (e: React.ClipboardEvent<HTMLTextAreaElement>) => {
@@ -604,13 +600,15 @@ const ChatInput = React.forwardRef<{ focus: () => void }, ChatInputProps>(
604600
};
605601
}, [isRelevantPlansVisible]);
606602

603+
const goToMcpServersTab = React.useCallback(() => {
607604
onSubMenuChange("mcp_servers");
608-
}, [onSubMenuChange])
609-
605+
}, [onSubMenuChange]);
606+
610607
const handleMcpServerSelectionChange = React.useCallback((newSelection: string[]) => {
611608
onSelectedMcpServersChange(newSelection);
612609
}, [onSelectedMcpServersChange]);
613610

611+
614612
return (
615613
<div className="mt-2 w-full relative">
616614
{notificationContextHolder}
@@ -625,21 +623,52 @@ const ChatInput = React.forwardRef<{ focus: () => void }, ChatInputProps>(
625623
/>
626624
)}
627625

626+
{/* Selected MCP Tools Display */}
627+
{selectedMcpServers.length > 0 && (
628+
<div
629+
className={`-mb-2 mx-1 ${darkMode === "dark" ? "bg-[#333333]" : "bg-gray-100"
630+
} rounded-t border-b-0 p-2 flex border flex-wrap gap-2`}
631+
>
632+
{selectedMcpServers.map((serverName) => (
633+
<div
634+
key={serverName}
635+
className={`flex items-center gap-1 ${darkMode === "dark"
636+
? "bg-[#444444] text-white"
637+
: "bg-white text-black"
638+
} rounded px-2 py-1 text-xs`}
639+
>
640+
<span className="truncate max-w-[150px]">🔧 {serverName}</span>
641+
{runStatus === "created" && (
642+
<Button
643+
type="text"
644+
size="small"
645+
className="p-0 ml-1 flex items-center justify-center"
646+
onClick={() =>
647+
onSelectedMcpServersChange(
648+
selectedMcpServers.filter((s) => s !== serverName)
649+
)
650+
}
651+
icon={<XIcon className="w-3 h-3" />}
652+
/>
653+
)}
654+
</div>
655+
))}
656+
</div>
657+
)}
658+
628659
{/* Attached Items Preview */}
629660
{(attachedPlan || fileList.length > 0) && (
630661
<div
631-
className={`-mb-2 mx-1 ${
632-
darkMode === "dark" ? "bg-[#333333]" : "bg-gray-100"
633-
} rounded-t border-b-0 p-2 flex border flex-wrap gap-2`}
662+
className={`${selectedMcpServers.length > 0 ? '-mt-2' : '-mb-2'} mx-1 ${darkMode === "dark" ? "bg-[#333333]" : "bg-gray-100"
663+
} ${selectedMcpServers.length > 0 ? 'rounded-b border-t-0' : 'rounded-t border-b-0'} p-2 flex border flex-wrap gap-2`}
634664
>
635665
{/* Attached Plan */}
636666
{attachedPlan && (
637667
<div
638-
className={`flex items-center gap-1 ${
639-
darkMode === "dark"
640-
? "bg-[#444444] text-white"
641-
: "bg-white text-black"
642-
} rounded px-2 py-1 text-xs cursor-pointer hover:opacity-80 transition-opacity`}
668+
className={`flex items-center gap-1 ${darkMode === "dark"
669+
? "bg-[#444444] text-white"
670+
: "bg-white text-black"
671+
} rounded px-2 py-1 text-xs cursor-pointer hover:opacity-80 transition-opacity`}
643672
onClick={handlePlanClick}
644673
>
645674
<span className="truncate max-w-[150px]">
@@ -662,11 +691,10 @@ const ChatInput = React.forwardRef<{ focus: () => void }, ChatInputProps>(
662691
{fileList.map((file) => (
663692
<div
664693
key={file.uid}
665-
className={`flex items-center gap-1 ${
666-
darkMode === "dark"
667-
? "bg-[#444444] text-white"
668-
: "bg-white text-black"
669-
} rounded px-2 py-1 text-xs`}
694+
className={`flex items-center gap-1 ${darkMode === "dark"
695+
? "bg-[#444444] text-white"
696+
: "bg-white text-black"
697+
} rounded px-2 py-1 text-xs`}
670698
>
671699
{getFileIcon(file)}
672700
<span className="truncate max-w-[150px]">{file.name}</span>
@@ -700,95 +728,80 @@ const ChatInput = React.forwardRef<{ focus: () => void }, ChatInputProps>(
700728
task={attachedPlan.task || ""}
701729
plan={attachedPlan.steps || []}
702730
viewOnly={true}
703-
setPlan={() => {}}
731+
setPlan={() => { }}
704732
/>
705733
)}
706734
</Modal>
707735

708-
<div className="mt-2 rounded shadow-sm">
736+
<div className="mt-2 rounded shadow-sm flex">
709737
<div
710-
className={`flex flex-col w-full ${dragOver ? "opacity-50" : ""}`}
738+
className={`flex w-full ${dragOver ? "opacity-50" : ""}`}
711739
onDragOver={handleDragOver}
712740
onDragLeave={handleDragLeave}
713741
onDrop={handleDrop}
714742
>
715-
{/* First row: Textarea full width */}
716-
<div className={`w-full border-t border-l border-r border-accent rounded-t-lg ${
717-
darkMode === "dark"
718-
? "bg-[#444444] text-white"
719-
: "bg-white text-black"
720-
}`}>
721-
<form
722-
onSubmit={(e) => {
723-
e.preventDefault();
724-
handleSubmit();
725-
}}
726-
>
727-
<textarea
728-
id="queryInput"
729-
name="queryInput"
730-
onPaste={handlePaste}
731-
ref={textAreaRef}
732-
defaultValue={""}
733-
onChange={handleTextChange}
734-
onKeyDown={handleKeyDown}
735-
className={`flex items-center w-full resize-none p-2 ${
736-
darkMode === "dark"
743+
<div className="flex w-full">
744+
<div className="flex-1">
745+
<form
746+
onSubmit={(e) => {
747+
e.preventDefault();
748+
handleSubmit();
749+
}}
750+
>
751+
<textarea
752+
id="queryInput"
753+
name="queryInput"
754+
onPaste={handlePaste}
755+
ref={textAreaRef}
756+
defaultValue={""}
757+
onChange={handleTextChange}
758+
onKeyDown={handleKeyDown}
759+
className={`flex items-center w-full resize-none border-l border-t border-b border-accent p-2 pl-5 rounded-l-lg ${darkMode === "dark"
737760
? "bg-[#444444] text-white"
738761
: "bg-white text-black"
739-
} ${
740-
isInputDisabled ? "cursor-not-allowed" : ""
741-
} focus:outline-none rounded-t-lg`}
742-
style={{
743-
maxHeight: "120px",
744-
overflowY: "auto",
745-
minHeight: "50px",
746-
}}
747-
placeholder={
748-
runStatus === "awaiting_input"
749-
? "Type your response here and let Magentic-UI know of any changes in the browser."
750-
: enable_upload
751-
? dragOver
752-
? "Drop files here..."
753-
: "Type your message here..."
754-
: "Type your message here..."
755-
}
756-
disabled={isInputDisabled}
757-
/>
758-
</form>
759-
</div>
760-
761-
{/* Second row: MCP Selector (flexible) + Buttons (right-aligned) */}
762-
<div className="flex w-full">
763-
{/* MCP Selector - flexible width */}
764-
<div className={`flex-1 border-l border-b border-accent p-2 rounded-bl-lg flex justify-start items-center ${
765-
darkMode === "dark"
766-
? "bg-[#444444] text-white"
767-
: "bg-white text-black"
768-
}`}>
769-
<McpServerSelector
770-
servers={mcpServers}
771-
onAddMcpServer={goToMcpServersTab}
772-
runStatus={runStatus}
773-
value={selectedMcpServers}
774-
onChange={handleMcpServerSelectionChange}
775-
/>
762+
} ${isInputDisabled ? "cursor-not-allowed" : ""
763+
} focus:outline-none`}
764+
style={{
765+
maxHeight: "120px",
766+
overflowY: "auto",
767+
minHeight: "50px",
768+
}}
769+
placeholder={
770+
runStatus === "awaiting_input"
771+
? "Type your response here and let Magentic-UI know of any changes in the browser."
772+
: enable_upload
773+
? dragOver
774+
? "Drop files here..."
775+
: "Type your message here..."
776+
: "Type your message here..."
777+
}
778+
disabled={isInputDisabled}
779+
/>
780+
</form>
776781
</div>
777782

778-
{/* Buttons - right-aligned */}
779783
<div
780-
className={`flex items-center justify-center gap-2 border-r border-b border-accent px-2 rounded-br-lg ${
781-
darkMode === "dark"
782-
? "bg-[#444444] text-white"
783-
: "bg-white text-black"
784-
}`}
784+
className={`flex items-center justify-center gap-2 border-t border-r border-b border-accent px-2 rounded-r-lg ${darkMode === "dark"
785+
? "bg-[#444444] text-white"
786+
: "bg-white text-black"
787+
}`}
785788
>
789+
790+
{runStatus === "created" && (
791+
<McpServerSelector
792+
servers={mcpServers}
793+
onAddMcpServer={goToMcpServersTab}
794+
runStatus={runStatus}
795+
value={selectedMcpServers}
796+
onChange={handleMcpServerSelectionChange}
797+
/>
798+
)}
799+
786800
{/* File upload button replaced with Dropdown */}
787801
{enable_upload && (
788802
<div
789-
className={`${
790-
isInputDisabled ? "pointer-events-none opacity-50" : ""
791-
}`}
803+
className={`${isInputDisabled ? "pointer-events-none opacity-50" : ""
804+
}`}
792805
>
793806
<Dropdown
794807
overlay={
@@ -857,11 +870,10 @@ const ChatInput = React.forwardRef<{ focus: () => void }, ChatInputProps>(
857870
type="button"
858871
onClick={handleSubmit}
859872
disabled={isInputDisabled}
860-
className={`bg-magenta-800 transition duration-300 rounded flex justify-center items-center w-11 h-9 ${
861-
isInputDisabled
862-
? "cursor-not-allowed"
863-
: "hover:bg-magenta-900"
864-
}`}
873+
className={`bg-magenta-800 transition duration-300 rounded flex justify-center items-center w-11 h-9 ${isInputDisabled
874+
? "cursor-not-allowed"
875+
: "hover:bg-magenta-900"
876+
}`}
865877
>
866878
<PaperAirplaneIcon className="h-6 w-6 text-white" />
867879
</button>
@@ -882,4 +894,4 @@ const ChatInput = React.forwardRef<{ focus: () => void }, ChatInputProps>(
882894
}
883895
);
884896

885-
export default ChatInput;
897+
export default ChatInput;

0 commit comments

Comments
 (0)