@lobehub/lobehub 2.0.0-next.47 → 2.0.0-next.48
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/.env.example +11 -0
- package/CHANGELOG.md +17 -0
- package/apps/desktop/src/main/controllers/AuthCtr.ts +27 -2
- package/apps/desktop/src/main/core/infrastructure/ProtocolManager.ts +9 -4
- package/changelog/v1.json +5 -0
- package/docs/development/database-schema.dbml +2 -0
- package/docs/self-hosting/environment-variables/basic.mdx +49 -3
- package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +49 -4
- package/locales/ar/discover.json +45 -0
- package/locales/ar/marketAuth.json +42 -0
- package/locales/ar/setting.json +94 -1
- package/locales/bg-BG/discover.json +45 -0
- package/locales/bg-BG/marketAuth.json +42 -0
- package/locales/bg-BG/setting.json +94 -1
- package/locales/de-DE/discover.json +45 -0
- package/locales/de-DE/marketAuth.json +42 -0
- package/locales/de-DE/setting.json +94 -1
- package/locales/en-US/discover.json +45 -0
- package/locales/en-US/marketAuth.json +42 -0
- package/locales/en-US/setting.json +94 -1
- package/locales/es-ES/discover.json +45 -0
- package/locales/es-ES/marketAuth.json +42 -0
- package/locales/es-ES/setting.json +94 -1
- package/locales/fa-IR/discover.json +45 -0
- package/locales/fa-IR/marketAuth.json +42 -0
- package/locales/fa-IR/setting.json +94 -1
- package/locales/fr-FR/discover.json +45 -0
- package/locales/fr-FR/marketAuth.json +42 -0
- package/locales/fr-FR/setting.json +94 -1
- package/locales/it-IT/discover.json +45 -0
- package/locales/it-IT/marketAuth.json +42 -0
- package/locales/it-IT/setting.json +94 -1
- package/locales/ja-JP/discover.json +45 -0
- package/locales/ja-JP/marketAuth.json +42 -0
- package/locales/ja-JP/setting.json +94 -1
- package/locales/ko-KR/discover.json +45 -0
- package/locales/ko-KR/marketAuth.json +42 -0
- package/locales/ko-KR/setting.json +94 -1
- package/locales/nl-NL/discover.json +45 -0
- package/locales/nl-NL/marketAuth.json +42 -0
- package/locales/nl-NL/setting.json +94 -1
- package/locales/pl-PL/discover.json +45 -0
- package/locales/pl-PL/marketAuth.json +42 -0
- package/locales/pl-PL/setting.json +94 -1
- package/locales/pt-BR/discover.json +45 -0
- package/locales/pt-BR/marketAuth.json +42 -0
- package/locales/pt-BR/setting.json +94 -1
- package/locales/ru-RU/discover.json +45 -0
- package/locales/ru-RU/marketAuth.json +42 -0
- package/locales/ru-RU/setting.json +94 -1
- package/locales/tr-TR/discover.json +45 -0
- package/locales/tr-TR/marketAuth.json +42 -0
- package/locales/tr-TR/setting.json +94 -1
- package/locales/vi-VN/discover.json +45 -0
- package/locales/vi-VN/marketAuth.json +42 -0
- package/locales/vi-VN/setting.json +94 -1
- package/locales/zh-CN/discover.json +45 -0
- package/locales/zh-CN/marketAuth.json +42 -0
- package/locales/zh-CN/setting.json +94 -1
- package/locales/zh-TW/discover.json +45 -0
- package/locales/zh-TW/marketAuth.json +42 -0
- package/locales/zh-TW/setting.json +94 -1
- package/package.json +27 -26
- package/packages/const/src/url.ts +1 -0
- package/packages/database/migrations/0044_add_tool_intervention.sql +1 -0
- package/packages/database/migrations/0044_high_toxin.sql +1 -0
- package/packages/database/migrations/0045_add_tool_intervention.sql +1 -0
- package/packages/database/migrations/meta/0039_snapshot.json +1 -1
- package/packages/database/migrations/meta/0044_snapshot.json +7813 -0
- package/packages/database/migrations/meta/0045_snapshot.json +8431 -0
- package/packages/database/migrations/meta/_journal.json +14 -0
- package/packages/database/src/core/migrations.json +36 -7
- package/packages/database/src/models/message.ts +1 -1
- package/packages/database/src/models/session.ts +42 -1
- package/packages/database/src/schemas/agent.ts +1 -0
- package/packages/database/src/schemas/message.ts +5 -8
- package/packages/electron-client-ipc/src/events/index.ts +6 -1
- package/packages/electron-client-ipc/src/events/remoteServer.ts +8 -0
- package/packages/fetch-sse/package.json +29 -0
- package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/fetchSSE.test.ts +4 -4
- package/packages/{utils/src/fetch → fetch-sse/src}/__tests__/parseError.test.ts +7 -4
- package/packages/{utils/src/fetch → fetch-sse/src}/fetchSSE.ts +2 -2
- package/packages/{utils/src/fetch → fetch-sse/src}/parseError.ts +3 -3
- package/packages/model-bank/src/aiModels/mistral.ts +2 -1
- package/packages/model-runtime/src/core/contextBuilders/anthropic.test.ts +17 -11
- package/packages/model-runtime/src/core/contextBuilders/anthropic.ts +1 -1
- package/packages/model-runtime/src/core/contextBuilders/google.test.ts +1 -1
- package/packages/model-runtime/src/core/contextBuilders/google.ts +3 -6
- package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +4 -2
- package/packages/model-runtime/src/core/contextBuilders/openai.ts +1 -1
- package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.test.ts +1 -1
- package/packages/model-runtime/src/core/openaiCompatibleFactory/createImage.ts +1 -1
- package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +3 -6
- package/packages/model-runtime/src/core/streams/openai/responsesStream.test.ts +1 -1
- package/packages/model-runtime/src/helpers/mergeChatMethodOptions.ts +2 -1
- package/packages/model-runtime/src/providers/aihubmix/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/anthropic/generateObject.test.ts +1 -1
- package/packages/model-runtime/src/providers/anthropic/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/baichuan/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/bedrock/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/bfl/createImage.test.ts +4 -4
- package/packages/model-runtime/src/providers/bfl/createImage.ts +1 -1
- package/packages/model-runtime/src/providers/cloudflare/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/cohere/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/google/createImage.test.ts +2 -2
- package/packages/model-runtime/src/providers/google/createImage.ts +1 -1
- package/packages/model-runtime/src/providers/google/generateObject.test.ts +1 -1
- package/packages/model-runtime/src/providers/google/index.test.ts +1 -4
- package/packages/model-runtime/src/providers/groq/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/hunyuan/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/minimax/createImage.test.ts +1 -1
- package/packages/model-runtime/src/providers/mistral/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/moonshot/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/novita/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/ollama/index.test.ts +43 -32
- package/packages/model-runtime/src/providers/ollama/index.ts +31 -7
- package/packages/model-runtime/src/providers/openrouter/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/perplexity/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/ppio/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/qwen/createImage.test.ts +1 -1
- package/packages/model-runtime/src/providers/search1api/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/siliconcloud/createImage.ts +1 -1
- package/packages/model-runtime/src/providers/taichu/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/wenxin/index.test.ts +1 -1
- package/packages/model-runtime/src/providers/zhipu/index.test.ts +1 -1
- package/packages/model-runtime/src/utils/errorResponse.test.ts +1 -1
- package/packages/ssrf-safe-fetch/index.browser.ts +14 -0
- package/packages/ssrf-safe-fetch/package.json +8 -1
- package/packages/types/src/discover/assistants.ts +16 -0
- package/packages/types/src/index.ts +1 -0
- package/packages/types/src/message/common/tools.ts +10 -0
- package/packages/types/src/message/db/item.ts +15 -1
- package/packages/types/src/message/ui/params.ts +15 -1
- package/packages/types/src/meta.ts +4 -0
- package/packages/types/src/session/agentSession.ts +2 -0
- package/packages/utils/src/imageToBase64.ts +17 -10
- package/packages/utils/src/index.ts +1 -1
- package/src/app/(backend)/market/agent/[[...segments]]/route.ts +153 -0
- package/src/app/(backend)/market/oidc/[[...segments]]/route.ts +207 -0
- package/src/app/[variants]/(main)/(mobile)/me/settings/features/useCategory.tsx +1 -0
- package/src/app/[variants]/(main)/_layout/Desktop/SideBar/PinList/index.tsx +4 -2
- package/src/app/[variants]/(main)/chat/settings/features/AgentInfoDescription/index.tsx +349 -0
- package/src/app/[variants]/(main)/chat/settings/features/HeaderContent.tsx +2 -2
- package/src/app/[variants]/(main)/chat/settings/features/PublishResultModal/index.tsx +64 -0
- package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishButton.tsx +196 -0
- package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishModal.tsx +358 -0
- package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/index.tsx +75 -0
- package/src/app/[variants]/(main)/discover/(detail)/assistant/AssistantDetailPage.tsx +11 -2
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/Client.tsx +12 -1
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Nav.tsx +19 -12
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/TagList.tsx +14 -5
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Overview/index.tsx +2 -0
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Related/index.tsx +14 -5
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/TagList.tsx +14 -5
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/SystemRole/index.tsx +43 -29
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/Versions/index.tsx +137 -0
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Details/index.tsx +2 -0
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Header.tsx +9 -10
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/ActionButton/AddAgent.tsx +105 -14
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/Sidebar/Related/index.tsx +20 -6
- package/src/app/[variants]/(main)/discover/(detail)/assistant/[...slugs]/features/StatusPage/index.tsx +113 -0
- package/src/app/[variants]/(main)/discover/(detail)/features/Breadcrumb.tsx +4 -3
- package/src/app/[variants]/(main)/discover/(list)/_layout/Desktop/Nav.tsx +3 -1
- package/src/app/[variants]/(main)/discover/(list)/assistant/AssistantPage.tsx +4 -1
- package/src/app/[variants]/(main)/discover/(list)/assistant/Client.tsx +6 -2
- package/src/app/[variants]/(main)/discover/(list)/assistant/features/Category/index.tsx +7 -3
- package/src/app/[variants]/(main)/discover/(list)/assistant/features/List/Item.tsx +13 -2
- package/src/app/[variants]/(main)/discover/(list)/assistant/features/MarketSourceSwitch.tsx +64 -0
- package/src/app/[variants]/(main)/discover/(list)/features/SortButton/index.tsx +26 -7
- package/src/app/[variants]/(main)/profile/_layout/Desktop/index.tsx +10 -10
- package/src/app/[variants]/(main)/settings/_layout/type.ts +1 -1
- package/src/app/[variants]/(main)/settings/agent/index.tsx +11 -10
- package/src/app/[variants]/(main)/settings/common/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/page.tsx +13 -10
- package/src/app/[variants]/(main)/settings/provider/ProviderMenu/Item.tsx +35 -36
- package/src/app/[variants]/(main)/settings/provider/ProviderMenu/SearchResult.tsx +5 -5
- package/src/app/[variants]/(main)/settings/provider/_layout/Desktop/Container.tsx +10 -4
- package/src/app/market-auth-callback/layout.tsx +15 -0
- package/src/app/market-auth-callback/page.tsx +196 -0
- package/src/features/AgentSetting/AgentPrompt/TokenTag.tsx +3 -2
- package/src/features/AgentSetting/AgentTTS/SelectWithTTSPreview.tsx +1 -1
- package/src/features/AgentSetting/store/action.ts +1 -1
- package/src/features/ChatInput/ActionBar/STT/browser.tsx +1 -1
- package/src/features/ChatInput/ActionBar/STT/openai.tsx +1 -1
- package/src/features/Conversation/components/Extras/TTS/InitPlayer.tsx +1 -1
- package/src/features/PluginTag/PluginStatus.tsx +1 -1
- package/src/hooks/useAgentOwnershipCheck.ts +143 -0
- package/src/instrumentation.node.ts +3 -2
- package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +364 -0
- package/src/layout/AuthProvider/MarketAuth/errors.ts +75 -0
- package/src/layout/AuthProvider/MarketAuth/index.ts +2 -0
- package/src/layout/AuthProvider/MarketAuth/oidc.ts +382 -0
- package/src/layout/AuthProvider/MarketAuth/types.ts +64 -0
- package/src/layout/AuthProvider/index.tsx +17 -4
- package/src/locales/default/discover.ts +46 -0
- package/src/locales/default/index.ts +2 -0
- package/src/locales/default/marketAuth.ts +42 -0
- package/src/locales/default/setting.ts +94 -1
- package/src/server/globalConfig/genServerAiProviderConfig.test.ts +5 -5
- package/src/server/globalConfig/genServerAiProviderConfig.ts +1 -1
- package/src/server/routers/lambda/market/index.ts +36 -14
- package/src/server/routers/lambda/message.ts +2 -2
- package/src/server/services/discover/index.test.ts +153 -11
- package/src/server/services/discover/index.ts +339 -40
- package/src/server/sitemap.ts +49 -35
- package/src/services/_url.ts +15 -1
- package/src/services/chat/chat.test.ts +5 -5
- package/src/services/chat/clientModelRuntime.test.ts +1 -1
- package/src/services/chat/index.ts +6 -6
- package/src/services/chat/types.ts +1 -2
- package/src/services/discover.ts +16 -5
- package/src/services/electron/remoteServer.ts +8 -1
- package/src/services/marketApi.ts +124 -0
- package/src/services/models.ts +2 -1
- package/src/store/discover/slices/assistant/action.ts +20 -7
- package/{packages/utils/src → src/utils}/electron/desktopRemoteRPCFetch.ts +1 -1
- package/{packages/utils/src → src/utils/server}/parseModels.ts +1 -2
- package/vitest.config.mts +2 -0
- package/packages/model-runtime/src/utils/imageToBase64.test.ts +0 -91
- package/packages/model-runtime/src/utils/imageToBase64.ts +0 -62
- package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +0 -98
- package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/index.tsx +0 -35
- package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/style.ts +0 -47
- /package/packages/{utils/src/fetch → fetch-sse/src}/headers.ts +0 -0
- /package/packages/{utils/src/fetch → fetch-sse/src}/index.ts +0 -0
- /package/packages/{utils/src/fetch → fetch-sse/src}/request.ts +0 -0
- /package/{packages/utils/src → src/utils/server}/__snapshots__/parseModels.test.ts.snap +0 -0
- /package/{packages/utils/src → src/utils/server}/parseModels.test.ts +0 -0
|
@@ -27,7 +27,7 @@ vi.stubGlobal(
|
|
|
27
27
|
);
|
|
28
28
|
|
|
29
29
|
// Mock image processing utilities
|
|
30
|
-
vi.mock('
|
|
30
|
+
vi.mock('@lobechat/fetch-sse', async (importOriginal) => {
|
|
31
31
|
const module = await importOriginal();
|
|
32
32
|
|
|
33
33
|
return { ...(module as any), getMessageError: vi.fn() };
|
|
@@ -988,7 +988,7 @@ describe('ChatService', () => {
|
|
|
988
988
|
|
|
989
989
|
beforeEach(async () => {
|
|
990
990
|
// Setup common fetchSSE mock for getChatCompletion tests
|
|
991
|
-
const { fetchSSE } = await import('
|
|
991
|
+
const { fetchSSE } = await import('@lobechat/fetch-sse');
|
|
992
992
|
mockFetchSSE = vi.fn().mockResolvedValue(new Response('mock response'));
|
|
993
993
|
vi.mocked(fetchSSE).mockImplementation(mockFetchSSE);
|
|
994
994
|
});
|
|
@@ -1049,7 +1049,7 @@ describe('ChatService', () => {
|
|
|
1049
1049
|
|
|
1050
1050
|
it('should return InvalidAccessCode error when enableFetchOnClient is true and auth is enabled but user is not signed in', async () => {
|
|
1051
1051
|
// Mock fetchSSE to call onErrorHandle with the error
|
|
1052
|
-
const { fetchSSE } = await import('
|
|
1052
|
+
const { fetchSSE } = await import('@lobechat/fetch-sse');
|
|
1053
1053
|
|
|
1054
1054
|
const mockFetchSSEWithError = vi.fn().mockImplementation((url, options) => {
|
|
1055
1055
|
// Simulate the error being caught and passed to onErrorHandle
|
|
@@ -1211,8 +1211,8 @@ vi.mock('../_auth', async (importOriginal) => {
|
|
|
1211
1211
|
describe('ChatService private methods', () => {
|
|
1212
1212
|
describe('getChatCompletion', () => {
|
|
1213
1213
|
it('should merge responseAnimation styles correctly', async () => {
|
|
1214
|
-
const { fetchSSE } = await import('
|
|
1215
|
-
vi.mock('
|
|
1214
|
+
const { fetchSSE } = await import('@lobechat/fetch-sse');
|
|
1215
|
+
vi.mock('@lobechat/fetch-sse', async (importOriginal) => {
|
|
1216
1216
|
const module = await importOriginal();
|
|
1217
1217
|
return {
|
|
1218
1218
|
...(module as any),
|
|
@@ -38,7 +38,7 @@ vi.stubGlobal(
|
|
|
38
38
|
vi.fn(() => Promise.resolve(new Response(JSON.stringify({ some: 'data' })))),
|
|
39
39
|
);
|
|
40
40
|
|
|
41
|
-
vi.mock('
|
|
41
|
+
vi.mock('@lobechat/fetch-sse', async (importOriginal) => {
|
|
42
42
|
const module = await importOriginal();
|
|
43
43
|
|
|
44
44
|
return { ...(module as any), getMessageError: vi.fn() };
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FetchSSEOptions,
|
|
3
|
+
fetchSSE,
|
|
4
|
+
getMessageError,
|
|
5
|
+
standardizeAnimationStyle,
|
|
6
|
+
} from '@lobechat/fetch-sse';
|
|
1
7
|
import { AgentRuntimeError, ChatCompletionErrorPayload } from '@lobechat/model-runtime';
|
|
2
8
|
import { ChatErrorType, TracePayload, TraceTagMap, UIChatMessage } from '@lobechat/types';
|
|
3
9
|
import { PluginRequestPayload, createHeadersWithPluginSettings } from '@lobehub/chat-plugin-sdk';
|
|
@@ -25,12 +31,6 @@ import {
|
|
|
25
31
|
import type { ChatStreamPayload, OpenAIChatMessage } from '@/types/openai/chat';
|
|
26
32
|
import { fetchWithInvokeStream } from '@/utils/electron/desktopRemoteRPCFetch';
|
|
27
33
|
import { createErrorResponse } from '@/utils/errorResponse';
|
|
28
|
-
import {
|
|
29
|
-
FetchSSEOptions,
|
|
30
|
-
fetchSSE,
|
|
31
|
-
getMessageError,
|
|
32
|
-
standardizeAnimationStyle,
|
|
33
|
-
} from '@/utils/fetch';
|
|
34
34
|
import { createTraceHeader, getTraceId } from '@/utils/trace';
|
|
35
35
|
|
|
36
36
|
import { createHeaderWithAuth } from '../_auth';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { FetchSSEOptions } from '@lobechat/fetch-sse';
|
|
1
2
|
import { TracePayload } from '@lobechat/types';
|
|
2
3
|
|
|
3
|
-
import { FetchSSEOptions } from '@/utils/fetch';
|
|
4
|
-
|
|
5
4
|
export interface FetchOptions extends FetchSSEOptions {
|
|
6
5
|
historySummary?: string;
|
|
7
6
|
signal?: AbortSignal | undefined;
|
package/src/services/discover.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { useUserStore } from '@/store/user';
|
|
|
7
7
|
import { preferenceSelectors } from '@/store/user/selectors';
|
|
8
8
|
import {
|
|
9
9
|
AssistantListResponse,
|
|
10
|
+
AssistantMarketSource,
|
|
10
11
|
AssistantQueryParams,
|
|
11
12
|
DiscoverAssistantDetail,
|
|
12
13
|
DiscoverMcpDetail,
|
|
@@ -30,27 +31,37 @@ class DiscoverService {
|
|
|
30
31
|
private _isRetrying = false;
|
|
31
32
|
|
|
32
33
|
// ============================== Assistant Market ==============================
|
|
33
|
-
getAssistantCategories = async (
|
|
34
|
+
getAssistantCategories = async (
|
|
35
|
+
params: CategoryListQuery & { source?: AssistantMarketSource } = {},
|
|
36
|
+
): Promise<CategoryItem[]> => {
|
|
34
37
|
const locale = globalHelpers.getCurrentLanguage();
|
|
38
|
+
const { source, ...rest } = params;
|
|
35
39
|
return lambdaClient.market.getAssistantCategories.query({
|
|
36
|
-
...
|
|
40
|
+
...rest,
|
|
37
41
|
locale,
|
|
42
|
+
source,
|
|
38
43
|
});
|
|
39
44
|
};
|
|
40
45
|
|
|
41
46
|
getAssistantDetail = async (params: {
|
|
42
47
|
identifier: string;
|
|
43
48
|
locale?: string;
|
|
49
|
+
source?: AssistantMarketSource;
|
|
50
|
+
version?: string;
|
|
44
51
|
}): Promise<DiscoverAssistantDetail | undefined> => {
|
|
45
52
|
const locale = globalHelpers.getCurrentLanguage();
|
|
46
53
|
return lambdaClient.market.getAssistantDetail.query({
|
|
47
|
-
|
|
54
|
+
identifier: params.identifier,
|
|
48
55
|
locale,
|
|
56
|
+
source: params.source,
|
|
57
|
+
version: params.version,
|
|
49
58
|
});
|
|
50
59
|
};
|
|
51
60
|
|
|
52
|
-
getAssistantIdentifiers = async (
|
|
53
|
-
|
|
61
|
+
getAssistantIdentifiers = async (
|
|
62
|
+
params: { source?: AssistantMarketSource } = {},
|
|
63
|
+
): Promise<IdentifiersResponse> => {
|
|
64
|
+
return lambdaClient.market.getAssistantIdentifiers.query(params);
|
|
54
65
|
};
|
|
55
66
|
|
|
56
67
|
getAssistantList = async (params: AssistantQueryParams = {}): Promise<AssistantListResponse> => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DataSyncConfig, dispatch } from '@lobechat/electron-client-ipc';
|
|
1
|
+
import { DataSyncConfig, MarketAuthorizationParams, dispatch } from '@lobechat/electron-client-ipc';
|
|
2
2
|
|
|
3
3
|
class RemoteServerService {
|
|
4
4
|
/**
|
|
@@ -28,6 +28,13 @@ class RemoteServerService {
|
|
|
28
28
|
requestAuthorization = async (config: DataSyncConfig) => {
|
|
29
29
|
return dispatch('requestAuthorization', config);
|
|
30
30
|
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 请求 Market 授权
|
|
34
|
+
*/
|
|
35
|
+
requestMarketAuthorization = async (params: MarketAuthorizationParams) => {
|
|
36
|
+
return dispatch('requestMarketAuthorization', params);
|
|
37
|
+
};
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
export const remoteServerService = new RemoteServerService();
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { AgentItemDetail } from '@lobehub/market-sdk';
|
|
2
|
+
|
|
3
|
+
import { MARKET_ENDPOINTS } from '@/services/_url';
|
|
4
|
+
|
|
5
|
+
export class MarketApiService {
|
|
6
|
+
private accessToken?: string;
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
private async request<T>(endpoint: string, init?: RequestInit): Promise<T> {
|
|
10
|
+
const headers = new Headers(init?.headers);
|
|
11
|
+
|
|
12
|
+
if (init?.body && !headers.has('content-type')) {
|
|
13
|
+
headers.set('content-type', 'application/json');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (this.accessToken && !headers.has('authorization')) {
|
|
17
|
+
headers.set('authorization', `Bearer ${this.accessToken}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const response = await fetch(endpoint, {
|
|
21
|
+
...init,
|
|
22
|
+
credentials: init?.credentials ?? 'same-origin',
|
|
23
|
+
headers,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (!response.ok) {
|
|
27
|
+
let message = 'Unknown error';
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const errorBody = await response.json();
|
|
31
|
+
message = errorBody?.message ?? message;
|
|
32
|
+
} catch {
|
|
33
|
+
message = await response.text();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
throw new Error(message || 'Market request failed');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (response.status === 204) {
|
|
40
|
+
return undefined as T;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (await response.json()) as T;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setAccessToken(token: string) {
|
|
47
|
+
this.accessToken = token;
|
|
48
|
+
}
|
|
49
|
+
// Create new agent
|
|
50
|
+
async createAgent(agentData: {
|
|
51
|
+
homepage?: string;
|
|
52
|
+
identifier: string;
|
|
53
|
+
isFeatured?: boolean;
|
|
54
|
+
name: string;
|
|
55
|
+
status?: 'published' | 'unpublished' | 'archived' | 'deprecated';
|
|
56
|
+
tokenUsage?: number;
|
|
57
|
+
visibility?: 'public' | 'private' | 'internal';
|
|
58
|
+
}): Promise<AgentItemDetail> {
|
|
59
|
+
return this.request(MARKET_ENDPOINTS.createAgent, {
|
|
60
|
+
body: JSON.stringify(agentData),
|
|
61
|
+
method: 'POST',
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Get agent detail by identifier
|
|
66
|
+
async getAgentDetail(identifier: string): Promise<AgentItemDetail> {
|
|
67
|
+
return this.request(MARKET_ENDPOINTS.getAgentDetail(identifier), {
|
|
68
|
+
method: 'GET',
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Check if agent exists (returns true if exists, false if not)
|
|
73
|
+
async checkAgentExists(identifier: string): Promise<boolean> {
|
|
74
|
+
try {
|
|
75
|
+
await this.getAgentDetail(identifier);
|
|
76
|
+
return true;
|
|
77
|
+
} catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Create agent version
|
|
83
|
+
async createAgentVersion(versionData: {
|
|
84
|
+
a2aProtocolVersion?: string;
|
|
85
|
+
avatar?: string;
|
|
86
|
+
category?: string;
|
|
87
|
+
changelog?: string;
|
|
88
|
+
config?: Record<string, any>;
|
|
89
|
+
defaultInputModes?: string[];
|
|
90
|
+
defaultOutputModes?: string[];
|
|
91
|
+
description?: string;
|
|
92
|
+
documentationUrl?: string;
|
|
93
|
+
extensions?: Record<string, any>[];
|
|
94
|
+
hasPushNotifications?: boolean;
|
|
95
|
+
hasStateTransitionHistory?: boolean;
|
|
96
|
+
hasStreaming?: boolean;
|
|
97
|
+
identifier: string;
|
|
98
|
+
interfaces?: Record<string, any>[];
|
|
99
|
+
name?: string;
|
|
100
|
+
preferredTransport?: string;
|
|
101
|
+
providerId?: number;
|
|
102
|
+
securityRequirements?: Record<string, any>[];
|
|
103
|
+
securitySchemes?: Record<string, any>;
|
|
104
|
+
setAsCurrent?: boolean;
|
|
105
|
+
summary?: string;
|
|
106
|
+
supportsAuthenticatedExtendedCard?: boolean;
|
|
107
|
+
tokenUsage?: number;
|
|
108
|
+
url?: string;
|
|
109
|
+
}): Promise<AgentItemDetail> {
|
|
110
|
+
const { identifier, ...rest } = versionData;
|
|
111
|
+
const targetIdentifier = identifier;
|
|
112
|
+
if (!targetIdentifier) throw new Error('Identifier is required');
|
|
113
|
+
|
|
114
|
+
return this.request(MARKET_ENDPOINTS.createAgentVersion, {
|
|
115
|
+
body: JSON.stringify({
|
|
116
|
+
identifier: targetIdentifier,
|
|
117
|
+
...rest,
|
|
118
|
+
}),
|
|
119
|
+
method: 'POST',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export const marketApiService = new MarketApiService();
|
package/src/services/models.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { getMessageError } from '@lobechat/fetch-sse';
|
|
2
|
+
|
|
1
3
|
import { createHeaderWithAuth } from '@/services/_auth';
|
|
2
4
|
import { aiProviderSelectors, getAiInfraStoreState } from '@/store/aiInfra';
|
|
3
5
|
import { ChatModelCard } from '@/types/llm';
|
|
4
|
-
import { getMessageError } from '@/utils/fetch';
|
|
5
6
|
|
|
6
7
|
import { API_ENDPOINTS } from './_url';
|
|
7
8
|
import { initializeWithClientStore } from './chat/clientModelRuntime';
|
|
@@ -7,17 +7,24 @@ import { DiscoverStore } from '@/store/discover';
|
|
|
7
7
|
import { globalHelpers } from '@/store/global/helpers';
|
|
8
8
|
import {
|
|
9
9
|
AssistantListResponse,
|
|
10
|
+
AssistantMarketSource,
|
|
10
11
|
AssistantQueryParams,
|
|
11
12
|
DiscoverAssistantDetail,
|
|
12
13
|
IdentifiersResponse,
|
|
13
14
|
} from '@/types/discover';
|
|
14
15
|
|
|
15
16
|
export interface AssistantAction {
|
|
16
|
-
useAssistantCategories: (
|
|
17
|
+
useAssistantCategories: (
|
|
18
|
+
params: CategoryListQuery & { source?: AssistantMarketSource },
|
|
19
|
+
) => SWRResponse<CategoryItem[]>;
|
|
17
20
|
useAssistantDetail: (params: {
|
|
18
21
|
identifier: string;
|
|
22
|
+
source?: AssistantMarketSource;
|
|
23
|
+
version?: string;
|
|
19
24
|
}) => SWRResponse<DiscoverAssistantDetail | undefined>;
|
|
20
|
-
useAssistantIdentifiers: (
|
|
25
|
+
useAssistantIdentifiers: (params?: {
|
|
26
|
+
source?: AssistantMarketSource;
|
|
27
|
+
}) => SWRResponse<IdentifiersResponse>;
|
|
21
28
|
useAssistantList: (params?: AssistantQueryParams) => SWRResponse<AssistantListResponse>;
|
|
22
29
|
}
|
|
23
30
|
|
|
@@ -41,7 +48,9 @@ export const createAssistantSlice: StateCreator<
|
|
|
41
48
|
useAssistantDetail: (params) => {
|
|
42
49
|
const locale = globalHelpers.getCurrentLanguage();
|
|
43
50
|
return useSWR(
|
|
44
|
-
['assistant-details', locale, params.identifier
|
|
51
|
+
['assistant-details', locale, params.identifier, params.version, params.source]
|
|
52
|
+
.filter(Boolean)
|
|
53
|
+
.join('-'),
|
|
45
54
|
async () => discoverService.getAssistantDetail(params),
|
|
46
55
|
{
|
|
47
56
|
revalidateOnFocus: false,
|
|
@@ -49,10 +58,14 @@ export const createAssistantSlice: StateCreator<
|
|
|
49
58
|
);
|
|
50
59
|
},
|
|
51
60
|
|
|
52
|
-
useAssistantIdentifiers: () => {
|
|
53
|
-
return useSWR(
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
useAssistantIdentifiers: (params) => {
|
|
62
|
+
return useSWR(
|
|
63
|
+
['assistant-identifiers', params?.source].filter(Boolean).join('-') || 'assistant-identifiers',
|
|
64
|
+
async () => discoverService.getAssistantIdentifiers(params),
|
|
65
|
+
{
|
|
66
|
+
revalidateOnFocus: false,
|
|
67
|
+
},
|
|
68
|
+
);
|
|
56
69
|
},
|
|
57
70
|
|
|
58
71
|
useAssistantList: (params = {}) => {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { isDesktop } from '@lobechat/const';
|
|
2
2
|
import { ProxyTRPCRequestParams, dispatch, streamInvoke } from '@lobechat/electron-client-ipc';
|
|
3
|
+
import { getRequestBody, headersToRecord } from '@lobechat/fetch-sse';
|
|
3
4
|
import debug from 'debug';
|
|
4
5
|
|
|
5
6
|
import { getElectronStoreState } from '@/store/electron';
|
|
6
7
|
import { electronSyncSelectors } from '@/store/electron/selectors';
|
|
7
|
-
import { getRequestBody, headersToRecord } from '@/utils/fetch';
|
|
8
8
|
|
|
9
9
|
const log = debug('utils:desktopRemoteRPCFetch');
|
|
10
10
|
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { getModelPropertyWithFallback } from '@lobechat/model-runtime';
|
|
2
|
+
import { merge } from '@lobechat/utils';
|
|
2
3
|
import { produce } from 'immer';
|
|
3
4
|
import { AiFullModelCard, AiModelType } from 'model-bank';
|
|
4
5
|
|
|
5
|
-
import { merge } from './merge';
|
|
6
|
-
|
|
7
6
|
/**
|
|
8
7
|
* Parse model string to add or remove models.
|
|
9
8
|
*/
|
package/vitest.config.mts
CHANGED
|
@@ -16,6 +16,8 @@ export default defineConfig({
|
|
|
16
16
|
// TODO: after refactor the errorResponse, we can remove it
|
|
17
17
|
'@/utils/errorResponse': resolve(__dirname, './src/utils/errorResponse'),
|
|
18
18
|
'@/utils/unzipFile': resolve(__dirname, './src/utils/unzipFile'),
|
|
19
|
+
'@/utils/server': resolve(__dirname, './src/utils/server'),
|
|
20
|
+
'@/utils/electron': resolve(__dirname, './src/utils/electron'),
|
|
19
21
|
'@/utils': resolve(__dirname, './packages/utils/src'),
|
|
20
22
|
'@/types': resolve(__dirname, './packages/types/src'),
|
|
21
23
|
'@/const': resolve(__dirname, './packages/const/src'),
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { imageToBase64, imageUrlToBase64 } from './imageToBase64';
|
|
4
|
-
|
|
5
|
-
describe('imageToBase64', () => {
|
|
6
|
-
let mockImage: HTMLImageElement;
|
|
7
|
-
let mockCanvas: HTMLCanvasElement;
|
|
8
|
-
let mockContext: CanvasRenderingContext2D;
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
mockImage = {
|
|
12
|
-
width: 200,
|
|
13
|
-
height: 100,
|
|
14
|
-
} as HTMLImageElement;
|
|
15
|
-
|
|
16
|
-
mockContext = {
|
|
17
|
-
drawImage: vi.fn(),
|
|
18
|
-
} as unknown as CanvasRenderingContext2D;
|
|
19
|
-
|
|
20
|
-
mockCanvas = {
|
|
21
|
-
width: 0,
|
|
22
|
-
height: 0,
|
|
23
|
-
getContext: vi.fn().mockReturnValue(mockContext),
|
|
24
|
-
toDataURL: vi.fn().mockReturnValue('data:image/webp;base64,mockBase64Data'),
|
|
25
|
-
} as unknown as HTMLCanvasElement;
|
|
26
|
-
|
|
27
|
-
vi.spyOn(document, 'createElement').mockReturnValue(mockCanvas);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
afterEach(() => {
|
|
31
|
-
vi.restoreAllMocks();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('should convert image to base64 with correct size and type', () => {
|
|
35
|
-
const result = imageToBase64({ img: mockImage, size: 100, type: 'image/jpeg' });
|
|
36
|
-
|
|
37
|
-
expect(document.createElement).toHaveBeenCalledWith('canvas');
|
|
38
|
-
expect(mockCanvas.width).toBe(100);
|
|
39
|
-
expect(mockCanvas.height).toBe(100);
|
|
40
|
-
expect(mockCanvas.getContext).toHaveBeenCalledWith('2d');
|
|
41
|
-
expect(mockContext.drawImage).toHaveBeenCalledWith(mockImage, 50, 0, 100, 100, 0, 0, 100, 100);
|
|
42
|
-
expect(mockCanvas.toDataURL).toHaveBeenCalledWith('image/jpeg');
|
|
43
|
-
expect(result).toBe('data:image/webp;base64,mockBase64Data');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should use default type when not specified', () => {
|
|
47
|
-
imageToBase64({ img: mockImage, size: 100 });
|
|
48
|
-
expect(mockCanvas.toDataURL).toHaveBeenCalledWith('image/webp');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should handle taller images correctly', () => {
|
|
52
|
-
mockImage.width = 100;
|
|
53
|
-
mockImage.height = 200;
|
|
54
|
-
imageToBase64({ img: mockImage, size: 100 });
|
|
55
|
-
expect(mockContext.drawImage).toHaveBeenCalledWith(mockImage, 0, 50, 100, 100, 0, 0, 100, 100);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe('imageUrlToBase64', () => {
|
|
60
|
-
const mockFetch = vi.fn();
|
|
61
|
-
const mockArrayBuffer = new ArrayBuffer(8);
|
|
62
|
-
|
|
63
|
-
beforeEach(() => {
|
|
64
|
-
global.fetch = mockFetch;
|
|
65
|
-
global.btoa = vi.fn().mockReturnValue('mockBase64String');
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
afterEach(() => {
|
|
69
|
-
vi.restoreAllMocks();
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('should convert image URL to base64 string', async () => {
|
|
73
|
-
mockFetch.mockResolvedValue({
|
|
74
|
-
arrayBuffer: () => Promise.resolve(mockArrayBuffer),
|
|
75
|
-
blob: () => Promise.resolve(new Blob([mockArrayBuffer], { type: 'image/jpg' })),
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
const result = await imageUrlToBase64('https://example.com/image.jpg');
|
|
79
|
-
|
|
80
|
-
expect(mockFetch).toHaveBeenCalledWith('https://example.com/image.jpg');
|
|
81
|
-
expect(global.btoa).toHaveBeenCalled();
|
|
82
|
-
expect(result).toEqual({ base64: 'mockBase64String', mimeType: 'image/jpg' });
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('should throw an error when fetch fails', async () => {
|
|
86
|
-
const mockError = new Error('Fetch failed');
|
|
87
|
-
mockFetch.mockRejectedValue(mockError);
|
|
88
|
-
|
|
89
|
-
await expect(imageUrlToBase64('https://example.com/image.jpg')).rejects.toThrow('Fetch failed');
|
|
90
|
-
});
|
|
91
|
-
});
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
export const imageToBase64 = ({
|
|
2
|
-
size,
|
|
3
|
-
img,
|
|
4
|
-
type = 'image/webp',
|
|
5
|
-
}: {
|
|
6
|
-
img: HTMLImageElement;
|
|
7
|
-
size: number;
|
|
8
|
-
type?: string;
|
|
9
|
-
}) => {
|
|
10
|
-
const canvas = document.createElement('canvas');
|
|
11
|
-
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
|
|
12
|
-
let startX = 0;
|
|
13
|
-
let startY = 0;
|
|
14
|
-
|
|
15
|
-
if (img.width > img.height) {
|
|
16
|
-
startX = (img.width - img.height) / 2;
|
|
17
|
-
} else {
|
|
18
|
-
startY = (img.height - img.width) / 2;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
canvas.width = size;
|
|
22
|
-
canvas.height = size;
|
|
23
|
-
|
|
24
|
-
ctx.drawImage(
|
|
25
|
-
img,
|
|
26
|
-
startX,
|
|
27
|
-
startY,
|
|
28
|
-
Math.min(img.width, img.height),
|
|
29
|
-
Math.min(img.width, img.height),
|
|
30
|
-
0,
|
|
31
|
-
0,
|
|
32
|
-
size,
|
|
33
|
-
size,
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
return canvas.toDataURL(type);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export const imageUrlToBase64 = async (
|
|
40
|
-
imageUrl: string,
|
|
41
|
-
): Promise<{ base64: string; mimeType: string }> => {
|
|
42
|
-
try {
|
|
43
|
-
const res = await fetch(imageUrl);
|
|
44
|
-
const blob = await res.blob();
|
|
45
|
-
const arrayBuffer = await blob.arrayBuffer();
|
|
46
|
-
|
|
47
|
-
const base64 =
|
|
48
|
-
typeof btoa === 'function'
|
|
49
|
-
? btoa(
|
|
50
|
-
new Uint8Array(arrayBuffer).reduce(
|
|
51
|
-
(data, byte) => data + String.fromCharCode(byte),
|
|
52
|
-
'',
|
|
53
|
-
),
|
|
54
|
-
)
|
|
55
|
-
: Buffer.from(arrayBuffer).toString('base64');
|
|
56
|
-
|
|
57
|
-
return { base64, mimeType: blob.type };
|
|
58
|
-
} catch (error) {
|
|
59
|
-
console.error('Error converting image to base64:', error);
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
|
-
};
|
package/src/app/[variants]/(main)/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { Alert, Button, Input, Modal, type ModalProps } from '@lobehub/ui';
|
|
4
|
-
import { Divider } from 'antd';
|
|
5
|
-
import { useTheme } from 'antd-style';
|
|
6
|
-
import isEqual from 'fast-deep-equal';
|
|
7
|
-
import { kebabCase } from 'lodash-es';
|
|
8
|
-
import qs from 'query-string';
|
|
9
|
-
import { memo, useState } from 'react';
|
|
10
|
-
import { useTranslation } from 'react-i18next';
|
|
11
|
-
import { Flexbox } from 'react-layout-kit';
|
|
12
|
-
|
|
13
|
-
import { AGENTS_INDEX_GITHUB_ISSUE } from '@/const/url';
|
|
14
|
-
import AgentInfo from '@/features/AgentInfo';
|
|
15
|
-
import { useAgentStore } from '@/store/agent';
|
|
16
|
-
import { agentSelectors } from '@/store/agent/selectors';
|
|
17
|
-
import { useGlobalStore } from '@/store/global';
|
|
18
|
-
import { globalGeneralSelectors } from '@/store/global/selectors';
|
|
19
|
-
import { useSessionStore } from '@/store/session';
|
|
20
|
-
import { sessionMetaSelectors } from '@/store/session/selectors';
|
|
21
|
-
|
|
22
|
-
const SubmitAgentModal = memo<ModalProps>(({ open, onCancel }) => {
|
|
23
|
-
const { t } = useTranslation('setting');
|
|
24
|
-
const [identifier, setIdentifier] = useState('');
|
|
25
|
-
const systemRole = useAgentStore(agentSelectors.currentAgentSystemRole);
|
|
26
|
-
const theme = useTheme();
|
|
27
|
-
const meta = useSessionStore(sessionMetaSelectors.currentAgentMeta, isEqual);
|
|
28
|
-
const language = useGlobalStore(globalGeneralSelectors.currentLanguage);
|
|
29
|
-
|
|
30
|
-
const isMetaPass = Boolean(
|
|
31
|
-
meta && meta.title && meta.description && (meta.tags as string[])?.length > 0 && meta.avatar,
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
const handleSubmit = () => {
|
|
35
|
-
const body = [
|
|
36
|
-
'### systemRole',
|
|
37
|
-
systemRole,
|
|
38
|
-
'### identifier',
|
|
39
|
-
kebabCase(identifier),
|
|
40
|
-
'### avatar',
|
|
41
|
-
meta.avatar,
|
|
42
|
-
'### title',
|
|
43
|
-
meta.title,
|
|
44
|
-
'### description',
|
|
45
|
-
meta.description,
|
|
46
|
-
'### tags',
|
|
47
|
-
(meta.tags as string[]).join(', '),
|
|
48
|
-
'### locale',
|
|
49
|
-
language,
|
|
50
|
-
].join('\n\n');
|
|
51
|
-
|
|
52
|
-
const url = qs.stringifyUrl({
|
|
53
|
-
query: { body, labels: '🤖 Agent PR', title: `[Agent] ${meta.title}` },
|
|
54
|
-
url: AGENTS_INDEX_GITHUB_ISSUE,
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
window.open(url, '_blank');
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<Modal
|
|
62
|
-
allowFullscreen
|
|
63
|
-
footer={
|
|
64
|
-
<Button
|
|
65
|
-
block
|
|
66
|
-
disabled={!isMetaPass || !identifier}
|
|
67
|
-
onClick={handleSubmit}
|
|
68
|
-
size={'large'}
|
|
69
|
-
type={'primary'}
|
|
70
|
-
>
|
|
71
|
-
{t('submitAgentModal.button')}
|
|
72
|
-
</Button>
|
|
73
|
-
}
|
|
74
|
-
onCancel={onCancel}
|
|
75
|
-
open={open}
|
|
76
|
-
title={t('submitAgentModal.tooltips')}
|
|
77
|
-
>
|
|
78
|
-
<Flexbox gap={16}>
|
|
79
|
-
{!isMetaPass && (
|
|
80
|
-
<Alert message={t('submitAgentModal.metaMiss')} showIcon type={'warning'} />
|
|
81
|
-
)}
|
|
82
|
-
<AgentInfo meta={meta} systemRole={systemRole} />
|
|
83
|
-
<Divider style={{ margin: '8px 0' }} />
|
|
84
|
-
<strong>
|
|
85
|
-
<span style={{ color: theme.colorError, marginRight: 4 }}>*</span>
|
|
86
|
-
{t('submitAgentModal.identifier')}
|
|
87
|
-
</strong>
|
|
88
|
-
<Input
|
|
89
|
-
onChange={(e) => setIdentifier(e.target.value)}
|
|
90
|
-
placeholder={t('submitAgentModal.placeholder')}
|
|
91
|
-
value={identifier}
|
|
92
|
-
/>
|
|
93
|
-
</Flexbox>
|
|
94
|
-
</Modal>
|
|
95
|
-
);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
export default SubmitAgentModal;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { ActionIcon, Button } from '@lobehub/ui';
|
|
2
|
-
import { Share2 } from 'lucide-react';
|
|
3
|
-
import { memo, useState } from 'react';
|
|
4
|
-
import { useTranslation } from 'react-i18next';
|
|
5
|
-
|
|
6
|
-
import { HEADER_ICON_SIZE } from '@/const/layoutTokens';
|
|
7
|
-
import { useServerConfigStore } from '@/store/serverConfig';
|
|
8
|
-
|
|
9
|
-
import SubmitAgentModal from './SubmitAgentModal';
|
|
10
|
-
|
|
11
|
-
const SubmitAgentButton = memo<{ modal?: boolean }>(({ modal }) => {
|
|
12
|
-
const { t } = useTranslation('setting');
|
|
13
|
-
const mobile = useServerConfigStore((s) => s.isMobile);
|
|
14
|
-
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<>
|
|
18
|
-
{modal ? (
|
|
19
|
-
<Button block icon={Share2} onClick={() => setIsModalOpen(true)} variant={'filled'}>
|
|
20
|
-
{t('submitAgentModal.tooltips')}
|
|
21
|
-
</Button>
|
|
22
|
-
) : (
|
|
23
|
-
<ActionIcon
|
|
24
|
-
icon={Share2}
|
|
25
|
-
onClick={() => setIsModalOpen(true)}
|
|
26
|
-
size={HEADER_ICON_SIZE(mobile)}
|
|
27
|
-
title={t('submitAgentModal.tooltips')}
|
|
28
|
-
/>
|
|
29
|
-
)}
|
|
30
|
-
<SubmitAgentModal onCancel={() => setIsModalOpen(false)} open={isModalOpen} />
|
|
31
|
-
</>
|
|
32
|
-
);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
export default SubmitAgentButton;
|