@alpaca-editor/core 1.0.4026 → 1.0.4030
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 +83 -29
- 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 +104 -18
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/AiTerminal.d.ts +18 -2
- package/dist/editor/ai/AiTerminal.js +423 -63
- package/dist/editor/ai/AiTerminal.js.map +1 -1
- package/dist/editor/ai/EditorAiTerminal.d.ts +2 -1
- package/dist/editor/ai/EditorAiTerminal.js +2 -2
- package/dist/editor/ai/EditorAiTerminal.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 +18 -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 +2 -0
- package/dist/index.js +2 -0
- 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 +147 -65
- package/src/editor/ai/AiPromptPopover.tsx +209 -0
- package/src/editor/ai/AiResponseMessage.tsx +232 -45
- package/src/editor/ai/AiTerminal.tsx +559 -88
- package/src/editor/ai/EditorAiTerminal.tsx +3 -0
- 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 +24 -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 +2 -0
- 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[];
|
|
@@ -26,6 +36,15 @@ type Response = {
|
|
|
26
36
|
numOutputTokens: number;
|
|
27
37
|
numCachedTokens: number;
|
|
28
38
|
state: string;
|
|
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;
|
|
29
48
|
};
|
|
30
49
|
|
|
31
50
|
export type ToolCall = {
|
|
@@ -47,9 +66,22 @@ export type Message = {
|
|
|
47
66
|
tool_call_id?: string; // For tool response messages
|
|
48
67
|
};
|
|
49
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
|
+
|
|
50
83
|
export type AiContext = {
|
|
51
84
|
promptData: any;
|
|
52
|
-
endpoint: string;
|
|
53
85
|
callback?: (response: Response) => void;
|
|
54
86
|
};
|
|
55
87
|
|
|
@@ -57,6 +89,15 @@ export type AiTerminalOptions = {
|
|
|
57
89
|
initialPrompt?: string;
|
|
58
90
|
hiddenSystemPrompt?: string;
|
|
59
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;
|
|
60
101
|
};
|
|
61
102
|
|
|
62
103
|
export function AiTerminal({
|
|
@@ -64,11 +105,13 @@ export function AiTerminal({
|
|
|
64
105
|
createAiContext,
|
|
65
106
|
defaultProfile,
|
|
66
107
|
options,
|
|
108
|
+
onAgentNameUpdate,
|
|
67
109
|
}: {
|
|
68
110
|
closeButton?: React.ReactNode;
|
|
69
111
|
createAiContext: ({ editContext }: { editContext: any }) => AiContext;
|
|
70
112
|
defaultProfile?: string;
|
|
71
113
|
options?: AiTerminalOptions;
|
|
114
|
+
onAgentNameUpdate?: (name: string) => void;
|
|
72
115
|
}) {
|
|
73
116
|
const editContext = useEditContext();
|
|
74
117
|
const [showPredefined, setShowPredefined] = useState(false);
|
|
@@ -84,7 +127,9 @@ export function AiTerminal({
|
|
|
84
127
|
const [profiles, setProfiles] = useState<AiProfile[]>([]);
|
|
85
128
|
const [activeProfile, setActiveProfile] = useState<AiProfile>();
|
|
86
129
|
const [initialPromptExecuted, setInitialPromptExecuted] = useState(false);
|
|
87
|
-
const [agentId] = useState<string>(
|
|
130
|
+
const [agentId, setAgentId] = useState<string>(
|
|
131
|
+
() => options?.agentId || crypto.randomUUID(),
|
|
132
|
+
);
|
|
88
133
|
const selection = editContext.selection;
|
|
89
134
|
const terminalRef = useRef<{ submit: () => void }>(null);
|
|
90
135
|
const [responseMessages, setResponseMessages] = useState<Message[]>(
|
|
@@ -147,11 +192,7 @@ export function AiTerminal({
|
|
|
147
192
|
|
|
148
193
|
// Format the initial messages for display
|
|
149
194
|
const formattedMessages = options.initialMessages.map((message) => {
|
|
150
|
-
const formattedContent =
|
|
151
|
-
message.content
|
|
152
|
-
?.trim()
|
|
153
|
-
?.replaceAll("\n", "<br>")
|
|
154
|
-
?.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>") || "";
|
|
195
|
+
const formattedContent = formatMessageContent(message.content || "");
|
|
155
196
|
|
|
156
197
|
return {
|
|
157
198
|
...message,
|
|
@@ -161,8 +202,6 @@ export function AiTerminal({
|
|
|
161
202
|
};
|
|
162
203
|
});
|
|
163
204
|
|
|
164
|
-
console.log("AiTerminal: Formatted messages", formattedMessages);
|
|
165
|
-
|
|
166
205
|
// Update the internal message states
|
|
167
206
|
setMessages(formattedMessages);
|
|
168
207
|
setResponseMessages(formattedMessages);
|
|
@@ -171,52 +210,85 @@ export function AiTerminal({
|
|
|
171
210
|
const initialResponse: Response = {
|
|
172
211
|
messages: formattedMessages,
|
|
173
212
|
editOperations: [],
|
|
174
|
-
numInputTokens: 0,
|
|
175
|
-
numOutputTokens: 0,
|
|
176
|
-
numCachedTokens: 0,
|
|
213
|
+
numInputTokens: options?.totalInputTokens || 0,
|
|
214
|
+
numOutputTokens: options?.totalOutputTokens || 0,
|
|
215
|
+
numCachedTokens: options?.totalCachedTokens || 0,
|
|
177
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,
|
|
178
225
|
};
|
|
179
226
|
|
|
180
|
-
console.log("AiTerminal: Setting response", initialResponse);
|
|
181
227
|
setResponse(initialResponse);
|
|
182
228
|
|
|
183
229
|
// Create individual Terminal messages for each conversation message
|
|
184
230
|
const terminalMessages: TerminalMessage[] = [];
|
|
185
231
|
|
|
186
|
-
|
|
232
|
+
// Group messages by conversation turns (user + assistant pairs)
|
|
233
|
+
let i = 0;
|
|
234
|
+
while (i < formattedMessages.length) {
|
|
235
|
+
const message = formattedMessages[i];
|
|
236
|
+
if (!message) {
|
|
237
|
+
i++;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
|
|
187
241
|
if (message.role === "user") {
|
|
188
242
|
// User messages appear as commands
|
|
189
243
|
terminalMessages.push({
|
|
190
244
|
type: "command",
|
|
191
245
|
text: message.content,
|
|
192
246
|
});
|
|
247
|
+
i++;
|
|
248
|
+
|
|
249
|
+
// Look for following assistant messages to group together
|
|
250
|
+
const assistantMessages: Message[] = [];
|
|
251
|
+
while (i < formattedMessages.length) {
|
|
252
|
+
const assistantMessage = formattedMessages[i];
|
|
253
|
+
if (assistantMessage && assistantMessage.role === "assistant") {
|
|
254
|
+
assistantMessages.push(assistantMessage);
|
|
255
|
+
i++;
|
|
256
|
+
} else {
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// If we have assistant messages, render them with AiResponseMessage
|
|
262
|
+
if (assistantMessages.length > 0) {
|
|
263
|
+
terminalMessages.push({
|
|
264
|
+
type: "response",
|
|
265
|
+
text: (
|
|
266
|
+
<AiResponseMessage
|
|
267
|
+
messages={assistantMessages}
|
|
268
|
+
editOperations={[]} // No edit operations for historical messages
|
|
269
|
+
finished={true}
|
|
270
|
+
/>
|
|
271
|
+
),
|
|
272
|
+
});
|
|
273
|
+
}
|
|
193
274
|
} else if (message.role === "assistant") {
|
|
194
|
-
//
|
|
275
|
+
// Handle standalone assistant messages
|
|
195
276
|
terminalMessages.push({
|
|
196
277
|
type: "response",
|
|
197
278
|
text: (
|
|
198
|
-
<
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
279
|
+
<AiResponseMessage
|
|
280
|
+
messages={[message]}
|
|
281
|
+
editOperations={[]} // No edit operations for historical messages
|
|
282
|
+
finished={true}
|
|
202
283
|
/>
|
|
203
284
|
),
|
|
204
285
|
});
|
|
286
|
+
i++;
|
|
287
|
+
} else {
|
|
288
|
+
// Skip other message types (like tool messages)
|
|
289
|
+
i++;
|
|
205
290
|
}
|
|
206
|
-
|
|
207
|
-
if (message.tool_calls && message.tool_calls.length > 0) {
|
|
208
|
-
message.tool_calls.forEach((toolCall) => {
|
|
209
|
-
terminalMessages.push({
|
|
210
|
-
type: "response",
|
|
211
|
-
text: (
|
|
212
|
-
<div className="text-xs text-gray-1">
|
|
213
|
-
🔧 {toolCall.displayName}
|
|
214
|
-
</div>
|
|
215
|
-
),
|
|
216
|
-
})
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
|
-
});
|
|
291
|
+
}
|
|
220
292
|
|
|
221
293
|
setInitialTerminalMessages(terminalMessages);
|
|
222
294
|
}
|
|
@@ -251,11 +323,7 @@ export function AiTerminal({
|
|
|
251
323
|
// Replace the conversation history with the authoritative response from AI
|
|
252
324
|
if (updatedMessages && Array.isArray(updatedMessages)) {
|
|
253
325
|
const formattedMessages = updatedMessages.map((message) => {
|
|
254
|
-
const formattedContent =
|
|
255
|
-
message.content
|
|
256
|
-
?.trim()
|
|
257
|
-
?.replaceAll("\n", "<br>")
|
|
258
|
-
?.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>") || "";
|
|
326
|
+
const formattedContent = formatMessageContent(message.content || "");
|
|
259
327
|
|
|
260
328
|
return {
|
|
261
329
|
...message,
|
|
@@ -304,12 +372,10 @@ export function AiTerminal({
|
|
|
304
372
|
|
|
305
373
|
const context = createAiContext({ editContext });
|
|
306
374
|
|
|
307
|
-
let lastOpIndex = 0;
|
|
308
375
|
const selectedText = editContext?.selectedRange?.text || null;
|
|
309
376
|
if (!activeProfile || !model) return;
|
|
310
377
|
|
|
311
|
-
//
|
|
312
|
-
const conversationHistory = [...messagesRef.current, userMessage];
|
|
378
|
+
// Only send the new user message - message history will be loaded from database
|
|
313
379
|
const messages = [
|
|
314
380
|
...(options?.hiddenSystemPrompt
|
|
315
381
|
? [
|
|
@@ -322,44 +388,425 @@ export function AiTerminal({
|
|
|
322
388
|
},
|
|
323
389
|
]
|
|
324
390
|
: []),
|
|
325
|
-
|
|
391
|
+
userMessage, // Send only the new user message
|
|
326
392
|
];
|
|
327
393
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
394
|
+
// Update local state to include the new user message for UI display
|
|
395
|
+
setMessages((prevMessages) => [...prevMessages, userMessage]);
|
|
396
|
+
setResponseMessages((prevMessages) => [...prevMessages, userMessage]);
|
|
397
|
+
|
|
398
|
+
try {
|
|
399
|
+
// Step 1: Start the agent execution
|
|
400
|
+
const startRequest: StartAgentRequest = {
|
|
401
|
+
agentId,
|
|
402
|
+
messages,
|
|
403
|
+
sessionId: editContext!.sessionId,
|
|
332
404
|
profileId: activeProfile.id,
|
|
333
|
-
selection,
|
|
334
|
-
selectedText,
|
|
335
405
|
model,
|
|
336
|
-
|
|
337
|
-
|
|
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,
|
|
338
414
|
addSelectedComponents: true,
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
(response: any) => {
|
|
342
|
-
setResponse(response);
|
|
343
|
-
handleResponse(response, callback, false);
|
|
344
|
-
},
|
|
345
|
-
);
|
|
346
|
-
|
|
347
|
-
if (response) {
|
|
348
|
-
handleResponse(response, callback, true);
|
|
349
|
-
if (context.callback) context.callback(response);
|
|
350
|
-
editContext?.requestRefresh("immediate");
|
|
351
|
-
}
|
|
415
|
+
profile: activeProfile.name,
|
|
416
|
+
};
|
|
352
417
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// content: response.responseText,
|
|
356
|
-
// role: "assistant",
|
|
357
|
-
// name: "assistant",
|
|
358
|
-
// });
|
|
418
|
+
const startResponse = await startAgent(startRequest, context);
|
|
419
|
+
console.log("Agent started:", startResponse);
|
|
359
420
|
|
|
360
|
-
|
|
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
|
+
);
|
|
361
769
|
|
|
362
|
-
|
|
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
|
+
}
|
|
363
810
|
}
|
|
364
811
|
|
|
365
812
|
useEffect(() => {
|
|
@@ -385,22 +832,44 @@ export function AiTerminal({
|
|
|
385
832
|
setResponseMessages([]);
|
|
386
833
|
setResponse(undefined);
|
|
387
834
|
setInitialTerminalMessages(undefined);
|
|
835
|
+
// Generate a new agentId when clearing the terminal to start fresh
|
|
836
|
+
setAgentId(crypto.randomUUID());
|
|
388
837
|
}}
|
|
389
838
|
initialMessages={initialTerminalMessages}
|
|
390
839
|
infobar={
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
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
|
+
/>
|
|
404
873
|
}
|
|
405
874
|
prompt={prompt}
|
|
406
875
|
setPrompt={setPrompt}
|
|
@@ -475,6 +944,8 @@ export function AiTerminal({
|
|
|
475
944
|
value={model}
|
|
476
945
|
onChange={(e) => setModel(e.value)}
|
|
477
946
|
options={activeProfile.models}
|
|
947
|
+
optionLabel="name"
|
|
948
|
+
optionValue="id"
|
|
478
949
|
/>
|
|
479
950
|
</div>
|
|
480
951
|
)}
|