Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/config/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<crate::conversation::ConversationSettings> {
if self.response_mode.is_none() && !self.save_attachments {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to_conversation_settings() currently only treats response_mode = None as “default”, so response_mode = "active" still injects a no-op layer. Also, when response_mode is set, this will always write save_attachments: Some(false) even though it's the default.

Suggested change
if self.response_mode.is_none() && !self.save_attachments {
let response_mode = self.response_mode.unwrap_or_default();
let save_attachments = self.save_attachments.then_some(true);
if response_mode == crate::conversation::settings::ResponseMode::Active
&& save_attachments.is_none()
{
return None;
}
Some(crate::conversation::ConversationSettings {
response_mode,
save_attachments,
..Default::default()
})

return None;
}
Some(crate::conversation::ConversationSettings {
response_mode: self.response_mode.unwrap_or_default(),
save_attachments: Some(self.save_attachments),
..Default::default()
})
}
Comment on lines +955 to +970
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Honor listen_only_mode when deriving the agent default.

This helper ignores the deprecated compatibility field completely. If a config still uses listen_only_mode = true with no explicit response_mode, Line 962 returns None, so the channel default is still dropped instead of producing the effective mode promised by the struct docs. Please derive the effective response mode from both fields before the early return.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/config/types.rs` around lines 955 - 970, The
ChannelConfig::to_conversation_settings helper currently ignores the deprecated
listen_only_mode when deciding whether to return None and when filling
response_mode; compute an effective_response_mode first (use self.response_mode
if Some, otherwise set to listen-only mode when self.listen_only_mode is true,
otherwise default), use that to decide the early return (return None only when
effective_response_mode is default and save_attachments is false), and set
response_mode to that effective value when constructing ConversationSettings
(replace the current unwrap_or_default usage).

}

/// OpenCode subprocess worker configuration.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OpenCodeConfig {
Expand Down
36 changes: 25 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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) => {
Expand All @@ -1982,19 +1983,27 @@ 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!(
%error,
%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(),
)
}
}
}
Expand All @@ -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(),
)
}
}
};
Expand Down Expand Up @@ -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(
Expand All @@ -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) => {
Expand All @@ -2253,7 +2267,7 @@ async fn run(
spacebot::conversation::settings::ResolvedConversationSettings::resolve(
None,
binding_settings.as_ref(),
None,
agent_channel_default.as_ref(),
)
}
}
Expand All @@ -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) => {
Expand All @@ -2286,7 +2300,7 @@ async fn run(
spacebot::conversation::settings::ResolvedConversationSettings::resolve(
None,
binding_settings.as_ref(),
None,
agent_channel_default.as_ref(),
)
}
}
Expand Down
Loading