@@ -32,9 +32,10 @@ import { ServerManager } from '../managers/server_manager.js'
3232import { extractModelInfo , Telemetry } from '../telemetry/index.js'
3333import { createSystemMessage } from './prompts/system_prompt_builder.js'
3434import { DEFAULT_SYSTEM_PROMPT_TEMPLATE , SERVER_MANAGER_SYSTEM_PROMPT_TEMPLATE } from './prompts/templates.js'
35+ import { RemoteAgent } from './remote.js'
3536
3637export class MCPAgent {
37- private llm : BaseLanguageModelInterface
38+ private llm ? : BaseLanguageModelInterface
3839 private client ?: MCPClient
3940 private connectors : BaseConnector [ ]
4041 private maxSteps : number
@@ -60,8 +61,12 @@ export class MCPAgent {
6061 private modelProvider : string
6162 private modelName : string
6263
64+ // Remote agent support
65+ private isRemote = false
66+ private remoteAgent : RemoteAgent | null = null
67+
6368 constructor ( options : {
64- llm : BaseLanguageModelInterface
69+ llm ? : BaseLanguageModelInterface
6570 client ?: MCPClient
6671 connectors ?: BaseConnector [ ]
6772 maxSteps ?: number
@@ -76,7 +81,40 @@ export class MCPAgent {
7681 verbose ?: boolean
7782 adapter ?: LangChainAdapter
7883 serverManagerFactory ?: ( client : MCPClient ) => ServerManager
84+ // Remote agent parameters
85+ agentId ?: string
86+ apiKey ?: string
87+ baseUrl ?: string
7988 } ) {
89+ // Handle remote execution
90+ if ( options . agentId ) {
91+ this . isRemote = true
92+ this . remoteAgent = new RemoteAgent ( {
93+ agentId : options . agentId ,
94+ apiKey : options . apiKey ,
95+ baseUrl : options . baseUrl ,
96+ } )
97+ // Set default values for remote agent
98+ this . maxSteps = options . maxSteps ?? 5
99+ this . memoryEnabled = options . memoryEnabled ?? true
100+ this . autoInitialize = options . autoInitialize ?? false
101+ this . verbose = options . verbose ?? false
102+ this . connectors = [ ]
103+ this . disallowedTools = [ ]
104+ this . additionalTools = [ ]
105+ this . useServerManager = false
106+ this . adapter = new LangChainAdapter ( )
107+ this . telemetry = Telemetry . getInstance ( )
108+ this . modelProvider = 'remote'
109+ this . modelName = 'remote-agent'
110+ return
111+ }
112+
113+ // Validate requirements for local execution
114+ if ( ! options . llm ) {
115+ throw new Error ( 'llm is required for local execution. For remote execution, provide agentId instead.' )
116+ }
117+
80118 this . llm = options . llm
81119
82120 this . client = options . client
@@ -111,9 +149,15 @@ export class MCPAgent {
111149 // Initialize telemetry
112150 this . telemetry = Telemetry . getInstance ( )
113151 // Track model info for telemetry
114- const [ provider , name ] = extractModelInfo ( this . llm as any )
115- this . modelProvider = provider
116- this . modelName = name
152+ if ( this . llm ) {
153+ const [ provider , name ] = extractModelInfo ( this . llm as any )
154+ this . modelProvider = provider
155+ this . modelName = name
156+ }
157+ else {
158+ this . modelProvider = 'unknown'
159+ this . modelName = 'unknown'
160+ }
117161
118162 // Make getters configurable for test mocking
119163 Object . defineProperty ( this , 'agentExecutor' , {
@@ -131,6 +175,12 @@ export class MCPAgent {
131175 }
132176
133177 public async initialize ( ) : Promise < void > {
178+ // Skip initialization for remote agents
179+ if ( this . isRemote ) {
180+ this . _initialized = true
181+ return
182+ }
183+
134184 logger . info ( '🚀 Initializing MCP agent and connecting to services...' )
135185
136186 // If using server manager, initialize it
@@ -219,6 +269,10 @@ export class MCPAgent {
219269 }
220270
221271 private createAgent ( ) : AgentExecutor {
272+ if ( ! this . llm ) {
273+ throw new Error ( 'LLM is required to create agent' )
274+ }
275+
222276 const systemContent = this . systemMessage ?. content ?? 'You are a helpful assistant.'
223277
224278 const prompt = ChatPromptTemplate . fromMessages ( [
@@ -327,6 +381,11 @@ export class MCPAgent {
327381 externalHistory ?: BaseMessage [ ] ,
328382 outputSchema ?: ZodSchema < T > ,
329383 ) : Promise < string | T > {
384+ // Delegate to remote agent if in remote mode
385+ if ( this . isRemote && this . remoteAgent ) {
386+ return this . remoteAgent . run ( query , maxSteps , manageConnector , externalHistory , outputSchema )
387+ }
388+
330389 const generator = this . stream < T > (
331390 query ,
332391 maxSteps ,
@@ -348,6 +407,12 @@ export class MCPAgent {
348407 externalHistory ?: BaseMessage [ ] ,
349408 outputSchema ?: ZodSchema < T > ,
350409 ) : AsyncGenerator < AgentStep , string | T , void > {
410+ // Delegate to remote agent if in remote mode
411+ if ( this . isRemote && this . remoteAgent ) {
412+ const result = await this . remoteAgent . run ( query , maxSteps , manageConnector , externalHistory , outputSchema )
413+ return result as string | T
414+ }
415+
351416 let result = ''
352417 let initializedHere = false
353418 const startTime = Date . now ( )
@@ -362,13 +427,16 @@ export class MCPAgent {
362427 query = this . _enhanceQueryWithSchema ( query , outputSchema )
363428 logger . debug ( `🔄 Structured output requested, schema: ${ JSON . stringify ( zodToJsonSchema ( outputSchema ) , null , 2 ) } ` )
364429 // Check if withStructuredOutput method exists
365- if ( 'withStructuredOutput' in this . llm && typeof ( this . llm as any ) . withStructuredOutput === 'function' ) {
430+ if ( this . llm && 'withStructuredOutput' in this . llm && typeof ( this . llm as any ) . withStructuredOutput === 'function' ) {
366431 structuredLlm = ( this . llm as any ) . withStructuredOutput ( outputSchema )
367432 }
368- else {
433+ else if ( this . llm ) {
369434 // Fallback: use the same LLM but we'll handle structure in our helper method
370435 structuredLlm = this . llm
371436 }
437+ else {
438+ throw new Error ( 'LLM is required for structured output' )
439+ }
372440 schemaDescription = JSON . stringify ( zodToJsonSchema ( outputSchema ) , null , 2 )
373441 }
374442
@@ -615,6 +683,12 @@ export class MCPAgent {
615683 }
616684
617685 public async close ( ) : Promise < void > {
686+ // Delegate to remote agent if in remote mode
687+ if ( this . isRemote && this . remoteAgent ) {
688+ await this . remoteAgent . close ( )
689+ return
690+ }
691+
618692 logger . info ( '🔌 Closing MCPAgent resources…' )
619693 try {
620694 this . _agentExecutor = null
0 commit comments