From 6e6f6c6ae5285b7fdcfdedcd5cf88583bd44cb92 Mon Sep 17 00:00:00 2001 From: James Pine Date: Tue, 7 Apr 2026 09:16:05 -0700 Subject: [PATCH] fix: apply [agents.channel] config when spawning platform channels The agent_default argument to ResolvedConversationSettings::resolve() was always None for platform channels (Slack, Discord, etc.) and the idle-worker resume path, so [agents.channel] settings (response_mode, save_attachments) were loaded from TOML but silently discarded at runtime. Adds ChannelConfig::to_conversation_settings() to centralise the conversion, and passes the result as agent_default in all six resolve() call sites (new-message path and idle-worker resume path). Co-Authored-By: Claude Sonnet 4.6 --- src/config/types.rs | 18 ++++++++++++++++++ src/main.rs | 36 +++++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/config/types.rs b/src/config/types.rs index 1cbd07501..d704e2b31 100644 --- a/src/config/types.rs +++ b/src/config/types.rs @@ -952,6 +952,24 @@ pub struct ChannelConfig { pub save_attachments: bool, } +impl ChannelConfig { + /// Convert to a `ConversationSettings` for use as the agent-level default in + /// `ResolvedConversationSettings::resolve`. Returns `None` when both fields + /// match their system defaults (avoids injecting a no-op layer). + pub fn to_conversation_settings( + &self, + ) -> Option { + if self.response_mode.is_none() && !self.save_attachments { + return None; + } + Some(crate::conversation::ConversationSettings { + response_mode: self.response_mode.unwrap_or_default(), + save_attachments: Some(self.save_attachments), + ..Default::default() + }) + } +} + /// OpenCode subprocess worker configuration. #[derive(Debug, Clone, PartialEq, Eq)] pub struct OpenCodeConfig { diff --git a/src/main.rs b/src/main.rs index aae7974e0..cacb026e2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1960,6 +1960,7 @@ async fn run( // Load per-conversation settings (idle worker resume). // Try portal store first, then channel_settings for platform channels. + let agent_channel_default = agent.config.channel.to_conversation_settings(); let resolved_settings = { let agent_id_str = agent_id.to_string(); let portal_store = spacebot::conversation::PortalConversationStore::new( @@ -1973,7 +1974,7 @@ async fn run( spacebot::conversation::settings::ResolvedConversationSettings::resolve( conv.settings.as_ref(), None, - None, + agent_channel_default.as_ref(), ) } Ok(None) => { @@ -1982,11 +1983,15 @@ async fn run( spacebot::conversation::settings::ResolvedConversationSettings::resolve( Some(&settings), None, - None, + agent_channel_default.as_ref(), ) } Ok(None) => { - spacebot::conversation::settings::ResolvedConversationSettings::default() + spacebot::conversation::settings::ResolvedConversationSettings::resolve( + None, + None, + agent_channel_default.as_ref(), + ) } Err(error) => { tracing::warn!( @@ -1994,7 +1999,11 @@ async fn run( %conversation_id, "idle worker resume: failed to load channel settings, using defaults" ); - spacebot::conversation::settings::ResolvedConversationSettings::default() + spacebot::conversation::settings::ResolvedConversationSettings::resolve( + None, + None, + agent_channel_default.as_ref(), + ) } } } @@ -2004,7 +2013,11 @@ async fn run( %conversation_id, "idle worker resume: failed to load portal settings, using defaults" ); - spacebot::conversation::settings::ResolvedConversationSettings::default() + spacebot::conversation::settings::ResolvedConversationSettings::resolve( + None, + None, + agent_channel_default.as_ref(), + ) } } }; @@ -2224,6 +2237,7 @@ async fn run( // Load per-conversation settings. // Resolution: per-channel DB override > binding defaults > agent defaults > system defaults + let agent_channel_default = agent.config.channel.to_conversation_settings(); let resolved_settings = if message.adapter.as_deref() == Some("portal") { // Portal: load from portal_conversations table. let store = spacebot::conversation::PortalConversationStore::new( @@ -2234,14 +2248,14 @@ async fn run( spacebot::conversation::settings::ResolvedConversationSettings::resolve( conv.settings.as_ref(), binding_settings.as_ref(), - None, + agent_channel_default.as_ref(), ) } Ok(None) => { spacebot::conversation::settings::ResolvedConversationSettings::resolve( None, binding_settings.as_ref(), - None, + agent_channel_default.as_ref(), ) } Err(error) => { @@ -2253,7 +2267,7 @@ async fn run( spacebot::conversation::settings::ResolvedConversationSettings::resolve( None, binding_settings.as_ref(), - None, + agent_channel_default.as_ref(), ) } } @@ -2267,14 +2281,14 @@ async fn run( spacebot::conversation::settings::ResolvedConversationSettings::resolve( Some(&settings), binding_settings.as_ref(), - None, + agent_channel_default.as_ref(), ) } Ok(None) => { spacebot::conversation::settings::ResolvedConversationSettings::resolve( None, binding_settings.as_ref(), - None, + agent_channel_default.as_ref(), ) } Err(error) => { @@ -2286,7 +2300,7 @@ async fn run( spacebot::conversation::settings::ResolvedConversationSettings::resolve( None, binding_settings.as_ref(), - None, + agent_channel_default.as_ref(), ) } }