fix(agent): use origin session key for system messages and add corresponding test

This commit is contained in:
Administrator 2026-03-26 17:54:23 +08:00
parent 9d6a445bb1
commit 964e34cf61
2 changed files with 56 additions and 7 deletions

View file

@ -1451,8 +1451,10 @@ func (al *AgentLoop) processSystemMessage(
return "", fmt.Errorf("no default agent for system message") return "", fmt.Errorf("no default agent for system message")
} }
// Use the origin session for context sessionKey := msg.SessionKey
sessionKey := routing.BuildAgentMainSessionKey(agent.ID) if sessionKey == "" {
sessionKey = routing.BuildAgentMainSessionKey(agent.ID)
}
return al.runAgentLoop(ctx, agent, processOptions{ return al.runAgentLoop(ctx, agent, processOptions{
SessionKey: sessionKey, SessionKey: sessionKey,
@ -2369,11 +2371,12 @@ turnLoop:
pubCtx, pubCancel := context.WithTimeout(context.Background(), 5*time.Second) pubCtx, pubCancel := context.WithTimeout(context.Background(), 5*time.Second)
defer pubCancel() defer pubCancel()
_ = al.bus.PublishInbound(pubCtx, bus.InboundMessage{ al.bus.PublishInbound(pubCtx, bus.InboundMessage{
Channel: "system", Channel: "system",
SenderID: fmt.Sprintf("async:%s", asyncToolName), SenderID: fmt.Sprintf("async:%s", asyncToolName),
ChatID: fmt.Sprintf("%s:%s", ts.channel, ts.chatID), ChatID: fmt.Sprintf("%s:%s", ts.channel, ts.chatID),
Content: content, Content: content,
SessionKey: ts.sessionKey,
}) })
} }

View file

@ -2926,3 +2926,49 @@ func TestProcessMessage_ContextOverflow_AnthropicStyle(t *testing.T) {
t.Fatalf("expected 2 calls for retry, got %d", provider.calls) t.Fatalf("expected 2 calls for retry, got %d", provider.calls)
} }
} }
// TestProcessSystemMessage_UsesOriginSessionKey verifies that when an async tool
// completes and publishes a system message with a SessionKey, the resulting turn
// runs in that session rather than the default "agent:main:main" session.
func TestProcessSystemMessage_UsesOriginSessionKey(t *testing.T) {
al := NewAgentLoop(&config.Config{
Agents: config.AgentsConfig{
Defaults: config.AgentDefaults{
Workspace: t.TempDir(),
ModelName: "test-model",
MaxTokens: 4096,
MaxToolIterations: 10,
},
},
}, bus.NewMessageBus(), &mockProvider{})
const wantSessionKey = "agent:main:weixin:direct:testchatid"
sub := al.SubscribeEvents(32)
defer al.UnsubscribeEvents(sub.ID)
done := make(chan error, 1)
go func() {
_, err := al.processMessage(context.Background(), bus.InboundMessage{
Channel: "system",
SenderID: "async:spawn",
ChatID: "weixin:testchatid",
Content: "task completed",
SessionKey: wantSessionKey,
})
done <- err
}()
evt := waitForEvent(t, sub.C, 5*time.Second, func(e Event) bool {
return e.Kind == EventKindTurnStart
})
if evt.Meta.SessionKey != wantSessionKey {
t.Errorf("turn started with session_key=%q, want %q (got agent:main:main means bug is present)",
evt.Meta.SessionKey, wantSessionKey)
}
if err := <-done; err != nil {
t.Logf("processMessage returned error (acceptable in test env): %v", err)
}
}