@@ -5,10 +5,10 @@ import type {
55import type { StructuredToolInterface , ToolInterface } from '@langchain/core/tools'
66import type { StreamEvent } from '@langchain/core/tracers/log_stream'
77import type { AgentFinish , AgentStep } from 'langchain/agents'
8+ import type { z } from 'zod'
89import type { MCPClient } from '../client.js'
910import type { BaseConnector } from '../connectors/base.js'
1011import type { MCPSession } from '../session.js'
11- import type { z } from 'zod'
1212import {
1313 AIMessage ,
1414 HumanMessage ,
@@ -305,7 +305,7 @@ export class MCPAgent {
305305 manageConnector ?: boolean ,
306306 externalHistory ?: BaseMessage [ ] ,
307307 ) : Promise < string >
308-
308+
309309 /**
310310 * Runs the agent with structured output and returns a promise for the typed result.
311311 */
@@ -316,7 +316,7 @@ export class MCPAgent {
316316 externalHistory ?: BaseMessage [ ] ,
317317 outputSchema ?: z . ZodSchema < T > ,
318318 ) : Promise < T >
319-
319+
320320 public async run < T > (
321321 query : string ,
322322 maxSteps ?: number ,
@@ -351,7 +351,7 @@ export class MCPAgent {
351351 const toolsUsedNames : string [ ] = [ ]
352352 let stepsTaken = 0
353353 let success = false
354-
354+
355355 // Schema-aware setup for structured output
356356 let structuredLlm : BaseLanguageModelInterface | null = null
357357 let schemaDescription = ''
@@ -360,7 +360,8 @@ export class MCPAgent {
360360 // Check if withStructuredOutput method exists
361361 if ( 'withStructuredOutput' in this . llm && typeof ( this . llm as any ) . withStructuredOutput === 'function' ) {
362362 structuredLlm = ( this . llm as any ) . withStructuredOutput ( outputSchema )
363- } else {
363+ }
364+ else {
364365 // Fallback: use the same LLM but we'll handle structure in our helper method
365366 structuredLlm = this . llm
366367 }
@@ -378,7 +379,8 @@ export class MCPAgent {
378379 }
379380 schemaDescription = fields . join ( '\n' )
380381 }
381- } catch ( e ) {
382+ }
383+ catch ( e ) {
382384 logger . warn ( `Could not extract schema details: ${ e } ` )
383385 schemaDescription = `Schema: ${ outputSchema . constructor . name } `
384386 }
@@ -461,27 +463,28 @@ export class MCPAgent {
461463 if ( ( nextStepOutput as AgentFinish ) . returnValues ) {
462464 logger . info ( `✅ Agent finished at step ${ stepNum + 1 } ` )
463465 result = ( nextStepOutput as AgentFinish ) . returnValues ?. output ?? 'No output generated'
464-
466+
465467 // If structured output is requested, attempt to create it
466468 if ( outputSchema && structuredLlm ) {
467469 try {
468470 logger . info ( '🔧 Attempting structured output...' )
469471 const structuredResult = await this . _attemptStructuredOutput < T > (
470- result ,
471- structuredLlm ,
472- outputSchema ,
473- schemaDescription
472+ result ,
473+ structuredLlm ,
474+ outputSchema ,
475+ schemaDescription ,
474476 )
475-
477+
476478 // Add the final response to conversation history if memory is enabled
477479 if ( this . memoryEnabled ) {
478480 this . addToHistory ( new AIMessage ( `Structured result: ${ JSON . stringify ( structuredResult ) } ` ) )
479481 }
480-
482+
481483 logger . info ( '✅ Structured output successful' )
482484 success = true
483485 return structuredResult as string | T
484- } catch ( e ) {
486+ }
487+ catch ( e ) {
485488 logger . warn ( `⚠️ Structured output failed: ${ e } ` )
486489 // Continue execution to gather missing information
487490 const missingInfoPrompt = `
@@ -495,17 +498,18 @@ export class MCPAgent {
495498
496499 Focus on finding the specific missing details.
497500 `
498-
501+
499502 // Add this as feedback and continue the loop
500503 inputs . input = missingInfoPrompt
501504 if ( this . memoryEnabled ) {
502505 this . addToHistory ( new HumanMessage ( missingInfoPrompt ) )
503506 }
504-
507+
505508 logger . info ( '🔄 Continuing execution to gather missing information...' )
506509 continue
507510 }
508- } else {
511+ }
512+ else {
509513 // Regular execution without structured output
510514 break
511515 }
@@ -568,21 +572,22 @@ export class MCPAgent {
568572 try {
569573 logger . info ( '🔧 Final attempt at structured output...' )
570574 const structuredResult = await this . _attemptStructuredOutput < T > (
571- result ,
572- structuredLlm ,
573- outputSchema ,
574- schemaDescription
575+ result ,
576+ structuredLlm ,
577+ outputSchema ,
578+ schemaDescription ,
575579 )
576-
580+
577581 // Add the final response to conversation history if memory is enabled
578582 if ( this . memoryEnabled ) {
579583 this . addToHistory ( new AIMessage ( `Structured result: ${ JSON . stringify ( structuredResult ) } ` ) )
580584 }
581-
585+
582586 logger . info ( '✅ Final structured output successful' )
583587 success = true
584588 return structuredResult as string | T
585- } catch ( e ) {
589+ }
590+ catch ( e ) {
586591 logger . error ( `❌ Final structured output attempt failed: ${ e } ` )
587592 throw new Error ( `Failed to generate structured output after ${ steps } steps: ${ e } ` )
588593 }
@@ -595,7 +600,7 @@ export class MCPAgent {
595600
596601 logger . info ( '🎉 Agent execution complete' )
597602 success = true
598-
603+
599604 // Return regular result
600605 return result as string | T
601606 }
@@ -832,7 +837,7 @@ export class MCPAgent {
832837 rawResult : string ,
833838 structuredLlm : BaseLanguageModelInterface ,
834839 outputSchema : z . ZodSchema < T > ,
835- schemaDescription : string
840+ schemaDescription : string ,
836841 ) : Promise < T > {
837842 const formatPrompt = `
838843 Please format the following information according to the specified schema.
@@ -854,7 +859,7 @@ export class MCPAgent {
854859 try {
855860 // Use Zod to validate the structured result
856861 const validatedResult = outputSchema . parse ( structuredResult )
857-
862+
858863 // Additional validation for required fields
859864 const schemaType = outputSchema as any
860865 if ( schemaType . _def && schemaType . _def . shape ) {
@@ -864,17 +869,18 @@ export class MCPAgent {
864869 const isNullable = field . isNullable ?.( ) ?? field . _def ?. typeName === 'ZodNullable'
865870 if ( ! isOptional && ! isNullable ) {
866871 const value = ( validatedResult as any ) [ fieldName ]
867- if ( value === null || value === undefined ||
868- ( typeof value === 'string' && ! value . trim ( ) ) ||
869- ( Array . isArray ( value ) && value . length === 0 ) ) {
872+ if ( value === null || value === undefined
873+ || ( typeof value === 'string' && ! value . trim ( ) )
874+ || ( Array . isArray ( value ) && value . length === 0 ) ) {
870875 throw new Error ( `Required field '${ fieldName } ' is missing or empty` )
871876 }
872877 }
873878 }
874879 }
875-
880+
876881 return validatedResult
877- } catch ( e ) {
882+ }
883+ catch ( e ) {
878884 logger . debug ( `Validation details: ${ e } ` )
879885 throw e // Re-raise to trigger retry logic
880886 }
@@ -900,7 +906,7 @@ export class MCPAgent {
900906 }
901907
902908 const schemaDescription = schemaFields . join ( '\n' )
903-
909+
904910 // Enhance the query with schema awareness
905911 const enhancedQuery = `
906912 ${ query }
@@ -912,9 +918,10 @@ export class MCPAgent {
912918 Make sure you gather ALL the required information during your task execution.
913919 If any required information is missing, continue working to find it.
914920 `
915-
921+
916922 return enhancedQuery
917- } catch ( e ) {
923+ }
924+ catch ( e ) {
918925 logger . warn ( `Could not extract schema details: ${ e } ` )
919926 return query
920927 }
0 commit comments