@lobehub/lobehub 2.0.0-next.334 → 2.0.0-next.336
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 +58 -0
- package/changelog/v1.json +17 -0
- package/docs/development/database-schema.dbml +34 -0
- package/package.json +1 -1
- package/packages/builtin-tool-group-management/src/manifest.ts +54 -53
- package/packages/builtin-tool-group-management/src/systemRole.ts +43 -111
- package/packages/context-engine/src/engine/tools/ToolArgumentsRepairer.ts +129 -0
- package/packages/context-engine/src/engine/tools/__tests__/ToolArgumentsRepairer.test.ts +186 -0
- package/packages/context-engine/src/engine/tools/index.ts +3 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/tasks/index.ts +2 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/tasks/with-assistant-group.json +156 -0
- package/packages/conversation-flow/src/__tests__/parse.test.ts +22 -0
- package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +88 -11
- package/packages/database/migrations/0070_add_user_memory_activities.sql +35 -0
- package/packages/database/migrations/meta/0070_snapshot.json +10656 -0
- package/packages/database/migrations/meta/_journal.json +8 -1
- package/packages/database/src/schemas/userMemories/index.ts +71 -0
- package/packages/types/src/openai/chat.ts +0 -4
- package/src/app/[variants]/(main)/community/(detail)/user/features/DetailProvider.tsx +5 -1
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserAgentCard.tsx +8 -8
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserGroupCard.tsx +142 -15
- package/src/app/[variants]/(main)/community/(detail)/user/features/useUserDetail.ts +45 -20
- package/src/server/routers/lambda/market/agentGroup.ts +179 -1
- package/src/server/services/discover/index.ts +4 -0
- package/src/services/chat/chat.test.ts +109 -104
- package/src/services/chat/index.ts +13 -32
- package/src/services/chat/mecha/agentConfigResolver.test.ts +113 -0
- package/src/services/chat/mecha/agentConfigResolver.ts +15 -5
- package/src/services/marketApi.ts +14 -0
- package/src/store/chat/agents/__tests__/createAgentExecutors/helpers/testExecutor.ts +13 -0
- package/src/store/chat/agents/createAgentExecutors.ts +13 -1
- package/src/store/chat/slices/aiChat/actions/__tests__/conversationControl.test.ts +5 -1
- package/src/store/chat/slices/aiChat/actions/__tests__/fixtures.ts +14 -0
- package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +131 -7
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +61 -62
- package/src/store/chat/slices/plugin/action.test.ts +71 -0
- package/src/store/chat/slices/plugin/actions/internals.ts +14 -5
|
@@ -202,6 +202,66 @@ export const agentGroupRouter = router({
|
|
|
202
202
|
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
|
+
* Deprecate agent group
|
|
206
|
+
* POST /market/agent-group/:identifier/deprecate
|
|
207
|
+
*/
|
|
208
|
+
deprecateAgentGroup: agentGroupProcedure
|
|
209
|
+
.input(z.object({ identifier: z.string() }))
|
|
210
|
+
.mutation(async ({ input, ctx }) => {
|
|
211
|
+
log('deprecateAgentGroup input: %O', input);
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
const deprecateUrl = `${MARKET_BASE_URL}/api/v1/agent-groups/${input.identifier}/deprecate`;
|
|
215
|
+
|
|
216
|
+
const headers: Record<string, string> = {
|
|
217
|
+
'Content-Type': 'application/json',
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
221
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
222
|
+
|
|
223
|
+
if (userInfo) {
|
|
224
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
225
|
+
if (trustedClientToken) {
|
|
226
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
231
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const response = await fetch(deprecateUrl, {
|
|
235
|
+
headers,
|
|
236
|
+
method: 'POST',
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
if (!response.ok) {
|
|
240
|
+
const errorText = await response.text();
|
|
241
|
+
log(
|
|
242
|
+
'Deprecate agent group failed: %s %s - %s',
|
|
243
|
+
response.status,
|
|
244
|
+
response.statusText,
|
|
245
|
+
errorText,
|
|
246
|
+
);
|
|
247
|
+
throw new Error(`Failed to deprecate agent group: ${response.statusText}`);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
log('Deprecate agent group success');
|
|
251
|
+
return { success: true };
|
|
252
|
+
} catch (error) {
|
|
253
|
+
log('Error deprecating agent group: %O', error);
|
|
254
|
+
throw new TRPCError({
|
|
255
|
+
cause: error,
|
|
256
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
257
|
+
message: error instanceof Error ? error.message : 'Failed to deprecate agent group',
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}),
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
/**
|
|
205
265
|
* Fork an agent group
|
|
206
266
|
* POST /market/agent-group/:identifier/fork
|
|
207
267
|
*/
|
|
@@ -340,7 +400,6 @@ getAgentGroupForkSource: agentGroupProcedure
|
|
|
340
400
|
|
|
341
401
|
|
|
342
402
|
|
|
343
|
-
|
|
344
403
|
/**
|
|
345
404
|
* Get all forks of an agent group
|
|
346
405
|
* GET /market/agent-group/:identifier/forks
|
|
@@ -401,6 +460,66 @@ getAgentGroupForks: agentGroupProcedure
|
|
|
401
460
|
|
|
402
461
|
|
|
403
462
|
|
|
463
|
+
/**
|
|
464
|
+
* Publish agent group
|
|
465
|
+
* POST /market/agent-group/:identifier/publish
|
|
466
|
+
*/
|
|
467
|
+
publishAgentGroup: agentGroupProcedure
|
|
468
|
+
.input(z.object({ identifier: z.string() }))
|
|
469
|
+
.mutation(async ({ input, ctx }) => {
|
|
470
|
+
log('publishAgentGroup input: %O', input);
|
|
471
|
+
|
|
472
|
+
try {
|
|
473
|
+
const publishUrl = `${MARKET_BASE_URL}/api/v1/agent-groups/${input.identifier}/publish`;
|
|
474
|
+
|
|
475
|
+
const headers: Record<string, string> = {
|
|
476
|
+
'Content-Type': 'application/json',
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
480
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
481
|
+
|
|
482
|
+
if (userInfo) {
|
|
483
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
484
|
+
if (trustedClientToken) {
|
|
485
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
490
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
const response = await fetch(publishUrl, {
|
|
494
|
+
headers,
|
|
495
|
+
method: 'POST',
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
if (!response.ok) {
|
|
499
|
+
const errorText = await response.text();
|
|
500
|
+
log(
|
|
501
|
+
'Publish agent group failed: %s %s - %s',
|
|
502
|
+
response.status,
|
|
503
|
+
response.statusText,
|
|
504
|
+
errorText,
|
|
505
|
+
);
|
|
506
|
+
throw new Error(`Failed to publish agent group: ${response.statusText}`);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
log('Publish agent group success');
|
|
510
|
+
return { success: true };
|
|
511
|
+
} catch (error) {
|
|
512
|
+
log('Error publishing agent group: %O', error);
|
|
513
|
+
throw new TRPCError({
|
|
514
|
+
cause: error,
|
|
515
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
516
|
+
message: error instanceof Error ? error.message : 'Failed to publish agent group',
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
}),
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|
|
404
523
|
/**
|
|
405
524
|
* Unified publish or create agent group flow
|
|
406
525
|
* 1. Check if identifier exists and if current user is owner
|
|
@@ -494,6 +613,65 @@ publishOrCreate: agentGroupProcedure
|
|
|
494
613
|
});
|
|
495
614
|
}
|
|
496
615
|
}),
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Unpublish agent group
|
|
620
|
+
* POST /market/agent-group/:identifier/unpublish
|
|
621
|
+
*/
|
|
622
|
+
unpublishAgentGroup: agentGroupProcedure
|
|
623
|
+
.input(z.object({ identifier: z.string() }))
|
|
624
|
+
.mutation(async ({ input, ctx }) => {
|
|
625
|
+
log('unpublishAgentGroup input: %O', input);
|
|
626
|
+
|
|
627
|
+
try {
|
|
628
|
+
const unpublishUrl = `${MARKET_BASE_URL}/api/v1/agent-groups/${input.identifier}/unpublish`;
|
|
629
|
+
|
|
630
|
+
const headers: Record<string, string> = {
|
|
631
|
+
'Content-Type': 'application/json',
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
const userInfo = ctx.marketUserInfo as TrustedClientUserInfo | undefined;
|
|
635
|
+
const accessToken = (ctx as { marketOidcAccessToken?: string }).marketOidcAccessToken;
|
|
636
|
+
|
|
637
|
+
if (userInfo) {
|
|
638
|
+
const trustedClientToken = generateTrustedClientToken(userInfo);
|
|
639
|
+
if (trustedClientToken) {
|
|
640
|
+
headers['x-lobe-trust-token'] = trustedClientToken;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
if (!headers['x-lobe-trust-token'] && accessToken) {
|
|
645
|
+
headers['Authorization'] = `Bearer ${accessToken}`;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
const response = await fetch(unpublishUrl, {
|
|
649
|
+
headers,
|
|
650
|
+
method: 'POST',
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
if (!response.ok) {
|
|
654
|
+
const errorText = await response.text();
|
|
655
|
+
log(
|
|
656
|
+
'Unpublish agent group failed: %s %s - %s',
|
|
657
|
+
response.status,
|
|
658
|
+
response.statusText,
|
|
659
|
+
errorText,
|
|
660
|
+
);
|
|
661
|
+
throw new Error(`Failed to unpublish agent group: ${response.statusText}`);
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
log('Unpublish agent group success');
|
|
665
|
+
return { success: true };
|
|
666
|
+
} catch (error) {
|
|
667
|
+
log('Error unpublishing agent group: %O', error);
|
|
668
|
+
throw new TRPCError({
|
|
669
|
+
cause: error,
|
|
670
|
+
code: 'INTERNAL_SERVER_ERROR',
|
|
671
|
+
message: error instanceof Error ? error.message : 'Failed to unpublish agent group',
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
}),
|
|
497
675
|
});
|
|
498
676
|
|
|
499
677
|
export type AgentGroupRouter = typeof agentGroupRouter;
|
|
@@ -1761,6 +1761,7 @@ export class DiscoverService {
|
|
|
1761
1761
|
knowledgeCount: agent.knowledgeCount || 0,
|
|
1762
1762
|
pluginCount: agent.pluginCount || 0,
|
|
1763
1763
|
schemaVersion: 1,
|
|
1764
|
+
status: agent.status,
|
|
1764
1765
|
tags: agent.tags || [],
|
|
1765
1766
|
title: agent.name || agent.identifier,
|
|
1766
1767
|
tokenUsage: agent.tokenUsage || 0,
|
|
@@ -1780,6 +1781,7 @@ export class DiscoverService {
|
|
|
1780
1781
|
isOfficial: group.isOfficial || false,
|
|
1781
1782
|
memberCount: 0, // Will be populated from memberAgents in detail view
|
|
1782
1783
|
schemaVersion: 1,
|
|
1784
|
+
status: group.status,
|
|
1783
1785
|
tags: group.tags || [],
|
|
1784
1786
|
title: group.name || group.identifier,
|
|
1785
1787
|
updatedAt: group.updatedAt,
|
|
@@ -1802,6 +1804,7 @@ export class DiscoverService {
|
|
|
1802
1804
|
knowledgeCount: agent.knowledgeCount || 0,
|
|
1803
1805
|
pluginCount: agent.pluginCount || 0,
|
|
1804
1806
|
schemaVersion: 1,
|
|
1807
|
+
status: agent.status,
|
|
1805
1808
|
tags: agent.tags || [],
|
|
1806
1809
|
title: agent.name || agent.identifier,
|
|
1807
1810
|
tokenUsage: agent.tokenUsage || 0,
|
|
@@ -1824,6 +1827,7 @@ export class DiscoverService {
|
|
|
1824
1827
|
isOfficial: group.isOfficial || false,
|
|
1825
1828
|
memberCount: 0, // Will be populated from memberAgents in detail view
|
|
1826
1829
|
schemaVersion: 1,
|
|
1830
|
+
status: group.status,
|
|
1827
1831
|
tags: group.tags || [],
|
|
1828
1832
|
title: group.name || group.identifier,
|
|
1829
1833
|
updatedAt: group.updatedAt,
|
|
@@ -15,6 +15,35 @@ import { aiModelSelectors } from '@/store/aiInfra';
|
|
|
15
15
|
import { useToolStore } from '@/store/tool';
|
|
16
16
|
|
|
17
17
|
import { chatService } from './index';
|
|
18
|
+
import type { ResolvedAgentConfig } from './mecha';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Default mock resolvedAgentConfig for tests
|
|
22
|
+
*/
|
|
23
|
+
const createMockResolvedConfig = (overrides?: {
|
|
24
|
+
agentConfig?: Partial<ResolvedAgentConfig['agentConfig']>;
|
|
25
|
+
chatConfig?: Partial<ResolvedAgentConfig['chatConfig']>;
|
|
26
|
+
plugins?: string[];
|
|
27
|
+
isBuiltinAgent?: boolean;
|
|
28
|
+
}): ResolvedAgentConfig =>
|
|
29
|
+
({
|
|
30
|
+
agentConfig: {
|
|
31
|
+
model: DEFAULT_AGENT_CONFIG.model,
|
|
32
|
+
provider: 'openai',
|
|
33
|
+
systemRole: '',
|
|
34
|
+
chatConfig: {},
|
|
35
|
+
params: {},
|
|
36
|
+
tts: {},
|
|
37
|
+
...overrides?.agentConfig,
|
|
38
|
+
},
|
|
39
|
+
chatConfig: {
|
|
40
|
+
searchMode: 'off',
|
|
41
|
+
autoCreateTopicThreshold: 2,
|
|
42
|
+
...overrides?.chatConfig,
|
|
43
|
+
},
|
|
44
|
+
isBuiltinAgent: overrides?.isBuiltinAgent ?? false,
|
|
45
|
+
plugins: overrides?.plugins ?? [],
|
|
46
|
+
}) as ResolvedAgentConfig;
|
|
18
47
|
|
|
19
48
|
// Mocking external dependencies
|
|
20
49
|
vi.mock('i18next', () => ({
|
|
@@ -109,7 +138,10 @@ describe('ChatService', () => {
|
|
|
109
138
|
],
|
|
110
139
|
});
|
|
111
140
|
});
|
|
112
|
-
await chatService.createAssistantMessage({
|
|
141
|
+
await chatService.createAssistantMessage({
|
|
142
|
+
messages,
|
|
143
|
+
resolvedAgentConfig: createMockResolvedConfig({ plugins: enabledPlugins }),
|
|
144
|
+
});
|
|
113
145
|
|
|
114
146
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
115
147
|
expect.objectContaining({
|
|
@@ -136,21 +168,14 @@ describe('ChatService', () => {
|
|
|
136
168
|
vi.spyOn(aiModelSelectors, 'isModelHasExtendParams').mockReturnValue(() => true);
|
|
137
169
|
vi.spyOn(aiModelSelectors, 'modelExtendParams').mockReturnValue(() => ['enableReasoning']);
|
|
138
170
|
|
|
139
|
-
// Mock agent chat config with reasoning enabled
|
|
140
|
-
vi.spyOn(chatConfigByIdSelectors, 'getChatConfigById').mockReturnValue(
|
|
141
|
-
() =>
|
|
142
|
-
({
|
|
143
|
-
enableReasoning: true,
|
|
144
|
-
reasoningBudgetToken: 2048,
|
|
145
|
-
searchMode: 'off',
|
|
146
|
-
}) as any,
|
|
147
|
-
);
|
|
148
|
-
|
|
149
171
|
await chatService.createAssistantMessage({
|
|
150
172
|
messages,
|
|
151
173
|
model: 'deepseek-reasoner',
|
|
152
174
|
provider: 'deepseek',
|
|
153
|
-
|
|
175
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
176
|
+
agentConfig: { model: 'deepseek-reasoner', provider: 'deepseek' },
|
|
177
|
+
chatConfig: { enableReasoning: true, reasoningBudgetToken: 2048 },
|
|
178
|
+
}),
|
|
154
179
|
});
|
|
155
180
|
|
|
156
181
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -172,20 +197,14 @@ describe('ChatService', () => {
|
|
|
172
197
|
vi.spyOn(aiModelSelectors, 'isModelHasExtendParams').mockReturnValue(() => true);
|
|
173
198
|
vi.spyOn(aiModelSelectors, 'modelExtendParams').mockReturnValue(() => ['enableReasoning']);
|
|
174
199
|
|
|
175
|
-
// Mock agent chat config with reasoning disabled
|
|
176
|
-
vi.spyOn(chatConfigByIdSelectors, 'getChatConfigById').mockReturnValue(
|
|
177
|
-
() =>
|
|
178
|
-
({
|
|
179
|
-
enableReasoning: false,
|
|
180
|
-
searchMode: 'off',
|
|
181
|
-
}) as any,
|
|
182
|
-
);
|
|
183
|
-
|
|
184
200
|
await chatService.createAssistantMessage({
|
|
185
201
|
messages,
|
|
186
202
|
model: 'deepseek-reasoner',
|
|
187
203
|
provider: 'deepseek',
|
|
188
|
-
|
|
204
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
205
|
+
agentConfig: { model: 'deepseek-reasoner', provider: 'deepseek' },
|
|
206
|
+
chatConfig: { enableReasoning: false },
|
|
207
|
+
}),
|
|
189
208
|
});
|
|
190
209
|
|
|
191
210
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -207,21 +226,15 @@ describe('ChatService', () => {
|
|
|
207
226
|
vi.spyOn(aiModelSelectors, 'isModelHasExtendParams').mockReturnValue(() => true);
|
|
208
227
|
vi.spyOn(aiModelSelectors, 'modelExtendParams').mockReturnValue(() => ['enableReasoning']);
|
|
209
228
|
|
|
210
|
-
// Mock agent chat config with reasoning enabled but no custom budget
|
|
211
|
-
vi.spyOn(chatConfigByIdSelectors, 'getChatConfigById').mockReturnValue(
|
|
212
|
-
() =>
|
|
213
|
-
({
|
|
214
|
-
enableReasoning: true,
|
|
215
|
-
// reasoningBudgetToken is undefined
|
|
216
|
-
searchMode: 'off',
|
|
217
|
-
}) as any,
|
|
218
|
-
);
|
|
219
|
-
|
|
220
229
|
await chatService.createAssistantMessage({
|
|
221
230
|
messages,
|
|
222
231
|
model: 'deepseek-reasoner',
|
|
223
232
|
provider: 'deepseek',
|
|
224
|
-
|
|
233
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
234
|
+
agentConfig: { model: 'deepseek-reasoner', provider: 'deepseek' },
|
|
235
|
+
// enableReasoning is true, but reasoningBudgetToken is undefined
|
|
236
|
+
chatConfig: { enableReasoning: true },
|
|
237
|
+
}),
|
|
225
238
|
});
|
|
226
239
|
|
|
227
240
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -243,20 +256,14 @@ describe('ChatService', () => {
|
|
|
243
256
|
vi.spyOn(aiModelSelectors, 'isModelHasExtendParams').mockReturnValue(() => true);
|
|
244
257
|
vi.spyOn(aiModelSelectors, 'modelExtendParams').mockReturnValue(() => ['reasoningEffort']);
|
|
245
258
|
|
|
246
|
-
// Mock agent chat config with reasoning effort set
|
|
247
|
-
vi.spyOn(chatConfigByIdSelectors, 'getChatConfigById').mockReturnValue(
|
|
248
|
-
() =>
|
|
249
|
-
({
|
|
250
|
-
reasoningEffort: 'high',
|
|
251
|
-
searchMode: 'off',
|
|
252
|
-
}) as any,
|
|
253
|
-
);
|
|
254
|
-
|
|
255
259
|
await chatService.createAssistantMessage({
|
|
256
260
|
messages,
|
|
257
261
|
model: 'test-model',
|
|
258
262
|
provider: 'test-provider',
|
|
259
|
-
|
|
263
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
264
|
+
agentConfig: { model: 'test-model', provider: 'test-provider' },
|
|
265
|
+
chatConfig: { reasoningEffort: 'high' },
|
|
266
|
+
}),
|
|
260
267
|
});
|
|
261
268
|
|
|
262
269
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -275,20 +282,14 @@ describe('ChatService', () => {
|
|
|
275
282
|
vi.spyOn(aiModelSelectors, 'isModelHasExtendParams').mockReturnValue(() => true);
|
|
276
283
|
vi.spyOn(aiModelSelectors, 'modelExtendParams').mockReturnValue(() => ['thinkingBudget']);
|
|
277
284
|
|
|
278
|
-
// Mock agent chat config with thinking budget set
|
|
279
|
-
vi.spyOn(chatConfigByIdSelectors, 'getChatConfigById').mockReturnValue(
|
|
280
|
-
() =>
|
|
281
|
-
({
|
|
282
|
-
thinkingBudget: 5000,
|
|
283
|
-
searchMode: 'off',
|
|
284
|
-
}) as any,
|
|
285
|
-
);
|
|
286
|
-
|
|
287
285
|
await chatService.createAssistantMessage({
|
|
288
286
|
messages,
|
|
289
287
|
model: 'test-model',
|
|
290
288
|
provider: 'test-provider',
|
|
291
|
-
|
|
289
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
290
|
+
agentConfig: { model: 'test-model', provider: 'test-provider' },
|
|
291
|
+
chatConfig: { thinkingBudget: 5000 },
|
|
292
|
+
}),
|
|
292
293
|
});
|
|
293
294
|
|
|
294
295
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -329,9 +330,11 @@ describe('ChatService', () => {
|
|
|
329
330
|
const getChatCompletionSpy = vi.spyOn(chatService, 'getChatCompletion');
|
|
330
331
|
await chatService.createAssistantMessage({
|
|
331
332
|
messages,
|
|
332
|
-
plugins: [],
|
|
333
333
|
model: 'gpt-4-vision-preview',
|
|
334
334
|
provider: 'openai',
|
|
335
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
336
|
+
agentConfig: { model: 'gpt-4-vision-preview', provider: 'openai' },
|
|
337
|
+
}),
|
|
335
338
|
});
|
|
336
339
|
|
|
337
340
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -378,7 +381,10 @@ describe('ChatService', () => {
|
|
|
378
381
|
] as UIChatMessage[];
|
|
379
382
|
|
|
380
383
|
const getChatCompletionSpy = vi.spyOn(chatService, 'getChatCompletion');
|
|
381
|
-
await chatService.createAssistantMessage({
|
|
384
|
+
await chatService.createAssistantMessage({
|
|
385
|
+
messages,
|
|
386
|
+
resolvedAgentConfig: createMockResolvedConfig(),
|
|
387
|
+
});
|
|
382
388
|
|
|
383
389
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
384
390
|
{
|
|
@@ -435,8 +441,10 @@ describe('ChatService', () => {
|
|
|
435
441
|
|
|
436
442
|
await chatService.createAssistantMessage({
|
|
437
443
|
messages,
|
|
438
|
-
plugins: [],
|
|
439
444
|
model: 'gpt-4-vision-preview',
|
|
445
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
446
|
+
agentConfig: { model: 'gpt-4-vision-preview' },
|
|
447
|
+
}),
|
|
440
448
|
});
|
|
441
449
|
|
|
442
450
|
// Verify the utility functions were called
|
|
@@ -525,8 +533,10 @@ describe('ChatService', () => {
|
|
|
525
533
|
|
|
526
534
|
await chatService.createAssistantMessage({
|
|
527
535
|
messages,
|
|
528
|
-
plugins: [],
|
|
529
536
|
model: 'gpt-4-vision-preview',
|
|
537
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
538
|
+
agentConfig: { model: 'gpt-4-vision-preview' },
|
|
539
|
+
}),
|
|
530
540
|
});
|
|
531
541
|
|
|
532
542
|
// Verify the utility functions were called
|
|
@@ -630,8 +640,10 @@ describe('ChatService', () => {
|
|
|
630
640
|
|
|
631
641
|
await chatService.createAssistantMessage({
|
|
632
642
|
messages,
|
|
633
|
-
plugins: [],
|
|
634
643
|
model: 'gpt-4-vision-preview',
|
|
644
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
645
|
+
agentConfig: { model: 'gpt-4-vision-preview' },
|
|
646
|
+
}),
|
|
635
647
|
});
|
|
636
648
|
|
|
637
649
|
// Verify isDesktopLocalStaticServerUrl was called for each image
|
|
@@ -730,7 +742,10 @@ describe('ChatService', () => {
|
|
|
730
742
|
messages,
|
|
731
743
|
model: 'gpt-3.5-turbo-1106',
|
|
732
744
|
top_p: 1,
|
|
733
|
-
|
|
745
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
746
|
+
agentConfig: { model: 'gpt-3.5-turbo-1106' },
|
|
747
|
+
plugins: ['seo'],
|
|
748
|
+
}),
|
|
734
749
|
});
|
|
735
750
|
|
|
736
751
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -832,7 +847,10 @@ describe('ChatService', () => {
|
|
|
832
847
|
messages,
|
|
833
848
|
model: 'gpt-3.5-turbo-1106',
|
|
834
849
|
top_p: 1,
|
|
835
|
-
|
|
850
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
851
|
+
agentConfig: { model: 'gpt-3.5-turbo-1106' },
|
|
852
|
+
plugins: ['seo'],
|
|
853
|
+
}),
|
|
836
854
|
});
|
|
837
855
|
|
|
838
856
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -888,7 +906,9 @@ describe('ChatService', () => {
|
|
|
888
906
|
messages,
|
|
889
907
|
model: 'gpt-3.5-turbo-1106',
|
|
890
908
|
top_p: 1,
|
|
891
|
-
|
|
909
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
910
|
+
agentConfig: { model: 'gpt-3.5-turbo-1106' },
|
|
911
|
+
}),
|
|
892
912
|
});
|
|
893
913
|
|
|
894
914
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -949,7 +969,10 @@ describe('ChatService', () => {
|
|
|
949
969
|
mockToolsEngine as any,
|
|
950
970
|
);
|
|
951
971
|
|
|
952
|
-
await chatService.createAssistantMessage({
|
|
972
|
+
await chatService.createAssistantMessage({
|
|
973
|
+
messages,
|
|
974
|
+
resolvedAgentConfig: createMockResolvedConfig(),
|
|
975
|
+
});
|
|
953
976
|
|
|
954
977
|
// Verify tools were passed to getChatCompletion
|
|
955
978
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -1003,7 +1026,10 @@ describe('ChatService', () => {
|
|
|
1003
1026
|
mockToolsEngine as any,
|
|
1004
1027
|
);
|
|
1005
1028
|
|
|
1006
|
-
await chatService.createAssistantMessage({
|
|
1029
|
+
await chatService.createAssistantMessage({
|
|
1030
|
+
messages,
|
|
1031
|
+
resolvedAgentConfig: createMockResolvedConfig(),
|
|
1032
|
+
});
|
|
1007
1033
|
|
|
1008
1034
|
// Verify enabledSearch was set to true
|
|
1009
1035
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -1051,7 +1077,10 @@ describe('ChatService', () => {
|
|
|
1051
1077
|
mockToolsEngine as any,
|
|
1052
1078
|
);
|
|
1053
1079
|
|
|
1054
|
-
await chatService.createAssistantMessage({
|
|
1080
|
+
await chatService.createAssistantMessage({
|
|
1081
|
+
messages,
|
|
1082
|
+
resolvedAgentConfig: createMockResolvedConfig(),
|
|
1083
|
+
});
|
|
1055
1084
|
|
|
1056
1085
|
// Verify enabledSearch was not set
|
|
1057
1086
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -1342,20 +1371,14 @@ describe('ChatService private methods', () => {
|
|
|
1342
1371
|
'disableContextCaching',
|
|
1343
1372
|
]);
|
|
1344
1373
|
|
|
1345
|
-
// Mock agent chat config with context caching disabled
|
|
1346
|
-
vi.spyOn(chatConfigByIdSelectors, 'getChatConfigById').mockReturnValue(
|
|
1347
|
-
() =>
|
|
1348
|
-
({
|
|
1349
|
-
disableContextCaching: true,
|
|
1350
|
-
searchMode: 'off',
|
|
1351
|
-
}) as any,
|
|
1352
|
-
);
|
|
1353
|
-
|
|
1354
1374
|
await chatService.createAssistantMessage({
|
|
1355
1375
|
messages,
|
|
1356
1376
|
model: 'test-model',
|
|
1357
1377
|
provider: 'test-provider',
|
|
1358
|
-
|
|
1378
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
1379
|
+
agentConfig: { model: 'test-model', provider: 'test-provider' },
|
|
1380
|
+
chatConfig: { disableContextCaching: true },
|
|
1381
|
+
}),
|
|
1359
1382
|
});
|
|
1360
1383
|
|
|
1361
1384
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -1378,20 +1401,14 @@ describe('ChatService private methods', () => {
|
|
|
1378
1401
|
'disableContextCaching',
|
|
1379
1402
|
]);
|
|
1380
1403
|
|
|
1381
|
-
// Mock agent chat config with context caching enabled (default)
|
|
1382
|
-
vi.spyOn(chatConfigByIdSelectors, 'getChatConfigById').mockReturnValue(
|
|
1383
|
-
() =>
|
|
1384
|
-
({
|
|
1385
|
-
disableContextCaching: false,
|
|
1386
|
-
searchMode: 'off',
|
|
1387
|
-
}) as any,
|
|
1388
|
-
);
|
|
1389
|
-
|
|
1390
1404
|
await chatService.createAssistantMessage({
|
|
1391
1405
|
messages,
|
|
1392
1406
|
model: 'test-model',
|
|
1393
1407
|
provider: 'test-provider',
|
|
1394
|
-
|
|
1408
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
1409
|
+
agentConfig: { model: 'test-model', provider: 'test-provider' },
|
|
1410
|
+
chatConfig: { disableContextCaching: false },
|
|
1411
|
+
}),
|
|
1395
1412
|
});
|
|
1396
1413
|
|
|
1397
1414
|
// enabledContextCaching should not be present in the call
|
|
@@ -1407,20 +1424,14 @@ describe('ChatService private methods', () => {
|
|
|
1407
1424
|
vi.spyOn(aiModelSelectors, 'isModelHasExtendParams').mockReturnValue(() => true);
|
|
1408
1425
|
vi.spyOn(aiModelSelectors, 'modelExtendParams').mockReturnValue(() => ['reasoningEffort']);
|
|
1409
1426
|
|
|
1410
|
-
// Mock agent chat config with reasoning effort set
|
|
1411
|
-
vi.spyOn(chatConfigByIdSelectors, 'getChatConfigById').mockReturnValue(
|
|
1412
|
-
() =>
|
|
1413
|
-
({
|
|
1414
|
-
reasoningEffort: 'high',
|
|
1415
|
-
searchMode: 'off',
|
|
1416
|
-
}) as any,
|
|
1417
|
-
);
|
|
1418
|
-
|
|
1419
1427
|
await chatService.createAssistantMessage({
|
|
1420
1428
|
messages,
|
|
1421
1429
|
model: 'test-model',
|
|
1422
1430
|
provider: 'test-provider',
|
|
1423
|
-
|
|
1431
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
1432
|
+
agentConfig: { model: 'test-model', provider: 'test-provider' },
|
|
1433
|
+
chatConfig: { reasoningEffort: 'high' },
|
|
1434
|
+
}),
|
|
1424
1435
|
});
|
|
1425
1436
|
|
|
1426
1437
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
|
@@ -1439,20 +1450,14 @@ describe('ChatService private methods', () => {
|
|
|
1439
1450
|
vi.spyOn(aiModelSelectors, 'isModelHasExtendParams').mockReturnValue(() => true);
|
|
1440
1451
|
vi.spyOn(aiModelSelectors, 'modelExtendParams').mockReturnValue(() => ['thinkingBudget']);
|
|
1441
1452
|
|
|
1442
|
-
// Mock agent chat config with thinking budget set
|
|
1443
|
-
vi.spyOn(chatConfigByIdSelectors, 'getChatConfigById').mockReturnValue(
|
|
1444
|
-
() =>
|
|
1445
|
-
({
|
|
1446
|
-
thinkingBudget: 5000,
|
|
1447
|
-
searchMode: 'off',
|
|
1448
|
-
}) as any,
|
|
1449
|
-
);
|
|
1450
|
-
|
|
1451
1453
|
await chatService.createAssistantMessage({
|
|
1452
1454
|
messages,
|
|
1453
1455
|
model: 'test-model',
|
|
1454
1456
|
provider: 'test-provider',
|
|
1455
|
-
|
|
1457
|
+
resolvedAgentConfig: createMockResolvedConfig({
|
|
1458
|
+
agentConfig: { model: 'test-model', provider: 'test-provider' },
|
|
1459
|
+
chatConfig: { thinkingBudget: 5000 },
|
|
1460
|
+
}),
|
|
1456
1461
|
});
|
|
1457
1462
|
|
|
1458
1463
|
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|