@alpaca-editor/core 1.0.4102 → 1.0.4104

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 (97) hide show
  1. package/dist/components/ui/context-menu.d.ts +1 -1
  2. package/dist/components/ui/context-menu.js +8 -8
  3. package/dist/components/ui/context-menu.js.map +1 -1
  4. package/dist/config/config.js +8 -1
  5. package/dist/config/config.js.map +1 -1
  6. package/dist/config/types.d.ts +1 -0
  7. package/dist/editor/ContentTree.js +15 -16
  8. package/dist/editor/ContentTree.js.map +1 -1
  9. package/dist/editor/ContextMenu.js +37 -6
  10. package/dist/editor/ContextMenu.js.map +1 -1
  11. package/dist/editor/MainLayout.js +1 -1
  12. package/dist/editor/MainLayout.js.map +1 -1
  13. package/dist/editor/ai/AgentHistory.js +1 -1
  14. package/dist/editor/ai/AgentTerminal.js +187 -13
  15. package/dist/editor/ai/AgentTerminal.js.map +1 -1
  16. package/dist/editor/ai/AiResponseMessage.d.ts +1 -1
  17. package/dist/editor/ai/types.d.ts +25 -0
  18. package/dist/editor/ai/types.js +2 -0
  19. package/dist/editor/ai/types.js.map +1 -0
  20. package/dist/editor/client/EditorShell.js +29 -0
  21. package/dist/editor/client/EditorShell.js.map +1 -1
  22. package/dist/editor/client/editContext.d.ts +3 -0
  23. package/dist/editor/client/editContext.js.map +1 -1
  24. package/dist/editor/commands/agentCommands.d.ts +9 -0
  25. package/dist/editor/commands/agentCommands.js +30 -0
  26. package/dist/editor/commands/agentCommands.js.map +1 -0
  27. package/dist/editor/commands/itemCommands.js +14 -14
  28. package/dist/editor/commands/itemCommands.js.map +1 -1
  29. package/dist/editor/component-designer/aiContext.d.ts +1 -1
  30. package/dist/editor/context-menu/InsertMenu.d.ts +2 -1
  31. package/dist/editor/context-menu/InsertMenu.js +20 -15
  32. package/dist/editor/context-menu/InsertMenu.js.map +1 -1
  33. package/dist/editor/field-types/NameValueListEditor.d.ts +7 -0
  34. package/dist/editor/field-types/NameValueListEditor.js +99 -0
  35. package/dist/editor/field-types/NameValueListEditor.js.map +1 -0
  36. package/dist/editor/fieldTypes.d.ts +1 -1
  37. package/dist/editor/page-editor-chrome/FrameMenu.js +47 -10
  38. package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
  39. package/dist/editor/page-editor-chrome/PlaceholderDropZone.d.ts +3 -1
  40. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +30 -4
  41. package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
  42. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +44 -5
  43. package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
  44. package/dist/editor/services/agentService.d.ts +22 -2
  45. package/dist/editor/services/agentService.js +26 -1
  46. package/dist/editor/services/agentService.js.map +1 -1
  47. package/dist/editor/services/aiService.d.ts +2 -1
  48. package/dist/editor/services/aiService.js.map +1 -1
  49. package/dist/editor/sidebar/GraphQL.js +47 -90
  50. package/dist/editor/sidebar/GraphQL.js.map +1 -1
  51. package/dist/editor/ui/DragPreview.d.ts +13 -0
  52. package/dist/editor/ui/DragPreview.js +35 -0
  53. package/dist/editor/ui/DragPreview.js.map +1 -0
  54. package/dist/editor/ui/ItemNameDialogNew.js +2 -2
  55. package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
  56. package/dist/editor/ui/PerfectTree.js +3 -15
  57. package/dist/editor/ui/PerfectTree.js.map +1 -1
  58. package/dist/revision.d.ts +2 -2
  59. package/dist/revision.js +2 -2
  60. package/dist/styles.css +37 -9
  61. package/dist/tour/default-tour.js +34 -38
  62. package/dist/tour/default-tour.js.map +1 -1
  63. package/package.json +1 -1
  64. package/src/components/ui/context-menu.tsx +31 -19
  65. package/src/config/config.tsx +9 -1
  66. package/src/config/types.ts +1 -0
  67. package/src/editor/ContentTree.tsx +13 -18
  68. package/src/editor/ContextMenu.tsx +112 -19
  69. package/src/editor/MainLayout.tsx +1 -1
  70. package/src/editor/ai/AgentHistory.tsx +2 -2
  71. package/src/editor/ai/AgentTerminal.tsx +226 -15
  72. package/src/editor/ai/AiResponseMessage.tsx +1 -1
  73. package/src/editor/ai/types.ts +27 -0
  74. package/src/editor/client/EditorShell.tsx +31 -0
  75. package/src/editor/client/editContext.ts +12 -1
  76. package/src/editor/commands/agentCommands.tsx +49 -0
  77. package/src/editor/commands/itemCommands.tsx +26 -14
  78. package/src/editor/component-designer/aiContext.ts +1 -1
  79. package/src/editor/context-menu/InsertMenu.tsx +64 -39
  80. package/src/editor/field-types/NameValueListEditor.tsx +197 -0
  81. package/src/editor/fieldTypes.ts +1 -1
  82. package/src/editor/page-editor-chrome/FrameMenu.tsx +61 -13
  83. package/src/editor/page-editor-chrome/PlaceholderDropZone.tsx +82 -20
  84. package/src/editor/page-editor-chrome/PlaceholderDropZones.tsx +77 -24
  85. package/src/editor/services/agentService.ts +53 -2
  86. package/src/editor/services/aiService.ts +3 -1
  87. package/src/editor/sidebar/GraphQL.tsx +50 -99
  88. package/src/editor/ui/DragPreview.tsx +44 -0
  89. package/src/editor/ui/ItemNameDialogNew.tsx +7 -3
  90. package/src/editor/ui/PerfectTree.tsx +2 -17
  91. package/src/revision.ts +2 -2
  92. package/src/tour/default-tour.tsx +34 -46
  93. package/dist/editor/ai/AiTerminal.d.ts +0 -47
  94. package/dist/editor/ai/AiTerminal.js +0 -300
  95. package/dist/editor/ai/AiTerminal.js.map +0 -1
  96. package/src/editor/ai/AiTerminal.tsx +0 -570
  97. package/src/editor/component-designer/ComponentDesignerAiTerminal.tsx_ +0 -11
@@ -1,570 +0,0 @@
1
- "use client";
2
-
3
- import { useEffect, useRef, useState } from "react";
4
-
5
- import { TerminalService } from "primereact/terminalservice";
6
-
7
- import { Terminal } from "../Terminal";
8
- import { EditContextType, useEditContext } from "../client/editContext";
9
- import { Dropdown } from "primereact/dropdown";
10
-
11
- import { WizardIcon } from "../ui/Icons";
12
- import { AiResponseMessage } from "./AiResponseMessage";
13
- import {
14
- AiProfile,
15
- loadAiProfiles,
16
- executePrompt,
17
- } from "../services/aiService";
18
- import { EditOperation } from "../../types";
19
- import { SimpleIconButton } from "../ui/SimpleIconButton";
20
- import { Settings } from "lucide-react";
21
-
22
- type Response = {
23
- messages: Message[];
24
- editOperations: EditOperation[];
25
- numInputTokens: number;
26
- numOutputTokens: number;
27
- numCachedTokens: number;
28
- state: string;
29
- };
30
-
31
- export type ToolCall = {
32
- id: string;
33
- displayName: string;
34
- function: {
35
- name: string;
36
- arguments: string;
37
- };
38
- };
39
-
40
- export type Message = {
41
- id: string; // Changed from number to string for UUID support
42
- content: string;
43
- formattedContent?: string;
44
- name: string;
45
- role: string;
46
- tool_calls?: ToolCall[];
47
- tool_call_id?: string; // For tool response messages
48
- createdDate?: string; // Timestamp from the original message
49
- };
50
-
51
- export type AiContext = {
52
- promptData: any;
53
- endpoint?: string;
54
- callback?: (response: Response) => void;
55
- };
56
-
57
- export type AiTerminalOptions = {
58
- initialPrompt?: string;
59
- hiddenSystemPrompt?: string;
60
- initialMessages?: Message[];
61
- };
62
-
63
- export function AiTerminal({
64
- closeButton,
65
- createAiContext,
66
- defaultProfile,
67
- options,
68
- }: {
69
- closeButton?: React.ReactNode;
70
- createAiContext: ({
71
- editContext,
72
- }: {
73
- editContext: EditContextType;
74
- }) => AiContext;
75
- defaultProfile?: string;
76
- options?: AiTerminalOptions;
77
- }) {
78
- const editContext = useEditContext();
79
- const [showPredefined, setShowPredefined] = useState(false);
80
-
81
- if (!editContext) return null;
82
-
83
- const [messages, setMessages] = useState<Message[]>(
84
- options?.initialMessages || [],
85
- );
86
- const [response, setResponse] = useState<Response>();
87
- const [model, setModel] = useState<string>();
88
- const [prompt, setPrompt] = useState("");
89
- const [profiles, setProfiles] = useState<AiProfile[]>([]);
90
- const [activeProfile, setActiveProfile] = useState<AiProfile>();
91
- const [initialPromptExecuted, setInitialPromptExecuted] = useState(false);
92
- const [agentId] = useState<string>(() => crypto.randomUUID());
93
- const selection = editContext.selection;
94
- const terminalRef = useRef<{ submit: () => void; focusPrompt: () => void }>(
95
- null,
96
- );
97
- const [responseMessages, setResponseMessages] = useState<Message[]>(
98
- options?.initialMessages || [],
99
- );
100
- const [showSettings, setShowSettings] = useState(false);
101
- const settingsRef = useRef<HTMLDivElement>(null);
102
- const [inputPlaceholder, setInputPlaceholder] = useState<string | undefined>(
103
- undefined,
104
- );
105
-
106
- useEffect(() => {
107
- if (options?.initialPrompt && !initialPromptExecuted && model) {
108
- // Set the initial prompt text into the terminal's state.
109
- console.log("setting prompt", options.initialPrompt);
110
- setPrompt(options.initialPrompt);
111
- setInitialPromptExecuted(true);
112
- // Wait for the Terminal to update, then programmatically submit.
113
- setTimeout(() => {
114
- terminalRef.current?.submit();
115
- }, 100);
116
- }
117
- }, [options?.initialPrompt, initialPromptExecuted, model]);
118
-
119
- useEffect(() => {
120
- async function fetchProfiles() {
121
- if (!editContext?.currentItemDescriptor) return;
122
- const profiles = await loadAiProfiles(editContext.currentItemDescriptor);
123
- setProfiles(profiles);
124
- if (!activeProfile)
125
- setActiveProfile(
126
- profiles.find((x) => x.name == defaultProfile) || profiles[0],
127
- );
128
- }
129
- fetchProfiles();
130
- }, [editContext?.currentItemDescriptor]);
131
-
132
- useEffect(() => {
133
- if (activeProfile?.defaultModelId) setModel(activeProfile.defaultModelId);
134
- }, [activeProfile]);
135
-
136
- const messagesRef = useRef(messages);
137
- useEffect(() => {
138
- messagesRef.current = responseMessages;
139
- }, [responseMessages]);
140
-
141
- // State for initial messages to pass to Terminal
142
- type TerminalMessage = {
143
- text: React.ReactNode;
144
- type: "command" | "response";
145
- };
146
- const [initialTerminalMessages, setInitialTerminalMessages] = useState<
147
- TerminalMessage[] | undefined
148
- >(undefined);
149
-
150
- // Effect to set up initial messages for display
151
- useEffect(() => {
152
- if (options?.initialMessages && options.initialMessages.length > 0) {
153
- console.log(
154
- "AiTerminal: Loading initial messages",
155
- options.initialMessages,
156
- );
157
-
158
- // Format the initial messages for display
159
- const formattedMessages = options.initialMessages.map((message) => {
160
- const formattedContent =
161
- message.content
162
- ?.trim()
163
- ?.replaceAll("\n", "<br>")
164
- ?.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>") || "";
165
-
166
- return {
167
- ...message,
168
- content: message.content || "",
169
- formattedContent: formattedContent,
170
- tool_calls: message.tool_calls || [],
171
- };
172
- });
173
-
174
- console.log("AiTerminal: Formatted messages", formattedMessages);
175
-
176
- // Update the internal message states
177
- setMessages(formattedMessages);
178
- setResponseMessages(formattedMessages);
179
-
180
- // Create a response object for internal state
181
- const initialResponse: Response = {
182
- messages: formattedMessages,
183
- editOperations: [],
184
- numInputTokens: 0,
185
- numOutputTokens: 0,
186
- numCachedTokens: 0,
187
- state: "loaded",
188
- };
189
-
190
- console.log("AiTerminal: Setting response", initialResponse);
191
- setResponse(initialResponse);
192
-
193
- // Create individual Terminal messages for each conversation message
194
- const terminalMessages: TerminalMessage[] = [];
195
-
196
- formattedMessages.forEach((message) => {
197
- if (message.role === "user") {
198
- // User messages appear as commands
199
- terminalMessages.push({
200
- type: "command",
201
- text: message.content,
202
- });
203
- } else if (message.role === "assistant") {
204
- // Assistant messages appear as responses
205
- terminalMessages.push({
206
- type: "response",
207
- text: (
208
- <div
209
- dangerouslySetInnerHTML={{
210
- __html: message.formattedContent || message.content || "",
211
- }}
212
- />
213
- ),
214
- });
215
- }
216
- // Add tool calls if present
217
- if (message.tool_calls && message.tool_calls.length > 0) {
218
- message.tool_calls.forEach((toolCall) => {
219
- terminalMessages.push({
220
- type: "response",
221
- text: (
222
- <div className="text-gray-1 text-xs">
223
- 🔧 {toolCall.displayName}
224
- </div>
225
- ),
226
- });
227
- });
228
- }
229
- });
230
-
231
- setInitialTerminalMessages(terminalMessages);
232
- }
233
- }, [options?.initialMessages]);
234
-
235
- // Handle click outside for settings popover
236
- useEffect(() => {
237
- function handleClickOutside(event: MouseEvent) {
238
- if (
239
- settingsRef.current &&
240
- !settingsRef.current.contains(event.target as Node)
241
- ) {
242
- setShowSettings(false);
243
- }
244
- }
245
-
246
- if (showSettings) {
247
- document.addEventListener("click", handleClickOutside);
248
- return () => {
249
- document.removeEventListener("click", handleClickOutside);
250
- };
251
- }
252
- }, [showSettings]);
253
-
254
- function handleResponse(
255
- response: Response,
256
- terminalCallback: (text: React.ReactNode, finished: boolean) => void,
257
- isFinished: boolean,
258
- ) {
259
- const updatedMessages = response.messages;
260
-
261
- // Replace the conversation history with the authoritative response from AI
262
- if (updatedMessages && Array.isArray(updatedMessages)) {
263
- const formattedMessages = updatedMessages.map((message) => {
264
- const formattedContent =
265
- message.content
266
- ?.trim()
267
- ?.replaceAll("\n", "<br>")
268
- ?.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>") || "";
269
-
270
- return {
271
- ...message,
272
- content: message.content || "",
273
- formattedContent: formattedContent,
274
- tool_calls: message.tool_calls || [],
275
- };
276
- });
277
-
278
- // Update the messages state with the complete conversation from AI
279
- setMessages([...formattedMessages]);
280
- setResponseMessages([...formattedMessages]);
281
-
282
- terminalCallback(
283
- <AiResponseMessage
284
- messages={formattedMessages}
285
- editOperations={response.editOperations}
286
- finished={isFinished}
287
- onQuickAction={(action) => {
288
- const text = (
289
- action.prompt ||
290
- action.value ||
291
- action.label ||
292
- ""
293
- ).trim();
294
- if (!text) return;
295
- if (action.behavior === "compose") {
296
- setPrompt(text);
297
- setInputPlaceholder(action.placeholder);
298
- setTimeout(() => terminalRef.current?.focusPrompt(), 0);
299
- return;
300
- }
301
- // Submit this as a new command
302
- commandHandler(text, (node, done) => {
303
- TerminalService.emit("response", node);
304
- if (done) TerminalService.emit("response", undefined);
305
- });
306
- }}
307
- />,
308
- isFinished,
309
- );
310
- } else {
311
- // Fallback: if no messages in response, keep current state
312
- terminalCallback(
313
- <AiResponseMessage
314
- messages={messagesRef.current}
315
- editOperations={response.editOperations}
316
- finished={isFinished}
317
- onQuickAction={(action) => {
318
- const text = (
319
- action.prompt ||
320
- action.value ||
321
- action.label ||
322
- ""
323
- ).trim();
324
- if (!text) return;
325
- if (action.behavior === "compose") {
326
- setPrompt(text);
327
- setInputPlaceholder(action.placeholder);
328
- setTimeout(() => terminalRef.current?.focusPrompt(), 0);
329
- return;
330
- }
331
- commandHandler(text, (node, done) => {
332
- TerminalService.emit("response", node);
333
- if (done) TerminalService.emit("response", undefined);
334
- });
335
- }}
336
- />,
337
- isFinished,
338
- );
339
- }
340
- }
341
-
342
- async function commandHandler(
343
- text: string,
344
- callback: (text: React.ReactNode, finished: boolean) => void,
345
- ) {
346
- const userMessage = {
347
- id: crypto.randomUUID(), // Add unique id
348
- content: text,
349
- role: "user",
350
- name: "user",
351
- tool_calls: [], // Add empty toolCalls array
352
- };
353
-
354
- const context = createAiContext({ editContext: editContext! });
355
-
356
- let lastOpIndex = 0;
357
- const selectedText = editContext?.selectedRange?.text || null;
358
- if (!activeProfile || !model) return;
359
-
360
- // Build complete message history for API call
361
- const conversationHistory = [...messagesRef.current, userMessage];
362
- const shouldAddTodoFormat = /\b(to-?do|check\s*list|task\s*list)\b/i.test(
363
- text,
364
- );
365
- const todoFormatInstructions =
366
- "If you produce a to-do list, output it as a 'todo_list' JSON block. Prefer one of these two forms only, with no extra commentary before/after it: \n" +
367
- '```todo_list\n{ "title": "<optional title>", "items": [ { "text": "<task>", "done": false, "note": "<optional>" } ] }\n```\n' +
368
- "or a plain header: todo_list: { ... }. Include only fields: title (optional), items (array of {text, done?, note?}).";
369
- const systemMessages = options?.hiddenSystemPrompt
370
- ? [
371
- {
372
- role: "system",
373
- name: "system",
374
- content: options.hiddenSystemPrompt,
375
- id: crypto.randomUUID(),
376
- toolCalls: [],
377
- },
378
- ]
379
- : [];
380
- const todoSystem = shouldAddTodoFormat
381
- ? [
382
- {
383
- role: "system",
384
- name: "system",
385
- content: todoFormatInstructions,
386
- id: crypto.randomUUID(),
387
- toolCalls: [],
388
- },
389
- ]
390
- : [];
391
- const messages = [...systemMessages, ...todoSystem, ...conversationHistory];
392
-
393
- const response = await executePrompt(
394
- messages,
395
- context,
396
- {
397
- profileId: activeProfile.id,
398
- selection,
399
- selectedText,
400
- model,
401
- sessionId: editContext!.sessionId,
402
- agentId,
403
- addSelectedComponents: true,
404
- },
405
- undefined,
406
- (response: any) => {
407
- setResponse(response);
408
- handleResponse(response, callback, false);
409
- },
410
- );
411
-
412
- if (response) {
413
- handleResponse(response, callback, true);
414
- if (context.callback) context.callback(response);
415
- editContext?.requestRefresh("immediate");
416
- }
417
-
418
- // if (response?.responseText)
419
- // newMessages.push({
420
- // content: response.responseText,
421
- // role: "assistant",
422
- // name: "assistant",
423
- // });
424
-
425
- setResponse(response ? response : undefined);
426
-
427
- // setMessages(newMessages);
428
- }
429
-
430
- useEffect(() => {
431
- TerminalService.on("command", commandHandler);
432
-
433
- return () => {
434
- TerminalService.off("command", commandHandler);
435
- };
436
- }, []);
437
-
438
- return (
439
- <div
440
- className="relative flex h-full flex-1 flex-col"
441
- data-testid="ai-terminal"
442
- >
443
- <div className="relative flex-1">
444
- <div className="tour-ai-terminal absolute inset-0">
445
- <Terminal
446
- disabled={!model}
447
- ref={terminalRef}
448
- onReset={() => {
449
- setMessages([]);
450
- setResponseMessages([]);
451
- setResponse(undefined);
452
- setInitialTerminalMessages(undefined);
453
- }}
454
- initialMessages={initialTerminalMessages}
455
- infobar={
456
- response?.numInputTokens && response?.numInputTokens > 0 ? (
457
- <div
458
- className="text-right text-gray-400"
459
- style={{ fontSize: "10px" }}
460
- >
461
- Tokens in: {response?.numInputTokens?.toLocaleString()} out:{" "}
462
- {response?.numOutputTokens?.toLocaleString()}{" "}
463
- {response?.numCachedTokens
464
- ? `cached: ${response?.numCachedTokens?.toLocaleString()} `
465
- : ""}
466
- {response?.state}
467
- </div>
468
- ) : null
469
- }
470
- prompt={prompt}
471
- setPrompt={setPrompt}
472
- placeholder={inputPlaceholder}
473
- statusbar=<div className="flex flex-1 items-center justify-between gap-1">
474
- <a
475
- className="ml-1 flex cursor-pointer items-center gap-1 text-xs"
476
- onClick={() => {
477
- setShowPredefined(!showPredefined);
478
- }}
479
- >
480
- <WizardIcon className="h-5 w-5" />
481
- Predefined prompts
482
- </a>
483
- {editContext.selection?.length > 0 && (
484
- <div className="mr-2 flex items-center text-xs text-red-400">
485
- {editContext.selection.length} items selected
486
- <SimpleIconButton
487
- icon="pi pi-times"
488
- label="Clear selection"
489
- onClick={() => {
490
- editContext.select([]);
491
- }}
492
- />
493
- </div>
494
- )}
495
- {showPredefined && (
496
- <div className="absolute right-0 bottom-8 left-0 flex flex-col gap-1 overflow-y-auto bg-white p-3 pb-1 text-sm">
497
- {activeProfile &&
498
- activeProfile.prompts.map((p, index) => (
499
- <div
500
- key={index}
501
- className="mb-1 cursor-pointer rounded-lg border border-gray-200 p-1.5 text-xs text-gray-700"
502
- onClick={() => {
503
- setPrompt(p.prompt);
504
- setShowPredefined(false);
505
- }}
506
- >
507
- {p.title}
508
- </div>
509
- ))}
510
- </div>
511
- )}
512
- </div>
513
- toolbar=<div className="flex items-stretch gap-1">
514
- <div className="relative" ref={settingsRef}>
515
- <SimpleIconButton
516
- icon={<Settings size={16} strokeWidth={1} />}
517
- label="Settings"
518
- onClick={() => setShowSettings(!showSettings)}
519
- />
520
- {showSettings && (
521
- <div className="absolute top-8 right-0 z-50 flex flex-col gap-2 rounded-lg border border-gray-200 bg-white p-3 shadow-lg">
522
- <div className="flex flex-col gap-1">
523
- <label className="text-xs font-medium text-gray-700">
524
- Profile
525
- </label>
526
- <Dropdown
527
- className="text-sm"
528
- value={activeProfile}
529
- onChange={(e) => setActiveProfile(e.value)}
530
- optionLabel="name"
531
- options={profiles}
532
- />
533
- </div>
534
- {activeProfile && (
535
- <div className="flex flex-col gap-1">
536
- <label className="text-xs font-medium text-gray-700">
537
- Model
538
- </label>
539
- <Dropdown
540
- className="text-sm"
541
- value={model}
542
- onChange={(e) => setModel(e.value)}
543
- options={activeProfile.models}
544
- />
545
- </div>
546
- )}
547
- </div>
548
- )}
549
- </div>
550
- {closeButton}
551
- </div>
552
- commandHandler={(v, callback) => {
553
- commandHandler(v, callback);
554
- }}
555
- />
556
- </div>
557
- {activeProfile?.errorMessage && (
558
- <div className="absolute inset-0 grid items-center justify-center p-2 text-sm text-red-500">
559
- {activeProfile?.errorMessage}
560
- </div>
561
- )}
562
- {!model && (
563
- <div className="absolute inset-0 grid items-center justify-center text-sm text-gray-400">
564
- {!activeProfile ? "No profile selected" : "No model selected"}
565
- </div>
566
- )}
567
- </div>
568
- </div>
569
- );
570
- }
@@ -1,11 +0,0 @@
1
- import { AiTerminal } from "../ai/AiTerminal";
2
- import { createDesignerAiContext } from "./aiContext";
3
-
4
- export function ComponentDesignerAiTerminal() {
5
- return (
6
- <AiTerminal
7
- createAiContext={createDesignerAiContext}
8
- defaultProfile="Component Designer"
9
- />
10
- );
11
- }