mirror of
https://github.com/lobehub/lobehub
synced 2026-04-21 17:47:27 +00:00
🐛 fix: slove the agents_documents will coverd the systemRole (#13667)
fix: slove the agents_documents will coverd the systemRole
This commit is contained in:
parent
c5ec0ef2a1
commit
26d1d6bbfb
2 changed files with 73 additions and 37 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import debug from 'debug';
|
||||
|
||||
import { BaseProvider } from '../base/BaseProvider';
|
||||
import { BaseSystemRoleProvider } from '../base/BaseSystemRoleProvider';
|
||||
import type { PipelineContext, ProcessorOptions } from '../types';
|
||||
|
||||
declare module '../types' {
|
||||
|
|
@ -18,9 +18,13 @@ export interface SystemRoleInjectorConfig {
|
|||
|
||||
/**
|
||||
* System Role Injector
|
||||
* Responsible for injecting system role messages at the beginning of the conversation
|
||||
*
|
||||
* Injects the agent's system role into the system message. If a system message
|
||||
* already exists (e.g. created by AgentDocumentBeforeSystemInjector), the
|
||||
* system role is appended to it via the BaseSystemRoleProvider join logic;
|
||||
* otherwise a new system message is created.
|
||||
*/
|
||||
export class SystemRoleInjector extends BaseProvider {
|
||||
export class SystemRoleInjector extends BaseSystemRoleProvider {
|
||||
readonly name = 'SystemRoleInjector';
|
||||
|
||||
constructor(
|
||||
|
|
@ -30,40 +34,18 @@ export class SystemRoleInjector extends BaseProvider {
|
|||
super(options);
|
||||
}
|
||||
|
||||
protected async doProcess(context: PipelineContext): Promise<PipelineContext> {
|
||||
const clonedContext = this.cloneContext(context);
|
||||
|
||||
// Skip injection if no system role is configured
|
||||
if (!this.config.systemRole || this.config.systemRole.trim() === '') {
|
||||
protected buildSystemRoleContent(_context: PipelineContext): string | null {
|
||||
const systemRole = this.config.systemRole;
|
||||
if (!systemRole || systemRole.trim() === '') {
|
||||
log('No system role configured, skipping injection');
|
||||
return this.markAsExecuted(clonedContext);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check if system role already exists at the beginning
|
||||
const hasExistingSystemRole =
|
||||
clonedContext.messages.length > 0 && clonedContext.messages[0].role === 'system';
|
||||
return systemRole;
|
||||
}
|
||||
|
||||
if (hasExistingSystemRole) {
|
||||
log('System role already exists, skipping injection');
|
||||
return this.markAsExecuted(clonedContext);
|
||||
}
|
||||
|
||||
// Inject system role at the beginning
|
||||
const systemMessage = {
|
||||
content: this.config.systemRole,
|
||||
createdAt: Date.now(),
|
||||
id: `system-${Date.now()}`,
|
||||
role: 'system' as const,
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
|
||||
clonedContext.messages.unshift(systemMessage);
|
||||
|
||||
// Update metadata
|
||||
clonedContext.metadata.systemRoleInjected = true;
|
||||
|
||||
log(`System role injected: "${this.config.systemRole.slice(0, 50)}..."`);
|
||||
|
||||
return this.markAsExecuted(clonedContext);
|
||||
protected onInjected(context: PipelineContext, content: string): void {
|
||||
context.metadata.systemRoleInjected = true;
|
||||
log(`System role injected: "${content.slice(0, 50)}..."`);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ describe('SystemRoleInjector', () => {
|
|||
expect(result.metadata.systemRoleInjected).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should skip injection when system role already exists', async () => {
|
||||
it('should append system role to existing system message', async () => {
|
||||
const provider = new SystemRoleInjector({
|
||||
systemRole: 'You are a helpful assistant.',
|
||||
});
|
||||
|
|
@ -125,8 +125,62 @@ describe('SystemRoleInjector', () => {
|
|||
const result = await provider.process(context);
|
||||
|
||||
expect(result.messages).toHaveLength(2);
|
||||
expect(result.messages[0].content).toBe('Existing system role');
|
||||
expect(result.metadata.systemRoleInjected).toBeUndefined();
|
||||
expect(result.messages[0].role).toBe('system');
|
||||
expect(result.messages[0].content).toBe('Existing system role\n\nYou are a helpful assistant.');
|
||||
expect(result.messages[1].role).toBe('user');
|
||||
expect(result.metadata.systemRoleInjected).toBe(true);
|
||||
});
|
||||
|
||||
it('should append systemRole after AgentDocumentBeforeSystemInjector output (regression for LOBE-6892)', async () => {
|
||||
const provider = new SystemRoleInjector({
|
||||
systemRole: '你是一个思维活跃的工程师,擅长 Python、JavaScript、Docker、SQL。',
|
||||
});
|
||||
|
||||
const beforeSystemDocContent =
|
||||
'<agent_documents>\n<document title="rules">always reply in Chinese</document>\n</agent_documents>';
|
||||
|
||||
const context = {
|
||||
initialState: {
|
||||
messages: [],
|
||||
model: 'gpt-4',
|
||||
provider: 'openai',
|
||||
systemRole: '',
|
||||
tools: [],
|
||||
},
|
||||
messages: [
|
||||
// Simulates the message that AgentDocumentBeforeSystemInjector unshifts
|
||||
{
|
||||
id: 'agent-doc-before-system-1700000000000',
|
||||
role: 'system',
|
||||
content: beforeSystemDocContent,
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
{
|
||||
id: '1',
|
||||
role: 'user',
|
||||
content: 'Hello',
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
model: 'gpt-4',
|
||||
maxTokens: 4096,
|
||||
},
|
||||
isAborted: false,
|
||||
};
|
||||
|
||||
const result = await provider.process(context);
|
||||
|
||||
expect(result.messages).toHaveLength(2);
|
||||
expect(result.messages[0].role).toBe('system');
|
||||
// doc content stays in front, systemRole appended after with \n\n separator
|
||||
expect(result.messages[0].content).toBe(
|
||||
`${beforeSystemDocContent}\n\n你是一个思维活跃的工程师,擅长 Python、JavaScript、Docker、SQL。`,
|
||||
);
|
||||
expect(result.messages[1].role).toBe('user');
|
||||
expect(result.metadata.systemRoleInjected).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle whitespace-only system role', async () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue