Skip to content

Commit 0eb1a98

Browse files
tusharmathforge-code-agent
authored andcommitted
refactor(config): cache ForgeConfig and pass through stack
1 parent 8745692 commit 0eb1a98

File tree

14 files changed

+67
-71
lines changed

14 files changed

+67
-71
lines changed

crates/forge_api/src/api.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::path::PathBuf;
33
use anyhow::Result;
44
use forge_app::dto::ToolsOverview;
55
use forge_app::{User, UserUsage};
6-
use forge_config::ForgeConfig;
76
use forge_domain::{AgentId, Effort, ModelId, ProviderModels};
87
use forge_stream::MpscStream;
98
use futures::stream::BoxStream;
@@ -51,9 +50,6 @@ pub trait API: Sync + Send {
5150
/// Returns the current environment
5251
fn environment(&self) -> Environment;
5352

54-
/// Returns the full application configuration.
55-
fn get_config(&self) -> ForgeConfig;
56-
5753
/// Adds a new conversation to the conversation store
5854
async fn upsert_conversation(&self, conversation: Conversation) -> Result<()>;
5955

crates/forge_api/src/forge_api.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,20 @@ use crate::API;
2525
pub struct ForgeAPI<S, F> {
2626
services: Arc<S>,
2727
infra: Arc<F>,
28+
config: forge_config::ForgeConfig,
2829
}
2930

3031
impl<A, F> ForgeAPI<A, F> {
31-
pub fn new(services: Arc<A>, infra: Arc<F>) -> Self {
32-
Self { services, infra }
32+
pub fn new(services: Arc<A>, infra: Arc<F>, config: forge_config::ForgeConfig) -> Self {
33+
Self { services, infra, config }
3334
}
3435

3536
/// Creates a ForgeApp instance with the current services
3637
fn app(&self) -> ForgeApp<A>
3738
where
3839
A: Services,
3940
{
40-
ForgeApp::new(self.services.clone())
41+
ForgeApp::new(self.services.clone(), self.config.clone())
4142
}
4243
}
4344

@@ -51,8 +52,8 @@ impl ForgeAPI<ForgeServices<ForgeRepo<ForgeInfra>>, ForgeRepo<ForgeInfra>> {
5152
pub fn init(cwd: PathBuf, config: ForgeConfig, services_url: Url) -> Self {
5253
let infra = Arc::new(ForgeInfra::new(cwd, config.clone(), services_url));
5354
let repo = Arc::new(ForgeRepo::new(infra.clone(), config.clone()));
54-
let app = Arc::new(ForgeServices::new(repo.clone(), config));
55-
ForgeAPI::new(app, repo)
55+
let app = Arc::new(ForgeServices::new(repo.clone(), config.clone()));
56+
ForgeAPI::new(app, repo, config)
5657
}
5758

5859
pub async fn get_skills_internal(&self) -> Result<Vec<Skill>> {
@@ -98,7 +99,7 @@ impl<A: Services, F: CommandInfra + EnvironmentInfra + SkillRepository + GrpcInf
9899
diff: Option<String>,
99100
additional_context: Option<String>,
100101
) -> Result<forge_app::CommitResult> {
101-
let git_app = GitApp::new(self.services.clone());
102+
let git_app = GitApp::new(self.services.clone(), self.config.clone());
102103
let result = git_app
103104
.commit_message(max_diff_size, diff, additional_context)
104105
.await?;
@@ -154,10 +155,6 @@ impl<A: Services, F: CommandInfra + EnvironmentInfra + SkillRepository + GrpcInf
154155
self.services.get_environment().clone()
155156
}
156157

157-
fn get_config(&self) -> ForgeConfig {
158-
self.services.get_config()
159-
}
160-
161158
async fn conversation(
162159
&self,
163160
conversation_id: &ConversationId,

crates/forge_app/src/agent.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub trait AgentService: Send + Sync + 'static {
3030
agent: &Agent,
3131
context: &ToolCallContext,
3232
call: ToolCallFull,
33+
config: &ForgeConfig,
3334
) -> ToolResult;
3435

3536
/// Synchronize the on-going conversation
@@ -60,8 +61,9 @@ impl<T: Services> AgentService for T {
6061
agent: &Agent,
6162
context: &ToolCallContext,
6263
call: ToolCallFull,
64+
config: &ForgeConfig,
6365
) -> ToolResult {
64-
let registry = ToolRegistry::new(Arc::new(self.clone()));
66+
let registry = ToolRegistry::new(Arc::new(self.clone()), config.clone());
6567
registry.call(agent, context, call).await
6668
}
6769

crates/forge_app/src/agent_executor.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,21 @@ use forge_template::Element;
1010
use futures::StreamExt;
1111
use tokio::sync::RwLock;
1212

13+
use forge_config::ForgeConfig;
14+
1315
use crate::error::Error;
1416
use crate::{AgentRegistry, ConversationService, Services};
1517

1618
#[derive(Clone)]
1719
pub struct AgentExecutor<S> {
1820
services: Arc<S>,
21+
config: ForgeConfig,
1922
pub tool_agents: Arc<RwLock<Option<Vec<ToolDefinition>>>>,
2023
}
2124

2225
impl<S: Services> AgentExecutor<S> {
23-
pub fn new(services: Arc<S>) -> Self {
24-
Self { services, tool_agents: Arc::new(RwLock::new(None)) }
26+
pub fn new(services: Arc<S>, config: ForgeConfig) -> Self {
27+
Self { services, config, tool_agents: Arc::new(RwLock::new(None)) }
2528
}
2629

2730
/// Returns a list of tool definitions for all available agents.
@@ -63,7 +66,7 @@ impl<S: Services> AgentExecutor<S> {
6366
.upsert_conversation(conversation.clone())
6467
.await?;
6568
// Execute the request through the ForgeApp
66-
let app = crate::ForgeApp::new(self.services.clone());
69+
let app = crate::ForgeApp::new(self.services.clone(), self.config.clone());
6770
let mut response_stream = app
6871
.chat(
6972
agent_id.clone(),

crates/forge_app/src/app.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ pub(crate) fn build_template_config(config: &ForgeConfig) -> forge_domain::Templ
4444
pub struct ForgeApp<S> {
4545
services: Arc<S>,
4646
tool_registry: ToolRegistry<S>,
47+
config: ForgeConfig,
4748
}
4849

4950
impl<S: Services> ForgeApp<S> {
50-
/// Creates a new ForgeApp instance with the provided services.
51-
pub fn new(services: Arc<S>) -> Self {
52-
Self { tool_registry: ToolRegistry::new(services.clone()), services }
51+
/// Creates a new ForgeApp instance with the provided services and config.
52+
pub fn new(services: Arc<S>, config: ForgeConfig) -> Self {
53+
Self { tool_registry: ToolRegistry::new(services.clone(), config.clone()), services, config }
5354
}
5455

5556
/// Executes a chat request and returns a stream of responses.
@@ -69,7 +70,7 @@ impl<S: Services> ForgeApp<S> {
6970
.expect("conversation for the request should've been created at this point.");
7071

7172
// Discover files using the discovery service
72-
let forge_config = services.get_config();
73+
let forge_config = self.config.clone();
7374
let environment = services.get_environment();
7475

7576
let files = services.list_current_directory().await?;
@@ -157,7 +158,7 @@ impl<S: Services> ForgeApp<S> {
157158

158159
let retry_config = forge_config.retry.clone().unwrap_or_default();
159160

160-
let orch = Orchestrator::new(services.clone(), retry_config, conversation, agent)
161+
let orch = Orchestrator::new(services.clone(), retry_config, conversation, agent, forge_config)
161162
.error_tracker(ToolErrorTracker::new(max_tool_failure_per_turn))
162163
.tool_definitions(tool_definitions)
163164
.models(models)
@@ -219,7 +220,7 @@ impl<S: Services> ForgeApp<S> {
219220
let original_messages = context.messages.len();
220221
let original_token_count = *context.token_count();
221222

222-
let forge_config = self.services.get_config();
223+
let forge_config = self.config.clone();
223224

224225
// Get agent and apply workflow config
225226
let agent = self.services.get_agent(&active_agent_id).await?;

crates/forge_app/src/git_app.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub enum GitAppError {
2222
/// GitApp handles git-related operations like commit message generation.
2323
pub struct GitApp<S> {
2424
services: Arc<S>,
25+
config: forge_config::ForgeConfig,
2526
}
2627

2728
/// Result of a commit operation
@@ -66,9 +67,9 @@ struct DiffContext {
6667
}
6768

6869
impl<S> GitApp<S> {
69-
/// Creates a new GitApp instance with the provided services.
70-
pub fn new(services: Arc<S>) -> Self {
71-
Self { services }
70+
/// Creates a new GitApp instance with the provided services and config.
71+
pub fn new(services: Arc<S>, config: forge_config::ForgeConfig) -> Self {
72+
Self { services, config }
7273
}
7374

7475
/// Truncates diff content if it exceeds the maximum size
@@ -213,7 +214,7 @@ impl<S: Services> GitApp<S>
213214
additional_context,
214215
};
215216

216-
let retry_config = self.services.get_config().retry.unwrap_or_default();
217+
let retry_config = self.config.retry.clone().unwrap_or_default();
217218
crate::retry::retry_with_config(
218219
&retry_config,
219220
|| self.generate_message_from_diff(ctx.clone()),
@@ -224,7 +225,7 @@ impl<S: Services> GitApp<S>
224225

225226
/// Fetches git context (branch name and recent commits)
226227
async fn fetch_git_context(&self, cwd: &Path) -> Result<(String, String)> {
227-
let max_commit_count = self.services.get_config().max_commit_count;
228+
let max_commit_count = self.config.max_commit_count;
228229
let git_log_cmd =
229230
format!("git log --pretty=format:%s --abbrev-commit --max-count={max_commit_count}");
230231
let (recent_commits, branch_name) = tokio::join!(

crates/forge_app/src/hooks/title_generation.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ mod tests {
189189
_agent: &Agent,
190190
_context: &ToolCallContext,
191191
_call: ToolCallFull,
192+
_config: &forge_config::ForgeConfig,
192193
) -> ToolResult {
193194
unreachable!("Not used in tests")
194195
}

crates/forge_app/src/orch.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub struct Orchestrator<S> {
2525
agent: Agent,
2626
error_tracker: ToolErrorTracker,
2727
hook: Arc<Hook>,
28+
config: forge_config::ForgeConfig,
2829
}
2930

3031
impl<S: AgentService> Orchestrator<S> {
@@ -33,12 +34,14 @@ impl<S: AgentService> Orchestrator<S> {
3334
retry_config: RetryConfig,
3435
conversation: Conversation,
3536
agent: Agent,
37+
config: forge_config::ForgeConfig,
3638
) -> Self {
3739
Self {
3840
conversation,
3941
retry_config,
4042
services,
4143
agent,
44+
config,
4245
sender: Default::default(),
4346
tool_definitions: Default::default(),
4447
models: Default::default(),
@@ -97,7 +100,7 @@ impl<S: AgentService> Orchestrator<S> {
97100
// Execute the tool
98101
let tool_result = self
99102
.services
100-
.call(&self.agent, tool_context, tool_call.clone())
103+
.call(&self.agent, tool_context, tool_call.clone(), &self.config)
101104
.await;
102105

103106
// Fire the ToolcallEnd lifecycle event (fires on both success and failure)

crates/forge_app/src/orch_spec/orch_runner.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl Runner {
120120
let conversation = SetConversationId.apply(conversation);
121121

122122
let retry_config = setup.config.retry.clone().unwrap_or_default();
123-
let orch = Orchestrator::new(services.clone(), retry_config, conversation, agent)
123+
let orch = Orchestrator::new(services.clone(), retry_config, conversation, agent, setup.config.clone())
124124
.error_tracker(ToolErrorTracker::new(3))
125125
.tool_definitions(system_tools)
126126
.hook(Arc::new(
@@ -171,6 +171,7 @@ impl AgentService for Runner {
171171
_: &forge_domain::Agent,
172172
_: &forge_domain::ToolCallContext,
173173
test_call: forge_domain::ToolCallFull,
174+
_: &forge_config::ForgeConfig,
174175
) -> forge_domain::ToolResult {
175176
let name = test_call.name.clone();
176177
let mut guard = self.test_tool_calls.lock().await;

crates/forge_app/src/services.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -604,12 +604,6 @@ pub trait Services: Send + Sync + 'static + Clone + EnvironmentInfra {
604604
fn provider_auth_service(&self) -> &Self::ProviderAuthService;
605605
fn workspace_service(&self) -> &Self::WorkspaceService;
606606
fn skill_fetch_service(&self) -> &Self::SkillFetchService;
607-
608-
/// Returns the current application configuration snapshot.
609-
///
610-
/// Config is read once at startup and passed via constructor. Values are
611-
/// not re-read from disk dynamically.
612-
fn get_config(&self) -> forge_config::ForgeConfig;
613607
}
614608

615609
#[async_trait::async_trait]

0 commit comments

Comments
 (0)