mcp-use 0.1.17 → 0.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -0
- package/dist/examples/observability.d.ts +6 -0
- package/dist/examples/observability.d.ts.map +1 -0
- package/dist/examples/observability.js +50 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/src/agents/mcp_agent.d.ts +40 -0
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/agents/mcp_agent.js +174 -1
- package/dist/src/observability/langfuse.d.ts +2 -0
- package/dist/src/observability/langfuse.d.ts.map +1 -1
- package/dist/src/observability/langfuse.js +99 -11
- package/dist/src/observability/manager.d.ts +15 -0
- package/dist/src/observability/manager.d.ts.map +1 -1
- package/dist/src/observability/manager.js +36 -4
- package/dist/tests/stream_events.test.js +2 -1
- package/package.json +11 -9
package/README.md
CHANGED
@@ -44,6 +44,7 @@
|
|
44
44
|
| 🧩 **Multi-Server Support** | Use multiple MCP servers in one agent. |
|
45
45
|
| 🛡️ **Tool Restrictions** | Restrict unsafe tools like filesystem or network. |
|
46
46
|
| 🔧 **Custom Agents** | Build your own agents with LangChain.js adapter or implement new adapters. |
|
47
|
+
| 📊 **Observability** | Built-in support for Langfuse with dynamic metadata and tag handling. |
|
47
48
|
|
48
49
|
---
|
49
50
|
|
@@ -295,6 +296,77 @@ export function Chat() {
|
|
295
296
|
|
296
297
|
---
|
297
298
|
|
299
|
+
## 📊 Observability & Monitoring
|
300
|
+
|
301
|
+
mcp-use-ts provides built-in observability support through the `ObservabilityManager`, with integration for Langfuse and other observability platforms.
|
302
|
+
|
303
|
+
#### To enable observability simply configure Environment Variables
|
304
|
+
|
305
|
+
```ini
|
306
|
+
# .env
|
307
|
+
LANGFUSE_PUBLIC_KEY=pk-lf-your-public-key
|
308
|
+
LANGFUSE_SECRET_KEY=sk-lf-your-secret-key
|
309
|
+
LANGFUSE_HOST=https://cloud.langfuse.com # or your self-hosted instance
|
310
|
+
```
|
311
|
+
|
312
|
+
### Advanced Observability Features
|
313
|
+
|
314
|
+
#### Dynamic Metadata and Tags
|
315
|
+
|
316
|
+
```ts
|
317
|
+
// Set custom metadata for the current execution
|
318
|
+
agent.setMetadata({
|
319
|
+
userId: 'user123',
|
320
|
+
sessionId: 'session456',
|
321
|
+
environment: 'production'
|
322
|
+
})
|
323
|
+
|
324
|
+
// Set tags for better organization
|
325
|
+
agent.setTags(['production', 'user-query', 'tool-discovery'])
|
326
|
+
|
327
|
+
// Run query with metadata and tags
|
328
|
+
const result = await agent.run('Search for restaurants in Tokyo')
|
329
|
+
```
|
330
|
+
|
331
|
+
#### Monitoring Agent Performance
|
332
|
+
|
333
|
+
```ts
|
334
|
+
// Stream events for detailed monitoring
|
335
|
+
const eventStream = agent.streamEvents('Complex multi-step query')
|
336
|
+
|
337
|
+
for await (const event of eventStream) {
|
338
|
+
// Monitor different event types
|
339
|
+
switch (event.event) {
|
340
|
+
case 'on_llm_start':
|
341
|
+
console.log('LLM call started:', event.data)
|
342
|
+
break
|
343
|
+
case 'on_tool_start':
|
344
|
+
console.log('Tool execution started:', event.name, event.data)
|
345
|
+
break
|
346
|
+
case 'on_tool_end':
|
347
|
+
console.log('Tool execution completed:', event.name, event.data)
|
348
|
+
break
|
349
|
+
case 'on_chain_end':
|
350
|
+
console.log('Agent execution completed:', event.data)
|
351
|
+
break
|
352
|
+
}
|
353
|
+
}
|
354
|
+
```
|
355
|
+
|
356
|
+
### Disabling Observability
|
357
|
+
|
358
|
+
To disable observability, either remove langfuse env variables or
|
359
|
+
|
360
|
+
```ts
|
361
|
+
const agent = new MCPAgent({
|
362
|
+
llm,
|
363
|
+
client,
|
364
|
+
observe: false
|
365
|
+
})
|
366
|
+
```
|
367
|
+
|
368
|
+
---
|
369
|
+
|
298
370
|
## 📂 Configuration File
|
299
371
|
|
300
372
|
You can store servers in a JSON file:
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../examples/observability.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
/**
|
2
|
+
* This example shows how to test the different functionalities of MCPs using the MCP server from
|
3
|
+
* anthropic.
|
4
|
+
*/
|
5
|
+
import { ChatOpenAI } from '@langchain/openai';
|
6
|
+
import { config } from 'dotenv';
|
7
|
+
import { Logger, MCPAgent, MCPClient } from '../index.js';
|
8
|
+
// Load environment variables from .env file
|
9
|
+
config();
|
10
|
+
// Enable debug logging to see observability messages
|
11
|
+
Logger.setDebug(true);
|
12
|
+
const everythingServer = {
|
13
|
+
mcpServers: { everything: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-everything'] } },
|
14
|
+
};
|
15
|
+
async function main() {
|
16
|
+
console.log('🚀 Starting MCP Observability example with Langfuse tracing...');
|
17
|
+
console.log('📊 Environment variables:');
|
18
|
+
console.log(` LANGFUSE_PUBLIC_KEY: ${process.env.LANGFUSE_PUBLIC_KEY ? '✅ Set' : '❌ Missing'}`);
|
19
|
+
console.log(` LANGFUSE_SECRET_KEY: ${process.env.LANGFUSE_SECRET_KEY ? '✅ Set' : '❌ Missing'}`);
|
20
|
+
console.log(` LANGFUSE_HOST: ${process.env.LANGFUSE_HOST || 'Not set'}`);
|
21
|
+
console.log(` MCP_USE_LANGFUSE: ${process.env.MCP_USE_LANGFUSE || 'Not set'}`);
|
22
|
+
const client = new MCPClient(everythingServer);
|
23
|
+
const llm = new ChatOpenAI({ model: 'gpt-4o', temperature: 0 });
|
24
|
+
const agent = new MCPAgent({
|
25
|
+
llm,
|
26
|
+
client,
|
27
|
+
maxSteps: 30,
|
28
|
+
});
|
29
|
+
// console.log('🔧 Initializing agent...')
|
30
|
+
// await agent.initialize()
|
31
|
+
// Set additional metadata for testing (Optional)
|
32
|
+
agent.setMetadata({
|
33
|
+
agent_id: 'test-agent-123',
|
34
|
+
test_run: true,
|
35
|
+
example: 'mcp_observability',
|
36
|
+
});
|
37
|
+
agent.setTags(['test-tag-1', 'test-tag-2']);
|
38
|
+
console.log('💬 Running agent query...');
|
39
|
+
const result = await agent.run(`Hello, you are a tester can you please answer the follwing questions:
|
40
|
+
- Which resources do you have access to?
|
41
|
+
- Which prompts do you have access to?
|
42
|
+
- Which tools do you have access to?`, 30);
|
43
|
+
console.log(`\n✅ Result: ${result}`);
|
44
|
+
// console.log('🧹 Closing agent...')
|
45
|
+
// await agent.close()
|
46
|
+
// console.log('🎉 Example completed! Check your Langfuse dashboard for traces.')
|
47
|
+
}
|
48
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
49
|
+
main().catch(console.error);
|
50
|
+
}
|
package/dist/index.d.ts
CHANGED
@@ -12,6 +12,7 @@ export { BaseAdapter, LangChainAdapter } from './src/adapters/index.js';
|
|
12
12
|
export * from './src/agents/utils/index.js';
|
13
13
|
export { ServerManager } from './src/managers/server_manager.js';
|
14
14
|
export * from './src/managers/tools/index.js';
|
15
|
+
export { type ObservabilityConfig, ObservabilityManager } from './src/observability/index.js';
|
15
16
|
export { setTelemetrySource, Telemetry } from './src/telemetry/index.js';
|
16
17
|
export { AIMessage, BaseMessage, HumanMessage, SystemMessage, ToolMessage } from '@langchain/core/messages';
|
17
18
|
export type { StreamEvent } from '@langchain/core/tracers/log_stream';
|
package/dist/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAElE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAEvE,cAAc,6BAA6B,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAEhE,cAAc,+BAA+B,CAAA;AAG7C,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGxE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAG3G,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAErE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAA"}
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAElE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAEvE,cAAc,6BAA6B,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAEhE,cAAc,+BAA+B,CAAA;AAG7C,OAAO,EAAE,KAAK,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAG7F,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGxE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAG3G,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AAErE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAA"}
|
package/dist/index.js
CHANGED
@@ -13,6 +13,8 @@ export { BaseAdapter, LangChainAdapter } from './src/adapters/index.js';
|
|
13
13
|
export * from './src/agents/utils/index.js';
|
14
14
|
export { ServerManager } from './src/managers/server_manager.js';
|
15
15
|
export * from './src/managers/tools/index.js';
|
16
|
+
// Export observability utilities
|
17
|
+
export { ObservabilityManager } from './src/observability/index.js';
|
16
18
|
// Export telemetry utilities
|
17
19
|
export { setTelemetrySource, Telemetry } from './src/telemetry/index.js';
|
18
20
|
// Re-export message classes to ensure a single constructor instance is shared by consumers
|
@@ -21,6 +21,7 @@ export declare class MCPAgent {
|
|
21
21
|
private additionalTools;
|
22
22
|
private useServerManager;
|
23
23
|
private verbose;
|
24
|
+
private observe;
|
24
25
|
private systemPrompt?;
|
25
26
|
private systemPromptTemplateOverride?;
|
26
27
|
private additionalInstructions?;
|
@@ -37,6 +38,8 @@ export declare class MCPAgent {
|
|
37
38
|
private modelName;
|
38
39
|
private observabilityManager;
|
39
40
|
private callbacks;
|
41
|
+
private metadata;
|
42
|
+
private tags;
|
40
43
|
private isRemote;
|
41
44
|
private remoteAgent;
|
42
45
|
constructor(options: {
|
@@ -53,6 +56,7 @@ export declare class MCPAgent {
|
|
53
56
|
additionalTools?: StructuredToolInterface[];
|
54
57
|
useServerManager?: boolean;
|
55
58
|
verbose?: boolean;
|
59
|
+
observe?: boolean;
|
56
60
|
adapter?: LangChainAdapter;
|
57
61
|
serverManagerFactory?: (client: MCPClient) => ServerManager;
|
58
62
|
callbacks?: BaseCallbackHandler[];
|
@@ -70,6 +74,42 @@ export declare class MCPAgent {
|
|
70
74
|
setSystemMessage(message: string): void;
|
71
75
|
setDisallowedTools(disallowedTools: string[]): void;
|
72
76
|
getDisallowedTools(): string[];
|
77
|
+
/**
|
78
|
+
* Set metadata for observability traces
|
79
|
+
* @param newMetadata - Key-value pairs to add to metadata. Keys should be strings, values should be serializable.
|
80
|
+
*/
|
81
|
+
setMetadata(newMetadata: Record<string, any>): void;
|
82
|
+
/**
|
83
|
+
* Get current metadata
|
84
|
+
* @returns A copy of the current metadata object
|
85
|
+
*/
|
86
|
+
getMetadata(): Record<string, any>;
|
87
|
+
/**
|
88
|
+
* Set tags for observability traces
|
89
|
+
* @param newTags - Array of tag strings to add. Duplicates will be automatically removed.
|
90
|
+
*/
|
91
|
+
setTags(newTags: string[]): void;
|
92
|
+
/**
|
93
|
+
* Get current tags
|
94
|
+
* @returns A copy of the current tags array
|
95
|
+
*/
|
96
|
+
getTags(): string[];
|
97
|
+
/**
|
98
|
+
* Sanitize metadata to ensure compatibility with observability platforms
|
99
|
+
* @param metadata - Raw metadata object
|
100
|
+
* @returns Sanitized metadata object
|
101
|
+
*/
|
102
|
+
private sanitizeMetadata;
|
103
|
+
/**
|
104
|
+
* Sanitize tags to ensure compatibility with observability platforms
|
105
|
+
* @param tags - Array of tag strings
|
106
|
+
* @returns Array of sanitized tag strings
|
107
|
+
*/
|
108
|
+
private sanitizeTags;
|
109
|
+
/**
|
110
|
+
* Get MCP server information for observability metadata
|
111
|
+
*/
|
112
|
+
private getMCPServerInfo;
|
73
113
|
private _consumeAndReturn;
|
74
114
|
/**
|
75
115
|
* Runs the agent and returns a promise for the final result.
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAEzE,OAAO,KAAK,EAAE,0BAA0B,EAAqB,MAAM,sCAAsC,CAAA;AAEzG,OAAO,KAAK,EACV,WAAW,EACZ,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAK,EAAE,uBAAuB,EAAiB,MAAM,uBAAuB,CAAA;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAA;AACrE,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAG1D,OAAO,EAGL,aAAa,EAEd,MAAM,0BAA0B,CAAA;AAQjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAA;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAA;AAO7D,qBAAa,QAAQ;IACnB,OAAO,CAAC,GAAG,CAAC,CAA4B;IACxC,OAAO,CAAC,MAAM,CAAC,CAAW;IAC1B,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,4BAA4B,CAAC,CAAe;IACpD,OAAO,CAAC,sBAAsB,CAAC,CAAe;IAE9C,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,mBAAmB,CAAoB;IAC/C,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAQ;IAGzB,OAAO,CAAC,oBAAoB,CAAsB;IAClD,OAAO,CAAC,SAAS,CAA4B;
|
1
|
+
{"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"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"}
|
@@ -23,6 +23,7 @@ export class MCPAgent {
|
|
23
23
|
additionalTools;
|
24
24
|
useServerManager;
|
25
25
|
verbose;
|
26
|
+
observe;
|
26
27
|
systemPrompt;
|
27
28
|
systemPromptTemplateOverride;
|
28
29
|
additionalInstructions;
|
@@ -40,6 +41,8 @@ export class MCPAgent {
|
|
40
41
|
// Observability support
|
41
42
|
observabilityManager;
|
42
43
|
callbacks = [];
|
44
|
+
metadata = {};
|
45
|
+
tags = [];
|
43
46
|
// Remote agent support
|
44
47
|
isRemote = false;
|
45
48
|
remoteAgent = null;
|
@@ -57,6 +60,7 @@ export class MCPAgent {
|
|
57
60
|
this.memoryEnabled = options.memoryEnabled ?? true;
|
58
61
|
this.autoInitialize = options.autoInitialize ?? false;
|
59
62
|
this.verbose = options.verbose ?? false;
|
63
|
+
this.observe = options.observe ?? true;
|
60
64
|
this.connectors = [];
|
61
65
|
this.disallowedTools = [];
|
62
66
|
this.additionalTools = [];
|
@@ -65,7 +69,10 @@ export class MCPAgent {
|
|
65
69
|
this.telemetry = Telemetry.getInstance();
|
66
70
|
this.modelProvider = 'remote';
|
67
71
|
this.modelName = 'remote-agent';
|
68
|
-
this.observabilityManager = new ObservabilityManager({
|
72
|
+
this.observabilityManager = new ObservabilityManager({
|
73
|
+
customCallbacks: options.callbacks,
|
74
|
+
agentId: options.agentId,
|
75
|
+
});
|
69
76
|
this.callbacks = [];
|
70
77
|
return;
|
71
78
|
}
|
@@ -86,6 +93,7 @@ export class MCPAgent {
|
|
86
93
|
this.additionalTools = options.additionalTools ?? [];
|
87
94
|
this.useServerManager = options.useServerManager ?? false;
|
88
95
|
this.verbose = options.verbose ?? false;
|
96
|
+
this.observe = options.observe ?? true;
|
89
97
|
if (!this.client && this.connectors.length === 0) {
|
90
98
|
throw new Error('Either \'client\' or at least one \'connector\' must be provided.');
|
91
99
|
}
|
@@ -116,6 +124,10 @@ export class MCPAgent {
|
|
116
124
|
this.observabilityManager = new ObservabilityManager({
|
117
125
|
customCallbacks: options.callbacks,
|
118
126
|
verbose: this.verbose,
|
127
|
+
observe: this.observe,
|
128
|
+
agentId: options.agentId,
|
129
|
+
metadataProvider: () => this.getMetadata(),
|
130
|
+
tagsProvider: () => this.getTags(),
|
119
131
|
});
|
120
132
|
// Make getters configurable for test mocking
|
121
133
|
Object.defineProperty(this, 'agentExecutor', {
|
@@ -193,6 +205,12 @@ export class MCPAgent {
|
|
193
205
|
// Create the agent executor and mark initialized
|
194
206
|
this._agentExecutor = this.createAgent();
|
195
207
|
this._initialized = true;
|
208
|
+
// Add MCP server information to observability metadata
|
209
|
+
const mcpServerInfo = this.getMCPServerInfo();
|
210
|
+
if (Object.keys(mcpServerInfo).length > 0) {
|
211
|
+
this.setMetadata(mcpServerInfo);
|
212
|
+
logger.debug(`MCP server info added to metadata: ${JSON.stringify(mcpServerInfo)}`);
|
213
|
+
}
|
196
214
|
logger.info('✨ Agent initialization complete');
|
197
215
|
}
|
198
216
|
async createSystemMessageFromTools(tools) {
|
@@ -265,6 +283,161 @@ export class MCPAgent {
|
|
265
283
|
getDisallowedTools() {
|
266
284
|
return this.disallowedTools;
|
267
285
|
}
|
286
|
+
/**
|
287
|
+
* Set metadata for observability traces
|
288
|
+
* @param newMetadata - Key-value pairs to add to metadata. Keys should be strings, values should be serializable.
|
289
|
+
*/
|
290
|
+
setMetadata(newMetadata) {
|
291
|
+
// Validate and sanitize metadata
|
292
|
+
const sanitizedMetadata = this.sanitizeMetadata(newMetadata);
|
293
|
+
// Merge with existing metadata instead of replacing it
|
294
|
+
this.metadata = { ...this.metadata, ...sanitizedMetadata };
|
295
|
+
logger.debug(`Metadata set: ${JSON.stringify(this.metadata)}`);
|
296
|
+
}
|
297
|
+
/**
|
298
|
+
* Get current metadata
|
299
|
+
* @returns A copy of the current metadata object
|
300
|
+
*/
|
301
|
+
getMetadata() {
|
302
|
+
return { ...this.metadata };
|
303
|
+
}
|
304
|
+
/**
|
305
|
+
* Set tags for observability traces
|
306
|
+
* @param newTags - Array of tag strings to add. Duplicates will be automatically removed.
|
307
|
+
*/
|
308
|
+
setTags(newTags) {
|
309
|
+
// Validate and sanitize tags
|
310
|
+
const sanitizedTags = this.sanitizeTags(newTags);
|
311
|
+
this.tags = [...new Set([...this.tags, ...sanitizedTags])]; // Remove duplicates
|
312
|
+
logger.debug(`Tags set: ${JSON.stringify(this.tags)}`);
|
313
|
+
}
|
314
|
+
/**
|
315
|
+
* Get current tags
|
316
|
+
* @returns A copy of the current tags array
|
317
|
+
*/
|
318
|
+
getTags() {
|
319
|
+
return [...this.tags];
|
320
|
+
}
|
321
|
+
/**
|
322
|
+
* Sanitize metadata to ensure compatibility with observability platforms
|
323
|
+
* @param metadata - Raw metadata object
|
324
|
+
* @returns Sanitized metadata object
|
325
|
+
*/
|
326
|
+
sanitizeMetadata(metadata) {
|
327
|
+
const sanitized = {};
|
328
|
+
for (const [key, value] of Object.entries(metadata)) {
|
329
|
+
// Validate key
|
330
|
+
if (typeof key !== 'string' || key.length === 0) {
|
331
|
+
logger.warn(`Invalid metadata key: ${key}. Skipping.`);
|
332
|
+
continue;
|
333
|
+
}
|
334
|
+
// Sanitize key (remove special characters that might cause issues)
|
335
|
+
const sanitizedKey = key.replace(/[^\w-]/g, '_');
|
336
|
+
// Validate and sanitize value
|
337
|
+
if (value === null || value === undefined) {
|
338
|
+
sanitized[sanitizedKey] = value;
|
339
|
+
}
|
340
|
+
else if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
341
|
+
sanitized[sanitizedKey] = value;
|
342
|
+
}
|
343
|
+
else if (Array.isArray(value)) {
|
344
|
+
// Only allow arrays of primitives
|
345
|
+
const sanitizedArray = value.filter(item => typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean');
|
346
|
+
if (sanitizedArray.length > 0) {
|
347
|
+
sanitized[sanitizedKey] = sanitizedArray;
|
348
|
+
}
|
349
|
+
}
|
350
|
+
else if (typeof value === 'object') {
|
351
|
+
// Try to serialize objects, but limit depth to prevent circular references
|
352
|
+
try {
|
353
|
+
const serialized = JSON.stringify(value);
|
354
|
+
if (serialized.length > 1000) {
|
355
|
+
logger.warn(`Metadata value for key '${sanitizedKey}' is too large. Truncating.`);
|
356
|
+
sanitized[sanitizedKey] = `${serialized.substring(0, 1000)}...`;
|
357
|
+
}
|
358
|
+
else {
|
359
|
+
sanitized[sanitizedKey] = value;
|
360
|
+
}
|
361
|
+
}
|
362
|
+
catch (error) {
|
363
|
+
logger.warn(`Failed to serialize metadata value for key '${sanitizedKey}': ${error}. Skipping.`);
|
364
|
+
}
|
365
|
+
}
|
366
|
+
else {
|
367
|
+
logger.warn(`Unsupported metadata value type for key '${sanitizedKey}': ${typeof value}. Skipping.`);
|
368
|
+
}
|
369
|
+
}
|
370
|
+
return sanitized;
|
371
|
+
}
|
372
|
+
/**
|
373
|
+
* Sanitize tags to ensure compatibility with observability platforms
|
374
|
+
* @param tags - Array of tag strings
|
375
|
+
* @returns Array of sanitized tag strings
|
376
|
+
*/
|
377
|
+
sanitizeTags(tags) {
|
378
|
+
return tags
|
379
|
+
.filter(tag => typeof tag === 'string' && tag.length > 0)
|
380
|
+
.map(tag => tag.replace(/[^\w:-]/g, '_'))
|
381
|
+
.filter(tag => tag.length <= 50); // Limit tag length
|
382
|
+
}
|
383
|
+
/**
|
384
|
+
* Get MCP server information for observability metadata
|
385
|
+
*/
|
386
|
+
getMCPServerInfo() {
|
387
|
+
const serverInfo = {};
|
388
|
+
try {
|
389
|
+
if (this.client) {
|
390
|
+
const serverNames = this.client.getServerNames();
|
391
|
+
serverInfo.mcp_servers_count = serverNames.length;
|
392
|
+
serverInfo.mcp_server_names = serverNames;
|
393
|
+
// Get server types and configurations
|
394
|
+
const serverConfigs = {};
|
395
|
+
for (const serverName of serverNames) {
|
396
|
+
try {
|
397
|
+
const config = this.client.getServerConfig(serverName);
|
398
|
+
if (config) {
|
399
|
+
// Determine server type based on configuration
|
400
|
+
let serverType = 'unknown';
|
401
|
+
if (config.command) {
|
402
|
+
serverType = 'command';
|
403
|
+
}
|
404
|
+
else if (config.url) {
|
405
|
+
serverType = 'http';
|
406
|
+
}
|
407
|
+
else if (config.ws_url) {
|
408
|
+
serverType = 'websocket';
|
409
|
+
}
|
410
|
+
serverConfigs[serverName] = {
|
411
|
+
type: serverType,
|
412
|
+
// Include safe configuration details (avoid sensitive data)
|
413
|
+
has_args: !!config.args,
|
414
|
+
has_env: !!config.env,
|
415
|
+
has_headers: !!config.headers,
|
416
|
+
url: config.url || null,
|
417
|
+
command: config.command || null,
|
418
|
+
};
|
419
|
+
}
|
420
|
+
}
|
421
|
+
catch (error) {
|
422
|
+
logger.warn(`Failed to get config for server '${serverName}': ${error}`);
|
423
|
+
serverConfigs[serverName] = { type: 'error', error: 'config_unavailable' };
|
424
|
+
}
|
425
|
+
}
|
426
|
+
serverInfo.mcp_server_configs = serverConfigs;
|
427
|
+
}
|
428
|
+
else if (this.connectors && this.connectors.length > 0) {
|
429
|
+
// Handle direct connectors
|
430
|
+
serverInfo.mcp_servers_count = this.connectors.length;
|
431
|
+
serverInfo.mcp_server_names = this.connectors.map(c => c.publicIdentifier);
|
432
|
+
serverInfo.mcp_server_types = this.connectors.map(c => c.constructor.name);
|
433
|
+
}
|
434
|
+
}
|
435
|
+
catch (error) {
|
436
|
+
logger.warn(`Failed to collect MCP server info: ${error}`);
|
437
|
+
serverInfo.error = 'collection_failed';
|
438
|
+
}
|
439
|
+
return serverInfo;
|
440
|
+
}
|
268
441
|
async _consumeAndReturn(generator) {
|
269
442
|
// Manually iterate through the generator to consume the steps.
|
270
443
|
// The for-await-of loop is not used because it discards the generator's
|
@@ -5,7 +5,9 @@
|
|
5
5
|
* for Langfuse observability platform.
|
6
6
|
*/
|
7
7
|
import type { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
8
|
+
declare function initializeLangfuse(agentId?: string, metadata?: Record<string, any>, metadataProvider?: () => Record<string, any>, tagsProvider?: () => string[]): Promise<void>;
|
8
9
|
export declare const langfuseHandler: () => BaseCallbackHandler | null;
|
9
10
|
export declare const langfuseClient: () => any;
|
10
11
|
export declare const langfuseInitPromise: () => Promise<void> | null;
|
12
|
+
export { initializeLangfuse };
|
11
13
|
//# sourceMappingURL=langfuse.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"langfuse.d.ts","sourceRoot":"","sources":["../../../src/observability/langfuse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;
|
1
|
+
{"version":3,"file":"langfuse.d.ts","sourceRoot":"","sources":["../../../src/observability/langfuse.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAgBzE,iBAAe,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,YAAY,CAAC,EAAE,MAAM,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8M9K;AAiBD,eAAO,MAAM,eAAe,kCAA8B,CAAA;AAC1D,eAAO,MAAM,cAAc,WAA6B,CAAA;AACxD,eAAO,MAAM,mBAAmB,4BAAkC,CAAA;AAClE,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
|
@@ -15,7 +15,7 @@ const langfuseState = {
|
|
15
15
|
client: null,
|
16
16
|
initPromise: null,
|
17
17
|
};
|
18
|
-
async function initializeLangfuse() {
|
18
|
+
async function initializeLangfuse(agentId, metadata, metadataProvider, tagsProvider) {
|
19
19
|
try {
|
20
20
|
// Dynamically import to avoid errors if package not installed
|
21
21
|
const langfuseModule = await import('langfuse-langchain').catch(() => null);
|
@@ -24,10 +24,104 @@ async function initializeLangfuse() {
|
|
24
24
|
return;
|
25
25
|
}
|
26
26
|
const { CallbackHandler } = langfuseModule;
|
27
|
-
// Create a custom CallbackHandler wrapper to add logging
|
27
|
+
// Create a custom CallbackHandler wrapper to add logging and custom metadata
|
28
28
|
class LoggingCallbackHandler extends CallbackHandler {
|
29
|
-
|
29
|
+
agentId;
|
30
|
+
metadata;
|
31
|
+
metadataProvider;
|
32
|
+
tagsProvider;
|
33
|
+
verbose;
|
34
|
+
constructor(config, agentId, metadata, metadataProvider, tagsProvider) {
|
30
35
|
super(config);
|
36
|
+
this.agentId = agentId;
|
37
|
+
this.metadata = metadata;
|
38
|
+
this.metadataProvider = metadataProvider;
|
39
|
+
this.tagsProvider = tagsProvider;
|
40
|
+
this.verbose = config?.verbose ?? false;
|
41
|
+
}
|
42
|
+
// Override to add custom metadata to traces
|
43
|
+
async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata, name, kwargs) {
|
44
|
+
logger.debug('Langfuse: Chain start intercepted');
|
45
|
+
// Add custom tags and metadata
|
46
|
+
const customTags = this.getCustomTags();
|
47
|
+
const metadataToAdd = this.getMetadata();
|
48
|
+
// Merge with existing tags and metadata
|
49
|
+
const enhancedTags = [...(tags || []), ...customTags];
|
50
|
+
const enhancedMetadata = { ...(metadata || {}), ...metadataToAdd };
|
51
|
+
if (this.verbose) {
|
52
|
+
logger.debug(`Langfuse: Chain start with custom tags: ${JSON.stringify(enhancedTags)}`);
|
53
|
+
logger.debug(`Langfuse: Chain start with metadata: ${JSON.stringify(enhancedMetadata)}`);
|
54
|
+
}
|
55
|
+
return super.handleChainStart(chain, inputs, runId, parentRunId, enhancedTags, enhancedMetadata, name, kwargs);
|
56
|
+
}
|
57
|
+
// Get custom tags based on environment and agent configuration
|
58
|
+
getCustomTags() {
|
59
|
+
const tags = [];
|
60
|
+
// Add environment tag
|
61
|
+
const env = this.getEnvironmentTag();
|
62
|
+
if (env) {
|
63
|
+
tags.push(`env:${env}`);
|
64
|
+
}
|
65
|
+
// Add agent ID tag if available
|
66
|
+
if (this.agentId) {
|
67
|
+
tags.push(`agent_id:${this.agentId}`);
|
68
|
+
}
|
69
|
+
// Add tags from provider if available
|
70
|
+
if (this.tagsProvider) {
|
71
|
+
const providerTags = this.tagsProvider();
|
72
|
+
if (providerTags && providerTags.length > 0) {
|
73
|
+
tags.push(...providerTags);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
return tags;
|
77
|
+
}
|
78
|
+
// Get metadata
|
79
|
+
getMetadata() {
|
80
|
+
const metadata = {};
|
81
|
+
// Add environment metadata
|
82
|
+
const env = this.getEnvironmentTag();
|
83
|
+
if (env) {
|
84
|
+
metadata.env = env;
|
85
|
+
}
|
86
|
+
// Add agent ID metadata if available
|
87
|
+
if (this.agentId) {
|
88
|
+
metadata.agent_id = this.agentId;
|
89
|
+
}
|
90
|
+
// Add static metadata if provided
|
91
|
+
if (this.metadata) {
|
92
|
+
Object.assign(metadata, this.metadata);
|
93
|
+
}
|
94
|
+
// Add dynamic metadata from provider if available
|
95
|
+
if (this.metadataProvider) {
|
96
|
+
const dynamicMetadata = this.metadataProvider();
|
97
|
+
if (dynamicMetadata) {
|
98
|
+
Object.assign(metadata, dynamicMetadata);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
return metadata;
|
102
|
+
}
|
103
|
+
// Determine environment tag based on MCP_USE_AGENT_ENV
|
104
|
+
getEnvironmentTag() {
|
105
|
+
const agentEnv = process.env.MCP_USE_AGENT_ENV;
|
106
|
+
if (!agentEnv) {
|
107
|
+
// Default to 'unknown' if environment is not explicitly set
|
108
|
+
return 'unknown';
|
109
|
+
}
|
110
|
+
const envLower = agentEnv.toLowerCase();
|
111
|
+
if (envLower === 'local' || envLower === 'development') {
|
112
|
+
return 'local';
|
113
|
+
}
|
114
|
+
else if (envLower === 'production' || envLower === 'prod') {
|
115
|
+
return 'production';
|
116
|
+
}
|
117
|
+
else if (envLower === 'staging' || envLower === 'stage') {
|
118
|
+
return 'staging';
|
119
|
+
}
|
120
|
+
else if (envLower === 'hosted' || envLower === 'cloud') {
|
121
|
+
return 'hosted';
|
122
|
+
}
|
123
|
+
// For any other values, use the value as-is but sanitized
|
124
|
+
return envLower.replace(/[^a-z0-9_-]/g, '_');
|
31
125
|
}
|
32
126
|
async handleLLMStart(...args) {
|
33
127
|
logger.debug('Langfuse: LLM start intercepted');
|
@@ -36,13 +130,6 @@ async function initializeLangfuse() {
|
|
36
130
|
}
|
37
131
|
return super.handleLLMStart(...args);
|
38
132
|
}
|
39
|
-
async handleChainStart(...args) {
|
40
|
-
logger.debug('Langfuse: Chain start intercepted');
|
41
|
-
if (this.verbose) {
|
42
|
-
logger.debug(`Langfuse: Chain start args: ${JSON.stringify(args)}`);
|
43
|
-
}
|
44
|
-
return super.handleChainStart(...args);
|
45
|
-
}
|
46
133
|
async handleToolStart(...args) {
|
47
134
|
logger.debug('Langfuse: Tool start intercepted');
|
48
135
|
if (this.verbose) {
|
@@ -83,7 +170,7 @@ async function initializeLangfuse() {
|
|
83
170
|
requestTimeout: Number.parseInt(process.env.LANGFUSE_REQUEST_TIMEOUT || '10000'),
|
84
171
|
enabled: process.env.LANGFUSE_ENABLED !== 'false',
|
85
172
|
};
|
86
|
-
langfuseState.handler = new LoggingCallbackHandler(config);
|
173
|
+
langfuseState.handler = new LoggingCallbackHandler(config, agentId, metadata, metadataProvider, tagsProvider);
|
87
174
|
logger.debug('Langfuse observability initialized successfully with logging enabled');
|
88
175
|
// Also initialize the client for direct usage if needed
|
89
176
|
try {
|
@@ -121,3 +208,4 @@ else {
|
|
121
208
|
export const langfuseHandler = () => langfuseState.handler;
|
122
209
|
export const langfuseClient = () => langfuseState.client;
|
123
210
|
export const langfuseInitPromise = () => langfuseState.initPromise;
|
211
|
+
export { initializeLangfuse };
|
@@ -10,6 +10,16 @@ export interface ObservabilityConfig {
|
|
10
10
|
customCallbacks?: BaseCallbackHandler[];
|
11
11
|
/** Whether to enable verbose logging */
|
12
12
|
verbose?: boolean;
|
13
|
+
/** Whether to enable observability (defaults to true) */
|
14
|
+
observe?: boolean;
|
15
|
+
/** Agent ID for tagging traces */
|
16
|
+
agentId?: string;
|
17
|
+
/** Metadata to add to traces */
|
18
|
+
metadata?: Record<string, any>;
|
19
|
+
/** Function to get current metadata from agent */
|
20
|
+
metadataProvider?: () => Record<string, any>;
|
21
|
+
/** Function to get current tags from agent */
|
22
|
+
tagsProvider?: () => string[];
|
13
23
|
}
|
14
24
|
export declare class ObservabilityManager {
|
15
25
|
private customCallbacks?;
|
@@ -17,6 +27,11 @@ export declare class ObservabilityManager {
|
|
17
27
|
private handlerNames;
|
18
28
|
private initialized;
|
19
29
|
private verbose;
|
30
|
+
private observe;
|
31
|
+
private agentId?;
|
32
|
+
private metadata?;
|
33
|
+
private metadataProvider?;
|
34
|
+
private tagsProvider?;
|
20
35
|
constructor(config?: ObservabilityConfig);
|
21
36
|
/**
|
22
37
|
* Collect all available observability handlers from configured platforms.
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/observability/manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAGzE,MAAM,WAAW,mBAAmB;IAClC,kDAAkD;IAClD,eAAe,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACvC,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAA;
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/observability/manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAGzE,MAAM,WAAW,mBAAmB;IAClC,kDAAkD;IAClD,eAAe,CAAC,EAAE,mBAAmB,EAAE,CAAA;IACvC,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5C,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,MAAM,EAAE,CAAA;CAC9B;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,eAAe,CAAC,CAAuB;IAC/C,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAQ;IACxB,OAAO,CAAC,QAAQ,CAAC,CAAqB;IACtC,OAAO,CAAC,gBAAgB,CAAC,CAA2B;IACpD,OAAO,CAAC,YAAY,CAAC,CAAgB;gBAEzB,MAAM,GAAE,mBAAwB;IAU5C;;OAEG;YACW,wBAAwB;IAwCtC;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IA0BpD;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAe1C;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAUtC;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAQhD;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB/B;;OAEG;IACH,QAAQ,IAAI,MAAM;CAOnB;AAKD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,oBAAoB,CAKxD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,GAAE,mBAAwB,GAAG,oBAAoB,CAEpF"}
|
@@ -11,9 +11,19 @@ export class ObservabilityManager {
|
|
11
11
|
handlerNames = [];
|
12
12
|
initialized = false;
|
13
13
|
verbose;
|
14
|
+
observe;
|
15
|
+
agentId;
|
16
|
+
metadata;
|
17
|
+
metadataProvider;
|
18
|
+
tagsProvider;
|
14
19
|
constructor(config = {}) {
|
15
20
|
this.customCallbacks = config.customCallbacks;
|
16
21
|
this.verbose = config.verbose ?? false;
|
22
|
+
this.observe = config.observe ?? true;
|
23
|
+
this.agentId = config.agentId;
|
24
|
+
this.metadata = config.metadata;
|
25
|
+
this.metadataProvider = config.metadataProvider;
|
26
|
+
this.tagsProvider = config.tagsProvider;
|
17
27
|
}
|
18
28
|
/**
|
19
29
|
* Collect all available observability handlers from configured platforms.
|
@@ -25,10 +35,19 @@ export class ObservabilityManager {
|
|
25
35
|
// Import handlers lazily to avoid circular imports
|
26
36
|
try {
|
27
37
|
const { langfuseHandler, langfuseInitPromise } = await import('./langfuse.js');
|
28
|
-
//
|
29
|
-
|
30
|
-
|
31
|
-
await
|
38
|
+
// If we have an agent ID, metadata, or providers, we need to reinitialize Langfuse
|
39
|
+
if (this.agentId || this.metadata || this.metadataProvider || this.tagsProvider) {
|
40
|
+
// Import the initialization function directly
|
41
|
+
const { initializeLangfuse } = await import('./langfuse.js');
|
42
|
+
await initializeLangfuse(this.agentId, this.metadata, this.metadataProvider, this.tagsProvider);
|
43
|
+
logger.debug(`ObservabilityManager: Reinitialized Langfuse with agent ID: ${this.agentId}, metadata: ${JSON.stringify(this.metadata)}`);
|
44
|
+
}
|
45
|
+
else {
|
46
|
+
// Wait for existing initialization to complete
|
47
|
+
const initPromise = langfuseInitPromise();
|
48
|
+
if (initPromise) {
|
49
|
+
await initPromise;
|
50
|
+
}
|
32
51
|
}
|
33
52
|
const handler = langfuseHandler();
|
34
53
|
if (handler) {
|
@@ -48,6 +67,11 @@ export class ObservabilityManager {
|
|
48
67
|
* @returns List of callbacks - either custom callbacks if provided, or all available observability handlers.
|
49
68
|
*/
|
50
69
|
async getCallbacks() {
|
70
|
+
// If observability is disabled, return empty array
|
71
|
+
if (!this.observe) {
|
72
|
+
logger.debug('ObservabilityManager: Observability disabled via observe=false');
|
73
|
+
return [];
|
74
|
+
}
|
51
75
|
// If custom callbacks were provided, use those
|
52
76
|
if (this.customCallbacks) {
|
53
77
|
logger.debug(`ObservabilityManager: Using ${this.customCallbacks.length} custom callbacks`);
|
@@ -68,6 +92,10 @@ export class ObservabilityManager {
|
|
68
92
|
* @returns List of handler names (e.g., ["Langfuse", "Laminar"])
|
69
93
|
*/
|
70
94
|
async getHandlerNames() {
|
95
|
+
// If observability is disabled, return empty array
|
96
|
+
if (!this.observe) {
|
97
|
+
return [];
|
98
|
+
}
|
71
99
|
if (this.customCallbacks) {
|
72
100
|
// For custom callbacks, try to get their class names
|
73
101
|
return this.customCallbacks.map(cb => cb.constructor.name);
|
@@ -80,6 +108,10 @@ export class ObservabilityManager {
|
|
80
108
|
* @returns True if callbacks are available, False otherwise.
|
81
109
|
*/
|
82
110
|
async hasCallbacks() {
|
111
|
+
// If observability is disabled, no callbacks are available
|
112
|
+
if (!this.observe) {
|
113
|
+
return false;
|
114
|
+
}
|
83
115
|
const callbacks = await this.getCallbacks();
|
84
116
|
return callbacks.length > 0;
|
85
117
|
}
|
@@ -75,7 +75,7 @@ describe('mCPAgent streamEvents()', () => {
|
|
75
75
|
yield {
|
76
76
|
event: 'on_chain_end',
|
77
77
|
name: 'AgentExecutor',
|
78
|
-
data: { output: 'Hello world' },
|
78
|
+
data: { output: [{ text: 'Hello world' }] },
|
79
79
|
};
|
80
80
|
});
|
81
81
|
// Mock initialize method
|
@@ -290,6 +290,7 @@ describe('mCPAgent streamEvents() edge cases', () => {
|
|
290
290
|
yield { event: 'malformed' }; // Missing required fields
|
291
291
|
yield null; // Invalid event
|
292
292
|
yield { event: 'on_chat_model_stream', data: { chunk: { content: 'test' } } };
|
293
|
+
yield { event: 'on_chain_end', data: { output: [{ text: 'test response' }] } };
|
293
294
|
}),
|
294
295
|
maxIterations: 3,
|
295
296
|
}),
|
package/package.json
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
{
|
2
2
|
"name": "mcp-use",
|
3
3
|
"type": "module",
|
4
|
-
"version": "0.1.
|
4
|
+
"version": "0.1.19",
|
5
5
|
"packageManager": "pnpm@10.6.1",
|
6
6
|
"description": "A utility library for integrating Model Context Protocol (MCP) with LangChain, Zod, and related tools. Provides helpers for schema conversion, event streaming, and SDK usage.",
|
7
|
-
"author": "
|
7
|
+
"author": "mcp-use, Inc.",
|
8
8
|
"license": "MIT",
|
9
9
|
"homepage": "https://github.com/mcp-use/mcp-use-ts#readme",
|
10
10
|
"repository": {
|
@@ -74,7 +74,8 @@
|
|
74
74
|
"example:oauth": "npm run build && node dist/examples/simple_oauth_example.js",
|
75
75
|
"example:blender": "npm run build && node dist/examples/blender_use.js",
|
76
76
|
"example:add_server": "npm run build && node dist/examples/add_server_tool.js",
|
77
|
-
"example:structured": "npm run build && node dist/examples/structured_output.js"
|
77
|
+
"example:structured": "npm run build && node dist/examples/structured_output.js",
|
78
|
+
"example:observability": "npm run build && node dist/examples/observability.js"
|
78
79
|
},
|
79
80
|
"peerDependencies": {
|
80
81
|
"langfuse": "^3.32.0",
|
@@ -90,15 +91,13 @@
|
|
90
91
|
},
|
91
92
|
"dependencies": {
|
92
93
|
"@dmitryrechkin/json-schema-to-zod": "^1.0.1",
|
93
|
-
"@langchain/anthropic": "^0.3.
|
94
|
-
"@langchain/core": "0.3.
|
95
|
-
"@langchain/openai": "^0.
|
94
|
+
"@langchain/anthropic": "^0.3.26",
|
95
|
+
"@langchain/core": "^0.3.72",
|
96
|
+
"@langchain/openai": "^0.6.9",
|
96
97
|
"@modelcontextprotocol/sdk": "1.12.1",
|
97
98
|
"@scarf/scarf": "^1.4.0",
|
98
99
|
"ai": "^4.3.19",
|
99
100
|
"dotenv": "^16.5.0",
|
100
|
-
"eventsource": "^3.0.6",
|
101
|
-
"fastembed": "^1.14.4",
|
102
101
|
"langchain": "^0.3.27",
|
103
102
|
"lodash-es": "^4.17.21",
|
104
103
|
"posthog-node": "^5.1.1",
|
@@ -117,7 +116,6 @@
|
|
117
116
|
"eslint-plugin-format": "^1.0.1",
|
118
117
|
"husky": "^9.1.7",
|
119
118
|
"lint-staged": "^15.2.11",
|
120
|
-
"shx": "^0.4.0",
|
121
119
|
"typescript": "^5.8.3",
|
122
120
|
"vitest": "^2.1.9"
|
123
121
|
},
|
@@ -125,6 +123,10 @@
|
|
125
123
|
"*.{js,ts}": [
|
126
124
|
"eslint --fix",
|
127
125
|
"eslint"
|
126
|
+
],
|
127
|
+
"*.md": [
|
128
|
+
"eslint --fix",
|
129
|
+
"eslint"
|
128
130
|
]
|
129
131
|
}
|
130
132
|
}
|