@parhelia/core 0.1.12515 → 0.1.12523
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/config.js +13 -0
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +9 -0
- package/dist/config/types.js.map +1 -1
- package/dist/editor/MainLayout.js +2 -1
- package/dist/editor/MainLayout.js.map +1 -1
- package/dist/editor/ai/AgentTerminal.js +171 -40
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/AiResponseMessage.d.ts +9 -1
- package/dist/editor/ai/AiResponseMessage.js +2 -2
- package/dist/editor/ai/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/ToolCallDisplay.d.ts +9 -1
- package/dist/editor/ai/ToolCallDisplay.js +9 -2
- package/dist/editor/ai/ToolCallDisplay.js.map +1 -1
- package/dist/editor/ai/dialogs/browserBoundCapture.js +18 -3
- package/dist/editor/ai/dialogs/browserBoundCapture.js.map +1 -1
- package/dist/editor/client/operations.js +5 -3
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/content-tree/index.d.ts +3 -0
- package/dist/editor/content-tree/index.js +4 -0
- package/dist/editor/content-tree/index.js.map +1 -0
- package/dist/editor/context-menu/InsertMenu.js +46 -23
- package/dist/editor/context-menu/InsertMenu.js.map +1 -1
- package/dist/editor/hooks/useNavigationPanelLogic.js +6 -1
- package/dist/editor/hooks/useNavigationPanelLogic.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +80 -13
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
- package/dist/editor/page-viewer/MiniMap.d.ts +1 -1
- package/dist/editor/page-viewer/MiniMap.js +18 -6
- package/dist/editor/page-viewer/MiniMap.js.map +1 -1
- package/dist/editor/reviews/SuggestedEdit.js +31 -3
- package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
- package/dist/editor/reviews/SuggestionDisplayPopover.js +31 -5
- package/dist/editor/reviews/SuggestionDisplayPopover.js.map +1 -1
- package/dist/editor/services/agentService.d.ts +14 -0
- package/dist/editor/services/agentService.js +14 -0
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/aiService.d.ts +1 -0
- package/dist/editor/services/aiService.js.map +1 -1
- package/dist/editor/services/contentService.d.ts +1 -0
- package/dist/editor/services/contentService.js.map +1 -1
- package/dist/editor/sidebar/ComponentTree.js +1 -36
- package/dist/editor/sidebar/ComponentTree.js.map +1 -1
- package/dist/editor/sidebar/NavigationPanelItem.js +5 -4
- package/dist/editor/sidebar/NavigationPanelItem.js.map +1 -1
- package/dist/editor/sidebar/SidebarPanel.js +10 -3
- package/dist/editor/sidebar/SidebarPanel.js.map +1 -1
- package/dist/editor/sidebar/Validation.js +22 -12
- package/dist/editor/sidebar/Validation.js.map +1 -1
- package/dist/editor/ui/Splitter.js +2 -2
- package/dist/editor/ui/Splitter.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/task-board/components/TaskAttachmentsSection.js +2 -1
- package/dist/task-board/components/TaskAttachmentsSection.js.map +1 -1
- package/dist/task-board/components/TaskDetailPanel.js +10 -7
- package/dist/task-board/components/TaskDetailPanel.js.map +1 -1
- package/dist/task-board/components/WizardTaskDetailsPanel.js +3 -2
- package/dist/task-board/components/WizardTaskDetailsPanel.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
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
|
-
import { getAgent, startAgent, claimAgentBrowser, updateAgentSettings, updateAgentCostLimit, updateAgentContext, getAgentSkillCatalog, getAgentAvailableTools, getAgentOperationAllowances, getAgentTriggerSubscriptions, cancelAgent, canonicalizeAgentMetadata, getPendingPrompts, releaseAgentBrowser, } from "../services/agentService";
|
|
4
|
+
import { getAgent, startAgent, claimAgentBrowser, assignAgentSkill, updateAgentSettings, updateAgentCostLimit, updateAgentContext, getAgentSkillCatalog, getAgentAvailableTools, getAgentOperationAllowances, getAgentTriggerSubscriptions, cancelAgent, canonicalizeAgentMetadata, getPendingPrompts, releaseAgentBrowser, revokeAgentSkill, } from "../services/agentService";
|
|
5
5
|
import { parseAgentStatus } from "../services/agentStatus";
|
|
6
6
|
import { useEditContext, useFieldsEditContext } from "../client/editContext";
|
|
7
7
|
import { localStorageService } from "../services/localStorageService";
|
|
@@ -1087,6 +1087,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1087
1087
|
const [selectableTemplateIds, setSelectableTemplateIds] = useState([]);
|
|
1088
1088
|
const [skillsLoading, setSkillsLoading] = useState(false);
|
|
1089
1089
|
const [skillsError, setSkillsError] = useState(null);
|
|
1090
|
+
const [skillActionError, setSkillActionError] = useState(null);
|
|
1090
1091
|
const [triggerSubscriptions, setTriggerSubscriptions] = useState([]);
|
|
1091
1092
|
const [availableTools, setAvailableTools] = useState([]);
|
|
1092
1093
|
const [operationAllowances, setOperationAllowances] = useState({
|
|
@@ -1289,9 +1290,8 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1289
1290
|
.filter((id) => id.length > 0);
|
|
1290
1291
|
}, [activeProfile?.preloadSkills]);
|
|
1291
1292
|
const autoAssignedSkillIds = useMemo(() => {
|
|
1292
|
-
const
|
|
1293
|
-
|
|
1294
|
-
: backendAssignedSkillIds;
|
|
1293
|
+
const preloadedIdSet = new Set(preloadedSkillIds.map((id) => id.toLowerCase()));
|
|
1294
|
+
const all = backendAssignedSkillIds.filter((id) => preloadedIdSet.has(id.toLowerCase()));
|
|
1295
1295
|
const seen = new Set();
|
|
1296
1296
|
const unique = [];
|
|
1297
1297
|
for (const id of all) {
|
|
@@ -1302,7 +1302,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1302
1302
|
unique.push(id);
|
|
1303
1303
|
}
|
|
1304
1304
|
return unique;
|
|
1305
|
-
}, [backendAssignedSkillIds,
|
|
1305
|
+
}, [backendAssignedSkillIds, preloadedSkillIds]);
|
|
1306
1306
|
const selectedSkillIds = useMemo(() => {
|
|
1307
1307
|
const all = [...autoAssignedSkillIds, ...metadataSelectedSkillIds];
|
|
1308
1308
|
const seen = new Set();
|
|
@@ -1444,7 +1444,9 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1444
1444
|
return availableSkills.filter((skill) => listedProfileSkillIdSet.has(skill.id.toLowerCase()));
|
|
1445
1445
|
}, [availableSkills, listedProfileSkillIdSet]);
|
|
1446
1446
|
const profileFilteredSkillIdSet = useMemo(() => new Set(profileFilteredSkills.map((s) => s.id.toLowerCase())), [profileFilteredSkills]);
|
|
1447
|
-
const
|
|
1447
|
+
const manuallyAssignableSkillIdSet = useMemo(() => new Set((activeProfile?.allowedSkills ?? [])
|
|
1448
|
+
.map((skill) => String(skill?.id || "").toLowerCase())
|
|
1449
|
+
.filter((id) => id.length > 0)), [activeProfile?.allowedSkills]);
|
|
1448
1450
|
const selectableTemplateIdSet = useMemo(() => new Set(selectableTemplateIds.map((id) => id.toLowerCase())), [selectableTemplateIds]);
|
|
1449
1451
|
const selectedSkills = useMemo(() => selectedSkillIds
|
|
1450
1452
|
.map((id) => availableSkills.find((s) => s.id.toLowerCase() === id.toLowerCase()))
|
|
@@ -1508,20 +1510,23 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1508
1510
|
return meta;
|
|
1509
1511
|
}
|
|
1510
1512
|
}, []);
|
|
1511
|
-
const
|
|
1512
|
-
|
|
1513
|
+
const getSkillActionErrorMessage = useCallback((error) => {
|
|
1514
|
+
const message = error instanceof Error && error.message.trim()
|
|
1515
|
+
? error.message.trim()
|
|
1516
|
+
: "Failed to update skill";
|
|
1517
|
+
if (message.includes("Skill is not available for this agent profile")) {
|
|
1518
|
+
return "This skill cannot be added for the current agent profile.";
|
|
1519
|
+
}
|
|
1520
|
+
return message;
|
|
1521
|
+
}, []);
|
|
1522
|
+
const clearLegacySelectedSkillsFromMetadata = useCallback(async () => {
|
|
1523
|
+
const legacySkillIds = metadataSelectedSkillIds;
|
|
1524
|
+
if (!agent?.id || legacySkillIds.length === 0) {
|
|
1513
1525
|
return;
|
|
1526
|
+
}
|
|
1514
1527
|
const current = agentMetadata || {};
|
|
1515
1528
|
const currentAdditionalData = current.additionalData || {};
|
|
1516
|
-
const nextAdditionalData =
|
|
1517
|
-
...currentAdditionalData,
|
|
1518
|
-
};
|
|
1519
|
-
if (skillIds.length > 0) {
|
|
1520
|
-
nextAdditionalData.skillIds = skillIds;
|
|
1521
|
-
}
|
|
1522
|
-
else {
|
|
1523
|
-
delete nextAdditionalData.skillIds;
|
|
1524
|
-
}
|
|
1529
|
+
const nextAdditionalData = Object.fromEntries(Object.entries(currentAdditionalData).filter(([key]) => key.toLowerCase() !== "skillids"));
|
|
1525
1530
|
const next = {
|
|
1526
1531
|
...current,
|
|
1527
1532
|
};
|
|
@@ -1532,26 +1537,86 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
1532
1537
|
delete next.additionalData;
|
|
1533
1538
|
}
|
|
1534
1539
|
try {
|
|
1535
|
-
if (agent.status === "new") {
|
|
1536
|
-
setAgentMetadata(next);
|
|
1537
|
-
return;
|
|
1538
|
-
}
|
|
1539
1540
|
await updateAgentContext(agent.id, next);
|
|
1540
1541
|
setAgentMetadata(next);
|
|
1541
1542
|
setAgent((prev) => prev ? { ...prev, agentContext: JSON.stringify(next) } : prev);
|
|
1542
1543
|
}
|
|
1543
1544
|
catch (e) {
|
|
1544
|
-
console.error("Failed to
|
|
1545
|
+
console.error("Failed to clear legacy selected skills", e);
|
|
1545
1546
|
}
|
|
1546
|
-
}, [
|
|
1547
|
+
}, [
|
|
1548
|
+
agent?.id,
|
|
1549
|
+
agentMetadata,
|
|
1550
|
+
metadataSelectedSkillIds,
|
|
1551
|
+
setAgent,
|
|
1552
|
+
setAgentMetadata,
|
|
1553
|
+
]);
|
|
1547
1554
|
const handleAddSkill = useCallback(async (skillId) => {
|
|
1548
1555
|
if (selectedSkillSet.has(skillId.toLowerCase()))
|
|
1549
1556
|
return;
|
|
1550
|
-
|
|
1551
|
-
|
|
1557
|
+
if (!agent?.id)
|
|
1558
|
+
return;
|
|
1559
|
+
try {
|
|
1560
|
+
setSkillActionError(null);
|
|
1561
|
+
await assignAgentSkill({ agentId: agent.id, skillId });
|
|
1562
|
+
setAgent((prev) => {
|
|
1563
|
+
if (!prev)
|
|
1564
|
+
return prev;
|
|
1565
|
+
const currentAssigned = Array.isArray(prev.assignedSkillIds)
|
|
1566
|
+
? prev.assignedSkillIds
|
|
1567
|
+
: [];
|
|
1568
|
+
if (currentAssigned.some((existingId) => String(existingId).toLowerCase() === skillId.toLowerCase())) {
|
|
1569
|
+
return prev;
|
|
1570
|
+
}
|
|
1571
|
+
return {
|
|
1572
|
+
...prev,
|
|
1573
|
+
assignedSkillIds: [...currentAssigned, skillId],
|
|
1574
|
+
};
|
|
1575
|
+
});
|
|
1576
|
+
await clearLegacySelectedSkillsFromMetadata();
|
|
1577
|
+
return true;
|
|
1578
|
+
}
|
|
1579
|
+
catch (e) {
|
|
1580
|
+
setSkillActionError(getSkillActionErrorMessage(e));
|
|
1581
|
+
return false;
|
|
1582
|
+
}
|
|
1583
|
+
}, [
|
|
1584
|
+
agent?.id,
|
|
1585
|
+
assignAgentSkill,
|
|
1586
|
+
clearLegacySelectedSkillsFromMetadata,
|
|
1587
|
+
getSkillActionErrorMessage,
|
|
1588
|
+
setAgent,
|
|
1589
|
+
selectedSkillSet,
|
|
1590
|
+
]);
|
|
1552
1591
|
const handleRemoveSkill = useCallback(async (skillId) => {
|
|
1553
|
-
|
|
1554
|
-
|
|
1592
|
+
if (!agent?.id)
|
|
1593
|
+
return;
|
|
1594
|
+
try {
|
|
1595
|
+
setSkillActionError(null);
|
|
1596
|
+
await revokeAgentSkill({ agentId: agent.id, skillId });
|
|
1597
|
+
setAgent((prev) => {
|
|
1598
|
+
if (!prev)
|
|
1599
|
+
return prev;
|
|
1600
|
+
const currentAssigned = Array.isArray(prev.assignedSkillIds)
|
|
1601
|
+
? prev.assignedSkillIds
|
|
1602
|
+
: [];
|
|
1603
|
+
return {
|
|
1604
|
+
...prev,
|
|
1605
|
+
assignedSkillIds: currentAssigned.filter((existingId) => String(existingId).toLowerCase() !== skillId.toLowerCase()),
|
|
1606
|
+
};
|
|
1607
|
+
});
|
|
1608
|
+
await clearLegacySelectedSkillsFromMetadata();
|
|
1609
|
+
}
|
|
1610
|
+
catch (e) {
|
|
1611
|
+
setSkillActionError(getSkillActionErrorMessage(e));
|
|
1612
|
+
}
|
|
1613
|
+
}, [
|
|
1614
|
+
agent?.id,
|
|
1615
|
+
clearLegacySelectedSkillsFromMetadata,
|
|
1616
|
+
getSkillActionErrorMessage,
|
|
1617
|
+
revokeAgentSkill,
|
|
1618
|
+
setAgent,
|
|
1619
|
+
]);
|
|
1555
1620
|
const handleOpenProfileSettings = useCallback(async () => {
|
|
1556
1621
|
if (!editContext || !activeProfile?.id)
|
|
1557
1622
|
return;
|
|
@@ -2007,6 +2072,12 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
2007
2072
|
// If no messageId is provided, we'll use the last assistant message or create a new one
|
|
2008
2073
|
let messageId = message.data?.messageId;
|
|
2009
2074
|
if (!messageId && agentData?.id) {
|
|
2075
|
+
console.warn("[AgentTerminal] Content chunk missing messageId; falling back to local resolution", {
|
|
2076
|
+
agentId: agentData.id,
|
|
2077
|
+
isIncremental: message.data?.isIncremental,
|
|
2078
|
+
previousContentLength: message.data?.previousContentLength,
|
|
2079
|
+
totalContentLength: message.data?.totalContentLength,
|
|
2080
|
+
});
|
|
2010
2081
|
// For backward compatibility: if no messageId, find or create the current streaming message
|
|
2011
2082
|
// This handles cases where the backend doesn't send messageId
|
|
2012
2083
|
const currentMessages = messagesRef.current;
|
|
@@ -2107,6 +2178,15 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
2107
2178
|
const existingMessageIndex = prev.findIndex((msg) => msg.id === messageId);
|
|
2108
2179
|
if (existingMessageIndex === -1) {
|
|
2109
2180
|
// Message doesn't exist - create new streaming message
|
|
2181
|
+
const previousContentLength = message.data?.previousContentLength || 0;
|
|
2182
|
+
if (message.data?.isIncremental && previousContentLength > 0) {
|
|
2183
|
+
console.warn("[AgentTerminal] Incremental chunk arrived before its base message existed", {
|
|
2184
|
+
messageId,
|
|
2185
|
+
previousContentLength,
|
|
2186
|
+
totalContentLength: message.data?.totalContentLength,
|
|
2187
|
+
deltaLength: (message.data?.deltaContent || "").length,
|
|
2188
|
+
});
|
|
2189
|
+
}
|
|
2110
2190
|
const newStreamMessage = createNewStreamMessage(messageId, agentData);
|
|
2111
2191
|
// Set the content for the new message
|
|
2112
2192
|
const updatedNewMessage = { ...newStreamMessage };
|
|
@@ -2129,8 +2209,21 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
2129
2209
|
return prev;
|
|
2130
2210
|
// Check if existing content is already longer than what we're trying to stream
|
|
2131
2211
|
const currentContentLength = existingMessage.content?.length || 0;
|
|
2212
|
+
const previousContentLength = message.data?.previousContentLength || 0;
|
|
2132
2213
|
const totalContentLength = message.data?.totalContentLength || 0;
|
|
2133
|
-
if (
|
|
2214
|
+
if (message.data?.isIncremental &&
|
|
2215
|
+
previousContentLength !== currentContentLength &&
|
|
2216
|
+
(previousContentLength > 0 || currentContentLength > 0)) {
|
|
2217
|
+
console.warn("[AgentTerminal] Content chunk length mismatch", {
|
|
2218
|
+
messageId,
|
|
2219
|
+
previousContentLength,
|
|
2220
|
+
currentContentLength,
|
|
2221
|
+
totalContentLength,
|
|
2222
|
+
deltaLength: (message.data?.deltaContent || "").length,
|
|
2223
|
+
});
|
|
2224
|
+
}
|
|
2225
|
+
if (message.data?.isIncremental &&
|
|
2226
|
+
currentContentLength >= totalContentLength &&
|
|
2134
2227
|
totalContentLength > 0) {
|
|
2135
2228
|
return prev;
|
|
2136
2229
|
}
|
|
@@ -2159,6 +2252,10 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
2159
2252
|
// Prefer provided messageId, otherwise fall back to the last streaming assistant message
|
|
2160
2253
|
let toolCallMessageId = message.data?.messageId;
|
|
2161
2254
|
if (!toolCallMessageId) {
|
|
2255
|
+
console.warn("[AgentTerminal] Tool call missing messageId; falling back", {
|
|
2256
|
+
toolCallId,
|
|
2257
|
+
toolName: message.data?.name || message.data?.displayName,
|
|
2258
|
+
});
|
|
2162
2259
|
const current = messagesRef.current;
|
|
2163
2260
|
const lastStreaming = [...current]
|
|
2164
2261
|
.reverse()
|
|
@@ -2322,6 +2419,10 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
2322
2419
|
// Prefer provided messageId, otherwise fall back to the last streaming assistant message
|
|
2323
2420
|
let resultMessageId = message.data?.messageId;
|
|
2324
2421
|
if (!resultMessageId) {
|
|
2422
|
+
console.warn("[AgentTerminal] Tool result missing messageId; falling back", {
|
|
2423
|
+
toolCallId: resultToolCallId,
|
|
2424
|
+
toolName: message.data?.functionName || message.data?.displayName,
|
|
2425
|
+
});
|
|
2325
2426
|
const current = messagesRef.current;
|
|
2326
2427
|
const lastStreaming = [...current]
|
|
2327
2428
|
.reverse()
|
|
@@ -5196,9 +5297,10 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
5196
5297
|
const renderBrowserClaimBanner = (variant = "inline") => {
|
|
5197
5298
|
if (!agent?.id || !editContext?.sessionId)
|
|
5198
5299
|
return null;
|
|
5199
|
-
if (!isClaimedByCurrentSession &&
|
|
5200
|
-
|
|
5201
|
-
|
|
5300
|
+
if (!isClaimedByCurrentSession && !isClaimedByAnotherBrowser) {
|
|
5301
|
+
return null;
|
|
5302
|
+
}
|
|
5303
|
+
if (isPendingBrowserCaptureWait) {
|
|
5202
5304
|
return null;
|
|
5203
5305
|
}
|
|
5204
5306
|
const label = isClaimedByCurrentSession
|
|
@@ -5222,6 +5324,24 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
5222
5324
|
};
|
|
5223
5325
|
const fixedBrowserClaimBanner = renderBrowserClaimBanner("fixed");
|
|
5224
5326
|
const inlineBrowserClaimBanner = null;
|
|
5327
|
+
const browserCaptureInlinePrompt = isPendingBrowserCaptureWait && !isClaimedByCurrentSession
|
|
5328
|
+
? {
|
|
5329
|
+
toolNames: ["capture-page-screenshot", "capture-page-dom"],
|
|
5330
|
+
label: isClaimedByAnotherBrowser
|
|
5331
|
+
? "Attached in another browser"
|
|
5332
|
+
: "No browser attached",
|
|
5333
|
+
description: isClaimedByAnotherBrowser
|
|
5334
|
+
? "This capture request is waiting in another browser. Take over browser control here to continue."
|
|
5335
|
+
: "This capture request is waiting for a browser attachment. Attach this browser to continue.",
|
|
5336
|
+
actionLabel: isClaimedByAnotherBrowser
|
|
5337
|
+
? "Take over browser control"
|
|
5338
|
+
: "Attach to this browser",
|
|
5339
|
+
isPending: isBrowserClaimMutationPending,
|
|
5340
|
+
onAction: () => {
|
|
5341
|
+
void handleClaimBrowser(isClaimedByAnotherBrowser);
|
|
5342
|
+
},
|
|
5343
|
+
}
|
|
5344
|
+
: null;
|
|
5225
5345
|
useEffect(() => {
|
|
5226
5346
|
if (agent?.status !== "waitingForInput") {
|
|
5227
5347
|
setPendingBrowserCaptureDialogType(null);
|
|
@@ -5291,7 +5411,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
5291
5411
|
__html: sanitizeSvg(activeProfile.svgIcon),
|
|
5292
5412
|
} })) : (_jsx(SecretAgentIcon, { size: 64, strokeWidth: 1, className: "text-gray-400" })), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "h-2 w-2 animate-bounce rounded-full bg-gray-400 [animation-delay:-0.3s]" }), _jsx("span", { className: "h-2 w-2 animate-bounce rounded-full bg-gray-400 [animation-delay:-0.15s]" }), _jsx("span", { className: "h-2 w-2 animate-bounce rounded-full bg-gray-400" })] })] }) })), inlineBrowserClaimBanner, renderErrorBanner(), inlineDialog ? (inlineDialog) : latestSummaryAssistantGroup ? (_jsx("div", { className: "space-y-0 divide-y divide-gray-100 select-text", children: _jsx(AiResponseMessage, { messages: summaryMessages, finished: !latestSummaryAssistantGroup.isLastGroup || !isExecuting, editOperations: summaryOperations, defaultCollapseJson: defaultCollapseJson, profileSvgIcon: activeProfile?.svgIcon, agentId: agent?.id || agentStub.id, agentName: activeProfile?.agentName ||
|
|
5293
5413
|
activeProfile?.displayTitle ||
|
|
5294
|
-
activeProfile?.name, allPendingApprovals: allPendingApprovals, onSwitchToAutonomous: handleSwitchToAutonomous, onQuickAction: (action) => {
|
|
5414
|
+
activeProfile?.name, allPendingApprovals: allPendingApprovals, onSwitchToAutonomous: handleSwitchToAutonomous, browserCaptureInlinePrompt: browserCaptureInlinePrompt, onQuickAction: (action) => {
|
|
5295
5415
|
const text = (action.prompt ||
|
|
5296
5416
|
action.value ||
|
|
5297
5417
|
action.label ||
|
|
@@ -5444,7 +5564,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
5444
5564
|
const operationsForGroup = getOperationsForMessageGroup(convertedMessages, agentOperations);
|
|
5445
5565
|
return (_jsx(AiResponseMessage, { messages: convertedMessages, finished: !isLastGroup || !isExecuting, editOperations: operationsForGroup, defaultCollapseJson: defaultCollapseJson, profileSvgIcon: activeProfile?.svgIcon, agentId: agent?.id || agentStub.id, agentName: activeProfile?.agentName ||
|
|
5446
5566
|
activeProfile?.displayTitle ||
|
|
5447
|
-
activeProfile?.name, allPendingApprovals: allPendingApprovals, onSwitchToAutonomous: handleSwitchToAutonomous, onQuickAction: (action) => {
|
|
5567
|
+
activeProfile?.name, allPendingApprovals: allPendingApprovals, onSwitchToAutonomous: handleSwitchToAutonomous, browserCaptureInlinePrompt: browserCaptureInlinePrompt, onQuickAction: (action) => {
|
|
5448
5568
|
const text = (action.prompt ||
|
|
5449
5569
|
action.value ||
|
|
5450
5570
|
action.label ||
|
|
@@ -5785,29 +5905,40 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
5785
5905
|
catch (err) {
|
|
5786
5906
|
console.error("Failed to persist agent model", err);
|
|
5787
5907
|
}
|
|
5788
|
-
} })] })) : null, _jsxs("div", { children: [_jsxs("div", { className: "mb-1 flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-1 text-[11px] font-medium text-gray-700", children: [_jsx(Target, { className: "h-3 w-3", strokeWidth: 1 }), "Skills"] }), _jsxs(Popover, { open: showSkillPicker, onOpenChange:
|
|
5908
|
+
} })] })) : null, _jsxs("div", { children: [_jsxs("div", { className: "mb-1 flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-1 text-[11px] font-medium text-gray-700", children: [_jsx(Target, { className: "h-3 w-3", strokeWidth: 1 }), "Skills"] }), _jsxs(Popover, { open: showSkillPicker, onOpenChange: (open) => {
|
|
5909
|
+
setShowSkillPicker(open);
|
|
5910
|
+
if (open) {
|
|
5911
|
+
setSkillActionError(null);
|
|
5912
|
+
}
|
|
5913
|
+
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { size: "xs", variant: "outline", className: "h-5 rounded border px-1.5 text-[10px] text-gray-600", "data-testid": "agent-skill-picker-trigger", children: [_jsx(Plus, { className: "mr-1 h-3 w-3", strokeWidth: 1.5 }), "Add"] }) }), _jsx(PopoverContent, { className: "w-88 p-2", align: "end", side: "bottom", children: _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "text-[11px] font-medium text-gray-700", children: "Select a skill" }), _jsxs("div", { className: "relative h-56 rounded border border-gray-200 bg-gray-50", children: [_jsx(ScrollingContentTree, { rootItemIds: skillRootIds, selectedItemId: selectedSkillIds[selectedSkillIds.length - 1] || undefined, expandedItemId: selectedSkillIds[selectedSkillIds.length - 1] || skillRootIds[0], scrollToSelected: true, hideRootNodes: false, onSelectionChange: (selection) => {
|
|
5789
5914
|
const selected = selection[0];
|
|
5790
5915
|
if (!selected?.id)
|
|
5791
5916
|
return;
|
|
5917
|
+
setSkillActionError(null);
|
|
5792
5918
|
if (selectableTemplateIdSet.size > 0 &&
|
|
5793
5919
|
(!selected.templateId ||
|
|
5794
5920
|
!selectableTemplateIdSet.has(selected.templateId.toLowerCase()))) {
|
|
5795
5921
|
return;
|
|
5796
5922
|
}
|
|
5797
|
-
if (!
|
|
5923
|
+
if (!manuallyAssignableSkillIdSet.has(selected.id.toLowerCase())) {
|
|
5924
|
+
setSkillActionError("This skill cannot be added for the current agent profile.");
|
|
5798
5925
|
return;
|
|
5799
5926
|
}
|
|
5800
|
-
void
|
|
5801
|
-
|
|
5927
|
+
void (async () => {
|
|
5928
|
+
const added = await handleAddSkill(selected.id);
|
|
5929
|
+
if (added) {
|
|
5930
|
+
setShowSkillPicker(false);
|
|
5931
|
+
}
|
|
5932
|
+
})();
|
|
5802
5933
|
} }), skillsLoading && (_jsx("div", { className: "bg-background/70 absolute inset-0 flex items-center justify-center text-[10px] text-gray-500", children: "Loading skills..." }))] }), !skillsLoading &&
|
|
5803
5934
|
!skillsError &&
|
|
5804
|
-
profileFilteredSkills.length > 0 && (_jsx("div", { className: "text-[10px] text-gray-500", children: "Click a skill item in the tree to add it." })), skillsError && (_jsx("div", { className: "text-[10px] text-red-600", children: skillsError })), !skillsLoading &&
|
|
5935
|
+
profileFilteredSkills.length > 0 && (_jsx("div", { className: "text-[10px] text-gray-500", children: "Click a skill item in the tree to add it." })), skillsError && (_jsx("div", { className: "text-[10px] text-red-600", children: skillsError })), !skillsError && skillActionError && (_jsx("div", { className: "text-[10px] text-red-600", children: skillActionError })), !skillsLoading &&
|
|
5805
5936
|
!skillsError &&
|
|
5806
5937
|
skillRootIds.length === 0 && (_jsx("div", { className: "text-[10px] text-gray-500", children: "No skill roots available." })), !skillsLoading &&
|
|
5807
5938
|
!skillsError &&
|
|
5808
5939
|
profileFilteredSkills.length === 0 && (_jsx("div", { className: "text-[10px] text-gray-500", children: selectedSkillIds.length > 0
|
|
5809
|
-
? "All
|
|
5810
|
-
: "No
|
|
5940
|
+
? "All addable skills are selected"
|
|
5941
|
+
: "No skills can be added for this profile" }))] }) })] })] }), selectedSkillIds.length > 0 && (_jsx("div", { className: "mb-2 flex flex-wrap gap-1", children: selectedSkillIds.map((skillId) => {
|
|
5811
5942
|
const skill = selectedSkills.find((s) => s.id === skillId);
|
|
5812
5943
|
return (_jsxs("div", { className: "inline-flex items-center gap-1 rounded-full border border-gray-200 bg-gray-100 px-1.5 py-0.5 text-[10px] text-gray-700", children: [_jsx("span", { children: skill?.name || skillId }), _jsx("button", { type: "button", className: "rounded p-0.5 text-gray-500 hover:bg-gray-200 hover:text-gray-700", title: "Open skill item", "aria-label": `Open ${skill?.name || skillId}`, onClick: () => {
|
|
5813
5944
|
void handleOpenSkillItem(skillId);
|