@@ -103,69 +103,84 @@ export default class LangChainManager extends AIManager {
103103 }
104104
105105 private createModel ( providerId : string , config : Record < string , any > ) : BaseChatModel {
106+ const sanitize = ( value : any ) =>
107+ typeof value === 'string' ? value . trim ( ) : value ;
108+ const sanitizedConfig = {
109+ ...config ,
110+ apiKey : sanitize ( config . apiKey ) ,
111+ endpoint : sanitize ( config . endpoint ) ,
112+ baseUrl : sanitize ( config . baseUrl ) ,
113+ deploymentName : sanitize ( config . deploymentName ) ,
114+ model : sanitize ( config . model ) ,
115+ } ;
116+
106117 try {
107118 switch ( providerId ) {
108119 case 'openai' :
109- if ( ! config . apiKey ) {
120+ if ( ! sanitizedConfig . apiKey ) {
110121 throw new Error ( 'API key is required for OpenAI' ) ;
111122 }
112123 return new ChatOpenAI ( {
113- apiKey : config . apiKey ,
114- modelName : config . model ,
124+ apiKey : sanitizedConfig . apiKey ,
125+ modelName : sanitizedConfig . model ,
115126 dangerouslyAllowBrowser : true ,
116127 verbose : true ,
117128 } ) ;
118129 case 'azure' :
119- if ( ! config . apiKey || ! config . endpoint || ! config . deploymentName ) {
130+ if (
131+ ! sanitizedConfig . apiKey ||
132+ ! sanitizedConfig . endpoint ||
133+ ! sanitizedConfig . deploymentName
134+ ) {
120135 throw new Error ( 'Incomplete Azure OpenAI configuration' ) ;
121136 }
122137 return new AzureChatOpenAI ( {
123- azureOpenAIEndpoint : config . endpoint . replace ( / \/ + \ $/ , '' ) ,
124- azureOpenAIApiKey : config . apiKey ,
125- azureOpenAIApiDeploymentName : config . deploymentName ,
138+ azureOpenAIEndpoint : sanitizedConfig . endpoint . replace ( / \/ + $ / , '' ) ,
139+ azureOpenAIApiKey : sanitizedConfig . apiKey ,
140+ azureOpenAIApiDeploymentName : sanitizedConfig . deploymentName ,
126141 azureOpenAIApiVersion : '2024-12-01-preview' ,
127- modelName : config . model ,
142+ modelName : sanitizedConfig . model ,
128143 dangerouslyAllowBrowser : true ,
129144 verbose : true ,
130145 } ) ;
131146 case 'anthropic' :
132- if ( ! config . apiKey ) {
147+ if ( ! sanitizedConfig . apiKey ) {
133148 throw new Error ( 'API key is required for Anthropic' ) ;
134149 }
135150 return new ChatAnthropic ( {
136- apiKey : config . apiKey ,
137- modelName : config . model ,
151+ apiKey : sanitizedConfig . apiKey ,
152+ modelName : sanitizedConfig . model ,
138153 dangerouslyAllowBrowser : true ,
139154 verbose : true ,
140155 } ) ;
141156 case 'mistral' :
142- if ( ! config . apiKey ) {
157+ if ( ! sanitizedConfig . apiKey ) {
143158 throw new Error ( 'API key is required for Mistral AI' ) ;
144159 }
145160 return new ChatMistralAI ( {
146- apiKey : config . apiKey ,
147- modelName : config . model ,
161+ apiKey : sanitizedConfig . apiKey ,
162+ modelName : sanitizedConfig . model ,
148163 dangerouslyAllowBrowser : true ,
149164 verbose : true ,
150165 } ) ;
151166 case 'gemini' : {
152- if ( ! config . apiKey ) {
167+ if ( ! sanitizedConfig . apiKey ) {
153168 throw new Error ( 'API key is required for Google Gemini' ) ;
154169 }
155170 return new ChatGoogleGenerativeAI ( {
156- apiKey : config . apiKey ,
157- model : config . model ,
171+ apiKey : sanitizedConfig . apiKey ,
172+ model : sanitizedConfig . model ,
158173 dangerouslyAllowBrowser : true ,
159174 verbose : true ,
160175 } ) ;
161176 }
162177 case 'local' :
163- if ( ! config . baseUrl ) {
178+ if ( ! sanitizedConfig . baseUrl ) {
164179 throw new Error ( 'Base URL is required for local models' ) ;
165180 }
166181 return new ChatOllama ( {
167- baseUrl : config . baseUrl ,
168- model : config . model ,
182+ baseUrl : sanitizedConfig . baseUrl ,
183+ model : sanitizedConfig . model ,
169184 dangerouslyAllowBrowser : true ,
170185 verbose : true ,
171186 } ) ;
0 commit comments