@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.
Files changed (171) hide show
  1. package/dist/components/App.d.ts.map +1 -1
  2. package/dist/components/App.js +15 -13
  3. package/dist/components/App.js.map +1 -1
  4. package/dist/components/ai-elements/actions.d.ts +1 -1
  5. package/dist/components/ai-elements/actions.d.ts.map +1 -1
  6. package/dist/components/ai-elements/actions.js +1 -1
  7. package/dist/components/ai-elements/actions.js.map +1 -1
  8. package/dist/components/ai-elements/code-block.d.ts +1 -1
  9. package/dist/components/ai-elements/code-block.d.ts.map +1 -1
  10. package/dist/components/ai-elements/code-block.js +22 -20
  11. package/dist/components/ai-elements/code-block.js.map +1 -1
  12. package/dist/components/ai-elements/conversation.d.ts +2 -2
  13. package/dist/components/ai-elements/conversation.d.ts.map +1 -1
  14. package/dist/components/ai-elements/conversation.js +5 -3
  15. package/dist/components/ai-elements/conversation.js.map +1 -1
  16. package/dist/components/ai-elements/message.d.ts +1 -1
  17. package/dist/components/ai-elements/message.d.ts.map +1 -1
  18. package/dist/components/ai-elements/message.js +4 -9
  19. package/dist/components/ai-elements/message.js.map +1 -1
  20. package/dist/components/ai-elements/prompt-input.d.ts.map +1 -1
  21. package/dist/components/ai-elements/prompt-input.js +1 -1
  22. package/dist/components/ai-elements/prompt-input.js.map +1 -1
  23. package/dist/components/ai-elements/shimmer.d.ts.map +1 -1
  24. package/dist/components/ai-elements/shimmer.js +1 -1
  25. package/dist/components/ai-elements/shimmer.js.map +1 -1
  26. package/dist/components/internal/chat.d.ts +10 -0
  27. package/dist/components/internal/chat.d.ts.map +1 -0
  28. package/dist/components/internal/chat.js +104 -0
  29. package/dist/components/internal/chat.js.map +1 -0
  30. package/dist/components/internal/{Header.d.ts → header.d.ts} +4 -6
  31. package/dist/components/internal/header.d.ts.map +1 -0
  32. package/dist/components/internal/header.js +25 -0
  33. package/dist/components/internal/header.js.map +1 -0
  34. package/dist/components/internal/{InputSection.d.ts → input-section.d.ts} +9 -9
  35. package/dist/components/internal/input-section.d.ts.map +1 -0
  36. package/dist/components/internal/input-section.js +162 -0
  37. package/dist/components/internal/input-section.js.map +1 -0
  38. package/dist/components/internal/json-editor.d.ts +14 -0
  39. package/dist/components/internal/json-editor.d.ts.map +1 -0
  40. package/dist/components/internal/{MonacoJsonEditor.js → json-editor.js} +40 -37
  41. package/dist/components/internal/json-editor.js.map +1 -0
  42. package/dist/components/internal/logo.d.ts +2 -3
  43. package/dist/components/internal/logo.d.ts.map +1 -1
  44. package/dist/components/internal/logo.js +2 -2
  45. package/dist/components/internal/logo.js.map +1 -1
  46. package/dist/components/internal/resizable-provider.d.ts.map +1 -0
  47. package/dist/components/internal/resizable-provider.js.map +1 -0
  48. package/dist/components/internal/{Schema.d.ts → schema.d.ts} +2 -2
  49. package/dist/components/internal/schema.d.ts.map +1 -0
  50. package/dist/components/internal/schema.js +13 -0
  51. package/dist/components/internal/schema.js.map +1 -0
  52. package/dist/components/internal/{WorkbenchProvider.d.ts → workbench-provider.d.ts} +8 -4
  53. package/dist/components/internal/workbench-provider.d.ts.map +1 -0
  54. package/dist/components/internal/{WorkbenchProvider.js → workbench-provider.js} +87 -60
  55. package/dist/components/internal/workbench-provider.js.map +1 -0
  56. package/dist/components/ui/avatar.d.ts +1 -1
  57. package/dist/components/ui/avatar.d.ts.map +1 -1
  58. package/dist/components/ui/avatar.js.map +1 -1
  59. package/dist/components/ui/button.d.ts +1 -1
  60. package/dist/components/ui/command.d.ts +1 -1
  61. package/dist/components/ui/command.d.ts.map +1 -1
  62. package/dist/components/ui/command.js.map +1 -1
  63. package/dist/components/ui/dialog.d.ts +1 -1
  64. package/dist/components/ui/dialog.d.ts.map +1 -1
  65. package/dist/components/ui/dialog.js.map +1 -1
  66. package/dist/components/ui/dropdown-menu.d.ts +1 -1
  67. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  68. package/dist/components/ui/dropdown-menu.js.map +1 -1
  69. package/dist/components/ui/hover-card.d.ts +1 -1
  70. package/dist/components/ui/hover-card.d.ts.map +1 -1
  71. package/dist/components/ui/hover-card.js.map +1 -1
  72. package/dist/components/ui/input-group.d.ts +2 -2
  73. package/dist/components/ui/input-group.d.ts.map +1 -1
  74. package/dist/components/ui/input-group.js.map +1 -1
  75. package/dist/components/ui/input.d.ts +1 -1
  76. package/dist/components/ui/input.d.ts.map +1 -1
  77. package/dist/components/ui/scroll-area.d.ts +1 -1
  78. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  79. package/dist/components/ui/scroll-area.js.map +1 -1
  80. package/dist/components/ui/textarea.d.ts +1 -1
  81. package/dist/components/ui/textarea.d.ts.map +1 -1
  82. package/dist/components/ui/theme-provider.d.ts.map +1 -1
  83. package/dist/components/ui/theme-provider.js +1 -1
  84. package/dist/components/ui/theme-provider.js.map +1 -1
  85. package/dist/components/ui/tooltip.d.ts +1 -1
  86. package/dist/components/ui/tooltip.d.ts.map +1 -1
  87. package/dist/components/ui/tooltip.js.map +1 -1
  88. package/dist/hooks/useAgentSchemas.d.ts +10 -10
  89. package/dist/hooks/useAgentSchemas.d.ts.map +1 -1
  90. package/dist/hooks/useAgentSchemas.js +9 -7
  91. package/dist/hooks/useAgentSchemas.js.map +1 -1
  92. package/dist/hooks/useLogger.d.ts.map +1 -1
  93. package/dist/hooks/useLogger.js +2 -1
  94. package/dist/hooks/useLogger.js.map +1 -1
  95. package/dist/hooks/useWorkbenchWebsocket.d.ts +2 -2
  96. package/dist/hooks/useWorkbenchWebsocket.d.ts.map +1 -1
  97. package/dist/hooks/useWorkbenchWebsocket.js +24 -20
  98. package/dist/hooks/useWorkbenchWebsocket.js.map +1 -1
  99. package/dist/index.d.ts +5 -5
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +4 -6
  102. package/dist/index.js.map +1 -1
  103. package/dist/lib/utils.d.ts +3 -0
  104. package/dist/lib/utils.d.ts.map +1 -1
  105. package/dist/lib/utils.js +59 -0
  106. package/dist/lib/utils.js.map +1 -1
  107. package/dist/server.d.ts +1 -1
  108. package/dist/server.d.ts.map +1 -1
  109. package/dist/server.js.map +1 -1
  110. package/dist/standalone.css +360 -295
  111. package/dist/types/config.d.ts +27 -18
  112. package/dist/types/config.d.ts.map +1 -1
  113. package/package.json +5 -5
  114. package/src/base.css +186 -158
  115. package/src/components/App.tsx +31 -16
  116. package/src/components/ai-elements/actions.tsx +2 -2
  117. package/src/components/ai-elements/code-block.tsx +46 -32
  118. package/src/components/ai-elements/conversation.tsx +18 -17
  119. package/src/components/ai-elements/message.tsx +4 -9
  120. package/src/components/ai-elements/prompt-input.tsx +1 -1
  121. package/src/components/ai-elements/shimmer.tsx +1 -1
  122. package/src/components/internal/chat.tsx +326 -0
  123. package/src/components/internal/{Header.tsx → header.tsx} +37 -40
  124. package/src/components/internal/{InputSection.tsx → input-section.tsx} +173 -119
  125. package/src/components/internal/{MonacoJsonEditor.tsx → json-editor.tsx} +77 -49
  126. package/src/components/internal/logo.tsx +3 -5
  127. package/src/components/internal/schema.tsx +96 -0
  128. package/src/components/internal/{WorkbenchProvider.tsx → workbench-provider.tsx} +194 -68
  129. package/src/components/ui/avatar.tsx +1 -1
  130. package/src/components/ui/command.tsx +1 -1
  131. package/src/components/ui/dialog.tsx +1 -1
  132. package/src/components/ui/dropdown-menu.tsx +1 -1
  133. package/src/components/ui/hover-card.tsx +1 -1
  134. package/src/components/ui/input-group.tsx +1 -1
  135. package/src/components/ui/input.tsx +1 -1
  136. package/src/components/ui/scroll-area.tsx +1 -1
  137. package/src/components/ui/textarea.tsx +1 -1
  138. package/src/components/ui/theme-provider.tsx +1 -1
  139. package/src/components/ui/tooltip.tsx +1 -1
  140. package/src/hooks/useAgentSchemas.ts +26 -15
  141. package/src/hooks/useLogger.ts +7 -1
  142. package/src/hooks/useWorkbenchWebsocket.ts +67 -32
  143. package/src/index.ts +5 -9
  144. package/src/lib/utils.ts +88 -0
  145. package/src/server.ts +1 -1
  146. package/src/types/config.ts +28 -21
  147. package/dist/components/internal/Chat.d.ts +0 -14
  148. package/dist/components/internal/Chat.d.ts.map +0 -1
  149. package/dist/components/internal/Chat.js +0 -61
  150. package/dist/components/internal/Chat.js.map +0 -1
  151. package/dist/components/internal/Header.d.ts.map +0 -1
  152. package/dist/components/internal/Header.js +0 -31
  153. package/dist/components/internal/Header.js.map +0 -1
  154. package/dist/components/internal/InputSection.d.ts.map +0 -1
  155. package/dist/components/internal/InputSection.js +0 -152
  156. package/dist/components/internal/InputSection.js.map +0 -1
  157. package/dist/components/internal/MonacoJsonEditor.d.ts +0 -13
  158. package/dist/components/internal/MonacoJsonEditor.d.ts.map +0 -1
  159. package/dist/components/internal/MonacoJsonEditor.js.map +0 -1
  160. package/dist/components/internal/Schema.d.ts.map +0 -1
  161. package/dist/components/internal/Schema.js +0 -13
  162. package/dist/components/internal/Schema.js.map +0 -1
  163. package/dist/components/internal/WorkbenchProvider.d.ts.map +0 -1
  164. package/dist/components/internal/WorkbenchProvider.js.map +0 -1
  165. package/dist/components/ui/resizable-provider.d.ts.map +0 -1
  166. package/dist/components/ui/resizable-provider.js.map +0 -1
  167. package/src/components/internal/Chat.tsx +0 -201
  168. package/src/components/internal/Schema.tsx +0 -100
  169. /package/dist/components/{ui → internal}/resizable-provider.d.ts +0 -0
  170. /package/dist/components/{ui → internal}/resizable-provider.js +0 -0
  171. /package/src/components/{ui → internal}/resizable-provider.tsx +0 -0
@@ -1,20 +1,21 @@
1
- import React, { useEffect, useState } from 'react';
2
1
  import Editor, { type Monaco, type OnMount } from '@monaco-editor/react';
3
- import { useTheme } from '../ui/theme-provider';
2
+ import oneDarkProModule from '@shikijs/themes/dark-plus';
3
+ import oneLightModule from '@shikijs/themes/light-plus';
4
4
  import type { JSONSchema7 } from 'ai';
5
5
  import type * as monaco from 'monaco-editor';
6
+ import React, { useEffect, useRef, useState } from 'react';
6
7
  import type { ThemeRegistration } from 'shiki';
7
- import oneLightModule from '@shikijs/themes/one-light';
8
- import oneDarkProModule from '@shikijs/themes/one-dark-pro';
8
+ import { useTheme } from '../ui/theme-provider';
9
9
 
10
- interface MonacoJsonEditorProps {
11
- value: string;
10
+ interface JsonEditorProps {
11
+ 'aria-invalid'?: boolean;
12
+ className?: string;
12
13
  onChange: (value: string) => void;
14
+ onSubmit: () => void;
15
+ onValidationChange?: (hasErrors: boolean) => void;
13
16
  schema?: JSONSchema7;
14
17
  schemaUri?: string;
15
- className?: string;
16
- 'aria-invalid'?: boolean;
17
- onValidationChange?: (hasErrors: boolean) => void;
18
+ value: string;
18
19
  }
19
20
 
20
21
  // Convert color value to valid hex for Monaco
@@ -64,7 +65,11 @@ function convertShikiToMonaco(
64
65
  const isDark = themeName.includes('dark');
65
66
 
66
67
  // Convert token colors to Monaco rules
67
- const rules: Array<{ token: string; foreground: string; fontStyle?: string }> = [];
68
+ const rules: Array<{
69
+ token: string;
70
+ foreground: string;
71
+ fontStyle?: string;
72
+ }> = [];
68
73
  tokenColors.forEach((tokenColor) => {
69
74
  if (tokenColor.scope && tokenColor.settings?.foreground) {
70
75
  const scopes = Array.isArray(tokenColor.scope) ? tokenColor.scope : [tokenColor.scope];
@@ -103,19 +108,25 @@ function convertShikiToMonaco(
103
108
  };
104
109
  }
105
110
 
106
- export function MonacoJsonEditor({
107
- value,
111
+ export function JsonEditor({
112
+ 'aria-invalid': ariaInvalid,
113
+ className = '',
108
114
  onChange,
115
+ onSubmit,
116
+ onValidationChange,
109
117
  schema,
110
118
  schemaUri = 'agentuity://schema/default',
111
- className = '',
112
- 'aria-invalid': ariaInvalid,
113
- onValidationChange,
114
- }: MonacoJsonEditorProps) {
119
+ value,
120
+ }: JsonEditorProps) {
115
121
  const { theme } = useTheme();
116
122
  const [editorInstance, setEditorInstance] = useState<Parameters<OnMount>[0] | null>(null);
117
123
  const [monacoInstance, setMonacoInstance] = useState<Monaco | null>(null);
118
124
  const [editorHeight, setEditorHeight] = useState(120);
125
+ const handleSubmit = useRef(onSubmit);
126
+
127
+ useEffect(() => {
128
+ handleSubmit.current = onSubmit;
129
+ }, [onSubmit]);
119
130
 
120
131
  // Get resolved theme (similar to useTheme's resolvedTheme from next-themes)
121
132
  const resolvedTheme = React.useMemo(() => {
@@ -163,8 +174,12 @@ export function MonacoJsonEditor({
163
174
  <div
164
175
  data-slot="input-group-control"
165
176
  aria-invalid={ariaInvalid}
166
- className={`w-full pl-3 pb-3 [&_.monaco-editor]:!bg-transparent [&_.monaco-editor-background]:!bg-transparent [&_.view-lines]:!bg-transparent [&_.monaco-editor]:!shadow-none [&_.monaco-scrollable-element]:!shadow-none [&_.overflow-guard]:!shadow-none [&_.monaco-scrollable-element>.shadow.top]:!hidden [&_.monaco-editor_.scroll-decoration]:!hidden [&_.shadow.top]:!hidden [&_.scroll-decoration]:!hidden ${className}`}
167
- style={{ minHeight: '64px', maxHeight: '192px', height: `${editorHeight}px` }}
177
+ className={`w-full pl-3 pb-3 [&_.monaco-editor]:bg-transparent! [&_.monaco-editor-background]:bg-transparent! [&_.view-lines]:bg-transparent! [&_.monaco-editor]:shadow-none! [&_.monaco-scrollable-element]:shadow-none! [&_.overflow-guard]:shadow-none! [&_.monaco-scrollable-element>.shadow.top]:hidden! [&_.monaco-editor_.scroll-decoration]:hidden! [&_.shadow.top]:hidden! [&_.scroll-decoration]:hidden! [&_.native-edit-context]:outline-gray-200! [&_.native-edit-context]:dark:outline-gray-800! ${className}`}
178
+ style={{
179
+ minHeight: '64px',
180
+ maxHeight: '192px',
181
+ height: `${editorHeight}px`,
182
+ }}
168
183
  >
169
184
  <Editor
170
185
  // Allow the editor to be truly empty. We intentionally do NOT coerce to `{}`.
@@ -174,62 +189,60 @@ export function MonacoJsonEditor({
174
189
  theme={resolvedTheme === 'light' ? 'custom-light' : 'custom-dark'}
175
190
  height="100%"
176
191
  options={{
177
- minimap: { enabled: false },
178
- lineNumbers: 'off',
179
- folding: false,
180
- scrollBeyondLastLine: false,
181
- wordWrap: 'on',
182
- renderLineHighlight: 'none',
183
- overviewRulerBorder: false,
184
- overviewRulerLanes: 0,
185
- hideCursorInOverviewRuler: true,
192
+ autoIndent: 'full',
193
+ automaticLayout: true,
186
194
  fixedOverflowWidgets: true,
187
- roundedSelection: false,
188
- occurrencesHighlight: 'off',
189
- selectionHighlight: false,
190
- renderWhitespace: 'none',
195
+ folding: false,
191
196
  fontSize: 14,
192
197
  fontWeight: '400',
193
198
  formatOnPaste: true,
194
199
  formatOnType: true,
195
- autoIndent: 'full',
196
200
  glyphMargin: false,
201
+ guides: { highlightActiveIndentation: false, indentation: false },
202
+ hideCursorInOverviewRuler: true,
197
203
  lineDecorationsWidth: 0,
204
+ lineNumbers: 'off',
198
205
  lineNumbersMinChars: 0,
199
- automaticLayout: true,
206
+ minimap: { enabled: false },
207
+ occurrencesHighlight: 'off',
208
+ overviewRulerBorder: false,
209
+ overviewRulerLanes: 0,
210
+ padding: { top: 12, bottom: 12 },
211
+ renderLineHighlight: 'none',
212
+ renderValidationDecorations: 'on',
213
+ renderWhitespace: 'none',
214
+ roundedSelection: false,
200
215
  scrollbar: {
201
- vertical: 'auto',
202
216
  horizontal: 'auto',
203
- verticalScrollbarSize: 10,
217
+ horizontalHasArrows: false,
204
218
  horizontalScrollbarSize: 10,
205
- // Disable scroll shadows
219
+ vertical: 'auto',
206
220
  verticalHasArrows: false,
207
- horizontalHasArrows: false,
208
- },
209
- padding: { top: 12, bottom: 12 },
210
- // Additional background transparency options
211
- renderValidationDecorations: 'on',
212
- guides: {
213
- indentation: false,
214
- highlightActiveIndentation: false,
221
+ verticalScrollbarSize: 10,
215
222
  },
216
- // Disable sticky scroll feature
217
- stickyScroll: { enabled: false },
218
- // Disable scroll decorations/shadows
219
223
  scrollBeyondLastColumn: 0,
220
- renderLineHighlightOnlyWhenFocus: true,
224
+ scrollBeyondLastLine: false,
225
+ selectionHighlight: false,
226
+ stickyScroll: { enabled: false },
227
+ wordWrap: 'on',
221
228
  }}
222
229
  onMount={(editor, monaco) => {
223
230
  setEditorInstance(editor);
224
231
  setMonacoInstance(monaco);
232
+
225
233
  editor.focus();
226
234
 
235
+ editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () =>
236
+ handleSubmit.current()
237
+ );
238
+
227
239
  // Auto-resize based on content
228
240
  const updateHeight = () => {
229
241
  const contentHeight = editor.getContentHeight();
230
242
  const maxHeight = 192; // max-h-48 = 12rem = 192px
231
243
  const minHeight = 64; // min-h-16 = 4rem = 64px
232
244
  const newHeight = Math.min(Math.max(contentHeight + 24, minHeight), maxHeight);
245
+
233
246
  setEditorHeight(newHeight);
234
247
 
235
248
  // Layout after height change
@@ -243,18 +256,24 @@ export function MonacoJsonEditor({
243
256
  if (onValidationChange) {
244
257
  const checkValidationErrors = () => {
245
258
  const model = editor.getModel();
259
+
246
260
  if (model) {
247
261
  // Treat an empty editor as a valid "empty state" (avoid Monaco's JSON parse error).
248
262
  if (!model.getValue().trim()) {
249
263
  onValidationChange(false);
264
+
250
265
  return;
251
266
  }
252
267
 
253
- const markers = monaco.editor.getModelMarkers({ resource: model.uri });
268
+ const markers = monaco.editor.getModelMarkers({
269
+ resource: model.uri,
270
+ });
271
+
254
272
  const hasErrors = markers.some(
255
273
  (marker: monaco.editor.IMarker) =>
256
274
  marker.severity === monaco.MarkerSeverity.Error
257
275
  );
276
+
258
277
  onValidationChange(hasErrors);
259
278
  }
260
279
  };
@@ -265,6 +284,7 @@ export function MonacoJsonEditor({
265
284
  // Check when markers change
266
285
  monaco.editor.onDidChangeMarkers((uris: readonly monaco.Uri[]) => {
267
286
  const model = editor.getModel();
287
+
268
288
  if (model && uris.includes(model.uri)) {
269
289
  checkValidationErrors();
270
290
  }
@@ -280,6 +300,7 @@ export function MonacoJsonEditor({
280
300
  // Ensure background transparency and remove shadows
281
301
  setTimeout(() => {
282
302
  const editorElement = editor.getDomNode();
303
+
283
304
  if (editorElement) {
284
305
  // Set transparent backgrounds on all relevant elements
285
306
  const elementsToMakeTransparent = [
@@ -295,6 +316,7 @@ export function MonacoJsonEditor({
295
316
 
296
317
  elementsToMakeTransparent.forEach((selector) => {
297
318
  const element = editorElement.querySelector(selector);
319
+
298
320
  if (element) {
299
321
  (element as HTMLElement).style.backgroundColor = 'transparent';
300
322
  (element as HTMLElement).style.boxShadow = 'none';
@@ -305,6 +327,7 @@ export function MonacoJsonEditor({
305
327
  const shadowTop = editorElement.querySelector(
306
328
  '.monaco-scrollable-element > .shadow.top'
307
329
  );
330
+
308
331
  if (shadowTop) {
309
332
  (shadowTop as HTMLElement).style.display = 'none';
310
333
  }
@@ -312,6 +335,7 @@ export function MonacoJsonEditor({
312
335
  const scrollDecorations = editorElement.querySelectorAll(
313
336
  '.monaco-editor .scroll-decoration, .scroll-decoration'
314
337
  );
338
+
315
339
  scrollDecorations.forEach((decoration) => {
316
340
  (decoration as HTMLElement).style.display = 'none';
317
341
  });
@@ -319,6 +343,7 @@ export function MonacoJsonEditor({
319
343
  const scrollableElement = editorElement.querySelector(
320
344
  '.monaco-scrollable-element'
321
345
  );
346
+
322
347
  if (scrollableElement) {
323
348
  (scrollableElement as HTMLElement).style.setProperty(
324
349
  '--scroll-shadow',
@@ -344,17 +369,20 @@ export function MonacoJsonEditor({
344
369
  const oneLight = (
345
370
  'default' in oneLightModule ? oneLightModule.default : oneLightModule
346
371
  ) as ThemeRegistration;
372
+
347
373
  const oneDarkPro = (
348
374
  'default' in oneDarkProModule ? oneDarkProModule.default : oneDarkProModule
349
375
  ) as ThemeRegistration;
350
376
 
351
377
  const lightMonacoTheme = convertShikiToMonaco(oneLight, 'one-light');
378
+
352
379
  monaco.editor.defineTheme(
353
380
  'custom-light',
354
381
  lightMonacoTheme as monaco.editor.IStandaloneThemeData
355
382
  );
356
383
 
357
384
  const darkMonacoTheme = convertShikiToMonaco(oneDarkPro, 'one-dark-pro');
385
+
358
386
  monaco.editor.defineTheme(
359
387
  'custom-dark',
360
388
  darkMonacoTheme as monaco.editor.IStandaloneThemeData
@@ -1,22 +1,20 @@
1
1
  import { forwardRef } from 'react';
2
- import React from 'react';
3
-
4
2
  import { cn } from '../../lib/utils';
5
3
 
6
4
  const Logo = forwardRef<SVGSVGElement, { className?: string; alt?: string }>(
7
- ({ className = '', alt = 'Agentuity' }, ref) => {
5
+ ({ className = '' }, ref) => {
8
6
  return (
9
7
  <svg
10
8
  ref={ref}
11
9
  role="img"
12
- aria-label={alt}
10
+ aria-label="Agentuity"
13
11
  className={cn('fill-cyan-600 dark:fill-cyan-500', className)}
14
12
  width="24"
15
13
  height="22"
16
14
  viewBox="0 0 24 22"
17
15
  xmlns="http://www.w3.org/2000/svg"
18
16
  >
19
- <title>{alt}</title>
17
+ <title>Agentuity</title>
20
18
  <path
21
19
  fillRule="evenodd"
22
20
  clipRule="evenodd"
@@ -0,0 +1,96 @@
1
+ import { Braces, X } from 'lucide-react';
2
+ import { CodeBlock, CodeBlockCopyButton } from '../ai-elements/code-block';
3
+ import { Button } from '../ui/button';
4
+ import { ScrollArea } from '../ui/scroll-area';
5
+ import { useWorkbench } from './workbench-provider';
6
+
7
+ export interface SchemaProps {
8
+ onOpenChange?: (open: boolean) => void;
9
+ }
10
+
11
+ export function Schema({ onOpenChange }: SchemaProps) {
12
+ const { agents, selectedAgent, schemasLoading, schemasError } = useWorkbench();
13
+
14
+ const selectedAgentData =
15
+ Object.values(agents).find((agent) => agent.metadata.agentId === selectedAgent) || null;
16
+
17
+ return (
18
+ <div className="h-full flex flex-col">
19
+ {onOpenChange && (
20
+ <div className="flex items-center justify-between py-2.5 px-4.5 border-b border-border">
21
+ <div className="flex items-center gap-2">
22
+ <Braces className="size-5 text-muted-foreground" />
23
+
24
+ <h2 className="font-medium mt-0.5">Schema</h2>
25
+ </div>
26
+
27
+ <Button
28
+ variant="ghost"
29
+ size="icon"
30
+ onClick={() => onOpenChange(false)}
31
+ className="size-8"
32
+ >
33
+ <X className="size-4" />
34
+ </Button>
35
+ </div>
36
+ )}
37
+
38
+ <ScrollArea className="flex-1 text-sm overflow-hidden">
39
+ <div className="flex flex-col gap-6 p-4">
40
+ {schemasLoading && (
41
+ <div className="text-center text-muted-foreground/70 py-8" data-loading>
42
+ Loading schema
43
+ </div>
44
+ )}
45
+
46
+ {schemasError && (
47
+ <div className="flex flex-col gap-1 rounded-md bg-destructive/10 text-destructive py-2.5 px-4">
48
+ <p className="font-medium">Error Loading Schemas</p>
49
+ <p className="text-xs">{schemasError.message}</p>
50
+ </div>
51
+ )}
52
+
53
+ {!schemasLoading && !schemasError && !selectedAgentData && (
54
+ <div className="text-center text-muted-foreground/70 py-8">
55
+ <p>No schema available for selected agent</p>
56
+ </div>
57
+ )}
58
+
59
+ {!schemasLoading && !schemasError && selectedAgentData && (
60
+ <>
61
+ {selectedAgentData.schema.input?.code ? (
62
+ <div className="flex flex-col gap-2">
63
+ <h3 className="text-sm text-muted-foreground">Input Schema</h3>
64
+
65
+ <CodeBlock
66
+ code={selectedAgentData.schema.input?.code}
67
+ language="typescript"
68
+ className="text-xs! [&_code]:text-xs! [&_pre]:py-3!"
69
+ >
70
+ <CodeBlockCopyButton />
71
+ </CodeBlock>
72
+ </div>
73
+ ) : null}
74
+
75
+ {selectedAgentData.schema.output?.code ? (
76
+ <div className="flex flex-col gap-2">
77
+ <h3 className="text-sm text-muted-foreground">Output Schema</h3>
78
+
79
+ <CodeBlock
80
+ code={selectedAgentData.schema.output?.code}
81
+ language="typescript"
82
+ className="text-xs! [&_code]:text-xs! [&_pre]:py-3!"
83
+ >
84
+ <CodeBlockCopyButton />
85
+ </CodeBlock>
86
+ </div>
87
+ ) : null}
88
+ </>
89
+ )}
90
+ </div>
91
+ </ScrollArea>
92
+ </div>
93
+ );
94
+ }
95
+
96
+ export default Schema;