@lobehub/lobehub 2.0.0-next.322 → 2.0.0-next.323
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/CHANGELOG.md +55 -0
- package/apps/desktop/src/main/core/infrastructure/UpdaterManager.ts +9 -76
- package/apps/desktop/src/main/core/infrastructure/__tests__/UpdaterManager.test.ts +0 -1
- package/apps/desktop/src/main/modules/updater/configs.ts +0 -4
- package/changelog/v1.json +15 -0
- package/e2e/src/mocks/llm/index.ts +3 -3
- package/locales/ar/common.json +5 -0
- package/locales/ar/error.json +10 -1
- package/locales/bg-BG/common.json +5 -0
- package/locales/bg-BG/error.json +10 -1
- package/locales/de-DE/common.json +5 -0
- package/locales/de-DE/error.json +10 -1
- package/locales/en-US/common.json +5 -0
- package/locales/es-ES/common.json +5 -0
- package/locales/es-ES/error.json +10 -1
- package/locales/fa-IR/common.json +5 -0
- package/locales/fa-IR/error.json +10 -1
- package/locales/fr-FR/common.json +5 -0
- package/locales/fr-FR/error.json +10 -1
- package/locales/it-IT/common.json +5 -0
- package/locales/it-IT/error.json +10 -1
- package/locales/ja-JP/common.json +5 -0
- package/locales/ja-JP/error.json +10 -1
- package/locales/ko-KR/common.json +5 -0
- package/locales/ko-KR/error.json +10 -1
- package/locales/nl-NL/common.json +5 -0
- package/locales/nl-NL/error.json +10 -1
- package/locales/pl-PL/common.json +5 -0
- package/locales/pl-PL/error.json +10 -1
- package/locales/pt-BR/common.json +5 -0
- package/locales/pt-BR/error.json +10 -1
- package/locales/ru-RU/common.json +5 -0
- package/locales/ru-RU/error.json +10 -1
- package/locales/tr-TR/common.json +5 -0
- package/locales/tr-TR/error.json +10 -1
- package/locales/vi-VN/common.json +5 -0
- package/locales/vi-VN/error.json +10 -1
- package/locales/zh-CN/common.json +5 -0
- package/locales/zh-TW/common.json +5 -0
- package/locales/zh-TW/error.json +10 -1
- package/package.json +2 -2
- package/packages/business/const/src/branding.ts +1 -0
- package/packages/business/const/src/llm.ts +2 -1
- package/packages/const/src/settings/llm.ts +2 -1
- package/packages/const/src/settings/systemAgent.ts +12 -7
- package/packages/database/src/models/agent.ts +18 -1
- package/packages/database/src/models/chatGroup.ts +18 -1
- package/packages/database/src/types/chatGroup.ts +1 -0
- package/packages/model-bank/package.json +1 -1
- package/packages/model-bank/src/aiModels/index.ts +2 -2
- package/packages/model-bank/src/aiModels/lobehub/chat/anthropic.ts +256 -0
- package/packages/model-bank/src/aiModels/lobehub/chat/deepseek.ts +45 -0
- package/packages/model-bank/src/aiModels/lobehub/chat/google.ts +267 -0
- package/packages/model-bank/src/aiModels/lobehub/chat/index.ts +26 -0
- package/packages/model-bank/src/aiModels/lobehub/chat/minimax.ts +75 -0
- package/packages/model-bank/src/aiModels/lobehub/chat/moonshot.ts +28 -0
- package/packages/model-bank/src/aiModels/lobehub/chat/openai.ts +345 -0
- package/packages/model-bank/src/aiModels/lobehub/chat/xai.ts +32 -0
- package/packages/model-bank/src/aiModels/lobehub/image.ts +240 -0
- package/packages/model-bank/src/aiModels/lobehub/index.ts +10 -0
- package/packages/model-bank/src/aiModels/lobehub/utils.ts +58 -0
- package/packages/model-bank/src/modelProviders/index.ts +10 -10
- package/packages/model-runtime/src/core/streams/qwen.test.ts +320 -0
- package/packages/model-runtime/src/core/streams/qwen.ts +19 -10
- package/packages/types/package.json +1 -1
- package/packages/types/src/agentGroup/index.ts +2 -0
- package/packages/types/src/discover/assistants.ts +9 -0
- package/packages/types/src/discover/fork.ts +163 -0
- package/packages/types/src/discover/groupAgents.ts +13 -4
- package/packages/types/src/discover/index.ts +9 -0
- package/src/app/[variants]/(auth)/_layout/index.tsx +2 -1
- package/src/app/[variants]/(auth)/auth-error/page.tsx +5 -5
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/List/Item/index.tsx +1 -2
- package/src/app/[variants]/(main)/community/(detail)/agent/features/Header.tsx +37 -0
- package/src/app/[variants]/(main)/community/(detail)/agent/features/Sidebar/ActionButton/ForkAndChat.tsx +133 -0
- package/src/app/[variants]/(main)/community/(detail)/agent/features/Sidebar/ActionButton/index.tsx +2 -2
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/index.tsx +7 -10
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/ActionButton/ForkGroupAndChat.tsx +208 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/ActionButton/index.tsx +2 -2
- package/src/app/[variants]/(main)/community/(detail)/user/features/DetailProvider.tsx +2 -0
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserContent.tsx +7 -0
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserForkedAgentGroups.tsx +63 -0
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserForkedAgents.tsx +61 -0
- package/src/app/[variants]/(main)/community/(detail)/user/index.tsx +3 -1
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/List/Item/index.tsx +1 -2
- package/src/app/[variants]/(main)/settings/profile/index.tsx +92 -68
- package/src/app/[variants]/(mobile)/chat/features/Topic/index.tsx +2 -1
- package/src/features/CommandMenu/AskAgentCommands.tsx +105 -0
- package/src/features/CommandMenu/CommandMenuContext.tsx +57 -38
- package/src/features/CommandMenu/components/CommandInput.tsx +43 -9
- package/src/features/CommandMenu/index.tsx +89 -27
- package/src/features/CommandMenu/types.ts +6 -0
- package/src/features/CommandMenu/useCommandMenu.ts +62 -39
- package/src/locales/default/common.ts +5 -0
- package/src/locales/default/discover.ts +371 -0
- package/src/server/globalConfig/parseMemoryExtractionConfig.ts +7 -8
- package/src/server/routers/lambda/agent.ts +14 -0
- package/src/server/routers/lambda/agentGroup.ts +19 -3
- package/src/server/routers/lambda/market/agent.ts +234 -26
- package/src/server/routers/lambda/market/agentGroup.ts +204 -1
- package/src/server/services/discover/index.ts +52 -2
- package/src/services/agent.ts +8 -0
- package/src/services/chatGroup/index.ts +8 -0
- package/src/services/marketApi.ts +78 -0
- package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +12 -12
- package/packages/model-bank/src/aiModels/lobehub.ts +0 -1315
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DEFAULT_MINI_PROVIDER } from '@lobechat/business-const';
|
|
2
|
+
import { DEFAULT_MINI_MODEL, DEFAULT_USER_MEMORY_EMBEDDING_MODEL_ITEM } from '@lobechat/const';
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
type GlobalMemoryExtractionConfig,
|
|
@@ -8,8 +9,6 @@ import {
|
|
|
8
9
|
} from '@/types/serverConfig';
|
|
9
10
|
|
|
10
11
|
const MEMORY_LAYERS: GlobalMemoryLayer[] = ['context', 'experience', 'identity', 'preference'];
|
|
11
|
-
const DEFAULT_GATE_MODEL = 'gpt-5-mini';
|
|
12
|
-
const DEFAULT_PROVIDER = 'openai';
|
|
13
12
|
|
|
14
13
|
const parseTokenLimitEnv = (value?: string) => {
|
|
15
14
|
if (value === undefined) return undefined;
|
|
@@ -62,8 +61,8 @@ export interface MemoryExtractionPrivateConfig {
|
|
|
62
61
|
const parseGateKeeperAgent = (): MemoryAgentConfig => {
|
|
63
62
|
const apiKey = process.env.MEMORY_USER_MEMORY_GATEKEEPER_API_KEY;
|
|
64
63
|
const baseURL = process.env.MEMORY_USER_MEMORY_GATEKEEPER_BASE_URL;
|
|
65
|
-
const model = process.env.MEMORY_USER_MEMORY_GATEKEEPER_MODEL ||
|
|
66
|
-
const provider = process.env.MEMORY_USER_MEMORY_GATEKEEPER_PROVIDER ||
|
|
64
|
+
const model = process.env.MEMORY_USER_MEMORY_GATEKEEPER_MODEL || DEFAULT_MINI_MODEL;
|
|
65
|
+
const provider = process.env.MEMORY_USER_MEMORY_GATEKEEPER_PROVIDER || DEFAULT_MINI_PROVIDER;
|
|
67
66
|
const language = process.env.MEMORY_USER_MEMORY_GATEKEEPER_LANGUAGE || 'English';
|
|
68
67
|
|
|
69
68
|
return {
|
|
@@ -79,7 +78,7 @@ const parseLayerExtractorAgent = (fallbackModel: string): MemoryLayerExtractorCo
|
|
|
79
78
|
const apiKey = process.env.MEMORY_USER_MEMORY_LAYER_EXTRACTOR_API_KEY;
|
|
80
79
|
const baseURL = process.env.MEMORY_USER_MEMORY_LAYER_EXTRACTOR_BASE_URL;
|
|
81
80
|
const model = process.env.MEMORY_USER_MEMORY_LAYER_EXTRACTOR_MODEL || fallbackModel;
|
|
82
|
-
const provider = process.env.MEMORY_USER_MEMORY_LAYER_EXTRACTOR_PROVIDER ||
|
|
81
|
+
const provider = process.env.MEMORY_USER_MEMORY_LAYER_EXTRACTOR_PROVIDER || DEFAULT_MINI_PROVIDER;
|
|
83
82
|
const contextLimit = parseTokenLimitEnv(
|
|
84
83
|
process.env.MEMORY_USER_MEMORY_LAYER_EXTRACTOR_CONTEXT_LIMIT,
|
|
85
84
|
);
|
|
@@ -117,7 +116,7 @@ const parseEmbeddingAgent = (
|
|
|
117
116
|
process.env.MEMORY_USER_MEMORY_EMBEDDING_PROVIDER ||
|
|
118
117
|
fallbackProvider ||
|
|
119
118
|
defaultProvider ||
|
|
120
|
-
|
|
119
|
+
DEFAULT_MINI_PROVIDER;
|
|
121
120
|
|
|
122
121
|
return {
|
|
123
122
|
apiKey: process.env.MEMORY_USER_MEMORY_EMBEDDING_API_KEY ?? fallbackApiKey,
|
|
@@ -174,7 +173,7 @@ export const parseMemoryExtractionConfig = (): MemoryExtractionPrivateConfig =>
|
|
|
174
173
|
const agentLayerExtractor = parseLayerExtractorAgent(agentGateKeeper.model);
|
|
175
174
|
const embedding = parseEmbeddingAgent(
|
|
176
175
|
agentLayerExtractor.model,
|
|
177
|
-
agentLayerExtractor.provider ||
|
|
176
|
+
agentLayerExtractor.provider || DEFAULT_MINI_PROVIDER,
|
|
178
177
|
agentGateKeeper.apiKey || agentLayerExtractor.apiKey,
|
|
179
178
|
);
|
|
180
179
|
const extractorObservabilityS3 = parseExtractorAgentObservabilityS3();
|
|
@@ -169,6 +169,20 @@ export const agentRouter = router({
|
|
|
169
169
|
return ctx.agentModel.duplicate(input.agentId, input.newTitle);
|
|
170
170
|
}),
|
|
171
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Get an agent by forkedFromIdentifier stored in params
|
|
174
|
+
* @returns agent id if exists, null otherwise
|
|
175
|
+
*/
|
|
176
|
+
getAgentByForkedFromIdentifier: agentProcedure
|
|
177
|
+
.input(
|
|
178
|
+
z.object({
|
|
179
|
+
forkedFromIdentifier: z.string(),
|
|
180
|
+
}),
|
|
181
|
+
)
|
|
182
|
+
.query(async ({ input, ctx }) => {
|
|
183
|
+
return ctx.agentModel.getAgentByForkedFromIdentifier(input.forkedFromIdentifier);
|
|
184
|
+
}),
|
|
185
|
+
|
|
172
186
|
/**
|
|
173
187
|
* Get an agent by marketIdentifier
|
|
174
188
|
* @returns agent id if exists, null otherwise
|
|
@@ -165,12 +165,14 @@ export const agentGroupRouter = router({
|
|
|
165
165
|
)
|
|
166
166
|
: undefined;
|
|
167
167
|
|
|
168
|
+
const normalizedConfig = ctx.agentGroupService.normalizeGroupConfig(
|
|
169
|
+
input.groupConfig.config as ChatGroupConfig | null,
|
|
170
|
+
);
|
|
171
|
+
|
|
168
172
|
const { group, supervisorAgentId } = await ctx.agentGroupRepo.createGroupWithSupervisor(
|
|
169
173
|
{
|
|
170
174
|
...input.groupConfig,
|
|
171
|
-
config:
|
|
172
|
-
input.groupConfig.config as ChatGroupConfig | null,
|
|
173
|
-
),
|
|
175
|
+
config: normalizedConfig,
|
|
174
176
|
},
|
|
175
177
|
memberAgentIds,
|
|
176
178
|
supervisorConfig as any,
|
|
@@ -213,6 +215,20 @@ export const agentGroupRouter = router({
|
|
|
213
215
|
return ctx.chatGroupModel.getGroupAgents(input.groupId);
|
|
214
216
|
}),
|
|
215
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Get a group by forkedFromIdentifier stored in config
|
|
220
|
+
* @returns group id if exists, null otherwise
|
|
221
|
+
*/
|
|
222
|
+
getGroupByForkedFromIdentifier: agentGroupProcedure
|
|
223
|
+
.input(
|
|
224
|
+
z.object({
|
|
225
|
+
forkedFromIdentifier: z.string(),
|
|
226
|
+
}),
|
|
227
|
+
)
|
|
228
|
+
.query(async ({ input, ctx }) => {
|
|
229
|
+
return ctx.chatGroupModel.getGroupByForkedFromIdentifier(input.forkedFromIdentifier);
|
|
230
|
+
}),
|
|
231
|
+
|
|
216
232
|
getGroupDetail: agentGroupProcedure
|
|
217
233
|
.input(z.object({ id: z.string() }))
|
|
218
234
|
.query(async ({ input, ctx }) => {
|
|
@@ -163,31 +163,23 @@ const paginationSchema = z.object({
|
|
|
163
163
|
|
|
164
164
|
// Schema for the unified publish/create flow
|
|
165
165
|
const publishOrCreateSchema = z.object({
|
|
166
|
-
|
|
167
166
|
// Version data
|
|
168
|
-
avatar: z.string().optional(),
|
|
169
|
-
|
|
167
|
+
avatar: z.string().optional(),
|
|
170
168
|
|
|
171
|
-
category: z.string().optional(),
|
|
169
|
+
category: z.string().optional(),
|
|
172
170
|
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
changelog: z.string().optional(),
|
|
175
172
|
|
|
176
|
-
|
|
177
|
-
|
|
173
|
+
config: z.record(z.any()).optional(),
|
|
178
174
|
|
|
179
|
-
|
|
180
|
-
|
|
175
|
+
description: z.string().optional(),
|
|
181
176
|
|
|
182
|
-
|
|
183
|
-
|
|
177
|
+
editorData: z.record(z.any()).optional(),
|
|
184
178
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// Agent basic info
|
|
188
|
-
identifier: z.string().optional(),
|
|
179
|
+
// Agent basic info
|
|
180
|
+
identifier: z.string().optional(),
|
|
189
181
|
// Optional - if not provided or not owned, will create new
|
|
190
|
-
name: z.string(),
|
|
182
|
+
name: z.string(),
|
|
191
183
|
tags: z.array(z.string()).optional(),
|
|
192
184
|
tokenUsage: z.number().optional(),
|
|
193
185
|
});
|
|
@@ -320,11 +312,86 @@ export const agentRouter = router({
|
|
|
320
312
|
}
|
|
321
313
|
}),
|
|
322
314
|
|
|
315
|
+
|
|
323
316
|
/**
|
|
317
|
+
* Fork an agent
|
|
318
|
+
* POST /market/agent/:identifier/fork
|
|
319
|
+
*/
|
|
320
|
+
forkAgent: agentProcedure
|
|
321
|
+
.input(
|
|
322
|
+
z.object({
|
|
323
|
+
identifier: z.string(),
|
|
324
|
+
name: z.string().optional(),
|
|
325
|
+
sourceIdentifier: z.string(),
|
|
326
|
+
status: z.enum(['published', 'unpublished', 'archived', 'deprecated']).optional(),
|
|
327
|
+
versionNumber: z.number().optional(),
|
|
328
|
+
visibility: z.enum(['public', 'private', 'internal']).optional(),
|
|
329
|
+
}),
|
|
330
|
+
)
|
|
331
|
+
.mutation(async ({ input, ctx }) => {
|
|
332
|
+
log('forkAgent input: %O', input);
|
|
333
|
+
|
|
334
|
+
try {
|
|
335
|
+
// Call Market API directly to fork agent
|
|
336
|
+
const forkUrl = `${MARKET_BASE_URL}/api/v1/agents/${input.sourceIdentifier}/fork`;
|
|
337
|
+
|
|
338
|
+
const headers: Record<string, string> = {
|
|
339
|
+
'Content-Type': 'application/json',
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// Use trustedClientToken or accessToken for authentication
|
|
343
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
344
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
345
|
+
|
|
346
|
+
if (userInfo) {
|
|
347
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
348
|
+
if (trustedClientToken) {
|
|
349
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
354
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const response = await fetch(forkUrl, {
|
|
358
|
+
body: JSON.stringify({
|
|
359
|
+
identifier: input.identifier,
|
|
360
|
+
name: input.name,
|
|
361
|
+
status: input.status,
|
|
362
|
+
versionNumber: input.versionNumber,
|
|
363
|
+
visibility: input.visibility,
|
|
364
|
+
}),
|
|
365
|
+
headers,
|
|
366
|
+
method: 'POST',
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
if (!response.ok) {
|
|
370
|
+
const errorText = await response.text();
|
|
371
|
+
log('Fork agent failed: %s %s - %s', response.status, response.statusText, errorText);
|
|
372
|
+
throw new Error(`Failed to fork agent: ${response.statusText}`);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const result = await response.json();
|
|
376
|
+
log('Fork agent success: %O', result);
|
|
377
|
+
return result;
|
|
378
|
+
} catch (error) {
|
|
379
|
+
log('Error forking agent: %O', error);
|
|
380
|
+
throw new TRPCError({
|
|
381
|
+
cause: error,
|
|
382
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
383
|
+
message: error instanceof Error ? error.message : 'Failed to fork agent',
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}),
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
/**
|
|
324
391
|
* Get agent detail by identifier
|
|
325
392
|
* GET /market/agent/:identifier
|
|
326
393
|
*/
|
|
327
|
-
|
|
394
|
+
getAgentDetail: agentProcedure
|
|
328
395
|
.input(z.object({ identifier: z.string() }))
|
|
329
396
|
.query(async ({ input, ctx }) => {
|
|
330
397
|
log('getAgentDetail input: %O', input);
|
|
@@ -342,11 +409,141 @@ export const agentRouter = router({
|
|
|
342
409
|
}
|
|
343
410
|
}),
|
|
344
411
|
|
|
345
|
-
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Get the fork source of an agent
|
|
417
|
+
* GET /market/agent/:identifier/fork-source
|
|
418
|
+
*/
|
|
419
|
+
getAgentForkSource: agentProcedure
|
|
420
|
+
.input(z.object({ identifier: z.string() }))
|
|
421
|
+
.query(async ({ input, ctx }) => {
|
|
422
|
+
log('getAgentForkSource input: %O', input);
|
|
423
|
+
|
|
424
|
+
try {
|
|
425
|
+
const forkSourceUrl = `${MARKET_BASE_URL}/api/v1/agents/${input.identifier}/fork-source`;
|
|
426
|
+
|
|
427
|
+
const headers: Record<string, string> = {
|
|
428
|
+
'Content-Type': 'application/json',
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
432
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
433
|
+
|
|
434
|
+
if (userInfo) {
|
|
435
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
436
|
+
if (trustedClientToken) {
|
|
437
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
442
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const response = await fetch(forkSourceUrl, {
|
|
446
|
+
headers,
|
|
447
|
+
method: 'GET',
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
if (!response.ok) {
|
|
451
|
+
const errorText = await response.text();
|
|
452
|
+
log(
|
|
453
|
+
'Get agent fork source failed: %s %s - %s',
|
|
454
|
+
response.status,
|
|
455
|
+
response.statusText,
|
|
456
|
+
errorText,
|
|
457
|
+
);
|
|
458
|
+
throw new Error(`Failed to get agent fork source: ${response.statusText}`);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
const result = await response.json();
|
|
462
|
+
return result;
|
|
463
|
+
} catch (error) {
|
|
464
|
+
log('Error getting agent fork source: %O', error);
|
|
465
|
+
throw new TRPCError({
|
|
466
|
+
cause: error,
|
|
467
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
468
|
+
message: error instanceof Error ? error.message : 'Failed to get agent fork source',
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}),
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Get all forks of an agent
|
|
480
|
+
* GET /market/agent/:identifier/forks
|
|
481
|
+
*/
|
|
482
|
+
getAgentForks: agentProcedure
|
|
483
|
+
.input(z.object({ identifier: z.string() }))
|
|
484
|
+
.query(async ({ input, ctx }) => {
|
|
485
|
+
log('getAgentForks input: %O', input);
|
|
486
|
+
|
|
487
|
+
try {
|
|
488
|
+
const forksUrl = `${MARKET_BASE_URL}/api/v1/agents/${input.identifier}/forks`;
|
|
489
|
+
|
|
490
|
+
const headers: Record<string, string> = {
|
|
491
|
+
'Content-Type': 'application/json',
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
495
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
496
|
+
|
|
497
|
+
if (userInfo) {
|
|
498
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
499
|
+
if (trustedClientToken) {
|
|
500
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
505
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const response = await fetch(forksUrl, {
|
|
509
|
+
headers,
|
|
510
|
+
method: 'GET',
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
if (!response.ok) {
|
|
514
|
+
const errorText = await response.text();
|
|
515
|
+
log(
|
|
516
|
+
'Get agent forks failed: %s %s - %s',
|
|
517
|
+
response.status,
|
|
518
|
+
response.statusText,
|
|
519
|
+
errorText,
|
|
520
|
+
);
|
|
521
|
+
throw new Error(`Failed to get agent forks: ${response.statusText}`);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const result = await response.json();
|
|
525
|
+
return result;
|
|
526
|
+
} catch (error) {
|
|
527
|
+
log('Error getting agent forks: %O', error);
|
|
528
|
+
throw new TRPCError({
|
|
529
|
+
cause: error,
|
|
530
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
531
|
+
message: error instanceof Error ? error.message : 'Failed to get agent forks',
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
}),
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
/**
|
|
346
543
|
* Get own agents (requires authentication)
|
|
347
544
|
* GET /market/agent/own
|
|
348
545
|
*/
|
|
349
|
-
|
|
546
|
+
getOwnAgents: agentProcedure.input(paginationSchema.optional()).query(async ({ input, ctx }) => {
|
|
350
547
|
log('getOwnAgents input: %O', input);
|
|
351
548
|
|
|
352
549
|
try {
|
|
@@ -365,11 +562,16 @@ export const agentRouter = router({
|
|
|
365
562
|
}
|
|
366
563
|
}),
|
|
367
564
|
|
|
368
|
-
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
/**
|
|
369
571
|
* Publish an agent (make it visible in marketplace)
|
|
370
572
|
* POST /market/agent/:identifier/publish
|
|
371
573
|
*/
|
|
372
|
-
|
|
574
|
+
publishAgent: agentProcedure
|
|
373
575
|
.input(z.object({ identifier: z.string() }))
|
|
374
576
|
.mutation(async ({ input, ctx }) => {
|
|
375
577
|
log('publishAgent input: %O', input);
|
|
@@ -387,7 +589,11 @@ export const agentRouter = router({
|
|
|
387
589
|
}
|
|
388
590
|
}),
|
|
389
591
|
|
|
390
|
-
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
/**
|
|
391
597
|
* Unified publish or create agent flow
|
|
392
598
|
* This procedure handles the complete publish logic:
|
|
393
599
|
* 1. Check if identifier exists and if current user is owner
|
|
@@ -396,7 +602,7 @@ export const agentRouter = router({
|
|
|
396
602
|
*
|
|
397
603
|
* Returns: { identifier, isNewAgent, success }
|
|
398
604
|
*/
|
|
399
|
-
|
|
605
|
+
publishOrCreate: agentProcedure.input(publishOrCreateSchema).mutation(async ({ input, ctx }) => {
|
|
400
606
|
log('publishOrCreate input: %O', input);
|
|
401
607
|
|
|
402
608
|
const { identifier: inputIdentifier, name, ...versionData } = input;
|
|
@@ -478,11 +684,13 @@ export const agentRouter = router({
|
|
|
478
684
|
}
|
|
479
685
|
}),
|
|
480
686
|
|
|
481
|
-
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
/**
|
|
482
690
|
* Unpublish an agent (hide from marketplace, can be republished)
|
|
483
691
|
* POST /market/agent/:identifier/unpublish
|
|
484
692
|
*/
|
|
485
|
-
|
|
693
|
+
unpublishAgent: agentProcedure
|
|
486
694
|
.input(z.object({ identifier: z.string() }))
|
|
487
695
|
.mutation(async ({ input, ctx }) => {
|
|
488
696
|
log('unpublishAgent input: %O', input);
|
|
@@ -200,13 +200,214 @@ export const agentGroupRouter = router({
|
|
|
200
200
|
}
|
|
201
201
|
}),
|
|
202
202
|
|
|
203
|
+
|
|
203
204
|
/**
|
|
205
|
+
* Fork an agent group
|
|
206
|
+
* POST /market/agent-group/:identifier/fork
|
|
207
|
+
*/
|
|
208
|
+
forkAgentGroup: agentGroupProcedure
|
|
209
|
+
.input(
|
|
210
|
+
z.object({
|
|
211
|
+
identifier: z.string(),
|
|
212
|
+
name: z.string().optional(),
|
|
213
|
+
sourceIdentifier: z.string(),
|
|
214
|
+
status: z.enum(['published', 'unpublished', 'archived', 'deprecated']).optional(),
|
|
215
|
+
versionNumber: z.number().optional(),
|
|
216
|
+
visibility: z.enum(['public', 'private', 'internal']).optional(),
|
|
217
|
+
}),
|
|
218
|
+
)
|
|
219
|
+
.mutation(async ({ input, ctx }) => {
|
|
220
|
+
log('forkAgentGroup input: %O', input);
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
// Call Market API directly to fork agent group
|
|
224
|
+
const forkUrl = `${MARKET_BASE_URL}/api/v1/agent-groups/${input.sourceIdentifier}/fork`;
|
|
225
|
+
|
|
226
|
+
const headers: Record<string, string> = {
|
|
227
|
+
'Content-Type': 'application/json',
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// Use trustedClientToken or accessToken for authentication
|
|
231
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
232
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
233
|
+
|
|
234
|
+
if (userInfo) {
|
|
235
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
236
|
+
if (trustedClientToken) {
|
|
237
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
242
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const response = await fetch(forkUrl, {
|
|
246
|
+
body: JSON.stringify({
|
|
247
|
+
identifier: input.identifier,
|
|
248
|
+
name: input.name,
|
|
249
|
+
status: input.status,
|
|
250
|
+
versionNumber: input.versionNumber,
|
|
251
|
+
visibility: input.visibility,
|
|
252
|
+
}),
|
|
253
|
+
headers,
|
|
254
|
+
method: 'POST',
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
if (!response.ok) {
|
|
258
|
+
const errorText = await response.text();
|
|
259
|
+
log(
|
|
260
|
+
'Fork agent group failed: %s %s - %s',
|
|
261
|
+
response.status,
|
|
262
|
+
response.statusText,
|
|
263
|
+
errorText,
|
|
264
|
+
);
|
|
265
|
+
throw new Error(`Failed to fork agent group: ${response.statusText}`);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const result = await response.json();
|
|
269
|
+
log('Fork agent group success: %O', result);
|
|
270
|
+
return result;
|
|
271
|
+
} catch (error) {
|
|
272
|
+
log('Error forking agent group: %O', error);
|
|
273
|
+
throw new TRPCError({
|
|
274
|
+
cause: error,
|
|
275
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
276
|
+
message: error instanceof Error ? error.message : 'Failed to fork agent group',
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}),
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Get the fork source of an agent group
|
|
285
|
+
* GET /market/agent-group/:identifier/fork-source
|
|
286
|
+
*/
|
|
287
|
+
getAgentGroupForkSource: agentGroupProcedure
|
|
288
|
+
.input(z.object({ identifier: z.string() }))
|
|
289
|
+
.query(async ({ input, ctx }) => {
|
|
290
|
+
log('getAgentGroupForkSource input: %O', input);
|
|
291
|
+
|
|
292
|
+
try {
|
|
293
|
+
const forkSourceUrl = `${MARKET_BASE_URL}/api/v1/agent-groups/${input.identifier}/fork-source`;
|
|
294
|
+
|
|
295
|
+
const headers: Record<string, string> = {
|
|
296
|
+
'Content-Type': 'application/json',
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
300
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
301
|
+
|
|
302
|
+
if (userInfo) {
|
|
303
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
304
|
+
if (trustedClientToken) {
|
|
305
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
310
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const response = await fetch(forkSourceUrl, {
|
|
314
|
+
headers,
|
|
315
|
+
method: 'GET',
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
if (!response.ok) {
|
|
319
|
+
const errorText = await response.text();
|
|
320
|
+
log(
|
|
321
|
+
'Get agent group fork source failed: %s %s - %s',
|
|
322
|
+
response.status,
|
|
323
|
+
response.statusText,
|
|
324
|
+
errorText,
|
|
325
|
+
);
|
|
326
|
+
throw new Error(`Failed to get agent group fork source: ${response.statusText}`);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const result = await response.json();
|
|
330
|
+
return result;
|
|
331
|
+
} catch (error) {
|
|
332
|
+
log('Error getting agent group fork source: %O', error);
|
|
333
|
+
throw new TRPCError({
|
|
334
|
+
cause: error,
|
|
335
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
336
|
+
message: error instanceof Error ? error.message : 'Failed to get agent group fork source',
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}),
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Get all forks of an agent group
|
|
346
|
+
* GET /market/agent-group/:identifier/forks
|
|
347
|
+
*/
|
|
348
|
+
getAgentGroupForks: agentGroupProcedure
|
|
349
|
+
.input(z.object({ identifier: z.string() }))
|
|
350
|
+
.query(async ({ input, ctx }) => {
|
|
351
|
+
log('getAgentGroupForks input: %O', input);
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
const forksUrl = `${MARKET_BASE_URL}/api/v1/agent-groups/${input.identifier}/forks`;
|
|
355
|
+
|
|
356
|
+
const headers: Record<string, string> = {
|
|
357
|
+
'Content-Type': 'application/json',
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
361
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
362
|
+
|
|
363
|
+
if (userInfo) {
|
|
364
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
365
|
+
if (trustedClientToken) {
|
|
366
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
371
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const response = await fetch(forksUrl, {
|
|
375
|
+
headers,
|
|
376
|
+
method: 'GET',
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
if (!response.ok) {
|
|
380
|
+
const errorText = await response.text();
|
|
381
|
+
log(
|
|
382
|
+
'Get agent group forks failed: %s %s - %s',
|
|
383
|
+
response.status,
|
|
384
|
+
response.statusText,
|
|
385
|
+
errorText,
|
|
386
|
+
);
|
|
387
|
+
throw new Error(`Failed to get agent group forks: ${response.statusText}`);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const result = await response.json();
|
|
391
|
+
return result;
|
|
392
|
+
} catch (error) {
|
|
393
|
+
log('Error getting agent group forks: %O', error);
|
|
394
|
+
throw new TRPCError({
|
|
395
|
+
cause: error,
|
|
396
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
397
|
+
message: error instanceof Error ? error.message : 'Failed to get agent group forks',
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
}),
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
/**
|
|
204
405
|
* Unified publish or create agent group flow
|
|
205
406
|
* 1. Check if identifier exists and if current user is owner
|
|
206
407
|
* 2. If not owner or no identifier, create new group
|
|
207
408
|
* 3. Create new version for the group if updating
|
|
208
409
|
*/
|
|
209
|
-
|
|
410
|
+
publishOrCreate: agentGroupProcedure
|
|
210
411
|
.input(publishOrCreateGroupSchema)
|
|
211
412
|
.mutation(async ({ input, ctx }) => {
|
|
212
413
|
log('publishOrCreate input: %O', input);
|
|
@@ -294,3 +495,5 @@ export const agentGroupRouter = router({
|
|
|
294
495
|
}
|
|
295
496
|
}),
|
|
296
497
|
});
|
|
498
|
+
|
|
499
|
+
export type AgentGroupRouter = typeof agentGroupRouter;
|