From 896f0bb8ad75c0d2ba29e51ac27595d060ea2e6b Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Fri, 24 Apr 2026 09:08:37 -0400 Subject: [PATCH] refactor(agent): add Session::from_source convenience constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Session keeps llm_client: Client as its internal model — a session is bounded (≤ 1 hour) and its cached client stays fresh within that window. Session::new(client, ...) remains the primitive (used by the server-mediated agent adapter path in fabro-cli/exec.rs, which builds a Client with a custom ProviderAdapter, no source involved). Add Session::from_source(source, ...) for callers that hold a source directly — resolves a Client via Client::from_source and delegates to new. Lets workflow-level callers that store Arc build a Session without hand-resolving first. Co-Authored-By: Claude Opus 4.7 (1M context) --- lib/crates/fabro-agent/src/session.rs | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/crates/fabro-agent/src/session.rs b/lib/crates/fabro-agent/src/session.rs index 673b2230c..7a4b846f0 100644 --- a/lib/crates/fabro-agent/src/session.rs +++ b/lib/crates/fabro-agent/src/session.rs @@ -2,6 +2,7 @@ use std::collections::{HashMap, VecDeque}; use std::sync::{Arc, Mutex}; use std::time::SystemTime; +use fabro_auth::CredentialSource; use fabro_llm::client::Client; use fabro_llm::error::ProviderErrorKind; use fabro_llm::generate::StreamAccumulator; @@ -91,6 +92,33 @@ impl Session { } } + /// Build a session from a credential source. Resolves the LLM client + /// once at construction and caches it for the session's lifetime. + /// Sessions are bounded (≤ 1 hour); cached client is fine within that + /// window. For longer-lived contexts (workflow runs) hold a source, + /// not a session. + /// + /// # Errors + /// + /// Returns an error if `Client::from_source` fails (e.g. vault unreachable, + /// OAuth refresh failed). + pub async fn from_source( + source: &dyn CredentialSource, + provider_profile: Arc, + sandbox: Arc, + config: SessionOptions, + subagent_manager: Option>>, + ) -> Result { + let client = Client::from_source(source).await?; + Ok(Self::new( + client, + provider_profile, + sandbox, + config, + subagent_manager, + )) + } + pub fn set_tool_env(&mut self, env: HashMap) { self.tool_env = Some(env); }