@alpaca-editor/core 1.0.3832 → 1.0.3833
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/config/config.js +17 -0
- package/dist/config/config.js.map +1 -1
- package/dist/editor/ContentTree.js +0 -1
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.d.ts +5 -6
- package/dist/editor/ai/AiResponseMessage.js +8 -6
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/AiTerminal.d.ts +13 -3
- package/dist/editor/ai/AiTerminal.js +107 -71
- package/dist/editor/ai/AiTerminal.js.map +1 -1
- package/dist/editor/ai/AiToolCall.d.ts +3 -7
- package/dist/editor/ai/AiToolCall.js +15 -3
- package/dist/editor/ai/AiToolCall.js.map +1 -1
- package/dist/editor/ai/GhostWriter.d.ts +1 -0
- package/dist/editor/ai/GhostWriter.js +307 -0
- package/dist/editor/ai/GhostWriter.js.map +1 -0
- package/dist/editor/client/EditorClient.js +3 -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/media-selector/AiImageSearch.js +2 -2
- package/dist/editor/media-selector/AiImageSearch.js.map +1 -1
- package/dist/editor/media-selector/AiImageSearchPrompt.js +2 -2
- package/dist/editor/media-selector/AiImageSearchPrompt.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/InlineEditor.js +124 -11
- package/dist/editor/page-editor-chrome/InlineEditor.js.map +1 -1
- package/dist/editor/page-editor-chrome/useInlineAICompletion.d.ts +7 -0
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js +600 -0
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -0
- package/dist/editor/page-viewer/PageViewer.js +6 -1
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +0 -1
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +6 -1
- package/dist/editor/services/aiService.js +2 -3
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/page-wizard/steps/CreatePage.js +5 -2
- package/dist/page-wizard/steps/CreatePage.js.map +1 -1
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.js +2 -1
- package/dist/page-wizard/steps/CreatePageAndLayoutStep.js.map +1 -1
- package/dist/page-wizard/steps/ImagesStep.js +1 -3
- package/dist/page-wizard/steps/ImagesStep.js.map +1 -1
- package/dist/page-wizard/steps/LayoutStep.js +5 -5
- package/dist/page-wizard/steps/LayoutStep.js.map +1 -1
- package/dist/page-wizard/steps/SelectStep.js +5 -5
- package/dist/page-wizard/steps/SelectStep.js.map +1 -1
- package/dist/styles.css +9 -0
- package/package.json +1 -1
- package/src/config/config.tsx +20 -2
- package/src/editor/ContentTree.tsx +0 -2
- package/src/editor/ai/AiResponseMessage.tsx +43 -19
- package/src/editor/ai/AiTerminal.tsx +153 -105
- package/src/editor/ai/AiToolCall.tsx +37 -21
- package/src/editor/ai/GhostWriter.tsx +432 -0
- package/src/editor/client/EditorClient.tsx +4 -0
- package/src/editor/client/editContext.ts +3 -0
- package/src/editor/media-selector/AiImageSearch.tsx +8 -9
- package/src/editor/media-selector/AiImageSearchPrompt.tsx +4 -5
- package/src/editor/page-editor-chrome/FrameMenu.tsx +1 -0
- package/src/editor/page-editor-chrome/InlineEditor.tsx +177 -18
- package/src/editor/page-editor-chrome/useInlineAICompletion.tsx +734 -0
- package/src/editor/page-viewer/PageViewer.tsx +21 -6
- package/src/editor/page-viewer/PageViewerFrame.tsx +0 -1
- package/src/editor/services/aiService.ts +10 -6
- package/src/page-wizard/steps/CreatePage.tsx +21 -26
- package/src/page-wizard/steps/CreatePageAndLayoutStep.tsx +2 -2
- package/src/page-wizard/steps/ImagesStep.tsx +2 -5
- package/src/page-wizard/steps/LayoutStep.tsx +12 -13
- package/src/page-wizard/steps/SelectStep.tsx +12 -13
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { useState } from "react";
|
|
2
|
-
|
|
3
|
-
import { EditOperation } from "../../types";
|
|
2
|
+
|
|
4
3
|
import { useEditContext } from "../client/editContext";
|
|
4
|
+
import { EditOperation } from "@/types";
|
|
5
|
+
import { Message } from "./AiTerminal";
|
|
6
|
+
import { AiToolCall } from "./AiToolCall";
|
|
5
7
|
|
|
6
8
|
export function AiResponseMessage({
|
|
7
|
-
|
|
8
|
-
toolcalls,
|
|
9
|
-
editOperations,
|
|
9
|
+
messages,
|
|
10
10
|
finished,
|
|
11
|
+
editOperations,
|
|
11
12
|
}: {
|
|
12
|
-
|
|
13
|
-
toolcalls: ToolCall[];
|
|
14
|
-
editOperations: EditOperation[];
|
|
13
|
+
messages: Message[];
|
|
15
14
|
finished: boolean;
|
|
15
|
+
editOperations: EditOperation[];
|
|
16
16
|
}) {
|
|
17
17
|
const editContext = useEditContext();
|
|
18
18
|
if (!editContext) return <></>;
|
|
19
19
|
|
|
20
|
-
const [showFunctions, setShowFunctions] = useState(false);
|
|
20
|
+
// const [showFunctions, setShowFunctions] = useState(false);
|
|
21
21
|
const [changesRejected, setChangesRejected] = useState<boolean | undefined>(
|
|
22
|
-
undefined
|
|
22
|
+
undefined,
|
|
23
23
|
);
|
|
24
24
|
|
|
25
25
|
const reversedEditOperations = [...editOperations].reverse();
|
|
@@ -29,41 +29,65 @@ export function AiResponseMessage({
|
|
|
29
29
|
reversedEditOperations.find(
|
|
30
30
|
(x, index) =>
|
|
31
31
|
editContext.editHistory[index]?.id !== x.id ||
|
|
32
|
-
!editContext.editHistory[index]?.canUndo
|
|
32
|
+
!editContext.editHistory[index]?.canUndo,
|
|
33
33
|
) === undefined;
|
|
34
34
|
|
|
35
35
|
return (
|
|
36
36
|
<div>
|
|
37
|
-
|
|
37
|
+
{messages
|
|
38
|
+
.filter((x) => x.role !== "tool")
|
|
39
|
+
.map((message, index) => (
|
|
40
|
+
<div key={index}>
|
|
41
|
+
<div
|
|
42
|
+
dangerouslySetInnerHTML={{
|
|
43
|
+
__html: message.formattedContent || message.content || "",
|
|
44
|
+
}}
|
|
45
|
+
/>
|
|
46
|
+
{message.tool_calls && message.tool_calls.length > 0 && (
|
|
47
|
+
<div className="text-xs text-gray-400">
|
|
48
|
+
{message.tool_calls.map((x, index) => (
|
|
49
|
+
<AiToolCall
|
|
50
|
+
toolCall={x}
|
|
51
|
+
key={index}
|
|
52
|
+
result={messages.find(
|
|
53
|
+
(m) => m.role === "tool" && m.tool_call_id === x.id,
|
|
54
|
+
)}
|
|
55
|
+
/>
|
|
56
|
+
))}
|
|
57
|
+
</div>
|
|
58
|
+
)}
|
|
59
|
+
</div>
|
|
60
|
+
))}
|
|
61
|
+
{/* <div
|
|
38
62
|
dangerouslySetInnerHTML={{
|
|
39
63
|
__html: responseText.replaceAll("\\n", "<br>"),
|
|
40
64
|
}}
|
|
41
65
|
/>
|
|
42
66
|
{toolcalls.length > 0 && (
|
|
43
67
|
<div
|
|
44
|
-
className="
|
|
68
|
+
className="mt-1 flex cursor-pointer items-center gap-1 text-xs text-gray-400"
|
|
45
69
|
onClick={() => setShowFunctions(!showFunctions)}
|
|
46
70
|
>
|
|
47
71
|
<i className="pi pi-wrench text-xs" /> Tool calls
|
|
48
72
|
</div>
|
|
49
|
-
)}
|
|
73
|
+
)} */}
|
|
50
74
|
|
|
51
|
-
{showFunctions && (
|
|
75
|
+
{/* {showFunctions && (
|
|
52
76
|
<div className="text-xs text-gray-400">
|
|
53
77
|
{toolcalls.map((x, index) => (
|
|
54
78
|
<AiToolCall toolCall={x} key={index} />
|
|
55
79
|
))}
|
|
56
80
|
</div>
|
|
57
|
-
)}
|
|
81
|
+
)} */}
|
|
58
82
|
|
|
59
83
|
{finished && editOperations.length > 0 && (
|
|
60
|
-
<div className="
|
|
61
|
-
<div className="
|
|
84
|
+
<div className="my-2 flex items-center gap-2">
|
|
85
|
+
<div className="tour-ai-response-message-changes text-xs">
|
|
62
86
|
{editOperations.length} changes
|
|
63
87
|
</div>
|
|
64
88
|
{canReject && !changesRejected && (
|
|
65
89
|
<div
|
|
66
|
-
className="
|
|
90
|
+
className="flex cursor-pointer items-center gap-1 text-xs text-red-500"
|
|
67
91
|
onClick={async () => {
|
|
68
92
|
await editContext?.operations.undo(editOperations.length);
|
|
69
93
|
setChangesRejected(true);
|
|
@@ -19,29 +19,34 @@ import {
|
|
|
19
19
|
} from "../../types";
|
|
20
20
|
import { SimpleIconButton } from "../ui/SimpleIconButton";
|
|
21
21
|
|
|
22
|
-
type Message = {
|
|
23
|
-
content: string;
|
|
24
|
-
name: string;
|
|
25
|
-
role: string;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
22
|
type Response = {
|
|
29
|
-
|
|
23
|
+
messages: Message[];
|
|
30
24
|
editOperations: EditOperation[];
|
|
31
25
|
numInputTokens: number;
|
|
32
26
|
numOutputTokens: number;
|
|
33
27
|
numCachedTokens: number;
|
|
34
|
-
toolCalls?: ToolCall[];
|
|
35
28
|
state: string;
|
|
36
29
|
};
|
|
37
30
|
|
|
38
|
-
type ToolCall = {
|
|
31
|
+
export type ToolCall = {
|
|
32
|
+
id: string;
|
|
33
|
+
displayName: string;
|
|
39
34
|
function: {
|
|
40
35
|
name: string;
|
|
41
36
|
arguments: string;
|
|
42
37
|
};
|
|
43
38
|
};
|
|
44
39
|
|
|
40
|
+
export type Message = {
|
|
41
|
+
id: number;
|
|
42
|
+
content: string;
|
|
43
|
+
formattedContent?: string;
|
|
44
|
+
name: string;
|
|
45
|
+
role: string;
|
|
46
|
+
tool_calls?: ToolCall[];
|
|
47
|
+
tool_call_id?: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
45
50
|
export type AiContext = {
|
|
46
51
|
promptData: any;
|
|
47
52
|
endpoint: string;
|
|
@@ -78,6 +83,7 @@ export function AiTerminal({
|
|
|
78
83
|
const [initialPromptExecuted, setInitialPromptExecuted] = useState(false);
|
|
79
84
|
const selection = editContext.selection;
|
|
80
85
|
const terminalRef = useRef<{ submit: () => void }>(null);
|
|
86
|
+
const [responseMessages, setResponseMessages] = useState<Message[]>([]);
|
|
81
87
|
|
|
82
88
|
useEffect(() => {
|
|
83
89
|
if (options?.initialPrompt && !initialPromptExecuted && model) {
|
|
@@ -111,8 +117,70 @@ export function AiTerminal({
|
|
|
111
117
|
|
|
112
118
|
const messagesRef = useRef(messages);
|
|
113
119
|
useEffect(() => {
|
|
114
|
-
messagesRef.current =
|
|
115
|
-
}, [
|
|
120
|
+
messagesRef.current = responseMessages;
|
|
121
|
+
}, [responseMessages]);
|
|
122
|
+
|
|
123
|
+
function handleResponse(
|
|
124
|
+
response: Response,
|
|
125
|
+
terminalCallback: (text: React.ReactNode, finished: boolean) => void,
|
|
126
|
+
isFinished: boolean,
|
|
127
|
+
) {
|
|
128
|
+
const currentMessages = messagesRef.current;
|
|
129
|
+
const updatedMessages = response.messages;
|
|
130
|
+
|
|
131
|
+
// Merge updatedMessages into currentMessages if they exist
|
|
132
|
+
if (updatedMessages && Array.isArray(updatedMessages)) {
|
|
133
|
+
// Ensure each message has the required properties
|
|
134
|
+
updatedMessages.forEach((message) => {
|
|
135
|
+
const existingMessageIndex = currentMessages.findIndex(
|
|
136
|
+
(m) => m.id === message.id,
|
|
137
|
+
);
|
|
138
|
+
const formattedContent = message.content
|
|
139
|
+
.trim()
|
|
140
|
+
.replaceAll("\n", "<br>")
|
|
141
|
+
?.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>");
|
|
142
|
+
|
|
143
|
+
if (existingMessageIndex !== -1) {
|
|
144
|
+
// Update existing message
|
|
145
|
+
currentMessages[existingMessageIndex] = {
|
|
146
|
+
...currentMessages[existingMessageIndex],
|
|
147
|
+
...message,
|
|
148
|
+
content: message.content,
|
|
149
|
+
formattedContent: formattedContent,
|
|
150
|
+
tool_calls:
|
|
151
|
+
message.tool_calls ||
|
|
152
|
+
currentMessages[existingMessageIndex]?.tool_calls ||
|
|
153
|
+
[],
|
|
154
|
+
};
|
|
155
|
+
} else {
|
|
156
|
+
// Add new message
|
|
157
|
+
currentMessages.push({
|
|
158
|
+
...message,
|
|
159
|
+
content: formattedContent,
|
|
160
|
+
tool_calls: message.tool_calls || [], // Ensure toolCalls exists
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Update the messages state
|
|
167
|
+
setMessages([...currentMessages]);
|
|
168
|
+
setResponseMessages([...currentMessages]);
|
|
169
|
+
console.log(
|
|
170
|
+
"response",
|
|
171
|
+
messagesRef.current,
|
|
172
|
+
response.messages,
|
|
173
|
+
currentMessages,
|
|
174
|
+
);
|
|
175
|
+
terminalCallback(
|
|
176
|
+
<AiResponseMessage
|
|
177
|
+
messages={currentMessages}
|
|
178
|
+
editOperations={response.editOperations}
|
|
179
|
+
finished={isFinished}
|
|
180
|
+
/>,
|
|
181
|
+
isFinished,
|
|
182
|
+
);
|
|
183
|
+
}
|
|
116
184
|
|
|
117
185
|
async function commandHandler(
|
|
118
186
|
text: string,
|
|
@@ -120,7 +188,13 @@ export function AiTerminal({
|
|
|
120
188
|
) {
|
|
121
189
|
const newMessages = [
|
|
122
190
|
...messagesRef.current,
|
|
123
|
-
{
|
|
191
|
+
{
|
|
192
|
+
id: Date.now(), // Add unique id
|
|
193
|
+
content: text,
|
|
194
|
+
role: "user",
|
|
195
|
+
name: "user",
|
|
196
|
+
tool_calls: [], // Add empty toolCalls array
|
|
197
|
+
},
|
|
124
198
|
];
|
|
125
199
|
|
|
126
200
|
const context = createAiContext({ editContext });
|
|
@@ -129,6 +203,8 @@ export function AiTerminal({
|
|
|
129
203
|
const selectedText = editContext?.selectedRange?.text || null;
|
|
130
204
|
if (!activeProfile || !model) return;
|
|
131
205
|
|
|
206
|
+
setResponseMessages([]);
|
|
207
|
+
|
|
132
208
|
const messages = [
|
|
133
209
|
...(options?.hiddenSystemPrompt
|
|
134
210
|
? [
|
|
@@ -136,6 +212,8 @@ export function AiTerminal({
|
|
|
136
212
|
role: "system",
|
|
137
213
|
name: "system",
|
|
138
214
|
content: options.hiddenSystemPrompt,
|
|
215
|
+
id: 0, // System message id
|
|
216
|
+
toolCalls: [],
|
|
139
217
|
},
|
|
140
218
|
]
|
|
141
219
|
: []),
|
|
@@ -155,61 +233,61 @@ export function AiTerminal({
|
|
|
155
233
|
(response: any) => {
|
|
156
234
|
setResponse(response);
|
|
157
235
|
handleResponse(response, callback, false);
|
|
158
|
-
if (response.editOperations.length) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
}
|
|
236
|
+
// if (response.editOperations.length) {
|
|
237
|
+
// if (!editContext) return;
|
|
238
|
+
|
|
239
|
+
// const newOps = response.editOperations.slice(lastOpIndex);
|
|
240
|
+
|
|
241
|
+
// if (newOps.length === 0) return;
|
|
242
|
+
|
|
243
|
+
// const isEditTextFieldOp = (op: EditOperation) => {
|
|
244
|
+
// if (op.type !== "edit-field") return false;
|
|
245
|
+
// const editFieldOp = op as EditFieldOperation;
|
|
246
|
+
// return (
|
|
247
|
+
// editFieldOp.fieldType &&
|
|
248
|
+
// editFieldOp.fieldType.indexOf("text") !== -1
|
|
249
|
+
// );
|
|
250
|
+
// };
|
|
251
|
+
|
|
252
|
+
// const isEditTextField = isEditTextFieldOp(newOps[newOps.length - 1]);
|
|
253
|
+
|
|
254
|
+
// if (isEditTextField) lastOpIndex = response.editOperations.length - 1;
|
|
255
|
+
// else lastOpIndex = response.editOperations.length;
|
|
256
|
+
|
|
257
|
+
// newOps.forEach((op: EditOperation) => {
|
|
258
|
+
// if (isEditTextFieldOp(op)) {
|
|
259
|
+
// const editFieldOp = op as EditFieldOperation;
|
|
260
|
+
|
|
261
|
+
// if (editFieldOp.itemId) {
|
|
262
|
+
// const fieldDescriptor = {
|
|
263
|
+
// item: {
|
|
264
|
+
// ...editFieldOp.mainItem,
|
|
265
|
+
// id: editFieldOp.itemId,
|
|
266
|
+
// },
|
|
267
|
+
// fieldId: editFieldOp.fieldId,
|
|
268
|
+
// };
|
|
269
|
+
// editContext.itemsRepository.updateFieldValue(
|
|
270
|
+
// fieldDescriptor,
|
|
271
|
+
// editFieldOp.user ?? { name: "unknown", ai: false },
|
|
272
|
+
// false,
|
|
273
|
+
// editFieldOp.value,
|
|
274
|
+
// );
|
|
275
|
+
|
|
276
|
+
// editContext.select([editFieldOp.itemId]);
|
|
277
|
+
// editContext.setScrollIntoView(editFieldOp.itemId);
|
|
278
|
+
|
|
279
|
+
// editContext?.setFocusedField(fieldDescriptor, false);
|
|
280
|
+
// }
|
|
281
|
+
// } else {
|
|
282
|
+
// const addOp = op as AddComponentOperation;
|
|
283
|
+
// if (op.type === "add-component" && addOp.componentId) {
|
|
284
|
+
// const newComponentId = addOp.componentId;
|
|
285
|
+
// editContext.select([newComponentId]);
|
|
286
|
+
// editContext.setScrollIntoView(newComponentId);
|
|
287
|
+
// }
|
|
288
|
+
// }
|
|
289
|
+
// });
|
|
290
|
+
// }
|
|
213
291
|
},
|
|
214
292
|
);
|
|
215
293
|
|
|
@@ -219,15 +297,16 @@ export function AiTerminal({
|
|
|
219
297
|
editContext?.requestRefresh("immediate");
|
|
220
298
|
}
|
|
221
299
|
|
|
222
|
-
if (response?.responseText)
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
300
|
+
// if (response?.responseText)
|
|
301
|
+
// newMessages.push({
|
|
302
|
+
// content: response.responseText,
|
|
303
|
+
// role: "assistant",
|
|
304
|
+
// name: "assistant",
|
|
305
|
+
// });
|
|
228
306
|
|
|
229
307
|
setResponse(response ? response : undefined);
|
|
230
|
-
|
|
308
|
+
|
|
309
|
+
// setMessages(newMessages);
|
|
231
310
|
}
|
|
232
311
|
|
|
233
312
|
useEffect(() => {
|
|
@@ -424,34 +503,3 @@ async function executePrompt(
|
|
|
424
503
|
|
|
425
504
|
return result;
|
|
426
505
|
}
|
|
427
|
-
|
|
428
|
-
function handleResponse(
|
|
429
|
-
response: any,
|
|
430
|
-
terminalCallback: (text: React.ReactNode, finished: boolean) => void,
|
|
431
|
-
isFinished: boolean,
|
|
432
|
-
) {
|
|
433
|
-
const toolcalls: [] =
|
|
434
|
-
response?.toolCalls?.map((tool_call: any) => {
|
|
435
|
-
return {
|
|
436
|
-
func: tool_call.function?.name,
|
|
437
|
-
arguments: tool_call.function?.arguments,
|
|
438
|
-
result: tool_call.result,
|
|
439
|
-
error: tool_call.error,
|
|
440
|
-
};
|
|
441
|
-
}) || [];
|
|
442
|
-
|
|
443
|
-
const responseText = response.responseText
|
|
444
|
-
?.trim()
|
|
445
|
-
.replace(/\n/g, "<br/>")
|
|
446
|
-
?.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>");
|
|
447
|
-
|
|
448
|
-
terminalCallback(
|
|
449
|
-
<AiResponseMessage
|
|
450
|
-
responseText={responseText}
|
|
451
|
-
toolcalls={toolcalls}
|
|
452
|
-
editOperations={response.editOperations}
|
|
453
|
-
finished={isFinished}
|
|
454
|
-
/>,
|
|
455
|
-
isFinished,
|
|
456
|
-
);
|
|
457
|
-
}
|
|
@@ -1,36 +1,52 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
2
|
|
|
3
3
|
import { JsonView, defaultStyles } from "react-json-view-lite";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
result
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
import { Message, ToolCall } from "./AiTerminal";
|
|
5
|
+
import { ProgressSpinner } from "primereact/progressspinner";
|
|
6
|
+
export function AiToolCall({
|
|
7
|
+
toolCall,
|
|
8
|
+
result,
|
|
9
|
+
}: {
|
|
10
|
+
toolCall: ToolCall;
|
|
11
|
+
result: Message | undefined;
|
|
12
|
+
}) {
|
|
13
13
|
const [expanded, setExpaded] = useState(false);
|
|
14
|
+
const [error, setError] = useState<string | undefined>(undefined);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
try {
|
|
18
|
+
const data = JSON.parse(result?.content || "{}");
|
|
19
|
+
setError(data.error);
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.error("Failed to parse tool call result:", err);
|
|
22
|
+
setError("Failed to parse response");
|
|
23
|
+
}
|
|
24
|
+
}, [result]);
|
|
14
25
|
|
|
15
26
|
return (
|
|
16
|
-
<div className="
|
|
27
|
+
<div className="m-2">
|
|
17
28
|
<div
|
|
18
29
|
onClick={() => setExpaded(!expanded)}
|
|
19
|
-
className="flex items-center
|
|
30
|
+
className="flex cursor-pointer items-center"
|
|
20
31
|
>
|
|
21
|
-
<i className="pi pi-angle-right" />
|
|
32
|
+
<i className="pi pi-angle-right" />
|
|
33
|
+
<div className="flex items-center gap-2">
|
|
34
|
+
{!result && (
|
|
35
|
+
<ProgressSpinner style={{ width: "1rem", height: "1rem" }} />
|
|
36
|
+
)}
|
|
37
|
+
{toolCall.displayName}
|
|
38
|
+
</div>
|
|
22
39
|
</div>
|
|
23
40
|
{expanded && (
|
|
24
41
|
<div className="ml-4">
|
|
25
42
|
<div className="italic">Args:</div>
|
|
26
|
-
<div>{renderJsonOrText(toolCall.arguments)}</div>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<div
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
</div>
|
|
43
|
+
<div>{renderJsonOrText(toolCall.function.arguments)}</div>
|
|
44
|
+
{error && (
|
|
45
|
+
<div className="ml-4 text-red-500">
|
|
46
|
+
<div className="italic">Error:</div>
|
|
47
|
+
<div>{error}</div>
|
|
48
|
+
</div>
|
|
49
|
+
)}
|
|
34
50
|
</div>
|
|
35
51
|
)}
|
|
36
52
|
</div>
|