From 23338c3955aacbcdc4fe40f2517e859f01f4a9d4 Mon Sep 17 00:00:00 2001 From: jpwilson Date: Tue, 24 Feb 2026 20:21:12 -0600 Subject: [PATCH] feat(agent): integrate Langfuse observability Add OpenTelemetry-based Langfuse tracing to the AI agent. Every generateText call now emits spans with tool calls, token usage, and metadata (userId, conversationId) to Langfuse for monitoring. --- apps/api/src/app/agent/agent.service.ts | 10 +++++++++- apps/api/src/main.ts | 16 ++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/apps/api/src/app/agent/agent.service.ts b/apps/api/src/app/agent/agent.service.ts index 1e23e31c2..842b680d8 100644 --- a/apps/api/src/app/agent/agent.service.ts +++ b/apps/api/src/app/agent/agent.service.ts @@ -544,7 +544,15 @@ If you detect any inconsistencies in the data, flag them clearly to the user.`, } }) }, - maxSteps: 5 + maxSteps: 5, + experimental_telemetry: { + isEnabled: true, + functionId: 'ghostfolio-agent', + metadata: { + userId, + conversationId: convId + } + } }); // --- Verification Layer --- diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index a8de3dc5e..f6de87cf8 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -20,6 +20,22 @@ import helmet from 'helmet'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; +// Initialize Langfuse OpenTelemetry tracing (if configured) +if (process.env.LANGFUSE_SECRET_KEY) { + try { + const { NodeSDK } = require('@opentelemetry/sdk-node'); + const { LangfuseSpanProcessor } = require('@langfuse/otel'); + + const sdk = new NodeSDK({ + spanProcessors: [new LangfuseSpanProcessor()] + }); + sdk.start(); + console.log('Langfuse tracing initialized'); + } catch (error) { + console.warn('Langfuse tracing not available:', error.message); + } +} + async function bootstrap() { const configApp = await NestFactory.create(AppModule); const configService = configApp.get(ConfigService);