@lobehub/lobehub 2.0.0-next.335 → 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 +33 -0
- package/changelog/v1.json +12 -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/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
|
@@ -146,6 +146,20 @@ export class MarketApiService {
|
|
|
146
146
|
return lambdaClient.market.agent.getAgentForkSource.query({ identifier });
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
// ==================== Agent Group Status Management ====================
|
|
150
|
+
|
|
151
|
+
async publishAgentGroup(identifier: string): Promise<void> {
|
|
152
|
+
await lambdaClient.market.agentGroup.publishAgentGroup.mutate({ identifier });
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async unpublishAgentGroup(identifier: string): Promise<void> {
|
|
156
|
+
await lambdaClient.market.agentGroup.unpublishAgentGroup.mutate({ identifier });
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async deprecateAgentGroup(identifier: string): Promise<void> {
|
|
160
|
+
await lambdaClient.market.agentGroup.deprecateAgentGroup.mutate({ identifier });
|
|
161
|
+
}
|
|
162
|
+
|
|
149
163
|
// ==================== Fork Agent Group API ====================
|
|
150
164
|
|
|
151
165
|
/**
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import type { AgentInstruction, AgentState } from '@lobechat/agent-runtime';
|
|
2
2
|
|
|
3
|
+
import { DEFAULT_AGENT_CHAT_CONFIG, DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
|
4
|
+
import type { ResolvedAgentConfig } from '@/services/chat/mecha';
|
|
3
5
|
import { createAgentExecutors } from '@/store/chat/agents/createAgentExecutors';
|
|
4
6
|
import type { OperationType } from '@/store/chat/slices/operation/types';
|
|
5
7
|
import type { ChatStore } from '@/store/chat/store';
|
|
6
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Create a mock ResolvedAgentConfig for testing
|
|
11
|
+
*/
|
|
12
|
+
const createMockResolvedAgentConfig = (): ResolvedAgentConfig => ({
|
|
13
|
+
agentConfig: { ...DEFAULT_AGENT_CONFIG },
|
|
14
|
+
chatConfig: { ...DEFAULT_AGENT_CHAT_CONFIG },
|
|
15
|
+
isBuiltinAgent: false,
|
|
16
|
+
plugins: [],
|
|
17
|
+
});
|
|
18
|
+
|
|
7
19
|
/**
|
|
8
20
|
* Execute an executor with mock context
|
|
9
21
|
*
|
|
@@ -60,6 +72,7 @@ export const executeWithMockContext = async ({
|
|
|
60
72
|
|
|
61
73
|
// Create executors with mock context
|
|
62
74
|
const executors = createAgentExecutors({
|
|
75
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
63
76
|
get: () => mockStore,
|
|
64
77
|
messageKey: context.messageKey,
|
|
65
78
|
operationId: context.operationId,
|
|
@@ -22,6 +22,8 @@ import type { ChatToolPayload, ConversationContext, CreateMessageParams } from '
|
|
|
22
22
|
import debug from 'debug';
|
|
23
23
|
import pMap from 'p-map';
|
|
24
24
|
|
|
25
|
+
import type { ResolvedAgentConfig } from '@/services/chat/mecha';
|
|
26
|
+
|
|
25
27
|
import { LOADING_FLAT } from '@/const/message';
|
|
26
28
|
import { aiAgentService } from '@/services/aiAgent';
|
|
27
29
|
import { agentByIdSelectors } from '@/store/agent/selectors';
|
|
@@ -49,6 +51,8 @@ const TOOL_PRICING: Record<string, number> = {
|
|
|
49
51
|
* @param context.skipCreateFirstMessage - Skip first message creation
|
|
50
52
|
*/
|
|
51
53
|
export const createAgentExecutors = (context: {
|
|
54
|
+
/** Pre-resolved agent config with isSubTask filtering applied */
|
|
55
|
+
agentConfig: ResolvedAgentConfig;
|
|
52
56
|
get: () => ChatStore;
|
|
53
57
|
messageKey: string;
|
|
54
58
|
operationId: string;
|
|
@@ -169,6 +173,7 @@ export const createAgentExecutors = (context: {
|
|
|
169
173
|
model: llmPayload.model,
|
|
170
174
|
provider: llmPayload.provider,
|
|
171
175
|
operationId: context.operationId,
|
|
176
|
+
agentConfig: context.agentConfig, // Pass pre-resolved config
|
|
172
177
|
// Pass runtime context for page editor injection
|
|
173
178
|
initialContext: runtimeContext?.initialContext,
|
|
174
179
|
stepContext: runtimeContext?.stepContext,
|
|
@@ -1735,7 +1740,12 @@ export const createAgentExecutors = (context: {
|
|
|
1735
1740
|
const { threadId, userMessageId, threadMessages, messages } = threadResult;
|
|
1736
1741
|
|
|
1737
1742
|
// 3. Build sub-task ConversationContext (uses threadId for isolation)
|
|
1738
|
-
const subContext: ConversationContext = {
|
|
1743
|
+
const subContext: ConversationContext = {
|
|
1744
|
+
agentId,
|
|
1745
|
+
topicId,
|
|
1746
|
+
threadId,
|
|
1747
|
+
scope: 'thread',
|
|
1748
|
+
};
|
|
1739
1749
|
|
|
1740
1750
|
// 4. Create a child operation for task execution (now with threadId)
|
|
1741
1751
|
const { operationId: taskOperationId } = context.get().startOperation({
|
|
@@ -1784,6 +1794,7 @@ export const createAgentExecutors = (context: {
|
|
|
1784
1794
|
parentMessageType: 'user',
|
|
1785
1795
|
operationId: taskOperationId,
|
|
1786
1796
|
parentOperationId: state.operationId,
|
|
1797
|
+
isSubTask: true, // Disable lobe-gtd tools to prevent nested sub-tasks
|
|
1787
1798
|
});
|
|
1788
1799
|
|
|
1789
1800
|
log('[%s][exec_client_task] Client-side AgentRuntime execution completed', taskLogId);
|
|
@@ -2107,6 +2118,7 @@ export const createAgentExecutors = (context: {
|
|
|
2107
2118
|
parentMessageType: 'user',
|
|
2108
2119
|
operationId: taskOperationId,
|
|
2109
2120
|
parentOperationId: state.operationId,
|
|
2121
|
+
isSubTask: true, // Disable lobe-gtd tools to prevent nested sub-tasks
|
|
2110
2122
|
});
|
|
2111
2123
|
|
|
2112
2124
|
log('[%s] Client-side AgentRuntime execution completed', taskLogId);
|
|
@@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
4
4
|
|
|
5
5
|
import { useChatStore } from '../../../../store';
|
|
6
6
|
import { messageMapKey } from '../../../../utils/messageMapKey';
|
|
7
|
-
import { TEST_IDS, createMockMessage } from './fixtures';
|
|
7
|
+
import { TEST_IDS, createMockMessage, createMockResolvedAgentConfig } from './fixtures';
|
|
8
8
|
import { resetTestEnvironment } from './helpers';
|
|
9
9
|
|
|
10
10
|
// Keep zustand mock as it's needed globally
|
|
@@ -425,6 +425,7 @@ describe('ConversationControl actions', () => {
|
|
|
425
425
|
.mockReturnValue({
|
|
426
426
|
state: {} as any,
|
|
427
427
|
context: { phase: 'init' } as any,
|
|
428
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
428
429
|
});
|
|
429
430
|
const internal_execAgentRuntimeSpy = vi
|
|
430
431
|
.spyOn(result.current, 'internal_execAgentRuntime')
|
|
@@ -497,6 +498,7 @@ describe('ConversationControl actions', () => {
|
|
|
497
498
|
.mockReturnValue({
|
|
498
499
|
state: {} as any,
|
|
499
500
|
context: { phase: 'init' } as any,
|
|
501
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
500
502
|
});
|
|
501
503
|
const internal_execAgentRuntimeSpy = vi
|
|
502
504
|
.spyOn(result.current, 'internal_execAgentRuntime')
|
|
@@ -596,6 +598,7 @@ describe('ConversationControl actions', () => {
|
|
|
596
598
|
.mockReturnValue({
|
|
597
599
|
state: {} as any,
|
|
598
600
|
context: { phase: 'init' } as any,
|
|
601
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
599
602
|
});
|
|
600
603
|
const internal_execAgentRuntimeSpy = vi
|
|
601
604
|
.spyOn(result.current, 'internal_execAgentRuntime')
|
|
@@ -669,6 +672,7 @@ describe('ConversationControl actions', () => {
|
|
|
669
672
|
.mockReturnValue({
|
|
670
673
|
state: {} as any,
|
|
671
674
|
context: { phase: 'init' } as any,
|
|
675
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
672
676
|
});
|
|
673
677
|
const internal_execAgentRuntimeSpy = vi
|
|
674
678
|
.spyOn(result.current, 'internal_execAgentRuntime')
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type UIChatMessage } from '@lobechat/types';
|
|
2
2
|
|
|
3
3
|
import { DEFAULT_AGENT_CHAT_CONFIG, DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
|
4
|
+
import type { ResolvedAgentConfig } from '@/services/chat/mecha';
|
|
4
5
|
|
|
5
6
|
// Test Constants
|
|
6
7
|
export const TEST_IDS = {
|
|
@@ -63,3 +64,16 @@ export const createMockStoreState = (overrides = {}) => ({
|
|
|
63
64
|
toolCallingStreamIds: {},
|
|
64
65
|
...overrides,
|
|
65
66
|
});
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Create a mock ResolvedAgentConfig for testing
|
|
70
|
+
*/
|
|
71
|
+
export const createMockResolvedAgentConfig = (
|
|
72
|
+
overrides: Partial<ResolvedAgentConfig> = {},
|
|
73
|
+
): ResolvedAgentConfig => ({
|
|
74
|
+
agentConfig: createMockAgentConfig(),
|
|
75
|
+
chatConfig: createMockChatConfig(),
|
|
76
|
+
isBuiltinAgent: false,
|
|
77
|
+
plugins: [],
|
|
78
|
+
...overrides,
|
|
79
|
+
});
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
createMockAgentConfig,
|
|
14
14
|
createMockChatConfig,
|
|
15
15
|
createMockMessage,
|
|
16
|
+
createMockResolvedAgentConfig,
|
|
16
17
|
} from './fixtures';
|
|
17
18
|
import { resetTestEnvironment, setupMockSelectors, spyOnMessageService } from './helpers';
|
|
18
19
|
|
|
@@ -57,6 +58,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
57
58
|
messageId: TEST_IDS.ASSISTANT_MESSAGE_ID,
|
|
58
59
|
model: 'gpt-4o-mini',
|
|
59
60
|
provider: 'openai',
|
|
61
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
60
62
|
});
|
|
61
63
|
expect(response.isFunctionCall).toEqual(false);
|
|
62
64
|
expect(response.content).toEqual(TEST_CONTENT.AI_RESPONSE);
|
|
@@ -83,6 +85,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
83
85
|
provider: 'openai',
|
|
84
86
|
messages,
|
|
85
87
|
messageId: TEST_IDS.ASSISTANT_MESSAGE_ID,
|
|
88
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
86
89
|
});
|
|
87
90
|
});
|
|
88
91
|
|
|
@@ -127,6 +130,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
127
130
|
messageId: TEST_IDS.ASSISTANT_MESSAGE_ID,
|
|
128
131
|
model: 'gpt-4o-mini',
|
|
129
132
|
provider: 'openai',
|
|
133
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
130
134
|
});
|
|
131
135
|
expect(response.isFunctionCall).toEqual(true);
|
|
132
136
|
});
|
|
@@ -165,6 +169,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
165
169
|
model: 'gpt-4o-mini',
|
|
166
170
|
provider: 'openai',
|
|
167
171
|
operationId,
|
|
172
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
168
173
|
});
|
|
169
174
|
});
|
|
170
175
|
|
|
@@ -213,6 +218,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
213
218
|
model: 'gpt-4o-mini',
|
|
214
219
|
provider: 'openai',
|
|
215
220
|
operationId,
|
|
221
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
216
222
|
});
|
|
217
223
|
});
|
|
218
224
|
|
|
@@ -251,6 +257,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
251
257
|
messageId: TEST_IDS.ASSISTANT_MESSAGE_ID,
|
|
252
258
|
model: 'gpt-4o-mini',
|
|
253
259
|
provider: 'openai',
|
|
260
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
254
261
|
});
|
|
255
262
|
});
|
|
256
263
|
|
|
@@ -300,6 +307,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
300
307
|
model: 'gpt-4o-mini',
|
|
301
308
|
provider: 'openai',
|
|
302
309
|
operationId,
|
|
310
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
303
311
|
});
|
|
304
312
|
});
|
|
305
313
|
|
|
@@ -355,6 +363,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
355
363
|
model: 'gpt-4o-mini',
|
|
356
364
|
provider: 'openai',
|
|
357
365
|
operationId,
|
|
366
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
358
367
|
});
|
|
359
368
|
});
|
|
360
369
|
|
|
@@ -394,6 +403,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
394
403
|
messageId: TEST_IDS.ASSISTANT_MESSAGE_ID,
|
|
395
404
|
model: 'gpt-4o-mini',
|
|
396
405
|
provider: 'openai',
|
|
406
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
397
407
|
});
|
|
398
408
|
expect(response.isFunctionCall).toEqual(true);
|
|
399
409
|
});
|
|
@@ -419,6 +429,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
419
429
|
messageId: TEST_IDS.ASSISTANT_MESSAGE_ID,
|
|
420
430
|
model: 'gpt-4o-mini',
|
|
421
431
|
provider: 'openai',
|
|
432
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
422
433
|
});
|
|
423
434
|
});
|
|
424
435
|
|
|
@@ -435,7 +446,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
435
446
|
});
|
|
436
447
|
|
|
437
448
|
describe('effectiveAgentId for group orchestration', () => {
|
|
438
|
-
it('should pass
|
|
449
|
+
it('should pass pre-resolved config for sub-agent when subAgentId is set in operation context', async () => {
|
|
439
450
|
const { result } = renderHook(() => useChatStore());
|
|
440
451
|
const messages = [createMockMessage({ role: 'user' })];
|
|
441
452
|
const supervisorAgentId = 'supervisor-agent-id';
|
|
@@ -453,6 +464,9 @@ describe('StreamingExecutor actions', () => {
|
|
|
453
464
|
label: 'Test Group Orchestration',
|
|
454
465
|
});
|
|
455
466
|
|
|
467
|
+
// Pre-resolved config for the sub-agent (in real usage, resolved by internal_createAgentState)
|
|
468
|
+
const subAgentConfig = createMockResolvedAgentConfig();
|
|
469
|
+
|
|
456
470
|
const streamSpy = vi
|
|
457
471
|
.spyOn(chatService, 'createAssistantMessageStream')
|
|
458
472
|
.mockImplementation(async ({ onFinish }) => {
|
|
@@ -466,14 +480,18 @@ describe('StreamingExecutor actions', () => {
|
|
|
466
480
|
model: 'gpt-4o-mini',
|
|
467
481
|
provider: 'openai',
|
|
468
482
|
operationId,
|
|
483
|
+
agentConfig: subAgentConfig,
|
|
469
484
|
});
|
|
470
485
|
});
|
|
471
486
|
|
|
472
|
-
//
|
|
487
|
+
// With the new architecture:
|
|
488
|
+
// - agentId param is for context/tracing (supervisor ID)
|
|
489
|
+
// - resolvedAgentConfig contains the sub-agent's config (passed in by caller)
|
|
473
490
|
expect(streamSpy).toHaveBeenCalledWith(
|
|
474
491
|
expect.objectContaining({
|
|
475
492
|
params: expect.objectContaining({
|
|
476
|
-
agentId:
|
|
493
|
+
agentId: supervisorAgentId, // For context/tracing purposes
|
|
494
|
+
resolvedAgentConfig: subAgentConfig, // Pre-resolved sub-agent config
|
|
477
495
|
}),
|
|
478
496
|
}),
|
|
479
497
|
);
|
|
@@ -511,6 +529,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
511
529
|
model: 'gpt-4o-mini',
|
|
512
530
|
provider: 'openai',
|
|
513
531
|
operationId,
|
|
532
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
514
533
|
});
|
|
515
534
|
});
|
|
516
535
|
|
|
@@ -526,7 +545,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
526
545
|
streamSpy.mockRestore();
|
|
527
546
|
});
|
|
528
547
|
|
|
529
|
-
it('should
|
|
548
|
+
it('should pass resolvedAgentConfig through chatService when subAgentId is present', async () => {
|
|
530
549
|
const { result } = renderHook(() => useChatStore());
|
|
531
550
|
const messages = [createMockMessage({ role: 'user' })];
|
|
532
551
|
const supervisorAgentId = 'supervisor-agent-id';
|
|
@@ -547,6 +566,9 @@ describe('StreamingExecutor actions', () => {
|
|
|
547
566
|
label: 'Test Speak Executor',
|
|
548
567
|
});
|
|
549
568
|
|
|
569
|
+
// Create a mock resolved config that represents the speaking agent's config
|
|
570
|
+
const speakingAgentConfig = createMockResolvedAgentConfig();
|
|
571
|
+
|
|
550
572
|
const streamSpy = vi
|
|
551
573
|
.spyOn(chatService, 'createAssistantMessageStream')
|
|
552
574
|
.mockImplementation(async ({ onFinish }) => {
|
|
@@ -560,15 +582,23 @@ describe('StreamingExecutor actions', () => {
|
|
|
560
582
|
model: 'gpt-4o-mini',
|
|
561
583
|
provider: 'openai',
|
|
562
584
|
operationId,
|
|
585
|
+
// Pass pre-resolved config for the speaking agent
|
|
586
|
+
// In real usage, this is resolved in internal_createAgentState using subAgentId
|
|
587
|
+
agentConfig: speakingAgentConfig,
|
|
563
588
|
});
|
|
564
589
|
});
|
|
565
590
|
|
|
566
|
-
//
|
|
567
|
-
//
|
|
591
|
+
// With the new architecture, config is pre-resolved and passed via resolvedAgentConfig.
|
|
592
|
+
// The agentId param is for context/tracing only.
|
|
593
|
+
// The speaking agent's config is ensured by the caller (internal_createAgentState)
|
|
594
|
+
// resolving config with subAgentId and passing it as agentConfig param.
|
|
568
595
|
expect(streamSpy).toHaveBeenCalledWith(
|
|
569
596
|
expect.objectContaining({
|
|
570
597
|
params: expect.objectContaining({
|
|
571
|
-
agentId
|
|
598
|
+
// agentId is supervisor for context purposes
|
|
599
|
+
agentId: supervisorAgentId,
|
|
600
|
+
// resolvedAgentConfig contains the speaking agent's config
|
|
601
|
+
resolvedAgentConfig: speakingAgentConfig,
|
|
572
602
|
}),
|
|
573
603
|
}),
|
|
574
604
|
);
|
|
@@ -902,6 +932,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
902
932
|
model: 'gpt-4o-mini',
|
|
903
933
|
provider: 'openai',
|
|
904
934
|
operationId,
|
|
935
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
905
936
|
});
|
|
906
937
|
});
|
|
907
938
|
|
|
@@ -943,6 +974,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
943
974
|
messageId: TEST_IDS.ASSISTANT_MESSAGE_ID,
|
|
944
975
|
model: 'gpt-4o-mini',
|
|
945
976
|
provider: 'openai',
|
|
977
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
946
978
|
});
|
|
947
979
|
});
|
|
948
980
|
|
|
@@ -1040,6 +1072,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
1040
1072
|
stepCount: 0,
|
|
1041
1073
|
},
|
|
1042
1074
|
},
|
|
1075
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
1043
1076
|
});
|
|
1044
1077
|
|
|
1045
1078
|
// Execute internal_execAgentRuntime with the pre-created operationId
|
|
@@ -1135,6 +1168,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
1135
1168
|
stepCount: 0,
|
|
1136
1169
|
},
|
|
1137
1170
|
},
|
|
1171
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
1138
1172
|
});
|
|
1139
1173
|
|
|
1140
1174
|
// Suppress console.error for this test
|
|
@@ -1235,6 +1269,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
1235
1269
|
stepCount: 0,
|
|
1236
1270
|
},
|
|
1237
1271
|
},
|
|
1272
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
1238
1273
|
});
|
|
1239
1274
|
|
|
1240
1275
|
// Should not throw
|
|
@@ -1489,6 +1524,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
1489
1524
|
stepCount: 1,
|
|
1490
1525
|
},
|
|
1491
1526
|
},
|
|
1527
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
1492
1528
|
});
|
|
1493
1529
|
|
|
1494
1530
|
await act(async () => {
|
|
@@ -1583,6 +1619,7 @@ describe('StreamingExecutor actions', () => {
|
|
|
1583
1619
|
stepCount: 1,
|
|
1584
1620
|
},
|
|
1585
1621
|
},
|
|
1622
|
+
agentConfig: createMockResolvedAgentConfig(),
|
|
1586
1623
|
});
|
|
1587
1624
|
|
|
1588
1625
|
await act(async () => {
|
|
@@ -1602,4 +1639,91 @@ describe('StreamingExecutor actions', () => {
|
|
|
1602
1639
|
expect(result.current.operations[operationId!].status).toBe('failed');
|
|
1603
1640
|
});
|
|
1604
1641
|
});
|
|
1642
|
+
|
|
1643
|
+
describe('isSubTask filtering', () => {
|
|
1644
|
+
it('should filter out lobe-gtd tools when isSubTask is true', async () => {
|
|
1645
|
+
const { result } = renderHook(() => useChatStore());
|
|
1646
|
+
const messages = [createMockMessage({ role: 'user' })];
|
|
1647
|
+
|
|
1648
|
+
// Mock resolveAgentConfig to return plugins including lobe-gtd
|
|
1649
|
+
const resolveAgentConfigSpy = vi
|
|
1650
|
+
.spyOn(agentConfigResolver, 'resolveAgentConfig')
|
|
1651
|
+
.mockReturnValue({
|
|
1652
|
+
agentConfig: createMockAgentConfig(),
|
|
1653
|
+
chatConfig: createMockChatConfig(),
|
|
1654
|
+
isBuiltinAgent: false,
|
|
1655
|
+
plugins: ['lobe-gtd', 'lobe-local-system', 'other-plugin'],
|
|
1656
|
+
});
|
|
1657
|
+
|
|
1658
|
+
// Create operation
|
|
1659
|
+
let operationId: string;
|
|
1660
|
+
act(() => {
|
|
1661
|
+
const res = result.current.startOperation({
|
|
1662
|
+
type: 'execClientTask',
|
|
1663
|
+
context: {
|
|
1664
|
+
agentId: TEST_IDS.SESSION_ID,
|
|
1665
|
+
topicId: TEST_IDS.TOPIC_ID,
|
|
1666
|
+
},
|
|
1667
|
+
});
|
|
1668
|
+
operationId = res.operationId;
|
|
1669
|
+
});
|
|
1670
|
+
|
|
1671
|
+
// Call internal_createAgentState with isSubTask: true
|
|
1672
|
+
act(() => {
|
|
1673
|
+
result.current.internal_createAgentState({
|
|
1674
|
+
messages,
|
|
1675
|
+
parentMessageId: TEST_IDS.USER_MESSAGE_ID,
|
|
1676
|
+
operationId,
|
|
1677
|
+
isSubTask: true,
|
|
1678
|
+
});
|
|
1679
|
+
});
|
|
1680
|
+
|
|
1681
|
+
// Verify that resolveAgentConfig was called
|
|
1682
|
+
expect(resolveAgentConfigSpy).toHaveBeenCalled();
|
|
1683
|
+
|
|
1684
|
+
resolveAgentConfigSpy.mockRestore();
|
|
1685
|
+
});
|
|
1686
|
+
|
|
1687
|
+
it('should NOT filter out lobe-gtd tools when isSubTask is false or undefined', async () => {
|
|
1688
|
+
const { result } = renderHook(() => useChatStore());
|
|
1689
|
+
const messages = [createMockMessage({ role: 'user' })];
|
|
1690
|
+
|
|
1691
|
+
// Mock resolveAgentConfig to return plugins including lobe-gtd
|
|
1692
|
+
const resolveAgentConfigSpy = vi
|
|
1693
|
+
.spyOn(agentConfigResolver, 'resolveAgentConfig')
|
|
1694
|
+
.mockReturnValue({
|
|
1695
|
+
agentConfig: createMockAgentConfig(),
|
|
1696
|
+
chatConfig: createMockChatConfig(),
|
|
1697
|
+
isBuiltinAgent: false,
|
|
1698
|
+
plugins: ['lobe-gtd', 'lobe-local-system', 'other-plugin'],
|
|
1699
|
+
});
|
|
1700
|
+
|
|
1701
|
+
// Create operation without isSubTask (normal conversation)
|
|
1702
|
+
let operationId: string;
|
|
1703
|
+
act(() => {
|
|
1704
|
+
const res = result.current.startOperation({
|
|
1705
|
+
type: 'execAgentRuntime',
|
|
1706
|
+
context: {
|
|
1707
|
+
agentId: TEST_IDS.SESSION_ID,
|
|
1708
|
+
topicId: TEST_IDS.TOPIC_ID,
|
|
1709
|
+
},
|
|
1710
|
+
});
|
|
1711
|
+
operationId = res.operationId;
|
|
1712
|
+
});
|
|
1713
|
+
|
|
1714
|
+
// Call internal_createAgentState without isSubTask
|
|
1715
|
+
act(() => {
|
|
1716
|
+
result.current.internal_createAgentState({
|
|
1717
|
+
messages,
|
|
1718
|
+
parentMessageId: TEST_IDS.USER_MESSAGE_ID,
|
|
1719
|
+
operationId,
|
|
1720
|
+
});
|
|
1721
|
+
});
|
|
1722
|
+
|
|
1723
|
+
// Verify that resolveAgentConfig was called
|
|
1724
|
+
expect(resolveAgentConfigSpy).toHaveBeenCalled();
|
|
1725
|
+
|
|
1726
|
+
resolveAgentConfigSpy.mockRestore();
|
|
1727
|
+
});
|
|
1728
|
+
});
|
|
1605
1729
|
});
|