@@ -11,6 +11,7 @@ import {
1111 missingLlmApiKey ,
1212 missingLlmConfig ,
1313 PQA_LLM_API_KEY ,
14+ PQA_LLM_BASE_URL ,
1415 resolveAgentGuardConfig ,
1516 resolveAgentParallel ,
1617 resolveBrowserHeaded ,
@@ -186,6 +187,38 @@ describe("loadConfig", () => {
186187 }
187188 } ) ;
188189
190+ it ( "applies PQA_LLM_BASE_URL when llm.baseURL is unset" , async ( ) => {
191+ const cwd = mkdtempSync ( path . join ( tmpdir ( ) , "pqa-config-" ) ) ;
192+ const prevBaseUrl = process . env [ PQA_LLM_BASE_URL ] ;
193+ process . env [ PQA_LLM_BASE_URL ] = "http://127.0.0.1:8080/v1" ;
194+ try {
195+ const config = await loadConfig ( undefined , cwd ) ;
196+ assert . equal ( config . llm . baseURL , "http://127.0.0.1:8080/v1" ) ;
197+ } finally {
198+ if ( prevBaseUrl === undefined ) delete process . env [ PQA_LLM_BASE_URL ] ;
199+ else process . env [ PQA_LLM_BASE_URL ] = prevBaseUrl ;
200+ }
201+ } ) ;
202+
203+ it ( "prefers llm.baseURL from pqa.config.json over env var" , async ( ) => {
204+ const cwd = mkdtempSync ( path . join ( tmpdir ( ) , "pqa-config-" ) ) ;
205+ writeFileSync (
206+ path . join ( cwd , "pqa.config.json" ) ,
207+ JSON . stringify ( {
208+ llm : { baseURL : "http://custom.local:1234/v1" } ,
209+ } ) ,
210+ ) ;
211+ const prevBaseUrl = process . env [ PQA_LLM_BASE_URL ] ;
212+ process . env [ PQA_LLM_BASE_URL ] = "http://127.0.0.1:8080/v1" ;
213+ try {
214+ const config = await loadConfig ( undefined , cwd ) ;
215+ assert . equal ( config . llm . baseURL , "http://custom.local:1234/v1" ) ;
216+ } finally {
217+ if ( prevBaseUrl === undefined ) delete process . env [ PQA_LLM_BASE_URL ] ;
218+ else process . env [ PQA_LLM_BASE_URL ] = prevBaseUrl ;
219+ }
220+ } ) ;
221+
189222 it ( "deep-merges browser.lightpanda overrides" , async ( ) => {
190223 const cwd = mkdtempSync ( path . join ( tmpdir ( ) , "pqa-config-" ) ) ;
191224 writeFileSync (
@@ -222,6 +255,14 @@ describe("missingLlmApiKey", () => {
222255 } ;
223256 assert . equal ( missingLlmApiKey ( config ) , undefined ) ;
224257 } ) ;
258+
259+ it ( "does not require an API key for lmstudio" , ( ) => {
260+ const config = {
261+ ...minimalConfig ( "chrome" ) ,
262+ llm : { provider : "lmstudio" as const , model : "qwen/qwen3-4b-2507" } ,
263+ } ;
264+ assert . equal ( missingLlmApiKey ( config ) , undefined ) ;
265+ } ) ;
225266} ) ;
226267
227268describe ( "resolveSensitiveEnvVars" , ( ) => {
0 commit comments