@agentuity/workbench 0.0.105 → 0.0.107
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/components/App.d.ts.map +1 -1
- package/dist/components/App.js +15 -13
- package/dist/components/App.js.map +1 -1
- package/dist/components/ai-elements/actions.d.ts +1 -1
- package/dist/components/ai-elements/actions.d.ts.map +1 -1
- package/dist/components/ai-elements/actions.js +1 -1
- package/dist/components/ai-elements/actions.js.map +1 -1
- package/dist/components/ai-elements/code-block.d.ts +1 -1
- package/dist/components/ai-elements/code-block.d.ts.map +1 -1
- package/dist/components/ai-elements/code-block.js +22 -20
- package/dist/components/ai-elements/code-block.js.map +1 -1
- package/dist/components/ai-elements/conversation.d.ts +2 -2
- package/dist/components/ai-elements/conversation.d.ts.map +1 -1
- package/dist/components/ai-elements/conversation.js +5 -3
- package/dist/components/ai-elements/conversation.js.map +1 -1
- package/dist/components/ai-elements/message.d.ts +1 -1
- package/dist/components/ai-elements/message.d.ts.map +1 -1
- package/dist/components/ai-elements/message.js +4 -9
- package/dist/components/ai-elements/message.js.map +1 -1
- package/dist/components/ai-elements/prompt-input.d.ts.map +1 -1
- package/dist/components/ai-elements/prompt-input.js +1 -1
- package/dist/components/ai-elements/prompt-input.js.map +1 -1
- package/dist/components/ai-elements/shimmer.d.ts.map +1 -1
- package/dist/components/ai-elements/shimmer.js +1 -1
- package/dist/components/ai-elements/shimmer.js.map +1 -1
- package/dist/components/internal/chat.d.ts +10 -0
- package/dist/components/internal/chat.d.ts.map +1 -0
- package/dist/components/internal/chat.js +104 -0
- package/dist/components/internal/chat.js.map +1 -0
- package/dist/components/internal/{Header.d.ts → header.d.ts} +4 -6
- package/dist/components/internal/header.d.ts.map +1 -0
- package/dist/components/internal/header.js +25 -0
- package/dist/components/internal/header.js.map +1 -0
- package/dist/components/internal/{InputSection.d.ts → input-section.d.ts} +9 -9
- package/dist/components/internal/input-section.d.ts.map +1 -0
- package/dist/components/internal/input-section.js +162 -0
- package/dist/components/internal/input-section.js.map +1 -0
- package/dist/components/internal/json-editor.d.ts +14 -0
- package/dist/components/internal/json-editor.d.ts.map +1 -0
- package/dist/components/internal/{MonacoJsonEditor.js → json-editor.js} +40 -37
- package/dist/components/internal/json-editor.js.map +1 -0
- package/dist/components/internal/logo.d.ts +2 -3
- package/dist/components/internal/logo.d.ts.map +1 -1
- package/dist/components/internal/logo.js +2 -2
- package/dist/components/internal/logo.js.map +1 -1
- package/dist/components/internal/resizable-provider.d.ts.map +1 -0
- package/dist/components/internal/resizable-provider.js.map +1 -0
- package/dist/components/internal/{Schema.d.ts → schema.d.ts} +2 -2
- package/dist/components/internal/schema.d.ts.map +1 -0
- package/dist/components/internal/schema.js +13 -0
- package/dist/components/internal/schema.js.map +1 -0
- package/dist/components/internal/{WorkbenchProvider.d.ts → workbench-provider.d.ts} +8 -4
- package/dist/components/internal/workbench-provider.d.ts.map +1 -0
- package/dist/components/internal/{WorkbenchProvider.js → workbench-provider.js} +87 -60
- package/dist/components/internal/workbench-provider.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +1 -1
- package/dist/components/ui/avatar.d.ts.map +1 -1
- package/dist/components/ui/avatar.js.map +1 -1
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/command.d.ts +1 -1
- package/dist/components/ui/command.d.ts.map +1 -1
- package/dist/components/ui/command.js.map +1 -1
- package/dist/components/ui/dialog.d.ts +1 -1
- package/dist/components/ui/dialog.d.ts.map +1 -1
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/dropdown-menu.d.ts +1 -1
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.js.map +1 -1
- package/dist/components/ui/hover-card.d.ts +1 -1
- package/dist/components/ui/hover-card.d.ts.map +1 -1
- package/dist/components/ui/hover-card.js.map +1 -1
- package/dist/components/ui/input-group.d.ts +2 -2
- package/dist/components/ui/input-group.d.ts.map +1 -1
- package/dist/components/ui/input-group.js.map +1 -1
- package/dist/components/ui/input.d.ts +1 -1
- package/dist/components/ui/input.d.ts.map +1 -1
- package/dist/components/ui/scroll-area.d.ts +1 -1
- package/dist/components/ui/scroll-area.d.ts.map +1 -1
- package/dist/components/ui/scroll-area.js.map +1 -1
- package/dist/components/ui/textarea.d.ts +1 -1
- package/dist/components/ui/textarea.d.ts.map +1 -1
- package/dist/components/ui/theme-provider.d.ts.map +1 -1
- package/dist/components/ui/theme-provider.js +1 -1
- package/dist/components/ui/theme-provider.js.map +1 -1
- package/dist/components/ui/tooltip.d.ts +1 -1
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/hooks/useAgentSchemas.d.ts +10 -10
- package/dist/hooks/useAgentSchemas.d.ts.map +1 -1
- package/dist/hooks/useAgentSchemas.js +9 -7
- package/dist/hooks/useAgentSchemas.js.map +1 -1
- package/dist/hooks/useLogger.d.ts.map +1 -1
- package/dist/hooks/useLogger.js +2 -1
- package/dist/hooks/useLogger.js.map +1 -1
- package/dist/hooks/useWorkbenchWebsocket.d.ts +2 -2
- package/dist/hooks/useWorkbenchWebsocket.d.ts.map +1 -1
- package/dist/hooks/useWorkbenchWebsocket.js +24 -20
- package/dist/hooks/useWorkbenchWebsocket.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +59 -0
- package/dist/lib/utils.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/standalone.css +360 -295
- package/dist/types/config.d.ts +27 -18
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/base.css +186 -158
- package/src/components/App.tsx +31 -16
- package/src/components/ai-elements/actions.tsx +2 -2
- package/src/components/ai-elements/code-block.tsx +46 -32
- package/src/components/ai-elements/conversation.tsx +18 -17
- package/src/components/ai-elements/message.tsx +4 -9
- package/src/components/ai-elements/prompt-input.tsx +1 -1
- package/src/components/ai-elements/shimmer.tsx +1 -1
- package/src/components/internal/chat.tsx +326 -0
- package/src/components/internal/{Header.tsx → header.tsx} +37 -40
- package/src/components/internal/{InputSection.tsx → input-section.tsx} +173 -119
- package/src/components/internal/{MonacoJsonEditor.tsx → json-editor.tsx} +77 -49
- package/src/components/internal/logo.tsx +3 -5
- package/src/components/internal/schema.tsx +96 -0
- package/src/components/internal/{WorkbenchProvider.tsx → workbench-provider.tsx} +194 -68
- package/src/components/ui/avatar.tsx +1 -1
- package/src/components/ui/command.tsx +1 -1
- package/src/components/ui/dialog.tsx +1 -1
- package/src/components/ui/dropdown-menu.tsx +1 -1
- package/src/components/ui/hover-card.tsx +1 -1
- package/src/components/ui/input-group.tsx +1 -1
- package/src/components/ui/input.tsx +1 -1
- package/src/components/ui/scroll-area.tsx +1 -1
- package/src/components/ui/textarea.tsx +1 -1
- package/src/components/ui/theme-provider.tsx +1 -1
- package/src/components/ui/tooltip.tsx +1 -1
- package/src/hooks/useAgentSchemas.ts +26 -15
- package/src/hooks/useLogger.ts +7 -1
- package/src/hooks/useWorkbenchWebsocket.ts +67 -32
- package/src/index.ts +5 -9
- package/src/lib/utils.ts +88 -0
- package/src/server.ts +1 -1
- package/src/types/config.ts +28 -21
- package/dist/components/internal/Chat.d.ts +0 -14
- package/dist/components/internal/Chat.d.ts.map +0 -1
- package/dist/components/internal/Chat.js +0 -61
- package/dist/components/internal/Chat.js.map +0 -1
- package/dist/components/internal/Header.d.ts.map +0 -1
- package/dist/components/internal/Header.js +0 -31
- package/dist/components/internal/Header.js.map +0 -1
- package/dist/components/internal/InputSection.d.ts.map +0 -1
- package/dist/components/internal/InputSection.js +0 -152
- package/dist/components/internal/InputSection.js.map +0 -1
- package/dist/components/internal/MonacoJsonEditor.d.ts +0 -13
- package/dist/components/internal/MonacoJsonEditor.d.ts.map +0 -1
- package/dist/components/internal/MonacoJsonEditor.js.map +0 -1
- package/dist/components/internal/Schema.d.ts.map +0 -1
- package/dist/components/internal/Schema.js +0 -13
- package/dist/components/internal/Schema.js.map +0 -1
- package/dist/components/internal/WorkbenchProvider.d.ts.map +0 -1
- package/dist/components/internal/WorkbenchProvider.js.map +0 -1
- package/dist/components/ui/resizable-provider.d.ts.map +0 -1
- package/dist/components/ui/resizable-provider.js.map +0 -1
- package/src/components/internal/Chat.tsx +0 -201
- package/src/components/internal/Schema.tsx +0 -100
- /package/dist/components/{ui → internal}/resizable-provider.d.ts +0 -0
- /package/dist/components/{ui → internal}/resizable-provider.js +0 -0
- /package/src/components/{ui → internal}/resizable-provider.tsx +0 -0
|
@@ -1,20 +1,50 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import { Settings } from 'lucide-react';
|
|
3
|
-
import
|
|
2
|
+
import { cn } from '../../lib/utils';
|
|
3
|
+
import type { ConnectionStatus } from '../../types/config';
|
|
4
4
|
import { Button } from '../ui/button';
|
|
5
5
|
import { ThemeToggle } from '../ui/theme-toggle';
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import Logo from './logo';
|
|
7
|
+
import { useWorkbench } from './workbench-provider';
|
|
8
8
|
|
|
9
9
|
export interface HeaderProps {
|
|
10
10
|
className?: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
showSettings?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function Header({ className, title = 'Workbench', showSettings = false }: HeaderProps) {
|
|
16
|
+
const { connectionStatus } = useWorkbench();
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<nav className={cn('flex items-center justify-between gap-6 py-2 px-4 border-b', className)}>
|
|
20
|
+
<div className="flex items-center gap-2.5">
|
|
21
|
+
<Logo />
|
|
22
|
+
|
|
23
|
+
<h1 className="text-sm">{title}</h1>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div className="flex items-center gap-3">
|
|
27
|
+
<StatusIndicator status={connectionStatus} />
|
|
28
|
+
|
|
29
|
+
<div className="flex items-center gap-1">
|
|
30
|
+
<ThemeToggle />
|
|
31
|
+
|
|
32
|
+
{showSettings && (
|
|
33
|
+
<Button size="icon" variant="ghost">
|
|
34
|
+
<Settings />
|
|
35
|
+
</Button>
|
|
36
|
+
)}
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</nav>
|
|
40
|
+
);
|
|
11
41
|
}
|
|
12
42
|
|
|
13
43
|
export function StatusIndicator({ status }: { status: ConnectionStatus }) {
|
|
14
44
|
if (status === 'connected') {
|
|
15
45
|
return (
|
|
16
46
|
<div className="flex items-center gap-1.5 text-xs text-green-600 dark:text-green-400">
|
|
17
|
-
<div className="
|
|
47
|
+
<div className="size-2 rounded-full bg-green-500 animate-pulse"></div>
|
|
18
48
|
<span>Connected</span>
|
|
19
49
|
</div>
|
|
20
50
|
);
|
|
@@ -23,7 +53,7 @@ export function StatusIndicator({ status }: { status: ConnectionStatus }) {
|
|
|
23
53
|
if (status === 'restarting') {
|
|
24
54
|
return (
|
|
25
55
|
<div className="flex items-center gap-1.5 text-xs text-amber-600 dark:text-amber-400">
|
|
26
|
-
<div className="
|
|
56
|
+
<div className="size-2 rounded-full bg-amber-500 animate-pulse"></div>
|
|
27
57
|
<span>Restarting...</span>
|
|
28
58
|
</div>
|
|
29
59
|
);
|
|
@@ -32,7 +62,7 @@ export function StatusIndicator({ status }: { status: ConnectionStatus }) {
|
|
|
32
62
|
if (status === 'disconnected') {
|
|
33
63
|
return (
|
|
34
64
|
<div className="flex items-center gap-1.5 text-xs text-red-600 dark:text-red-400">
|
|
35
|
-
<div className="
|
|
65
|
+
<div className="size-2 rounded-full bg-red-500"></div>
|
|
36
66
|
<span>Disconnected</span>
|
|
37
67
|
</div>
|
|
38
68
|
);
|
|
@@ -41,37 +71,4 @@ export function StatusIndicator({ status }: { status: ConnectionStatus }) {
|
|
|
41
71
|
return null;
|
|
42
72
|
}
|
|
43
73
|
|
|
44
|
-
/**
|
|
45
|
-
* Header component - navigation bar with logo, title, and settings
|
|
46
|
-
* Must be used within WorkbenchProvider
|
|
47
|
-
*/
|
|
48
|
-
export function Header({ className }: HeaderProps) {
|
|
49
|
-
const { connectionStatus } = useWorkbench();
|
|
50
|
-
const LogoComponent = Logo;
|
|
51
|
-
const title = 'Workbench';
|
|
52
|
-
const showSettings = true;
|
|
53
|
-
|
|
54
|
-
return (
|
|
55
|
-
<nav
|
|
56
|
-
className={`flex items-center justify-between gap-6 py-2 px-4 border-b ${className || ''}`}
|
|
57
|
-
>
|
|
58
|
-
<div className="flex items-center gap-2.5">
|
|
59
|
-
<LogoComponent />
|
|
60
|
-
<h1 className="mt-0.5 text-sm">{title}</h1>
|
|
61
|
-
</div>
|
|
62
|
-
<div className="flex items-center gap-3">
|
|
63
|
-
<StatusIndicator status={connectionStatus} />
|
|
64
|
-
<div className="flex items-center gap-1">
|
|
65
|
-
<ThemeToggle />
|
|
66
|
-
{showSettings && (
|
|
67
|
-
<Button size="icon" variant="ghost">
|
|
68
|
-
<Settings />
|
|
69
|
-
</Button>
|
|
70
|
-
)}
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
73
|
-
</nav>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
74
|
export default Header;
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { JSONSchema7 } from 'ai';
|
|
2
2
|
import {
|
|
3
|
+
ArrowUp,
|
|
4
|
+
Braces,
|
|
3
5
|
CheckIcon,
|
|
6
|
+
ChevronDownIcon,
|
|
4
7
|
ChevronsUpDownIcon,
|
|
5
|
-
|
|
6
|
-
SendIcon,
|
|
8
|
+
ListPlus,
|
|
7
9
|
Loader2Icon,
|
|
10
|
+
SendIcon,
|
|
8
11
|
Sparkles,
|
|
12
|
+
SquareCode,
|
|
9
13
|
Trash2,
|
|
10
14
|
} from 'lucide-react';
|
|
11
|
-
import {
|
|
15
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
16
|
+
import { convertJsonSchemaToZod } from 'zod-from-json-schema';
|
|
17
|
+
import type { AgentSchemaData } from '../../hooks/useAgentSchemas';
|
|
18
|
+
import { useLogger } from '../../hooks/useLogger';
|
|
19
|
+
import { cn, generateTemplateFromSchema } from '../../lib/utils';
|
|
12
20
|
import {
|
|
13
21
|
PromptInput,
|
|
14
22
|
PromptInputBody,
|
|
@@ -25,31 +33,27 @@ import {
|
|
|
25
33
|
CommandList,
|
|
26
34
|
} from '../ui/command';
|
|
27
35
|
import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
|
|
28
|
-
import { Select, SelectContent, SelectItem, SelectTrigger } from '../ui/select';
|
|
29
36
|
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
|
|
30
|
-
import {
|
|
31
|
-
import
|
|
32
|
-
import { useLogger } from '../../hooks/useLogger';
|
|
33
|
-
import type { JSONSchema7 } from 'ai';
|
|
34
|
-
import { useWorkbench } from './WorkbenchProvider';
|
|
35
|
-
import { convertJsonSchemaToZod } from 'zod-from-json-schema';
|
|
37
|
+
import { JsonEditor } from './json-editor';
|
|
38
|
+
import { useWorkbench } from './workbench-provider';
|
|
36
39
|
|
|
37
40
|
export interface InputSectionProps {
|
|
38
|
-
|
|
41
|
+
agents: Record<string, AgentSchemaData>;
|
|
42
|
+
className?: string;
|
|
43
|
+
clearAgentState?: (agentId: string) => Promise<void>;
|
|
44
|
+
isLoading: boolean;
|
|
45
|
+
isSchemaOpen?: boolean;
|
|
39
46
|
onChange: (value: string) => void;
|
|
47
|
+
onSchemaToggle?: () => void;
|
|
40
48
|
onSubmit: () => void | Promise<void>;
|
|
41
|
-
isLoading: boolean;
|
|
42
|
-
agents: Record<string, AgentSchemaData>;
|
|
43
49
|
selectedAgent: string;
|
|
44
50
|
setSelectedAgent: (agentId: string) => void;
|
|
45
|
-
|
|
46
|
-
isSchemaOpen: boolean;
|
|
47
|
-
onSchemaToggle: () => void;
|
|
48
|
-
clearAgentState?: (agentId: string) => Promise<void>;
|
|
51
|
+
value: string;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
function isSchemaRootObject(schemaJson?: JSONSchema7): boolean {
|
|
52
55
|
if (!schemaJson) return false;
|
|
56
|
+
|
|
53
57
|
try {
|
|
54
58
|
return (
|
|
55
59
|
schemaJson.type === 'object' ||
|
|
@@ -61,21 +65,23 @@ function isSchemaRootObject(schemaJson?: JSONSchema7): boolean {
|
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
export function InputSection({
|
|
64
|
-
|
|
68
|
+
agents,
|
|
69
|
+
className,
|
|
70
|
+
clearAgentState,
|
|
71
|
+
isLoading,
|
|
72
|
+
isSchemaOpen,
|
|
65
73
|
onChange,
|
|
74
|
+
onSchemaToggle,
|
|
66
75
|
onSubmit,
|
|
67
|
-
isLoading,
|
|
68
|
-
agents,
|
|
69
76
|
selectedAgent,
|
|
70
77
|
setSelectedAgent,
|
|
71
|
-
|
|
72
|
-
isSchemaOpen,
|
|
73
|
-
onSchemaToggle,
|
|
74
|
-
clearAgentState,
|
|
78
|
+
value,
|
|
75
79
|
}: InputSectionProps) {
|
|
76
80
|
const logger = useLogger('InputSection');
|
|
77
|
-
const { generateSample, isGeneratingSample,
|
|
81
|
+
const { generateSample, isGeneratingSample, env } = useWorkbench();
|
|
82
|
+
const isAuthenticated = env.authenticated;
|
|
78
83
|
const [agentSelectOpen, setAgentSelectOpen] = useState(false);
|
|
84
|
+
const [prefillOpen, setPrefillOpen] = useState(false);
|
|
79
85
|
const [isValidInput, setIsValidInput] = useState(true);
|
|
80
86
|
const [monacoHasErrors, setMonacoHasErrors] = useState<boolean | null>(null);
|
|
81
87
|
|
|
@@ -86,6 +92,7 @@ export function InputSection({
|
|
|
86
92
|
// Determine input type for switch case
|
|
87
93
|
const inputType = useMemo(() => {
|
|
88
94
|
const schema = selectedAgentData?.schema?.input?.json;
|
|
95
|
+
|
|
89
96
|
logger.debug(
|
|
90
97
|
'🎛️ InputSection - selectedAgent:',
|
|
91
98
|
selectedAgent,
|
|
@@ -94,17 +101,21 @@ export function InputSection({
|
|
|
94
101
|
'schema:',
|
|
95
102
|
schema
|
|
96
103
|
);
|
|
104
|
+
|
|
97
105
|
if (!schema) {
|
|
98
106
|
return 'none'; // Agent has no input schema
|
|
99
107
|
}
|
|
108
|
+
|
|
100
109
|
if (isSchemaRootObject(schema)) {
|
|
101
110
|
return 'object'; // Complex object schema
|
|
102
111
|
}
|
|
112
|
+
|
|
103
113
|
if (schema.type === 'string') {
|
|
104
114
|
return 'string'; // String schema
|
|
105
115
|
}
|
|
116
|
+
|
|
106
117
|
return 'none'; // Default to none for other types
|
|
107
|
-
}, [selectedAgentData
|
|
118
|
+
}, [selectedAgentData, logger, selectedAgent]);
|
|
108
119
|
|
|
109
120
|
const isObjectSchema = inputType === 'object';
|
|
110
121
|
|
|
@@ -125,6 +136,7 @@ export function InputSection({
|
|
|
125
136
|
|
|
126
137
|
// Validate with zod
|
|
127
138
|
const result = zodSchema.safeParse(parsedJson);
|
|
139
|
+
|
|
128
140
|
return result.success;
|
|
129
141
|
} catch {
|
|
130
142
|
// JSON parse error or schema validation error
|
|
@@ -135,11 +147,12 @@ export function InputSection({
|
|
|
135
147
|
);
|
|
136
148
|
|
|
137
149
|
// Reset Monaco error state when schema changes
|
|
150
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: Trigger on schema change
|
|
138
151
|
useEffect(() => {
|
|
139
152
|
if (isObjectSchema) {
|
|
140
153
|
setMonacoHasErrors(null);
|
|
141
154
|
}
|
|
142
|
-
}, [selectedAgentData
|
|
155
|
+
}, [selectedAgentData, isObjectSchema]);
|
|
143
156
|
|
|
144
157
|
// Update validation state - use Monaco errors if available, otherwise fall back to zod validation
|
|
145
158
|
useEffect(() => {
|
|
@@ -150,6 +163,7 @@ export function InputSection({
|
|
|
150
163
|
} else {
|
|
151
164
|
// Monaco hasn't reported yet, use zod validation as fallback
|
|
152
165
|
const isValid = validateInput(value, selectedAgentData?.schema?.input?.json);
|
|
166
|
+
|
|
153
167
|
setIsValidInput(isValid);
|
|
154
168
|
}
|
|
155
169
|
} else {
|
|
@@ -169,31 +183,40 @@ export function InputSection({
|
|
|
169
183
|
|
|
170
184
|
try {
|
|
171
185
|
const sampleJson = await generateSample(selectedAgent);
|
|
186
|
+
|
|
172
187
|
onChange(sampleJson);
|
|
173
188
|
} catch (error) {
|
|
174
189
|
logger.error('Failed to generate sample JSON:', error);
|
|
175
|
-
console.error('Failed to generate sample JSON:', error);
|
|
176
190
|
}
|
|
177
191
|
};
|
|
178
192
|
|
|
179
193
|
// Memoized submit disabled condition for readability
|
|
180
194
|
const isSubmitDisabled = useMemo(() => {
|
|
181
|
-
if (isLoading)
|
|
182
|
-
|
|
183
|
-
|
|
195
|
+
if (isLoading) {
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (inputType === 'string' && !value.trim()) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (inputType === 'object' && (!isValidInput || !value.trim())) {
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
|
|
184
207
|
return false;
|
|
185
208
|
}, [isLoading, inputType, value, isValidInput]);
|
|
186
209
|
|
|
187
210
|
return (
|
|
188
|
-
|
|
189
|
-
<div className="flex items-center gap-2
|
|
211
|
+
<div className={cn('flex flex-col gap-4 p-4 z-100', className)}>
|
|
212
|
+
<div className="flex items-center gap-2">
|
|
190
213
|
<Popover open={agentSelectOpen} onOpenChange={setAgentSelectOpen}>
|
|
191
214
|
<PopoverTrigger asChild>
|
|
192
215
|
<Button
|
|
193
216
|
aria-expanded={agentSelectOpen}
|
|
194
|
-
className="font-normal bg-transparent dark:bg-transparent"
|
|
195
217
|
variant="outline"
|
|
196
218
|
size="sm"
|
|
219
|
+
className="font-normal bg-background dark:bg-background hover:bg-background dark:hover:bg-background dark:hover:border-border/70"
|
|
197
220
|
>
|
|
198
221
|
{Object.values(agents).find(
|
|
199
222
|
(agent) => agent.metadata.agentId === selectedAgent
|
|
@@ -201,7 +224,7 @@ export function InputSection({
|
|
|
201
224
|
<ChevronsUpDownIcon className="size-4 shrink-0 opacity-50" />
|
|
202
225
|
</Button>
|
|
203
226
|
</PopoverTrigger>
|
|
204
|
-
<PopoverContent className="w-fit p-0">
|
|
227
|
+
<PopoverContent side="top" align="start" className="w-fit p-0 z-101">
|
|
205
228
|
<Command>
|
|
206
229
|
<CommandInput placeholder="Search agents..." />
|
|
207
230
|
<CommandList>
|
|
@@ -211,8 +234,10 @@ export function InputSection({
|
|
|
211
234
|
.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name))
|
|
212
235
|
.map((agent) => {
|
|
213
236
|
const isSelected = selectedAgent === agent.metadata.agentId;
|
|
237
|
+
|
|
214
238
|
// Use name for search but include agentId to ensure uniqueness
|
|
215
239
|
const searchValue = `${agent.metadata.name}|${agent.metadata.agentId}`;
|
|
240
|
+
|
|
216
241
|
return (
|
|
217
242
|
<CommandItem
|
|
218
243
|
key={agent.metadata.agentId}
|
|
@@ -223,6 +248,7 @@ export function InputSection({
|
|
|
223
248
|
const selectedAgentData = Object.values(agents).find(
|
|
224
249
|
(a) => a.metadata.agentId === agentId
|
|
225
250
|
);
|
|
251
|
+
|
|
226
252
|
if (selectedAgentData) {
|
|
227
253
|
logger.debug(
|
|
228
254
|
'🎯 Agent selected by name:',
|
|
@@ -230,8 +256,10 @@ export function InputSection({
|
|
|
230
256
|
'agentId:',
|
|
231
257
|
agentId
|
|
232
258
|
);
|
|
259
|
+
|
|
233
260
|
setSelectedAgent(agentId);
|
|
234
261
|
}
|
|
262
|
+
|
|
235
263
|
setAgentSelectOpen(false);
|
|
236
264
|
}}
|
|
237
265
|
>
|
|
@@ -251,96 +279,118 @@ export function InputSection({
|
|
|
251
279
|
</PopoverContent>
|
|
252
280
|
</Popover>
|
|
253
281
|
|
|
254
|
-
{
|
|
255
|
-
<
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
</SelectContent>
|
|
269
|
-
</Select>
|
|
282
|
+
{onSchemaToggle && (
|
|
283
|
+
<Button
|
|
284
|
+
aria-label={isSchemaOpen ? 'Hide Schema' : 'View Schema'}
|
|
285
|
+
size="sm"
|
|
286
|
+
variant="outline"
|
|
287
|
+
className={cn(
|
|
288
|
+
'font-normal bg-background dark:bg-background hover:bg-background dark:hover:bg-background dark:hover:border-border/50',
|
|
289
|
+
isSchemaOpen && 'bg-secondary!'
|
|
290
|
+
)}
|
|
291
|
+
onClick={onSchemaToggle}
|
|
292
|
+
>
|
|
293
|
+
<Braces className="size-4" />
|
|
294
|
+
Schema
|
|
295
|
+
</Button>
|
|
270
296
|
)}
|
|
271
297
|
|
|
272
|
-
{isObjectSchema &&
|
|
273
|
-
|
|
274
|
-
<
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
<
|
|
298
|
+
{isObjectSchema && (
|
|
299
|
+
<Popover open={prefillOpen} onOpenChange={setPrefillOpen}>
|
|
300
|
+
<PopoverTrigger asChild>
|
|
301
|
+
<Button
|
|
302
|
+
aria-expanded={prefillOpen}
|
|
303
|
+
aria-label="Pre-fill input"
|
|
304
|
+
size="sm"
|
|
305
|
+
variant="outline"
|
|
306
|
+
className="font-normal bg-background dark:bg-background hover:bg-background dark:hover:bg-background dark:hover:border-border/70"
|
|
307
|
+
>
|
|
308
|
+
<ListPlus className="size-4" />
|
|
309
|
+
Pre-fill
|
|
310
|
+
<ChevronDownIcon className="size-4 shrink-0 opacity-50" />
|
|
311
|
+
</Button>
|
|
312
|
+
</PopoverTrigger>
|
|
313
|
+
<PopoverContent side="top" align="start" className="w-fit max-w-xl p-0 z-101">
|
|
314
|
+
<Command>
|
|
315
|
+
<CommandList>
|
|
316
|
+
<CommandGroup>
|
|
317
|
+
<CommandItem
|
|
318
|
+
onSelect={() => {
|
|
319
|
+
const template = generateTemplateFromSchema(
|
|
320
|
+
selectedAgentData?.schema?.input?.json
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
onChange(template);
|
|
324
|
+
setPrefillOpen(false);
|
|
325
|
+
}}
|
|
326
|
+
>
|
|
327
|
+
<SquareCode className="size-4" />
|
|
328
|
+
<span>Template</span>
|
|
329
|
+
<span className="ml-auto text-xs text-muted-foreground">
|
|
330
|
+
Empty schema structure
|
|
331
|
+
</span>
|
|
332
|
+
</CommandItem>
|
|
333
|
+
|
|
334
|
+
{isAuthenticated ? (
|
|
335
|
+
<CommandItem
|
|
336
|
+
disabled={isGeneratingSample}
|
|
337
|
+
onSelect={() => {
|
|
338
|
+
handleGenerateSample();
|
|
339
|
+
setPrefillOpen(false);
|
|
340
|
+
}}
|
|
341
|
+
>
|
|
342
|
+
{isGeneratingSample ? (
|
|
343
|
+
<Loader2Icon className="size-4 animate-spin" />
|
|
344
|
+
) : (
|
|
345
|
+
<Sparkles className="size-4" />
|
|
346
|
+
)}
|
|
347
|
+
<span>Mock Input</span>
|
|
348
|
+
<span className="ml-auto text-xs text-muted-foreground">
|
|
349
|
+
AI-generated data
|
|
350
|
+
</span>
|
|
351
|
+
</CommandItem>
|
|
303
352
|
) : (
|
|
304
|
-
<
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
353
|
+
<Tooltip>
|
|
354
|
+
<TooltipTrigger asChild>
|
|
355
|
+
<CommandItem disabled className="opacity-50">
|
|
356
|
+
<Sparkles className="size-4" />
|
|
357
|
+
<span>Mock Input</span>
|
|
358
|
+
<span className="ml-auto text-xs text-muted-foreground">
|
|
359
|
+
Login required
|
|
360
|
+
</span>
|
|
361
|
+
</CommandItem>
|
|
362
|
+
</TooltipTrigger>
|
|
363
|
+
<TooltipContent>
|
|
364
|
+
Login to generate a mock input using AI
|
|
365
|
+
</TooltipContent>
|
|
366
|
+
</Tooltip>
|
|
367
|
+
)}
|
|
368
|
+
</CommandGroup>
|
|
369
|
+
</CommandList>
|
|
370
|
+
</Command>
|
|
371
|
+
</PopoverContent>
|
|
372
|
+
</Popover>
|
|
373
|
+
)}
|
|
325
374
|
|
|
326
375
|
{clearAgentState && selectedAgent && (
|
|
327
376
|
<Button
|
|
328
377
|
aria-label="Clear conversation history"
|
|
329
378
|
size="sm"
|
|
330
379
|
variant="outline"
|
|
331
|
-
className="
|
|
380
|
+
className="ml-auto font-normal bg-background dark:bg-background hover:bg-background dark:hover:bg-background dark:hover:border-border/50 text-foreground hover:text-destructive"
|
|
332
381
|
onClick={() => clearAgentState(selectedAgent)}
|
|
333
382
|
>
|
|
334
|
-
<Trash2 className="size-4" />
|
|
383
|
+
<Trash2 className="size-4" />
|
|
384
|
+
Clear Thread
|
|
335
385
|
</Button>
|
|
336
386
|
)}
|
|
337
387
|
</div>
|
|
338
388
|
|
|
339
|
-
<PromptInput onSubmit={onSubmit}
|
|
389
|
+
<PromptInput onSubmit={onSubmit}>
|
|
340
390
|
<PromptInputBody>
|
|
341
391
|
{!selectedAgent ? (
|
|
342
|
-
<div className="flex flex-col items-center justify-center py-
|
|
343
|
-
<p className="text-sm text-muted-foreground">
|
|
392
|
+
<div className="flex flex-col items-center justify-center py-6 px-4 text-center">
|
|
393
|
+
<p className="text-sm text-muted-foreground/70">
|
|
344
394
|
Select an agent to get started.
|
|
345
395
|
</p>
|
|
346
396
|
</div>
|
|
@@ -349,22 +399,23 @@ export function InputSection({
|
|
|
349
399
|
switch (inputType) {
|
|
350
400
|
case 'object':
|
|
351
401
|
return (
|
|
352
|
-
<
|
|
353
|
-
|
|
402
|
+
<JsonEditor
|
|
403
|
+
aria-invalid={!isValidInput}
|
|
354
404
|
onChange={onChange}
|
|
405
|
+
onSubmit={onSubmit}
|
|
406
|
+
onValidationChange={setMonacoHasErrors}
|
|
355
407
|
schema={selectedAgentData?.schema.input?.json}
|
|
356
408
|
schemaUri={`agentuity://schema/${selectedAgentData?.metadata.id}/input`}
|
|
357
|
-
|
|
358
|
-
onValidationChange={setMonacoHasErrors}
|
|
409
|
+
value={value}
|
|
359
410
|
/>
|
|
360
411
|
);
|
|
361
412
|
|
|
362
413
|
case 'string':
|
|
363
414
|
return (
|
|
364
415
|
<PromptInputTextarea
|
|
416
|
+
onChange={(e) => onChange(e.target.value)}
|
|
365
417
|
placeholder="Enter a message to send..."
|
|
366
418
|
value={value}
|
|
367
|
-
onChange={(e) => onChange(e.target.value)}
|
|
368
419
|
/>
|
|
369
420
|
);
|
|
370
421
|
default:
|
|
@@ -372,9 +423,10 @@ export function InputSection({
|
|
|
372
423
|
<div className="flex flex-col items-center justify-center py-8 px-4 text-center ">
|
|
373
424
|
<p className="text-sm text-muted-foreground">
|
|
374
425
|
<span className="font-medium">
|
|
375
|
-
This agent has no input schema.
|
|
426
|
+
This agent has no input schema.
|
|
376
427
|
</span>
|
|
377
428
|
</p>
|
|
429
|
+
|
|
378
430
|
<Button
|
|
379
431
|
aria-label="Run Agent"
|
|
380
432
|
size="sm"
|
|
@@ -396,7 +448,8 @@ export function InputSection({
|
|
|
396
448
|
})()
|
|
397
449
|
)}
|
|
398
450
|
</PromptInputBody>
|
|
399
|
-
|
|
451
|
+
|
|
452
|
+
<PromptInputFooter className={cn('pt-0', !selectedAgent && 'pb-0')}>
|
|
400
453
|
{selectedAgent && inputType !== 'none' && (
|
|
401
454
|
<Button
|
|
402
455
|
aria-label="Submit"
|
|
@@ -410,19 +463,20 @@ export function InputSection({
|
|
|
410
463
|
'value:',
|
|
411
464
|
value
|
|
412
465
|
);
|
|
466
|
+
|
|
413
467
|
onSubmit();
|
|
414
468
|
}}
|
|
415
|
-
className=
|
|
469
|
+
className={cn('ml-auto', isSubmitDisabled && 'opacity-10!')}
|
|
416
470
|
>
|
|
417
471
|
{isLoading ? (
|
|
418
472
|
<Loader2Icon className="size-4 animate-spin" />
|
|
419
473
|
) : (
|
|
420
|
-
<
|
|
474
|
+
<ArrowUp className="size-4" />
|
|
421
475
|
)}
|
|
422
476
|
</Button>
|
|
423
477
|
)}
|
|
424
478
|
</PromptInputFooter>
|
|
425
479
|
</PromptInput>
|
|
426
|
-
|
|
480
|
+
</div>
|
|
427
481
|
);
|
|
428
482
|
}
|