@lobehub/lobehub 2.0.0-next.286 → 2.0.0-next.288
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/apps/desktop/src/main/const/theme.ts +0 -3
- package/apps/desktop/src/main/core/browser/Browser.ts +1 -1
- package/apps/desktop/src/main/core/browser/WindowThemeManager.ts +3 -2
- package/apps/desktop/src/main/core/browser/__tests__/Browser.test.ts +0 -1
- package/apps/desktop/src/main/core/browser/__tests__/WindowThemeManager.test.ts +8 -5
- package/changelog/v1.json +14 -0
- package/locales/en-US/plugin.json +3 -5
- package/locales/zh-CN/plugin.json +3 -5
- package/locales/zh-CN/tool.json +2 -0
- package/package.json +1 -1
- package/packages/builtin-agents/src/agents/group-supervisor/index.ts +12 -1
- package/packages/builtin-agents/src/agents/group-supervisor/systemRole.ts +0 -7
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/EditLocalFile/index.tsx +93 -0
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/GlobLocalFiles/index.tsx +73 -0
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/GrepContent/index.tsx +69 -0
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/ListLocalFiles/index.tsx +68 -0
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/ReadLocalFile/index.tsx +74 -0
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/SearchLocalFiles/index.tsx +70 -0
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/WriteLocalFile/index.tsx +57 -0
- package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/index.ts +14 -0
- package/packages/builtin-tool-cloud-sandbox/src/client/Render/WriteFile/index.tsx +54 -35
- package/packages/builtin-tool-cloud-sandbox/src/client/components/FilePathDisplay.tsx +52 -0
- package/packages/builtin-tool-group-management/src/client/Inspector/ExecuteTasks/index.tsx +90 -0
- package/packages/builtin-tool-group-management/src/client/Inspector/index.ts +2 -0
- package/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTasks.tsx +237 -0
- package/packages/builtin-tool-group-management/src/client/Intervention/index.ts +4 -1
- package/packages/builtin-tool-group-management/src/client/Render/index.ts +1 -1
- package/packages/builtin-tool-group-management/src/client/Streaming/ExecuteTask/index.tsx +69 -0
- package/packages/builtin-tool-group-management/src/client/Streaming/ExecuteTasks/index.tsx +87 -0
- package/packages/builtin-tool-group-management/src/client/Streaming/index.ts +4 -0
- package/packages/builtin-tool-group-management/src/executor.test.ts +8 -311
- package/packages/builtin-tool-group-management/src/executor.ts +5 -160
- package/packages/builtin-tool-group-management/src/manifest.ts +50 -94
- package/packages/builtin-tool-group-management/src/systemRole.ts +251 -172
- package/packages/builtin-tool-group-management/src/types.ts +29 -40
- package/packages/context-engine/src/engine/messages/MessagesEngine.ts +6 -4
- package/packages/context-engine/src/engine/messages/types.ts +4 -4
- package/packages/context-engine/src/processors/GroupRoleTransform.ts +261 -0
- package/packages/context-engine/src/processors/__tests__/GroupRoleTransform.test.ts +553 -0
- package/packages/context-engine/src/processors/index.ts +2 -2
- package/packages/context-engine/src/providers/__tests__/GroupContextInjector.test.ts +4 -16
- package/packages/context-engine/src/providers/__tests__/__snapshots__/GroupContextInjector.test.ts.snap +23 -28
- package/packages/desktop-bridge/src/index.ts +3 -0
- package/packages/prompts/src/prompts/agentGroup/__snapshots__/index.test.ts.snap +0 -7
- package/packages/prompts/src/prompts/agentGroup/groupContext.ts +0 -7
- package/src/app/[variants]/(main)/group/features/Conversation/AgentWelcome/OpeningQuestions.tsx +4 -8
- package/src/app/[variants]/(main)/group/features/Conversation/MainChatInput/GroupChat.tsx +0 -3
- package/src/app/[variants]/(main)/group/features/Conversation/useGroupContext.ts +3 -0
- package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +15 -2
- package/src/features/ChatInput/Desktop/index.tsx +1 -3
- package/src/features/Conversation/store/slices/message/action/crud.ts +2 -2
- package/src/features/ElectronTitlebar/Connection/ConnectionMode.tsx +2 -2
- package/src/features/ElectronTitlebar/SimpleTitleBar.tsx +1 -2
- package/src/features/ElectronTitlebar/index.tsx +2 -2
- package/src/hooks/useUserAvatar.test.ts +23 -4
- package/src/locales/default/plugin.ts +3 -5
- package/src/locales/default/tool.ts +3 -0
- package/src/services/chat/mecha/agentConfigResolver.test.ts +160 -0
- package/src/services/chat/mecha/agentConfigResolver.ts +15 -3
- package/src/services/chat/mecha/contextEngineering.ts +2 -1
- package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +4 -2
- package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +2 -0
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +1 -18
- package/src/store/chat/slices/message/selectors/displayMessage.test.ts +24 -0
- package/src/store/chat/slices/message/selectors/displayMessage.ts +6 -1
- package/src/store/chat/slices/topic/action.test.ts +10 -4
- package/src/store/chat/slices/topic/action.ts +3 -2
- package/src/store/electron/selectors/sync.ts +17 -1
- package/packages/context-engine/src/processors/GroupMessageSender.ts +0 -138
- package/packages/context-engine/src/processors/__tests__/GroupMessageSender.test.ts +0 -274
- package/src/features/ElectronTitlebar/const.ts +0 -1
|
@@ -2,17 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* API names for Group Management tool
|
|
5
|
+
*
|
|
6
|
+
* Note: Member management APIs (searchAgent, inviteAgent, createAgent, removeAgent)
|
|
7
|
+
* are handled by group-agent-builder tool. This tool focuses on orchestration.
|
|
5
8
|
*/
|
|
6
9
|
export const GroupManagementApiName = {
|
|
7
|
-
// ====================
|
|
8
|
-
/** Search for agents that can be invited to the group */
|
|
9
|
-
searchAgent: 'searchAgent',
|
|
10
|
-
/** Invite an agent to join the group */
|
|
11
|
-
inviteAgent: 'inviteAgent',
|
|
12
|
-
/** Create a new agent and add it to the group */
|
|
13
|
-
createAgent: 'createAgent',
|
|
14
|
-
/** Remove an agent from the group */
|
|
15
|
-
removeAgent: 'removeAgent',
|
|
10
|
+
// ==================== Agent Info ====================
|
|
16
11
|
/** Get detailed information about an agent */
|
|
17
12
|
getAgentInfo: 'getAgentInfo',
|
|
18
13
|
|
|
@@ -26,7 +21,9 @@ export const GroupManagementApiName = {
|
|
|
26
21
|
|
|
27
22
|
// ==================== Task Execution ====================
|
|
28
23
|
/** Let an agent execute a task asynchronously */
|
|
29
|
-
|
|
24
|
+
executeAgentTask: 'executeAgentTask',
|
|
25
|
+
/** Let multiple agents execute different tasks in parallel */
|
|
26
|
+
executeAgentTasks: 'executeAgentTasks',
|
|
30
27
|
/** Interrupt a running agent task */
|
|
31
28
|
interrupt: 'interrupt',
|
|
32
29
|
|
|
@@ -44,28 +41,7 @@ export const GroupManagementApiName = {
|
|
|
44
41
|
export type GroupManagementApiNameType =
|
|
45
42
|
(typeof GroupManagementApiName)[keyof typeof GroupManagementApiName];
|
|
46
43
|
|
|
47
|
-
// ====================
|
|
48
|
-
|
|
49
|
-
export interface SearchAgentParams {
|
|
50
|
-
limit?: number;
|
|
51
|
-
query?: string;
|
|
52
|
-
source?: 'user' | 'community';
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface InviteAgentParams {
|
|
56
|
-
agentId: string;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface CreateAgentParams {
|
|
60
|
-
avatar?: string;
|
|
61
|
-
description?: string;
|
|
62
|
-
systemRole: string;
|
|
63
|
-
title: string;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export interface RemoveAgentParams {
|
|
67
|
-
agentId: string;
|
|
68
|
-
}
|
|
44
|
+
// ==================== Agent Info Params ====================
|
|
69
45
|
|
|
70
46
|
export interface GetAgentInfoParams {
|
|
71
47
|
agentId: string;
|
|
@@ -116,6 +92,27 @@ export interface ExecuteTaskParams {
|
|
|
116
92
|
timeout?: number;
|
|
117
93
|
}
|
|
118
94
|
|
|
95
|
+
export interface TaskItem {
|
|
96
|
+
/** The ID of the agent to execute this task */
|
|
97
|
+
agentId: string;
|
|
98
|
+
/** Detailed instruction/prompt for the task execution */
|
|
99
|
+
instruction: string;
|
|
100
|
+
/** Optional timeout in milliseconds for this specific task */
|
|
101
|
+
timeout?: number;
|
|
102
|
+
/** Brief title describing what this task does (shown in UI) */
|
|
103
|
+
title: string;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface ExecuteTasksParams {
|
|
107
|
+
/**
|
|
108
|
+
* If true, the orchestration will end after all tasks complete,
|
|
109
|
+
* without calling the supervisor again.
|
|
110
|
+
*/
|
|
111
|
+
skipCallSupervisor?: boolean;
|
|
112
|
+
/** Array of tasks to execute, each assigned to a specific agent */
|
|
113
|
+
tasks: TaskItem[];
|
|
114
|
+
}
|
|
115
|
+
|
|
119
116
|
export interface InterruptParams {
|
|
120
117
|
taskId: string;
|
|
121
118
|
}
|
|
@@ -156,14 +153,6 @@ export interface VoteParams {
|
|
|
156
153
|
|
|
157
154
|
// ==================== Result Types ====================
|
|
158
155
|
|
|
159
|
-
export interface AgentSearchResult {
|
|
160
|
-
avatar?: string;
|
|
161
|
-
description?: string;
|
|
162
|
-
id: string;
|
|
163
|
-
source: 'user' | 'community';
|
|
164
|
-
title: string;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
156
|
export interface VoteResult {
|
|
168
157
|
agentId: string;
|
|
169
158
|
reasoning?: string;
|
|
@@ -7,7 +7,7 @@ import { ContextEngine } from '../../pipeline';
|
|
|
7
7
|
import {
|
|
8
8
|
AgentCouncilFlattenProcessor,
|
|
9
9
|
GroupMessageFlattenProcessor,
|
|
10
|
-
|
|
10
|
+
GroupRoleTransformProcessor,
|
|
11
11
|
HistoryTruncateProcessor,
|
|
12
12
|
InputTemplateProcessor,
|
|
13
13
|
MessageCleanupProcessor,
|
|
@@ -274,11 +274,13 @@ export class MessagesEngine {
|
|
|
274
274
|
// 15. Supervisor role restore (convert role=supervisor back to role=assistant for model)
|
|
275
275
|
new SupervisorRoleRestoreProcessor(),
|
|
276
276
|
|
|
277
|
-
// 16. Group
|
|
278
|
-
|
|
277
|
+
// 16. Group role transform (convert other agents' messages to user role with speaker tags)
|
|
278
|
+
// This must be BEFORE ToolCallProcessor so other agents' tool messages are converted first
|
|
279
|
+
...(isAgentGroupEnabled && agentGroup.currentAgentId
|
|
279
280
|
? [
|
|
280
|
-
new
|
|
281
|
+
new GroupRoleTransformProcessor({
|
|
281
282
|
agentMap: agentGroup.agentMap!,
|
|
283
|
+
currentAgentId: agentGroup.currentAgentId,
|
|
282
284
|
}),
|
|
283
285
|
]
|
|
284
286
|
: []),
|
|
@@ -4,12 +4,12 @@ import type { RuntimeInitialContext, RuntimeStepContext } from '@lobechat/types'
|
|
|
4
4
|
|
|
5
5
|
import type { OpenAIChatMessage, UIChatMessage } from '@/types/index';
|
|
6
6
|
|
|
7
|
-
import type { AgentInfo } from '../../processors/
|
|
7
|
+
import type { AgentInfo } from '../../processors/GroupRoleTransform';
|
|
8
8
|
import type { AgentBuilderContext } from '../../providers/AgentBuilderContextInjector';
|
|
9
|
-
import type { GroupAgentBuilderContext } from '../../providers/GroupAgentBuilderContextInjector';
|
|
10
|
-
import type { GroupMemberInfo } from '../../providers/GroupContextInjector';
|
|
11
9
|
import type { GTDPlan } from '../../providers/GTDPlanInjector';
|
|
12
10
|
import type { GTDTodoList } from '../../providers/GTDTodoInjector';
|
|
11
|
+
import type { GroupAgentBuilderContext } from '../../providers/GroupAgentBuilderContextInjector';
|
|
12
|
+
import type { GroupMemberInfo } from '../../providers/GroupContextInjector';
|
|
13
13
|
import type { LobeToolManifest } from '../tools/types';
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -249,7 +249,7 @@ export interface MessagesEngineResult {
|
|
|
249
249
|
|
|
250
250
|
// Re-export types for convenience
|
|
251
251
|
|
|
252
|
-
export { type AgentInfo } from '../../processors/
|
|
252
|
+
export { type AgentInfo } from '../../processors/GroupRoleTransform';
|
|
253
253
|
export { type AgentBuilderContext } from '../../providers/AgentBuilderContextInjector';
|
|
254
254
|
export { type GroupAgentBuilderContext } from '../../providers/GroupAgentBuilderContextInjector';
|
|
255
255
|
export { type GTDPlan } from '../../providers/GTDPlanInjector';
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
|
|
3
|
+
import { BaseProcessor } from '../base/BaseProcessor';
|
|
4
|
+
import type { Message, PipelineContext, ProcessorOptions } from '../types';
|
|
5
|
+
|
|
6
|
+
const log = debug('context-engine:processor:GroupRoleTransformProcessor');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Agent info for message sender identification
|
|
10
|
+
*/
|
|
11
|
+
export interface AgentInfo {
|
|
12
|
+
name: string;
|
|
13
|
+
role: 'supervisor' | 'participant';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Configuration for GroupRoleTransformProcessor
|
|
18
|
+
*/
|
|
19
|
+
export interface GroupRoleTransformConfig {
|
|
20
|
+
/**
|
|
21
|
+
* Mapping from agentId to agent info
|
|
22
|
+
* Used to look up agent name for each message
|
|
23
|
+
*/
|
|
24
|
+
agentMap: Record<string, AgentInfo>;
|
|
25
|
+
/**
|
|
26
|
+
* The current agent ID that is responding
|
|
27
|
+
* Messages from this agent will remain as assistant role
|
|
28
|
+
*/
|
|
29
|
+
currentAgentId: string;
|
|
30
|
+
/**
|
|
31
|
+
* Custom function to generate tool name from identifier and apiName
|
|
32
|
+
*/
|
|
33
|
+
genToolName?: (identifier: string, apiName: string) => string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Group Role Transform Processor
|
|
38
|
+
*
|
|
39
|
+
* Transforms messages from other agents to user role with speaker tags.
|
|
40
|
+
* This prevents the model from imitating speaker tags in its output.
|
|
41
|
+
*
|
|
42
|
+
* From the model's perspective:
|
|
43
|
+
* - role: assistant = "my" responses (current agent)
|
|
44
|
+
* - role: user = external input (human users and other agents)
|
|
45
|
+
*
|
|
46
|
+
* Processing logic:
|
|
47
|
+
* 1. Current agent's messages: Keep as assistant (no modifications)
|
|
48
|
+
* 2. Other agents' assistant messages: Convert to user with speaker tag
|
|
49
|
+
* 3. Other agents' tool messages: Convert to user with tool_result tag
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const processor = new GroupRoleTransformProcessor({
|
|
54
|
+
* currentAgentId: 'travel-advisor',
|
|
55
|
+
* agentMap: {
|
|
56
|
+
* 'weather-expert': { name: 'Weather Expert', role: 'participant' },
|
|
57
|
+
* 'travel-advisor': { name: 'Travel Advisor', role: 'participant' },
|
|
58
|
+
* 'supervisor': { name: 'Supervisor', role: 'supervisor' },
|
|
59
|
+
* }
|
|
60
|
+
* });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export class GroupRoleTransformProcessor extends BaseProcessor {
|
|
64
|
+
readonly name = 'GroupRoleTransformProcessor';
|
|
65
|
+
|
|
66
|
+
constructor(
|
|
67
|
+
private config: GroupRoleTransformConfig,
|
|
68
|
+
options: ProcessorOptions = {},
|
|
69
|
+
) {
|
|
70
|
+
super(options);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected async doProcess(context: PipelineContext): Promise<PipelineContext> {
|
|
74
|
+
const clonedContext = this.cloneContext(context);
|
|
75
|
+
|
|
76
|
+
// Skip if no currentAgentId or agentMap provided
|
|
77
|
+
if (!this.config.currentAgentId || !this.config.agentMap) {
|
|
78
|
+
log('No currentAgentId or agentMap provided, skipping processing');
|
|
79
|
+
return this.markAsExecuted(clonedContext);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let assistantTransformed = 0;
|
|
83
|
+
let toolTransformed = 0;
|
|
84
|
+
|
|
85
|
+
clonedContext.messages = clonedContext.messages.map((msg: Message) => {
|
|
86
|
+
// Process assistant messages
|
|
87
|
+
if (msg.role === 'assistant' && msg.agentId) {
|
|
88
|
+
if (msg.agentId === this.config.currentAgentId) {
|
|
89
|
+
// Current agent: keep as assistant, no modifications
|
|
90
|
+
return msg;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Other agent: transform to user with speaker tag
|
|
94
|
+
const transformed = this.transformAssistantMessage(msg);
|
|
95
|
+
if (transformed !== msg) {
|
|
96
|
+
assistantTransformed++;
|
|
97
|
+
log(`Transformed assistant message from agent: ${msg.agentId} to user`);
|
|
98
|
+
}
|
|
99
|
+
return transformed;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Process tool messages
|
|
103
|
+
if (msg.role === 'tool' && msg.agentId) {
|
|
104
|
+
if (msg.agentId === this.config.currentAgentId) {
|
|
105
|
+
// Current agent: keep as tool
|
|
106
|
+
return msg;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Other agent: transform to user with tool_result tag
|
|
110
|
+
const transformed = this.transformToolMessage(msg);
|
|
111
|
+
if (transformed !== msg) {
|
|
112
|
+
toolTransformed++;
|
|
113
|
+
log(`Transformed tool message from agent: ${msg.agentId} to user`);
|
|
114
|
+
}
|
|
115
|
+
return transformed;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return msg;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Update metadata
|
|
122
|
+
clonedContext.metadata.groupRoleTransformProcessed = {
|
|
123
|
+
assistantTransformed,
|
|
124
|
+
toolTransformed,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
log(
|
|
128
|
+
`Group role transform completed: ${assistantTransformed} assistant messages, ${toolTransformed} tool messages transformed`,
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
return this.markAsExecuted(clonedContext);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Transform an assistant message from another agent to a user message
|
|
136
|
+
*/
|
|
137
|
+
private transformAssistantMessage(msg: Message): Message {
|
|
138
|
+
const agentInfo = this.config.agentMap[msg.agentId];
|
|
139
|
+
if (!agentInfo) {
|
|
140
|
+
// No agent info found, keep original
|
|
141
|
+
return msg;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const agentName = agentInfo.name;
|
|
145
|
+
let content = this.buildSpeakerTag(agentName);
|
|
146
|
+
|
|
147
|
+
// Add original content
|
|
148
|
+
const originalContent = this.getStringContent(msg.content);
|
|
149
|
+
if (originalContent) {
|
|
150
|
+
content += originalContent;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Add tool_use section if message has tools
|
|
154
|
+
if (msg.tools && msg.tools.length > 0) {
|
|
155
|
+
content += this.buildToolUseSection(msg.tools);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
...msg,
|
|
160
|
+
content,
|
|
161
|
+
role: 'user',
|
|
162
|
+
// Remove tool-related fields as they're now embedded in content
|
|
163
|
+
tools: undefined,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Transform a tool result message from another agent to a user message
|
|
169
|
+
*/
|
|
170
|
+
private transformToolMessage(msg: Message): Message {
|
|
171
|
+
const agentInfo = this.config.agentMap[msg.agentId];
|
|
172
|
+
if (!agentInfo) {
|
|
173
|
+
// No agent info found, keep original
|
|
174
|
+
return msg;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const agentName = agentInfo.name;
|
|
178
|
+
const toolName = this.getToolName(msg.plugin);
|
|
179
|
+
const toolCallId = msg.tool_call_id || 'unknown';
|
|
180
|
+
const resultContent = this.getStringContent(msg.content);
|
|
181
|
+
|
|
182
|
+
const content = `${this.buildSpeakerTag(agentName)}<tool_result id="${toolCallId}" name="${toolName}">
|
|
183
|
+
${resultContent}
|
|
184
|
+
</tool_result>`;
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
...msg,
|
|
188
|
+
content,
|
|
189
|
+
// Remove tool-related fields
|
|
190
|
+
plugin: undefined,
|
|
191
|
+
role: 'user',
|
|
192
|
+
tool_call_id: undefined,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Build the speaker tag
|
|
198
|
+
*/
|
|
199
|
+
private buildSpeakerTag(agentName: string): string {
|
|
200
|
+
return `<speaker name="${agentName}" />\n`;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Build the tool_use section for assistant messages with tools
|
|
205
|
+
*/
|
|
206
|
+
private buildToolUseSection(tools: any[]): string {
|
|
207
|
+
let section = '\n\n<tool_use>\n';
|
|
208
|
+
|
|
209
|
+
for (const tool of tools) {
|
|
210
|
+
const toolName = this.getToolName(tool);
|
|
211
|
+
const toolId = tool.id || 'unknown';
|
|
212
|
+
const args = tool.arguments || '';
|
|
213
|
+
|
|
214
|
+
section += `<tool id="${toolId}" name="${toolName}">\n`;
|
|
215
|
+
section += `${args}\n`;
|
|
216
|
+
section += `</tool>\n`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
section += '</tool_use>';
|
|
220
|
+
return section;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get tool name from tool object
|
|
225
|
+
*/
|
|
226
|
+
private getToolName(tool: any): string {
|
|
227
|
+
if (!tool) return 'unknown';
|
|
228
|
+
|
|
229
|
+
const identifier = tool.identifier || '';
|
|
230
|
+
const apiName = tool.apiName || '';
|
|
231
|
+
|
|
232
|
+
if (this.config.genToolName) {
|
|
233
|
+
return this.config.genToolName(identifier, apiName);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (identifier && apiName) {
|
|
237
|
+
return `${identifier}.${apiName}`;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return identifier || apiName || 'unknown';
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Extract string content from message content (handles both string and array formats)
|
|
245
|
+
*/
|
|
246
|
+
private getStringContent(content: string | any[]): string {
|
|
247
|
+
if (typeof content === 'string') {
|
|
248
|
+
return content;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (Array.isArray(content)) {
|
|
252
|
+
// Extract text from array content
|
|
253
|
+
return content
|
|
254
|
+
.filter((part: any) => part.type === 'text')
|
|
255
|
+
.map((part: any) => part.text || '')
|
|
256
|
+
.join('\n');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return '';
|
|
260
|
+
}
|
|
261
|
+
}
|