fix(cli): prevent system-injected messages from appearing as user role (#361)

This commit is contained in:
Haoqing Wang
2026-03-26 08:06:30 +08:00
committed by GitHub
parent 2b133feec5
commit 279f75815e
2 changed files with 133 additions and 1 deletions
+98
View File
@@ -0,0 +1,98 @@
import { describe, expect, it } from 'vitest'
import { isExternalUserMessage } from './apiSession'
describe('isExternalUserMessage', () => {
const baseUserMsg = {
type: 'user' as const,
uuid: 'test-uuid',
userType: 'external' as const,
isSidechain: false,
message: { role: 'user', content: 'hello' },
}
it('returns true for a real user text message', () => {
expect(isExternalUserMessage(baseUserMsg)).toBe(true)
})
it('returns false when isMeta is true (skill injections)', () => {
expect(isExternalUserMessage({ ...baseUserMsg, isMeta: true })).toBe(false)
})
it('returns false when isSidechain is true', () => {
expect(isExternalUserMessage({ ...baseUserMsg, isSidechain: true })).toBe(false)
})
it('returns false when content is an array (tool results)', () => {
expect(
isExternalUserMessage({
...baseUserMsg,
message: { role: 'user', content: [{ type: 'tool_result', tool_use_id: 'x', content: 'y' }] },
} as never)
).toBe(false)
})
it('returns false for assistant messages', () => {
expect(
isExternalUserMessage({
type: 'assistant',
uuid: 'test-uuid',
message: { role: 'assistant', content: 'hi' },
} as never)
).toBe(false)
})
// System-injected content detection
it('returns false for <task-notification> messages', () => {
expect(
isExternalUserMessage({
...baseUserMsg,
message: { role: 'user', content: '<task-notification>\n<task-id>abc123</task-id>\n</task-notification>' },
})
).toBe(false)
})
it('returns false for <command-name> messages', () => {
expect(
isExternalUserMessage({
...baseUserMsg,
message: { role: 'user', content: '<command-name>/clear</command-name>' },
})
).toBe(false)
})
it('returns false for <local-command-caveat> messages', () => {
expect(
isExternalUserMessage({
...baseUserMsg,
message: { role: 'user', content: '<local-command-caveat>Caveat: ...</local-command-caveat>' },
})
).toBe(false)
})
it('returns false for <system-reminder> messages', () => {
expect(
isExternalUserMessage({
...baseUserMsg,
message: { role: 'user', content: '<system-reminder>\nToday is 2026.\n</system-reminder>' },
})
).toBe(false)
})
it('returns true for user text that mentions XML-like strings but is not injected', () => {
expect(
isExternalUserMessage({
...baseUserMsg,
message: { role: 'user', content: 'How do I use the <task-notification> tag?' },
})
).toBe(true)
})
it('returns false for <task-notification> with leading whitespace', () => {
expect(
isExternalUserMessage({
...baseUserMsg,
message: { role: 'user', content: ' \n<task-notification>\n<task-id>x</task-id>\n</task-notification>' },
})
).toBe(false)
})
})