@parhelia/core 0.1.12169 → 0.1.12181
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/editor/ai/AgentTerminal.js +256 -81
- package/dist/editor/ai/AgentTerminal.js.map +1 -1
- package/dist/editor/ai/AgentTerminalStatusBar.d.ts +1 -3
- package/dist/editor/ai/AgentTerminalStatusBar.js +3 -15
- package/dist/editor/ai/AgentTerminalStatusBar.js.map +1 -1
- package/dist/editor/ai/ContextInfoBar.d.ts +1 -3
- package/dist/editor/ai/ContextInfoBar.js +6 -148
- package/dist/editor/ai/ContextInfoBar.js.map +1 -1
- package/dist/editor/ui/SimpleTabs.d.ts +1 -0
- package/dist/editor/ui/SimpleTabs.js +9 -6
- package/dist/editor/ui/SimpleTabs.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/task-board/TaskBoardWorkspace.js +46 -9
- package/dist/task-board/TaskBoardWorkspace.js.map +1 -1
- package/dist/task-board/components/ProjectSelector.js +12 -5
- package/dist/task-board/components/ProjectSelector.js.map +1 -1
- package/dist/task-board/components/TaskBoardTitlebar.js +1 -1
- package/dist/task-board/components/TaskBoardTitlebar.js.map +1 -1
- package/dist/task-board/views/ListView.js +11 -6
- package/dist/task-board/views/ListView.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,11 @@
|
|
|
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
|
-
import { Send, AlertCircle, Loader2, User, Wand2, Square, Mic, MicOff, ChevronDown, ChevronUp, ListTodo, ArrowLeft, DollarSign, } from "lucide-react";
|
|
4
|
-
import { getAgent, startAgent, updateAgentSettings, updateAgentCostLimit, updateAgentContext, cancelAgent, canonicalizeAgentMetadata, getPendingPrompts, } from "../services/agentService";
|
|
3
|
+
import { Send, AlertCircle, Loader2, User, Wand2, Square, Mic, MicOff, ChevronDown, ChevronUp, ListTodo, ArrowLeft, DollarSign, ExternalLink, Settings2, Target, Plus, X, } from "lucide-react";
|
|
4
|
+
import { getAgent, startAgent, updateAgentSettings, updateAgentCostLimit, updateAgentContext, getAgentSkills, cancelAgent, canonicalizeAgentMetadata, getPendingPrompts, } from "../services/agentService";
|
|
5
5
|
import { useEditContext, useFieldsEditContext } from "../client/editContext";
|
|
6
6
|
import { Textarea } from "../../components/ui/textarea";
|
|
7
7
|
import { Button } from "../../components/ui/button";
|
|
8
|
+
import { Input } from "../../components/ui/input";
|
|
8
9
|
import { PlaceholderInput, } from "../../components/ui/PlaceholderInput";
|
|
9
10
|
import { AiResponseMessage } from "./AiResponseMessage";
|
|
10
11
|
import { ContextInfoBar } from "./ContextInfoBar";
|
|
@@ -771,6 +772,11 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
771
772
|
const [contextPanelsActiveTab, setContextPanelsActiveTab] = useState(0);
|
|
772
773
|
const [hiddenContextPanelTabIds, setHiddenContextPanelTabIds] = useState(new Set());
|
|
773
774
|
const [showCostAndAgent, setShowCostAndAgent] = useState(false);
|
|
775
|
+
const [showAgentSettings, setShowAgentSettings] = useState(false);
|
|
776
|
+
const [skillSearchTerm, setSkillSearchTerm] = useState("");
|
|
777
|
+
const [availableSkills, setAvailableSkills] = useState([]);
|
|
778
|
+
const [skillsLoading, setSkillsLoading] = useState(false);
|
|
779
|
+
const [skillsError, setSkillsError] = useState(null);
|
|
774
780
|
const hasSpawnedAgents = useMemo(() => {
|
|
775
781
|
if (!agentMetadata)
|
|
776
782
|
return false;
|
|
@@ -865,6 +871,33 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
865
871
|
});
|
|
866
872
|
return () => unsubscribe();
|
|
867
873
|
}, [agent?.id, editContext?.addSocketMessageListener]);
|
|
874
|
+
useEffect(() => {
|
|
875
|
+
let active = true;
|
|
876
|
+
const loadSkills = async () => {
|
|
877
|
+
try {
|
|
878
|
+
setSkillsLoading(true);
|
|
879
|
+
setSkillsError(null);
|
|
880
|
+
const skills = await getAgentSkills(false);
|
|
881
|
+
if (active) {
|
|
882
|
+
setAvailableSkills(skills.filter((s) => !s.disabled));
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
catch (e) {
|
|
886
|
+
if (active) {
|
|
887
|
+
setSkillsError(e?.message || "Failed to load skills");
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
finally {
|
|
891
|
+
if (active) {
|
|
892
|
+
setSkillsLoading(false);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
void loadSkills();
|
|
897
|
+
return () => {
|
|
898
|
+
active = false;
|
|
899
|
+
};
|
|
900
|
+
}, []);
|
|
868
901
|
const modeOptions = useMemo(() => [
|
|
869
902
|
{
|
|
870
903
|
value: "supervised",
|
|
@@ -899,6 +932,70 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
899
932
|
value: m.id,
|
|
900
933
|
label: m.name,
|
|
901
934
|
})) || []).sort((a, b) => a.label.localeCompare(b.label)), [activeProfile]);
|
|
935
|
+
const metadataSelectedSkillIds = useMemo(() => {
|
|
936
|
+
const rawSkillIds = agentMetadata?.additionalData?.skillIds ??
|
|
937
|
+
agentMetadata?.AdditionalData?.skillIds ??
|
|
938
|
+
agentMetadata?.skillIds ??
|
|
939
|
+
agentMetadata?.SkillIds ??
|
|
940
|
+
[];
|
|
941
|
+
if (!Array.isArray(rawSkillIds)) {
|
|
942
|
+
return [];
|
|
943
|
+
}
|
|
944
|
+
return rawSkillIds
|
|
945
|
+
.map((x) => String(x || "").trim())
|
|
946
|
+
.filter((x) => x.length > 0);
|
|
947
|
+
}, [agentMetadata]);
|
|
948
|
+
const backendAssignedSkillIds = useMemo(() => {
|
|
949
|
+
const rawSkillIds = agent?.assignedSkillIds ?? agent?.AssignedSkillIds ?? [];
|
|
950
|
+
if (!Array.isArray(rawSkillIds)) {
|
|
951
|
+
return [];
|
|
952
|
+
}
|
|
953
|
+
return rawSkillIds
|
|
954
|
+
.map((x) => String(x || "").trim())
|
|
955
|
+
.filter((x) => x.length > 0);
|
|
956
|
+
}, [agent]);
|
|
957
|
+
const selectedSkillIds = useMemo(() => {
|
|
958
|
+
const all = [...backendAssignedSkillIds, ...metadataSelectedSkillIds];
|
|
959
|
+
const seen = new Set();
|
|
960
|
+
const unique = [];
|
|
961
|
+
for (const id of all) {
|
|
962
|
+
const key = id.toLowerCase();
|
|
963
|
+
if (seen.has(key))
|
|
964
|
+
continue;
|
|
965
|
+
seen.add(key);
|
|
966
|
+
unique.push(id);
|
|
967
|
+
}
|
|
968
|
+
return unique;
|
|
969
|
+
}, [backendAssignedSkillIds, metadataSelectedSkillIds]);
|
|
970
|
+
const allowedProfileSkillIdSet = useMemo(() => {
|
|
971
|
+
const ids = activeProfile?.allowedSkills
|
|
972
|
+
?.map((skill) => String(skill?.id || "").toLowerCase())
|
|
973
|
+
.filter((id) => id.length > 0) || [];
|
|
974
|
+
return new Set(ids);
|
|
975
|
+
}, [activeProfile?.allowedSkills]);
|
|
976
|
+
const profileFilteredSkills = useMemo(() => {
|
|
977
|
+
if (allowedProfileSkillIdSet.size === 0) {
|
|
978
|
+
return availableSkills;
|
|
979
|
+
}
|
|
980
|
+
return availableSkills.filter((skill) => allowedProfileSkillIdSet.has(skill.id.toLowerCase()));
|
|
981
|
+
}, [availableSkills, allowedProfileSkillIdSet]);
|
|
982
|
+
const selectedSkills = useMemo(() => selectedSkillIds
|
|
983
|
+
.map((id) => profileFilteredSkills.find((s) => s.id.toLowerCase() === id.toLowerCase()))
|
|
984
|
+
.filter((s) => !!s), [profileFilteredSkills, selectedSkillIds]);
|
|
985
|
+
const selectedSkillSet = useMemo(() => new Set(selectedSkillIds.map((id) => id.toLowerCase())), [selectedSkillIds]);
|
|
986
|
+
const backendAssignedSkillSet = useMemo(() => new Set(backendAssignedSkillIds.map((id) => id.toLowerCase())), [backendAssignedSkillIds]);
|
|
987
|
+
const selectableSkills = useMemo(() => profileFilteredSkills.filter((skill) => !selectedSkillSet.has(skill.id.toLowerCase())), [profileFilteredSkills, selectedSkillSet]);
|
|
988
|
+
const filteredSelectableSkills = useMemo(() => {
|
|
989
|
+
const q = skillSearchTerm.trim().toLowerCase();
|
|
990
|
+
if (!q)
|
|
991
|
+
return selectableSkills;
|
|
992
|
+
return selectableSkills.filter((skill) => {
|
|
993
|
+
const name = (skill.name || "").toLowerCase();
|
|
994
|
+
const description = (skill.description || "").toLowerCase();
|
|
995
|
+
const id = (skill.id || "").toLowerCase();
|
|
996
|
+
return name.includes(q) || description.includes(q) || id.includes(q);
|
|
997
|
+
});
|
|
998
|
+
}, [selectableSkills, skillSearchTerm]);
|
|
902
999
|
// Remove deprecated cost limit fields from metadata to avoid confusion with agent/profile settings
|
|
903
1000
|
const sanitizeAgentMetadata = useCallback((meta) => {
|
|
904
1001
|
try {
|
|
@@ -923,6 +1020,65 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
923
1020
|
return meta;
|
|
924
1021
|
}
|
|
925
1022
|
}, []);
|
|
1023
|
+
const updateSelectedSkillIds = useCallback(async (skillIds) => {
|
|
1024
|
+
if (!agent?.id)
|
|
1025
|
+
return;
|
|
1026
|
+
const current = agentMetadata || {};
|
|
1027
|
+
const currentAdditionalData = current.additionalData ||
|
|
1028
|
+
current.AdditionalData ||
|
|
1029
|
+
{};
|
|
1030
|
+
const nextAdditionalData = {
|
|
1031
|
+
...currentAdditionalData,
|
|
1032
|
+
};
|
|
1033
|
+
if (skillIds.length > 0) {
|
|
1034
|
+
nextAdditionalData.skillIds = skillIds;
|
|
1035
|
+
}
|
|
1036
|
+
else {
|
|
1037
|
+
delete nextAdditionalData.skillIds;
|
|
1038
|
+
}
|
|
1039
|
+
const next = {
|
|
1040
|
+
...current,
|
|
1041
|
+
};
|
|
1042
|
+
if (Object.keys(nextAdditionalData).length > 0) {
|
|
1043
|
+
next.additionalData = nextAdditionalData;
|
|
1044
|
+
delete next.AdditionalData;
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
delete next.additionalData;
|
|
1048
|
+
delete next.AdditionalData;
|
|
1049
|
+
}
|
|
1050
|
+
try {
|
|
1051
|
+
if (agent.status === "new") {
|
|
1052
|
+
setAgentMetadata(next);
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
await updateAgentContext(agent.id, next);
|
|
1056
|
+
setAgentMetadata(next);
|
|
1057
|
+
setAgent((prev) => prev ? { ...prev, agentContext: JSON.stringify(next) } : prev);
|
|
1058
|
+
}
|
|
1059
|
+
catch (e) {
|
|
1060
|
+
console.error("Failed to update selected skills", e);
|
|
1061
|
+
}
|
|
1062
|
+
}, [agent?.id, agent?.status, agentMetadata, setAgent, setAgentMetadata]);
|
|
1063
|
+
const handleAddSkill = useCallback(async (skillId) => {
|
|
1064
|
+
if (selectedSkillSet.has(skillId.toLowerCase()))
|
|
1065
|
+
return;
|
|
1066
|
+
await updateSelectedSkillIds([...metadataSelectedSkillIds, skillId]);
|
|
1067
|
+
}, [metadataSelectedSkillIds, selectedSkillSet, updateSelectedSkillIds]);
|
|
1068
|
+
const handleRemoveSkill = useCallback(async (skillId) => {
|
|
1069
|
+
await updateSelectedSkillIds(metadataSelectedSkillIds.filter((id) => id.toLowerCase() !== skillId.toLowerCase()));
|
|
1070
|
+
}, [metadataSelectedSkillIds, updateSelectedSkillIds]);
|
|
1071
|
+
const handleOpenProfileSettings = useCallback(async () => {
|
|
1072
|
+
if (!editContext || !activeProfile?.id)
|
|
1073
|
+
return;
|
|
1074
|
+
const lang = editContext.currentItemDescriptor?.language || "en";
|
|
1075
|
+
await editContext.loadItem({
|
|
1076
|
+
id: activeProfile.id,
|
|
1077
|
+
language: lang,
|
|
1078
|
+
version: 0,
|
|
1079
|
+
});
|
|
1080
|
+
editContext.switchWorkspace("editor");
|
|
1081
|
+
}, [editContext, activeProfile?.id]);
|
|
926
1082
|
// Read deterministic flags from query string once
|
|
927
1083
|
let deterministicFlags;
|
|
928
1084
|
try {
|
|
@@ -4139,7 +4295,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
4139
4295
|
if (isLoading && !activeInlineDialog) {
|
|
4140
4296
|
return (_jsx("div", { className: "flex h-full items-center justify-center", children: _jsxs("div", { className: "flex items-center gap-2 text-[11px] text-gray-500", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin", strokeWidth: 1 }), "Loading agent..."] }) }));
|
|
4141
4297
|
}
|
|
4142
|
-
const renderContextInfoBar = () => (_jsx(ContextInfoBar, { agent: agent, agentMetadata: agentMetadata, setAgentMetadata: setAgentMetadata, setAgent: setAgent, resolvedPageName: resolvedPageName, resolvedComponentName: resolvedComponentName, resolvedFieldName: resolvedFieldName, isLiveEditorContextMode: isLiveEditorContextMode,
|
|
4298
|
+
const renderContextInfoBar = () => (_jsx(ContextInfoBar, { agent: agent, agentMetadata: agentMetadata, setAgentMetadata: setAgentMetadata, setAgent: setAgent, resolvedPageName: resolvedPageName, resolvedComponentName: resolvedComponentName, resolvedFieldName: resolvedFieldName, isLiveEditorContextMode: isLiveEditorContextMode, onRefreshContext: handleRefreshContext }));
|
|
4143
4299
|
const renderCostLimitBanner = () => {
|
|
4144
4300
|
if (!costLimitExceeded)
|
|
4145
4301
|
return null;
|
|
@@ -4424,7 +4580,6 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
4424
4580
|
? "border-amber-300 bg-amber-50! text-amber-700 hover:bg-amber-100!"
|
|
4425
4581
|
: "border-red-300 bg-red-50! text-red-700 hover:bg-red-100!"), value: mode, options: modeOptions, onValueChange: async (val) => {
|
|
4426
4582
|
const nextMode = val || "supervised";
|
|
4427
|
-
// Optimistic UI update
|
|
4428
4583
|
setMode(nextMode);
|
|
4429
4584
|
const current = agentMetadata || {};
|
|
4430
4585
|
const nextMeta = {
|
|
@@ -4434,7 +4589,6 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
4434
4589
|
try {
|
|
4435
4590
|
if (!agent?.id || agent.status === "new") {
|
|
4436
4591
|
setAgentMetadata(nextMeta);
|
|
4437
|
-
// Cache until first start when agent is persisted
|
|
4438
4592
|
pendingSettingsRef.current = {
|
|
4439
4593
|
...(pendingSettingsRef.current || {}),
|
|
4440
4594
|
mode: nextMode,
|
|
@@ -4445,87 +4599,108 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
4445
4599
|
mode: nextMode,
|
|
4446
4600
|
});
|
|
4447
4601
|
setAgentMetadata(nextMeta);
|
|
4448
|
-
setAgent((prev) => prev
|
|
4449
|
-
? { ...prev, metadata: JSON.stringify(nextMeta) }
|
|
4450
|
-
: prev);
|
|
4451
|
-
}
|
|
4452
|
-
catch (e2) {
|
|
4453
|
-
console.error("Failed to persist mode change", e2);
|
|
4454
|
-
}
|
|
4455
|
-
} }), profiles?.length > 0 && (_jsx(Select, { size: "xs", maxWidth: 200, searchable: profiles.length > 5, searchPlaceholder: "Filter profiles...", className: "h-5 w-auto min-w-[120px] rounded border px-1.5 text-[11px] text-gray-500", value: activeProfile?.id || "", options: profileOptions, "data-testid": "agent-profile-selector", onValueChange: async (val) => {
|
|
4456
|
-
const nextProfile = profiles.find((x) => x.id === val);
|
|
4457
|
-
if (!nextProfile)
|
|
4458
|
-
return;
|
|
4459
|
-
setActiveProfile(nextProfile);
|
|
4460
|
-
try {
|
|
4461
|
-
if (agent?.id && agent.status !== "new") {
|
|
4462
|
-
await updateAgentSettings(agent.id, {
|
|
4463
|
-
profileId: nextProfile.id,
|
|
4464
|
-
profileName: nextProfile.name,
|
|
4465
|
-
});
|
|
4466
|
-
}
|
|
4467
|
-
else {
|
|
4468
|
-
// cache until first start
|
|
4469
|
-
pendingSettingsRef.current = {
|
|
4470
|
-
...(pendingSettingsRef.current || {}),
|
|
4471
|
-
// we cache profile by updating local metadata
|
|
4472
|
-
};
|
|
4473
|
-
setAgentMetadata((current) => {
|
|
4474
|
-
const next = { ...(current || {}) };
|
|
4475
|
-
next.profile = nextProfile.name;
|
|
4476
|
-
next.additionalData = {
|
|
4477
|
-
...(next.additionalData || {}),
|
|
4478
|
-
profileId: nextProfile.id,
|
|
4479
|
-
profileName: nextProfile.name,
|
|
4480
|
-
};
|
|
4481
|
-
return next;
|
|
4482
|
-
});
|
|
4483
|
-
}
|
|
4484
|
-
// reflect in local agent stub so tabs and titles can use it if needed
|
|
4485
4602
|
setAgent((prev) => prev
|
|
4486
4603
|
? {
|
|
4487
4604
|
...prev,
|
|
4488
|
-
metadata: JSON.stringify(
|
|
4489
|
-
...(agentMetadata || {}),
|
|
4490
|
-
profile: nextProfile.name,
|
|
4491
|
-
additionalData: {
|
|
4492
|
-
...(agentMetadata
|
|
4493
|
-
?.additionalData || {}),
|
|
4494
|
-
profileId: nextProfile.id,
|
|
4495
|
-
profileName: nextProfile.name,
|
|
4496
|
-
},
|
|
4497
|
-
}),
|
|
4605
|
+
metadata: JSON.stringify(nextMeta),
|
|
4498
4606
|
}
|
|
4499
4607
|
: prev);
|
|
4500
4608
|
}
|
|
4501
|
-
catch (
|
|
4502
|
-
console.error("Failed to persist
|
|
4503
|
-
}
|
|
4504
|
-
} })), activeProfile?.models?.length ? (_jsx(Select, { size: "xs", maxWidth: 300, searchable: activeProfile.models.length > 5, searchPlaceholder: "Filter models...", className: "h-5 w-auto min-w-[120px] rounded border px-1.5 text-[11px] text-gray-500", value: selectedModelId || "", options: modelOptions, onValueChange: async (val) => {
|
|
4505
|
-
const nextId = val;
|
|
4506
|
-
setSelectedModelId(nextId);
|
|
4507
|
-
const modelName = activeProfile?.models?.find((m) => m.id === nextId)
|
|
4508
|
-
?.name || "";
|
|
4509
|
-
// Update local agent state immediately for UX and to reflect in streaming stub
|
|
4510
|
-
setAgent((prev) => prev ? { ...prev, model: modelName } : prev);
|
|
4511
|
-
// Persist only for existing agents; otherwise cache until first start
|
|
4512
|
-
try {
|
|
4513
|
-
if (agent?.id && agent.status !== "new") {
|
|
4514
|
-
await updateAgentSettings(agent.id, {
|
|
4515
|
-
model: modelName,
|
|
4516
|
-
});
|
|
4517
|
-
}
|
|
4518
|
-
else {
|
|
4519
|
-
pendingSettingsRef.current = {
|
|
4520
|
-
...(pendingSettingsRef.current || {}),
|
|
4521
|
-
modelName,
|
|
4522
|
-
};
|
|
4523
|
-
}
|
|
4524
|
-
}
|
|
4525
|
-
catch (err) {
|
|
4526
|
-
console.error("Failed to persist agent model", err);
|
|
4609
|
+
catch (e2) {
|
|
4610
|
+
console.error("Failed to persist mode change", e2);
|
|
4527
4611
|
}
|
|
4528
|
-
} })
|
|
4612
|
+
} }), _jsxs(Popover, { open: showAgentSettings, onOpenChange: (open) => {
|
|
4613
|
+
setShowAgentSettings(open);
|
|
4614
|
+
if (!open)
|
|
4615
|
+
setSkillSearchTerm("");
|
|
4616
|
+
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { size: "xs", variant: "outline", className: "h-5 rounded border px-1.5 text-[11px] text-gray-600", "data-testid": "agent-settings-popover-trigger", children: [_jsx(Settings2, { className: "mr-1 h-3 w-3", strokeWidth: 1 }), "Agent settings"] }) }), _jsx(PopoverContent, { className: "w-80 p-3", align: "start", children: _jsxs("div", { className: "space-y-3", children: [profiles?.length > 0 && (_jsxs("div", { children: [_jsx("div", { className: "mb-1 text-[11px] font-medium text-gray-700", children: "Agent profile" }), _jsx(Select, { size: "xs", maxWidth: 300, searchable: profiles.length > 5, searchPlaceholder: "Filter profiles...", className: "h-6 w-full rounded border px-1.5 text-[11px] text-gray-500", value: activeProfile?.id || "", options: profileOptions, "data-testid": "agent-profile-selector", onValueChange: async (val) => {
|
|
4617
|
+
const nextProfile = profiles.find((x) => x.id === val);
|
|
4618
|
+
if (!nextProfile)
|
|
4619
|
+
return;
|
|
4620
|
+
setActiveProfile(nextProfile);
|
|
4621
|
+
try {
|
|
4622
|
+
if (agent?.id && agent.status !== "new") {
|
|
4623
|
+
await updateAgentSettings(agent.id, {
|
|
4624
|
+
profileId: nextProfile.id,
|
|
4625
|
+
profileName: nextProfile.name,
|
|
4626
|
+
});
|
|
4627
|
+
}
|
|
4628
|
+
else {
|
|
4629
|
+
pendingSettingsRef.current = {
|
|
4630
|
+
...(pendingSettingsRef.current || {}),
|
|
4631
|
+
};
|
|
4632
|
+
setAgentMetadata((current) => {
|
|
4633
|
+
const next = { ...(current || {}) };
|
|
4634
|
+
next.profile = nextProfile.name;
|
|
4635
|
+
next.additionalData = {
|
|
4636
|
+
...(next.additionalData || {}),
|
|
4637
|
+
profileId: nextProfile.id,
|
|
4638
|
+
profileName: nextProfile.name,
|
|
4639
|
+
};
|
|
4640
|
+
return next;
|
|
4641
|
+
});
|
|
4642
|
+
}
|
|
4643
|
+
setAgent((prev) => prev
|
|
4644
|
+
? {
|
|
4645
|
+
...prev,
|
|
4646
|
+
metadata: JSON.stringify({
|
|
4647
|
+
...(agentMetadata || {}),
|
|
4648
|
+
profile: nextProfile.name,
|
|
4649
|
+
additionalData: {
|
|
4650
|
+
...(agentMetadata
|
|
4651
|
+
?.additionalData || {}),
|
|
4652
|
+
profileId: nextProfile.id,
|
|
4653
|
+
profileName: nextProfile.name,
|
|
4654
|
+
},
|
|
4655
|
+
}),
|
|
4656
|
+
}
|
|
4657
|
+
: prev);
|
|
4658
|
+
}
|
|
4659
|
+
catch (err) {
|
|
4660
|
+
console.error("Failed to persist agent profile", err);
|
|
4661
|
+
}
|
|
4662
|
+
} }), activeProfile && (_jsxs("button", { type: "button", className: "mt-1 inline-flex items-center gap-1 text-[10px] text-gray-500 hover:text-gray-700", onClick: () => {
|
|
4663
|
+
void handleOpenProfileSettings();
|
|
4664
|
+
setShowAgentSettings(false);
|
|
4665
|
+
}, children: ["Open profile settings", _jsx(ExternalLink, { className: "h-2.5 w-2.5", strokeWidth: 1.5 })] }))] })), activeProfile?.models?.length ? (_jsxs("div", { children: [_jsx("div", { className: "mb-1 text-[11px] font-medium text-gray-700", children: "Model" }), _jsx(Select, { size: "xs", maxWidth: 300, searchable: activeProfile.models.length > 5, searchPlaceholder: "Filter models...", className: "h-6 w-full rounded border px-1.5 text-[11px] text-gray-500", value: selectedModelId || "", options: modelOptions, onValueChange: async (val) => {
|
|
4666
|
+
const nextId = val;
|
|
4667
|
+
setSelectedModelId(nextId);
|
|
4668
|
+
const modelName = activeProfile?.models?.find((m) => m.id === nextId)
|
|
4669
|
+
?.name || "";
|
|
4670
|
+
setAgent((prev) => prev ? { ...prev, model: modelName } : prev);
|
|
4671
|
+
try {
|
|
4672
|
+
if (agent?.id && agent.status !== "new") {
|
|
4673
|
+
await updateAgentSettings(agent.id, {
|
|
4674
|
+
model: modelName,
|
|
4675
|
+
});
|
|
4676
|
+
}
|
|
4677
|
+
else {
|
|
4678
|
+
pendingSettingsRef.current = {
|
|
4679
|
+
...(pendingSettingsRef.current || {}),
|
|
4680
|
+
modelName,
|
|
4681
|
+
};
|
|
4682
|
+
}
|
|
4683
|
+
}
|
|
4684
|
+
catch (err) {
|
|
4685
|
+
console.error("Failed to persist agent model", err);
|
|
4686
|
+
}
|
|
4687
|
+
} })] })) : null, _jsxs("div", { children: [_jsxs("div", { className: "mb-1 flex items-center gap-1 text-[11px] font-medium text-gray-700", children: [_jsx(Target, { className: "h-3 w-3", strokeWidth: 1 }), "Skills"] }), _jsx(Input, { value: skillSearchTerm, onChange: (e) => setSkillSearchTerm(e.target.value), placeholder: "Search skills...", className: "mb-2 h-6 px-2 text-[10px]" }), selectedSkillIds.length > 0 && (_jsx("div", { className: "mb-2 flex flex-wrap gap-1", children: selectedSkillIds.map((skillId) => {
|
|
4688
|
+
const skill = selectedSkills.find((s) => s.id === skillId);
|
|
4689
|
+
return (_jsxs("button", { type: "button", 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 hover:bg-gray-200", onClick: () => {
|
|
4690
|
+
if (backendAssignedSkillSet.has(skillId.toLowerCase()))
|
|
4691
|
+
return;
|
|
4692
|
+
void handleRemoveSkill(skillId);
|
|
4693
|
+
}, disabled: backendAssignedSkillSet.has(skillId.toLowerCase()), title: backendAssignedSkillSet.has(skillId.toLowerCase())
|
|
4694
|
+
? "Assigned by backend profile"
|
|
4695
|
+
: "Remove skill", children: [_jsx("span", { children: skill?.name || skillId }), backendAssignedSkillSet.has(skillId.toLowerCase()) ? (_jsx("span", { className: "text-[9px] text-gray-500", children: "auto" })) : (_jsx(X, { className: "h-2.5 w-2.5", strokeWidth: 1 }))] }, skillId));
|
|
4696
|
+
}) })), _jsx("div", { className: "max-h-40 space-y-1 overflow-y-auto rounded border border-gray-200 bg-gray-50 p-1.5", children: skillsLoading ? (_jsx("div", { className: "px-1 text-[10px] text-gray-500", children: "Loading skills..." })) : filteredSelectableSkills.length > 0 ? (filteredSelectableSkills.map((skill) => (_jsxs("button", { type: "button", className: "flex w-full items-start gap-1 rounded px-1.5 py-1 text-left text-[10px] text-gray-700 hover:bg-gray-100", onClick: () => {
|
|
4697
|
+
void handleAddSkill(skill.id);
|
|
4698
|
+
setSkillSearchTerm("");
|
|
4699
|
+
}, children: [_jsx(Plus, { className: "mt-[1px] h-2.5 w-2.5 shrink-0", strokeWidth: 1 }), _jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "block truncate font-medium text-gray-900", children: skill.name }), skill.description && (_jsx("span", { className: "line-clamp-2 text-[10px] text-gray-500", children: skill.description }))] })] }, skill.id)))) : (_jsx("div", { className: "px-1 text-[10px] text-gray-500", children: selectableSkills.length === 0
|
|
4700
|
+
? selectedSkillIds.length > 0
|
|
4701
|
+
? "All allowed skills are selected"
|
|
4702
|
+
: "No skills available for this profile"
|
|
4703
|
+
: "No skills match your search" })) }), !skillsLoading && selectableSkills.length > 0 && (_jsxs("div", { className: "mt-1 text-[10px] text-gray-500", children: ["Showing ", filteredSelectableSkills.length, " of ", selectableSkills.length] })), skillsError && (_jsx("div", { className: "mt-1 text-[10px] text-red-600", children: skillsError }))] })] }) })] }), activeProfile?.prompts?.length ? (_jsxs(Popover, { open: showPredefined, onOpenChange: setShowPredefined, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { className: "rounded p-1 hover:bg-gray-100", onClick: () => { }, title: "Predefined prompts", "aria-label": "Predefined prompts", type: "button", children: _jsx(Wand2, { className: "h-3 w-3", strokeWidth: 1 }) }) }), _jsx(PopoverContent, { className: "w-64 p-0", align: "start", children: _jsx("div", { className: "max-h-56 overflow-y-auto p-2", children: activeProfile.prompts.map((p, index) => (_jsx("div", { className: "cursor-pointer rounded p-1.5 text-[10px] text-gray-700 hover:bg-gray-100", onClick: () => {
|
|
4529
4704
|
setPrompt(p.prompt);
|
|
4530
4705
|
setShowPredefined(false);
|
|
4531
4706
|
if (textareaRef.current)
|
|
@@ -4545,7 +4720,7 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
4545
4720
|
cacheWriteCost: liveTotals.cacheWriteCost ?? 0,
|
|
4546
4721
|
totalCost: liveTotals.totalCost,
|
|
4547
4722
|
}
|
|
4548
|
-
: totalTokens, effectiveCostLimit: effectiveCostLimit, messages: messages,
|
|
4723
|
+
: totalTokens, effectiveCostLimit: effectiveCostLimit, messages: messages, showCompressionPopover: showCompressionPopover, setShowCompressionPopover: setShowCompressionPopover }) }) })] }))] })), _jsxs("div", { className: "flex items-center gap-1 self-end", children: [_jsx("span", { title: isVoiceDisabled
|
|
4549
4724
|
? "Your browser does not support Speech Recognition"
|
|
4550
4725
|
: isListening
|
|
4551
4726
|
? "Stop voice input"
|
|
@@ -4578,6 +4753,6 @@ export function AgentTerminal({ agentStub, initialMetadata, profiles, isActive =
|
|
|
4578
4753
|
cacheWriteCost: liveTotals.cacheWriteCost ?? 0,
|
|
4579
4754
|
totalCost: liveTotals.totalCost,
|
|
4580
4755
|
}
|
|
4581
|
-
: totalTokens, effectiveCostLimit: effectiveCostLimit, messages: messages,
|
|
4756
|
+
: totalTokens, effectiveCostLimit: effectiveCostLimit, messages: messages, showCompressionPopover: showCompressionPopover, setShowCompressionPopover: setShowCompressionPopover }))] })] }));
|
|
4582
4757
|
}
|
|
4583
4758
|
//# sourceMappingURL=AgentTerminal.js.map
|