Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions crates/agent-gateway/web/src/app/GatewayApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { SharedHistoryManagerModal } from "@liveagent/ui/components/chat/SharedH
import { TaskProgressIndicator } from "@liveagent/ui/components/chat/TaskProgressIndicator";
import { ToolApprovalBar } from "@liveagent/ui/components/chat/ToolApprovalBar";
import { useSequencedTaskProgress } from "@liveagent/ui/components/chat/useSequencedTaskProgress";
import { WorkspaceResourceSettingsDrawer } from "@liveagent/ui/components/chat/WorkspaceResourceSettingsDrawer";
import type {
GitCommitContextPayload,
GitFileContextPayload,
Expand Down Expand Up @@ -123,8 +124,10 @@ import {
type RightDockFileTreeStatePatch,
type RightDockProjectState,
removeRightDockProjectState,
resetWorkspaceResourceSettings,
resolveEffectiveTheme,
resolveWorkspaceProjects,
resolveWorkspaceResources,
type SelectedModel,
setSelectedModel,
updateChatRuntimeControlsForProvider,
Expand All @@ -136,6 +139,7 @@ import {
updateSkills,
updateSshProjectHostIds,
updateSystem,
updateWorkspaceResourceSettings,
type WorkspaceProject,
workspaceProjectPathKey,
} from "@/lib/settings";
Expand Down Expand Up @@ -395,6 +399,9 @@ export default function GatewayApp() {
const [sharedHistoryItems, setSharedHistoryItems] = useState<ChatHistorySummary[]>([]);
const [userMenuOpen, setUserMenuOpen] = useState(false);
const [activeView, setActiveView] = useState<"chat" | "skills-hub" | "mcp-hub">("chat");
const [resourceSettingsProject, setResourceSettingsProject] = useState<WorkspaceProject | null>(
null,
);
const [rightDockOpen, setRightDockOpen] = useState(false);
const { confirm: requestConfirmDialog, dialog: confirmDialog } = useConfirmDialog();
// Both elements arrive via callback refs → state so the scroll-follow hook
Expand Down Expand Up @@ -2812,7 +2819,10 @@ export default function GatewayApp() {
getDefaultWorkspaceProjectPath(prev.system),
),
};
return removeRightDockProjectState(nextSettings, pathKey);
return removeRightDockProjectState(
resetWorkspaceResourceSettings(nextSettings, pathKey),
pathKey,
);
});
setProjectRenamingId((current) => (current === project.id ? null : current));
setProjectRenameDraft("");
Expand Down Expand Up @@ -3955,14 +3965,22 @@ export default function GatewayApp() {
[displayedConversationId, setSettings],
);

const skillsEnabled = settings.skills.enabled && isAgentMode;
const resourceWorkdir =
sidebarConversationsById.get(displayedConversationId)?.cwd?.trim() ||
conversationWorkdirsRef.current.get(displayedConversationId)?.trim() ||
(isAgentMode ? activeWorkspaceProjectPath || settings.system.workdir.trim() : "");
const workspaceResources = useMemo(
() => resolveWorkspaceResources(settings, resourceWorkdir),
[resourceWorkdir, settings],
);
const skillsEnabled = workspaceResources.skillsEnabled && isAgentMode;
const selectedSkillNames = useMemo(
() => (skillsEnabled ? mergeAlwaysEnabledSkillNames(settings.skills.selected) : []),
[skillsEnabled, settings.skills.selected],
() => (skillsEnabled ? workspaceResources.skillNames : []),
[skillsEnabled, workspaceResources.skillNames],
);
const { availableSkills, skillsRootDir } = useChatSkills({
skillsEnabled,
selectedSkillNames,
skillsEnabled: settings.skills.enabled && isAgentMode,
selectedSkillNames: settings.skills.selected,
setSettings,
});
const enabledComposerSkills = useMemo(() => {
Expand Down Expand Up @@ -4721,6 +4739,7 @@ export default function GatewayApp() {
onSelectProject={handleSelectWorkspaceProject}
onNewConversationForProject={handleNewConversationForProject}
onBrowseProjectInFileTree={handleBrowseWorkspaceProjectInFileTree}
onConfigureProjectResources={setResourceSettingsProject}
onStartRenamingProject={handleStartRenamingWorkspaceProject}
onProjectRenameDraftChange={setProjectRenameDraft}
onCommitProjectRename={handleCommitWorkspaceProjectRename}
Expand Down Expand Up @@ -5253,6 +5272,21 @@ export default function GatewayApp() {
/>
) : null}

{resourceSettingsProject ? (
<WorkspaceResourceSettingsDrawer
project={resourceSettingsProject}
settings={settings}
skills={availableSkills}
onClose={() => setResourceSettingsProject(null)}
onSave={(draft) => {
setSettings((prev) =>
updateWorkspaceResourceSettings(prev, resourceSettingsProject.path, draft),
);
setResourceSettingsProject(null);
}}
/>
) : null}

{settingsOpen ? (
<div
className={`gateway-settings-overlay ${
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export type GatewaySidebarContainerProps = {
onSelectProject: (project: WorkspaceProject) => void;
onNewConversationForProject: (project: WorkspaceProject) => void;
onBrowseProjectInFileTree: (project: WorkspaceProject) => void;
onConfigureProjectResources: (project: WorkspaceProject) => void;
onStartRenamingProject: (project: WorkspaceProject) => void;
onProjectRenameDraftChange: (value: string) => void;
onCommitProjectRename: () => void;
Expand Down Expand Up @@ -353,6 +354,7 @@ export function GatewaySidebarContainer(props: GatewaySidebarContainerProps) {
onSelectProject={props.onSelectProject}
onNewConversationForProject={props.onNewConversationForProject}
onBrowseProjectInFileTree={props.onBrowseProjectInFileTree}
onConfigureProjectResources={props.onConfigureProjectResources}
onStartRenamingProject={props.onStartRenamingProject}
onProjectRenameDraftChange={props.onProjectRenameDraftChange}
onCommitProjectRename={props.onCommitProjectRename}
Expand Down
25 changes: 25 additions & 0 deletions crates/agent-gateway/web/src/i18n/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ export const translations: Record<Locale, Record<string, string>> = {
"chat.workspaceCloneWebDisabled": "请先在远程设置中启用网页 Git 操作。",
"chat.workspaceNewConversation": "新对话",
"chat.workspaceMore": "更多",
"chat.workspaceResources": "配置 Skills 与 MCP",
"chat.workspaceResourcesTitle": "工作空间资源设置",
"chat.workspaceResourcesModeInherit": "跟随全局",
"chat.workspaceResourcesModeCustom": "自定义",
"chat.workspaceResourcesModeOff": "全部关闭",
"chat.workspaceResourcesInheritHint": "使用 Skill Hub 与 MCP Hub 中的默认启用设置。",
"chat.workspaceResourcesCustomHint": "选择仅向此工作空间中的 Agent 暴露的 Skills 与 MCP。",
"chat.workspaceResourcesOffHint": "此工作空间不会向 Agent 暴露 Skills 或 MCP。",
"chat.workspaceResourcesSearch": "搜索名称或描述",
"chat.workspaceResourcesSelected": "已选择 {skills} 个 Skills、{mcp} 个 MCP",
"chat.workspaceResourcesMissingSkill": "此 Skill 尚未安装在当前设备上。",
"chat.workspacePin": "置顶工作空间",
"chat.workspaceUnpin": "取消置顶",
"chat.workspaceRename": "修改标题",
Expand Down Expand Up @@ -2248,6 +2259,20 @@ export const translations: Record<Locale, Record<string, string>> = {
"chat.workspaceCloneWebDisabled": "Enable Web Git in Remote settings before cloning.",
"chat.workspaceNewConversation": "New conversation",
"chat.workspaceMore": "More",
"chat.workspaceResources": "Configure Skills & MCP",
"chat.workspaceResourcesTitle": "Workspace resources",
"chat.workspaceResourcesModeInherit": "Use defaults",
"chat.workspaceResourcesModeCustom": "Custom",
"chat.workspaceResourcesModeOff": "Disable all",
"chat.workspaceResourcesInheritHint":
"Uses the default enabled resources from Skill Hub and MCP Hub.",
"chat.workspaceResourcesCustomHint":
"Choose the Skills and MCP servers exposed to agents in this workspace.",
"chat.workspaceResourcesOffHint":
"No Skills or MCP servers are exposed to agents in this workspace.",
"chat.workspaceResourcesSearch": "Search names or descriptions",
"chat.workspaceResourcesSelected": "{skills} Skills and {mcp} MCP servers selected",
"chat.workspaceResourcesMissingSkill": "This Skill is not installed on this device.",
"chat.workspacePin": "Pin workspace",
"chat.workspaceUnpin": "Unpin",
"chat.workspaceRename": "Rename",
Expand Down
Loading
Loading