Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions crates/forge_config/.forge.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ tool_timeout_secs = 300
top_k = 30
top_p = 0.8
verify_todos = true
research_subagent = false

[retry]
backoff_factor = 2
Expand Down
7 changes: 7 additions & 0 deletions crates/forge_config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,13 @@ pub struct ForgeConfig {
/// when a task ends and reminds the LLM about them.
#[serde(default)]
pub verify_todos: bool,

/// Whether the deep research agent is available.
///
/// When set to `true`, the Sage agent is added to the agent list and
/// the `:sage` app command is enabled. Defaults to `false`.
#[serde(default)]
pub research_subagent: bool,
}

impl ForgeConfig {
Expand Down
6 changes: 5 additions & 1 deletion crates/forge_main/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2008,7 +2008,11 @@ impl<A: API + ConsoleWriter + 'static, F: Fn(ForgeConfig) -> A + Send + Sync> UI
self.on_agent_change(AgentId::MUSE).await?;
}
AppCommand::Sage => {
self.on_agent_change(AgentId::SAGE).await?;
if !self.config.research_subagent {
self.writeln("Sage agent is disabled. Set `research_subagent = true` in .forge.toml to enable it.")?;
} else {
self.on_agent_change(AgentId::SAGE).await?;
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

User should be able to switch to sage if they want to. Sage should only be disabled as a sub-agent.

}
AppCommand::Help => {
let info = Info::from(self.command.as_ref());
Expand Down
18 changes: 15 additions & 3 deletions crates/forge_repo/src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,17 @@ impl<F: FileInfoInfra + EnvironmentInfra<Config = ForgeConfig> + DirectoryReader
AgentRepository for ForgeAgentRepository<F>
{
async fn get_agents(&self) -> anyhow::Result<Vec<forge_domain::Agent>> {
let config = self.infra.get_config()?;
let agent_defs = self.load_agents().await?;

let session = self
.infra
.get_config()?
let session = config
.session
.clone()
.ok_or(forge_domain::Error::NoDefaultSession)?;

Ok(agent_defs
.into_iter()
.filter(|def| filter_agent(def, &config))
.map(|def| {
def.into_agent(
ProviderId::from(session.provider_id.clone()),
Expand All @@ -182,9 +183,11 @@ impl<F: FileInfoInfra + EnvironmentInfra<Config = ForgeConfig> + DirectoryReader
}

async fn get_agent_infos(&self) -> anyhow::Result<Vec<forge_domain::AgentInfo>> {
let config = self.infra.get_config()?;
let agent_defs = self.load_agents().await?;
Ok(agent_defs
.into_iter()
.filter(|def| filter_agent(def, &config))
.map(|def| forge_domain::AgentInfo {
id: def.id,
title: def.title,
Expand All @@ -194,6 +197,15 @@ impl<F: FileInfoInfra + EnvironmentInfra<Config = ForgeConfig> + DirectoryReader
}
}

/// Returns `false` for agents that are disabled by a feature flag in the
/// configuration, `true` for all others.
fn filter_agent(def: &AgentDefinition, config: &ForgeConfig) -> bool {
if def.id.as_str() == forge_domain::AgentId::SAGE.as_str() && !config.research_subagent {
return false;
}
true
}
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Move this logic closer to the sub-agent task description. The repo must list all the sub-agents always.


#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
Expand Down
5 changes: 5 additions & 0 deletions forge.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@
}
]
},
"research_subagent": {
"description": "Whether the deep research agent is available.\n\nWhen set to `true`, the Sage agent is added to the agent list and\nthe `:sage` app command is enabled. Defaults to `false`.",
"type": "boolean",
"default": false
},
"restricted": {
"description": "Whether restricted mode is active; when enabled, tool execution requires\nexplicit permission grants.",
"type": "boolean",
Expand Down
Loading