@@ -548,8 +548,11 @@ class APIServer {
548548 await new Promise ( resolve => setTimeout ( resolve , waitTimeout ) ) ;
549549 }
550550
551+ // Extract tracing metadata for Langfuse integration
552+ const tracingMetadata = requestBody . metadata || { } ;
553+
551554 // Create a dynamic request for this request
552- const request = this . createDynamicRequestNested ( requestBody . input , nestedModelConfig ) ;
555+ const request = this . createDynamicRequestNested ( requestBody . input , nestedModelConfig , tracingMetadata ) ;
553556
554557 // Execute the request on the new tab's DevTools client
555558 logger . info ( 'Executing request on new tab' , {
@@ -581,29 +584,35 @@ class APIServer {
581584 */
582585 processNestedModelConfig ( requestBody ) {
583586 const defaults = this . configDefaults ?. model || { } ;
587+ // Default LiteLLM endpoint from environment variable
588+ const defaultLiteLLMEndpoint = process . env . LITELLM_ENDPOINT ;
584589
585590 // If nested format is provided, use it directly with fallbacks
586591 if ( requestBody . model ) {
587- // Extract endpoint from each model tier, with fallback chain:
592+ // Helper to get endpoint with fallback chain:
588593 // 1. Try tier-specific endpoint (e.g., main_model.endpoint)
589594 // 2. Fall back to top-level endpoint (e.g., model.endpoint)
590- // 3. Fall back to undefined (will use env var later)
591- const mainEndpoint = requestBody . model . main_model ?. endpoint || requestBody . model . endpoint ;
592- const miniEndpoint = requestBody . model . mini_model ?. endpoint || requestBody . model . endpoint ;
593- const nanoEndpoint = requestBody . model . nano_model ?. endpoint || requestBody . model . endpoint ;
595+ // 3. Fall back to LITELLM_ENDPOINT env var (for litellm provider)
596+ const getEndpoint = ( tierConfig ) => {
597+ const explicitEndpoint = tierConfig ?. endpoint || requestBody . model . endpoint ;
598+ if ( explicitEndpoint ) return explicitEndpoint ;
599+ // Use env var default for litellm provider
600+ if ( tierConfig ?. provider === 'litellm' ) return defaultLiteLLMEndpoint ;
601+ return undefined ;
602+ } ;
594603
595604 return {
596605 main_model : {
597606 ...this . extractModelTierConfig ( 'main' , requestBody . model . main_model , defaults ) ,
598- endpoint : mainEndpoint
607+ endpoint : getEndpoint ( requestBody . model . main_model )
599608 } ,
600609 mini_model : {
601610 ...this . extractModelTierConfig ( 'mini' , requestBody . model . mini_model , defaults ) ,
602- endpoint : miniEndpoint
611+ endpoint : getEndpoint ( requestBody . model . mini_model )
603612 } ,
604613 nano_model : {
605614 ...this . extractModelTierConfig ( 'nano' , requestBody . model . nano_model , defaults ) ,
606- endpoint : nanoEndpoint
615+ endpoint : getEndpoint ( requestBody . model . nano_model )
607616 }
608617 } ;
609618 }
@@ -633,10 +642,15 @@ class APIServer {
633642
634643 // If it's an object with provider/model/api_key, extract those fields
635644 if ( typeof tierConfig === 'object' && tierConfig . provider ) {
645+ // Get API key with fallback for litellm provider
646+ let apiKey = tierConfig . api_key ;
647+ if ( ! apiKey && tierConfig . provider === 'litellm' ) {
648+ apiKey = process . env . LITELLM_API_KEY ;
649+ }
636650 return {
637651 provider : tierConfig . provider ,
638652 model : tierConfig . model ,
639- api_key : tierConfig . api_key
653+ api_key : apiKey
640654 // endpoint will be added by caller
641655 } ;
642656 }
@@ -750,9 +764,10 @@ class APIServer {
750764 * Create a dynamic evaluation object with nested model configuration
751765 * @param {string|Array<{role: string, content: string}> } input - Input message (string) or conversation array (OpenAI Responses API format)
752766 * @param {import('./types/model-config').ModelConfig } nestedModelConfig - Model configuration
767+ * @param {Object } tracingMetadata - Optional tracing metadata for Langfuse integration
753768 * @returns {import('./types/model-config').EvaluationRequest } Evaluation request object
754769 */
755- createDynamicRequestNested ( input , nestedModelConfig ) {
770+ createDynamicRequestNested ( input , nestedModelConfig , tracingMetadata = { } ) {
756771 const requestId = `api-req-${ Date . now ( ) } -${ Math . random ( ) . toString ( 36 ) . substring ( 2 , 9 ) } ` ;
757772
758773 // Determine input format and structure accordingly
@@ -792,7 +807,10 @@ class APIServer {
792807 tags : [ 'api' , 'dynamic' ] ,
793808 priority : 'high' ,
794809 source : 'api'
795- }
810+ } ,
811+ // Tracing metadata for Langfuse integration
812+ // Contains session_id, trace_id, eval_id, etc. from eval framework
813+ tracing : tracingMetadata
796814 } ;
797815 }
798816
0 commit comments