🌐 chore: translate non-English comments to English in ChatInput/ActionBar/Tools (#12663)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
LobeHub Bot
2026-03-06 11:27:27 +08:00
committed by GitHub
parent 92cb759c37
commit 616d53e2ec
5 changed files with 85 additions and 85 deletions

View File

@@ -11,9 +11,9 @@ import { KlavisServerStatus } from '@/store/tool/slices/klavisStore';
import { useUserStore } from '@/store/user';
import { userProfileSelectors } from '@/store/user/selectors';
// 轮询配置
const POLL_INTERVAL_MS = 1000; // 每秒轮询一次
const POLL_TIMEOUT_MS = 15_000; // 15 秒超时
// Polling configuration
const POLL_INTERVAL_MS = 1000; // Poll once per second
const POLL_TIMEOUT_MS = 15_000; // 15-second timeout
interface KlavisServerItemProps {
/**
@@ -53,7 +53,7 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
const activeAgentId = useAgentStore((s) => s.activeAgentId);
const effectiveAgentId = agentId || activeAgentId || '';
// 清理所有定时器
// Clean up all timers
const cleanup = useCallback(() => {
if (windowCheckIntervalRef.current) {
clearInterval(windowCheckIntervalRef.current);
@@ -71,14 +71,14 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
setIsWaitingAuth(false);
}, []);
// 组件卸载时清理
// Clean up on component unmount
useEffect(() => {
return () => {
cleanup();
};
}, [cleanup]);
// 当服务器状态变为 CONNECTED 时停止所有监听
// Stop all listeners when server status becomes CONNECTED
useEffect(() => {
if (server?.status === KlavisServerStatus.CONNECTED && isWaitingAuth) {
cleanup();
@@ -86,14 +86,14 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
}, [server?.status, isWaitingAuth, cleanup, t]);
/**
* 启动降级轮询(当 window.closed 不可访问时)
* Start fallback polling (when window.closed is inaccessible)
*/
const startFallbackPolling = useCallback(
(serverName: string) => {
// 已经在轮询了,不重复启动
// Already polling, don't start again
if (pollIntervalRef.current) return;
// 每秒轮询一次
// Poll once per second
pollIntervalRef.current = setInterval(async () => {
try {
await refreshKlavisServerTools(serverName);
@@ -102,7 +102,7 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
}
}, POLL_INTERVAL_MS);
// 15 秒后超时停止
// Stop after 15-second timeout
pollTimeoutRef.current = setTimeout(() => {
if (pollIntervalRef.current) {
clearInterval(pollIntervalRef.current);
@@ -115,27 +115,27 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
);
/**
* 监听 OAuth 窗口关闭
* Monitor OAuth window close
*/
const startWindowMonitor = useCallback(
(oauthWindow: Window, serverName: string) => {
// 每 500ms 检查窗口状态
// Check window state every 500ms
windowCheckIntervalRef.current = setInterval(() => {
try {
// 尝试访问 window.closed(可能被 COOP 阻止)
// Try to access window.closed (may be blocked by COOP)
if (oauthWindow.closed) {
// 窗口已关闭,清理监听并检查认证状态
// Window closed, clean up listeners and check auth status
if (windowCheckIntervalRef.current) {
clearInterval(windowCheckIntervalRef.current);
windowCheckIntervalRef.current = null;
}
oauthWindowRef.current = null;
// 窗口关闭后开始轮询检查认证状态
// Start polling to check auth status after window closes
startFallbackPolling(serverName);
}
} catch {
// COOP 阻止了访问,降级到轮询方案
// COOP blocked access, falling back to polling
console.info('[Klavis] COOP blocked window.closed access, falling back to polling');
if (windowCheckIntervalRef.current) {
clearInterval(windowCheckIntervalRef.current);
@@ -149,28 +149,28 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
);
/**
* 打开 OAuth 窗口
* Open OAuth window
*/
const openOAuthWindow = useCallback(
(oauthUrl: string, serverName: string) => {
// 清理之前的状态
// Clean up previous state
cleanup();
setIsWaitingAuth(true);
// 打开 OAuth 窗口
// Open OAuth window
const oauthWindow = window.open(oauthUrl, '_blank', 'width=600,height=700');
if (oauthWindow) {
oauthWindowRef.current = oauthWindow;
startWindowMonitor(oauthWindow, serverName);
} else {
// 窗口被阻止,直接用轮询
// Window blocked, use polling directly
startFallbackPolling(serverName);
}
},
[cleanup, startWindowMonitor, startFallbackPolling, t],
);
// Get plugin ID for this server (使用 identifier 作为 pluginId)
// Get plugin ID for this server (use identifier as pluginId)
const pluginId = server ? server.identifier : '';
const plugins =
useAgentStore(agentSelectors.getAgentConfigById(effectiveAgentId))?.plugins || [];
@@ -209,15 +209,15 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
});
if (newServer) {
// 安装完成后自动启用插件(使用 identifier
// Auto-enable plugin after installation (using identifier)
const newPluginId = newServer.identifier;
await togglePlugin(newPluginId);
// 如果已认证,直接刷新工具列表,跳过 OAuth
// If already authenticated, refresh tool list directly, skip OAuth
if (newServer.isAuthenticated) {
await refreshKlavisServerTools(newServer.identifier);
} else if (newServer.oauthUrl) {
// 需要 OAuth,打开 OAuth 窗口并监听关闭
// Need OAuth, open OAuth window and monitor close
openOAuthWindow(newServer.oauthUrl, newServer.identifier);
}
}
@@ -235,9 +235,9 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
setIsToggling(false);
};
// 渲染右侧控件
// Render right-side controls
const renderRightControl = () => {
// 正在连接中
// Connecting in progress
if (isConnecting) {
return (
<Flexbox horizontal align="center" gap={4} onClick={stopPropagation}>
@@ -246,7 +246,7 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
);
}
// 未连接,显示 Connect 按钮
// Not connected, show Connect button
if (!server) {
return (
<Flexbox
@@ -265,10 +265,10 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
);
}
// 根据状态显示不同控件
// Show different controls based on status
switch (server.status) {
case KlavisServerStatus.CONNECTED: {
// 正在切换状态
// Toggling state
if (isToggling) {
return <Icon spin icon={Loader2} />;
}
@@ -283,7 +283,7 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
);
}
case KlavisServerStatus.PENDING_AUTH: {
// 正在等待认证
// Waiting for authentication
if (isWaitingAuth) {
return (
<Flexbox horizontal align="center" gap={4} onClick={stopPropagation}>
@@ -299,7 +299,7 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
style={{ cursor: 'pointer', opacity: 0.65 }}
onClick={(e) => {
e.stopPropagation();
// 点击重新打开 OAuth 窗口
// Click to reopen OAuth window
if (server.oauthUrl) {
openOAuthWindow(server.oauthUrl, server.identifier);
}
@@ -331,7 +331,7 @@ const KlavisServerItem = memo<KlavisServerItemProps>(
justify={'space-between'}
onClick={(e) => {
e.stopPropagation();
// 如果已连接,点击整行切换状态
// If connected, clicking the row toggles state
if (server?.status === KlavisServerStatus.CONNECTED) {
handleToggle();
}

View File

@@ -6,7 +6,7 @@ import { memo } from 'react';
export const SKILL_ICON_SIZE = 20;
/**
* Klavis 服务器图标组件
* Klavis server icon component
*/
const KlavisSkillIcon = memo<Pick<KlavisServerType, 'icon' | 'label'> & { size: number }>(
({ icon, label, size = SKILL_ICON_SIZE }) => {

View File

@@ -6,7 +6,7 @@ import { memo } from 'react';
export const SKILL_ICON_SIZE = 20;
/**
* LobeHub Skill Provider 图标组件
* LobeHub Skill Provider icon component
*/
const LobehubSkillIcon = memo<Pick<LobehubSkillProviderType, 'icon' | 'label'> & { size: number }>(
({ icon, label, size = SKILL_ICON_SIZE }) => {

View File

@@ -195,7 +195,7 @@ const LobehubSkillServerItem = memo<LobehubSkillServerItemProps>(({ provider, la
}, [provider, cleanup, checkStatus, togglePlugin, effectiveAgentId]);
const handleConnect = async () => {
// 只有已连接状态才阻止重新连接
// Only block reconnection when already connected
if (server?.isConnected) return;
setIsConnecting(true);

View File

@@ -46,15 +46,15 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
const builtinList = useToolStore(builtinToolSelectors.metaList, isEqual);
const plugins = useAgentStore((s) => agentByIdSelectors.getAgentPluginsById(agentId)(s));
// Klavis 相关状态
// Klavis-related state
const allKlavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual);
const isKlavisEnabledInEnv = useServerConfigStore(serverConfigSelectors.enableKlavis);
// LobeHub Skill 相关状态
// LobeHub Skill related state
const allLobehubSkillServers = useToolStore(lobehubSkillStoreSelectors.getServers, isEqual);
const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill);
// Agent Skills 相关状态
// Agent Skills related state
const installedBuiltinSkills = useToolStore(builtinToolSelectors.installedBuiltinSkills, isEqual);
const marketAgentSkills = useToolStore(agentSkillsSelectors.getMarketAgentSkills, isEqual);
const userAgentSkills = useToolStore(agentSkillsSelectors.getUserAgentSkills, isEqual);
@@ -79,24 +79,24 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
useFetchAgentSkills(true);
useCheckPluginsIsInstalled(plugins);
// 使用 SWR 加载用户的 Klavis 集成(从数据库)
// Load user's Klavis integrations via SWR (from database)
useFetchUserKlavisServers(isKlavisEnabledInEnv);
// 使用 SWR 加载用户的 LobeHub Skill 连接
// Load user's LobeHub Skill connections via SWR
useFetchLobehubSkillConnections(isLobehubSkillEnabled);
// 根据 identifier 获取已连接的服务器
// Get connected server by identifier
const getServerByName = (identifier: string) => {
return allKlavisServers.find((server) => server.identifier === identifier);
};
// 获取所有 Klavis 服务器类型的 identifier 集合(用于过滤 builtinList
// 这里使用 KLAVIS_SERVER_TYPES 而不是已连接的服务器,因为我们要过滤掉所有可能的 Klavis 类型
// Get all Klavis server type identifier sets (used for filtering builtinList)
// Using KLAVIS_SERVER_TYPES instead of connected servers here, because we want to filter out all possible Klavis types
const allKlavisTypeIdentifiers = useMemo(
() => new Set(KLAVIS_SERVER_TYPES.map((type) => type.identifier)),
[],
);
// 获取所有 skill identifier 集合(用于过滤 builtinList
// Get all skill identifier sets (used for filtering builtinList)
const allSkillIdentifiers = useMemo(() => {
const ids = new Set<string>();
for (const s of installedBuiltinSkills) ids.add(s.identifier);
@@ -105,7 +105,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
return ids;
}, [installedBuiltinSkills, marketAgentSkills, userAgentSkills]);
// 过滤掉 builtinList 中的 klavis 工具和 skill它们会单独显示
// Filter out Klavis tools and skills from builtinList (they will be displayed separately)
const filteredBuiltinList = useMemo(() => {
let list = builtinList;
if (isKlavisEnabledInEnv) {
@@ -114,7 +114,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
return list.filter((item) => !allSkillIdentifiers.has(item.identifier));
}, [builtinList, allKlavisTypeIdentifiers, isKlavisEnabledInEnv, allSkillIdentifiers]);
// 获取推荐的 Klavis skill IDs
// Get recommended Klavis skill IDs
const recommendedKlavisIds = useMemo(
() =>
new Set(
@@ -123,7 +123,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
[],
);
// 获取推荐的 Lobehub skill IDs
// Get recommended Lobehub skill IDs
const recommendedLobehubIds = useMemo(
() =>
new Set(
@@ -132,19 +132,19 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
[],
);
// 获取已安装的 Klavis server IDs
// Get installed Klavis server IDs
const installedKlavisIds = useMemo(
() => new Set(allKlavisServers.map((s) => s.identifier)),
[allKlavisServers],
);
// 获取已安装的 Lobehub skill IDs
// Get installed Lobehub skill IDs
const installedLobehubIds = useMemo(
() => new Set(allLobehubSkillServers.map((s) => s.identifier)),
[allLobehubSkillServers],
);
// Klavis 服务器列表项 - 只展示已安装或推荐的
// Klavis server list items - only show installed or recommended
const klavisServerItems = useMemo(
() =>
isKlavisEnabledInEnv
@@ -168,7 +168,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
[isKlavisEnabledInEnv, allKlavisServers, installedKlavisIds, recommendedKlavisIds, agentId],
);
// LobeHub Skill Provider 列表项 - 只展示已安装或推荐的
// LobeHub Skill Provider list items - only show installed or recommended
const lobehubSkillItems = useMemo(
() =>
isLobehubSkillEnabled
@@ -183,7 +183,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
size={SKILL_ICON_SIZE}
/>
),
key: provider.id, // 使用 provider.id 作为 key,与 pluginId 保持一致
key: provider.id, // Use provider.id as key, consistent with pluginId
label: (
<LobehubSkillServerItem
agentId={agentId}
@@ -202,7 +202,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
],
);
// Builtin 工具列表项(不包含 Klavis LobeHub Skill
// Builtin tool list items (excluding Klavis and LobeHub Skill)
const builtinItems = useMemo(
() =>
filteredBuiltinList.map((item) => ({
@@ -231,7 +231,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
[filteredBuiltinList, checked, togglePlugin, setUpdating],
);
// Builtin Agent Skills 列表项(归入 LobeHub 分组)
// Builtin Agent Skills list items (grouped under LobeHub)
const builtinAgentSkillItems = useMemo(
() =>
installedBuiltinSkills.map((skill) => ({
@@ -260,7 +260,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
[installedBuiltinSkills, checked, togglePlugin, setUpdating],
);
// Market Agent Skills 列表项(归入 Community 分组)
// Market Agent Skills list items (grouped under Community)
const marketAgentSkillItems = useMemo(
() =>
marketAgentSkills.map((skill) => ({
@@ -284,7 +284,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
[marketAgentSkills, checked, togglePlugin, setUpdating],
);
// User Agent Skills 列表项(归入 Custom 分组)
// User Agent Skills list items (grouped under Custom)
const userAgentSkillItems = useMemo(
() =>
userAgentSkills.map((skill) => ({
@@ -308,8 +308,8 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
[userAgentSkills, checked, togglePlugin, setUpdating],
);
// Skills 列表项(包含 LobeHub Skill Klavis
// 已连接的排在前面
// Skills list items (including LobeHub Skill and Klavis)
// Connected items listed first
const skillItems = useMemo(() => {
const allItems = [...lobehubSkillItems, ...klavisServerItems];
@@ -325,11 +325,11 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
});
}, [lobehubSkillItems, klavisServerItems, installedLobehubIds, installedKlavisIds]);
// 区分社区插件和自定义插件
// Distinguish community plugins and custom plugins
const communityPlugins = list.filter((item) => item.type !== 'customPlugin');
const customPlugins = list.filter((item) => item.type === 'customPlugin');
// 生成插件列表项的函数
// Function to map plugins to list items
const mapPluginToItem = (item: (typeof list)[0]) => ({
icon: item?.avatar ? (
<PluginAvatar avatar={item.avatar} size={SKILL_ICON_SIZE} />
@@ -351,31 +351,31 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
),
});
// 构建 LobeHub 分组的 children(包含 Builtin Agent Skills、内置工具和 LobeHub Skill/Klavis
// Build LobeHub group children (including Builtin Agent Skills, builtin tools, and LobeHub Skill/Klavis)
const lobehubGroupChildren: ItemType[] = [
// 1. Builtin Agent Skills
...builtinAgentSkillItems,
// 2. 内置工具
// 2. Builtin tools
...builtinItems,
// 3. LobeHub Skill Klavis(作为内置技能)
// 3. LobeHub Skill and Klavis (as builtin skills)
...skillItems,
];
// 构建 Community 分组的 childrenMarket Agent Skills + 社区插件)
// Build Community group children (Market Agent Skills + community plugins)
const communityGroupChildren: ItemType[] = [
...marketAgentSkillItems,
...communityPlugins.map(mapPluginToItem),
];
// 构建 Custom 分组的 childrenUser Agent Skills + 自定义插件)
// Build Custom group children (User Agent Skills + custom plugins)
const customGroupChildren: ItemType[] = [
...userAgentSkillItems,
...customPlugins.map(mapPluginToItem),
];
// 市场 tab 的 items
// Items for the market tab
const marketItems: ItemType[] = [
// LobeHub 分组
// LobeHub group
...(lobehubGroupChildren.length > 0
? [
{
@@ -386,7 +386,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
},
]
: []),
// Community 分组
// Community group
...(communityGroupChildren.length > 0
? [
{
@@ -397,7 +397,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
},
]
: []),
// Custom 分组(只有在有自定义插件时才显示)
// Custom group (only shown when there are custom plugins)
...(customGroupChildren.length > 0
? [
{
@@ -410,11 +410,11 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
: []),
];
// 已安装 tab 的 items - 只显示已安装的插件
// Items for the installed tab - only show installed plugins
const installedPluginItems: ItemType[] = useMemo(() => {
const installedItems: ItemType[] = [];
// 已安装的 builtin 工具
// Installed builtin tools
const enabledBuiltinItems = filteredBuiltinList
.filter((item) => checked.includes(item.identifier))
.map((item) => ({
@@ -441,20 +441,20 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
),
}));
// 已连接的 Klavis 服务器
// Connected Klavis servers
const connectedKlavisItems = klavisServerItems.filter((item) =>
checked.includes(item.key as string),
);
// 已连接的 LobeHub Skill Providers
// Connected LobeHub Skill Providers
const connectedLobehubSkillItems = lobehubSkillItems.filter((item) =>
checked.includes(item.key as string),
);
// 合并已启用的 LobeHub Skill Klavis(作为内置技能)
// Merge enabled LobeHub Skill and Klavis (as builtin skills)
const enabledSkillItems = [...connectedLobehubSkillItems, ...connectedKlavisItems];
// 已启用的 Builtin Agent Skills
// Enabled Builtin Agent Skills
const enabledBuiltinAgentSkillItems = installedBuiltinSkills
.filter((skill) => checked.includes(skill.identifier))
.map((skill) => ({
@@ -481,17 +481,17 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
),
}));
// 构建内置工具分组的 children包含 Builtin Agent Skills、内置工具和 LobeHub Skill/Klavis
// Build builtin tools group children (including Builtin Agent Skills, builtin tools, and LobeHub Skill/Klavis)
const allBuiltinItems: ItemType[] = [
// 1. Builtin Agent Skills
...enabledBuiltinAgentSkillItems,
// 2. 内置工具
// 2. Builtin tools
...enabledBuiltinItems,
// 3. divider (如果有内置工具且有 skill items)
// 3. divider (if there are builtin tools and skill items)
...(enabledBuiltinItems.length > 0 && enabledSkillItems.length > 0
? [{ key: 'installed-divider-builtin-skill', type: 'divider' as const }]
: []),
// 4. LobeHub Skill Klavis
// 4. LobeHub Skill and Klavis
...enabledSkillItems,
];
@@ -504,7 +504,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
});
}
// 已启用的社区插件
// Enabled community plugins
const enabledCommunityPlugins = communityPlugins
.filter((item) => checked.includes(item.identifier))
.map((item) => ({
@@ -528,7 +528,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
),
}));
// 已启用的自定义插件
// Enabled custom plugins
const enabledCustomPlugins = customPlugins
.filter((item) => checked.includes(item.identifier))
.map((item) => ({
@@ -552,7 +552,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
),
}));
// 已启用的 Market Agent Skills
// Enabled Market Agent Skills
const enabledMarketAgentSkillItems = marketAgentSkills
.filter((skill) => checked.includes(skill.identifier))
.map((skill) => ({
@@ -574,7 +574,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
),
}));
// Community 分组(Market Agent Skills + 社区插件)
// Community group (Market Agent Skills + community plugins)
const allCommunityItems = [...enabledMarketAgentSkillItems, ...enabledCommunityPlugins];
if (allCommunityItems.length > 0) {
installedItems.push({
@@ -585,7 +585,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
});
}
// 已启用的 User Agent Skills
// Enabled User Agent Skills
const enabledUserAgentSkillItems = userAgentSkills
.filter((skill) => checked.includes(skill.identifier))
.map((skill) => ({
@@ -607,7 +607,7 @@ export const useControls = ({ setUpdating }: { setUpdating: (updating: boolean)
),
}));
// Custom 分组(User Agent Skills + 自定义插件)
// Custom group (User Agent Skills + custom plugins)
const allCustomItems = [...enabledUserAgentSkillItems, ...enabledCustomPlugins];
if (allCustomItems.length > 0) {
installedItems.push({