Skip to content

Commit 115efff

Browse files
alban bertoliniclaude
andcommitted
refactor(ai-proxy): use Logger from datasource-toolkit instead of custom logger
Replace the custom Logger type with the Logger from @forestadmin/datasource-toolkit which has the standard signature (level, message, error?). This ensures consistency across all Forest Admin packages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 100204a commit 115efff

File tree

6 files changed

+24
-36
lines changed

6 files changed

+24
-36
lines changed

packages/agent/src/routes/ai/ai-proxy.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,20 @@ export default class AiProxyRoute extends BaseRoute {
1818
super(services, options);
1919
this.aiProxyRouter = new AiProxyRouter({
2020
aiClients: aiLlmConfig.aiClients,
21-
logger: {
22-
error: (...args: unknown[]) => {
23-
this.options.logger('Error', String(args[0]));
24-
},
25-
},
21+
logger: this.options.logger,
2622
});
2723
}
2824

2925
setupRoutes(router: KoaRouter): void {
30-
router.all('/ai-proxy/:route', this.handleAiProxy.bind(this));
26+
router.post('/ai-proxy/:route', this.handleAiProxy.bind(this));
3127
}
3228

3329
private async handleAiProxy(context: Context): Promise<void> {
34-
const route = context.params.route as Route;
35-
36-
// Fetch MCP server configs from Forest Admin server
37-
const mcpConfigs =
38-
await this.options.forestAdminClient.mcpServerConfigService.getConfiguration();
39-
4030
context.response.body = await this.aiProxyRouter.route({
41-
route,
31+
route: context.params.route,
4232
body: context.request.body,
43-
query: context.query as { provider?: string; 'tool-name'?: string },
44-
mcpConfigs,
33+
query: context.query,
34+
mcpConfigs: await this.options.forestAdminClient.mcpServerConfigService.getConfiguration(),
4535
});
4636
context.response.status = HttpCode.Ok;
4737
}

packages/ai-proxy/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"dependencies": {
1515
"openai": "4.95.0",
1616
"zod": "3.23.8",
17+
"@forestadmin/datasource-toolkit": "1.50.0",
1718
"@langchain/community": "0.3.57",
1819
"@langchain/core": "0.3.78",
1920
"@langchain/mcp-adapters": "0.6.0"

packages/ai-proxy/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export * from './provider-dispatcher';
66
export * from './remote-tools';
77
export * from './router';
88
export * from './mcp-client';
9-
export * from './logger';
109

1110
export * from './errors';
1211

packages/ai-proxy/src/logger.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

packages/ai-proxy/src/mcp-client.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import type { Logger } from '@forestadmin/datasource-toolkit';
2+
13
import { MultiServerMCPClient } from '@langchain/mcp-adapters';
24

35
import { McpConnectionError } from './errors';
4-
import { type Logger, defaultLogger } from './logger';
56
import RemoteTool from './remote-tool';
67

78
export type McpConfiguration = {
@@ -10,11 +11,11 @@ export type McpConfiguration = {
1011

1112
export default class McpClient {
1213
private readonly mcpClients: Record<string, MultiServerMCPClient> = {};
13-
private readonly logger: Logger;
14+
private readonly logger?: Logger;
1415

1516
readonly tools: RemoteTool[] = [];
1617

17-
constructor(config: McpConfiguration, logger: Logger = defaultLogger) {
18+
constructor(config: McpConfiguration, logger?: Logger) {
1819
this.logger = logger;
1920
// split the config into several clients to be more resilient
2021
// if a mcp server is down, the others will still work
@@ -43,7 +44,7 @@ export default class McpClient {
4344
);
4445
this.tools.push(...extendedTools);
4546
} catch (error) {
46-
this.logger.error(`Error loading tools for ${name}:`, error);
47+
this.logger?.('Error', `Error loading tools for ${name}`, error as Error);
4748
errors.push({ server: name, error: error as Error });
4849
}
4950
}),
@@ -52,7 +53,8 @@ export default class McpClient {
5253
// Surface partial failures to provide better feedback
5354
if (errors.length > 0) {
5455
const errorMessage = errors.map(e => `${e.server}: ${e.error.message}`).join('; ');
55-
this.logger.error(
56+
this.logger?.(
57+
'Error',
5658
`Failed to load tools from ${errors.length}/${Object.keys(this.mcpClients).length} ` +
5759
`MCP server(s): ${errorMessage}`,
5860
);
@@ -75,7 +77,7 @@ export default class McpClient {
7577
await this.closeConnections();
7678
} catch (cleanupError) {
7779
// Log but don't throw - we don't want to mask the original connection error
78-
this.logger.error('Error during test connection cleanup:', cleanupError);
80+
this.logger?.('Error', 'Error during test connection cleanup', cleanupError as Error);
7981
}
8082
}
8183
}
@@ -91,12 +93,14 @@ export default class McpClient {
9193

9294
if (failures.length > 0) {
9395
failures.forEach(({ name, result }) => {
94-
this.logger.error(
95-
`Failed to close MCP connection for ${name}:`,
96+
this.logger?.(
97+
'Error',
98+
`Failed to close MCP connection for ${name}`,
9699
(result as PromiseRejectedResult).reason,
97100
);
98101
});
99-
this.logger.error(
102+
this.logger?.(
103+
'Error',
100104
`Failed to close ${failures.length}/${results.length} MCP connections. ` +
101105
`This may result in resource leaks.`,
102106
);

packages/ai-proxy/src/router.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
import type { Logger } from '@forestadmin/datasource-toolkit';
2+
13
import type { McpConfiguration } from './mcp-client';
24
import type { Clients, DispatchBody } from './provider-dispatcher';
35
import type { Messages, RemoteToolsApiKeys } from './remote-tools';
46

57
import { AIUnprocessableError, ProviderDispatcher } from './index';
6-
import { type Logger, defaultLogger } from './logger';
78
import McpClient from './mcp-client';
89
import { RemoteTools } from './remote-tools';
910

@@ -19,12 +20,12 @@ export type ApiKeys = RemoteToolsApiKeys;
1920
export class Router {
2021
private readonly localToolsApiKeys?: ApiKeys;
2122
private readonly aiClients: Clients;
22-
private readonly logger: Logger;
23+
private readonly logger?: Logger;
2324

2425
constructor(params?: { aiClients: Clients; localToolsApiKeys?: ApiKeys; logger?: Logger }) {
2526
this.aiClients = params?.aiClients;
2627
this.localToolsApiKeys = params?.localToolsApiKeys;
27-
this.logger = params?.logger ?? defaultLogger;
28+
this.logger = params?.logger;
2829
}
2930

3031
/**
@@ -90,7 +91,7 @@ export class Router {
9091
try {
9192
await mcpClient.closeConnections();
9293
} catch (cleanupError) {
93-
this.logger.error('Error during MCP connection cleanup:', cleanupError);
94+
this.logger?.('Error', 'Error during MCP connection cleanup', cleanupError as Error);
9495
}
9596
}
9697
}

0 commit comments

Comments
 (0)