Skip to content

Commit cf4d88b

Browse files
authored
fix(tarko-agent-ui): restore fallback image upload when no runtime settings (#1619)
1 parent a59d33d commit cf4d88b

File tree

2 files changed

+63
-21
lines changed

2 files changed

+63
-21
lines changed

multimodal/tarko/agent-ui/src/standalone/chat/MessageInput/AgentOptionsSelector.tsx

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ interface AgentOptionsSelectorProps {
2323
sessionMetadata?: SessionItemMetadata;
2424
className?: string;
2525
onActiveOptionsChange?: (options: ActiveOption[]) => void;
26+
onSchemaChange?: (hasOptions: boolean) => void;
2627
onToggleOption?: (key: string, currentValue: any) => void;
2728
showAttachments?: boolean;
2829
onFileUpload?: () => void;
@@ -128,14 +129,14 @@ const DropdownSubMenu: React.FC<DropdownSubMenuProps> = ({
128129
return (
129130
<>
130131
<button
131-
ref={triggerRef}
132-
onClick={() => !disabled && setIsOpen(!isOpen)}
133-
onMouseEnter={handleMouseEnter}
134-
onMouseLeave={handleMouseLeave}
135-
className={`group flex w-full items-center rounded-lg px-2.5 py-1.5 text-left transition-all duration-200 hover:bg-gray-50 dark:hover:bg-gray-800/50 text-gray-900 dark:text-gray-100 ${
136-
disabled ? 'opacity-50 cursor-not-allowed' : 'hover:scale-[1.02]'
137-
}`}
138-
disabled={disabled}
132+
ref={triggerRef}
133+
onClick={() => !disabled && setIsOpen(!isOpen)}
134+
onMouseEnter={handleMouseEnter}
135+
onMouseLeave={handleMouseLeave}
136+
className={`group flex w-full items-center rounded-lg px-2.5 py-1.5 text-left transition-all duration-200 hover:bg-gray-50 dark:hover:bg-gray-800/50 text-gray-900 dark:text-gray-100 ${
137+
disabled ? 'opacity-50 cursor-not-allowed' : 'hover:scale-[1.02]'
138+
}`}
139+
disabled={disabled}
139140
>
140141
{trigger}
141142
<FiChevronRight className="ml-1.5 w-3.5 h-3.5 text-gray-400" />
@@ -155,6 +156,7 @@ export const AgentOptionsSelector = forwardRef<AgentOptionsSelectorRef, AgentOpt
155156
sessionMetadata,
156157
className = '',
157158
onActiveOptionsChange,
159+
onSchemaChange,
158160
onToggleOption,
159161
showAttachments = true,
160162
onFileUpload,
@@ -326,24 +328,36 @@ export const AgentOptionsSelector = forwardRef<AgentOptionsSelectorRef, AgentOpt
326328
onActiveOptionsChange(activeOptions);
327329
}, [schema, currentValues, onActiveOptionsChange]);
328330

329-
// Don't render if in replay mode or processing
330-
if (isReplayMode || isProcessingProp) {
331+
// Notify parent about schema availability
332+
useEffect(() => {
333+
if (onSchemaChange) {
334+
const hasOptions = schema?.properties && Object.keys(schema.properties).length > 0;
335+
onSchemaChange(!!hasOptions);
336+
}
337+
}, [schema, onSchemaChange]);
338+
339+
// Don't render if in replay mode, processing, or no schema available
340+
if (
341+
isReplayMode ||
342+
isProcessingProp ||
343+
!schema?.properties ||
344+
Object.keys(schema.properties).length === 0
345+
) {
331346
return null;
332347
}
333348

334-
// Always show the button, even if no schema options available
335-
const options = schema?.properties
336-
? Object.entries(schema.properties).map(([key, property]) => ({
337-
key,
338-
property,
339-
currentValue: currentValues?.[key] ?? property.default,
340-
}))
341-
: [];
349+
// Only show the button when schema options are available
350+
const options = Object.entries(schema.properties).map(([key, property]) => ({
351+
key,
352+
property,
353+
currentValue: currentValues?.[key] ?? property.default,
354+
}));
342355

343356
const getOptionIcon = (key: string, property: any) => {
344357
const lowerKey = key.toLowerCase();
345358
const lowerTitle = (property.title || '').toLowerCase();
346-
if (lowerKey.includes('browser') || lowerTitle.includes('browser')) return <TbBrowser className="w-4 h-4" />;
359+
if (lowerKey.includes('browser') || lowerTitle.includes('browser'))
360+
return <TbBrowser className="w-4 h-4" />;
347361
if (lowerKey.includes('search')) return <TbSearch className="w-4 h-4" />;
348362
if (lowerKey.includes('research')) return <TbBook className="w-4 h-4" />;
349363
if (lowerKey.includes('foo')) return <TbBulb className="w-4 h-4" />;

multimodal/tarko/agent-ui/src/standalone/chat/MessageInput/ChatInput.tsx

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export const ChatInput: React.FC<ChatInputProps> = ({
6262
const [activeAgentOptions, setActiveAgentOptions] = useState<
6363
Array<{ key: string; title: string; currentValue: any; displayValue?: string }>
6464
>([]);
65+
const [hasAgentOptions, setHasAgentOptions] = useState(false);
6566
const agentOptionsSelectorRef = useRef<AgentOptionsSelectorRef | null>(null);
6667

6768
const { activeSessionId, sessionMetadata } = useSession();
@@ -82,8 +83,20 @@ export const ChatInput: React.FC<ChatInputProps> = ({
8283
// Clear active agent options when session changes
8384
useEffect(() => {
8485
setActiveAgentOptions([]);
86+
setHasAgentOptions(false);
8587
}, [sessionId]);
8688

89+
const handleSchemaChange = useCallback((hasOptions: boolean) => {
90+
setHasAgentOptions(hasOptions);
91+
}, []);
92+
93+
const handleActiveOptionsChange = useCallback(
94+
(options: Array<{ key: string; title: string; currentValue: any; displayValue?: string }>) => {
95+
setActiveAgentOptions(options);
96+
},
97+
[],
98+
);
99+
87100
const handleToggleOption = useCallback((key: string, currentValue: any) => {
88101
// Use the ref to call the toggle method on AgentOptionsSelector
89102
if (agentOptionsSelectorRef.current) {
@@ -450,14 +463,28 @@ export const ChatInput: React.FC<ChatInputProps> = ({
450463
ref={agentOptionsSelectorRef}
451464
activeSessionId={sessionId}
452465
sessionMetadata={sessionMetadata}
453-
onActiveOptionsChange={setActiveAgentOptions}
466+
onActiveOptionsChange={handleActiveOptionsChange}
467+
onSchemaChange={handleSchemaChange}
454468
onToggleOption={handleToggleOption}
455469
showAttachments={showAttachments}
456470
onFileUpload={handleFileUpload}
457471
isDisabled={isDisabled}
458472
isProcessing={isProcessing}
459473
/>
460474

475+
{/* Fallback image upload button when no agent options */}
476+
{!hasAgentOptions && showAttachments && (
477+
<button
478+
type="button"
479+
onClick={handleFileUpload}
480+
disabled={isDisabled || isProcessing}
481+
className="p-2 rounded-full text-gray-500 hover:bg-gray-50 dark:hover:bg-gray-700/30 dark:text-gray-400 transition-all duration-200 hover:scale-105 active:scale-90"
482+
title="Add Images"
483+
>
484+
<FiImage size={18} />
485+
</button>
486+
)}
487+
461488
{/* Active agent options tags */}
462489
{activeAgentOptions.length > 0 && (
463490
<div className="flex flex-wrap gap-1.5">
@@ -466,7 +493,8 @@ export const ChatInput: React.FC<ChatInputProps> = ({
466493
const getOptionIcon = () => {
467494
const lowerKey = option.key.toLowerCase();
468495
const lowerTitle = option.title.toLowerCase();
469-
if (lowerKey.includes('browser') || lowerTitle.includes('browser')) return <TbBrowser className="w-3 h-3" />;
496+
if (lowerKey.includes('browser') || lowerTitle.includes('browser'))
497+
return <TbBrowser className="w-3 h-3" />;
470498
if (lowerKey.includes('foo')) return <TbBulb className="w-3 h-3" />;
471499
if (lowerKey.includes('search')) return <TbSearch className="w-3 h-3" />;
472500
if (lowerKey.includes('research')) return <TbBook className="w-3 h-3" />;

0 commit comments

Comments
 (0)