@lobehub/lobehub 2.0.0-next.337 → 2.0.0-next.339
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/.gitattributes +35 -0
- package/CHANGELOG.md +69 -0
- package/changelog/v1.json +24 -0
- package/locales/ar/plugin.json +12 -2
- package/locales/ar/providers.json +1 -0
- package/locales/ar/setting.json +77 -1
- package/locales/bg-BG/models.json +5 -10
- package/locales/bg-BG/plugin.json +12 -2
- package/locales/bg-BG/providers.json +1 -0
- package/locales/bg-BG/setting.json +78 -2
- package/locales/de-DE/models.json +51 -9
- package/locales/de-DE/plugin.json +12 -2
- package/locales/de-DE/providers.json +1 -0
- package/locales/de-DE/setting.json +78 -2
- package/locales/en-US/models.json +11 -10
- package/locales/en-US/plugin.json +14 -4
- package/locales/en-US/providers.json +1 -0
- package/locales/en-US/setting.json +97 -2
- package/locales/es-ES/plugin.json +12 -2
- package/locales/es-ES/providers.json +1 -0
- package/locales/es-ES/setting.json +78 -2
- package/locales/fa-IR/plugin.json +12 -2
- package/locales/fa-IR/providers.json +1 -0
- package/locales/fa-IR/setting.json +78 -2
- package/locales/fr-FR/plugin.json +12 -2
- package/locales/fr-FR/providers.json +1 -0
- package/locales/fr-FR/setting.json +78 -2
- package/locales/it-IT/plugin.json +12 -2
- package/locales/it-IT/providers.json +1 -0
- package/locales/it-IT/setting.json +78 -2
- package/locales/ja-JP/plugin.json +12 -2
- package/locales/ja-JP/providers.json +1 -0
- package/locales/ja-JP/setting.json +78 -2
- package/locales/ko-KR/plugin.json +12 -2
- package/locales/ko-KR/providers.json +1 -0
- package/locales/ko-KR/setting.json +78 -2
- package/locales/nl-NL/models.json +4 -9
- package/locales/nl-NL/plugin.json +12 -2
- package/locales/nl-NL/providers.json +1 -0
- package/locales/nl-NL/setting.json +78 -2
- package/locales/pl-PL/plugin.json +12 -2
- package/locales/pl-PL/providers.json +1 -0
- package/locales/pl-PL/setting.json +78 -2
- package/locales/pt-BR/plugin.json +12 -2
- package/locales/pt-BR/providers.json +1 -0
- package/locales/pt-BR/setting.json +78 -2
- package/locales/ru-RU/plugin.json +12 -2
- package/locales/ru-RU/providers.json +1 -0
- package/locales/ru-RU/setting.json +78 -2
- package/locales/tr-TR/plugin.json +12 -2
- package/locales/tr-TR/providers.json +1 -0
- package/locales/tr-TR/setting.json +78 -2
- package/locales/vi-VN/plugin.json +12 -2
- package/locales/vi-VN/providers.json +1 -0
- package/locales/vi-VN/setting.json +77 -1
- package/locales/zh-CN/auth.json +1 -0
- package/locales/zh-CN/plugin.json +12 -2
- package/locales/zh-CN/providers.json +1 -0
- package/locales/zh-CN/setting.json +97 -2
- package/locales/zh-TW/plugin.json +12 -2
- package/locales/zh-TW/providers.json +1 -0
- package/locales/zh-TW/setting.json +78 -2
- package/package.json +1 -1
- package/packages/agent-runtime/src/groupOrchestration/GroupOrchestrationSupervisor.ts +2 -0
- package/packages/agent-runtime/src/groupOrchestration/__tests__/GroupOrchestrationSupervisor.test.ts +3 -1
- package/packages/agent-runtime/src/groupOrchestration/types.ts +5 -0
- package/packages/const/src/index.ts +1 -0
- package/packages/const/src/klavis.ts +144 -0
- package/packages/const/src/lobehubSkill.ts +34 -0
- package/packages/const/src/recommendedSkill.ts +17 -0
- package/packages/model-runtime/src/core/contextBuilders/anthropic.test.ts +38 -0
- package/packages/model-runtime/src/core/contextBuilders/anthropic.ts +20 -1
- package/packages/model-runtime/src/core/contextBuilders/google.test.ts +42 -0
- package/packages/model-runtime/src/core/contextBuilders/google.ts +17 -0
- package/packages/model-runtime/src/providers/google/index.ts +14 -14
- package/packages/model-runtime/src/providers/moonshot/index.ts +1 -1
- package/packages/model-runtime/src/providers/openai/index.ts +3 -3
- package/packages/types/src/discover/index.ts +1 -1
- package/scripts/electronWorkflow/modifiers/dynamicToStatic.mts +273 -0
- package/scripts/electronWorkflow/modifiers/index.mts +10 -0
- package/scripts/electronWorkflow/modifiers/nextConfig.mts +1 -0
- package/scripts/electronWorkflow/modifiers/nextDynamicToStatic.mts +233 -0
- package/scripts/electronWorkflow/modifiers/removeSuspense.mts +124 -0
- package/scripts/electronWorkflow/modifiers/routes.mts +14 -2
- package/scripts/electronWorkflow/modifiers/settingsContentToStatic.mts +148 -0
- package/scripts/electronWorkflow/modifiers/wrapChildrenWithClientOnly.mts +73 -0
- package/src/app/[variants]/(main)/agent/cron/[cronId]/CronConfig.ts +16 -16
- package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobSaveButton.tsx +1 -1
- package/src/app/[variants]/(main)/agent/cron/[cronId]/features/CronJobScheduleConfig.tsx +5 -2
- package/src/app/[variants]/(main)/community/features/Search.tsx +1 -1
- package/src/app/[variants]/(main)/home/features/InputArea/SkillInstallBanner.tsx +131 -0
- package/src/app/[variants]/(main)/home/features/InputArea/index.tsx +34 -27
- package/src/app/[variants]/(main)/settings/features/SettingHeader.tsx +8 -4
- package/src/app/[variants]/(main)/settings/features/SettingsContent.tsx +3 -0
- package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +6 -0
- package/src/{features/PluginStore/InstalledList/List/Item/Action.tsx → app/[variants]/(main)/settings/skill/features/Actions.tsx} +45 -40
- package/src/app/[variants]/(main)/settings/skill/features/KlavisSkillItem.tsx +353 -0
- package/src/app/[variants]/(main)/settings/skill/features/LobehubSkillItem.tsx +344 -0
- package/src/app/[variants]/(main)/settings/skill/features/McpSkillItem.tsx +116 -0
- package/src/app/[variants]/(main)/settings/skill/features/SkillList.tsx +244 -0
- package/src/app/[variants]/(main)/settings/skill/index.tsx +35 -0
- package/src/app/[variants]/(mobile)/router/mobileRouter.config.tsx +27 -0
- package/src/app/[variants]/(mobile)/settings/_layout/Header.tsx +8 -17
- package/src/app/[variants]/(mobile)/settings/_layout/index.tsx +6 -1
- package/src/app/[variants]/(mobile)/settings/provider/_layout/index.tsx +22 -0
- package/src/components/Plugins/PluginTag.tsx +23 -35
- package/src/components/client/ClientOnly.tsx +6 -2
- package/src/features/AgentSetting/AgentPlugin/index.tsx +2 -2
- package/src/features/ChatInput/ActionBar/Tools/KlavisServerItem.tsx +8 -32
- package/src/features/ChatInput/ActionBar/Tools/LobehubSkillServerItem.tsx +8 -30
- package/src/features/ChatInput/ActionBar/Tools/PopoverContent.tsx +48 -59
- package/src/features/ChatInput/ActionBar/Tools/index.tsx +5 -23
- package/src/features/ChatInput/ActionBar/Tools/useControls.tsx +158 -56
- package/src/features/IntegrationDetailModal/index.tsx +293 -0
- package/src/features/{PluginStore/McpList/Detail → MCP/MCPDetail}/index.tsx +15 -6
- package/src/features/MCP/MCPSettings/McpSettingsModal.tsx +58 -0
- package/src/features/{PluginStore/McpList/Detail/Settings → MCP/MCPSettings}/index.tsx +39 -27
- package/src/features/PluginDetailModal/index.tsx +2 -2
- package/src/features/PluginDevModal/index.tsx +16 -40
- package/src/features/ProfileEditor/AgentTool.tsx +2 -2
- package/src/features/ProtocolUrlHandler/InstallPlugin/OfficialPluginInstallModal/index.tsx +1 -1
- package/src/features/{PluginStore/AddPluginButton.tsx → SkillStore/AddSkillButton.tsx} +3 -3
- package/src/features/SkillStore/CommunityList/Item.tsx +158 -0
- package/src/features/SkillStore/CommunityList/index.tsx +101 -0
- package/src/features/SkillStore/Content.tsx +59 -0
- package/src/features/{PluginStore/PluginEmpty.tsx → SkillStore/Empty.tsx} +8 -8
- package/src/features/SkillStore/LobeHubList/Item.tsx +118 -0
- package/src/features/SkillStore/LobeHubList/index.tsx +187 -0
- package/src/features/SkillStore/LobeHubList/useSkillConnect.ts +239 -0
- package/src/features/SkillStore/Search/index.tsx +43 -0
- package/src/features/{PluginStore → SkillStore}/index.tsx +14 -10
- package/src/features/SkillStore/style.ts +27 -0
- package/src/locales/default/plugin.ts +15 -4
- package/src/locales/default/setting.ts +204 -2
- package/src/services/chat/mecha/agentConfigResolver.test.ts +197 -0
- package/src/services/chat/mecha/agentConfigResolver.ts +44 -17
- package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +40 -37
- package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +78 -0
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +50 -16
- package/src/store/global/initialState.ts +1 -0
- package/src/store/tool/slices/lobehubSkillStore/action.test.ts +914 -0
- package/src/store/tool/slices/lobehubSkillStore/selectors.test.ts +548 -0
- package/.cursor/skills/vercel-react-best-practices/AGENTS.md +0 -2410
- package/.cursor/skills/vercel-react-best-practices/SKILL.md +0 -125
- package/.cursor/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/.cursor/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -49
- package/.cursor/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
- package/.cursor/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
- package/.cursor/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -36
- package/.cursor/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
- package/.cursor/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/.cursor/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/.cursor/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
- package/.cursor/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/.cursor/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/.cursor/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
- package/.cursor/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
- package/.cursor/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
- package/.cursor/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
- package/.cursor/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
- package/.cursor/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -57
- package/.cursor/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
- package/.cursor/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
- package/.cursor/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
- package/.cursor/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
- package/.cursor/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
- package/.cursor/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/.cursor/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
- package/.cursor/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
- package/.cursor/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
- package/.cursor/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/.cursor/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/.cursor/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
- package/.cursor/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/.cursor/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/.cursor/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/.cursor/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/.cursor/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/.cursor/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/.cursor/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/.cursor/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
- package/.cursor/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
- package/.cursor/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/.cursor/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/.cursor/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
- package/.cursor/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
- package/.cursor/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/.cursor/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
- package/.cursor/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
- package/.cursor/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
- package/.cursor/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
- package/src/features/PluginStore/Content.tsx +0 -54
- package/src/features/PluginStore/InstalledList/Detail/CustomPluginEmptyState.tsx +0 -79
- package/src/features/PluginStore/InstalledList/Detail/index.tsx +0 -21
- package/src/features/PluginStore/InstalledList/List/Item/index.tsx +0 -61
- package/src/features/PluginStore/InstalledList/List/index.tsx +0 -72
- package/src/features/PluginStore/InstalledList/index.tsx +0 -90
- package/src/features/PluginStore/McpList/List/Action.tsx +0 -119
- package/src/features/PluginStore/McpList/List/Item.tsx +0 -83
- package/src/features/PluginStore/McpList/List/index.tsx +0 -93
- package/src/features/PluginStore/McpList/index.tsx +0 -58
- package/src/features/PluginStore/PluginList/Detail/DetailProvider.tsx +0 -19
- package/src/features/PluginStore/PluginList/Detail/EmptyState.tsx +0 -56
- package/src/features/PluginStore/PluginList/Detail/Header.tsx +0 -130
- package/src/features/PluginStore/PluginList/Detail/InstallDetail/Nav.tsx +0 -73
- package/src/features/PluginStore/PluginList/Detail/InstallDetail/Settings.tsx +0 -19
- package/src/features/PluginStore/PluginList/Detail/InstallDetail/Tools.tsx +0 -111
- package/src/features/PluginStore/PluginList/Detail/InstallDetail/index.tsx +0 -24
- package/src/features/PluginStore/PluginList/Detail/Loading.tsx +0 -42
- package/src/features/PluginStore/PluginList/Detail/TagList.tsx +0 -35
- package/src/features/PluginStore/PluginList/Detail/index.tsx +0 -39
- package/src/features/PluginStore/PluginList/Detail/useCategory.tsx +0 -76
- package/src/features/PluginStore/PluginList/List/Action.tsx +0 -78
- package/src/features/PluginStore/PluginList/List/Item.tsx +0 -92
- package/src/features/PluginStore/PluginList/List/index.tsx +0 -94
- package/src/features/PluginStore/PluginList/index.tsx +0 -46
- package/src/features/PluginStore/Search/index.tsx +0 -40
- /package/{.codex/skills → .agents}/vercel-react-best-practices/AGENTS.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/SKILL.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/advanced-use-latest.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-api-routes.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-defer-await.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-dependencies.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-parallel.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-conditional.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/bundle-preload.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/client-event-listeners.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/client-swr-dedup.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-cache-function-results.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-cache-property-access.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-cache-storage.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-combine-iterations.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-early-exit.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-index-maps.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-length-check-first.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-min-max-loop.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-activity.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-dependencies.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-derived-state.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-memo.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/rerender-transitions.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-cache-lru.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-cache-react.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -0
- /package/{.codex/skills → .agents}/vercel-react-best-practices/rules/server-serialization.md +0 -0
- /package/src/{features/PluginStore/InstalledList → app/[variants]/(main)/settings/skill/features}/EditCustomPlugin.tsx +0 -0
- /package/src/features/{PluginStore/McpList/Detail → MCP/MCPDetail}/Loading.tsx +0 -0
- /package/src/features/{PluginStore → SkillStore}/Loading.tsx +0 -0
- /package/src/features/{PluginStore → SkillStore}/VirtuosoLoading.tsx +0 -0
|
@@ -2,12 +2,22 @@ import { IconType, SiCaldotcom, SiGithub } from '@icons-pack/react-simple-icons'
|
|
|
2
2
|
import { Klavis } from 'klavis';
|
|
3
3
|
|
|
4
4
|
export interface KlavisServerType {
|
|
5
|
+
/**
|
|
6
|
+
* Author/Developer of the integration
|
|
7
|
+
*/
|
|
8
|
+
author: string;
|
|
9
|
+
/**
|
|
10
|
+
* Author's website URL
|
|
11
|
+
*/
|
|
12
|
+
authorUrl?: string;
|
|
13
|
+
description: string;
|
|
5
14
|
icon: string | IconType;
|
|
6
15
|
/**
|
|
7
16
|
* Identifier used for storage in database (e.g., 'google-calendar')
|
|
8
17
|
* Format: lowercase, spaces replaced with hyphens
|
|
9
18
|
*/
|
|
10
19
|
identifier: string;
|
|
20
|
+
introduction: string;
|
|
11
21
|
label: string;
|
|
12
22
|
/**
|
|
13
23
|
* Server name used to call Klavis API (e.g., 'Google Calendar')
|
|
@@ -17,141 +27,275 @@ export interface KlavisServerType {
|
|
|
17
27
|
|
|
18
28
|
export const KLAVIS_SERVER_TYPES: KlavisServerType[] = [
|
|
19
29
|
{
|
|
30
|
+
author: 'Klavis',
|
|
31
|
+
authorUrl: 'https://klavis.io',
|
|
32
|
+
description: 'Gmail is a free email service provided by Google',
|
|
20
33
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/gmail.svg',
|
|
21
34
|
identifier: 'gmail',
|
|
35
|
+
introduction:
|
|
36
|
+
'Bring the power of Gmail directly into your AI assistant. Read, compose, and send emails, search your inbox, manage labels, and organize your communications—all through natural conversation.',
|
|
22
37
|
label: 'Gmail',
|
|
23
38
|
serverName: Klavis.McpServerName.Gmail,
|
|
24
39
|
},
|
|
25
40
|
{
|
|
41
|
+
author: 'Klavis',
|
|
42
|
+
authorUrl: 'https://klavis.io',
|
|
43
|
+
description: 'Google Calendar is a time-management and scheduling calendar service',
|
|
26
44
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/googlecalendar.svg',
|
|
27
45
|
identifier: 'google-calendar',
|
|
46
|
+
introduction:
|
|
47
|
+
'Integrate Google Calendar to view, create, and manage your events seamlessly. Schedule meetings, set reminders, check availability, and coordinate your time—all through natural language commands.',
|
|
28
48
|
label: 'Google Calendar',
|
|
29
49
|
serverName: Klavis.McpServerName.GoogleCalendar,
|
|
30
50
|
},
|
|
31
51
|
{
|
|
52
|
+
author: 'Klavis',
|
|
53
|
+
authorUrl: 'https://klavis.io',
|
|
54
|
+
description: 'Notion is a collaborative productivity and note-taking application',
|
|
32
55
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/notion.svg',
|
|
33
56
|
identifier: 'notion',
|
|
57
|
+
introduction:
|
|
58
|
+
'Connect to Notion to access and manage your workspace. Create pages, search content, update databases, and organize your knowledge base—all through natural conversation with your AI assistant.',
|
|
34
59
|
label: 'Notion',
|
|
35
60
|
serverName: Klavis.McpServerName.Notion,
|
|
36
61
|
},
|
|
37
62
|
{
|
|
63
|
+
author: 'Klavis',
|
|
64
|
+
authorUrl: 'https://klavis.io',
|
|
65
|
+
description:
|
|
66
|
+
'Airtable is a cloud-based database and spreadsheet platform that combines the flexibility of a spreadsheet with the power of a database, enabling teams to organize, track, and collaborate on projects with customizable views and powerful automation features',
|
|
38
67
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/airtable.svg',
|
|
39
68
|
identifier: 'airtable',
|
|
69
|
+
introduction:
|
|
70
|
+
'Integrate with Airtable to manage your databases and workflows. Query records, create entries, update data, and automate operations with customizable views and powerful tracking features.',
|
|
40
71
|
label: 'Airtable',
|
|
41
72
|
serverName: Klavis.McpServerName.Airtable,
|
|
42
73
|
},
|
|
43
74
|
{
|
|
75
|
+
author: 'Klavis',
|
|
76
|
+
authorUrl: 'https://klavis.io',
|
|
77
|
+
description:
|
|
78
|
+
'Google Sheets is a web-based spreadsheet application that allows users to create, edit, and collaborate on spreadsheets online',
|
|
44
79
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/googlesheets.svg',
|
|
45
80
|
identifier: 'google-sheets',
|
|
81
|
+
introduction:
|
|
82
|
+
'Connect to Google Sheets to read, write, and analyze spreadsheet data. Perform calculations, generate reports, create charts, and manage tabular data collaboratively with AI assistance.',
|
|
46
83
|
label: 'Google Sheets',
|
|
47
84
|
serverName: Klavis.McpServerName.GoogleSheets,
|
|
48
85
|
},
|
|
49
86
|
{
|
|
87
|
+
author: 'Klavis',
|
|
88
|
+
authorUrl: 'https://klavis.io',
|
|
89
|
+
description:
|
|
90
|
+
'Google Docs is a word processor included as part of the free, web-based Google Docs Editors suite',
|
|
50
91
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/googledocs.svg',
|
|
51
92
|
identifier: 'google-docs',
|
|
93
|
+
introduction:
|
|
94
|
+
'Integrate with Google Docs to create, edit, and manage documents. Write content, format text, collaborate in real-time, and access your documents through natural conversation.',
|
|
52
95
|
label: 'Google Docs',
|
|
53
96
|
serverName: Klavis.McpServerName.GoogleDocs,
|
|
54
97
|
},
|
|
55
98
|
{
|
|
99
|
+
author: 'Klavis',
|
|
100
|
+
authorUrl: 'https://klavis.io',
|
|
101
|
+
description: 'Enhanced GitHub MCP Server',
|
|
56
102
|
icon: SiGithub,
|
|
57
103
|
identifier: 'github',
|
|
104
|
+
introduction:
|
|
105
|
+
'Connect to GitHub to manage repositories, issues, pull requests, and code. Search code, review changes, create branches, and collaborate on software development projects through conversational AI.',
|
|
58
106
|
label: 'GitHub',
|
|
59
107
|
serverName: Klavis.McpServerName.Github,
|
|
60
108
|
},
|
|
61
109
|
{
|
|
110
|
+
author: 'Klavis',
|
|
111
|
+
authorUrl: 'https://klavis.io',
|
|
112
|
+
description: 'Supabase official MCP Server',
|
|
62
113
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/supabase.svg',
|
|
63
114
|
identifier: 'supabase',
|
|
115
|
+
introduction:
|
|
116
|
+
'Integrate with Supabase to manage your database and backend services. Query data, manage authentication, handle storage, and interact with your application backend through natural conversation.',
|
|
64
117
|
label: 'Supabase',
|
|
65
118
|
serverName: Klavis.McpServerName.Supabase,
|
|
66
119
|
},
|
|
67
120
|
{
|
|
121
|
+
author: 'Klavis',
|
|
122
|
+
authorUrl: 'https://klavis.io',
|
|
123
|
+
description: 'Google Drive is a cloud storage service',
|
|
68
124
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/googledrive.svg',
|
|
69
125
|
identifier: 'google-drive',
|
|
126
|
+
introduction:
|
|
127
|
+
'Connect to Google Drive to access, organize, and manage your files. Search documents, upload files, share content, and navigate your cloud storage efficiently through AI assistance.',
|
|
70
128
|
label: 'Google Drive',
|
|
71
129
|
serverName: Klavis.McpServerName.GoogleDrive,
|
|
72
130
|
},
|
|
73
131
|
{
|
|
132
|
+
author: 'Klavis',
|
|
133
|
+
authorUrl: 'https://klavis.io',
|
|
134
|
+
description:
|
|
135
|
+
'Slack is a messaging app for business that connects people to the information they need',
|
|
74
136
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/slack.svg',
|
|
75
137
|
identifier: 'slack',
|
|
138
|
+
introduction:
|
|
139
|
+
'Integrate with Slack to send messages, search conversations, and manage channels. Connect with your team, automate communication workflows, and access workspace information through natural language.',
|
|
76
140
|
label: 'Slack',
|
|
77
141
|
serverName: Klavis.McpServerName.Slack,
|
|
78
142
|
},
|
|
79
143
|
{
|
|
144
|
+
author: 'Klavis',
|
|
145
|
+
authorUrl: 'https://klavis.io',
|
|
146
|
+
description: 'Confluence is a team workspace where knowledge and collaboration meet',
|
|
80
147
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/confluence.svg',
|
|
81
148
|
identifier: 'confluence',
|
|
149
|
+
introduction:
|
|
150
|
+
'Connect to Confluence to access and manage team documentation. Search pages, create content, organize spaces, and build your knowledge base through conversational AI assistance.',
|
|
82
151
|
label: 'Confluence',
|
|
83
152
|
serverName: Klavis.McpServerName.Confluence,
|
|
84
153
|
},
|
|
85
154
|
{
|
|
155
|
+
author: 'Klavis',
|
|
156
|
+
authorUrl: 'https://klavis.io',
|
|
157
|
+
description: 'Jira is a project management and issue tracking tool developed by Atlassian',
|
|
86
158
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/jira.svg',
|
|
87
159
|
identifier: 'jira',
|
|
160
|
+
introduction:
|
|
161
|
+
'Integrate with Jira to manage issues, track progress, and organize sprints. Create tickets, update statuses, query project data, and streamline your development workflow through natural conversation.',
|
|
88
162
|
label: 'Jira',
|
|
89
163
|
serverName: Klavis.McpServerName.Jira,
|
|
90
164
|
},
|
|
91
165
|
{
|
|
166
|
+
author: 'Klavis',
|
|
167
|
+
authorUrl: 'https://klavis.io',
|
|
168
|
+
description:
|
|
169
|
+
'ClickUp is a comprehensive project management and productivity platform that helps teams organize tasks, manage projects, and collaborate effectively with customizable workflows and powerful tracking features',
|
|
92
170
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/clickup.svg',
|
|
93
171
|
identifier: 'clickup',
|
|
172
|
+
introduction:
|
|
173
|
+
'Connect to ClickUp to manage tasks, track projects, and organize your work. Create tasks, update statuses, manage custom workflows, and collaborate with your team through natural language commands.',
|
|
94
174
|
label: 'ClickUp',
|
|
95
175
|
serverName: Klavis.McpServerName.Clickup,
|
|
96
176
|
},
|
|
97
177
|
{
|
|
178
|
+
author: 'Klavis',
|
|
179
|
+
authorUrl: 'https://klavis.io',
|
|
180
|
+
description:
|
|
181
|
+
'Complete file management solution for Dropbox cloud storage. Upload, download, organize files and folders, manage sharing and collaboration, handle file versions, create file requests, and perform batch operations on your Dropbox files and folders',
|
|
98
182
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/dropbox.svg',
|
|
99
183
|
identifier: 'dropbox',
|
|
184
|
+
introduction:
|
|
185
|
+
'Integrate with Dropbox to access and manage your files. Upload, download, share files, manage folders, handle file versions, and organize your cloud storage through conversational AI.',
|
|
100
186
|
label: 'Dropbox',
|
|
101
187
|
serverName: Klavis.McpServerName.Dropbox,
|
|
102
188
|
},
|
|
103
189
|
{
|
|
190
|
+
author: 'Klavis',
|
|
191
|
+
authorUrl: 'https://klavis.io',
|
|
192
|
+
description: 'Figma is a collaborative interface design tool for web and mobile applications.',
|
|
104
193
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/figma.svg',
|
|
105
194
|
identifier: 'figma',
|
|
195
|
+
introduction:
|
|
196
|
+
'Connect to Figma to access design files and collaborate on projects. View designs, export assets, browse components, and manage your design workflow through natural conversation.',
|
|
106
197
|
label: 'Figma',
|
|
107
198
|
serverName: Klavis.McpServerName.Figma,
|
|
108
199
|
},
|
|
109
200
|
{
|
|
201
|
+
author: 'Klavis',
|
|
202
|
+
authorUrl: 'https://klavis.io',
|
|
203
|
+
description:
|
|
204
|
+
'HubSpot is a developer and marketer of software products for inbound marketing, sales, and customer service',
|
|
110
205
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/hubspot.svg',
|
|
111
206
|
identifier: 'hubspot',
|
|
207
|
+
introduction:
|
|
208
|
+
'Integrate with HubSpot to manage contacts, deals, and marketing campaigns. Access CRM data, track pipelines, automate workflows, and streamline your sales and marketing operations.',
|
|
112
209
|
label: 'HubSpot',
|
|
113
210
|
serverName: Klavis.McpServerName.Hubspot,
|
|
114
211
|
},
|
|
115
212
|
{
|
|
213
|
+
author: 'Klavis',
|
|
214
|
+
authorUrl: 'https://klavis.io',
|
|
215
|
+
description:
|
|
216
|
+
'OneDrive is a file hosting service and synchronization service operated by Microsoft',
|
|
116
217
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/onedrive.svg',
|
|
117
218
|
identifier: 'onedrive',
|
|
219
|
+
introduction:
|
|
220
|
+
'Connect to OneDrive to access and manage your Microsoft cloud files. Upload, download, share files, organize folders, and collaborate on documents through AI-powered assistance.',
|
|
118
221
|
label: 'OneDrive',
|
|
119
222
|
serverName: Klavis.McpServerName.Onedrive,
|
|
120
223
|
},
|
|
121
224
|
{
|
|
225
|
+
author: 'Klavis',
|
|
226
|
+
authorUrl: 'https://klavis.io',
|
|
227
|
+
description:
|
|
228
|
+
'Outlook Mail is a web-based suite of webmail, contacts, tasks, and calendaring services from Microsoft.',
|
|
122
229
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/outlook.svg',
|
|
123
230
|
identifier: 'outlook-mail',
|
|
231
|
+
introduction:
|
|
232
|
+
'Integrate with Outlook Mail to read, send, and manage your Microsoft emails. Search messages, compose emails, manage folders, and organize your inbox through natural conversation.',
|
|
124
233
|
label: 'Outlook Mail',
|
|
125
234
|
serverName: Klavis.McpServerName.OutlookMail,
|
|
126
235
|
},
|
|
127
236
|
{
|
|
237
|
+
author: 'Klavis',
|
|
238
|
+
authorUrl: 'https://klavis.io',
|
|
239
|
+
description:
|
|
240
|
+
"Salesforce is the world's leading customer relationship management (CRM) platform that helps businesses connect with customers, partners, and potential customers",
|
|
128
241
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/salesforce.svg',
|
|
129
242
|
identifier: 'salesforce',
|
|
243
|
+
introduction:
|
|
244
|
+
'Connect to Salesforce to manage customer relationships and sales data. Query records, update opportunities, track leads, and automate your CRM workflows through natural language commands.',
|
|
130
245
|
label: 'Salesforce',
|
|
131
246
|
serverName: Klavis.McpServerName.Salesforce,
|
|
132
247
|
},
|
|
133
248
|
{
|
|
249
|
+
author: 'Klavis',
|
|
250
|
+
authorUrl: 'https://klavis.io',
|
|
251
|
+
description:
|
|
252
|
+
'WhatsApp Business API integration that enables sending text messages, media, and managing conversations with customers. Perfect for customer support, marketing campaigns, and automated messaging workflows through the official WhatsApp Business platform.',
|
|
134
253
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/whatsapp.svg',
|
|
135
254
|
identifier: 'whatsapp',
|
|
255
|
+
introduction:
|
|
256
|
+
'Integrate with WhatsApp Business to send messages, manage conversations, and engage with customers. Automate messaging workflows and handle communications through conversational AI.',
|
|
136
257
|
label: 'WhatsApp',
|
|
137
258
|
serverName: Klavis.McpServerName.Whatsapp,
|
|
138
259
|
},
|
|
139
260
|
{
|
|
261
|
+
author: 'Klavis',
|
|
262
|
+
authorUrl: 'https://klavis.io',
|
|
263
|
+
description:
|
|
264
|
+
'YouTube is a video-sharing platform where users can upload, share, and discover content. Access video information, transcripts, and metadata programmatically.',
|
|
140
265
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/youtube.svg',
|
|
141
266
|
identifier: 'youtube',
|
|
267
|
+
introduction:
|
|
268
|
+
'Connect to YouTube to search videos, access transcripts, and retrieve video information. Analyze content, extract metadata, and discover videos through natural conversation.',
|
|
142
269
|
label: 'YouTube',
|
|
143
270
|
serverName: Klavis.McpServerName.Youtube,
|
|
144
271
|
},
|
|
145
272
|
{
|
|
273
|
+
author: 'Klavis',
|
|
274
|
+
authorUrl: 'https://klavis.io',
|
|
275
|
+
description: 'Zendesk is a customer service software company',
|
|
146
276
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/zendesk.svg',
|
|
147
277
|
identifier: 'zendesk',
|
|
278
|
+
introduction:
|
|
279
|
+
'Integrate with Zendesk to manage support tickets and customer interactions. Create, update, and track support requests, access customer data, and streamline your support operations.',
|
|
148
280
|
label: 'Zendesk',
|
|
149
281
|
serverName: Klavis.McpServerName.Zendesk,
|
|
150
282
|
},
|
|
151
283
|
{
|
|
284
|
+
author: 'Klavis',
|
|
285
|
+
authorUrl: 'https://klavis.io',
|
|
286
|
+
description:
|
|
287
|
+
'Cal.com is an open-source scheduling platform that helps you schedule meetings without the back-and-forth emails. Manage event types, bookings, availability, and integrate with calendars for seamless appointment scheduling',
|
|
152
288
|
icon: SiCaldotcom,
|
|
153
289
|
identifier: 'cal-com',
|
|
290
|
+
introduction:
|
|
291
|
+
'Connect to Cal.com to manage your scheduling and appointments. View availability, book meetings, manage event types, and automate your calendar through natural conversation.',
|
|
154
292
|
label: 'Cal.com',
|
|
155
293
|
serverName: Klavis.McpServerName.CalCom,
|
|
156
294
|
},
|
|
157
295
|
];
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Get server config by identifier
|
|
299
|
+
*/
|
|
300
|
+
export const getKlavisServerByServerIdentifier = (identifier: string) =>
|
|
301
|
+
KLAVIS_SERVER_TYPES.find((s) => s.identifier === identifier);
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { type IconType, SiLinear, SiX } from '@icons-pack/react-simple-icons';
|
|
2
2
|
|
|
3
3
|
export interface LobehubSkillProviderType {
|
|
4
|
+
/**
|
|
5
|
+
* Author/Developer of the integration
|
|
6
|
+
*/
|
|
7
|
+
author: string;
|
|
8
|
+
/**
|
|
9
|
+
* Author's website URL
|
|
10
|
+
*/
|
|
11
|
+
authorUrl?: string;
|
|
4
12
|
/**
|
|
5
13
|
* Whether this provider is visible by default in the UI
|
|
6
14
|
*/
|
|
7
15
|
defaultVisible?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Short description of the skill
|
|
18
|
+
*/
|
|
19
|
+
description: string;
|
|
8
20
|
/**
|
|
9
21
|
* Icon - can be a URL string or a React icon component
|
|
10
22
|
*/
|
|
@@ -13,6 +25,10 @@ export interface LobehubSkillProviderType {
|
|
|
13
25
|
* Provider ID (matches Market API, e.g., 'linear', 'microsoft')
|
|
14
26
|
*/
|
|
15
27
|
id: string;
|
|
28
|
+
/**
|
|
29
|
+
* Detailed introduction of the skill
|
|
30
|
+
*/
|
|
31
|
+
introduction: string;
|
|
16
32
|
/**
|
|
17
33
|
* Display label for the provider
|
|
18
34
|
*/
|
|
@@ -29,21 +45,39 @@ export interface LobehubSkillProviderType {
|
|
|
29
45
|
*/
|
|
30
46
|
export const LOBEHUB_SKILL_PROVIDERS: LobehubSkillProviderType[] = [
|
|
31
47
|
{
|
|
48
|
+
author: 'LobeHub',
|
|
49
|
+
authorUrl: 'https://lobehub.com',
|
|
32
50
|
defaultVisible: true,
|
|
51
|
+
description:
|
|
52
|
+
'Linear is a modern issue tracking and project management tool designed for high-performance teams to build better software faster',
|
|
33
53
|
icon: SiLinear,
|
|
34
54
|
id: 'linear',
|
|
55
|
+
introduction:
|
|
56
|
+
'Bring the power of Linear directly into your AI assistant. Create and update issues, manage sprints, track project progress, and streamline your development workflow—all through natural conversation.',
|
|
35
57
|
label: 'Linear',
|
|
36
58
|
},
|
|
37
59
|
{
|
|
60
|
+
author: 'LobeHub',
|
|
61
|
+
authorUrl: 'https://lobehub.com',
|
|
38
62
|
defaultVisible: true,
|
|
63
|
+
description:
|
|
64
|
+
'Outlook Calendar is an integrated scheduling tool within Microsoft Outlook that enables users to create appointments, organize meetings with others, and manage their time and events effectively.',
|
|
39
65
|
icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/outlook.svg',
|
|
40
66
|
id: 'microsoft',
|
|
67
|
+
introduction:
|
|
68
|
+
'Integrate with Outlook Calendar to view, create, and manage your events seamlessly. Schedule meetings, check availability, set reminders, and coordinate your time—all through natural language commands.',
|
|
41
69
|
label: 'Outlook Calendar',
|
|
42
70
|
},
|
|
43
71
|
{
|
|
72
|
+
author: 'LobeHub',
|
|
73
|
+
authorUrl: 'https://lobehub.com',
|
|
44
74
|
defaultVisible: true,
|
|
75
|
+
description:
|
|
76
|
+
'X (Twitter) is a social media platform for sharing real-time updates, news, and engaging with your audience through posts, replies, and direct messages.',
|
|
45
77
|
icon: SiX,
|
|
46
78
|
id: 'twitter',
|
|
79
|
+
introduction:
|
|
80
|
+
'Connect to X (Twitter) to post tweets, manage your timeline, and engage with your audience. Create content, schedule posts, monitor mentions, and build your social media presence through conversational AI.',
|
|
47
81
|
label: 'X (Twitter)',
|
|
48
82
|
},
|
|
49
83
|
];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export enum RecommendedSkillType {
|
|
2
|
+
Klavis = 'klavis',
|
|
3
|
+
Lobehub = 'lobehub',
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface RecommendedSkillItem {
|
|
7
|
+
id: string;
|
|
8
|
+
type: RecommendedSkillType;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const RECOMMENDED_SKILLS: RecommendedSkillItem[] = [
|
|
12
|
+
{ id: 'gmail', type: RecommendedSkillType.Klavis },
|
|
13
|
+
{ id: 'notion', type: RecommendedSkillType.Klavis },
|
|
14
|
+
{ id: 'google-drive', type: RecommendedSkillType.Klavis },
|
|
15
|
+
{ id: 'google-calendar', type: RecommendedSkillType.Klavis },
|
|
16
|
+
{ id: 'slack', type: RecommendedSkillType.Klavis },
|
|
17
|
+
];
|
|
@@ -125,6 +125,44 @@ describe('anthropicHelpers', () => {
|
|
|
125
125
|
|
|
126
126
|
await expect(buildAnthropicBlock(content)).rejects.toThrow('Invalid image URL: invalid-url');
|
|
127
127
|
});
|
|
128
|
+
|
|
129
|
+
it('should return undefined for unsupported SVG image (base64)', async () => {
|
|
130
|
+
vi.mocked(parseDataUri).mockReturnValueOnce({
|
|
131
|
+
mimeType: 'image/svg+xml',
|
|
132
|
+
base64: 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==',
|
|
133
|
+
type: 'base64',
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const content = {
|
|
137
|
+
type: 'image_url',
|
|
138
|
+
image_url: {
|
|
139
|
+
url: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==',
|
|
140
|
+
},
|
|
141
|
+
} as const;
|
|
142
|
+
|
|
143
|
+
const result = await buildAnthropicBlock(content);
|
|
144
|
+
expect(result).toBeUndefined();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should return undefined for unsupported SVG image (URL)', async () => {
|
|
148
|
+
vi.mocked(parseDataUri).mockReturnValueOnce({
|
|
149
|
+
mimeType: null,
|
|
150
|
+
base64: null,
|
|
151
|
+
type: 'url',
|
|
152
|
+
});
|
|
153
|
+
vi.mocked(imageUrlToBase64).mockResolvedValueOnce({
|
|
154
|
+
base64: 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==',
|
|
155
|
+
mimeType: 'image/svg+xml',
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const content = {
|
|
159
|
+
type: 'image_url',
|
|
160
|
+
image_url: { url: 'https://example.com/image.svg' },
|
|
161
|
+
} as const;
|
|
162
|
+
|
|
163
|
+
const result = await buildAnthropicBlock(content);
|
|
164
|
+
expect(result).toBeUndefined();
|
|
165
|
+
});
|
|
128
166
|
});
|
|
129
167
|
|
|
130
168
|
describe('buildAnthropicMessage', () => {
|
|
@@ -5,6 +5,19 @@ import OpenAI from 'openai';
|
|
|
5
5
|
import { OpenAIChatMessage, UserMessageContentPart } from '../../types';
|
|
6
6
|
import { parseDataUri } from '../../utils/uriParser';
|
|
7
7
|
|
|
8
|
+
const ANTHROPIC_SUPPORTED_IMAGE_TYPES = new Set([
|
|
9
|
+
'image/jpeg',
|
|
10
|
+
'image/jpg',
|
|
11
|
+
'image/png',
|
|
12
|
+
'image/gif',
|
|
13
|
+
'image/webp',
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
const isImageTypeSupported = (mimeType: string | null): boolean => {
|
|
17
|
+
if (!mimeType) return true;
|
|
18
|
+
return ANTHROPIC_SUPPORTED_IMAGE_TYPES.has(mimeType.toLowerCase());
|
|
19
|
+
};
|
|
20
|
+
|
|
8
21
|
export const buildAnthropicBlock = async (
|
|
9
22
|
content: UserMessageContentPart,
|
|
10
23
|
): Promise<Anthropic.ContentBlock | Anthropic.ImageBlockParam | undefined> => {
|
|
@@ -23,7 +36,9 @@ export const buildAnthropicBlock = async (
|
|
|
23
36
|
case 'image_url': {
|
|
24
37
|
const { mimeType, base64, type } = parseDataUri(content.image_url.url);
|
|
25
38
|
|
|
26
|
-
if (type === 'base64')
|
|
39
|
+
if (type === 'base64') {
|
|
40
|
+
if (!isImageTypeSupported(mimeType)) return undefined;
|
|
41
|
+
|
|
27
42
|
return {
|
|
28
43
|
source: {
|
|
29
44
|
data: base64 as string,
|
|
@@ -32,9 +47,13 @@ export const buildAnthropicBlock = async (
|
|
|
32
47
|
},
|
|
33
48
|
type: 'image',
|
|
34
49
|
};
|
|
50
|
+
}
|
|
35
51
|
|
|
36
52
|
if (type === 'url') {
|
|
37
53
|
const { base64, mimeType } = await imageUrlToBase64(content.image_url.url);
|
|
54
|
+
|
|
55
|
+
if (!isImageTypeSupported(mimeType)) return undefined;
|
|
56
|
+
|
|
38
57
|
return {
|
|
39
58
|
source: {
|
|
40
59
|
data: base64 as string,
|
|
@@ -149,6 +149,48 @@ describe('google contextBuilders', () => {
|
|
|
149
149
|
thoughtSignature: GEMINI_MAGIC_THOUGHT_SIGNATURE,
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
|
+
|
|
153
|
+
it('should return undefined for unsupported SVG image (base64)', async () => {
|
|
154
|
+
const svgBase64 =
|
|
155
|
+
'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==';
|
|
156
|
+
|
|
157
|
+
vi.mocked(parseDataUri).mockReturnValueOnce({
|
|
158
|
+
base64: 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==',
|
|
159
|
+
mimeType: 'image/svg+xml',
|
|
160
|
+
type: 'base64',
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const content: UserMessageContentPart = {
|
|
164
|
+
image_url: { url: svgBase64 },
|
|
165
|
+
type: 'image_url',
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const result = await buildGooglePart(content);
|
|
169
|
+
expect(result).toBeUndefined();
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('should return undefined for unsupported SVG image (URL)', async () => {
|
|
173
|
+
const svgUrl = 'https://example.com/image.svg';
|
|
174
|
+
|
|
175
|
+
vi.mocked(parseDataUri).mockReturnValueOnce({
|
|
176
|
+
base64: null,
|
|
177
|
+
mimeType: null,
|
|
178
|
+
type: 'url',
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
vi.spyOn(imageToBase64Module, 'imageUrlToBase64').mockResolvedValueOnce({
|
|
182
|
+
base64: 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==',
|
|
183
|
+
mimeType: 'image/svg+xml',
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const content: UserMessageContentPart = {
|
|
187
|
+
image_url: { url: svgUrl },
|
|
188
|
+
type: 'image_url',
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const result = await buildGooglePart(content);
|
|
192
|
+
expect(result).toBeUndefined();
|
|
193
|
+
});
|
|
152
194
|
});
|
|
153
195
|
|
|
154
196
|
describe('buildGoogleMessage', () => {
|
|
@@ -11,6 +11,19 @@ import { ChatCompletionTool, OpenAIChatMessage, UserMessageContentPart } from '.
|
|
|
11
11
|
import { safeParseJSON } from '../../utils/safeParseJSON';
|
|
12
12
|
import { parseDataUri } from '../../utils/uriParser';
|
|
13
13
|
|
|
14
|
+
const GOOGLE_SUPPORTED_IMAGE_TYPES = new Set([
|
|
15
|
+
'image/jpeg',
|
|
16
|
+
'image/jpg',
|
|
17
|
+
'image/png',
|
|
18
|
+
'image/gif',
|
|
19
|
+
'image/webp',
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
const isImageTypeSupported = (mimeType: string | null): boolean => {
|
|
23
|
+
if (!mimeType) return true;
|
|
24
|
+
return GOOGLE_SUPPORTED_IMAGE_TYPES.has(mimeType.toLowerCase());
|
|
25
|
+
};
|
|
26
|
+
|
|
14
27
|
/**
|
|
15
28
|
* Magic thoughtSignature
|
|
16
29
|
* @see https://ai.google.dev/gemini-api/docs/thought-signatures#model-behavior:~:text=context_engineering_is_the_way_to_go
|
|
@@ -43,6 +56,8 @@ export const buildGooglePart = async (
|
|
|
43
56
|
throw new TypeError("Image URL doesn't contain base64 data");
|
|
44
57
|
}
|
|
45
58
|
|
|
59
|
+
if (!isImageTypeSupported(mimeType)) return undefined;
|
|
60
|
+
|
|
46
61
|
return {
|
|
47
62
|
inlineData: { data: base64, mimeType: mimeType || 'image/png' },
|
|
48
63
|
thoughtSignature: GEMINI_MAGIC_THOUGHT_SIGNATURE,
|
|
@@ -52,6 +67,8 @@ export const buildGooglePart = async (
|
|
|
52
67
|
if (type === 'url') {
|
|
53
68
|
const { base64, mimeType } = await imageUrlToBase64(content.image_url.url);
|
|
54
69
|
|
|
70
|
+
if (!isImageTypeSupported(mimeType)) return undefined;
|
|
71
|
+
|
|
55
72
|
return {
|
|
56
73
|
inlineData: { data: base64, mimeType },
|
|
57
74
|
thoughtSignature: GEMINI_MAGIC_THOUGHT_SIGNATURE,
|
|
@@ -242,7 +242,7 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
|
242
242
|
} catch (e) {
|
|
243
243
|
const err = e as Error;
|
|
244
244
|
|
|
245
|
-
//
|
|
245
|
+
// Remove previous silent handling, throw error uniformly
|
|
246
246
|
if (isAbortError(err)) {
|
|
247
247
|
log('Request was cancelled');
|
|
248
248
|
throw AgentRuntimeError.chat({
|
|
@@ -307,10 +307,10 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
|
307
307
|
try {
|
|
308
308
|
for await (const chunk of originalStream) {
|
|
309
309
|
if (signal.aborted) {
|
|
310
|
-
//
|
|
310
|
+
// If data has already been output, close the stream gracefully instead of throwing an error
|
|
311
311
|
if (hasData) {
|
|
312
312
|
log('Stream cancelled gracefully, preserving existing output');
|
|
313
|
-
//
|
|
313
|
+
// Explicitly inject cancellation error to avoid SSE fallback unexpected_end
|
|
314
314
|
controller.enqueue({
|
|
315
315
|
[LOBE_ERROR_KEY]: {
|
|
316
316
|
body: { name: 'Stream cancelled', provider, reason: 'aborted' },
|
|
@@ -322,7 +322,7 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
|
322
322
|
controller.close();
|
|
323
323
|
return;
|
|
324
324
|
} else {
|
|
325
|
-
//
|
|
325
|
+
// If no data has been output yet, close the stream directly and let downstream SSE emit error event during flush phase
|
|
326
326
|
log('Stream cancelled before any output');
|
|
327
327
|
controller.close();
|
|
328
328
|
return;
|
|
@@ -335,12 +335,12 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
|
335
335
|
} catch (error) {
|
|
336
336
|
const err = error as Error;
|
|
337
337
|
|
|
338
|
-
//
|
|
338
|
+
// Handle all errors uniformly, including abort errors
|
|
339
339
|
if (isAbortError(err) || signal.aborted) {
|
|
340
|
-
//
|
|
340
|
+
// If data has already been output, close the stream gracefully
|
|
341
341
|
if (hasData) {
|
|
342
342
|
log('Stream reading cancelled gracefully, preserving existing output');
|
|
343
|
-
//
|
|
343
|
+
// Explicitly inject cancellation error to avoid SSE fallback unexpected_end
|
|
344
344
|
controller.enqueue({
|
|
345
345
|
[LOBE_ERROR_KEY]: {
|
|
346
346
|
body: { name: 'Stream cancelled', provider, reason: 'aborted' },
|
|
@@ -353,7 +353,7 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
|
353
353
|
return;
|
|
354
354
|
} else {
|
|
355
355
|
log('Stream reading cancelled before any output');
|
|
356
|
-
//
|
|
356
|
+
// Inject an error marker with detailed error information to be handled by downstream google-ai transformer to output error event
|
|
357
357
|
controller.enqueue({
|
|
358
358
|
[LOBE_ERROR_KEY]: {
|
|
359
359
|
body: {
|
|
@@ -371,14 +371,14 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
|
371
371
|
return;
|
|
372
372
|
}
|
|
373
373
|
} else {
|
|
374
|
-
//
|
|
374
|
+
// Handle other stream parsing errors
|
|
375
375
|
log('Stream parsing error: %O', err);
|
|
376
|
-
//
|
|
376
|
+
// Try to parse Google error and extract code/message/status
|
|
377
377
|
const { error: parsedError, errorType } = parseGoogleErrorMessage(
|
|
378
378
|
err?.message || String(err),
|
|
379
379
|
);
|
|
380
380
|
|
|
381
|
-
//
|
|
381
|
+
// Inject an error marker with detailed error information to be handled by downstream google-ai transformer to output error event
|
|
382
382
|
controller.enqueue({
|
|
383
383
|
[LOBE_ERROR_KEY]: {
|
|
384
384
|
body: { ...parsedError, provider },
|
|
@@ -453,12 +453,12 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
|
453
453
|
const hasUrlContext = payload?.urlContext;
|
|
454
454
|
const hasFunctionTools = tools && tools.length > 0;
|
|
455
455
|
|
|
456
|
-
//
|
|
456
|
+
// If tool_calls already exist, prioritize handling function declarations
|
|
457
457
|
if (hasToolCalls && hasFunctionTools) {
|
|
458
458
|
return buildGoogleTools(tools);
|
|
459
459
|
}
|
|
460
460
|
|
|
461
|
-
//
|
|
461
|
+
// Build and return search-related tools (search tools cannot be used with FunctionCall simultaneously)
|
|
462
462
|
if (hasUrlContext && hasSearch) {
|
|
463
463
|
return [{ urlContext: {} }, { googleSearch: {} }];
|
|
464
464
|
}
|
|
@@ -469,7 +469,7 @@ export class LobeGoogleAI implements LobeRuntimeAI {
|
|
|
469
469
|
return [{ googleSearch: {} }];
|
|
470
470
|
}
|
|
471
471
|
|
|
472
|
-
//
|
|
472
|
+
// Finally consider function declarations
|
|
473
473
|
return buildGoogleTools(tools);
|
|
474
474
|
}
|
|
475
475
|
}
|