mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-26 12:17:14 +00:00
Merge remote-tracking branch 'origin/master' into feat/workflow
# Conflicts: # pyproject.toml # src/langbot/pkg/api/http/controller/main.py # src/langbot/pkg/core/app.py # src/langbot/pkg/core/stages/build_app.py # src/langbot/pkg/provider/modelmgr/requester.py # uv.lock # web/package-lock.json # web/package.json # web/pnpm-lock.yaml # web/src/app/home/components/dynamic-form/DynamicFormComponent.tsx # web/src/app/home/components/dynamic-form/DynamicFormItemComponent.tsx # web/src/app/home/components/home-sidebar/HomeSidebar.tsx # web/src/app/infra/entities/api/index.ts # web/src/app/infra/http/BackendClient.ts # web/src/i18n/locales/en-US.ts # web/src/i18n/locales/es-ES.ts # web/src/i18n/locales/ja-JP.ts # web/src/i18n/locales/ru-RU.ts # web/src/i18n/locales/th-TH.ts # web/src/i18n/locales/vi-VN.ts # web/src/i18n/locales/zh-Hans.ts # web/src/i18n/locales/zh-Hant.ts # web/src/router.tsx
This commit is contained in:
@@ -26,11 +26,10 @@ export interface SidebarEntityItem {
|
||||
installInfo?: Record<string, unknown>;
|
||||
hasUpdate?: boolean;
|
||||
debug?: boolean;
|
||||
// Set when this item appears in the unified extensions list
|
||||
extensionType?: 'plugin' | 'mcp' | 'skill';
|
||||
}
|
||||
|
||||
// Install action types that can be triggered from sidebar
|
||||
export type PluginInstallAction = 'local' | 'github' | null;
|
||||
|
||||
// Plugin page registered by a plugin
|
||||
export interface PluginPageItem {
|
||||
id: string; // "author/name/pageId"
|
||||
@@ -51,6 +50,7 @@ export interface SidebarDataContextValue {
|
||||
knowledgeBases: SidebarEntityItem[];
|
||||
plugins: SidebarEntityItem[];
|
||||
mcpServers: SidebarEntityItem[];
|
||||
skills: SidebarEntityItem[];
|
||||
pluginPages: PluginPageItem[];
|
||||
refreshBots: () => Promise<void>;
|
||||
refreshPipelines: () => Promise<void>;
|
||||
@@ -58,13 +58,14 @@ export interface SidebarDataContextValue {
|
||||
refreshKnowledgeBases: () => Promise<void>;
|
||||
refreshPlugins: () => Promise<void>;
|
||||
refreshMCPServers: () => Promise<void>;
|
||||
refreshSkills: () => Promise<void>;
|
||||
refreshAll: () => Promise<void>;
|
||||
// Breadcrumb: entity name shown when viewing a detail page
|
||||
detailEntityName: string | null;
|
||||
setDetailEntityName: (name: string | null) => void;
|
||||
// Pending plugin install action triggered from sidebar
|
||||
pendingPluginInstallAction: PluginInstallAction;
|
||||
setPendingPluginInstallAction: (action: PluginInstallAction) => void;
|
||||
// Whether the extensions list is grouped by type (shared between page and sidebar)
|
||||
extensionsGroupByType: boolean;
|
||||
setExtensionsGroupByType: (enabled: boolean) => void;
|
||||
}
|
||||
|
||||
const SidebarDataContext = createContext<SidebarDataContextValue | null>(null);
|
||||
@@ -80,10 +81,22 @@ export function SidebarDataProvider({
|
||||
const [knowledgeBases, setKnowledgeBases] = useState<SidebarEntityItem[]>([]);
|
||||
const [plugins, setPlugins] = useState<SidebarEntityItem[]>([]);
|
||||
const [mcpServers, setMCPServers] = useState<SidebarEntityItem[]>([]);
|
||||
const [skills, setSkills] = useState<SidebarEntityItem[]>([]);
|
||||
const [pluginPages, setPluginPages] = useState<PluginPageItem[]>([]);
|
||||
const [detailEntityName, setDetailEntityName] = useState<string | null>(null);
|
||||
const [pendingPluginInstallAction, setPendingPluginInstallAction] =
|
||||
useState<PluginInstallAction>(null);
|
||||
const [extensionsGroupByType, setExtensionsGroupByTypeState] =
|
||||
useState<boolean>(() => {
|
||||
if (typeof window === 'undefined') return false;
|
||||
return localStorage.getItem('extensions_group_by_type') === 'true';
|
||||
});
|
||||
const setExtensionsGroupByType = useCallback((enabled: boolean) => {
|
||||
setExtensionsGroupByTypeState(enabled);
|
||||
try {
|
||||
localStorage.setItem('extensions_group_by_type', String(enabled));
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}, []);
|
||||
|
||||
const refreshBots = useCallback(async () => {
|
||||
try {
|
||||
@@ -245,8 +258,8 @@ export function SidebarDataProvider({
|
||||
const resp = await httpClient.getMCPServers();
|
||||
setMCPServers(
|
||||
resp.servers.map((server) => ({
|
||||
id: server.name,
|
||||
name: server.name,
|
||||
id: server.name, // Keep __ for API calls
|
||||
name: server.name.replace(/__/g, '/'), // Display with / for readability
|
||||
enabled: server.enable,
|
||||
runtimeStatus: server.runtime_info?.status,
|
||||
})),
|
||||
@@ -256,6 +269,22 @@ export function SidebarDataProvider({
|
||||
}
|
||||
}, []);
|
||||
|
||||
const refreshSkills = useCallback(async () => {
|
||||
try {
|
||||
const resp = await httpClient.getSkills();
|
||||
setSkills(
|
||||
resp.skills.map((skill) => ({
|
||||
id: skill.name,
|
||||
name: skill.display_name || skill.name,
|
||||
description: skill.description,
|
||||
updatedAt: skill.updated_at,
|
||||
})),
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch skills for sidebar:', error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const refreshAll = useCallback(async () => {
|
||||
await Promise.all([
|
||||
refreshBots(),
|
||||
@@ -264,6 +293,7 @@ export function SidebarDataProvider({
|
||||
refreshKnowledgeBases(),
|
||||
refreshPlugins(),
|
||||
refreshMCPServers(),
|
||||
refreshSkills(),
|
||||
]);
|
||||
}, [
|
||||
refreshBots,
|
||||
@@ -272,6 +302,7 @@ export function SidebarDataProvider({
|
||||
refreshKnowledgeBases,
|
||||
refreshPlugins,
|
||||
refreshMCPServers,
|
||||
refreshSkills,
|
||||
]);
|
||||
|
||||
// Fetch all entity lists on mount
|
||||
@@ -288,6 +319,7 @@ export function SidebarDataProvider({
|
||||
knowledgeBases,
|
||||
plugins,
|
||||
mcpServers,
|
||||
skills,
|
||||
pluginPages,
|
||||
refreshBots,
|
||||
refreshPipelines,
|
||||
@@ -295,11 +327,12 @@ export function SidebarDataProvider({
|
||||
refreshKnowledgeBases,
|
||||
refreshPlugins,
|
||||
refreshMCPServers,
|
||||
refreshSkills,
|
||||
refreshAll,
|
||||
detailEntityName,
|
||||
setDetailEntityName,
|
||||
pendingPluginInstallAction,
|
||||
setPendingPluginInstallAction,
|
||||
extensionsGroupByType,
|
||||
setExtensionsGroupByType,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user