feat: add optional Langfuse observability integration

- Add session tracking with unique sessionId per conversation
- Add user tracking via IP address (x-forwarded-for header)
- Make telemetry conditional - only enabled if LANGFUSE_PUBLIC_KEY is set
- Add environment variable validation in instrumentation.ts
- Add sessionId validation (type check + 200 char limit)
- Update env.example with Langfuse configuration docs
- Remove unused langfuse-vercel and @vercel/otel packages
This commit is contained in:
dayuan.jiang
2025-12-04 00:13:42 +09:00
parent d84edb529c
commit 30b598d960
6 changed files with 265 additions and 138 deletions

View File

@@ -30,7 +30,16 @@ function createCachedStreamResponse(xml: string): Response {
export async function POST(req: Request) {
try {
const { messages, xml } = await req.json();
const { messages, xml, sessionId } = await req.json();
// Get user IP for Langfuse tracking
const forwardedFor = req.headers.get('x-forwarded-for');
const userId = forwardedFor?.split(',')[0]?.trim() || 'anonymous';
// Validate sessionId for Langfuse (must be string, max 200 chars)
const validSessionId = sessionId && typeof sessionId === 'string' && sessionId.length <= 200
? sessionId
: undefined;
// === CACHE CHECK START ===
const isFirstMessage = messages.length === 1;
@@ -257,7 +266,16 @@ ${lastMessageText}
messages: [systemMessageWithCache, ...enhancedMessages],
...(providerOptions && { providerOptions }),
...(headers && { headers }),
experimental_telemetry: { isEnabled: true },
// Only enable telemetry if Langfuse is configured
...(process.env.LANGFUSE_PUBLIC_KEY && {
experimental_telemetry: {
isEnabled: true,
metadata: {
sessionId: validSessionId,
userId: userId,
},
},
}),
onFinish: ({ usage, providerMetadata }) => {
console.log('[Cache] Usage:', JSON.stringify({
inputTokens: usage?.inputTokens,