diff --git a/apps/web/app/api/chat/route.ts b/apps/web/app/api/chat/route.ts index 8e91b9c60bd..efc2f026b6e 100644 --- a/apps/web/app/api/chat/route.ts +++ b/apps/web/app/api/chat/route.ts @@ -44,7 +44,8 @@ export async function POST(req: Request) { messages, sessionId, sessionKey, - }: { messages: UIMessage[]; sessionId?: string; sessionKey?: string } = await req.json(); + distinctId, + }: { messages: UIMessage[]; sessionId?: string; sessionKey?: string; distinctId?: string } = await req.json(); const lastUserMessage = messages.filter((m) => m.role === "user").pop(); const userText = @@ -60,10 +61,14 @@ export async function POST(req: Request) { return new Response("No message provided", { status: 400 }); } - trackServer("chat_message_sent", { - message_length: userText.length, - is_subagent: typeof sessionKey === "string" && sessionKey.includes(":subagent:"), - }); + trackServer( + "chat_message_sent", + { + message_length: userText.length, + is_subagent: typeof sessionKey === "string" && sessionKey.includes(":subagent:"), + }, + distinctId, + ); const isSubagentSession = typeof sessionKey === "string" && sessionKey.includes(":subagent:"); diff --git a/apps/web/app/api/feedback/route.ts b/apps/web/app/api/feedback/route.ts index 0bbf8647bf1..0ecec894542 100644 --- a/apps/web/app/api/feedback/route.ts +++ b/apps/web/app/api/feedback/route.ts @@ -62,12 +62,14 @@ export async function POST(req: Request) { } const conversation = lines.slice(0, cutoff); - const inputState = conversation - .filter((m) => m.role === "user") - .map((m) => ({ role: "user" as const, content: extractTextContent(m) })); - const outputState = conversation - .filter((m) => m.role === "assistant") - .map((m) => ({ role: "assistant" as const, content: extractTextContent(m) })); + const chronological = conversation.map((m) => ({ + role: m.role as "user" | "assistant", + content: extractTextContent(m), + })); + + const lastAssistant = [...conversation] + .reverse() + .find((m) => m.role === "assistant"); trackServer( "$ai_trace", @@ -75,8 +77,10 @@ export async function POST(req: Request) { $ai_trace_id: sessionId, $ai_session_id: sessionId, $ai_span_name: "chat_session", - $ai_input_state: inputState.length > 0 ? inputState : undefined, - $ai_output_state: outputState.length > 0 ? outputState : undefined, + $ai_input_state: chronological.length > 0 ? chronological : undefined, + $ai_output_state: lastAssistant + ? [{ role: "assistant" as const, content: extractTextContent(lastAssistant) }] + : undefined, }, distinctId, ); diff --git a/apps/web/app/components/posthog-provider.tsx b/apps/web/app/components/posthog-provider.tsx index 582d79ba7cb..c209ce1b88d 100644 --- a/apps/web/app/components/posthog-provider.tsx +++ b/apps/web/app/components/posthog-provider.tsx @@ -2,7 +2,7 @@ import posthog from "posthog-js"; import { PostHogProvider as PHProvider } from "posthog-js/react"; -import { useEffect } from "react"; +import { useEffect, useRef } from "react"; import { usePathname, useSearchParams } from "next/navigation"; const POSTHOG_KEY = process.env.NEXT_PUBLIC_POSTHOG_KEY || ""; @@ -10,7 +10,7 @@ const POSTHOG_HOST = "https://us.i.posthog.com"; let initialized = false; -function initPostHog() { +function initPostHog(anonymousId?: string) { if (initialized || !POSTHOG_KEY || typeof window === "undefined") return; posthog.init(POSTHOG_KEY, { @@ -21,6 +21,9 @@ function initPostHog() { autocapture: false, disable_session_recording: true, person_profiles: "identified_only", + bootstrap: anonymousId + ? { distinctID: anonymousId, isIdentifiedID: false } + : undefined, }); initialized = true; } @@ -40,12 +43,18 @@ function PageviewTracker() { export function PostHogProvider({ children, + anonymousId, }: { children: React.ReactNode; + anonymousId?: string; }) { + const initRef = useRef(false); + useEffect(() => { - initPostHog(); - }, []); + if (initRef.current) return; + initRef.current = true; + initPostHog(anonymousId); + }, [anonymousId]); if (!POSTHOG_KEY) return <>{children}>; diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx index 13edae493b3..0f46760724f 100644 --- a/apps/web/app/layout.tsx +++ b/apps/web/app/layout.tsx @@ -1,5 +1,6 @@ import type { Metadata, Viewport } from "next"; import { Suspense } from "react"; +import { getOrCreateAnonymousId } from "@/lib/telemetry"; import { PostHogProvider } from "./components/posthog-provider"; import "./globals.css"; @@ -20,6 +21,8 @@ export default function RootLayout({ }: { children: React.ReactNode; }) { + const anonymousId = getOrCreateAnonymousId(); + return (
@@ -42,7 +45,7 @@ export default function RootLayout({