🐛 fix: slove the agents_documents will coverd the systemRole (#13667)

fix: slove the agents_documents will coverd the systemRole
This commit is contained in:
LiJian 2026-04-08 20:54:20 +08:00 committed by GitHub
parent c5ec0ef2a1
commit 26d1d6bbfb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 73 additions and 37 deletions

View file

@ -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)}..."`);
}
}

View file

@ -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 () => {