Merge pull request #71 from Askhz/fix/server-agent-switch

fix(server): 修复内置 agent 切换时系统提示未注入及 @agent 出现在用户消息中的问题
This commit is contained in:
DoSun 2026-05-12 17:54:11 +08:00 committed by GitHub
commit be821416e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 7 deletions

View File

@ -3108,9 +3108,28 @@ function runHeadlessStreaming(
sendControlResponseSuccess(msg)
} else if (msg.request.subtype === 'set_agent') {
const agent = typeof msg.request.agent === 'string' ? msg.request.agent : undefined
if (agent) {
setMainThreadAgentType(agent)
saveAgentSetting(agent)
// 'build' is the frontend display name for the default (no-agent) mode.
// Treat it as clearing the agent, same as undefined.
const resolvedAgent = agent === 'build' ? undefined : agent
setMainThreadAgentType(resolvedAgent)
saveAgentSetting(resolvedAgent ?? '')
if (resolvedAgent) {
// Apply the agent's system prompt so QueryEngine picks it up on the next turn.
// QueryEngine.ask() uses options.systemPrompt (customSystemPrompt) directly,
// bypassing buildEffectiveSystemPrompt/mainThreadAgentDefinition. For built-in
// agents the getSystemPrompt params are ignored; pass a minimal stub.
const agentDef = currentAgents.find(a => a.agentType === resolvedAgent)
if (agentDef) {
const agentSystemPrompt = isBuiltInAgent(agentDef)
? agentDef.getSystemPrompt({ toolUseContext: { options: {} as never } })
: agentDef.getSystemPrompt()
if (agentSystemPrompt) {
options.systemPrompt = agentSystemPrompt
}
}
} else {
// Switching back to default mode: clear any previously applied agent system prompt.
options.systemPrompt = undefined
}
sendControlResponseSuccess(msg)
} else if (msg.request.subtype === 'set_max_thinking_tokens') {

View File

@ -393,8 +393,10 @@ export function createSessionRoutes(
.join('\n') ?? ''
const agentParts = body.parts?.filter((p) => p.type === 'agent' && p.name) ?? []
const agentMentions = agentParts.map((p) => `@agent-${p.name}`).join(' ')
const content = [textContent, agentMentions].filter(Boolean).join('\n')
// Agent switching is handled via setAgent() control message below.
// Do not append @agent-* mentions to content — they are REPL-only syntax
// and would be sent verbatim to the model in server mode.
const content = textContent
if (!content) throw badRequest('content is required')
if (handle.prompting) throw conflict('session is already processing a prompt')
@ -432,8 +434,10 @@ export function createSessionRoutes(
.join('\n') ?? ''
const agentParts = body.parts?.filter((p) => p.type === 'agent' && p.name) ?? []
const agentMentions = agentParts.map((p) => `@agent-${p.name}`).join(' ')
const content = [textContent, agentMentions].filter(Boolean).join('\n')
// Agent switching is handled via setAgent() control message below.
// Do not append @agent-* mentions to content — they are REPL-only syntax
// and would be sent verbatim to the model in server mode.
const content = textContent
if (!content) {
throw badRequest('content is required')