@@ -13,12 +13,12 @@ use goose::conversation::Conversation;
1313use goose:: mcp_utils:: ToolResult ;
1414use goose:: permission:: permission_confirmation:: PrincipalType ;
1515use goose:: permission:: { Permission , PermissionConfirmation } ;
16- use goose:: providers:: create ;
16+ use goose:: providers:: provider_registry :: ProviderConstructor ;
1717use goose:: session:: session_manager:: SessionType ;
1818use goose:: session:: { Session , SessionManager } ;
1919use rmcp:: model:: { CallToolResult , RawContent , ResourceContents , Role } ;
2020use sacp:: schema:: {
21- AgentCapabilities , AuthenticateRequest , AuthenticateResponse , BlobResourceContents ,
21+ AgentCapabilities , AuthMethod , AuthenticateRequest , AuthenticateResponse , BlobResourceContents ,
2222 CancelNotification , Content , ContentBlock , ContentChunk , EmbeddedResource ,
2323 EmbeddedResourceResource , ImageContent , InitializeRequest , InitializeResponse ,
2424 LoadSessionRequest , LoadSessionResponse , McpCapabilities , McpServer , NewSessionRequest ,
@@ -46,16 +46,9 @@ struct GooseAcpSession {
4646pub struct GooseAcpAgent {
4747 sessions : Arc < Mutex < HashMap < String , GooseAcpSession > > > ,
4848 agent : Arc < Agent > ,
49- provider : Arc < dyn goose:: providers:: base:: Provider > ,
50- }
51-
52- pub struct AcpServerConfig {
53- pub provider : Arc < dyn goose:: providers:: base:: Provider > ,
54- pub builtins : Vec < String > ,
55- pub data_dir : std:: path:: PathBuf ,
56- pub config_dir : std:: path:: PathBuf ,
57- pub goose_mode : goose:: config:: GooseMode ,
58- pub disable_session_naming : bool ,
49+ provider_factory : ProviderConstructor ,
50+ config_dir : std:: path:: PathBuf ,
51+ provider_initialized : tokio:: sync:: OnceCell < String > ,
5952}
6053
6154fn mcp_server_to_extension_config ( mcp_server : McpServer ) -> Result < ExtensionConfig , String > {
@@ -278,54 +271,23 @@ impl GooseAcpAgent {
278271 Arc :: clone ( & self . agent . config . permission_manager )
279272 }
280273
281- pub async fn new ( builtins : Vec < String > ) -> Result < Self > {
282- let config = Config :: global ( ) ;
283-
284- let provider_name: String = config
285- . get_goose_provider ( )
286- . map_err ( |e| anyhow:: anyhow!( "No provider configured: {}" , e) ) ?;
287-
288- let model_name: String = config
289- . get_goose_model ( )
290- . map_err ( |e| anyhow:: anyhow!( "No model configured: {}" , e) ) ?;
291-
292- let model_config = goose:: model:: ModelConfig {
293- model_name : model_name. clone ( ) ,
294- context_limit : None ,
295- temperature : None ,
296- max_tokens : None ,
297- toolshim : false ,
298- toolshim_model : None ,
299- fast_model : None ,
300- request_params : None ,
301- } ;
302- let provider = create ( & provider_name, model_config) . await ?;
303- let goose_mode = config
304- . get_goose_mode ( )
305- . unwrap_or ( goose:: config:: GooseMode :: Auto ) ;
306-
307- Self :: with_config ( AcpServerConfig {
308- provider,
309- builtins,
310- data_dir : Paths :: data_dir ( ) ,
311- config_dir : Paths :: config_dir ( ) ,
312- goose_mode,
313- disable_session_naming : config. get_goose_disable_session_naming ( ) . unwrap_or ( false ) ,
314- } )
315- . await
316- }
317-
318- pub async fn with_config ( config : AcpServerConfig ) -> Result < Self > {
319- let session_manager = Arc :: new ( SessionManager :: new ( config. data_dir ) ) ;
320- let config_dir = config. config_dir . clone ( ) ;
321- let permission_manager = Arc :: new ( PermissionManager :: new ( config. config_dir ) ) ;
274+ pub async fn new (
275+ provider_factory : ProviderConstructor ,
276+ builtins : Vec < String > ,
277+ data_dir : std:: path:: PathBuf ,
278+ config_dir : std:: path:: PathBuf ,
279+ goose_mode : goose:: config:: GooseMode ,
280+ disable_session_naming : bool ,
281+ ) -> Result < Self > {
282+ let session_manager = Arc :: new ( SessionManager :: new ( data_dir) ) ;
283+ let permission_manager = Arc :: new ( PermissionManager :: new ( config_dir. clone ( ) ) ) ;
322284
323285 let agent = Agent :: with_config ( AgentConfig :: new (
324286 Arc :: clone ( & session_manager) ,
325287 permission_manager,
326288 None ,
327- config . goose_mode ,
328- config . disable_session_naming ,
289+ goose_mode,
290+ disable_session_naming,
329291 ) ) ;
330292
331293 let agent_ptr = Arc :: new ( agent) ;
@@ -334,13 +296,15 @@ impl GooseAcpAgent {
334296 let config_file = Config :: new ( & config_path, "goose" ) ?;
335297 let extensions = get_enabled_extensions_with_config ( & config_file) ;
336298
337- add_builtins ( & agent_ptr, config . builtins ) . await ;
299+ add_builtins ( & agent_ptr, builtins) . await ;
338300 add_extensions ( & agent_ptr, extensions) . await ;
339301
340302 Ok ( Self {
341- provider : config. provider . clone ( ) ,
342303 sessions : Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ,
343304 agent : agent_ptr,
305+ provider_factory,
306+ config_dir,
307+ provider_initialized : tokio:: sync:: OnceCell :: new ( ) ,
344308 } )
345309 }
346310
@@ -354,9 +318,7 @@ impl GooseAcpAgent {
354318 )
355319 . await ?;
356320
357- self . agent
358- . update_provider ( self . provider . clone ( ) , & goose_session. id )
359- . await ?;
321+ self . ensure_provider ( & goose_session) . await ?;
360322
361323 let session = GooseAcpSession {
362324 messages : Conversation :: new_unvalidated ( Vec :: new ( ) ) ,
@@ -692,7 +654,15 @@ impl GooseAcpAgent {
692654 . embedded_context ( true ) ,
693655 )
694656 . mcp_capabilities ( McpCapabilities :: new ( ) . http ( true ) ) ;
695- Ok ( InitializeResponse :: new ( args. protocol_version ) . agent_capabilities ( capabilities) )
657+ Ok ( InitializeResponse :: new ( args. protocol_version )
658+ . agent_capabilities ( capabilities)
659+ . auth_methods ( vec ! [ AuthMethod :: new(
660+ "goose-provider" ,
661+ "Configure Provider" ,
662+ )
663+ . description(
664+ "Run `goose configure` to set up your AI provider and API key" ,
665+ ) ] ) )
696666 }
697667
698668 async fn on_new_session (
@@ -712,7 +682,9 @@ impl GooseAcpAgent {
712682 . map_err ( |e| {
713683 sacp:: Error :: internal_error ( ) . data ( format ! ( "Failed to create session: {}" , e) )
714684 } ) ?;
715- self . update_session_with_provider ( & goose_session) . await ?;
685+ self . ensure_provider ( & goose_session) . await . map_err ( |e| {
686+ sacp:: Error :: internal_error ( ) . data ( format ! ( "Failed to set provider: {}" , e) )
687+ } ) ?;
716688
717689 for mcp_server in args. mcp_servers {
718690 let config = match mcp_server_to_extension_config ( mcp_server) {
@@ -746,16 +718,21 @@ impl GooseAcpAgent {
746718 Ok ( NewSessionResponse :: new ( SessionId :: new ( goose_session. id ) ) )
747719 }
748720
749- async fn update_session_with_provider (
750- & self ,
751- goose_session : & Session ,
752- ) -> Result < ( ) , sacp:: Error > {
753- self . agent
754- . update_provider ( self . provider . clone ( ) , & goose_session. id )
755- . await
756- . map_err ( |e| {
757- sacp:: Error :: internal_error ( ) . data ( format ! ( "Failed to set provider: {}" , e) )
758- } ) ?;
721+ // Called at most once via OnceCell; returns the model_id used.
722+ async fn create_provider ( & self , session : & Session ) -> Result < String > {
723+ let config_path = self . config_dir . join ( CONFIG_YAML_NAME ) ;
724+ let config = Config :: new ( & config_path, "goose" ) ?;
725+ let model_id = config. get_goose_model ( ) ?;
726+ let model_config = goose:: model:: ModelConfig :: new ( & model_id) ?;
727+ let provider = ( self . provider_factory ) ( model_config) . await ?;
728+ self . agent . update_provider ( provider, & session. id ) . await ?;
729+ Ok ( model_id)
730+ }
731+
732+ async fn ensure_provider ( & self , session : & Session ) -> Result < ( ) > {
733+ self . provider_initialized
734+ . get_or_try_init ( || self . create_provider ( session) )
735+ . await ?;
759736 Ok ( ( ) )
760737 }
761738
@@ -773,7 +750,9 @@ impl GooseAcpAgent {
773750 sacp:: Error :: invalid_params ( )
774751 . data ( format ! ( "Failed to load session {}: {}" , session_id, e) )
775752 } ) ?;
776- self . update_session_with_provider ( & goose_session) . await ?;
753+ self . ensure_provider ( & goose_session) . await . map_err ( |e| {
754+ sacp:: Error :: internal_error ( ) . data ( format ! ( "Failed to set provider: {}" , e) )
755+ } ) ?;
777756
778757 let conversation = goose_session. conversation . ok_or_else ( || {
779758 sacp:: Error :: internal_error ( )
@@ -1045,7 +1024,13 @@ pub async fn run(builtins: Vec<String>) -> Result<()> {
10451024 let outgoing = tokio:: io:: stdout ( ) . compat_write ( ) ;
10461025 let incoming = tokio:: io:: stdin ( ) . compat ( ) ;
10471026
1048- let agent = Arc :: new ( GooseAcpAgent :: new ( builtins) . await ?) ;
1027+ let server =
1028+ crate :: server_factory:: AcpServer :: new ( crate :: server_factory:: AcpServerFactoryConfig {
1029+ builtins,
1030+ data_dir : Paths :: data_dir ( ) ,
1031+ config_dir : Paths :: config_dir ( ) ,
1032+ } ) ;
1033+ let agent = server. create_agent ( ) . await ?;
10491034 serve ( agent, incoming, outgoing) . await
10501035}
10511036
0 commit comments