@@ -783,39 +783,9 @@ impl Agent {
783783 ) -> Result < AgentSession > {
784784 let opts = options. unwrap_or_default ( ) ;
785785
786- let llm_client = if let Some ( ref model) = opts. model {
787- let ( provider_name, model_id) = model
788- . split_once ( '/' )
789- . context ( "model format must be 'provider/model' (e.g., 'openai/gpt-4o')" ) ?;
790-
791- let mut llm_config = self
792- . code_config
793- . llm_config ( provider_name, model_id)
794- . with_context ( || {
795- format ! ( "provider '{provider_name}' or model '{model_id}' not found in config" )
796- } ) ?;
797-
798- if let Some ( temp) = opts. temperature {
799- llm_config = llm_config. with_temperature ( temp) ;
800- }
801- if let Some ( budget) = opts. thinking_budget {
802- llm_config = llm_config. with_thinking_budget ( budget) ;
803- }
804-
805- crate :: llm:: create_client_with_config ( llm_config)
806- } else {
807- if opts. temperature . is_some ( ) || opts. thinking_budget . is_some ( ) {
808- tracing:: warn!(
809- "temperature/thinking_budget set without model override — these will be ignored. \
810- Use with_model() to apply LLM parameter overrides."
811- ) ;
812- }
813- self . llm_client . clone ( )
814- } ;
815-
816786 // Merge global MCP manager with any session-level one from opts.
817787 // If both exist, session-level servers are added into the global manager.
818- let merged_opts = match ( & self . global_mcp , & opts. mcp_manager ) {
788+ let mut merged_opts = match ( & self . global_mcp , & opts. mcp_manager ) {
819789 ( Some ( global) , Some ( session) ) => {
820790 let global = Arc :: clone ( global) ;
821791 let session_mgr = Arc :: clone ( session) ;
@@ -857,6 +827,13 @@ impl Agent {
857827 _ => opts,
858828 } ;
859829
830+ let session_id = merged_opts
831+ . session_id
832+ . clone ( )
833+ . unwrap_or_else ( || uuid:: Uuid :: new_v4 ( ) . to_string ( ) ) ;
834+ merged_opts. session_id = Some ( session_id. clone ( ) ) ;
835+ let llm_client = self . resolve_session_llm_client ( & merged_opts, Some ( & session_id) ) ?;
836+
860837 self . build_session ( workspace. into ( ) , llm_client, & merged_opts)
861838 }
862839
@@ -963,21 +940,7 @@ impl Agent {
963940 // Build session with the saved workspace
964941 let mut opts = options;
965942 opts. session_id = Some ( data. id . clone ( ) ) ;
966-
967- let llm_client = if let Some ( ref model) = opts. model {
968- let ( provider_name, model_id) = model
969- . split_once ( '/' )
970- . context ( "model format must be 'provider/model'" ) ?;
971- let llm_config = self
972- . code_config
973- . llm_config ( provider_name, model_id)
974- . with_context ( || {
975- format ! ( "provider '{provider_name}' or model '{model_id}' not found" )
976- } ) ?;
977- crate :: llm:: create_client_with_config ( llm_config)
978- } else {
979- self . llm_client . clone ( )
980- } ;
943+ let llm_client = self . resolve_session_llm_client ( & opts, Some ( & data. id ) ) ?;
981944
982945 let session = self . build_session ( data. config . workspace . clone ( ) , llm_client, & opts) ?;
983946
@@ -987,6 +950,53 @@ impl Agent {
987950 Ok ( session)
988951 }
989952
953+ fn resolve_session_llm_client (
954+ & self ,
955+ opts : & SessionOptions ,
956+ session_id : Option < & str > ,
957+ ) -> Result < Arc < dyn LlmClient > > {
958+ let model_ref = if let Some ( ref model) = opts. model {
959+ model. as_str ( )
960+ } else {
961+ if opts. temperature . is_some ( ) || opts. thinking_budget . is_some ( ) {
962+ tracing:: warn!(
963+ "temperature/thinking_budget set without model override — these will be ignored. \
964+ Use with_model() to apply LLM parameter overrides."
965+ ) ;
966+ }
967+ self . code_config
968+ . default_model
969+ . as_deref ( )
970+ . context ( "default_model must be set in 'provider/model' format" ) ?
971+ } ;
972+
973+ let ( provider_name, model_id) = model_ref
974+ . split_once ( '/' )
975+ . context ( "model format must be 'provider/model' (e.g., 'openai/gpt-4o')" ) ?;
976+
977+ let mut llm_config = self
978+ . code_config
979+ . llm_config ( provider_name, model_id)
980+ . with_context ( || {
981+ format ! ( "provider '{provider_name}' or model '{model_id}' not found in config" )
982+ } ) ?;
983+
984+ if opts. model . is_some ( ) {
985+ if let Some ( temp) = opts. temperature {
986+ llm_config = llm_config. with_temperature ( temp) ;
987+ }
988+ if let Some ( budget) = opts. thinking_budget {
989+ llm_config = llm_config. with_thinking_budget ( budget) ;
990+ }
991+ }
992+
993+ if let Some ( session_id) = session_id {
994+ llm_config = llm_config. with_session_id ( session_id) ;
995+ }
996+
997+ Ok ( crate :: llm:: create_client_with_config ( llm_config) )
998+ }
999+
9901000 fn build_session (
9911001 & self ,
9921002 workspace : String ,
@@ -2710,12 +2720,16 @@ mod tests {
27102720 name: "anthropic" . to_string( ) ,
27112721 api_key: Some ( "test-key" . to_string( ) ) ,
27122722 base_url: None ,
2723+ headers: std:: collections:: HashMap :: new( ) ,
2724+ session_id_header: None ,
27132725 models: vec![ ModelConfig {
27142726 id: "claude-sonnet-4-20250514" . to_string( ) ,
27152727 name: "Claude Sonnet 4" . to_string( ) ,
27162728 family: "claude-sonnet" . to_string( ) ,
27172729 api_key: None ,
27182730 base_url: None ,
2731+ headers: std:: collections:: HashMap :: new( ) ,
2732+ session_id_header: None ,
27192733 attachment: false ,
27202734 reasoning: false ,
27212735 tool_call: true ,
@@ -2730,12 +2744,16 @@ mod tests {
27302744 name: "openai" . to_string( ) ,
27312745 api_key: Some ( "test-openai-key" . to_string( ) ) ,
27322746 base_url: None ,
2747+ headers: std:: collections:: HashMap :: new( ) ,
2748+ session_id_header: None ,
27332749 models: vec![ ModelConfig {
27342750 id: "gpt-4o" . to_string( ) ,
27352751 name: "GPT-4o" . to_string( ) ,
27362752 family: "gpt-4" . to_string( ) ,
27372753 api_key: None ,
27382754 base_url: None ,
2755+ headers: std:: collections:: HashMap :: new( ) ,
2756+ session_id_header: None ,
27392757 attachment: false ,
27402758 reasoning: false ,
27412759 tool_call: true ,
@@ -3387,6 +3405,8 @@ dir content
33873405 name: "anthropic" . to_string( ) ,
33883406 api_key: Some ( "test-key" . to_string( ) ) ,
33893407 base_url: None ,
3408+ headers: std:: collections:: HashMap :: new( ) ,
3409+ session_id_header: None ,
33903410 models: vec![ ] ,
33913411 } ] ,
33923412 ..Default :: default ( )
0 commit comments