diff --git a/internal/services/channelbridge/proactive.go b/internal/services/channelbridge/proactive.go index 953d8ba..511fc9b 100644 --- a/internal/services/channelbridge/proactive.go +++ b/internal/services/channelbridge/proactive.go @@ -6,6 +6,7 @@ import ( "strings" "git.yeij.top/AskaEth/Cyrene_v2/internal/channel/adapter" + "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/history" ) // proactiveTarget is the owner's IM address (platform + account id) resolved for @@ -46,6 +47,13 @@ func (b *Bridge) SendProactive(ctx context.Context, msg adapter.UnifiedMessage) if err := ad.SendProactive(ctx, out); err != nil { return fmt.Errorf("channelbridge: send proactive via %q: %w", target.platform, err) } + // Mirror the proactive message into the main conversation context (design/16 + // §4.4 + §4.6.1). Without this the model would not see what it proactively said, so + // a follow-up owner reply would feel incoherent (the message "loses" its history). + // It is the same mirror path as owner-private IM replies, scoped to MainSessionID. + b.persistToMain(ctx, history.RoleAssistant, msg.Content, target.platform, + fmt.Sprintf("%s:%s:%s", target.platform, target.accountID, target.accountID), + target.platform) return nil }