@agentuity/workbench 0.0.104 → 0.0.106
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/{InputSection.js → input-section.js} +36 -25
- 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} +1 -1
- 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} +58 -39
- 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 +5 -5
- 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 +355 -298
- 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 +324 -0
- package/src/components/internal/{Header.tsx → header.tsx} +37 -40
- package/src/components/internal/{InputSection.tsx → input-section.tsx} +169 -115
- 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 → schema.tsx} +28 -34
- package/src/components/internal/{WorkbenchProvider.tsx → workbench-provider.tsx} +156 -48
- 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 +22 -13
- 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.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/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,42 @@ 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);
|
|
190
|
+
|
|
175
191
|
console.error('Failed to generate sample JSON:', error);
|
|
176
192
|
}
|
|
177
193
|
};
|
|
178
194
|
|
|
179
195
|
// Memoized submit disabled condition for readability
|
|
180
196
|
const isSubmitDisabled = useMemo(() => {
|
|
181
|
-
if (isLoading)
|
|
182
|
-
|
|
183
|
-
|
|
197
|
+
if (isLoading) {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (inputType === 'string' && !value.trim()) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (inputType === 'object' && (!isValidInput || !value.trim())) {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
|
|
184
209
|
return false;
|
|
185
210
|
}, [isLoading, inputType, value, isValidInput]);
|
|
186
211
|
|
|
187
212
|
return (
|
|
188
|
-
|
|
189
|
-
<div className="flex items-center gap-2
|
|
213
|
+
<div className={cn('flex flex-col gap-4 p-4 z-100', className)}>
|
|
214
|
+
<div className="flex items-center gap-2">
|
|
190
215
|
<Popover open={agentSelectOpen} onOpenChange={setAgentSelectOpen}>
|
|
191
216
|
<PopoverTrigger asChild>
|
|
192
217
|
<Button
|
|
193
218
|
aria-expanded={agentSelectOpen}
|
|
194
|
-
className="font-normal bg-transparent dark:bg-transparent"
|
|
195
219
|
variant="outline"
|
|
196
220
|
size="sm"
|
|
221
|
+
className="font-normal bg-background dark:bg-background hover:bg-background dark:hover:bg-background dark:hover:border-border/70"
|
|
197
222
|
>
|
|
198
223
|
{Object.values(agents).find(
|
|
199
224
|
(agent) => agent.metadata.agentId === selectedAgent
|
|
@@ -201,7 +226,7 @@ export function InputSection({
|
|
|
201
226
|
<ChevronsUpDownIcon className="size-4 shrink-0 opacity-50" />
|
|
202
227
|
</Button>
|
|
203
228
|
</PopoverTrigger>
|
|
204
|
-
<PopoverContent className="w-fit p-0">
|
|
229
|
+
<PopoverContent side="top" align="start" className="w-fit p-0 z-101">
|
|
205
230
|
<Command>
|
|
206
231
|
<CommandInput placeholder="Search agents..." />
|
|
207
232
|
<CommandList>
|
|
@@ -211,8 +236,10 @@ export function InputSection({
|
|
|
211
236
|
.sort((a, b) => a.metadata.name.localeCompare(b.metadata.name))
|
|
212
237
|
.map((agent) => {
|
|
213
238
|
const isSelected = selectedAgent === agent.metadata.agentId;
|
|
239
|
+
|
|
214
240
|
// Use name for search but include agentId to ensure uniqueness
|
|
215
241
|
const searchValue = `${agent.metadata.name}|${agent.metadata.agentId}`;
|
|
242
|
+
|
|
216
243
|
return (
|
|
217
244
|
<CommandItem
|
|
218
245
|
key={agent.metadata.agentId}
|
|
@@ -223,6 +250,7 @@ export function InputSection({
|
|
|
223
250
|
const selectedAgentData = Object.values(agents).find(
|
|
224
251
|
(a) => a.metadata.agentId === agentId
|
|
225
252
|
);
|
|
253
|
+
|
|
226
254
|
if (selectedAgentData) {
|
|
227
255
|
logger.debug(
|
|
228
256
|
'🎯 Agent selected by name:',
|
|
@@ -230,8 +258,10 @@ export function InputSection({
|
|
|
230
258
|
'agentId:',
|
|
231
259
|
agentId
|
|
232
260
|
);
|
|
261
|
+
|
|
233
262
|
setSelectedAgent(agentId);
|
|
234
263
|
}
|
|
264
|
+
|
|
235
265
|
setAgentSelectOpen(false);
|
|
236
266
|
}}
|
|
237
267
|
>
|
|
@@ -251,96 +281,116 @@ export function InputSection({
|
|
|
251
281
|
</PopoverContent>
|
|
252
282
|
</Popover>
|
|
253
283
|
|
|
254
|
-
{suggestions.length > 0 && (
|
|
255
|
-
<Select onValueChange={(value) => onChange(value)}>
|
|
256
|
-
<SelectTrigger
|
|
257
|
-
size="sm"
|
|
258
|
-
className="ml-auto bg-transparent dark:bg-transparent text-foreground!"
|
|
259
|
-
>
|
|
260
|
-
Suggestions
|
|
261
|
-
</SelectTrigger>
|
|
262
|
-
<SelectContent className="text-sm" side="top" align="end">
|
|
263
|
-
{suggestions.map((suggestion) => (
|
|
264
|
-
<SelectItem key={suggestion} value={suggestion}>
|
|
265
|
-
{suggestion}
|
|
266
|
-
</SelectItem>
|
|
267
|
-
))}
|
|
268
|
-
</SelectContent>
|
|
269
|
-
</Select>
|
|
270
|
-
)}
|
|
271
|
-
|
|
272
|
-
{isObjectSchema &&
|
|
273
|
-
(isAuthenticated ? (
|
|
274
|
-
<Button
|
|
275
|
-
aria-label="Generate Sample JSON"
|
|
276
|
-
size="sm"
|
|
277
|
-
variant="outline"
|
|
278
|
-
className="bg-none font-normal"
|
|
279
|
-
onClick={handleGenerateSample}
|
|
280
|
-
disabled={isGeneratingSample || !isAuthenticated}
|
|
281
|
-
>
|
|
282
|
-
{isGeneratingSample ? (
|
|
283
|
-
<Loader2Icon className="size-4 animate-spin" />
|
|
284
|
-
) : (
|
|
285
|
-
<Sparkles className="size-4" />
|
|
286
|
-
)}{' '}
|
|
287
|
-
Sample
|
|
288
|
-
</Button>
|
|
289
|
-
) : (
|
|
290
|
-
<Tooltip>
|
|
291
|
-
<TooltipTrigger asChild>
|
|
292
|
-
<span className="inline-flex">
|
|
293
|
-
<Button
|
|
294
|
-
aria-label="Generate Sample JSON"
|
|
295
|
-
size="sm"
|
|
296
|
-
variant="outline"
|
|
297
|
-
className="bg-none font-normal"
|
|
298
|
-
onClick={handleGenerateSample}
|
|
299
|
-
disabled={isGeneratingSample || !isAuthenticated}
|
|
300
|
-
>
|
|
301
|
-
{isGeneratingSample ? (
|
|
302
|
-
<Loader2Icon className="size-4 animate-spin" />
|
|
303
|
-
) : (
|
|
304
|
-
<Sparkles className="size-4" />
|
|
305
|
-
)}{' '}
|
|
306
|
-
Sample
|
|
307
|
-
</Button>
|
|
308
|
-
</span>
|
|
309
|
-
</TooltipTrigger>
|
|
310
|
-
<TooltipContent>
|
|
311
|
-
<p>Login to generate a sample</p>
|
|
312
|
-
</TooltipContent>
|
|
313
|
-
</Tooltip>
|
|
314
|
-
))}
|
|
315
|
-
|
|
316
284
|
<Button
|
|
317
285
|
aria-label={isSchemaOpen ? 'Hide Schema' : 'View Schema'}
|
|
318
286
|
size="sm"
|
|
319
|
-
variant=
|
|
320
|
-
className={cn(
|
|
287
|
+
variant="outline"
|
|
288
|
+
className={cn(
|
|
289
|
+
'font-normal bg-background dark:bg-background hover:bg-background dark:hover:bg-background dark:hover:border-border/50',
|
|
290
|
+
isSchemaOpen && 'bg-secondary!'
|
|
291
|
+
)}
|
|
321
292
|
onClick={onSchemaToggle}
|
|
322
293
|
>
|
|
323
|
-
<
|
|
294
|
+
<Braces className="size-4" />
|
|
295
|
+
Schema
|
|
324
296
|
</Button>
|
|
325
297
|
|
|
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>
|
|
352
|
+
) : (
|
|
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
|
+
)}
|
|
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="pt-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
|
}
|