@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
|
@@ -1,4 +1,48 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AiContext } from "../ai/AiTerminal";
|
|
2
|
+
|
|
3
|
+
export const AGENT_BASE_URL = "/alpaca/editor/agent";
|
|
4
|
+
|
|
5
|
+
export interface StartAgentRequest {
|
|
6
|
+
agentId: string;
|
|
7
|
+
messages: any[];
|
|
8
|
+
sessionId: string;
|
|
9
|
+
profileId: string;
|
|
10
|
+
model?: string;
|
|
11
|
+
itemid: string;
|
|
12
|
+
language: string;
|
|
13
|
+
version: number;
|
|
14
|
+
selection?: string[];
|
|
15
|
+
selectedText?: string;
|
|
16
|
+
allowedFunctions?: string[];
|
|
17
|
+
addContextContent?: boolean;
|
|
18
|
+
addAllContent?: boolean;
|
|
19
|
+
addSelectedComponents?: boolean;
|
|
20
|
+
profile?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface StartAgentResponse {
|
|
24
|
+
agentId: string;
|
|
25
|
+
status: string;
|
|
26
|
+
message: string;
|
|
27
|
+
startedAt: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface AgentStreamMessage {
|
|
31
|
+
type: string;
|
|
32
|
+
data: any;
|
|
33
|
+
timestamp: string;
|
|
34
|
+
error?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export enum AgentStreamMessageType {
|
|
38
|
+
StatusUpdate = "StatusUpdate",
|
|
39
|
+
ContentChunk = "ContentChunk",
|
|
40
|
+
ToolCall = "ToolCall",
|
|
41
|
+
ToolResult = "ToolResult",
|
|
42
|
+
EditOperations = "EditOperations",
|
|
43
|
+
Completed = "Completed",
|
|
44
|
+
Error = "Error",
|
|
45
|
+
}
|
|
2
46
|
|
|
3
47
|
export interface AgentChat {
|
|
4
48
|
id: string;
|
|
@@ -13,13 +57,19 @@ export interface AgentChat {
|
|
|
13
57
|
profileId?: string;
|
|
14
58
|
profileName: string;
|
|
15
59
|
model: string;
|
|
16
|
-
status:
|
|
60
|
+
status: string;
|
|
17
61
|
createdDate: string;
|
|
18
62
|
updatedDate: string;
|
|
19
63
|
lastMessageDate?: string;
|
|
20
64
|
totalTokensUsed: number;
|
|
21
65
|
totalInputTokens: number;
|
|
22
66
|
totalOutputTokens: number;
|
|
67
|
+
totalCachedInputTokens: number;
|
|
68
|
+
totalInputTokenCost: number;
|
|
69
|
+
totalOutputTokenCost: number;
|
|
70
|
+
totalCachedInputTokenCost: number;
|
|
71
|
+
totalCost: number;
|
|
72
|
+
currency: string;
|
|
23
73
|
messageCount: number;
|
|
24
74
|
metadata?: string;
|
|
25
75
|
messages?: AgentChatMessage[];
|
|
@@ -32,28 +82,34 @@ export interface AgentChatMessage {
|
|
|
32
82
|
role: string;
|
|
33
83
|
content: string;
|
|
34
84
|
name: string;
|
|
35
|
-
toolCallId?: string;
|
|
36
|
-
messageType
|
|
85
|
+
toolCallId?: string;
|
|
86
|
+
messageType: string;
|
|
37
87
|
isCompleted: boolean;
|
|
38
|
-
model
|
|
88
|
+
model: string;
|
|
39
89
|
tokensUsed: number;
|
|
40
90
|
inputTokens: number;
|
|
41
91
|
outputTokens: number;
|
|
92
|
+
cachedInputTokens: number;
|
|
93
|
+
inputTokenCost: number;
|
|
94
|
+
outputTokenCost: number;
|
|
95
|
+
cachedInputTokenCost: number;
|
|
96
|
+
totalCost: number;
|
|
97
|
+
currency: string;
|
|
42
98
|
responseTimeMs?: number;
|
|
43
99
|
createdDate: string;
|
|
44
|
-
editOperations?:
|
|
45
|
-
longRunningTaskIds?: string
|
|
100
|
+
editOperations?: string;
|
|
101
|
+
longRunningTaskIds?: string;
|
|
46
102
|
metadata?: string;
|
|
47
|
-
toolCalls?: AgentChatToolCall[];
|
|
103
|
+
toolCalls?: AgentChatToolCall[];
|
|
48
104
|
}
|
|
49
105
|
|
|
50
106
|
export interface AgentChatToolCall {
|
|
51
107
|
id: string;
|
|
52
108
|
messageId: string;
|
|
53
|
-
toolCallId: string;
|
|
109
|
+
toolCallId: string;
|
|
54
110
|
functionName: string;
|
|
55
|
-
functionArguments
|
|
56
|
-
functionResult?:
|
|
111
|
+
functionArguments: string;
|
|
112
|
+
functionResult?: string;
|
|
57
113
|
functionError?: string;
|
|
58
114
|
isCompleted: boolean;
|
|
59
115
|
responseTimeMs?: number;
|
|
@@ -61,34 +117,352 @@ export interface AgentChatToolCall {
|
|
|
61
117
|
}
|
|
62
118
|
|
|
63
119
|
/**
|
|
64
|
-
*
|
|
120
|
+
* Starts an agent execution and returns immediately
|
|
65
121
|
*/
|
|
66
|
-
export async function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
) {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
122
|
+
export async function startAgent(
|
|
123
|
+
request: StartAgentRequest,
|
|
124
|
+
context: AiContext,
|
|
125
|
+
): Promise<StartAgentResponse> {
|
|
126
|
+
const response = await fetch(AGENT_BASE_URL + "/start", {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: {
|
|
129
|
+
"Content-Type": "application/json",
|
|
130
|
+
},
|
|
131
|
+
body: JSON.stringify(request),
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
if (!response.ok) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
`Failed to start agent: ${response.status} ${response.statusText}`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return await response.json();
|
|
73
141
|
}
|
|
74
142
|
|
|
75
143
|
/**
|
|
76
|
-
*
|
|
144
|
+
* Connects to an agent's real-time stream using Server-Sent Events
|
|
77
145
|
*/
|
|
78
|
-
export async function
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
146
|
+
export async function connectToAgentStream(
|
|
147
|
+
agentId: string,
|
|
148
|
+
context: AiContext,
|
|
149
|
+
onMessage: (message: AgentStreamMessage) => void,
|
|
150
|
+
signal?: AbortSignal,
|
|
151
|
+
): Promise<void> {
|
|
152
|
+
// Add cache-busting timestamp to prevent browser connection reuse
|
|
153
|
+
const timestamp = Date.now();
|
|
154
|
+
const streamUrl =
|
|
155
|
+
AGENT_BASE_URL + "/stream?agentId=" + agentId + "&t=" + timestamp;
|
|
156
|
+
|
|
157
|
+
// Retry logic to handle potential race conditions
|
|
158
|
+
let retryCount = 0;
|
|
159
|
+
const maxRetries = 3;
|
|
160
|
+
const retryDelay = 500; // 500ms
|
|
161
|
+
|
|
162
|
+
while (retryCount <= maxRetries) {
|
|
163
|
+
try {
|
|
164
|
+
const response = await fetch(streamUrl, {
|
|
165
|
+
headers: {
|
|
166
|
+
Accept: "text/event-stream",
|
|
167
|
+
"Cache-Control": "no-cache",
|
|
168
|
+
Pragma: "no-cache",
|
|
169
|
+
},
|
|
170
|
+
cache: "no-store",
|
|
171
|
+
signal,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
if (response.ok) {
|
|
175
|
+
// Success - proceed with stream processing
|
|
176
|
+
await processEventStream(response, onMessage);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// If 404 and we haven't maxed out retries, wait and retry
|
|
181
|
+
if (response.status === 404 && retryCount < maxRetries) {
|
|
182
|
+
retryCount++;
|
|
183
|
+
console.warn(
|
|
184
|
+
`Agent stream not ready (404), retrying in ${retryDelay}ms... (${retryCount}/${maxRetries})`,
|
|
185
|
+
);
|
|
186
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// For other errors or max retries reached, throw
|
|
191
|
+
throw new Error(
|
|
192
|
+
`Failed to connect to agent stream: ${response.status} ${response.statusText}`,
|
|
193
|
+
);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
if (signal?.aborted) {
|
|
196
|
+
throw error; // Don't retry if cancelled
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (retryCount >= maxRetries) {
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
retryCount++;
|
|
204
|
+
console.warn(
|
|
205
|
+
`Error connecting to agent stream, retrying... (${retryCount}/${maxRetries})`,
|
|
206
|
+
error,
|
|
207
|
+
);
|
|
208
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Processes the event stream response
|
|
215
|
+
*/
|
|
216
|
+
async function processEventStream(
|
|
217
|
+
response: Response,
|
|
218
|
+
onMessage: (message: AgentStreamMessage) => void,
|
|
219
|
+
): Promise<void> {
|
|
220
|
+
const reader = response.body?.getReader();
|
|
221
|
+
if (!reader) {
|
|
222
|
+
throw new Error("Failed to get stream reader");
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const decoder = new TextDecoder();
|
|
226
|
+
let buffer = "";
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
while (true) {
|
|
230
|
+
const { done, value } = await reader.read();
|
|
231
|
+
|
|
232
|
+
if (done) {
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
buffer += decoder.decode(value, { stream: true });
|
|
237
|
+
|
|
238
|
+
// Process complete messages
|
|
239
|
+
const lines = buffer.split("\n");
|
|
240
|
+
|
|
241
|
+
// Only keep the last line if it doesn't end with a newline (incomplete)
|
|
242
|
+
// If the buffer ends with \n, then all lines are complete
|
|
243
|
+
if (buffer.endsWith("\n")) {
|
|
244
|
+
// All lines are complete, process them all
|
|
245
|
+
buffer = "";
|
|
246
|
+
} else {
|
|
247
|
+
// Last line might be incomplete, keep it for next iteration
|
|
248
|
+
buffer = lines.pop() || "";
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
for (const line of lines) {
|
|
252
|
+
if (line.startsWith("data: ")) {
|
|
253
|
+
try {
|
|
254
|
+
const data = line.slice(6); // Remove 'data: ' prefix
|
|
255
|
+
if (data.trim()) {
|
|
256
|
+
const message: AgentStreamMessage = JSON.parse(data);
|
|
257
|
+
|
|
258
|
+
// Normalize message type (handle both numeric and string enum values)
|
|
259
|
+
if (typeof message.type === "number") {
|
|
260
|
+
switch (message.type) {
|
|
261
|
+
case 0:
|
|
262
|
+
message.type = AgentStreamMessageType.StatusUpdate;
|
|
263
|
+
break;
|
|
264
|
+
case 1:
|
|
265
|
+
message.type = AgentStreamMessageType.ContentChunk;
|
|
266
|
+
break;
|
|
267
|
+
case 2:
|
|
268
|
+
message.type = AgentStreamMessageType.ToolCall;
|
|
269
|
+
break;
|
|
270
|
+
case 3:
|
|
271
|
+
message.type = AgentStreamMessageType.ToolResult;
|
|
272
|
+
break;
|
|
273
|
+
case 4:
|
|
274
|
+
message.type = AgentStreamMessageType.EditOperations;
|
|
275
|
+
break;
|
|
276
|
+
case 5:
|
|
277
|
+
message.type = AgentStreamMessageType.Completed;
|
|
278
|
+
break;
|
|
279
|
+
case 6:
|
|
280
|
+
message.type = AgentStreamMessageType.Error;
|
|
281
|
+
break;
|
|
282
|
+
default:
|
|
283
|
+
message.type = `Unknown_${message.type}`;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
onMessage(message);
|
|
288
|
+
|
|
289
|
+
// Break on completion or error
|
|
290
|
+
if (
|
|
291
|
+
message.type === AgentStreamMessageType.Completed ||
|
|
292
|
+
message.type === AgentStreamMessageType.Error
|
|
293
|
+
) {
|
|
294
|
+
// console.log("Stream ending due to message type:", message.type);
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
} catch (error) {
|
|
299
|
+
console.error("Failed to parse SSE message:", error, line);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
} finally {
|
|
305
|
+
// console.log("Stream ended, releasing reader lock");
|
|
306
|
+
reader.releaseLock();
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Gets the current status of an agent execution
|
|
312
|
+
*/
|
|
313
|
+
export async function getAgentStatus(
|
|
314
|
+
agentId: string,
|
|
315
|
+
context: AiContext,
|
|
316
|
+
): Promise<any> {
|
|
317
|
+
const response = await fetch(
|
|
318
|
+
AGENT_BASE_URL + "/getAgentStatus?agentId=" + agentId,
|
|
319
|
+
{
|
|
320
|
+
method: "GET",
|
|
321
|
+
headers: {
|
|
322
|
+
"Content-Type": "application/json",
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
if (!response.ok) {
|
|
328
|
+
throw new Error(
|
|
329
|
+
`Failed to get agent status: ${response.status} ${response.statusText}`,
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return await response.json();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Gets all currently running agents for monitoring
|
|
338
|
+
*/
|
|
339
|
+
export async function getRunningAgents(context: AiContext): Promise<any> {
|
|
340
|
+
const response = await fetch(AGENT_BASE_URL + "/getRunningAgents", {
|
|
341
|
+
method: "GET",
|
|
342
|
+
headers: {
|
|
343
|
+
"Content-Type": "application/json",
|
|
344
|
+
},
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
if (!response.ok) {
|
|
348
|
+
throw new Error(
|
|
349
|
+
`Failed to get running agents: ${response.status} ${response.statusText}`,
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return await response.json();
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Gets a single agent by ID with complete message history and cost information
|
|
358
|
+
*/
|
|
359
|
+
export async function getAgent(
|
|
360
|
+
agentId: string,
|
|
361
|
+
context: AiContext,
|
|
362
|
+
): Promise<any> {
|
|
363
|
+
const response = await fetch(
|
|
364
|
+
AGENT_BASE_URL + "/getAgent?agentId=" + agentId,
|
|
365
|
+
{
|
|
366
|
+
method: "GET",
|
|
367
|
+
headers: {
|
|
368
|
+
"Content-Type": "application/json",
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
if (!response.ok) {
|
|
374
|
+
throw new Error(
|
|
375
|
+
`Failed to get agent: ${response.status} ${response.statusText}`,
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return await response.json();
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Gets all agents for the current user
|
|
384
|
+
*/
|
|
385
|
+
export async function getAgents(
|
|
386
|
+
context: AiContext,
|
|
387
|
+
status?: string,
|
|
388
|
+
limit?: number,
|
|
389
|
+
): Promise<any> {
|
|
390
|
+
const params = new URLSearchParams();
|
|
391
|
+
if (status) params.append("status", status);
|
|
392
|
+
if (limit) params.append("limit", limit.toString());
|
|
393
|
+
|
|
394
|
+
const queryString = params.toString();
|
|
395
|
+
const url =
|
|
396
|
+
AGENT_BASE_URL + "/getAgents" + (queryString ? `?${queryString}` : "");
|
|
397
|
+
|
|
398
|
+
const response = await fetch(url, {
|
|
399
|
+
method: "GET",
|
|
400
|
+
headers: {
|
|
401
|
+
"Content-Type": "application/json",
|
|
402
|
+
},
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
if (!response.ok) {
|
|
406
|
+
throw new Error(
|
|
407
|
+
`Failed to get agents: ${response.status} ${response.statusText}`,
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return await response.json();
|
|
82
412
|
}
|
|
83
413
|
|
|
84
414
|
/**
|
|
85
415
|
* Gets chat history for the current user
|
|
86
416
|
*/
|
|
87
417
|
export async function getChatHistory(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
418
|
+
context: AiContext,
|
|
419
|
+
status?: string,
|
|
420
|
+
limit?: number,
|
|
421
|
+
): Promise<any> {
|
|
422
|
+
const params = new URLSearchParams();
|
|
423
|
+
if (status) params.append("status", status);
|
|
424
|
+
if (limit) params.append("limit", limit.toString());
|
|
425
|
+
|
|
426
|
+
const queryString = params.toString();
|
|
427
|
+
const url =
|
|
428
|
+
AGENT_BASE_URL + "/chatHistory" + (queryString ? `?${queryString}` : "");
|
|
429
|
+
|
|
430
|
+
const response = await fetch(url, {
|
|
431
|
+
method: "GET",
|
|
432
|
+
headers: {
|
|
433
|
+
"Content-Type": "application/json",
|
|
434
|
+
},
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
if (!response.ok) {
|
|
438
|
+
throw new Error(
|
|
439
|
+
`Failed to get chat history: ${response.status} ${response.statusText}`,
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return await response.json();
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Cancels a running agent execution
|
|
448
|
+
*/
|
|
449
|
+
export async function cancelAgent(
|
|
450
|
+
agentId: string,
|
|
451
|
+
context: AiContext,
|
|
452
|
+
): Promise<any> {
|
|
453
|
+
const response = await fetch(AGENT_BASE_URL + "/cancelAgent", {
|
|
454
|
+
method: "POST",
|
|
455
|
+
headers: {
|
|
456
|
+
"Content-Type": "application/json",
|
|
457
|
+
},
|
|
458
|
+
body: JSON.stringify({ agentId }),
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
if (!response.ok) {
|
|
462
|
+
throw new Error(
|
|
463
|
+
`Failed to cancel agent: ${response.status} ${response.statusText}`,
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return await response.json();
|
|
468
|
+
}
|
|
@@ -5,12 +5,17 @@ import { JsonCleaner } from "../utils/jsonCleaner";
|
|
|
5
5
|
|
|
6
6
|
import { ExecutionResult, get, post } from "./serviceHelper";
|
|
7
7
|
|
|
8
|
+
export type AiModel = {
|
|
9
|
+
id: string; // Guid as string
|
|
10
|
+
name: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
8
13
|
export type AiProfile = {
|
|
9
14
|
id: string;
|
|
10
15
|
name: string;
|
|
11
16
|
instructions: string;
|
|
12
|
-
defaultModel: string;
|
|
13
|
-
models:
|
|
17
|
+
defaultModel: string | null; // Guid as string, nullable
|
|
18
|
+
models: AiModel[]; // Array of model objects with id and name
|
|
14
19
|
prompts: { prompt: string; title: string }[];
|
|
15
20
|
errorMessage?: string;
|
|
16
21
|
};
|
|
@@ -50,6 +55,17 @@ export interface ExecutePromptResponse {
|
|
|
50
55
|
deltaContent?: string;
|
|
51
56
|
previousContentLength?: number;
|
|
52
57
|
totalContentLength?: number;
|
|
58
|
+
// Updated agent name (only sent when the agent name has been updated)
|
|
59
|
+
agentName?: string;
|
|
60
|
+
totalCost?: number;
|
|
61
|
+
totalInputTokenCost?: number;
|
|
62
|
+
totalOutputTokenCost?: number;
|
|
63
|
+
totalCachedTokenCost?: number;
|
|
64
|
+
totalInputTokens?: number;
|
|
65
|
+
totalOutputTokens?: number;
|
|
66
|
+
totalCachedTokens?: number;
|
|
67
|
+
totalTokens?: number;
|
|
68
|
+
totalMessages?: number;
|
|
53
69
|
}
|
|
54
70
|
|
|
55
71
|
// Unified options interface that supports both calling patterns
|
|
@@ -57,6 +73,7 @@ export interface ExecutePromptOptions {
|
|
|
57
73
|
// Common options
|
|
58
74
|
sessionId?: string | null;
|
|
59
75
|
model?: string | null;
|
|
76
|
+
stream?: boolean;
|
|
60
77
|
|
|
61
78
|
// AiTerminal style options
|
|
62
79
|
profileId?: string;
|
|
@@ -84,6 +101,7 @@ export async function executePrompt(
|
|
|
84
101
|
options: ExecutePromptOptions = {},
|
|
85
102
|
requestOptions?: RequestInit,
|
|
86
103
|
callback?: (response: any) => void,
|
|
104
|
+
stream?: boolean,
|
|
87
105
|
): Promise<ExecutePromptResponse | null> {
|
|
88
106
|
let endpoint: string;
|
|
89
107
|
let requestBody: any;
|
|
@@ -91,7 +109,7 @@ export async function executePrompt(
|
|
|
91
109
|
|
|
92
110
|
// Handle context - either direct AiContext or need to create it
|
|
93
111
|
let aiContext: AiContext;
|
|
94
|
-
if ("
|
|
112
|
+
if ("promptData" in context) {
|
|
95
113
|
// Direct AiContext (AiTerminal style)
|
|
96
114
|
aiContext = context;
|
|
97
115
|
} else {
|
|
@@ -103,7 +121,8 @@ export async function executePrompt(
|
|
|
103
121
|
}
|
|
104
122
|
}
|
|
105
123
|
|
|
106
|
-
endpoint
|
|
124
|
+
// Use hardcoded endpoint for old prompt system
|
|
125
|
+
endpoint = "/alpaca/editor/ai/Prompt";
|
|
107
126
|
|
|
108
127
|
// Build unified request body
|
|
109
128
|
requestBody = {
|
|
@@ -111,7 +130,7 @@ export async function executePrompt(
|
|
|
111
130
|
...aiContext.promptData,
|
|
112
131
|
sessionId: options.sessionId,
|
|
113
132
|
model: options.model,
|
|
114
|
-
|
|
133
|
+
stream: stream,
|
|
115
134
|
// Include all provided options
|
|
116
135
|
...options,
|
|
117
136
|
};
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { get, post } from "./serviceHelper";
|
|
2
|
-
import { SystemStatus, UserPreferences } from "../../types";
|
|
2
|
+
import { SystemStatus, UserPreferences, EditorSettings } from "../../types";
|
|
3
|
+
|
|
3
4
|
export function getSystemStatus() {
|
|
4
5
|
return get<SystemStatus>("/alpaca/editor/status");
|
|
5
6
|
}
|
|
7
|
+
|
|
8
|
+
export function getEditorSettings() {
|
|
9
|
+
return get<EditorSettings>("/alpaca/editor/settings");
|
|
10
|
+
}
|
|
11
|
+
|
|
6
12
|
export function saveUserPreferences(preferences: UserPreferences) {
|
|
7
13
|
return post<UserPreferences>("/alpaca/editor/savepreferences", preferences);
|
|
8
14
|
}
|
|
@@ -64,7 +64,10 @@ export function ComponentPalette({}: {}) {
|
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
return (
|
|
67
|
-
<div
|
|
67
|
+
<div
|
|
68
|
+
className="tour-component-palette relative flex h-full flex-col"
|
|
69
|
+
data-testid="component-palette"
|
|
70
|
+
>
|
|
68
71
|
<div className="p-4">
|
|
69
72
|
<FilterInput
|
|
70
73
|
ref={filterRef}
|
|
@@ -46,6 +46,7 @@ export function EditHistory() {
|
|
|
46
46
|
}}
|
|
47
47
|
icon={undoCommand.icon}
|
|
48
48
|
label={undoCommand.label}
|
|
49
|
+
data-testid="undo-button"
|
|
49
50
|
disabled={editContext.isCommandDisabled({ command: undoCommand })}
|
|
50
51
|
/>
|
|
51
52
|
<SimpleIconButton
|
|
@@ -54,6 +55,7 @@ export function EditHistory() {
|
|
|
54
55
|
}}
|
|
55
56
|
icon={redoCommand.icon}
|
|
56
57
|
label={redoCommand.label}
|
|
58
|
+
data-testid="redo-button"
|
|
57
59
|
disabled={editContext.isCommandDisabled({ command: redoCommand })}
|
|
58
60
|
/>
|
|
59
61
|
</SimpleToolbar>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import "@uiw/react-textarea-code-editor/dist.css";
|
|
2
|
+
|
|
1
3
|
import { Splitter, SplitterPanel } from "primereact/splitter";
|
|
2
|
-
import
|
|
4
|
+
import CodeEditor from "@uiw/react-textarea-code-editor";
|
|
3
5
|
import { ActionButton } from "../../components/ActionButton";
|
|
4
6
|
import { useEffect, useState } from "react";
|
|
5
7
|
|
|
@@ -256,12 +258,22 @@ export function GraphQL() {
|
|
|
256
258
|
<Splitter layout="horizontal" style={{ height: "100%" }}>
|
|
257
259
|
<SplitterPanel size={50} className="relative">
|
|
258
260
|
<div className="absolute inset-0 flex items-stretch">
|
|
259
|
-
<
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
261
|
+
<div className="min-w-0 flex-1">
|
|
262
|
+
<CodeEditor
|
|
263
|
+
value={query}
|
|
264
|
+
language="graphql"
|
|
265
|
+
placeholder="Enter your GraphQL query here..."
|
|
266
|
+
onChange={(evn: any) => setQuery(evn.target.value)}
|
|
267
|
+
padding={15}
|
|
268
|
+
style={{
|
|
269
|
+
fontSize: 12,
|
|
270
|
+
backgroundColor: "#f8f9fa",
|
|
271
|
+
fontFamily:
|
|
272
|
+
"ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace",
|
|
273
|
+
height: "100%",
|
|
274
|
+
}}
|
|
275
|
+
/>
|
|
276
|
+
</div>
|
|
265
277
|
<ActionButton
|
|
266
278
|
onClick={refresh}
|
|
267
279
|
disabled={showSpinner}
|
|
@@ -67,7 +67,7 @@ export function SEOInfo() {
|
|
|
67
67
|
|
|
68
68
|
// Try to send AI analysis request
|
|
69
69
|
const aiServiceUrl =
|
|
70
|
-
editContext.configuration.services.aiService.
|
|
70
|
+
editContext.configuration.services.aiService.endpoint;
|
|
71
71
|
console.log("AI Service URL:", aiServiceUrl);
|
|
72
72
|
|
|
73
73
|
if (!aiServiceUrl) {
|