@@ -10,6 +10,7 @@ import type {
1010 LDLogger ,
1111 LDMessage ,
1212 LDTokenUsage ,
13+ StructuredResponse ,
1314} from '@launchdarkly/server-sdk-ai' ;
1415
1516/**
@@ -44,39 +45,102 @@ export class LangChainProvider extends AIProvider {
4445 * Invoke the LangChain model with an array of messages.
4546 */
4647 async invokeModel ( messages : LDMessage [ ] ) : Promise < ChatResponse > {
47- // Convert LDMessage[] to LangChain messages
48- const langchainMessages = LangChainProvider . convertMessagesToLangChain ( messages ) ;
49-
50- // Get the LangChain response
51- const response : AIMessage = await this . _llm . invoke ( langchainMessages ) ;
52-
53- // Generate metrics early (assumes success by default)
54- const metrics = LangChainProvider . getAIMetricsFromResponse ( response ) ;
55-
56- // Extract text content from the response
57- let content : string = '' ;
58- if ( typeof response . content === 'string' ) {
59- content = response . content ;
60- } else {
61- // Log warning for non-string content (likely multimodal)
62- this . logger ?. warn (
63- `Multimodal response not supported, expecting a string. Content type: ${ typeof response . content } , Content:` ,
64- JSON . stringify ( response . content , null , 2 ) ,
65- ) ;
66- // Update metrics to reflect content loss
67- metrics . success = false ;
48+ try {
49+ // Convert LDMessage[] to LangChain messages
50+ const langchainMessages = LangChainProvider . convertMessagesToLangChain ( messages ) ;
51+
52+ // Get the LangChain response
53+ const response : AIMessage = await this . _llm . invoke ( langchainMessages ) ;
54+
55+ // Generate metrics early (assumes success by default)
56+ const metrics = LangChainProvider . getAIMetricsFromResponse ( response ) ;
57+
58+ // Extract text content from the response
59+ let content : string = '' ;
60+ if ( typeof response . content === 'string' ) {
61+ content = response . content ;
62+ } else {
63+ // Log warning for non-string content (likely multimodal)
64+ this . logger ?. warn (
65+ `Multimodal response not supported, expecting a string. Content type: ${ typeof response . content } , Content:` ,
66+ JSON . stringify ( response . content , null , 2 ) ,
67+ ) ;
68+ // Update metrics to reflect content loss
69+ metrics . success = false ;
70+ }
71+
72+ // Create the assistant message
73+ const assistantMessage : LDMessage = {
74+ role : 'assistant' ,
75+ content,
76+ } ;
77+
78+ return {
79+ message : assistantMessage ,
80+ metrics,
81+ } ;
82+ } catch ( error ) {
83+ this . logger ?. warn ( 'LangChain model invocation failed:' , error ) ;
84+
85+ return {
86+ message : {
87+ role : 'assistant' ,
88+ content : '' ,
89+ } ,
90+ metrics : {
91+ success : false ,
92+ } ,
93+ } ;
6894 }
95+ }
6996
70- // Create the assistant message
71- const assistantMessage : LDMessage = {
72- role : 'assistant' ,
73- content,
74- } ;
97+ /**
98+ * Invoke the LangChain model with structured output support.
99+ */
100+ async invokeStructuredModel (
101+ messages : LDMessage [ ] ,
102+ responseStructure : Record < string , unknown > ,
103+ ) : Promise < StructuredResponse > {
104+ try {
105+ // Convert LDMessage[] to LangChain messages
106+ const langchainMessages = LangChainProvider . convertMessagesToLangChain ( messages ) ;
75107
76- return {
77- message : assistantMessage ,
78- metrics,
79- } ;
108+ // Get the LangChain response
109+ const response = await this . _llm
110+ . withStructuredOutput ( responseStructure )
111+ . invoke ( langchainMessages ) ;
112+
113+ // Using structured output doesn't support metrics
114+ const metrics = {
115+ success : true ,
116+ usage : {
117+ total : 0 ,
118+ input : 0 ,
119+ output : 0 ,
120+ } ,
121+ } ;
122+
123+ return {
124+ data : response ,
125+ rawResponse : JSON . stringify ( response ) ,
126+ metrics,
127+ } ;
128+ } catch ( error ) {
129+ this . logger ?. warn ( 'LangChain structured model invocation failed:' , error ) ;
130+
131+ return {
132+ data : { } ,
133+ rawResponse : '' ,
134+ metrics : {
135+ success : false ,
136+ usage : {
137+ total : 0 ,
138+ input : 0 ,
139+ output : 0 ,
140+ } ,
141+ } ,
142+ } ;
143+ }
80144 }
81145
82146 /**
@@ -191,8 +255,8 @@ export class LangChainProvider extends AIProvider {
191255
192256 // Use LangChain's universal initChatModel to support multiple providers
193257 return initChatModel ( modelName , {
194- modelProvider : LangChainProvider . mapProvider ( provider ) ,
195258 ...parameters ,
259+ modelProvider : LangChainProvider . mapProvider ( provider ) ,
196260 } ) ;
197261 }
198262}
0 commit comments