@agentuity/workbench 0.0.79 → 0.0.84

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.
Files changed (53) hide show
  1. package/dist/components/internal/Chat.d.ts.map +1 -1
  2. package/dist/components/internal/Chat.js +6 -1
  3. package/dist/components/internal/Chat.js.map +1 -1
  4. package/dist/components/internal/InputSection.d.ts.map +1 -1
  5. package/dist/components/internal/InputSection.js +29 -151
  6. package/dist/components/internal/InputSection.js.map +1 -1
  7. package/dist/components/internal/MonacoJsonEditor.d.ts +11 -0
  8. package/dist/components/internal/MonacoJsonEditor.d.ts.map +1 -0
  9. package/dist/components/internal/MonacoJsonEditor.js +270 -0
  10. package/dist/components/internal/MonacoJsonEditor.js.map +1 -0
  11. package/dist/components/internal/Schema.d.ts.map +1 -1
  12. package/dist/components/internal/Schema.js +1 -1
  13. package/dist/components/internal/Schema.js.map +1 -1
  14. package/dist/components/internal/WorkbenchProvider.d.ts.map +1 -1
  15. package/dist/components/internal/WorkbenchProvider.js +30 -9
  16. package/dist/components/internal/WorkbenchProvider.js.map +1 -1
  17. package/dist/components/ui/field.d.ts +1 -1
  18. package/dist/components.d.ts +1 -0
  19. package/dist/components.d.ts.map +1 -1
  20. package/dist/components.js +1 -0
  21. package/dist/components.js.map +1 -1
  22. package/dist/hooks/index.d.ts +1 -0
  23. package/dist/hooks/index.d.ts.map +1 -1
  24. package/dist/hooks/index.js +1 -0
  25. package/dist/hooks/index.js.map +1 -1
  26. package/dist/hooks/useAgentSchemas.d.ts +1 -0
  27. package/dist/hooks/useAgentSchemas.d.ts.map +1 -1
  28. package/dist/hooks/useAgentSchemas.js.map +1 -1
  29. package/dist/hooks/useLogger.d.ts +9 -0
  30. package/dist/hooks/useLogger.d.ts.map +1 -0
  31. package/dist/hooks/useLogger.js +41 -0
  32. package/dist/hooks/useLogger.js.map +1 -0
  33. package/dist/index.d.ts +1 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +1 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/lib/utils.d.ts +3 -0
  38. package/dist/lib/utils.d.ts.map +1 -1
  39. package/dist/lib/utils.js +31 -0
  40. package/dist/lib/utils.js.map +1 -1
  41. package/dist/styles.css +60 -0
  42. package/package.json +10 -5
  43. package/src/components/internal/Chat.tsx +8 -1
  44. package/src/components/internal/InputSection.tsx +71 -193
  45. package/src/components/internal/MonacoJsonEditor.tsx +359 -0
  46. package/src/components/internal/Schema.tsx +2 -1
  47. package/src/components/internal/WorkbenchProvider.tsx +35 -9
  48. package/src/components.tsx +1 -0
  49. package/src/hooks/index.ts +1 -0
  50. package/src/hooks/useAgentSchemas.ts +1 -0
  51. package/src/hooks/useLogger.ts +57 -0
  52. package/src/index.ts +1 -0
  53. package/src/lib/utils.ts +41 -0
@@ -12,6 +12,7 @@ import { InputSection } from './InputSection';
12
12
  import { Shimmer } from '../ai-elements/shimmer';
13
13
  import { cn } from '../../lib/utils';
14
14
  import { useWorkbench } from './WorkbenchProvider';
15
+ import { useLogger } from '../../hooks/useLogger';
15
16
  import { Schema } from './Schema';
16
17
 
17
18
  export interface ChatProps {
@@ -23,6 +24,7 @@ export interface ChatProps {
23
24
  * Must be used within WorkbenchProvider
24
25
  */
25
26
  export function Chat({ className: _className }: ChatProps) {
27
+ const logger = useLogger('Chat');
26
28
  const {
27
29
  agents,
28
30
  suggestions,
@@ -37,8 +39,13 @@ export function Chat({ className: _className }: ChatProps) {
37
39
  const [schemaOpen, setSchemaOpen] = useState(false);
38
40
 
39
41
  const handleSubmit = async () => {
40
- const selectedAgentData = agents[selectedAgent];
42
+ logger.debug('🎯 Chat handleSubmit - selectedAgent:', selectedAgent, 'value:', value);
43
+ const selectedAgentData = Object.values(agents).find(
44
+ (agent) => agent.metadata.agentId === selectedAgent
45
+ );
46
+ logger.debug('📊 Chat handleSubmit - selectedAgentData:', selectedAgentData);
41
47
  const hasInputSchema = selectedAgentData?.schema?.input?.json;
48
+ logger.debug('📝 Chat handleSubmit - hasInputSchema:', hasInputSchema);
42
49
 
43
50
  // If agent has no input schema, submit without requiring input
44
51
  if (!hasInputSchema) {
@@ -1,4 +1,4 @@
1
- import React, { useEffect, useMemo, useRef, useState } from 'react';
1
+ import React, { useMemo, useState } from 'react';
2
2
  import {
3
3
  CheckIcon,
4
4
  ChevronsUpDownIcon,
@@ -7,8 +7,7 @@ import {
7
7
  Loader2Icon,
8
8
  Sparkles,
9
9
  } from 'lucide-react';
10
- import { init } from 'modern-monaco';
11
- import type * as Monaco from 'modern-monaco/editor-core';
10
+ import { MonacoJsonEditor } from './MonacoJsonEditor';
12
11
  import {
13
12
  PromptInput,
14
13
  PromptInputBody,
@@ -28,6 +27,7 @@ import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover';
28
27
  import { Select, SelectContent, SelectItem, SelectTrigger } from '../ui/select';
29
28
  import { cn } from '../../lib/utils';
30
29
  import type { AgentSchemaData } from '../../hooks/useAgentSchemas';
30
+ import { useLogger } from '../../hooks/useLogger';
31
31
  import type { JSONSchema7 } from 'ai';
32
32
  import { convertJsonSchemaToZod } from 'zod-from-json-schema';
33
33
  import { zocker } from 'zocker';
@@ -67,15 +67,24 @@ export function InputSection({
67
67
  suggestions,
68
68
  onSchemaOpen,
69
69
  }: InputSectionProps) {
70
+ const logger = useLogger('InputSection');
70
71
  const [agentSelectOpen, setAgentSelectOpen] = useState(false);
71
- const monacoEditorRef = useRef<HTMLDivElement>(null);
72
- const editorInstanceRef = useRef<Monaco.editor.IStandaloneCodeEditor | null>(null);
73
72
 
74
- const selectedAgentData = agents[selectedAgent];
73
+ const selectedAgentData = Object.values(agents).find(
74
+ (agent) => agent.metadata.agentId === selectedAgent
75
+ );
75
76
 
76
77
  // Determine input type for switch case
77
78
  const inputType = useMemo(() => {
78
79
  const schema = selectedAgentData?.schema?.input?.json;
80
+ logger.debug(
81
+ '🎛️ InputSection - selectedAgent:',
82
+ selectedAgent,
83
+ 'selectedAgentData:',
84
+ selectedAgentData,
85
+ 'schema:',
86
+ schema
87
+ );
79
88
  if (!schema) {
80
89
  return 'none'; // Agent has no input schema
81
90
  }
@@ -101,171 +110,11 @@ export function InputSection({
101
110
  const sampleData = zocker(zodSchema).generate();
102
111
  const sampleJson = JSON.stringify(sampleData, null, 2);
103
112
  onChange(sampleJson);
104
-
105
- // Update Monaco editor directly if it exists
106
- if (editorInstanceRef.current) {
107
- editorInstanceRef.current.setValue(sampleJson);
108
- editorInstanceRef.current.layout();
109
- }
110
113
  } catch (error) {
111
114
  console.error('Failed to generate sample JSON:', error);
112
115
  }
113
116
  };
114
117
 
115
- useEffect(() => {
116
- if (!isObjectSchema || !monacoEditorRef.current) {
117
- if (editorInstanceRef.current) {
118
- editorInstanceRef.current.dispose();
119
- editorInstanceRef.current = null;
120
- }
121
- return;
122
- }
123
-
124
- let isMounted = true;
125
- let disposed = false;
126
- let resizeObserver: ResizeObserver | null = null;
127
-
128
- init({
129
- theme: 'vitesse-dark',
130
- langs: ['json'],
131
- }).then((monaco) => {
132
- if (!isMounted || !monacoEditorRef.current) return;
133
-
134
- if (editorInstanceRef.current) {
135
- editorInstanceRef.current.dispose();
136
- }
137
-
138
- // Configure JSON schema if available
139
- const jsonSchema = selectedAgentData?.schema.input?.json;
140
- if (jsonSchema) {
141
- // Parse schema if it's a string, otherwise use directly
142
- const schemaObject =
143
- typeof jsonSchema === 'string' ? JSON.parse(jsonSchema) : jsonSchema;
144
-
145
- // Access json namespace directly from monaco
146
- if ('json' in monaco && typeof monaco.json === 'object' && monaco.json !== null) {
147
- const jsonModule = monaco.json;
148
- if (
149
- 'jsonDefaults' in jsonModule &&
150
- typeof jsonModule.jsonDefaults === 'object' &&
151
- jsonModule.jsonDefaults !== null
152
- ) {
153
- const jsonDefaults = jsonModule.jsonDefaults;
154
- if (
155
- 'setDiagnosticsOptions' in jsonDefaults &&
156
- typeof jsonDefaults.setDiagnosticsOptions === 'function'
157
- ) {
158
- jsonDefaults.setDiagnosticsOptions({
159
- validate: true,
160
- schemas: [
161
- {
162
- // URI is just an identifier, doesn't need to be a real URL
163
- uri: `agentuity://schema/${selectedAgentData.metadata.id}/input`,
164
- fileMatch: ['*'],
165
- schema: schemaObject,
166
- },
167
- ],
168
- });
169
- }
170
- }
171
- }
172
- }
173
-
174
- // Set initial height
175
- const container = monacoEditorRef.current;
176
- container.style.height = '64px'; // min-h-16 = 4rem = 64px
177
-
178
- const editor = monaco.editor.create(container, {
179
- value: value || '{}',
180
- language: 'json',
181
- minimap: { enabled: false },
182
- fontSize: 14,
183
- lineNumbers: 'off',
184
- scrollBeyondLastLine: false,
185
- wordWrap: 'on',
186
- automaticLayout: true,
187
- scrollbar: {
188
- vertical: 'auto',
189
- horizontal: 'auto',
190
- },
191
- padding: { top: 12, bottom: 12 },
192
- });
193
-
194
- // Make background transparent
195
- setTimeout(() => {
196
- if (disposed) return;
197
- const editorElement = container.querySelector('.monaco-editor');
198
- if (editorElement) {
199
- (editorElement as HTMLElement).style.backgroundColor = 'transparent';
200
- }
201
-
202
- const backgroundElement = container.querySelector(
203
- '.monaco-editor .monaco-editor-background'
204
- );
205
- if (backgroundElement) {
206
- (backgroundElement as HTMLElement).style.backgroundColor = 'transparent';
207
- }
208
-
209
- const viewLines = container.querySelector('.monaco-editor .view-lines');
210
- if (viewLines) {
211
- (viewLines as HTMLElement).style.backgroundColor = 'transparent';
212
- }
213
- }, 0);
214
-
215
- editor.onDidChangeModelContent(() => {
216
- const newValue = editor.getValue();
217
- onChange(newValue);
218
-
219
- // Auto-resize based on content
220
- if (container) {
221
- const contentHeight = editor.getContentHeight();
222
- const maxHeight = 192; // max-h-48 = 12rem = 192px
223
- const minHeight = 64; // min-h-16 = 4rem = 64px
224
- const newHeight = Math.min(Math.max(contentHeight + 24, minHeight), maxHeight);
225
- container.style.height = `${newHeight}px`;
226
- editor.layout();
227
- }
228
- });
229
-
230
- // Resize observer for container size changes
231
- resizeObserver = new ResizeObserver(() => {
232
- if (!disposed && editor && isMounted) {
233
- editor.layout();
234
- }
235
- });
236
- resizeObserver.observe(container);
237
-
238
- // Force layout update after creation
239
- setTimeout(() => {
240
- if (disposed) return;
241
- editor.layout();
242
- }, 0);
243
-
244
- editorInstanceRef.current = editor;
245
- });
246
-
247
- return () => {
248
- isMounted = false;
249
- disposed = true;
250
- if (resizeObserver) {
251
- resizeObserver.disconnect();
252
- }
253
- if (editorInstanceRef.current) {
254
- editorInstanceRef.current.dispose();
255
- editorInstanceRef.current = null;
256
- }
257
- };
258
- }, [isObjectSchema, onChange, selectedAgentData]);
259
-
260
- useEffect(() => {
261
- if (isObjectSchema && editorInstanceRef.current) {
262
- const currentValue = editorInstanceRef.current.getValue();
263
- if (currentValue !== value) {
264
- editorInstanceRef.current.setValue(value || '{}');
265
- }
266
- }
267
- }, [value, isObjectSchema]);
268
-
269
118
  return (
270
119
  <>
271
120
  <div className="flex items-center gap-2 py-2 px-3">
@@ -277,7 +126,9 @@ export function InputSection({
277
126
  variant="outline"
278
127
  size="sm"
279
128
  >
280
- {agents[selectedAgent]?.metadata.name || 'Select agent'}
129
+ {Object.values(agents).find(
130
+ (agent) => agent.metadata.agentId === selectedAgent
131
+ )?.metadata.name || 'Select agent'}
281
132
  <ChevronsUpDownIcon className="size-4 shrink-0 opacity-50" />
282
133
  </Button>
283
134
  </PopoverTrigger>
@@ -287,26 +138,44 @@ export function InputSection({
287
138
  <CommandList>
288
139
  <CommandEmpty>No agents found.</CommandEmpty>
289
140
  <CommandGroup>
290
- {Object.values(agents).map((agent) => (
291
- <CommandItem
292
- key={agent.metadata.identifier}
293
- value={agent.metadata.identifier}
294
- onSelect={(currentValue) => {
295
- setSelectedAgent(currentValue);
296
- setAgentSelectOpen(false);
297
- }}
298
- >
299
- <CheckIcon
300
- className={cn(
301
- 'size-4 text-green-500',
302
- selectedAgent === agent.metadata.identifier
303
- ? 'opacity-100'
304
- : 'opacity-0'
305
- )}
306
- />
307
- {agent.metadata.name}
308
- </CommandItem>
309
- ))}
141
+ {Object.values(agents)
142
+ .sort((a, b) => a.metadata.name.localeCompare(b.metadata.name))
143
+ .map((agent) => {
144
+ const isSelected = selectedAgent === agent.metadata.agentId;
145
+ // Use name for search but include agentId to ensure uniqueness
146
+ const searchValue = `${agent.metadata.name}|${agent.metadata.agentId}`;
147
+ return (
148
+ <CommandItem
149
+ key={agent.metadata.agentId}
150
+ value={searchValue}
151
+ onSelect={(currentValue) => {
152
+ // Extract agentId from the compound value
153
+ const agentId = currentValue.split('|')[1];
154
+ const selectedAgentData = Object.values(agents).find(
155
+ (a) => a.metadata.agentId === agentId
156
+ );
157
+ if (selectedAgentData) {
158
+ logger.debug(
159
+ '🎯 Agent selected by name:',
160
+ agent.metadata.name,
161
+ 'agentId:',
162
+ agentId
163
+ );
164
+ setSelectedAgent(agentId);
165
+ }
166
+ setAgentSelectOpen(false);
167
+ }}
168
+ >
169
+ <CheckIcon
170
+ className={cn(
171
+ 'size-4 text-green-500',
172
+ isSelected ? 'opacity-100' : 'opacity-0'
173
+ )}
174
+ />
175
+ {agent.metadata.name}
176
+ </CommandItem>
177
+ );
178
+ })}
310
179
  </CommandGroup>
311
180
  </CommandList>
312
181
  </Command>
@@ -360,10 +229,11 @@ export function InputSection({
360
229
  switch (inputType) {
361
230
  case 'object':
362
231
  return (
363
- <div
364
- ref={monacoEditorRef}
365
- className="w-full rounded-md bg-transparent overflow-hidden"
366
- style={{ minHeight: '64px', maxHeight: '192px', height: '64px' }}
232
+ <MonacoJsonEditor
233
+ value={value}
234
+ onChange={onChange}
235
+ schema={selectedAgentData?.schema.input?.json}
236
+ schemaUri={`agentuity://schema/${selectedAgentData?.metadata.id}/input`}
367
237
  />
368
238
  );
369
239
 
@@ -380,7 +250,7 @@ export function InputSection({
380
250
  <div className="flex flex-col items-center justify-center py-8 px-4 text-center ">
381
251
  <p className="text-sm text-muted-foreground">
382
252
  <span className="font-medium">
383
- This agent has not input schema.{' '}
253
+ This agent has no input schema.{' '}
384
254
  </span>
385
255
  </p>
386
256
  <Button
@@ -410,7 +280,15 @@ export function InputSection({
410
280
  size="icon"
411
281
  variant="default"
412
282
  disabled={isLoading || (inputType === 'string' && !value.trim())}
413
- onClick={onSubmit}
283
+ onClick={() => {
284
+ logger.debug(
285
+ '🔥 Submit button clicked! inputType:',
286
+ inputType,
287
+ 'value:',
288
+ value
289
+ );
290
+ onSubmit();
291
+ }}
414
292
  className="ml-auto"
415
293
  >
416
294
  {isLoading ? (