@alpaca-editor/core 1.0.4065 → 1.0.4066
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/editor/ImageEditButton.js +10 -3
- package/dist/editor/ImageEditButton.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.d.ts +3 -2
- package/dist/editor/ai/AgentTerminal.js +386 -94
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/Agents.js +36 -19
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.d.ts +6 -1
- package/dist/editor/ai/AiResponseMessage.js +63 -3
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/AiTerminal.js +27 -2
- package/dist/editor/ai/AiTerminal.js.map +1 -1
- package/dist/editor/client/EditorClient.js +15 -0
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +2 -0
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/commands/componentCommands.js +56 -6
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/page-editor-chrome/CommentHighlighting.js +6 -4
- package/dist/editor/page-editor-chrome/CommentHighlighting.js.map +1 -1
- package/dist/editor/page-editor-chrome/CommentHighlightings.js +1 -1
- package/dist/editor/page-editor-chrome/CommentHighlightings.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +6 -8
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/reviews/Comment.js +3 -58
- package/dist/editor/reviews/Comment.js.map +1 -1
- package/dist/editor/reviews/CommentDisplayPopover.js +2 -3
- package/dist/editor/reviews/CommentDisplayPopover.js.map +1 -1
- package/dist/editor/reviews/Comments.js +4 -0
- package/dist/editor/reviews/Comments.js.map +1 -1
- package/dist/editor/reviews/commentAi.d.ts +7 -0
- package/dist/editor/reviews/commentAi.js +86 -0
- package/dist/editor/reviews/commentAi.js.map +1 -0
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/styles.css +10 -0
- package/package.json +1 -1
- package/src/editor/ImageEditButton.tsx +36 -8
- package/src/editor/ai/AgentTerminal.tsx +436 -65
- package/src/editor/ai/Agents.tsx +193 -140
- package/src/editor/ai/AiResponseMessage.tsx +106 -2
- package/src/editor/ai/AiTerminal.tsx +27 -0
- package/src/editor/client/EditorClient.tsx +23 -0
- package/src/editor/client/editContext.ts +2 -0
- package/src/editor/commands/componentCommands.tsx +60 -12
- package/src/editor/page-editor-chrome/CommentHighlighting.tsx +6 -4
- package/src/editor/page-editor-chrome/CommentHighlightings.tsx +3 -1
- package/src/editor/page-editor-chrome/FrameMenu.tsx +6 -8
- package/src/editor/reviews/Comment.tsx +4 -66
- package/src/editor/reviews/CommentDisplayPopover.tsx +2 -3
- package/src/editor/reviews/Comments.tsx +12 -0
- package/src/editor/reviews/commentAi.ts +106 -0
- package/src/revision.ts +2 -2
- package/dist/editor/ai/AiPromptPopover.d.ts +0 -7
- package/dist/editor/ai/AiPromptPopover.js +0 -111
- package/dist/editor/ai/AiPromptPopover.js.map +0 -1
- package/src/editor/ai/AiPromptPopover.tsx +0 -206
|
@@ -2,7 +2,6 @@ import { EditContextType } from "../client/editContext";
|
|
|
2
2
|
import uuid from "react-uuid";
|
|
3
3
|
import { Command, CommandContext, CommandData } from "./commands";
|
|
4
4
|
|
|
5
|
-
import { getComponentById } from "../componentTreeHelper";
|
|
6
5
|
import {
|
|
7
6
|
PlaceholderToSynchronize,
|
|
8
7
|
RemoveComponentOperation,
|
|
@@ -13,7 +12,6 @@ import { Component, ItemDescriptor, Placeholder } from "../pageModel";
|
|
|
13
12
|
import {
|
|
14
13
|
Check,
|
|
15
14
|
Copy,
|
|
16
|
-
MessageCircleMore,
|
|
17
15
|
MessageCirclePlus,
|
|
18
16
|
Palette,
|
|
19
17
|
Plus,
|
|
@@ -24,7 +22,8 @@ import {
|
|
|
24
22
|
Trash2,
|
|
25
23
|
TriangleAlert,
|
|
26
24
|
} from "lucide-react";
|
|
27
|
-
|
|
25
|
+
// Removed popover; we trigger Agents panel and focus prompt instead
|
|
26
|
+
import { startAgent, StartAgentRequest } from "../services/agentService";
|
|
28
27
|
import { showCommentPopoverAt } from "../reviews/CommentPopover";
|
|
29
28
|
|
|
30
29
|
export type ComponentCommandData = CommandData & {
|
|
@@ -138,20 +137,69 @@ function getAiCommand(
|
|
|
138
137
|
): ComponentCommand {
|
|
139
138
|
return {
|
|
140
139
|
id: "ai",
|
|
141
|
-
icon:
|
|
142
|
-
<AiPromptPopover components={components}>
|
|
143
|
-
<Sparkles size={defaultIconSize} />
|
|
144
|
-
</AiPromptPopover>
|
|
145
|
-
),
|
|
140
|
+
icon: <Sparkles size={defaultIconSize} strokeWidth={1} />,
|
|
146
141
|
label: "AI",
|
|
147
142
|
disabled: (c) => components.length === 0,
|
|
148
143
|
|
|
149
144
|
execute: async (context: CommandContext<any>) => {
|
|
150
|
-
// The AiPromptPopover handles the click interaction directly
|
|
151
|
-
// No need to execute anything here as the popover trigger handles it
|
|
152
145
|
const event = context.event!;
|
|
153
|
-
event.preventDefault();
|
|
154
|
-
event.stopPropagation();
|
|
146
|
+
if (event?.preventDefault) event.preventDefault();
|
|
147
|
+
if (event?.stopPropagation) event.stopPropagation();
|
|
148
|
+
|
|
149
|
+
// Ensure selection matches the invoked components for proper context
|
|
150
|
+
const selection = components.map((c) => c.id);
|
|
151
|
+
if (selection.length) {
|
|
152
|
+
try {
|
|
153
|
+
editContext.select(selection);
|
|
154
|
+
} catch {}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Open the Agents panel so the user can type a prompt
|
|
158
|
+
editContext.setShowAgentsPanel(true);
|
|
159
|
+
|
|
160
|
+
// Ask Agents/AgentTerminal to open a new terminal (if desired) and focus the prompt
|
|
161
|
+
// Delay slightly to ensure the panel mounts before dispatching
|
|
162
|
+
setTimeout(() => {
|
|
163
|
+
try {
|
|
164
|
+
const page = editContext.page?.item?.descriptor;
|
|
165
|
+
const pageName = editContext.contentEditorItem?.name;
|
|
166
|
+
const detail = page
|
|
167
|
+
? {
|
|
168
|
+
metadata: {
|
|
169
|
+
additionalData: {
|
|
170
|
+
context: {
|
|
171
|
+
pages: [
|
|
172
|
+
{
|
|
173
|
+
id: page.id,
|
|
174
|
+
language: page.language,
|
|
175
|
+
version: page.version,
|
|
176
|
+
name: pageName,
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
componentIds:
|
|
180
|
+
selection && selection.length ? selection : undefined,
|
|
181
|
+
field:
|
|
182
|
+
editContext.focusedField?.fieldId &&
|
|
183
|
+
editContext.focusedField?.item?.id
|
|
184
|
+
? {
|
|
185
|
+
fieldId: editContext.focusedField.fieldId,
|
|
186
|
+
itemId: editContext.focusedField.item.id,
|
|
187
|
+
name: editContext.focusedField.fieldName,
|
|
188
|
+
}
|
|
189
|
+
: undefined,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
}
|
|
194
|
+
: undefined;
|
|
195
|
+
window.dispatchEvent(
|
|
196
|
+
new CustomEvent("editor:addNewAgent", { detail } as any),
|
|
197
|
+
);
|
|
198
|
+
} catch {}
|
|
199
|
+
try {
|
|
200
|
+
window.dispatchEvent(new CustomEvent("editor:focusAgentPrompt"));
|
|
201
|
+
} catch {}
|
|
202
|
+
}, 100);
|
|
155
203
|
},
|
|
156
204
|
visibilityScopes: ["editFrame", "contextMenu"],
|
|
157
205
|
};
|
|
@@ -214,9 +214,11 @@ export function CommentHighlighting({
|
|
|
214
214
|
>
|
|
215
215
|
<CommentIcon
|
|
216
216
|
className={
|
|
217
|
-
|
|
218
|
-
? "text-
|
|
219
|
-
:
|
|
217
|
+
comment.isResolved
|
|
218
|
+
? "text-green-500 hover:text-green-600"
|
|
219
|
+
: isSelected
|
|
220
|
+
? "text-red-700 hover:text-red-800"
|
|
221
|
+
: "text-blue-500 hover:text-blue-600"
|
|
220
222
|
}
|
|
221
223
|
/>
|
|
222
224
|
</div>
|
|
@@ -232,7 +234,7 @@ export function CommentHighlighting({
|
|
|
232
234
|
? "rgba(255, 0, 0, 1)" // Darker red for selected
|
|
233
235
|
: comment.isResolved
|
|
234
236
|
? "rgba(0, 255, 0, 0.45)" // Green for resolved
|
|
235
|
-
: "rgba(
|
|
237
|
+
: "rgba(0, 0, 255, 0.45)", // Red for unresolved
|
|
236
238
|
}}
|
|
237
239
|
></div>
|
|
238
240
|
)}
|
|
@@ -322,10 +322,10 @@ export function FrameMenu({
|
|
|
322
322
|
isMultiSelected && "rounded-t-xs",
|
|
323
323
|
)}
|
|
324
324
|
style={{
|
|
325
|
-
left: componentRect.x,
|
|
326
|
-
top: componentRect.y,
|
|
327
|
-
width: componentRect.width
|
|
328
|
-
height: componentRect.height,
|
|
325
|
+
left: componentRect.x - 1,
|
|
326
|
+
top: componentRect.y - 1,
|
|
327
|
+
width: (componentRect.width ?? 0) + 2,
|
|
328
|
+
height: componentRect.height + 2,
|
|
329
329
|
zIndex: 8,
|
|
330
330
|
}}
|
|
331
331
|
data-testid="frame-menu"
|
|
@@ -339,12 +339,10 @@ export function FrameMenu({
|
|
|
339
339
|
(isHeaderWiderThanComponent ? " rounded-bl" : "")
|
|
340
340
|
}
|
|
341
341
|
style={{
|
|
342
|
-
right: "-
|
|
342
|
+
right: "-1px",
|
|
343
343
|
top: componentRect.y - 36 < 0 ? "0" : undefined,
|
|
344
344
|
bottom:
|
|
345
|
-
componentRect.y - 36 >= 0
|
|
346
|
-
? componentRect.height - 2
|
|
347
|
-
: undefined,
|
|
345
|
+
componentRect.y - 36 >= 0 ? componentRect.height : undefined,
|
|
348
346
|
zIndex: 800,
|
|
349
347
|
height: "36px",
|
|
350
348
|
}}
|
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
resolveComment,
|
|
8
8
|
unresolveComment,
|
|
9
9
|
} from "../services/reviewsService";
|
|
10
|
-
import { startAgent, StartAgentRequest } from "../services/agentService";
|
|
10
|
+
// import { startAgent, StartAgentRequest } from "../services/agentService";
|
|
11
|
+
import { openAiAgentForComment } from "./commentAi";
|
|
11
12
|
import { useDebouncedCallback } from "use-debounce";
|
|
12
13
|
import { CommentView } from "./CommentView";
|
|
13
14
|
import { CommentEditor } from "./CommentEditor";
|
|
@@ -100,71 +101,8 @@ export function Comment({
|
|
|
100
101
|
await unresolveComment(comment);
|
|
101
102
|
};
|
|
102
103
|
|
|
103
|
-
const handleAiAction = async () =>
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// Respect quota if available
|
|
107
|
-
if ((editContext as any).isQuotaExceeded) {
|
|
108
|
-
editContext.showToast?.(
|
|
109
|
-
"AI quota exceeded. Please try again later or adjust settings.",
|
|
110
|
-
);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const selectedText = (() => {
|
|
115
|
-
if (
|
|
116
|
-
typeof comment.rangeStart === "number" &&
|
|
117
|
-
typeof comment.rangeEnd === "number" &&
|
|
118
|
-
comment.fieldValue
|
|
119
|
-
) {
|
|
120
|
-
try {
|
|
121
|
-
return comment.fieldValue.substring(
|
|
122
|
-
Math.max(0, comment.rangeStart),
|
|
123
|
-
Math.max(comment.rangeStart, comment.rangeEnd),
|
|
124
|
-
);
|
|
125
|
-
} catch {
|
|
126
|
-
return undefined;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return undefined;
|
|
130
|
-
})();
|
|
131
|
-
|
|
132
|
-
const promptParts: string[] = [];
|
|
133
|
-
const text = (comment.text || "").trim();
|
|
134
|
-
if (text) promptParts.push(`Comment: "${text}"`);
|
|
135
|
-
if (comment.fieldName) promptParts.push(`Field: ${comment.fieldName}`);
|
|
136
|
-
if (comment.itemName) promptParts.push(`Item: ${comment.itemName}`);
|
|
137
|
-
if (selectedText) promptParts.push(`Selected text: "${selectedText}"`);
|
|
138
|
-
|
|
139
|
-
const initialPrompt =
|
|
140
|
-
promptParts.length > 0
|
|
141
|
-
? `Please help resolve this review comment. ${promptParts.join(" | ")}`
|
|
142
|
-
: "Please help resolve this review comment.";
|
|
143
|
-
|
|
144
|
-
const agentId = crypto.randomUUID();
|
|
145
|
-
|
|
146
|
-
const request: StartAgentRequest = {
|
|
147
|
-
agentId,
|
|
148
|
-
message: initialPrompt,
|
|
149
|
-
sessionId: editContext.sessionId,
|
|
150
|
-
profileId: "Editor",
|
|
151
|
-
itemid: comment.mainItemId || editContext.currentItemDescriptor?.id || "",
|
|
152
|
-
language: comment.language,
|
|
153
|
-
version: comment.version,
|
|
154
|
-
selectedText: selectedText,
|
|
155
|
-
addContextContent: true,
|
|
156
|
-
addSelectedComponents: false,
|
|
157
|
-
profile: "Editor",
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
try {
|
|
161
|
-
editContext.setShowAgentsPanel(true);
|
|
162
|
-
await startAgent(request);
|
|
163
|
-
} catch (e) {
|
|
164
|
-
console.error("Failed to start agent for comment:", e);
|
|
165
|
-
editContext.showToast?.("Failed to start AI agent for this comment.");
|
|
166
|
-
}
|
|
167
|
-
};
|
|
104
|
+
const handleAiAction = async () =>
|
|
105
|
+
openAiAgentForComment(comment, editContext);
|
|
168
106
|
|
|
169
107
|
if (isEditing) {
|
|
170
108
|
return (
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from "../services/reviewsService";
|
|
20
20
|
import { CommentView } from "./CommentView";
|
|
21
21
|
import { CommentEditor } from "./CommentEditor";
|
|
22
|
+
import { openAiAgentForComment } from "./commentAi";
|
|
22
23
|
|
|
23
24
|
interface CommentDisplayPopoverProps {
|
|
24
25
|
comment: Comment;
|
|
@@ -103,9 +104,7 @@ export function CommentDisplayPopover({
|
|
|
103
104
|
onCommentUpdated?.();
|
|
104
105
|
};
|
|
105
106
|
|
|
106
|
-
const handleAiAction = () =>
|
|
107
|
-
// TODO: Implement AI action
|
|
108
|
-
};
|
|
107
|
+
const handleAiAction = () => openAiAgentForComment(comment, editContext);
|
|
109
108
|
|
|
110
109
|
const handleEditorKeyDown = (e: React.KeyboardEvent) => {
|
|
111
110
|
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
|
@@ -122,6 +122,18 @@ export function Comments() {
|
|
|
122
122
|
editContext?.setShowSuggestedEdits((x) => !x);
|
|
123
123
|
}}
|
|
124
124
|
/>
|
|
125
|
+
<SimpleIconButton
|
|
126
|
+
selected={!!editContext?.showResolvedComments}
|
|
127
|
+
icon={<CheckCircle2 size={16} className="p-0.5" />}
|
|
128
|
+
label={
|
|
129
|
+
editContext?.showResolvedComments
|
|
130
|
+
? "Hide Resolved Comments"
|
|
131
|
+
: "Show Resolved Comments"
|
|
132
|
+
}
|
|
133
|
+
onClick={() => {
|
|
134
|
+
editContext?.setShowResolvedComments((x) => !x);
|
|
135
|
+
}}
|
|
136
|
+
/>
|
|
125
137
|
{editContext?.showSuggestedEdits && (
|
|
126
138
|
<SimpleIconButton
|
|
127
139
|
selected={editContext?.showSuggestedEditsDiff}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Comment as CommentType } from "../../types";
|
|
2
|
+
import { EditContextType } from "../client/editContext";
|
|
3
|
+
import { AgentMetadata } from "../services/agentService";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Opens the Agents panel and seeds it with context from a review comment.
|
|
7
|
+
* Safe to call with an undefined editContext; it will no-op.
|
|
8
|
+
*/
|
|
9
|
+
export function openAiAgentForComment(
|
|
10
|
+
comment: CommentType,
|
|
11
|
+
editContext?: EditContextType,
|
|
12
|
+
): void {
|
|
13
|
+
if (!editContext) return;
|
|
14
|
+
|
|
15
|
+
// Respect quota if available
|
|
16
|
+
if (editContext.isQuotaExceeded) {
|
|
17
|
+
editContext.showToast?.(
|
|
18
|
+
"AI quota exceeded. Please try again later or adjust settings.",
|
|
19
|
+
);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const selectedText = (() => {
|
|
24
|
+
if (
|
|
25
|
+
typeof comment.rangeStart === "number" &&
|
|
26
|
+
typeof comment.rangeEnd === "number" &&
|
|
27
|
+
comment.fieldValue
|
|
28
|
+
) {
|
|
29
|
+
try {
|
|
30
|
+
return comment.fieldValue.substring(
|
|
31
|
+
Math.max(0, comment.rangeStart),
|
|
32
|
+
Math.max(comment.rangeStart, comment.rangeEnd),
|
|
33
|
+
);
|
|
34
|
+
} catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
})();
|
|
40
|
+
|
|
41
|
+
const promptParts: string[] = [];
|
|
42
|
+
const text = (comment.text || "").trim();
|
|
43
|
+
if (text) promptParts.push(`Comment: "${text}"`);
|
|
44
|
+
if (selectedText) promptParts.push(`Selected text: "${selectedText}"`);
|
|
45
|
+
|
|
46
|
+
const initialPrompt =
|
|
47
|
+
promptParts.length > 0
|
|
48
|
+
? `Please help resolve this review comment. ${promptParts.join(" | ")}`
|
|
49
|
+
: "Please help resolve this review comment.";
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
editContext.setShowAgentsPanel(true);
|
|
53
|
+
|
|
54
|
+
const initialMetadata: AgentMetadata = {
|
|
55
|
+
additionalData: {
|
|
56
|
+
initialPrompt,
|
|
57
|
+
context: {
|
|
58
|
+
pages: [
|
|
59
|
+
{
|
|
60
|
+
id:
|
|
61
|
+
(comment as any).mainItemId ||
|
|
62
|
+
editContext.currentItemDescriptor?.id!,
|
|
63
|
+
language: comment.language,
|
|
64
|
+
version: comment.version,
|
|
65
|
+
name: editContext.contentEditorItem?.name,
|
|
66
|
+
} as any,
|
|
67
|
+
],
|
|
68
|
+
componentIds:
|
|
69
|
+
editContext.selection && editContext.selection.length
|
|
70
|
+
? editContext.selection
|
|
71
|
+
: undefined,
|
|
72
|
+
field:
|
|
73
|
+
comment.fieldId && comment.itemId
|
|
74
|
+
? {
|
|
75
|
+
fieldId: comment.fieldId,
|
|
76
|
+
itemId: comment.itemId,
|
|
77
|
+
name: comment.fieldName,
|
|
78
|
+
}
|
|
79
|
+
: undefined,
|
|
80
|
+
comment: {
|
|
81
|
+
id: comment.id,
|
|
82
|
+
text: comment.text,
|
|
83
|
+
fieldName: comment.fieldName,
|
|
84
|
+
itemName: comment.itemName,
|
|
85
|
+
author: comment.author,
|
|
86
|
+
selectedText: selectedText,
|
|
87
|
+
rangeStart: comment.rangeStart,
|
|
88
|
+
rangeEnd: comment.rangeEnd,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
} as any;
|
|
93
|
+
|
|
94
|
+
// Ask Agents UI to open a new terminal seeded with this metadata
|
|
95
|
+
try {
|
|
96
|
+
window.dispatchEvent(
|
|
97
|
+
new CustomEvent("editor:addNewAgent", {
|
|
98
|
+
detail: { metadata: initialMetadata },
|
|
99
|
+
} as any),
|
|
100
|
+
);
|
|
101
|
+
} catch {}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
console.error("Failed to start agent for comment:", e);
|
|
104
|
+
editContext.showToast?.("Failed to start AI agent for this comment.");
|
|
105
|
+
}
|
|
106
|
+
}
|
package/src/revision.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = "1.0.
|
|
2
|
-
export const buildDate = "2025-08-
|
|
1
|
+
export const version = "1.0.4066";
|
|
2
|
+
export const buildDate = "2025-08-26 01:45:51";
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Component } from "../pageModel";
|
|
2
|
-
interface AiPromptPopoverProps {
|
|
3
|
-
children: React.ReactNode;
|
|
4
|
-
components?: Component[];
|
|
5
|
-
}
|
|
6
|
-
export declare function AiPromptPopover({ children, components, }: AiPromptPopoverProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
export {};
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import { Sparkles, Send } from "lucide-react";
|
|
5
|
-
import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
|
|
6
|
-
import { Button } from "../../components/ui/button";
|
|
7
|
-
import { Textarea } from "../../components/ui/textarea";
|
|
8
|
-
import { useEditContext } from "../client/editContext";
|
|
9
|
-
import { startAgent } from "../services/agentService";
|
|
10
|
-
import { createEditorAiContext } from "./editorAiContext";
|
|
11
|
-
export function AiPromptPopover({ children, components = [], }) {
|
|
12
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
13
|
-
const [prompt, setPrompt] = useState("");
|
|
14
|
-
const editContext = useEditContext();
|
|
15
|
-
const handleSubmit = async () => {
|
|
16
|
-
if (!prompt.trim())
|
|
17
|
-
return;
|
|
18
|
-
// Close the popover
|
|
19
|
-
setIsOpen(false);
|
|
20
|
-
// Create comprehensive AI options with component context
|
|
21
|
-
let finalPrompt = prompt.trim();
|
|
22
|
-
let hiddenSystemPrompt;
|
|
23
|
-
if (components.length > 0) {
|
|
24
|
-
// Create detailed component context for the agent
|
|
25
|
-
const componentInfo = components
|
|
26
|
-
.map((comp) => {
|
|
27
|
-
const componentType = comp.type || comp.name || "Unknown";
|
|
28
|
-
const componentId = comp.id;
|
|
29
|
-
const hasContent = comp.items && comp.items.length > 0;
|
|
30
|
-
return `- ${componentType} (ID: ${componentId})${hasContent ? " with data" : " (empty)"}`;
|
|
31
|
-
})
|
|
32
|
-
.join("\n");
|
|
33
|
-
finalPrompt = `I'm working with the following ${components.length === 1 ? "component" : "components"}:
|
|
34
|
-
${componentInfo}
|
|
35
|
-
|
|
36
|
-
User request: ${prompt.trim()}`;
|
|
37
|
-
// Add hidden system prompt with component details for agent context
|
|
38
|
-
const componentDetails = components.map((comp) => ({
|
|
39
|
-
id: comp.id,
|
|
40
|
-
name: comp.name,
|
|
41
|
-
type: comp.type,
|
|
42
|
-
renderingId: comp.rendering?.id,
|
|
43
|
-
items: comp.items?.length || 0,
|
|
44
|
-
placeholder: comp.parentPlaceholder?.name,
|
|
45
|
-
isShared: comp.isShared,
|
|
46
|
-
}));
|
|
47
|
-
hiddenSystemPrompt = `Working with components: ${JSON.stringify(componentDetails, null, 2)}`;
|
|
48
|
-
}
|
|
49
|
-
try {
|
|
50
|
-
await startAgentExecution(finalPrompt, hiddenSystemPrompt);
|
|
51
|
-
// Switch to agents view after agent has been created so it appears on initial load
|
|
52
|
-
editContext?.switchView("agents");
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
console.error("Failed to start agent:", error);
|
|
56
|
-
}
|
|
57
|
-
// Reset the prompt
|
|
58
|
-
setPrompt("");
|
|
59
|
-
};
|
|
60
|
-
const startAgentExecution = async (initialPrompt, hiddenSystemPrompt) => {
|
|
61
|
-
if (!editContext)
|
|
62
|
-
return;
|
|
63
|
-
if (!editContext.currentItemDescriptor?.id) {
|
|
64
|
-
console.error("Cannot start agent: no current item selected");
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
const newAgentId = crypto.randomUUID();
|
|
68
|
-
const userMessage = {
|
|
69
|
-
id: crypto.randomUUID(),
|
|
70
|
-
content: initialPrompt,
|
|
71
|
-
role: "user",
|
|
72
|
-
name: "user",
|
|
73
|
-
};
|
|
74
|
-
const messages = [
|
|
75
|
-
...(hiddenSystemPrompt
|
|
76
|
-
? [
|
|
77
|
-
{
|
|
78
|
-
role: "system",
|
|
79
|
-
name: "system",
|
|
80
|
-
content: hiddenSystemPrompt,
|
|
81
|
-
id: crypto.randomUUID(),
|
|
82
|
-
},
|
|
83
|
-
]
|
|
84
|
-
: []),
|
|
85
|
-
userMessage,
|
|
86
|
-
];
|
|
87
|
-
const aiContext = createEditorAiContext({ editContext });
|
|
88
|
-
const startRequest = {
|
|
89
|
-
agentId: newAgentId,
|
|
90
|
-
message: initialPrompt,
|
|
91
|
-
sessionId: editContext.sessionId,
|
|
92
|
-
profileId: "Editor",
|
|
93
|
-
itemid: editContext.currentItemDescriptor.id,
|
|
94
|
-
language: editContext.currentItemDescriptor?.language || "en",
|
|
95
|
-
version: editContext.currentItemDescriptor?.version || 1,
|
|
96
|
-
selection: components?.map((c) => c.id),
|
|
97
|
-
addSelectedComponents: components?.length > 0,
|
|
98
|
-
profile: "Editor",
|
|
99
|
-
};
|
|
100
|
-
await startAgent(startRequest);
|
|
101
|
-
// Agents view will reflect the new agent via its own refresh mechanisms
|
|
102
|
-
};
|
|
103
|
-
const handleKeyDown = (e) => {
|
|
104
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
105
|
-
e.preventDefault();
|
|
106
|
-
handleSubmit();
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
return (_jsxs(Popover, { open: isOpen, onOpenChange: setIsOpen, enableIframeClickDetection: false, children: [_jsx(PopoverTrigger, { asChild: true, children: children }), _jsx(PopoverContent, { className: "w-96 p-4", side: "bottom", align: "start", onMouseDown: (e) => e.stopPropagation(), onClick: (e) => e.stopPropagation(), children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Sparkles, { size: 16, strokeWidth: 1, className: "text-blue-500" }), _jsx("h3", { className: "font-medium", children: "AI Assistant" })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("label", { htmlFor: "ai-prompt", className: "text-sm text-gray-700", children: ["What would you like AI to help you with?", components.length > 0 && (_jsxs("span", { className: "mt-1 block text-xs text-gray-500", children: ["Working with ", components.length, " selected component", components.length === 1 ? "" : "s"] }))] }), _jsx(Textarea, { id: "ai-prompt", value: prompt, onChange: (e) => setPrompt(e.target.value), onKeyDown: handleKeyDown, placeholder: "Enter your prompt here...", className: "mt-2 resize-none", rows: 3, autoFocus: true })] }), _jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { variant: "outline", size: "sm", onClick: () => setIsOpen(false), children: "Cancel" }), _jsxs(Button, { size: "sm", onClick: handleSubmit, disabled: !prompt.trim(), className: "flex items-center gap-1", children: [_jsx(Send, { size: 14, strokeWidth: 1 }), "Start Agent"] })] })] }) })] }));
|
|
110
|
-
}
|
|
111
|
-
//# sourceMappingURL=AiPromptPopover.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AiPromptPopover.js","sourceRoot":"","sources":["../../../src/editor/ai/AiPromptPopover.tsx"],"names":[],"mappings":"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"}
|