mirror of
https://github.com/hanzoai/insights-js.git
synced 2026-11-02 09:24:43 +00:00
## Problem
Our AI examples use PostHog's direct SDK wrappers (`@posthog/ai/openai`, `@posthog/ai/anthropic`, etc.) for tracking LLM calls. We want to silently deprecate these in favor of standard OpenTelemetry auto-instrumentation, which is more portable and follows industry conventions.
## Changes
Migrates 23 Node.js AI examples from PostHog direct wrappers to OpenTelemetry auto-instrumentation (or framework-native integrations where no OTel option exists):
- **15 OpenAI-compatible providers** (Groq, DeepSeek, Mistral, xAI, Together AI, Ollama, Cohere, Hugging Face, Perplexity, Cerebras, Fireworks AI, OpenRouter, Helicone, Vercel AI Gateway, Portkey) → `@opentelemetry/instrumentation-openai`
- **OpenAI** (all 7 files), **Azure OpenAI**, **Instructor** → `@opentelemetry/instrumentation-openai`
- **Anthropic** (chat + streaming) → `@traceloop/instrumentation-anthropic`
- **Vercel AI SDK** (8 files) → built-in `experimental_telemetry`
- **LangChain**, **LangGraph** → `@traceloop/instrumentation-langchain`
- **Mastra** → `@mastra/posthog` exporter (Mastra's native PostHog integration — no mature OTel path for Mastra yet)
All OTel-based examples set resource attributes to demonstrate the full feature set:
```ts
resource: resourceFromAttributes({
'service.name': 'example-groq-app',
'posthog.distinct_id': 'example-user',
foo: 'bar',
'conversation_id': 'abc-123',
}),
```
These map to `distinct_id` and custom event properties via PostHog's OTLP ingestion endpoint.
**Kept as-is:** Gemini (no Node.js OTel for `@google/genai`), AWS Bedrock/Convex/OTel (already OTel-based).
Key implementation details:
- Uses `SimpleSpanProcessor` instead of `BatchSpanProcessor` so spans export immediately without needing `sdk.shutdown()` (with an inline comment explaining why)
- Uses `resourceFromAttributes` from `@opentelemetry/resources` v2
- Static imports (no dynamic `await import()`)
- OTel deps at `^0.200.0` / `^2.0.0` for consistent resolution
- `example-ai-otel/package.json` bumped to matching OTel versions per reviewer feedback
## Release info Sub-libraries affected
### Libraries affected
- [ ] All of them
- [ ] posthog-js (web)
- [ ] posthog-js-lite (web lite)
- [ ] posthog-node
- [ ] posthog-react-native
- [ ] @posthog/react
- [ ] @posthog/ai
- [ ] @posthog/convex
- [ ] @posthog/next
- [ ] @posthog/nextjs-config
- [ ] @posthog/nuxt
- [ ] @posthog/rollup-plugin
- [ ] @posthog/webpack-plugin
- [ ] @posthog/types
No library version bumps — this only touches `examples/`.
## Checklist
- [ ] Tests for new code
- [x] Accounted for the impact of any changes across different platforms
- [x] Accounted for backwards compatibility of any changes (no breaking changes!)
- [x] Took care not to unnecessarily increase the bundle size
### If releasing new changes
- [ ] Ran `pnpm changeset` to generate a changeset file
- [ ] Added the "release" label to the PR to indicate we're publishing new versions for the affected packages
69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
/** Mastra agent with PostHog tracking via the official @mastra/posthog exporter. */
|
|
|
|
import { Mastra } from '@mastra/core'
|
|
import { Agent } from '@mastra/core/agent'
|
|
import { createTool } from '@mastra/core/tools'
|
|
import { Observability } from '@mastra/observability'
|
|
import { PosthogExporter } from '@mastra/posthog'
|
|
import { z } from 'zod'
|
|
|
|
const weatherTool = createTool({
|
|
id: 'get_weather',
|
|
description: 'Get current weather for a location',
|
|
inputSchema: z.object({
|
|
latitude: z.number(),
|
|
longitude: z.number(),
|
|
location_name: z.string(),
|
|
}),
|
|
execute: async ({ latitude, longitude, location_name }) => {
|
|
const url = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,relative_humidity_2m,wind_speed_10m`
|
|
const resp = await fetch(url)
|
|
const data = await resp.json()
|
|
const current = data.current
|
|
return `Weather in ${location_name}: ${current.temperature_2m}°C, humidity ${current.relative_humidity_2m}%, wind ${current.wind_speed_10m} km/h`
|
|
},
|
|
})
|
|
|
|
const weatherAgent = new Agent({
|
|
id: 'weather-agent',
|
|
name: 'Weather Agent',
|
|
instructions: 'You are a helpful assistant with access to weather data.',
|
|
model: { id: 'openai/gpt-5-mini' },
|
|
tools: { get_weather: weatherTool },
|
|
})
|
|
|
|
const mastra = new Mastra({
|
|
agents: { weatherAgent },
|
|
observability: new Observability({
|
|
configs: {
|
|
posthog: {
|
|
serviceName: 'example-mastra-app',
|
|
exporters: [
|
|
new PosthogExporter({
|
|
apiKey: process.env.POSTHOG_API_KEY!,
|
|
host: process.env.POSTHOG_HOST || 'https://us.i.posthog.com',
|
|
defaultDistinctId: 'example-user',
|
|
}),
|
|
],
|
|
},
|
|
},
|
|
}),
|
|
})
|
|
|
|
async function main() {
|
|
const agent = mastra.getAgent('weatherAgent')
|
|
const result = await agent.generate("What's the weather like in Dublin, Ireland?", {
|
|
tracingOptions: {
|
|
metadata: {
|
|
userId: 'example-user',
|
|
sessionId: 'session-abc-123',
|
|
foo: 'bar',
|
|
conversation_id: 'abc-123',
|
|
},
|
|
},
|
|
})
|
|
console.log(result.text)
|
|
}
|
|
|
|
main()
|