@lobehub/lobehub 2.0.0-next.310 → 2.0.0-next.311
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/.github/PULL_REQUEST_TEMPLATE.md +1 -1
- package/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/docs/development/basic/chat-api.mdx +0 -1
- package/docs/development/basic/chat-api.zh-CN.mdx +0 -1
- package/package.json +1 -1
- package/packages/model-runtime/src/core/BaseAI.ts +0 -2
- package/packages/model-runtime/src/core/ModelRuntime.test.ts +0 -37
- package/packages/model-runtime/src/core/ModelRuntime.ts +0 -5
- package/packages/model-runtime/src/core/RouterRuntime/baseRuntimeMap.ts +4 -0
- package/packages/model-runtime/src/core/RouterRuntime/createRuntime.test.ts +325 -200
- package/packages/model-runtime/src/core/RouterRuntime/createRuntime.ts +205 -64
- package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +0 -14
- package/packages/model-runtime/src/providers/aihubmix/index.test.ts +14 -20
- package/packages/model-runtime/src/types/index.ts +0 -1
- package/packages/model-runtime/src/utils/createError.test.ts +0 -20
- package/packages/model-runtime/src/utils/createError.ts +0 -1
- package/src/app/(backend)/market/agent/[[...segments]]/route.ts +3 -33
- package/src/app/(backend)/market/oidc/[[...segments]]/route.ts +5 -6
- package/src/app/(backend)/market/social/[[...segments]]/route.ts +5 -52
- package/src/app/(backend)/market/user/[username]/route.ts +3 -9
- package/src/app/(backend)/market/user/me/route.ts +3 -34
- package/src/features/ChatMiniMap/useMinimapData.ts +1 -1
- package/src/features/Conversation/ChatList/components/VirtualizedList.tsx +20 -2
- package/src/features/Conversation/store/slices/virtuaList/action.ts +9 -0
- package/src/libs/trpc/lambda/middleware/marketSDK.ts +14 -23
- package/src/libs/trusted-client/index.ts +1 -1
- package/src/server/routers/lambda/market/index.ts +5 -0
- package/src/server/routers/lambda/market/oidc.ts +41 -61
- package/src/server/routers/tools/market.ts +12 -44
- package/src/server/services/agentRuntime/AgentRuntimeService.test.ts +7 -0
- package/src/server/services/agentRuntime/AgentRuntimeService.ts +1 -1
- package/src/server/services/aiAgent/__tests__/execAgent.threadId.test.ts +7 -0
- package/src/server/services/aiAgent/__tests__/execGroupSubAgentTask.test.ts +7 -0
- package/src/server/services/aiAgent/index.ts +9 -96
- package/src/server/services/discover/index.ts +11 -16
- package/src/server/services/market/index.ts +485 -0
- package/src/server/services/toolExecution/builtin.ts +11 -17
- package/src/server/services/toolExecution/index.ts +6 -2
- package/src/services/codeInterpreter.ts +0 -13
- package/packages/model-runtime/src/types/textToImage.ts +0 -36
- package/src/server/services/lobehubSkill/index.ts +0 -109
|
@@ -152,7 +152,7 @@ export class AgentRuntimeService {
|
|
|
152
152
|
|
|
153
153
|
// Initialize ToolExecutionService with dependencies
|
|
154
154
|
const pluginGatewayService = new PluginGatewayService();
|
|
155
|
-
const builtinToolsExecutor = new BuiltinToolsExecutor();
|
|
155
|
+
const builtinToolsExecutor = new BuiltinToolsExecutor(db, userId);
|
|
156
156
|
|
|
157
157
|
this.toolExecutionService = new ToolExecutionService({
|
|
158
158
|
builtinToolsExecutor,
|
|
@@ -2,6 +2,13 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
2
2
|
|
|
3
3
|
import { AiAgentService } from '../index';
|
|
4
4
|
|
|
5
|
+
// Mock trusted client to avoid server-side env access
|
|
6
|
+
vi.mock('@/libs/trusted-client', () => ({
|
|
7
|
+
generateTrustedClientToken: vi.fn().mockReturnValue(undefined),
|
|
8
|
+
getTrustedClientTokenForSession: vi.fn().mockResolvedValue(undefined),
|
|
9
|
+
isTrustedClientEnabled: vi.fn().mockReturnValue(false),
|
|
10
|
+
}));
|
|
11
|
+
|
|
5
12
|
// Mock MessageModel to capture create calls
|
|
6
13
|
const mockMessageCreate = vi.fn();
|
|
7
14
|
|
|
@@ -3,6 +3,13 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
3
3
|
|
|
4
4
|
import { AiAgentService } from '../index';
|
|
5
5
|
|
|
6
|
+
// Mock trusted client to avoid server-side env access
|
|
7
|
+
vi.mock('@/libs/trusted-client', () => ({
|
|
8
|
+
generateTrustedClientToken: vi.fn().mockReturnValue(undefined),
|
|
9
|
+
getTrustedClientTokenForSession: vi.fn().mockResolvedValue(undefined),
|
|
10
|
+
isTrustedClientEnabled: vi.fn().mockReturnValue(false),
|
|
11
|
+
}));
|
|
12
|
+
|
|
6
13
|
// Mock ThreadModel
|
|
7
14
|
const mockThreadModel = {
|
|
8
15
|
create: vi.fn(),
|
|
@@ -11,7 +11,6 @@ import type {
|
|
|
11
11
|
} from '@lobechat/types';
|
|
12
12
|
import { ThreadStatus, ThreadType } from '@lobechat/types';
|
|
13
13
|
import { nanoid } from '@lobechat/utils';
|
|
14
|
-
import { MarketSDK } from '@lobehub/market-sdk';
|
|
15
14
|
import debug from 'debug';
|
|
16
15
|
|
|
17
16
|
import { LOADING_FLAT } from '@/const/message';
|
|
@@ -20,8 +19,6 @@ import { MessageModel } from '@/database/models/message';
|
|
|
20
19
|
import { PluginModel } from '@/database/models/plugin';
|
|
21
20
|
import { ThreadModel } from '@/database/models/thread';
|
|
22
21
|
import { TopicModel } from '@/database/models/topic';
|
|
23
|
-
import { UserModel } from '@/database/models/user';
|
|
24
|
-
import { generateTrustedClientToken } from '@/libs/trusted-client';
|
|
25
22
|
import {
|
|
26
23
|
type ServerAgentToolsContext,
|
|
27
24
|
createServerAgentToolsEngine,
|
|
@@ -30,6 +27,7 @@ import {
|
|
|
30
27
|
import { AgentService } from '@/server/services/agent';
|
|
31
28
|
import { AgentRuntimeService } from '@/server/services/agentRuntime';
|
|
32
29
|
import type { StepLifecycleCallbacks } from '@/server/services/agentRuntime/types';
|
|
30
|
+
import { MarketService } from '@/server/services/market';
|
|
33
31
|
|
|
34
32
|
const log = debug('lobe-server:ai-agent-service');
|
|
35
33
|
|
|
@@ -88,6 +86,7 @@ export class AiAgentService {
|
|
|
88
86
|
private readonly threadModel: ThreadModel;
|
|
89
87
|
private readonly topicModel: TopicModel;
|
|
90
88
|
private readonly agentRuntimeService: AgentRuntimeService;
|
|
89
|
+
private readonly marketService: MarketService;
|
|
91
90
|
|
|
92
91
|
constructor(db: LobeChatDatabase, userId: string) {
|
|
93
92
|
this.userId = userId;
|
|
@@ -99,6 +98,7 @@ export class AiAgentService {
|
|
|
99
98
|
this.threadModel = new ThreadModel(db, userId);
|
|
100
99
|
this.topicModel = new TopicModel(db, userId);
|
|
101
100
|
this.agentRuntimeService = new AgentRuntimeService(db, userId);
|
|
101
|
+
this.marketService = new MarketService({ userInfo: { userId } });
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
/**
|
|
@@ -190,7 +190,12 @@ export class AiAgentService {
|
|
|
190
190
|
};
|
|
191
191
|
|
|
192
192
|
// 5. Fetch LobeHub Skills manifests (temporary solution until LOBE-3517 is implemented)
|
|
193
|
-
|
|
193
|
+
let lobehubSkillManifests: LobeToolManifest[] = [];
|
|
194
|
+
try {
|
|
195
|
+
lobehubSkillManifests = await this.marketService.getLobehubSkillManifests();
|
|
196
|
+
} catch (error) {
|
|
197
|
+
log('execAgent: failed to fetch lobehub skill manifests: %O', error);
|
|
198
|
+
}
|
|
194
199
|
log('execAgent: got %d lobehub skill manifests', lobehubSkillManifests.length);
|
|
195
200
|
|
|
196
201
|
// 6. Create tools using Server AgentToolsEngine
|
|
@@ -736,98 +741,6 @@ export class AiAgentService {
|
|
|
736
741
|
};
|
|
737
742
|
}
|
|
738
743
|
|
|
739
|
-
/**
|
|
740
|
-
* Fetch LobeHub Skills manifests from Market API
|
|
741
|
-
* This is a temporary solution until LOBE-3517 is implemented (store skills in DB)
|
|
742
|
-
*/
|
|
743
|
-
private async fetchLobehubSkillManifests(): Promise<LobeToolManifest[]> {
|
|
744
|
-
try {
|
|
745
|
-
// 1. Get user info for trusted client token
|
|
746
|
-
const user = await UserModel.findById(this.db, this.userId);
|
|
747
|
-
if (!user?.email) {
|
|
748
|
-
log('fetchLobehubSkillManifests: user email not found, skipping');
|
|
749
|
-
return [];
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
// 2. Generate trusted client token
|
|
753
|
-
const trustedClientToken = generateTrustedClientToken({
|
|
754
|
-
email: user.email,
|
|
755
|
-
name: user.fullName || user.firstName || undefined,
|
|
756
|
-
userId: this.userId,
|
|
757
|
-
});
|
|
758
|
-
|
|
759
|
-
if (!trustedClientToken) {
|
|
760
|
-
log('fetchLobehubSkillManifests: trusted client not configured, skipping');
|
|
761
|
-
return [];
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
// 3. Create MarketSDK instance
|
|
765
|
-
const marketSDK = new MarketSDK({
|
|
766
|
-
baseURL: process.env.NEXT_PUBLIC_MARKET_BASE_URL,
|
|
767
|
-
trustedClientToken,
|
|
768
|
-
});
|
|
769
|
-
|
|
770
|
-
// 4. Get user's connected skills
|
|
771
|
-
const { connections } = await marketSDK.connect.listConnections();
|
|
772
|
-
if (!connections || connections.length === 0) {
|
|
773
|
-
log('fetchLobehubSkillManifests: no connected skills found');
|
|
774
|
-
return [];
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
log('fetchLobehubSkillManifests: found %d connected skills', connections.length);
|
|
778
|
-
|
|
779
|
-
// 5. Fetch tools for each connection and build manifests
|
|
780
|
-
const manifests: LobeToolManifest[] = [];
|
|
781
|
-
|
|
782
|
-
for (const connection of connections) {
|
|
783
|
-
try {
|
|
784
|
-
// Connection returns providerId (e.g., 'twitter', 'linear'), not numeric id
|
|
785
|
-
const providerId = (connection as any).providerId;
|
|
786
|
-
if (!providerId) {
|
|
787
|
-
log('fetchLobehubSkillManifests: connection missing providerId: %O', connection);
|
|
788
|
-
continue;
|
|
789
|
-
}
|
|
790
|
-
const providerName =
|
|
791
|
-
(connection as any).providerName || (connection as any).name || providerId;
|
|
792
|
-
const icon = (connection as any).icon;
|
|
793
|
-
|
|
794
|
-
const { tools } = await marketSDK.skills.listTools(providerId);
|
|
795
|
-
if (!tools || tools.length === 0) continue;
|
|
796
|
-
|
|
797
|
-
const manifest: LobeToolManifest = {
|
|
798
|
-
api: tools.map((tool: any) => ({
|
|
799
|
-
description: tool.description || '',
|
|
800
|
-
name: tool.name,
|
|
801
|
-
parameters: tool.inputSchema || { properties: {}, type: 'object' },
|
|
802
|
-
})),
|
|
803
|
-
identifier: providerId,
|
|
804
|
-
meta: {
|
|
805
|
-
avatar: icon || '🔗',
|
|
806
|
-
description: `LobeHub Skill: ${providerName}`,
|
|
807
|
-
tags: ['lobehub-skill', providerId],
|
|
808
|
-
title: providerName,
|
|
809
|
-
},
|
|
810
|
-
type: 'builtin',
|
|
811
|
-
};
|
|
812
|
-
|
|
813
|
-
manifests.push(manifest);
|
|
814
|
-
log(
|
|
815
|
-
'fetchLobehubSkillManifests: built manifest for %s with %d tools',
|
|
816
|
-
providerId,
|
|
817
|
-
tools.length,
|
|
818
|
-
);
|
|
819
|
-
} catch (error) {
|
|
820
|
-
log('fetchLobehubSkillManifests: failed to fetch tools for connection: %O', error);
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
return manifests;
|
|
825
|
-
} catch (error) {
|
|
826
|
-
log('fetchLobehubSkillManifests: error fetching skills: %O', error);
|
|
827
|
-
return [];
|
|
828
|
-
}
|
|
829
|
-
}
|
|
830
|
-
|
|
831
744
|
/**
|
|
832
745
|
* Calculate total tokens from AgentState usage object
|
|
833
746
|
* AgentState.usage is of type Usage from @lobechat/agent-runtime
|
|
@@ -62,10 +62,11 @@ import { cloneDeep, countBy, isString, merge, uniq, uniqBy } from 'es-toolkit/co
|
|
|
62
62
|
import matter from 'gray-matter';
|
|
63
63
|
import urlJoin from 'url-join';
|
|
64
64
|
|
|
65
|
-
import { type TrustedClientUserInfo
|
|
65
|
+
import { type TrustedClientUserInfo } from '@/libs/trusted-client';
|
|
66
66
|
import { normalizeLocale } from '@/locales/resources';
|
|
67
67
|
import { AssistantStore } from '@/server/modules/AssistantStore';
|
|
68
68
|
import { PluginStore } from '@/server/modules/PluginStore';
|
|
69
|
+
import { MarketService } from '@/server/services/market';
|
|
69
70
|
|
|
70
71
|
const log = debug('lobe-server:discover');
|
|
71
72
|
|
|
@@ -84,18 +85,14 @@ export class DiscoverService {
|
|
|
84
85
|
constructor(options: DiscoverServiceOptions = {}) {
|
|
85
86
|
const { accessToken, userInfo } = options;
|
|
86
87
|
|
|
87
|
-
//
|
|
88
|
-
const
|
|
88
|
+
// Use MarketService to initialize MarketSDK
|
|
89
|
+
const marketService = new MarketService({ accessToken, userInfo });
|
|
90
|
+
this.market = marketService.market;
|
|
89
91
|
|
|
90
|
-
this.market = new MarketSDK({
|
|
91
|
-
accessToken,
|
|
92
|
-
baseURL: process.env.NEXT_PUBLIC_MARKET_BASE_URL,
|
|
93
|
-
trustedClientToken,
|
|
94
|
-
});
|
|
95
92
|
log(
|
|
96
|
-
'DiscoverService initialized with market baseURL: %s,
|
|
93
|
+
'DiscoverService initialized with market baseURL: %s, hasAuth: %s, userId: %s',
|
|
97
94
|
process.env.NEXT_PUBLIC_MARKET_BASE_URL,
|
|
98
|
-
!!
|
|
95
|
+
!!(accessToken || userInfo),
|
|
99
96
|
userInfo?.userId,
|
|
100
97
|
);
|
|
101
98
|
}
|
|
@@ -135,14 +132,12 @@ export class DiscoverService {
|
|
|
135
132
|
}
|
|
136
133
|
|
|
137
134
|
async fetchM2MToken(params: { clientId: string; clientSecret: string }) {
|
|
138
|
-
//
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
clientId: params.clientId,
|
|
142
|
-
clientSecret: params.clientSecret,
|
|
135
|
+
// Use MarketService with M2M credentials
|
|
136
|
+
const marketService = new MarketService({
|
|
137
|
+
clientCredentials: params,
|
|
143
138
|
});
|
|
144
139
|
|
|
145
|
-
const tokenInfo = await
|
|
140
|
+
const tokenInfo = await marketService.fetchM2MToken();
|
|
146
141
|
|
|
147
142
|
return {
|
|
148
143
|
accessToken: tokenInfo.accessToken,
|