@parhelia/core 0.1.12496 → 0.1.12515
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/agents-view/AgentCard.js +20 -19
- package/dist/agents-view/AgentCard.js.map +1 -1
- package/dist/agents-view/AgentsInbox.js +2 -13
- package/dist/agents-view/AgentsInbox.js.map +1 -1
- package/dist/agents-view/AgentsView.js +7 -55
- package/dist/agents-view/AgentsView.js.map +1 -1
- package/dist/agents-view/AgentsWorkspaceView.js +2 -11
- package/dist/agents-view/AgentsWorkspaceView.js.map +1 -1
- package/dist/components/ui/copy-button.d.ts +2 -1
- package/dist/components/ui/copy-button.js +2 -2
- package/dist/components/ui/copy-button.js.map +1 -1
- package/dist/components/ui/paste-button.d.ts +2 -1
- package/dist/components/ui/paste-button.js +2 -2
- package/dist/components/ui/paste-button.js.map +1 -1
- package/dist/config/config.js +40 -0
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +23 -5
- package/dist/config/types.js.map +1 -1
- package/dist/editor/ContentTree.js +36 -4
- package/dist/editor/ContentTree.js.map +1 -1
- package/dist/editor/FieldListField.js +4 -4
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/FieldListFieldWithFallbacks.js +23 -2
- package/dist/editor/FieldListFieldWithFallbacks.js.map +1 -1
- package/dist/editor/GlobalMenuBar.js +1 -1
- package/dist/editor/GlobalMenuBar.js.map +1 -1
- package/dist/editor/ItemInfo.js +36 -1
- package/dist/editor/ItemInfo.js.map +1 -1
- package/dist/editor/MainLayout.d.ts +0 -2
- package/dist/editor/MainLayout.js +0 -1
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/Titlebar.js +2 -2
- package/dist/editor/Titlebar.js.map +1 -1
- package/dist/editor/ai/AgentStatusBadge.d.ts +0 -5
- package/dist/editor/ai/AgentStatusBadge.js +57 -71
- package/dist/editor/ai/AgentStatusBadge.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.js +51 -89
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/Agents.js +8 -63
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/InlineAiDialog.js +1 -6
- package/dist/editor/ai/InlineAiDialog.js.map +1 -1
- package/dist/editor/ai/ToolCallDisplay.js +152 -63
- package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
- package/dist/editor/ai/useAgentStatus.js +12 -85
- package/dist/editor/ai/useAgentStatus.js.map +1 -1
- package/dist/editor/client/EditorShell.js +49 -59
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +3 -15
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/hooks/useEditorUrlSync.js +1 -2
- package/dist/editor/client/hooks/useEditorUrlSync.js.map +1 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.js +19 -6
- package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
- package/dist/editor/client/operations.js +15 -3
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/client/ui/EditorChrome.d.ts +0 -4
- package/dist/editor/client/ui/EditorChrome.js.map +1 -1
- package/dist/editor/client/waitForEditOperationTerminal.d.ts +8 -3
- package/dist/editor/client/waitForEditOperationTerminal.js +5 -1
- package/dist/editor/client/waitForEditOperationTerminal.js.map +1 -1
- package/dist/editor/commands/itemCommands.js +5 -0
- package/dist/editor/commands/itemCommands.js.map +1 -1
- package/dist/editor/content-tree/IndicatorSettings.d.ts +11 -0
- package/dist/editor/content-tree/IndicatorSettings.js +60 -0
- package/dist/editor/content-tree/IndicatorSettings.js.map +1 -0
- package/dist/editor/content-tree/TreeOptions.d.ts +6 -0
- package/dist/editor/content-tree/TreeOptions.js +8 -0
- package/dist/editor/content-tree/TreeOptions.js.map +1 -0
- package/dist/editor/content-tree/TreeSettingsMenu.d.ts +2 -0
- package/dist/editor/content-tree/TreeSettingsMenu.js +30 -0
- package/dist/editor/content-tree/TreeSettingsMenu.js.map +1 -0
- package/dist/editor/hooks/useNavigationPanelLogic.js +2 -6
- package/dist/editor/hooks/useNavigationPanelLogic.js.map +1 -1
- package/dist/editor/manualActionEvents.d.ts +8 -0
- package/dist/editor/manualActionEvents.js +48 -0
- package/dist/editor/manualActionEvents.js.map +1 -0
- package/dist/editor/menubar/PageSelector.js +9 -12
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/menubar/WorkflowButton.js +23 -23
- package/dist/editor/menubar/WorkflowButton.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/ManualBrowser.d.ts +3 -9
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +225 -71
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
- package/dist/editor/notifications/WatchButton.js +2 -2
- package/dist/editor/notifications/WatchButton.js.map +1 -1
- package/dist/editor/page-viewer/EditorForm.js +2 -0
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.js +8 -2
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/reviews/CreateReviewDialog.js +0 -2
- package/dist/editor/reviews/CreateReviewDialog.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +3 -2
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/agentStatus.d.ts +12 -0
- package/dist/editor/services/agentStatus.js +59 -0
- package/dist/editor/services/agentStatus.js.map +1 -0
- package/dist/editor/settings/SettingsView.js +4 -4
- package/dist/editor/settings/SettingsView.js.map +1 -1
- package/dist/editor/settings/index/useIndexStatus.js +1 -1
- package/dist/editor/settings/index/useIndexStatus.js.map +1 -1
- package/dist/editor/settings/panels/JavaScriptToolConfigPanel.js +1 -1
- package/dist/editor/settings/panels/JavaScriptToolConfigPanel.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.js +201 -40
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/MainContentTree.js +3 -2
- package/dist/editor/sidebar/MainContentTree.js.map +1 -1
- package/dist/editor/sidebar/MorePanelsButton.js +1 -1
- package/dist/editor/sidebar/MorePanelsButton.js.map +1 -1
- package/dist/editor/sidebar/NavigationPanelItem.js +2 -2
- package/dist/editor/sidebar/NavigationPanelItem.js.map +1 -1
- package/dist/editor/sidebar/SidebarPanel.js +20 -4
- package/dist/editor/sidebar/SidebarPanel.js.map +1 -1
- package/dist/editor/sidebar/SidebarStack.js +1 -0
- package/dist/editor/sidebar/SidebarStack.js.map +1 -1
- package/dist/editor/sidebar/Workbox.js +53 -3
- package/dist/editor/sidebar/Workbox.js.map +1 -1
- package/dist/editor/tree-indicators/GutterContext.d.ts +4 -0
- package/dist/editor/tree-indicators/GutterContext.js +23 -0
- package/dist/editor/tree-indicators/GutterContext.js.map +1 -1
- package/dist/editor/tree-indicators/index.d.ts +0 -1
- package/dist/editor/tree-indicators/index.js +0 -1
- package/dist/editor/tree-indicators/index.js.map +1 -1
- package/dist/editor/tree-indicators/types.d.ts +1 -1
- package/dist/editor/ui/HomeButton.js +1 -1
- package/dist/editor/ui/HomeButton.js.map +1 -1
- package/dist/editor/ui/ItemNameDialogNew.d.ts +2 -0
- package/dist/editor/ui/ItemNameDialogNew.js +17 -7
- package/dist/editor/ui/ItemNameDialogNew.js.map +1 -1
- package/dist/editor/ui/ItemSearch.js +7 -11
- package/dist/editor/ui/ItemSearch.js.map +1 -1
- package/dist/editor/ui/SimpleTabs.js +33 -16
- package/dist/editor/ui/SimpleTabs.js.map +1 -1
- package/dist/editor/ui/Splitter.js +1 -1
- package/dist/editor/ui/Splitter.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/setup/wizard/steps/AddModelDialog.js +3 -2
- package/dist/setup/wizard/steps/AddModelDialog.js.map +1 -1
- package/dist/task-board/components/AssignAgentDialog.js +0 -8
- package/dist/task-board/components/AssignAgentDialog.js.map +1 -1
- package/dist/task-board/components/ProjectAgentsPanel.js +1 -26
- package/dist/task-board/components/ProjectAgentsPanel.js.map +1 -1
- package/dist/task-board/components/TaskAgentPanel.js +2 -6
- package/dist/task-board/components/TaskAgentPanel.js.map +1 -1
- package/dist/types.d.ts +2 -13
- package/package.json +1 -1
- package/dist/editor/tree-indicators/GutterSelector.d.ts +0 -5
- package/dist/editor/tree-indicators/GutterSelector.js +0 -91
- package/dist/editor/tree-indicators/GutterSelector.js.map +0 -1
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import React, { useEffect, useState, useRef, useCallback, useLayoutEffect, useMemo, } from "react";
|
|
3
3
|
import { Send, AlertCircle, Loader2, User, Wand2, Square, Mic, MicOff, ChevronDown, ChevronUp, ListTodo, ArrowLeft, DollarSign, ExternalLink, Settings2, Target, X, Plus, } from "lucide-react";
|
|
4
4
|
import { getAgent, startAgent, claimAgentBrowser, updateAgentSettings, updateAgentCostLimit, updateAgentContext, getAgentSkillCatalog, getAgentAvailableTools, getAgentOperationAllowances, getAgentTriggerSubscriptions, cancelAgent, canonicalizeAgentMetadata, getPendingPrompts, releaseAgentBrowser, } from "../services/agentService";
|
|
5
|
+
import { parseAgentStatus } from "../services/agentStatus";
|
|
5
6
|
import { useEditContext, useFieldsEditContext } from "../client/editContext";
|
|
6
7
|
import { localStorageService } from "../services/localStorageService";
|
|
7
8
|
import { Textarea } from "../../components/ui/textarea";
|
|
@@ -28,6 +29,19 @@ import { AgentTerminalStatusBar } from "./AgentTerminalStatusBar";
|
|
|
28
29
|
import { SimpleTabs } from "../ui/SimpleTabs";
|
|
29
30
|
import { Splitter } from "../ui/Splitter";
|
|
30
31
|
import { ScrollingContentTree } from "../ScrollingContentTree";
|
|
32
|
+
import { MarkdownDisplay, } from "../../components/MarkdownDisplay";
|
|
33
|
+
const userMessageMarkdownComponents = {
|
|
34
|
+
h1: (props) => (_jsx("h1", { ...props, className: "mb-2 text-sm font-semibold leading-5 text-gray-900" })),
|
|
35
|
+
h2: (props) => (_jsx("h2", { ...props, className: "mb-1.5 text-[13px] font-semibold leading-5 text-gray-900" })),
|
|
36
|
+
h3: (props) => (_jsx("h3", { ...props, className: "mb-1 text-[12px] font-semibold leading-5 text-gray-900" })),
|
|
37
|
+
h4: (props) => (_jsx("h4", { ...props, className: "mb-1 text-[12px] font-medium leading-5 text-gray-800" })),
|
|
38
|
+
p: (props) => _jsx("p", { ...props, className: "my-1 text-[12px] leading-5 text-gray-700" }),
|
|
39
|
+
ul: (props) => (_jsx("ul", { ...props, className: "my-2 ml-5 list-disc space-y-1 text-[12px] leading-5 text-gray-700" })),
|
|
40
|
+
ol: (props) => (_jsx("ol", { ...props, className: "my-2 ml-5 list-decimal space-y-1 text-[12px] leading-5 text-gray-700" })),
|
|
41
|
+
li: (props) => _jsx("li", { ...props, className: "text-[12px] leading-5 text-gray-700" }),
|
|
42
|
+
pre: (props) => (_jsx("pre", { ...props, className: "my-2 overflow-auto rounded-md bg-slate-100 px-3 py-2 text-[11px] leading-4 text-slate-700" })),
|
|
43
|
+
code: ({ inline, className, ...props }) => inline ? (_jsx("code", { ...props, className: "rounded bg-slate-100 px-1 py-0.5 text-[11px] text-slate-700" })) : (_jsx("code", { ...props, className: className })),
|
|
44
|
+
};
|
|
31
45
|
function buildPlaceholderAgentDetails(agentStub) {
|
|
32
46
|
const now = new Date().toISOString();
|
|
33
47
|
const updated = agentStub.updatedDate || now;
|
|
@@ -178,7 +192,7 @@ function toUserFacingAgentErrorMessage(value) {
|
|
|
178
192
|
return cleaned;
|
|
179
193
|
}
|
|
180
194
|
function isAgentErrorStatusValue(status) {
|
|
181
|
-
return status === "error"
|
|
195
|
+
return status === "error";
|
|
182
196
|
}
|
|
183
197
|
// Simple user message component
|
|
184
198
|
const UserMessage = ({ message }) => {
|
|
@@ -191,7 +205,7 @@ const UserMessage = ({ message }) => {
|
|
|
191
205
|
const triggerContent = triggerMatch?.[2] || "";
|
|
192
206
|
const isTriggerMessage = triggerName.length > 0;
|
|
193
207
|
if (isTriggerMessage) {
|
|
194
|
-
return (_jsx("div", { className: "px-4 py-2", children: _jsxs("div", { className: "text-[11px]", children: [_jsxs("button", { type: "button", onClick: () => setIsTriggerExpanded((expanded) => !expanded), className: "text-theme-secondary hover:bg-theme-hover flex w-full items-center gap-2 rounded-md border-l-2 border-cyan-200 px-2 py-1 text-left transition-colors", "data-testid": "trigger-message-toggle", "data-expanded": isTriggerExpanded ? "true" : "false", children: [_jsx(Target, { className: "h-3.5 w-3.5 shrink-0", strokeWidth: 1.5 }), _jsxs("span", { className: "truncate font-medium", children: ["Trigger: ", triggerName] }), message.createdDate && (_jsx("span", { className: "ml-1 shrink-0 text-[10px] text-gray-400", children: formatTime(new Date(message.createdDate)) })), _jsx("span", { className: "ml-auto shrink-0", children: isTriggerExpanded ? (_jsx(ChevronUp, { className: "h-3.5 w-3.5" })) : (_jsx(ChevronDown, { className: "h-3.5 w-3.5" })) })] }), isTriggerExpanded && (_jsx("div", { className: "mt-1 border-l-2 border-cyan-100 pl-[1.35rem] text-[11px] text-gray-600", children: triggerContent }))] }) }));
|
|
208
|
+
return (_jsx("div", { className: "px-4 py-2", children: _jsxs("div", { className: "text-[11px]", children: [_jsxs("button", { type: "button", onClick: () => setIsTriggerExpanded((expanded) => !expanded), className: "text-theme-secondary hover:bg-theme-hover flex w-full items-center gap-2 rounded-md border-l-2 border-cyan-200 px-2 py-1 text-left transition-colors", "data-testid": "trigger-message-toggle", "data-expanded": isTriggerExpanded ? "true" : "false", children: [_jsx(Target, { className: "h-3.5 w-3.5 shrink-0", strokeWidth: 1.5 }), _jsxs("span", { className: "truncate font-medium", children: ["Trigger: ", triggerName] }), message.createdDate && (_jsx("span", { className: "ml-1 shrink-0 text-[10px] text-gray-400", children: formatTime(new Date(message.createdDate)) })), _jsx("span", { className: "ml-auto shrink-0", children: isTriggerExpanded ? (_jsx(ChevronUp, { className: "h-3.5 w-3.5" })) : (_jsx(ChevronDown, { className: "h-3.5 w-3.5" })) })] }), isTriggerExpanded && (_jsx("div", { className: "mt-1 border-l-2 border-cyan-100 pl-[1.35rem] text-[11px] text-gray-600", children: _jsx(MarkdownDisplay, { source: triggerContent, components: userMessageMarkdownComponents }) }))] }) }));
|
|
195
209
|
}
|
|
196
210
|
// Parse source agent name from content if it starts with "[From ...]:"
|
|
197
211
|
// Backend formats messages from other agents as "[From {sourceAgentName}]: {content}"
|
|
@@ -219,7 +233,7 @@ const UserMessage = ({ message }) => {
|
|
|
219
233
|
message.sourceAgent?.name;
|
|
220
234
|
}
|
|
221
235
|
const displayName = sourceAgentName ? `[From ${sourceAgentName}]` : "You";
|
|
222
|
-
return (_jsxs("div", { className: "flex gap-3 p-4", children: [_jsx("div", { className: "shrink-0", children: _jsx(User, { className: "text-theme-secondary h-5 w-5", strokeWidth: 1 }) }), _jsxs("div", { className: "min-w-0 flex-1 select-text", children: [_jsxs("div", { className: "mb-1 flex items-center gap-2", children: [_jsx("span", { className: "text-[12px] font-medium text-gray-900", children: displayName }), message.createdDate && (_jsx("span", { className: "text-[12px] text-gray-400", "data-testid": "user-message-timestamp", "data-timestamp": message.createdDate, children: formatTime(new Date(message.createdDate)) }))] }), _jsx("div", { className: "prose prose max-w-none text-[12px] text-gray-700 select-text", children: displayContent })] })] }));
|
|
236
|
+
return (_jsxs("div", { className: "flex gap-3 p-4", children: [_jsx("div", { className: "shrink-0", children: _jsx(User, { className: "text-theme-secondary h-5 w-5", strokeWidth: 1 }) }), _jsxs("div", { className: "min-w-0 flex-1 select-text", children: [_jsxs("div", { className: "mb-1 flex items-center gap-2", children: [_jsx("span", { className: "text-[12px] font-medium text-gray-900", children: displayName }), message.createdDate && (_jsx("span", { className: "text-[12px] text-gray-400", "data-testid": "user-message-timestamp", "data-timestamp": message.createdDate, children: formatTime(new Date(message.createdDate)) }))] }), _jsx("div", { className: "prose prose max-w-none text-[12px] text-gray-700 select-text", children: _jsx(MarkdownDisplay, { source: displayContent, components: userMessageMarkdownComponents }) })] })] }));
|
|
223
237
|
};
|
|
224
238
|
const HeartbeatMessage = ({ message }) => {
|
|
225
239
|
return (_jsx("div", { className: "px-4 py-2", "data-testid": "agent-heartbeat-message", children: _jsxs("div", { className: "flex items-center gap-2 rounded-md border border-sky-100 bg-sky-50/80 px-3 py-2 text-[11px] text-sky-700", children: [_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin", strokeWidth: 1.5 }), _jsx("span", { className: "min-w-0 flex-1", children: message.content }), message.createdDate && (_jsx("span", { className: "shrink-0 text-[10px] text-sky-500", children: formatTime(new Date(message.createdDate)) }))] }) }));
|
|
@@ -463,12 +477,9 @@ const TodoListPanel = ({ messages, agentMetadata, }) => {
|
|
|
463
477
|
const [isExpanded, setIsExpanded] = useState(true);
|
|
464
478
|
// First try to get todos from agent metadata (real-time updates)
|
|
465
479
|
// Server sends additionalData.todoList directly via contextChanged status
|
|
466
|
-
// Also check top-level todoList for backward compatibility with stored contexts
|
|
467
480
|
const metadataTodos = (() => {
|
|
468
481
|
try {
|
|
469
|
-
|
|
470
|
-
const todoList = agentMetadata?.additionalData?.todoList ||
|
|
471
|
-
agentMetadata?.todoList;
|
|
482
|
+
const todoList = agentMetadata?.additionalData?.todoList;
|
|
472
483
|
if (todoList?.items && Array.isArray(todoList.items)) {
|
|
473
484
|
const rawItems = todoList.items
|
|
474
485
|
.map((item, idx) => ({
|
|
@@ -1061,11 +1072,6 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1061
1072
|
value === "supervised") {
|
|
1062
1073
|
return value;
|
|
1063
1074
|
}
|
|
1064
|
-
// Backend task/spawned agents persist raw "agent", which behaves like
|
|
1065
|
-
// autonomous in the frontend's current 3-mode model.
|
|
1066
|
-
if (value === "agent") {
|
|
1067
|
-
return "autonomous";
|
|
1068
|
-
}
|
|
1069
1075
|
return null;
|
|
1070
1076
|
};
|
|
1071
1077
|
const [mode, setMode] = useState("supervised");
|
|
@@ -1108,8 +1114,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1108
1114
|
const hasTodoContent = useMemo(() => {
|
|
1109
1115
|
const metadataTodos = (() => {
|
|
1110
1116
|
try {
|
|
1111
|
-
const todoList = agentMetadata?.additionalData?.todoList
|
|
1112
|
-
agentMetadata?.todoList;
|
|
1117
|
+
const todoList = agentMetadata?.additionalData?.todoList;
|
|
1113
1118
|
if (todoList?.items && Array.isArray(todoList.items)) {
|
|
1114
1119
|
const raw = todoList.items.filter((item) => item?.title || item?.text || item?.label || item?.task);
|
|
1115
1120
|
return raw.length > 0;
|
|
@@ -1257,9 +1262,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1257
1262
|
label: m.name,
|
|
1258
1263
|
})) || []).sort((a, b) => a.label.localeCompare(b.label)), [activeProfile]);
|
|
1259
1264
|
const metadataSelectedSkillIds = useMemo(() => {
|
|
1260
|
-
const rawSkillIds = agentMetadata?.additionalData?.skillIds ??
|
|
1261
|
-
agentMetadata?.skillIds ??
|
|
1262
|
-
[];
|
|
1265
|
+
const rawSkillIds = agentMetadata?.additionalData?.skillIds ?? [];
|
|
1263
1266
|
if (!Array.isArray(rawSkillIds)) {
|
|
1264
1267
|
return [];
|
|
1265
1268
|
}
|
|
@@ -1682,7 +1685,12 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1682
1685
|
// Auto-focus terminal input on mount
|
|
1683
1686
|
useEffect(() => {
|
|
1684
1687
|
if (textareaRef.current) {
|
|
1685
|
-
|
|
1688
|
+
try {
|
|
1689
|
+
textareaRef.current.focus({ preventScroll: true });
|
|
1690
|
+
}
|
|
1691
|
+
catch {
|
|
1692
|
+
textareaRef.current.focus();
|
|
1693
|
+
}
|
|
1686
1694
|
}
|
|
1687
1695
|
}, []);
|
|
1688
1696
|
// Start voice recognition
|
|
@@ -2012,7 +2020,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
2012
2020
|
// If the agent isn't currently running (e.g., we switched tabs after the run
|
|
2013
2021
|
// completed), skip creating a new streaming message to avoid duplicates.
|
|
2014
2022
|
const currentAgentStatus = (agentData || agent)?.status;
|
|
2015
|
-
const isAgentRunning = currentAgentStatus === "running"
|
|
2023
|
+
const isAgentRunning = currentAgentStatus === "running";
|
|
2016
2024
|
if (!isAgentRunning) {
|
|
2017
2025
|
return;
|
|
2018
2026
|
}
|
|
@@ -2819,29 +2827,8 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
2819
2827
|
if (!contextJson)
|
|
2820
2828
|
return null;
|
|
2821
2829
|
const parsedContext = JSON.parse(contextJson);
|
|
2822
|
-
// Context is stored as flat structure with top-level properties.
|
|
2823
|
-
// Due to C# [JsonExtensionData], AdditionalData entries can be serialized at top level.
|
|
2824
|
-
// Normalize well-known extension keys back under additionalData for consistent UI behavior.
|
|
2825
2830
|
if (parsedContext && typeof parsedContext === "object") {
|
|
2826
|
-
|
|
2827
|
-
const additionalData = {
|
|
2828
|
-
...(normalized.additionalData || {}),
|
|
2829
|
-
};
|
|
2830
|
-
let additionalDataUpdated = false;
|
|
2831
|
-
// If todoList is at top level but not in additionalData, move it
|
|
2832
|
-
if (normalized.todoList && !normalized.additionalData?.todoList) {
|
|
2833
|
-
additionalData.todoList = normalized.todoList;
|
|
2834
|
-
additionalDataUpdated = true;
|
|
2835
|
-
}
|
|
2836
|
-
// Planner/task skill selections may also be flattened from JsonExtensionData.
|
|
2837
|
-
if (normalized.skillIds && !normalized.additionalData?.skillIds) {
|
|
2838
|
-
additionalData.skillIds = normalized.skillIds;
|
|
2839
|
-
additionalDataUpdated = true;
|
|
2840
|
-
}
|
|
2841
|
-
if (additionalDataUpdated) {
|
|
2842
|
-
normalized.additionalData = additionalData;
|
|
2843
|
-
}
|
|
2844
|
-
return normalized;
|
|
2831
|
+
return parsedContext;
|
|
2845
2832
|
}
|
|
2846
2833
|
return null;
|
|
2847
2834
|
}
|
|
@@ -2927,7 +2914,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
2927
2914
|
return;
|
|
2928
2915
|
}
|
|
2929
2916
|
// Check if cost limit exceeded based on status or cost values
|
|
2930
|
-
const statusIndicatesLimit = agent.status === "costLimitReached"
|
|
2917
|
+
const statusIndicatesLimit = agent.status === "costLimitReached";
|
|
2931
2918
|
// Use liveTotals.totalCost as fallback if agent.totalCost is missing or 0
|
|
2932
2919
|
const effectiveTotalCost = agent.totalCost || liveTotals?.totalCost || 0;
|
|
2933
2920
|
const costExceedsLimit = agent.costLimit &&
|
|
@@ -3294,12 +3281,9 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3294
3281
|
// Route based on statusData.state
|
|
3295
3282
|
try {
|
|
3296
3283
|
// Normalize various status shapes and handle Cancelled uniformly
|
|
3297
|
-
const normalizedStatus = statusData?.state ||
|
|
3298
|
-
statusData?.status;
|
|
3299
|
-
if (normalizedStatus === "
|
|
3300
|
-
normalizedStatus === "canceled" ||
|
|
3301
|
-
normalizedStatus === "stopped" ||
|
|
3302
|
-
normalizedStatus === "Stopped") {
|
|
3284
|
+
const normalizedStatus = parseAgentStatus(statusData?.state) ||
|
|
3285
|
+
parseAgentStatus(statusData?.status);
|
|
3286
|
+
if (normalizedStatus === "idle") {
|
|
3303
3287
|
// Stop indicators and mark any in-progress streaming messages as completed
|
|
3304
3288
|
clearHeartbeatMessages();
|
|
3305
3289
|
setAgent((prev) => (prev ? { ...prev, status: "idle" } : prev));
|
|
@@ -3437,8 +3421,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3437
3421
|
return;
|
|
3438
3422
|
}
|
|
3439
3423
|
// Handle waiting states explicitly
|
|
3440
|
-
if (
|
|
3441
|
-
statusData?.state === "waitingForApproval") {
|
|
3424
|
+
if (normalizedStatus === "waitingForApproval") {
|
|
3442
3425
|
setPendingBrowserCaptureDialogType(null);
|
|
3443
3426
|
setAgent((prev) => prev ? { ...prev, status: "waitingForApproval" } : prev);
|
|
3444
3427
|
setIsConnecting(false);
|
|
@@ -3446,8 +3429,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3446
3429
|
setIsAgentThinking(false);
|
|
3447
3430
|
return;
|
|
3448
3431
|
}
|
|
3449
|
-
if (
|
|
3450
|
-
statusData?.state === "waitingForInput") {
|
|
3432
|
+
if (normalizedStatus === "waitingForInput") {
|
|
3451
3433
|
const dialogType = typeof statusData?.dialogType === "string"
|
|
3452
3434
|
? statusData.dialogType
|
|
3453
3435
|
: null;
|
|
@@ -3470,7 +3452,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3470
3452
|
setIsAgentThinking(false);
|
|
3471
3453
|
return;
|
|
3472
3454
|
}
|
|
3473
|
-
if (
|
|
3455
|
+
if (normalizedStatus === "costLimitReached") {
|
|
3474
3456
|
setPendingBrowserCaptureDialogType(null);
|
|
3475
3457
|
const totalCost = Number(statusData.totalCost) || 0;
|
|
3476
3458
|
const costLimit = Number(statusData.costLimit) || agent?.costLimit || 0;
|
|
@@ -3518,8 +3500,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3518
3500
|
return;
|
|
3519
3501
|
}
|
|
3520
3502
|
// Handle "completed" state (fallback for legacy code paths that send status instead of lifecycle event)
|
|
3521
|
-
if (normalizedStatus === "completed"
|
|
3522
|
-
normalizedStatus === "Completed") {
|
|
3503
|
+
if (normalizedStatus === "completed") {
|
|
3523
3504
|
// Reset deduplication for the next run
|
|
3524
3505
|
lastSeqRef.current = 0;
|
|
3525
3506
|
clearHeartbeatMessages();
|
|
@@ -3545,21 +3526,8 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3545
3526
|
setIsAgentThinking(false);
|
|
3546
3527
|
return;
|
|
3547
3528
|
}
|
|
3548
|
-
// Handle "Idle" state - agent has finished processing
|
|
3549
|
-
if (normalizedStatus === "idle" || normalizedStatus === "Idle") {
|
|
3550
|
-
// Update agent status to idle
|
|
3551
|
-
clearHeartbeatMessages();
|
|
3552
|
-
setAgent((prev) => (prev ? { ...prev, status: "idle" } : prev));
|
|
3553
|
-
setIsWaitingForResponse(false);
|
|
3554
|
-
isWaitingRef.current = false;
|
|
3555
|
-
setIsConnecting(false);
|
|
3556
|
-
shouldCreateNewMessage.current = false;
|
|
3557
|
-
setIsAgentThinking(false);
|
|
3558
|
-
return;
|
|
3559
|
-
}
|
|
3560
3529
|
// Handle "Running" state - agent is actively processing
|
|
3561
|
-
if (normalizedStatus === "running"
|
|
3562
|
-
normalizedStatus === "Running") {
|
|
3530
|
+
if (normalizedStatus === "running") {
|
|
3563
3531
|
// Update agent status to running
|
|
3564
3532
|
setAgent((prev) => (prev ? { ...prev, status: "running" } : prev));
|
|
3565
3533
|
setIsWaitingForResponse(true);
|
|
@@ -3568,7 +3536,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3568
3536
|
return;
|
|
3569
3537
|
}
|
|
3570
3538
|
// Handle "Error" state
|
|
3571
|
-
if (normalizedStatus === "error"
|
|
3539
|
+
if (normalizedStatus === "error") {
|
|
3572
3540
|
const errorMsg = statusData?.statusMessage || statusData?.error || "Unknown error";
|
|
3573
3541
|
clearHeartbeatMessages();
|
|
3574
3542
|
setAgent((prev) => prev
|
|
@@ -3840,9 +3808,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3840
3808
|
}
|
|
3841
3809
|
setTimeout(() => {
|
|
3842
3810
|
if (request.dialogType === "questionnaire") {
|
|
3843
|
-
|
|
3844
|
-
block: "start",
|
|
3845
|
-
});
|
|
3811
|
+
scrollToBottomRefForDialogs.current?.();
|
|
3846
3812
|
return;
|
|
3847
3813
|
}
|
|
3848
3814
|
scrollToBottomRefForDialogs.current?.();
|
|
@@ -3910,11 +3876,12 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3910
3876
|
// Use case-insensitive comparison for GUID matching (backend may return different casing)
|
|
3911
3877
|
const normalizedProfileId = profileIdToUse?.toLowerCase();
|
|
3912
3878
|
const candidate = normalizedProfileId
|
|
3913
|
-
?
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3879
|
+
? profiles.find((p) => p.id?.toLowerCase() === normalizedProfileId)
|
|
3880
|
+
: undefined;
|
|
3881
|
+
if (!candidate) {
|
|
3882
|
+
setActiveProfile(undefined);
|
|
3917
3883
|
return;
|
|
3884
|
+
}
|
|
3918
3885
|
// Keep active profile in sync whenever the matching entry in `profiles` changes —
|
|
3919
3886
|
// not only when the profile id changes. Otherwise availableSkills (and similar fields)
|
|
3920
3887
|
// that are merged in the parent after async loads never update (e.g. Template Builder
|
|
@@ -3936,7 +3903,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
3936
3903
|
return prev;
|
|
3937
3904
|
return candidate;
|
|
3938
3905
|
});
|
|
3939
|
-
}, [profiles, agent?.profileId, agentStub.profileId]);
|
|
3906
|
+
}, [profiles, agent?.id, agent?.profileId, agentStub.id, agentStub.profileId]);
|
|
3940
3907
|
// Clear queued prompts when agent changes or is new;
|
|
3941
3908
|
// initial fetch is handled by loadAgent() for better performance and reliability
|
|
3942
3909
|
useEffect(() => {
|
|
@@ -4265,8 +4232,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
4265
4232
|
const response = await startAgent(request);
|
|
4266
4233
|
console.log("[AgentTerminal] startAgent response:", response);
|
|
4267
4234
|
// Check if prompt was queued (agent was already running)
|
|
4268
|
-
const wasQueued = response.message?.toLowerCase().includes("queued")
|
|
4269
|
-
response.status === "Queued";
|
|
4235
|
+
const wasQueued = response.message?.toLowerCase().includes("queued");
|
|
4270
4236
|
if (wasQueued) {
|
|
4271
4237
|
// Prompt was queued - show a brief notification but don't set waiting state
|
|
4272
4238
|
// The prompt will be processed when the agent becomes idle
|
|
@@ -5221,11 +5187,11 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
5221
5187
|
};
|
|
5222
5188
|
const renderErrorBanner = () => {
|
|
5223
5189
|
const currentAgent = agent || agentStub;
|
|
5224
|
-
const isErrorStatus = currentAgent?.status === "error"
|
|
5190
|
+
const isErrorStatus = currentAgent?.status === "error";
|
|
5225
5191
|
const errorMessage = (isErrorStatus ? currentAgent?.statusMessage : null) || error;
|
|
5226
5192
|
if (!errorMessage)
|
|
5227
5193
|
return null;
|
|
5228
|
-
return (_jsx("div", { className: "m-3 rounded border border-red-300 bg-red-50 p-3 text-[11px] text-red-900", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertCircle, { className: "mt-0.5 h-4 w-4 shrink-0 text-red-500", strokeWidth: 1 }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "mb-1 font-semibold", children: "Agent Error" }), _jsx("div", { className: "text-red-800", children: errorMessage })] })] }) }));
|
|
5194
|
+
return (_jsx("div", { className: "m-3 rounded border border-red-300 bg-red-50 p-3 text-[11px] text-red-900", "data-testid": "agent-error-banner", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertCircle, { className: "mt-0.5 h-4 w-4 shrink-0 text-red-500", strokeWidth: 1 }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "mb-1 font-semibold", children: "Agent Error" }), _jsx("div", { className: "text-red-800", children: errorMessage })] })] }) }));
|
|
5229
5195
|
};
|
|
5230
5196
|
const renderBrowserClaimBanner = (variant = "inline") => {
|
|
5231
5197
|
if (!agent?.id || !editContext?.sessionId)
|
|
@@ -5254,12 +5220,8 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
5254
5220
|
? "Take over browser control"
|
|
5255
5221
|
: "Attach to this browser" })) })] }) }));
|
|
5256
5222
|
};
|
|
5257
|
-
const fixedBrowserClaimBanner =
|
|
5258
|
-
|
|
5259
|
-
: null;
|
|
5260
|
-
const inlineBrowserClaimBanner = !isClaimedByCurrentSession
|
|
5261
|
-
? renderBrowserClaimBanner("inline")
|
|
5262
|
-
: null;
|
|
5223
|
+
const fixedBrowserClaimBanner = renderBrowserClaimBanner("fixed");
|
|
5224
|
+
const inlineBrowserClaimBanner = null;
|
|
5263
5225
|
useEffect(() => {
|
|
5264
5226
|
if (agent?.status !== "waitingForInput") {
|
|
5265
5227
|
setPendingBrowserCaptureDialogType(null);
|
|
@@ -5438,7 +5400,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
5438
5400
|
})()
|
|
5439
5401
|
: null;
|
|
5440
5402
|
const fullModeInlineDialog = displayMode === "full" ? renderInlineDialogContent() : null;
|
|
5441
|
-
const fullModeUpperContent = (_jsxs("div", { className: "flex h-full min-h-0 flex-1 flex-col", children: [fixedBrowserClaimBanner, _jsxs("div", { ref: messagesContainerRef, className: "flex-1 overflow-y-auto", onScroll: handleScroll, children: [
|
|
5403
|
+
const fullModeUpperContent = (_jsxs("div", { className: "flex h-full min-h-0 flex-1 flex-col", children: [fixedBrowserClaimBanner, _jsxs("div", { ref: messagesContainerRef, className: "flex-1 overflow-y-auto", onScroll: handleScroll, children: [messages.length === 0 && !error && !hideGreeting && (_jsx("div", { className: "flex h-full items-center justify-center", children: !activeProfile ? (_jsx(Loader2, { className: "mx-auto h-8 w-8 animate-spin text-gray-400" })) : (_jsx(AgentGreeting, { profile: activeProfile, onPromptClick: (p) => {
|
|
5442
5404
|
setPrompt(p);
|
|
5443
5405
|
// Use setTimeout to ensure state is updated before submission
|
|
5444
5406
|
setTimeout(() => {
|