@@ -85,6 +85,29 @@ def _process_endpoint(self, endpoint_name: str) -> Optional[List[str]]:
8585
8686 def _write_opencode_config (self , selected_models_by_endpoint : Dict [str , List [str ]]) -> Path :
8787 """Write OpenCode.ai configuration to ~/.config/opencode/opencode.json."""
88+ config_file = Path .home () / ".config" / "opencode" / "opencode.json"
89+
90+ # Load existing config to preserve all existing settings
91+ existing = {}
92+ if config_file .exists ():
93+ try :
94+ existing = json .loads (config_file .read_text (encoding = "utf-8" ))
95+ if not isinstance (existing , dict ):
96+ existing = {}
97+ except Exception :
98+ pass
99+
100+ opencode_config = {
101+ "$schema" : "https://opencode.ai/config.json" ,
102+ "provider" : existing .get ("provider" , {}),
103+ "mcp" : existing .get ("mcp" , {}),
104+ }
105+
106+ # Preserve other top-level keys from existing config (e.g. theme, keybinds)
107+ for key , val in existing .items ():
108+ if key not in opencode_config :
109+ opencode_config [key ] = val
110+
88111 # Set default model to the first selected model with provider prefix
89112 default_model = None
90113 for endpoint_name , selected_models in selected_models_by_endpoint .items ():
@@ -95,42 +118,43 @@ def _write_opencode_config(self, selected_models_by_endpoint: Dict[str, List[str
95118 default_model = f"{ provider_id } /{ model_key } "
96119 break
97120
98- opencode_config = {
99- "$schema" : "https://opencode.ai/config.json" ,
100- "provider" : {},
101- "mcp" : {},
102- }
103-
104121 if default_model :
105122 opencode_config ["model" ] = default_model
106123
107- # Create providers from selected models
124+ # Merge providers from selected models into existing providers
108125 for endpoint_name , selected_models in selected_models_by_endpoint .items ():
109126 success , endpoint_config = self .endpoint_manager .get_endpoint_config (endpoint_name )
110127 if not success :
111128 continue
112129
113130 provider_id = endpoint_name .replace (":" , "-" ).replace ("_" , "-" ).lower ()
114- provider = {
131+
132+ # Start from existing provider entry if present, otherwise create new
133+ provider = opencode_config ["provider" ].get (provider_id , {
115134 "npm" : "@ai-sdk/openai-compatible" ,
116135 "name" : endpoint_config .get ("description" , endpoint_name ),
117136 "options" : {
118137 "baseURL" : endpoint_config ["endpoint" ]
119138 },
120139 "models" : {}
121- }
140+ })
141+
142+ # Update mutable fields so they stay current
143+ provider ["npm" ] = "@ai-sdk/openai-compatible"
144+ provider ["name" ] = endpoint_config .get ("description" , endpoint_name )
145+ provider .setdefault ("options" , {})["baseURL" ] = endpoint_config ["endpoint" ]
146+ provider .setdefault ("models" , {})
122147
123148 # Handle API key configuration
124149 if "api_key_env" in endpoint_config :
125150 provider ["options" ]["apiKey" ] = f"{{env:{ endpoint_config ['api_key_env' ]} }}"
126151 elif "api_key" in endpoint_config :
127152 provider ["options" ]["apiKey" ] = endpoint_config ["api_key" ]
128153
129- # Add selected models
154+ # Append selected models (existing models are preserved)
130155 for model_name in selected_models :
131156 # Fix model name for copilot-api
132157 if endpoint_name == "copilot-api" and model_name in ["g" , "r" , "o" , "k" , "-" , "c" , "d" , "e" , "f" , "a" , "s" , "t" , "1" ]:
133- # If single letters, replace with proper model
134158 model_name = "lmstudio/google/gemma-3n-e4b"
135159 model_key = model_name .replace ("/" , "-" ).replace (":" , "-" ).replace ("." , "-" ).lower ()
136160 provider ["models" ][model_key ] = {
@@ -143,16 +167,6 @@ def _write_opencode_config(self, selected_models_by_endpoint: Dict[str, List[str
143167
144168 opencode_config ["provider" ][provider_id ] = provider
145169
146- # Preserve existing MCP servers (if any)
147- config_file = Path .home () / ".config" / "opencode" / "opencode.json"
148- if config_file .exists ():
149- try :
150- existing = json .loads (config_file .read_text (encoding = "utf-8" ))
151- if isinstance (existing , dict ) and isinstance (existing .get ("mcp" ), dict ):
152- opencode_config ["mcp" ] = existing ["mcp" ]
153- except Exception :
154- pass
155-
156170 # Write the config
157171 config_file .parent .mkdir (parents = True , exist_ok = True )
158172 with open (config_file , "w" , encoding = "utf-8" ) as f :
0 commit comments