@alpaca-editor/core 1.0.4027 → 1.0.4031
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/components/ActionButton.js +2 -2
- package/dist/components/ActionButton.js.map +1 -1
- package/dist/components/SimpleLanguageSelector.js +3 -1
- package/dist/components/SimpleLanguageSelector.js.map +1 -1
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/config/config.js +1 -1
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +1 -1
- package/dist/editor/ContextMenu.js +0 -1
- package/dist/editor/ContextMenu.js.map +1 -1
- package/dist/editor/Editor.js +9 -3
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/FieldListField.js +16 -24
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/ImageEditButton.js +1 -1
- package/dist/editor/ImageEditButton.js.map +1 -1
- package/dist/editor/ImageEditor.js +1 -1
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/MainLayout.js +2 -2
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/Terminal.js +1 -1
- package/dist/editor/Terminal.js.map +1 -1
- package/dist/editor/Titlebar.js +0 -1
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/ai/AgentCostDisplay.d.ts +26 -0
- package/dist/editor/ai/AgentCostDisplay.js +65 -0
- package/dist/editor/ai/AgentCostDisplay.js.map +1 -0
- package/dist/editor/ai/Agents.js +59 -15
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/AiPromptPopover.d.ts +7 -0
- package/dist/editor/ai/AiPromptPopover.js +111 -0
- package/dist/editor/ai/AiPromptPopover.js.map +1 -0
- package/dist/editor/ai/AiResponseMessage.d.ts +1 -0
- package/dist/editor/ai/AiResponseMessage.js +101 -23
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/AiTerminal.d.ts +15 -1
- package/dist/editor/ai/AiTerminal.js +379 -48
- package/dist/editor/ai/AiTerminal.js.map +1 -1
- package/dist/editor/ai/editorAiContext.d.ts +0 -1
- package/dist/editor/ai/editorAiContext.js +0 -2
- package/dist/editor/ai/editorAiContext.js.map +1 -1
- package/dist/editor/client/EditorClient.d.ts +3 -2
- package/dist/editor/client/EditorClient.js +326 -68
- package/dist/editor/client/EditorClient.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +6 -4
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/fieldModificationStore.d.ts +19 -0
- package/dist/editor/client/fieldModificationStore.js +125 -0
- package/dist/editor/client/fieldModificationStore.js.map +1 -0
- package/dist/editor/client/itemsRepository.d.ts +1 -1
- package/dist/editor/client/itemsRepository.js +38 -28
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/client/operations.d.ts +1 -0
- package/dist/editor/client/operations.js +39 -31
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/commands/componentCommands.js +5 -3
- package/dist/editor/commands/componentCommands.js.map +1 -1
- package/dist/editor/commands/itemCommands.js.map +1 -1
- package/dist/editor/component-designer/aiContext.js +0 -2
- package/dist/editor/component-designer/aiContext.js.map +1 -1
- package/dist/editor/field-types/DropLinkEditor.js +1 -1
- package/dist/editor/field-types/DropLinkEditor.js.map +1 -1
- package/dist/editor/field-types/MultiLineText.js +5 -7
- package/dist/editor/field-types/MultiLineText.js.map +1 -1
- package/dist/editor/field-types/RichTextEditorComponent.js +5 -7
- package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
- package/dist/editor/field-types/SingleLineText.js +5 -7
- package/dist/editor/field-types/SingleLineText.js.map +1 -1
- package/dist/editor/hooks/useEditorSettings.d.ts +17 -0
- package/dist/editor/hooks/useEditorSettings.js +61 -0
- package/dist/editor/hooks/useEditorSettings.js.map +1 -0
- package/dist/editor/menubar/ItemActionsMenu.js +2 -2
- package/dist/editor/menubar/ItemActionsMenu.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +1 -1
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/EditControls.js +1 -1
- package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/InsertControls.js +1 -1
- package/dist/editor/menubar/toolbar-sections/InsertControls.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js +1 -1
- package/dist/editor/menubar/toolbar-sections/UtilityControls.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/ViewportControls.js +1 -1
- package/dist/editor/menubar/toolbar-sections/ViewportControls.js.map +1 -1
- package/dist/editor/page-editor-chrome/FieldEditedIndicators.js +4 -3
- package/dist/editor/page-editor-chrome/FieldEditedIndicators.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +9 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js +0 -1
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +1 -1
- package/dist/editor/page-viewer/EditorForm.js +1 -1
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.js +9 -8
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.js +7 -1
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/pageViewContext.js +40 -6
- package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
- package/dist/editor/reviews/Comment.js +7 -6
- package/dist/editor/reviews/Comment.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +84 -12
- package/dist/editor/services/agentService.js +256 -15
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +17 -3
- package/dist/editor/services/aiService.js +5 -3
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/services/contextService.js +0 -1
- package/dist/editor/services/contextService.js.map +1 -1
- package/dist/editor/services/systemService.d.ts +2 -1
- package/dist/editor/services/systemService.js +3 -0
- package/dist/editor/services/systemService.js.map +1 -1
- package/dist/editor/sidebar/ComponentPalette.js +1 -1
- package/dist/editor/sidebar/ComponentPalette.js.map +1 -1
- package/dist/editor/sidebar/EditHistory.js +2 -2
- package/dist/editor/sidebar/EditHistory.js.map +1 -1
- package/dist/editor/sidebar/GraphQL.d.ts +1 -0
- package/dist/editor/sidebar/GraphQL.js +8 -2
- package/dist/editor/sidebar/GraphQL.js.map +1 -1
- package/dist/editor/sidebar/MainContentTree.js +1 -1
- package/dist/editor/sidebar/MainContentTree.js.map +1 -1
- package/dist/editor/sidebar/SEOInfo.js +1 -1
- package/dist/editor/sidebar/SEOInfo.js.map +1 -1
- package/dist/editor/sidebar/ViewSelector.d.ts +4 -1
- package/dist/editor/sidebar/ViewSelector.js +64 -48
- package/dist/editor/sidebar/ViewSelector.js.map +1 -1
- package/dist/editor/ui/PerfectTree.js +2 -11
- package/dist/editor/ui/PerfectTree.js.map +1 -1
- package/dist/editor/ui/SimpleIconButton.d.ts +2 -0
- package/dist/editor/ui/SimpleIconButton.js +8 -4
- package/dist/editor/ui/SimpleIconButton.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/page-wizard/steps/CollectStep.js +1 -1
- package/dist/page-wizard/steps/CollectStep.js.map +1 -1
- package/dist/page-wizard/steps/StructureStep.js +1 -1
- package/dist/page-wizard/steps/StructureStep.js.map +1 -1
- package/dist/page-wizard/steps/TranslateStep.js +233 -18
- package/dist/page-wizard/steps/TranslateStep.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/splash-screen/RecentPages.js +1 -13
- package/dist/splash-screen/RecentPages.js.map +1 -1
- package/dist/splash-screen/SplashScreen.js +1 -1
- package/dist/splash-screen/SplashScreen.js.map +1 -1
- package/dist/styles.css +88 -3
- package/dist/types.d.ts +6 -0
- package/package.json +2 -2
- package/src/components/ActionButton.tsx +3 -2
- package/src/components/SimpleLanguageSelector.tsx +6 -1
- package/src/config/config.tsx +1 -1
- package/src/config/types.ts +1 -1
- package/src/editor/ContextMenu.tsx +0 -3
- package/src/editor/Editor.tsx +11 -3
- package/src/editor/FieldListField.tsx +22 -31
- package/src/editor/ImageEditButton.tsx +1 -0
- package/src/editor/ImageEditor.tsx +1 -0
- package/src/editor/MainLayout.tsx +2 -2
- package/src/editor/Terminal.tsx +1 -1
- package/src/editor/Titlebar.tsx +0 -2
- package/src/editor/ai/AgentCostDisplay.tsx +237 -0
- package/src/editor/ai/Agents.tsx +69 -20
- package/src/editor/ai/AiPromptPopover.tsx +209 -0
- package/src/editor/ai/AiResponseMessage.tsx +201 -60
- package/src/editor/ai/AiTerminal.tsx +502 -71
- package/src/editor/ai/editorAiContext.ts +0 -3
- package/src/editor/client/EditorClient.tsx +409 -117
- package/src/editor/client/editContext.ts +7 -5
- package/src/editor/client/fieldModificationStore.ts +196 -0
- package/src/editor/client/itemsRepository.ts +41 -31
- package/src/editor/client/operations.ts +95 -76
- package/src/editor/commands/componentCommands.tsx +9 -3
- package/src/editor/commands/itemCommands.tsx +0 -1
- package/src/editor/component-designer/aiContext.ts +0 -2
- package/src/editor/field-types/DropLinkEditor.tsx +1 -1
- package/src/editor/field-types/MultiLineText.tsx +9 -9
- package/src/editor/field-types/RichTextEditorComponent.tsx +8 -8
- package/src/editor/field-types/SingleLineText.tsx +9 -9
- package/src/editor/hooks/useEditorSettings.ts +68 -0
- package/src/editor/menubar/ItemActionsMenu.tsx +3 -2
- package/src/editor/menubar/PageSelector.tsx +1 -1
- package/src/editor/menubar/toolbar-sections/EditControls.tsx +1 -0
- package/src/editor/menubar/toolbar-sections/InsertControls.tsx +1 -0
- package/src/editor/menubar/toolbar-sections/UtilityControls.tsx +2 -0
- package/src/editor/menubar/toolbar-sections/ViewportControls.tsx +2 -0
- package/src/editor/page-editor-chrome/FieldEditedIndicators.tsx +4 -3
- package/src/editor/page-editor-chrome/FrameMenu.tsx +10 -1
- package/src/editor/page-editor-chrome/useInlineAICompletion.tsx +0 -1
- package/src/editor/page-viewer/EditorForm.tsx +1 -0
- package/src/editor/page-viewer/PageViewer.tsx +9 -8
- package/src/editor/page-viewer/PageViewerFrame.tsx +7 -1
- package/src/editor/page-viewer/pageViewContext.ts +40 -5
- package/src/editor/reviews/Comment.tsx +7 -7
- package/src/editor/services/agentService.ts +405 -31
- package/src/editor/services/aiService.ts +22 -5
- package/src/editor/services/contextService.ts +0 -1
- package/src/editor/services/systemService.ts +7 -1
- package/src/editor/sidebar/ComponentPalette.tsx +4 -1
- package/src/editor/sidebar/EditHistory.tsx +2 -0
- package/src/editor/sidebar/GraphQL.tsx +19 -7
- package/src/editor/sidebar/MainContentTree.tsx +1 -1
- package/src/editor/sidebar/SEOInfo.tsx +1 -1
- package/src/editor/sidebar/ViewSelector.tsx +80 -64
- package/src/editor/ui/PerfectTree.tsx +2 -18
- package/src/editor/ui/SimpleIconButton.tsx +56 -38
- package/src/index.ts +4 -2
- package/src/page-wizard/steps/CollectStep.tsx +0 -2
- package/src/page-wizard/steps/StructureStep.tsx +3 -0
- package/src/page-wizard/steps/TranslateStep.tsx +473 -62
- package/src/revision.ts +2 -2
- package/src/splash-screen/RecentPages.tsx +0 -14
- package/src/splash-screen/SplashScreen.tsx +3 -2
- package/src/types.ts +7 -0
- package/dist/editor/ai/AiPopup.d.ts +0 -10
- package/dist/editor/ai/AiPopup.js +0 -23
- package/dist/editor/ai/AiPopup.js.map +0 -1
- package/dist/editor/ai/AiToolCall.d.ts +0 -5
- package/dist/editor/ai/AiToolCall.js +0 -28
- package/dist/editor/ai/AiToolCall.js.map +0 -1
- package/src/editor/ai/AiPopup.tsx +0 -59
- package/src/editor/ai/AiToolCall.tsx +0 -71
|
@@ -10,14 +10,24 @@ import { Dropdown } from "primereact/dropdown";
|
|
|
10
10
|
|
|
11
11
|
import { WizardIcon } from "../ui/Icons";
|
|
12
12
|
import { AiResponseMessage } from "./AiResponseMessage";
|
|
13
|
+
import { AiProfile, loadAiProfiles } from "../services/aiService";
|
|
13
14
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
startAgent,
|
|
16
|
+
connectToAgentStream,
|
|
17
|
+
getAgentStatus,
|
|
18
|
+
getRunningAgents,
|
|
19
|
+
getAgent,
|
|
20
|
+
getAgents,
|
|
21
|
+
getChatHistory,
|
|
22
|
+
cancelAgent,
|
|
23
|
+
AgentStreamMessageType,
|
|
24
|
+
StartAgentRequest,
|
|
25
|
+
AgentStreamMessage,
|
|
26
|
+
} from "../services/agentService";
|
|
18
27
|
import { EditOperation } from "../../types";
|
|
19
28
|
import { SimpleIconButton } from "../ui/SimpleIconButton";
|
|
20
29
|
import { Settings } from "lucide-react";
|
|
30
|
+
import { AgentCostDisplay } from "./AgentCostDisplay";
|
|
21
31
|
|
|
22
32
|
type Response = {
|
|
23
33
|
messages: Message[];
|
|
@@ -27,6 +37,14 @@ type Response = {
|
|
|
27
37
|
numCachedTokens: number;
|
|
28
38
|
state: string;
|
|
29
39
|
agentName?: string; // Updated agent name (only sent when the agent name has been updated)
|
|
40
|
+
// Cost information from backend
|
|
41
|
+
totalCost?: number;
|
|
42
|
+
totalInputTokenCost?: number;
|
|
43
|
+
totalOutputTokenCost?: number;
|
|
44
|
+
totalCachedTokenCost?: number;
|
|
45
|
+
totalInputTokens?: number;
|
|
46
|
+
totalOutputTokens?: number;
|
|
47
|
+
totalCachedTokens?: number;
|
|
30
48
|
};
|
|
31
49
|
|
|
32
50
|
export type ToolCall = {
|
|
@@ -48,9 +66,22 @@ export type Message = {
|
|
|
48
66
|
tool_call_id?: string; // For tool response messages
|
|
49
67
|
};
|
|
50
68
|
|
|
69
|
+
// Helper function to format message content
|
|
70
|
+
function formatMessageContent(content: string): string {
|
|
71
|
+
return (
|
|
72
|
+
content
|
|
73
|
+
?.trim()
|
|
74
|
+
?.replaceAll("\n", "<br>")
|
|
75
|
+
?.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>") // Bold markdown
|
|
76
|
+
?.replace(
|
|
77
|
+
/\[([^\]]+)\]\(([^)]+)\)/g,
|
|
78
|
+
'<a href="$2" target="_blank" class="text-blue-500" rel="noopener noreferrer">$1</a>',
|
|
79
|
+
) || "" // Links
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
51
83
|
export type AiContext = {
|
|
52
84
|
promptData: any;
|
|
53
|
-
endpoint: string;
|
|
54
85
|
callback?: (response: Response) => void;
|
|
55
86
|
};
|
|
56
87
|
|
|
@@ -58,6 +89,15 @@ export type AiTerminalOptions = {
|
|
|
58
89
|
initialPrompt?: string;
|
|
59
90
|
hiddenSystemPrompt?: string;
|
|
60
91
|
initialMessages?: Message[];
|
|
92
|
+
agentId?: string;
|
|
93
|
+
// Cost information for loaded agent sessions
|
|
94
|
+
totalCost?: number;
|
|
95
|
+
totalInputTokenCost?: number;
|
|
96
|
+
totalOutputTokenCost?: number;
|
|
97
|
+
totalCachedTokenCost?: number;
|
|
98
|
+
totalInputTokens?: number;
|
|
99
|
+
totalOutputTokens?: number;
|
|
100
|
+
totalCachedTokens?: number;
|
|
61
101
|
};
|
|
62
102
|
|
|
63
103
|
export function AiTerminal({
|
|
@@ -87,7 +127,9 @@ export function AiTerminal({
|
|
|
87
127
|
const [profiles, setProfiles] = useState<AiProfile[]>([]);
|
|
88
128
|
const [activeProfile, setActiveProfile] = useState<AiProfile>();
|
|
89
129
|
const [initialPromptExecuted, setInitialPromptExecuted] = useState(false);
|
|
90
|
-
const [agentId, setAgentId] = useState<string>(
|
|
130
|
+
const [agentId, setAgentId] = useState<string>(
|
|
131
|
+
() => options?.agentId || crypto.randomUUID(),
|
|
132
|
+
);
|
|
91
133
|
const selection = editContext.selection;
|
|
92
134
|
const terminalRef = useRef<{ submit: () => void }>(null);
|
|
93
135
|
const [responseMessages, setResponseMessages] = useState<Message[]>(
|
|
@@ -150,11 +192,7 @@ export function AiTerminal({
|
|
|
150
192
|
|
|
151
193
|
// Format the initial messages for display
|
|
152
194
|
const formattedMessages = options.initialMessages.map((message) => {
|
|
153
|
-
const formattedContent =
|
|
154
|
-
message.content
|
|
155
|
-
?.trim()
|
|
156
|
-
?.replaceAll("\n", "<br>")
|
|
157
|
-
?.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>") || "";
|
|
195
|
+
const formattedContent = formatMessageContent(message.content || "");
|
|
158
196
|
|
|
159
197
|
return {
|
|
160
198
|
...message,
|
|
@@ -164,8 +202,6 @@ export function AiTerminal({
|
|
|
164
202
|
};
|
|
165
203
|
});
|
|
166
204
|
|
|
167
|
-
console.log("AiTerminal: Formatted messages", formattedMessages);
|
|
168
|
-
|
|
169
205
|
// Update the internal message states
|
|
170
206
|
setMessages(formattedMessages);
|
|
171
207
|
setResponseMessages(formattedMessages);
|
|
@@ -174,13 +210,20 @@ export function AiTerminal({
|
|
|
174
210
|
const initialResponse: Response = {
|
|
175
211
|
messages: formattedMessages,
|
|
176
212
|
editOperations: [],
|
|
177
|
-
numInputTokens: 0,
|
|
178
|
-
numOutputTokens: 0,
|
|
179
|
-
numCachedTokens: 0,
|
|
213
|
+
numInputTokens: options?.totalInputTokens || 0,
|
|
214
|
+
numOutputTokens: options?.totalOutputTokens || 0,
|
|
215
|
+
numCachedTokens: options?.totalCachedTokens || 0,
|
|
180
216
|
state: "loaded",
|
|
217
|
+
// Include cost information from loaded agent session
|
|
218
|
+
totalCost: options?.totalCost,
|
|
219
|
+
totalInputTokenCost: options?.totalInputTokenCost,
|
|
220
|
+
totalOutputTokenCost: options?.totalOutputTokenCost,
|
|
221
|
+
totalCachedTokenCost: options?.totalCachedTokenCost,
|
|
222
|
+
totalInputTokens: options?.totalInputTokens,
|
|
223
|
+
totalOutputTokens: options?.totalOutputTokens,
|
|
224
|
+
totalCachedTokens: options?.totalCachedTokens,
|
|
181
225
|
};
|
|
182
226
|
|
|
183
|
-
console.log("AiTerminal: Setting response", initialResponse);
|
|
184
227
|
setResponse(initialResponse);
|
|
185
228
|
|
|
186
229
|
// Create individual Terminal messages for each conversation message
|
|
@@ -280,11 +323,7 @@ export function AiTerminal({
|
|
|
280
323
|
// Replace the conversation history with the authoritative response from AI
|
|
281
324
|
if (updatedMessages && Array.isArray(updatedMessages)) {
|
|
282
325
|
const formattedMessages = updatedMessages.map((message) => {
|
|
283
|
-
const formattedContent =
|
|
284
|
-
message.content
|
|
285
|
-
?.trim()
|
|
286
|
-
?.replaceAll("\n", "<br>")
|
|
287
|
-
?.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>") || "";
|
|
326
|
+
const formattedContent = formatMessageContent(message.content || "");
|
|
288
327
|
|
|
289
328
|
return {
|
|
290
329
|
...message,
|
|
@@ -333,7 +372,6 @@ export function AiTerminal({
|
|
|
333
372
|
|
|
334
373
|
const context = createAiContext({ editContext });
|
|
335
374
|
|
|
336
|
-
let lastOpIndex = 0;
|
|
337
375
|
const selectedText = editContext?.selectedRange?.text || null;
|
|
338
376
|
if (!activeProfile || !model) return;
|
|
339
377
|
|
|
@@ -357,47 +395,418 @@ export function AiTerminal({
|
|
|
357
395
|
setMessages((prevMessages) => [...prevMessages, userMessage]);
|
|
358
396
|
setResponseMessages((prevMessages) => [...prevMessages, userMessage]);
|
|
359
397
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
398
|
+
try {
|
|
399
|
+
// Step 1: Start the agent execution
|
|
400
|
+
const startRequest: StartAgentRequest = {
|
|
401
|
+
agentId,
|
|
402
|
+
messages,
|
|
403
|
+
sessionId: editContext!.sessionId,
|
|
364
404
|
profileId: activeProfile.id,
|
|
365
|
-
selection,
|
|
366
|
-
selectedText,
|
|
367
405
|
model,
|
|
368
|
-
|
|
369
|
-
|
|
406
|
+
itemid: context.promptData.itemid,
|
|
407
|
+
language: context.promptData.language,
|
|
408
|
+
version: context.promptData.version,
|
|
409
|
+
selection,
|
|
410
|
+
selectedText: selectedText || undefined,
|
|
411
|
+
allowedFunctions: context.promptData.allowedFunctions,
|
|
412
|
+
addContextContent: context.promptData.addContextContent,
|
|
413
|
+
addAllContent: context.promptData.addAllContent,
|
|
370
414
|
addSelectedComponents: true,
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
(response: any) => {
|
|
374
|
-
setResponse(response);
|
|
375
|
-
handleResponse(response, callback, false);
|
|
376
|
-
},
|
|
377
|
-
);
|
|
378
|
-
|
|
379
|
-
if (response) {
|
|
380
|
-
handleResponse(response, callback, true);
|
|
381
|
-
|
|
382
|
-
// Handle agent name update
|
|
383
|
-
if ((response as any).agentName && onAgentNameUpdate) {
|
|
384
|
-
onAgentNameUpdate((response as any).agentName);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
if (context.callback) context.callback(response);
|
|
388
|
-
editContext?.requestRefresh("immediate");
|
|
389
|
-
}
|
|
415
|
+
profile: activeProfile.name,
|
|
416
|
+
};
|
|
390
417
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
// content: response.responseText,
|
|
394
|
-
// role: "assistant",
|
|
395
|
-
// name: "assistant",
|
|
396
|
-
// });
|
|
418
|
+
const startResponse = await startAgent(startRequest, context);
|
|
419
|
+
console.log("Agent started:", startResponse);
|
|
397
420
|
|
|
398
|
-
|
|
421
|
+
// Step 2: Connect to the agent stream for real-time updates
|
|
422
|
+
const abortController = new AbortController();
|
|
423
|
+
let accumulatedResponse: any = {
|
|
424
|
+
messages: [...messages],
|
|
425
|
+
editOperations: [],
|
|
426
|
+
numInputTokens: 0,
|
|
427
|
+
numOutputTokens: 0,
|
|
428
|
+
numCachedTokens: 0,
|
|
429
|
+
state: "running",
|
|
430
|
+
};
|
|
431
|
+
let completionProcessed = false;
|
|
432
|
+
|
|
433
|
+
try {
|
|
434
|
+
console.log("Connecting to agent stream");
|
|
435
|
+
await connectToAgentStream(
|
|
436
|
+
agentId,
|
|
437
|
+
context,
|
|
438
|
+
(streamMessage) => {
|
|
439
|
+
// console.log(
|
|
440
|
+
// "Stream message:",
|
|
441
|
+
// streamMessage,
|
|
442
|
+
// new Date().toISOString(),
|
|
443
|
+
// );
|
|
444
|
+
|
|
445
|
+
// Message types are now normalized in agentService.ts
|
|
446
|
+
switch (streamMessage.type) {
|
|
447
|
+
case AgentStreamMessageType.StatusUpdate:
|
|
448
|
+
//console.log("Status update:", streamMessage.data);
|
|
449
|
+
break;
|
|
450
|
+
|
|
451
|
+
case AgentStreamMessageType.ContentChunk:
|
|
452
|
+
if (streamMessage.data) {
|
|
453
|
+
// Handle incremental content updates
|
|
454
|
+
if (
|
|
455
|
+
streamMessage.data.isIncremental &&
|
|
456
|
+
streamMessage.data.deltaContent
|
|
457
|
+
) {
|
|
458
|
+
// Find the last assistant message to append delta content to
|
|
459
|
+
const updatedMessages = [
|
|
460
|
+
...(accumulatedResponse.messages || []),
|
|
461
|
+
];
|
|
462
|
+
let lastAssistantMessage = null;
|
|
463
|
+
let lastAssistantIndex = -1;
|
|
464
|
+
|
|
465
|
+
// Find the last assistant message
|
|
466
|
+
for (let i = updatedMessages.length - 1; i >= 0; i--) {
|
|
467
|
+
if (updatedMessages[i].role === "assistant") {
|
|
468
|
+
lastAssistantMessage = updatedMessages[i];
|
|
469
|
+
lastAssistantIndex = i;
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// If no assistant message exists, or the last one has tool calls, create a new one
|
|
475
|
+
if (
|
|
476
|
+
!lastAssistantMessage ||
|
|
477
|
+
(lastAssistantMessage.tool_calls &&
|
|
478
|
+
lastAssistantMessage.tool_calls.length > 0)
|
|
479
|
+
) {
|
|
480
|
+
lastAssistantMessage = {
|
|
481
|
+
id: crypto.randomUUID(),
|
|
482
|
+
role: "assistant",
|
|
483
|
+
name: "assistant",
|
|
484
|
+
content: "",
|
|
485
|
+
tool_calls: [],
|
|
486
|
+
};
|
|
487
|
+
updatedMessages.push(lastAssistantMessage);
|
|
488
|
+
lastAssistantIndex = updatedMessages.length - 1;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Append the delta content to build up the full message
|
|
492
|
+
const currentContent = lastAssistantMessage.content || "";
|
|
493
|
+
const newContent =
|
|
494
|
+
currentContent + streamMessage.data.deltaContent;
|
|
495
|
+
|
|
496
|
+
// Update the message with accumulated content
|
|
497
|
+
updatedMessages[lastAssistantIndex] = {
|
|
498
|
+
...lastAssistantMessage,
|
|
499
|
+
content: newContent,
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
// Update accumulated response with incremental content
|
|
503
|
+
accumulatedResponse = {
|
|
504
|
+
...accumulatedResponse,
|
|
505
|
+
...streamMessage.data,
|
|
506
|
+
messages: updatedMessages,
|
|
507
|
+
editOperations:
|
|
508
|
+
streamMessage.data.editOperations ||
|
|
509
|
+
accumulatedResponse.editOperations,
|
|
510
|
+
};
|
|
511
|
+
} else {
|
|
512
|
+
// Non-incremental update - use as provided
|
|
513
|
+
accumulatedResponse = {
|
|
514
|
+
...accumulatedResponse,
|
|
515
|
+
...streamMessage.data,
|
|
516
|
+
editOperations:
|
|
517
|
+
streamMessage.data.editOperations ||
|
|
518
|
+
accumulatedResponse.editOperations,
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Always trigger UI update for content chunks
|
|
523
|
+
handleResponse(accumulatedResponse, callback, false);
|
|
524
|
+
}
|
|
525
|
+
break;
|
|
526
|
+
|
|
527
|
+
case AgentStreamMessageType.ToolCall:
|
|
528
|
+
// console.log("Tool call received:", streamMessage.data);
|
|
529
|
+
if (streamMessage.data) {
|
|
530
|
+
// Find or create the assistant message that contains this tool call
|
|
531
|
+
const updatedMessages = [
|
|
532
|
+
...(accumulatedResponse.messages || []),
|
|
533
|
+
];
|
|
534
|
+
let lastAssistantMessage = null;
|
|
535
|
+
let lastAssistantIndex = -1;
|
|
536
|
+
|
|
537
|
+
// Find the last assistant message
|
|
538
|
+
for (let i = updatedMessages.length - 1; i >= 0; i--) {
|
|
539
|
+
if (updatedMessages[i].role === "assistant") {
|
|
540
|
+
lastAssistantMessage = updatedMessages[i];
|
|
541
|
+
lastAssistantIndex = i;
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// If no assistant message exists, create one
|
|
547
|
+
if (!lastAssistantMessage) {
|
|
548
|
+
lastAssistantMessage = {
|
|
549
|
+
id: crypto.randomUUID(),
|
|
550
|
+
role: "assistant",
|
|
551
|
+
name: "assistant",
|
|
552
|
+
content: "",
|
|
553
|
+
tool_calls: [],
|
|
554
|
+
};
|
|
555
|
+
updatedMessages.push(lastAssistantMessage);
|
|
556
|
+
lastAssistantIndex = updatedMessages.length - 1;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Add or update the tool call
|
|
560
|
+
const toolCall = {
|
|
561
|
+
id: streamMessage.data.id,
|
|
562
|
+
displayName: streamMessage.data.displayName,
|
|
563
|
+
function: {
|
|
564
|
+
name:
|
|
565
|
+
streamMessage.data.function?.name ||
|
|
566
|
+
streamMessage.data.name,
|
|
567
|
+
arguments:
|
|
568
|
+
streamMessage.data.function?.arguments ||
|
|
569
|
+
streamMessage.data.arguments,
|
|
570
|
+
},
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
// Update or add the tool call to the assistant message
|
|
574
|
+
const existingToolCalls =
|
|
575
|
+
lastAssistantMessage.tool_calls || [];
|
|
576
|
+
const existingIndex = existingToolCalls.findIndex(
|
|
577
|
+
(tc: any) => tc.id === toolCall.id,
|
|
578
|
+
);
|
|
579
|
+
|
|
580
|
+
let updatedToolCalls;
|
|
581
|
+
if (existingIndex >= 0) {
|
|
582
|
+
// Update existing tool call
|
|
583
|
+
updatedToolCalls = [...existingToolCalls];
|
|
584
|
+
updatedToolCalls[existingIndex] = toolCall;
|
|
585
|
+
} else {
|
|
586
|
+
// Add new tool call
|
|
587
|
+
updatedToolCalls = [...existingToolCalls, toolCall];
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Update the assistant message with the tool call
|
|
591
|
+
updatedMessages[lastAssistantIndex] = {
|
|
592
|
+
...lastAssistantMessage,
|
|
593
|
+
tool_calls: updatedToolCalls,
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
// Update accumulated response
|
|
597
|
+
accumulatedResponse = {
|
|
598
|
+
...accumulatedResponse,
|
|
599
|
+
messages: updatedMessages,
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
// Trigger UI update to show the tool call
|
|
603
|
+
handleResponse(accumulatedResponse, callback, false);
|
|
604
|
+
}
|
|
605
|
+
break;
|
|
606
|
+
|
|
607
|
+
case AgentStreamMessageType.ToolResult:
|
|
608
|
+
console.log("Tool result received:", streamMessage.data);
|
|
609
|
+
if (streamMessage.data) {
|
|
610
|
+
// Find the assistant message and tool call to update with the result
|
|
611
|
+
const updatedMessages = [
|
|
612
|
+
...(accumulatedResponse.messages || []),
|
|
613
|
+
];
|
|
614
|
+
|
|
615
|
+
// Find the assistant message with the matching tool call ID
|
|
616
|
+
for (let i = updatedMessages.length - 1; i >= 0; i--) {
|
|
617
|
+
if (
|
|
618
|
+
updatedMessages[i].role === "assistant" &&
|
|
619
|
+
updatedMessages[i].tool_calls
|
|
620
|
+
) {
|
|
621
|
+
const toolCalls = updatedMessages[i].tool_calls || [];
|
|
622
|
+
const toolCallIndex = toolCalls.findIndex(
|
|
623
|
+
(tc: any) => tc.id === streamMessage.data.toolCallId,
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
if (toolCallIndex >= 0) {
|
|
627
|
+
// Update the tool call with the result
|
|
628
|
+
const updatedToolCalls = [...toolCalls];
|
|
629
|
+
updatedToolCalls[toolCallIndex] = {
|
|
630
|
+
...updatedToolCalls[toolCallIndex],
|
|
631
|
+
function: {
|
|
632
|
+
...updatedToolCalls[toolCallIndex].function,
|
|
633
|
+
result: streamMessage.data.result,
|
|
634
|
+
},
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
// Update the message
|
|
638
|
+
updatedMessages[i] = {
|
|
639
|
+
...updatedMessages[i],
|
|
640
|
+
tool_calls: updatedToolCalls,
|
|
641
|
+
};
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Update accumulated response
|
|
648
|
+
accumulatedResponse = {
|
|
649
|
+
...accumulatedResponse,
|
|
650
|
+
messages: updatedMessages,
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
// Trigger UI update to show the tool result
|
|
654
|
+
handleResponse(accumulatedResponse, callback, false);
|
|
655
|
+
}
|
|
656
|
+
break;
|
|
657
|
+
|
|
658
|
+
case AgentStreamMessageType.Completed:
|
|
659
|
+
if (streamMessage.data) {
|
|
660
|
+
// Final completion data
|
|
661
|
+
const finalResponse = {
|
|
662
|
+
messages:
|
|
663
|
+
streamMessage.data.messages ||
|
|
664
|
+
accumulatedResponse.messages,
|
|
665
|
+
editOperations:
|
|
666
|
+
streamMessage.data.editOperations ||
|
|
667
|
+
accumulatedResponse.editOperations,
|
|
668
|
+
numInputTokens:
|
|
669
|
+
streamMessage.data.tokenUsage?.inputTokens ||
|
|
670
|
+
accumulatedResponse.numInputTokens,
|
|
671
|
+
numOutputTokens:
|
|
672
|
+
streamMessage.data.tokenUsage?.outputTokens ||
|
|
673
|
+
accumulatedResponse.numOutputTokens,
|
|
674
|
+
numCachedTokens:
|
|
675
|
+
streamMessage.data.tokenUsage?.cachedTokens ||
|
|
676
|
+
accumulatedResponse.numCachedTokens,
|
|
677
|
+
state: "completed",
|
|
678
|
+
agentName: streamMessage.data.agentName,
|
|
679
|
+
// Add cost fields from backend (try both tokenUsage object and direct properties)
|
|
680
|
+
totalCost:
|
|
681
|
+
streamMessage.data.totalCost ||
|
|
682
|
+
streamMessage.data.tokenUsage?.totalCost,
|
|
683
|
+
totalInputTokenCost:
|
|
684
|
+
streamMessage.data.totalInputTokenCost ||
|
|
685
|
+
streamMessage.data.tokenUsage?.inputTokenCost,
|
|
686
|
+
totalOutputTokenCost:
|
|
687
|
+
streamMessage.data.totalOutputTokenCost ||
|
|
688
|
+
streamMessage.data.tokenUsage?.outputTokenCost,
|
|
689
|
+
totalCachedTokenCost:
|
|
690
|
+
streamMessage.data.totalCachedTokenCost ||
|
|
691
|
+
streamMessage.data.tokenUsage?.cachedTokenCost,
|
|
692
|
+
totalInputTokens:
|
|
693
|
+
streamMessage.data.totalInputTokens ||
|
|
694
|
+
streamMessage.data.tokenUsage?.inputTokens,
|
|
695
|
+
totalOutputTokens:
|
|
696
|
+
streamMessage.data.totalOutputTokens ||
|
|
697
|
+
streamMessage.data.tokenUsage?.outputTokens,
|
|
698
|
+
totalCachedTokens:
|
|
699
|
+
streamMessage.data.totalCachedTokens ||
|
|
700
|
+
streamMessage.data.tokenUsage?.cachedTokens,
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
completionProcessed = true;
|
|
704
|
+
setResponse(finalResponse);
|
|
705
|
+
|
|
706
|
+
// On completion, just update the internal state and call the final callback
|
|
707
|
+
// Don't call handleResponse again as it would duplicate the message
|
|
708
|
+
// The Terminal component will clear the streaming response and add it to the message history
|
|
709
|
+
const formattedMessages = (finalResponse.messages || []).map(
|
|
710
|
+
(message: any) => {
|
|
711
|
+
const formattedContent = formatMessageContent(
|
|
712
|
+
message.content || "",
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
return {
|
|
716
|
+
...message,
|
|
717
|
+
content: message.content || "",
|
|
718
|
+
formattedContent: formattedContent,
|
|
719
|
+
tool_calls: message.tool_calls || [],
|
|
720
|
+
};
|
|
721
|
+
},
|
|
722
|
+
);
|
|
723
|
+
|
|
724
|
+
// Update internal state without triggering a new render via handleResponse
|
|
725
|
+
setMessages([...formattedMessages]);
|
|
726
|
+
setResponseMessages([...formattedMessages]);
|
|
727
|
+
|
|
728
|
+
// Only call the terminal callback to mark completion (this will add to history)
|
|
729
|
+
callback(
|
|
730
|
+
<AiResponseMessage
|
|
731
|
+
messages={formattedMessages}
|
|
732
|
+
editOperations={finalResponse.editOperations}
|
|
733
|
+
finished={true}
|
|
734
|
+
/>,
|
|
735
|
+
true,
|
|
736
|
+
);
|
|
737
|
+
|
|
738
|
+
// Handle agent name update
|
|
739
|
+
if (finalResponse.agentName && onAgentNameUpdate) {
|
|
740
|
+
onAgentNameUpdate(finalResponse.agentName);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
if (context.callback) context.callback(finalResponse);
|
|
744
|
+
//editContext?.requestRefresh("immediate");
|
|
745
|
+
}
|
|
746
|
+
break;
|
|
747
|
+
|
|
748
|
+
case AgentStreamMessageType.Error:
|
|
749
|
+
console.error("Agent execution error:", streamMessage.error);
|
|
750
|
+
const errorResponse = {
|
|
751
|
+
...accumulatedResponse,
|
|
752
|
+
state: "error",
|
|
753
|
+
error: streamMessage.error,
|
|
754
|
+
};
|
|
755
|
+
setResponse(errorResponse);
|
|
756
|
+
handleResponse(errorResponse, callback, true);
|
|
757
|
+
break;
|
|
758
|
+
|
|
759
|
+
default:
|
|
760
|
+
console.log(
|
|
761
|
+
"Unhandled stream message type:",
|
|
762
|
+
streamMessage.type,
|
|
763
|
+
);
|
|
764
|
+
break;
|
|
765
|
+
}
|
|
766
|
+
},
|
|
767
|
+
abortController.signal,
|
|
768
|
+
);
|
|
399
769
|
|
|
400
|
-
|
|
770
|
+
// If we reach here, the stream ended without a Completed message
|
|
771
|
+
if (!completionProcessed) {
|
|
772
|
+
// console.log("Stream ended without Completed message, cleaning up");
|
|
773
|
+
const finalResponse = {
|
|
774
|
+
...accumulatedResponse,
|
|
775
|
+
state: "completed",
|
|
776
|
+
};
|
|
777
|
+
setResponse(finalResponse);
|
|
778
|
+
handleResponse(finalResponse, callback, true);
|
|
779
|
+
}
|
|
780
|
+
} catch (streamError) {
|
|
781
|
+
console.error("Stream connection error:", streamError);
|
|
782
|
+
const errorMessage =
|
|
783
|
+
streamError instanceof Error
|
|
784
|
+
? streamError.message
|
|
785
|
+
: "Unknown stream error";
|
|
786
|
+
const errorResponse = {
|
|
787
|
+
...accumulatedResponse,
|
|
788
|
+
state: "error",
|
|
789
|
+
error: errorMessage,
|
|
790
|
+
};
|
|
791
|
+
setResponse(errorResponse);
|
|
792
|
+
handleResponse(errorResponse, callback, true);
|
|
793
|
+
}
|
|
794
|
+
} catch (error) {
|
|
795
|
+
console.error("Error starting agent:", error);
|
|
796
|
+
const errorMessage =
|
|
797
|
+
error instanceof Error ? error.message : "Unknown error";
|
|
798
|
+
const errorResponse = {
|
|
799
|
+
messages: [...messages],
|
|
800
|
+
editOperations: [],
|
|
801
|
+
numInputTokens: 0,
|
|
802
|
+
numOutputTokens: 0,
|
|
803
|
+
numCachedTokens: 0,
|
|
804
|
+
state: "error",
|
|
805
|
+
error: errorMessage,
|
|
806
|
+
};
|
|
807
|
+
setResponse(errorResponse);
|
|
808
|
+
handleResponse(errorResponse, callback, true);
|
|
809
|
+
}
|
|
401
810
|
}
|
|
402
811
|
|
|
403
812
|
useEffect(() => {
|
|
@@ -428,19 +837,39 @@ export function AiTerminal({
|
|
|
428
837
|
}}
|
|
429
838
|
initialMessages={initialTerminalMessages}
|
|
430
839
|
infobar={
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
840
|
+
<AgentCostDisplay
|
|
841
|
+
response={
|
|
842
|
+
response
|
|
843
|
+
? {
|
|
844
|
+
numInputTokens: response.numInputTokens,
|
|
845
|
+
numOutputTokens: response.numOutputTokens,
|
|
846
|
+
numCachedTokens: response.numCachedTokens,
|
|
847
|
+
totalCost: response.totalCost,
|
|
848
|
+
inputCost: response.totalInputTokenCost,
|
|
849
|
+
outputCost: response.totalOutputTokenCost,
|
|
850
|
+
cachedCost: response.totalCachedTokenCost,
|
|
851
|
+
}
|
|
852
|
+
: null
|
|
853
|
+
}
|
|
854
|
+
totalTokens={
|
|
855
|
+
response
|
|
856
|
+
? {
|
|
857
|
+
input:
|
|
858
|
+
response.totalInputTokens || response.numInputTokens,
|
|
859
|
+
output:
|
|
860
|
+
response.totalOutputTokens ||
|
|
861
|
+
response.numOutputTokens,
|
|
862
|
+
cached:
|
|
863
|
+
response.totalCachedTokens ||
|
|
864
|
+
response.numCachedTokens,
|
|
865
|
+
totalCost: response.totalCost || 0,
|
|
866
|
+
inputCost: response.totalInputTokenCost || 0,
|
|
867
|
+
outputCost: response.totalOutputTokenCost || 0,
|
|
868
|
+
cachedCost: response.totalCachedTokenCost || 0,
|
|
869
|
+
}
|
|
870
|
+
: undefined
|
|
871
|
+
}
|
|
872
|
+
/>
|
|
444
873
|
}
|
|
445
874
|
prompt={prompt}
|
|
446
875
|
setPrompt={setPrompt}
|
|
@@ -515,6 +944,8 @@ export function AiTerminal({
|
|
|
515
944
|
value={model}
|
|
516
945
|
onChange={(e) => setModel(e.value)}
|
|
517
946
|
options={activeProfile.models}
|
|
947
|
+
optionLabel="name"
|
|
948
|
+
optionValue="id"
|
|
518
949
|
/>
|
|
519
950
|
</div>
|
|
520
951
|
)}
|
|
@@ -5,10 +5,7 @@ export function createEditorAiContext({
|
|
|
5
5
|
}: {
|
|
6
6
|
editContext: EditContextType;
|
|
7
7
|
}) {
|
|
8
|
-
const aiPromptUrl = editContext.configuration.services.aiService.promptUrl;
|
|
9
|
-
|
|
10
8
|
return {
|
|
11
|
-
endpoint: aiPromptUrl,
|
|
12
9
|
promptData: {
|
|
13
10
|
itemid: editContext.currentItemDescriptor?.id,
|
|
14
11
|
language: editContext.currentItemDescriptor?.language,
|