From 2f21f454cb92c36fb8a34a2951b40013be840861 Mon Sep 17 00:00:00 2001 From: Carlos Marchal Date: Mon, 8 Jun 2026 12:38:48 +0200 Subject: [PATCH] chore: add @posthog/ai sdk test scripts with opt-in local-sdk linking --- Makefile | 6 +- README.md | 33 +++- package.json | 7 +- pnpm-lock.yaml | 306 ++++++++++++--------------------- scripts/link_local_ai_sdk.sh | 33 ++++ scripts/test_posthog_ai_sdk.ts | 137 +++++++++++++++ scripts/test_vercel_ai_otel.ts | 23 +-- 7 files changed, 330 insertions(+), 215 deletions(-) create mode 100755 scripts/link_local_ai_sdk.sh create mode 100644 scripts/test_posthog_ai_sdk.ts diff --git a/Makefile b/Makefile index 717bba7..a623469 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,14 @@ -.PHONY: setup run-trace-generator run-trace-generator-debug demo-data demo-data-quick demo-data-tools demo-data-negative +.PHONY: setup link-local-sdk run-trace-generator run-trace-generator-debug demo-data demo-data-quick demo-data-tools demo-data-negative ## Install all dependencies setup: @uv sync @pnpm install +## Build & link a local @posthog/ai for unreleased SDK testing (override path with POSTHOG_JS_PATH) +link-local-sdk: + @./scripts/link_local_ai_sdk.sh + ## Run the trace generator (mock trace data, no LLM calls) run-trace-generator: @uv run trace-generator/trace_generator.py diff --git a/README.md b/README.md index ef529ca..6a36fec 100644 --- a/README.md +++ b/README.md @@ -73,9 +73,20 @@ uv run scripts/test_litellm.py uv run scripts/test_langchain_otel.py uv run scripts/test_pydantic_ai_otel.py -# Node (Vercel AI SDK) -npx tsx scripts/test_vercel_ai_otel.ts -npx tsx scripts/test_vercel_anthropic.ts +# Node — @posthog/ai +npx tsx scripts/test_posthog_ai_sdk.ts # subpath clients + captureAiGeneration +npx tsx scripts/test_vercel_ai_otel.ts # OTel via PostHogSpanProcessor +npx tsx scripts/test_vercel_anthropic.ts # withTracing (Vercel AI SDK) +``` + +The Node scripts read `POSTHOG_API_KEY` / `POSTHOG_HOST` from the environment. +For a local PostHog, fetch the project key first and pass it through `op run` +(which resolves the provider keys in `.env`): + +```bash +KEY=$(uv run scripts/get_localhost_api_key.py -q) +POSTHOG_API_KEY="$KEY" POSTHOG_HOST=http://localhost:8010 \ + op run --env-file=.env -- pnpm exec tsx scripts/test_posthog_ai_sdk.ts ``` ## Local SDK Development @@ -87,6 +98,22 @@ POSTHOG_PYTHON_PATH=../../posthog-python POSTHOG_JS_PATH=../../posthog-js ``` +### Testing unreleased `@posthog/ai` + +By default `package.json` pins the **published** `@posthog/ai`, so `make setup` +works with no posthog-js checkout. To run the Node scripts against a local SDK +build instead (e.g. to validate an unreleased change), link it in: + +```bash +make link-local-sdk # uses ../posthog-js +POSTHOG_JS_PATH=/path/to/posthog-js make link-local-sdk # or any location +``` + +`link-local-sdk` builds `@posthog/ai` (and its workspace deps, in topo order) +and rewrites `package.json` to point `@posthog/ai` + `posthog-node` at your +checkout. That edit is local-only — don't commit it. To restore the published +SDK: `git checkout -- package.json pnpm-lock.yaml && pnpm install`. + ## License MIT License - see LICENSE file for details. diff --git a/package.json b/package.json index 2f630fe..b86d134 100644 --- a/package.json +++ b/package.json @@ -6,14 +6,17 @@ "dependencies": { "@ai-sdk/anthropic": "^3.0.58", "@ai-sdk/openai": "^3.0.41", + "@anthropic-ai/sdk": "^0.78.0", "@opentelemetry/api": "^1.9.0", "@opentelemetry/exporter-trace-otlp-http": "^0.213.0", "@opentelemetry/resources": "^2.6.0", "@opentelemetry/sdk-node": "^0.213.0", - "@posthog/ai": "^7.12.1", + "@opentelemetry/sdk-trace-base": "^2.0.0", + "@posthog/ai": "^7.20.14", "ai": "^6.0.116", "dotenv": "^17.3.1", - "posthog-node": "^5.28.4", + "openai": "^6.25.0", + "posthog-node": "^5.35.14", "zod": "^4.3.6" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7d8d47d..deea0bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@ai-sdk/openai': specifier: ^3.0.41 version: 3.0.41(zod@4.3.6) + '@anthropic-ai/sdk': + specifier: ^0.78.0 + version: 0.78.0(zod@4.3.6) '@opentelemetry/api': specifier: ^1.9.0 version: 1.9.0 @@ -26,18 +29,24 @@ importers: '@opentelemetry/sdk-node': specifier: ^0.213.0 version: 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': + specifier: ^2.0.0 + version: 2.6.0(@opentelemetry/api@1.9.0) '@posthog/ai': - specifier: ^7.12.1 - version: 7.12.1(@ai-sdk/provider@3.0.8)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-http@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(posthog-node@5.28.4)(ws@8.19.0) + specifier: ^7.20.14 + version: 7.20.14(@ai-sdk/provider@3.0.8)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-http@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(posthog-node@5.36.4)(ws@8.19.0) ai: specifier: ^6.0.116 version: 6.0.116(zod@4.3.6) dotenv: specifier: ^17.3.1 version: 17.3.1 + openai: + specifier: ^6.25.0 + version: 6.32.0(ws@8.19.0)(zod@4.3.6) posthog-node: - specifier: ^5.28.4 - version: 5.28.4 + specifier: ^5.35.14 + version: 5.36.4 zod: specifier: ^4.3.6 version: 4.3.6 @@ -248,8 +257,8 @@ packages: cpu: [x64] os: [win32] - '@google/genai@1.46.0': - resolution: {integrity: sha512-ewPMN5JkKfgU5/kdco9ZhXBHDPhVqZpMQqIFQhwsHLf8kyZfx1cNpw1pHo1eV6PGEW7EhIBFi3aYZraFndAXqg==} + '@google/genai@1.52.0': + resolution: {integrity: sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -269,27 +278,25 @@ packages: '@js-sdsl/ordered-map@4.4.2': resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} - '@langchain/core@1.1.34': - resolution: {integrity: sha512-IDlZES5Vexo5meLQRCGkAU7NM0tPGPfPP5wcUzBd7Ot+JoFBmSXutC4gGzvZod5AKRVn3I0Qy5k8vkTraY21jA==} + '@langchain/core@1.1.48': + resolution: {integrity: sha512-fQU6Guyb1pwc2fEplmA8FPbKfOMAofjnyJzExevro0FxEiuGHE18Ov/ZHmT9trWCDTZRI9eW1VIc6aChxV8pAQ==} engines: {node: '>=20'} - '@langchain/langgraph-checkpoint@1.0.1': - resolution: {integrity: sha512-HM0cJLRpIsSlWBQ/xuDC67l52SqZ62Bh2Y61DX+Xorqwoh5e1KxYvfCD7GnSTbWWhjBOutvnR0vPhu4orFkZfw==} + '@langchain/langgraph-checkpoint@1.0.4': + resolution: {integrity: sha512-1y5MgZ0gXXrtmoy56e3kaBChI3GwFPIKl27xkrHwN+VE/3iUsyr9gO3Jtp7kdKAe6diZGbcas5bdC/r0yUwTZA==} engines: {node: '>=18'} peerDependencies: - '@langchain/core': ^1.0.1 + '@langchain/core': ^1.1.44 - '@langchain/langgraph-sdk@1.7.5': - resolution: {integrity: sha512-j6MjD5btOfVSj2nVKVTu28YPHA9vzBuDbOFnzzfa5q4F6Tbt2Dwg+EiGhJptUz/3XKmU0OKp/3gCWk0ZTHHD1Q==} + '@langchain/langgraph-sdk@1.9.18': + resolution: {integrity: sha512-EQLlop/GLlm52Rii06oZDv1bPvrWARnDuzSY6in4d1gnZX2KSQvxajeZH8GYfMjapDVhbo324DRYJgL9euo2fg==} peerDependencies: - '@langchain/core': ^1.1.16 + '@langchain/core': ^1.1.48 react: ^18 || ^19 react-dom: ^18 || ^19 svelte: ^4.0.0 || ^5.0.0 vue: ^3.0.0 peerDependenciesMeta: - '@langchain/core': - optional: true react: optional: true react-dom: @@ -299,17 +306,20 @@ packages: vue: optional: true - '@langchain/langgraph@1.2.4': - resolution: {integrity: sha512-opUmulmIkQFwFP/JpsXl8K7vqfzeNjuZObeQ1ASu4ZjUcQdyaY1Vm11g9fxH/pXJFeIWy+6BLVJcLUxQ1DRhcA==} + '@langchain/langgraph@1.3.6': + resolution: {integrity: sha512-OlpIhaMYs2IlN5hCGUMF9B/jgVacLK5nYbwri1AQatB+CcFIk1xVi9jHcD+fkAtn+7ExFbwiOAAdhuGeWQA9BA==} engines: {node: '>=18'} peerDependencies: - '@langchain/core': ^1.1.16 + '@langchain/core': ^1.1.48 zod: ^3.25.32 || ^4.2.0 zod-to-json-schema: ^3.x peerDependenciesMeta: zod-to-json-schema: optional: true + '@langchain/protocol@0.0.16': + resolution: {integrity: sha512-ws+J7MaHyhO5dG7f0vdyHQiUn9hoCnki0f3crJPa4MCTGzcRC39jYSCghyrGtBPYQnZbUQiGyRVpW3z3M8IpJg==} + '@opentelemetry/api-logs@0.213.0': resolution: {integrity: sha512-zRM5/Qj6G84Ej3F1yt33xBVY/3tnMxtL1fiDIxYbDWYaZ/eudVw3/PBiZ8G7JwUxXxjW8gU4g6LnOyfGKYHYgw==} engines: {node: '>=8.0.0'} @@ -478,24 +488,33 @@ packages: resolution: {integrity: sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==} engines: {node: '>=14'} - '@posthog/ai@7.12.1': - resolution: {integrity: sha512-QhaXyU9FSehY95jTu7jgseGwHOWoOV9LkoEnqvU34fZmrMiaP0G1QjDDlJcSEKsOMAtI4l9ySLSJ4G3SVyb1Xg==} + '@posthog/ai@7.20.14': + resolution: {integrity: sha512-xjzG2aSpqnSDUWYN1gHa6LHmrGwwqZi7E5DfRTpUq2YOwQbVk5mr8K+Hq5keck8bowApalVRySKMM6LZr/1JHA==} engines: {node: ^20.20.0 || >=22.22.0} peerDependencies: '@ai-sdk/provider': ^2.0.0 || ^3.0.0 + '@openai/agents': ^0.8.0 '@opentelemetry/api': ^1.9.0 - '@opentelemetry/exporter-trace-otlp-http': ^0.200.0 + '@opentelemetry/exporter-trace-otlp-http': '>=0.200.0 <1.0.0' + '@opentelemetry/sdk-trace-base': ^2.0.0 posthog-node: ^5.0.0 peerDependenciesMeta: '@ai-sdk/provider': optional: true + '@openai/agents': + optional: true '@opentelemetry/api': optional: true '@opentelemetry/exporter-trace-otlp-http': optional: true + '@opentelemetry/sdk-trace-base': + optional: true - '@posthog/core@1.24.0': - resolution: {integrity: sha512-Wkp9mgNfgdf6+G4C1VMKakm2RXKQFf4bb5/CPQRAjpqv9l6BY36zZrD1+X5Y2XIAzZqbMKRxsDu3V1r6uKu7/A==} + '@posthog/core@1.30.10': + resolution: {integrity: sha512-R7Z5jDB3ugwfSujMmRd5osPPR6L6BqfcaSNcYOekzRMZ4Jklq74p05xByP09EnUvKXb5czI+RQVCITTWRWuFXw==} + + '@posthog/types@1.382.0': + resolution: {integrity: sha512-iK4OcSgvtmS9FZ9EUpvwlRZmHCLXaZ3+6dbRjkE7q9LL0zHLewxJH84H6uGvCw8aGzxs5rIliZqPHgimTcQEaw==} '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -539,9 +558,6 @@ packages: '@types/retry@0.12.0': resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} - '@types/uuid@10.0.0': - resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} - '@vercel/oidc@3.1.0': resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} engines: {node: '>= 20'} @@ -574,10 +590,6 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -587,14 +599,6 @@ packages: buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - chalk@5.6.2: - resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - cjs-module-lexer@2.2.0: resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} @@ -609,13 +613,6 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - console-table-printer@2.15.0: - resolution: {integrity: sha512-SrhBq4hYVjLCkBVOWaTzceJalvn5K1Zq5aQA6wXC/cYjI3frKWNPEMK3sZsJfNNQApvCQmgBcc13ZKmFj8qExw==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -629,10 +626,6 @@ packages: supports-color: optional: true - decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - dotenv@17.3.1: resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} engines: {node: '>=12'} @@ -678,8 +671,8 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - gaxios@7.1.4: - resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} + gaxios@7.1.5: + resolution: {integrity: sha512-5FZy72Rh8LhtjmvDrKkI+lVhrsQrVKVsItxMoDm5mNQE+xR0WVIIs+jzPSJgBvKVsLi24fZhXJIsNI0bihDzFg==} engines: {node: '>=18'} gcp-metadata@8.1.2: @@ -693,8 +686,8 @@ packages: get-tsconfig@4.13.6: resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} - google-auth-library@10.6.2: - resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} + google-auth-library@10.7.0: + resolution: {integrity: sha512-QpTAbNJ36TliZLx3TTtahR8HG0hN9RllL1e3FymOvQSIKK8JmgV58H924ub2wa2DsS3ANjjP1Aw1N+Ramc8hqQ==} engines: {node: '>=18'} google-logging-utils@1.1.3: @@ -713,13 +706,10 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-network-error@1.3.1: - resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} + is-network-error@1.3.2: + resolution: {integrity: sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==} engines: {node: '>=16'} - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - js-tiktoken@1.0.21: resolution: {integrity: sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==} @@ -739,14 +729,14 @@ packages: jws@4.0.1: resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} - langchain@1.2.35: - resolution: {integrity: sha512-uMK/YZu8i4mCfGarB3EJ/efd7CKidtphw7M5qcgTxWvXMXxHCG8KMLMq70hnJ63GQa1TpgreOzePrK4bvdE2ig==} + langchain@1.4.4: + resolution: {integrity: sha512-tepOCwUDaIZOYJ9Eo0O6o5dXEN/0KJheiFDnHHFL8Tx8rfkDLL4cOTSTln4Vpn9LpWzXYkjQ8lkHnnNDQWZPeg==} engines: {node: '>=20'} peerDependencies: - '@langchain/core': ^1.1.34 + '@langchain/core': ^1.1.48 - langsmith@0.5.11: - resolution: {integrity: sha512-Yio502Ow2vbVt16P1sybNMNpMsr5BMqoeonoi4flrcDsP55No/aCe2zydtBNOv0+kjKQw4WSKAzTsNwenDeD5w==} + langsmith@0.7.5: + resolution: {integrity: sha512-OeD6+yKtWwy6sAboq25kD5DICzYv7j2KgtV2n4LsJ8nU2LpEdt1UwbjA6BON/zTggmS/YjV2TtLTHd7VEJhtEA==} peerDependencies: '@opentelemetry/api': '*' '@opentelemetry/exporter-trace-otlp-proto': '*' @@ -810,8 +800,8 @@ packages: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} - p-queue@9.1.0: - resolution: {integrity: sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==} + p-queue@9.3.0: + resolution: {integrity: sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==} engines: {node: '>=20'} p-retry@4.6.2: @@ -830,12 +820,8 @@ packages: resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} engines: {node: '>=20'} - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - posthog-node@5.28.4: - resolution: {integrity: sha512-j8JBDNuSwUWR0TBZNuCwNRHQ+OReVz1UwDYMDol+iqFTbYrIKZnyC05oyGtSBRGntrYBiaIWFbH9N3kZuxfVdg==} + posthog-node@5.36.4: + resolution: {integrity: sha512-N+1WiypMHf3SO3NNoXTUFRzX98TuM5w4bDCm8RenYPf0rvX6r8v+yH6IzL1g/Me+wWA5+sfE1JZ6kGV6pWTZyQ==} engines: {node: ^20.20.0 || >=22.22.0} peerDependencies: rxjs: ^7.0.0 @@ -865,22 +851,6 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - simple-wcswidth@1.1.2: - resolution: {integrity: sha512-j7piyCjAeTDSjzTSQ7DokZtMNwNlEAyxqSZeCS+CXH7fJ4jx3FuJ/mTW3mE+6JLs4VJBbcll0Kjn+KXI5t21Iw==} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -900,27 +870,18 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - uuid@10.0.0: - resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} - hasBin: true - - uuid@11.1.0: - resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + uuid@11.1.1: + resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==} hasBin: true - uuid@13.0.0: - resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} + uuid@14.0.0: + resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} hasBin: true web-streams-polyfill@3.3.3: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -1077,9 +1038,9 @@ snapshots: '@esbuild/win32-x64@0.27.4': optional: true - '@google/genai@1.46.0': + '@google/genai@1.52.0': dependencies: - google-auth-library: 10.6.2 + google-auth-library: 10.7.0 p-retry: 4.6.2 protobufjs: 7.5.4 ws: 8.19.0 @@ -1102,18 +1063,14 @@ snapshots: '@js-sdsl/ordered-map@4.4.2': {} - '@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)': + '@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)': dependencies: '@cfworker/json-schema': 4.1.1 '@standard-schema/spec': 1.1.0 - ansi-styles: 5.2.0 - camelcase: 6.3.0 - decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.5.11(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) + langsmith: 0.7.5(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) mustache: 4.2.0 p-queue: 6.6.2 - uuid: 11.1.0 zod: 4.3.6 transitivePeerDependencies: - '@opentelemetry/api' @@ -1122,27 +1079,28 @@ snapshots: - openai - ws - '@langchain/langgraph-checkpoint@1.0.1(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))': + '@langchain/langgraph-checkpoint@1.0.4(@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))': dependencies: - '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) - uuid: 10.0.0 + '@langchain/core': 1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) + uuid: 14.0.0 - '@langchain/langgraph-sdk@1.7.5(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))': + '@langchain/langgraph-sdk@1.9.18(@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))': dependencies: + '@langchain/core': 1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) + '@langchain/protocol': 0.0.16 '@types/json-schema': 7.0.15 - p-queue: 9.1.0 + p-queue: 9.3.0 p-retry: 7.1.1 - uuid: 13.0.0 - optionalDependencies: - '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) + uuid: 14.0.0 - '@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))(zod@4.3.6)': + '@langchain/langgraph@1.3.6(@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))(zod@4.3.6)': dependencies: - '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) - '@langchain/langgraph-checkpoint': 1.0.1(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)) - '@langchain/langgraph-sdk': 1.7.5(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)) + '@langchain/core': 1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) + '@langchain/langgraph-checkpoint': 1.0.4(@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)) + '@langchain/langgraph-sdk': 1.9.18(@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)) + '@langchain/protocol': 0.0.16 '@standard-schema/spec': 1.1.0 - uuid: 10.0.0 + uuid: 14.0.0 zod: 4.3.6 transitivePeerDependencies: - react @@ -1150,6 +1108,8 @@ snapshots: - svelte - vue + '@langchain/protocol@0.0.16': {} + '@opentelemetry/api-logs@0.213.0': dependencies: '@opentelemetry/api': 1.9.0 @@ -1387,25 +1347,25 @@ snapshots: '@opentelemetry/semantic-conventions@1.40.0': {} - '@posthog/ai@7.12.1(@ai-sdk/provider@3.0.8)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-http@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(posthog-node@5.28.4)(ws@8.19.0)': + '@posthog/ai@7.20.14(@ai-sdk/provider@3.0.8)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-http@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(posthog-node@5.36.4)(ws@8.19.0)': dependencies: '@anthropic-ai/sdk': 0.78.0(zod@4.3.6) - '@google/genai': 1.46.0 - '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) - '@posthog/core': 1.24.0 - langchain: 1.2.35(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) + '@google/genai': 1.52.0 + '@langchain/core': 1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) + '@posthog/core': 1.30.10 + langchain: 1.4.4(@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) openai: 6.32.0(ws@8.19.0)(zod@4.3.6) - posthog-node: 5.28.4 - uuid: 11.1.0 + posthog-node: 5.36.4 + uuid: 11.1.1 zod: 4.3.6 optionalDependencies: '@ai-sdk/provider': 3.0.8 '@opentelemetry/api': 1.9.0 '@opentelemetry/exporter-trace-otlp-http': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) transitivePeerDependencies: - '@modelcontextprotocol/sdk' - '@opentelemetry/exporter-trace-otlp-proto' - - '@opentelemetry/sdk-trace-base' - bufferutil - react - react-dom @@ -1416,9 +1376,11 @@ snapshots: - ws - zod-to-json-schema - '@posthog/core@1.24.0': + '@posthog/core@1.30.10': dependencies: - cross-spawn: 7.0.6 + '@posthog/types': 1.382.0 + + '@posthog/types@1.382.0': {} '@protobufjs/aspromise@1.1.2': {} @@ -1453,8 +1415,6 @@ snapshots: '@types/retry@0.12.0': {} - '@types/uuid@10.0.0': {} - '@vercel/oidc@3.1.0': {} acorn-import-attributes@1.9.5(acorn@8.16.0): @@ -1479,18 +1439,12 @@ snapshots: dependencies: color-convert: 2.0.1 - ansi-styles@5.2.0: {} - base64-js@1.5.1: {} bignumber.js@9.3.1: {} buffer-equal-constant-time@1.0.1: {} - camelcase@6.3.0: {} - - chalk@5.6.2: {} - cjs-module-lexer@2.2.0: {} cliui@8.0.1: @@ -1505,24 +1459,12 @@ snapshots: color-name@1.1.4: {} - console-table-printer@2.15.0: - dependencies: - simple-wcswidth: 1.1.2 - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - data-uri-to-buffer@4.0.1: {} debug@4.4.3: dependencies: ms: 2.1.3 - decamelize@1.2.0: {} - dotenv@17.3.1: {} ecdsa-sig-formatter@1.0.11: @@ -1582,7 +1524,7 @@ snapshots: fsevents@2.3.3: optional: true - gaxios@7.1.4: + gaxios@7.1.5: dependencies: extend: 3.0.2 https-proxy-agent: 7.0.6 @@ -1592,7 +1534,7 @@ snapshots: gcp-metadata@8.1.2: dependencies: - gaxios: 7.1.4 + gaxios: 7.1.5 google-logging-utils: 1.1.3 json-bigint: 1.0.0 transitivePeerDependencies: @@ -1604,11 +1546,11 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - google-auth-library@10.6.2: + google-auth-library@10.7.0: dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 - gaxios: 7.1.4 + gaxios: 7.1.5 gcp-metadata: 8.1.2 google-logging-utils: 1.1.3 jws: 4.0.1 @@ -1633,9 +1575,7 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-network-error@1.3.1: {} - - isexe@2.0.0: {} + is-network-error@1.3.2: {} js-tiktoken@1.0.21: dependencies: @@ -1663,13 +1603,12 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 - langchain@1.2.35(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0): + langchain@1.4.4(@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0): dependencies: - '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) - '@langchain/langgraph': 1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))(zod@4.3.6) - '@langchain/langgraph-checkpoint': 1.0.1(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)) - langsmith: 0.5.11(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) - uuid: 11.1.0 + '@langchain/core': 1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) + '@langchain/langgraph': 1.3.6(@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0))(zod@4.3.6) + '@langchain/langgraph-checkpoint': 1.0.4(@langchain/core@1.1.48(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0)) + langsmith: 0.7.5(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0) zod: 4.3.6 transitivePeerDependencies: - '@opentelemetry/api' @@ -1683,14 +1622,9 @@ snapshots: - ws - zod-to-json-schema - langsmith@0.5.11(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0): + langsmith@0.7.5(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.19.0)(zod@4.3.6))(ws@8.19.0): dependencies: - '@types/uuid': 10.0.0 - chalk: 5.6.2 - console-table-printer: 2.15.0 p-queue: 6.6.2 - semver: 7.7.4 - uuid: 10.0.0 optionalDependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/exporter-trace-otlp-proto': 0.213.0(@opentelemetry/api@1.9.0) @@ -1728,7 +1662,7 @@ snapshots: eventemitter3: 4.0.7 p-timeout: 3.2.0 - p-queue@9.1.0: + p-queue@9.3.0: dependencies: eventemitter3: 5.0.4 p-timeout: 7.0.1 @@ -1740,7 +1674,7 @@ snapshots: p-retry@7.1.1: dependencies: - is-network-error: 1.3.1 + is-network-error: 1.3.2 p-timeout@3.2.0: dependencies: @@ -1748,11 +1682,9 @@ snapshots: p-timeout@7.0.1: {} - path-key@3.1.1: {} - - posthog-node@5.28.4: + posthog-node@5.36.4: dependencies: - '@posthog/core': 1.24.0 + '@posthog/core': 1.30.10 protobufjs@7.5.4: dependencies: @@ -1784,16 +1716,6 @@ snapshots: safe-buffer@5.2.1: {} - semver@7.7.4: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - simple-wcswidth@1.1.2: {} - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -1815,18 +1737,12 @@ snapshots: undici-types@7.18.2: {} - uuid@10.0.0: {} + uuid@11.1.1: {} - uuid@11.1.0: {} - - uuid@13.0.0: {} + uuid@14.0.0: {} web-streams-polyfill@3.3.3: {} - which@2.0.2: - dependencies: - isexe: 2.0.0 - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 diff --git a/scripts/link_local_ai_sdk.sh b/scripts/link_local_ai_sdk.sh new file mode 100755 index 0000000..486db23 --- /dev/null +++ b/scripts/link_local_ai_sdk.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# Builds @posthog/ai from a local posthog-js checkout and links it (plus the +# matching posthog-node) into this repo, so the Node scripts run against an +# unreleased SDK build instead of the published version pinned in package.json. +# +# ./scripts/link_local_ai_sdk.sh # uses ../posthog-js +# POSTHOG_JS_PATH=/path/to/posthog-js ./scripts/link_local_ai_sdk.sh +# +# This rewrites package.json's @posthog/ai / posthog-node entries to link: paths +# (a local-only change — don't commit it). Restore the published versions with: +# git checkout -- package.json pnpm-lock.yaml && pnpm install +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +JS_PATH="$(cd "${POSTHOG_JS_PATH:-$REPO_ROOT/../posthog-js}" 2>/dev/null && pwd || true)" + +if [ -z "$JS_PATH" ] || [ ! -d "$JS_PATH/packages/ai" ]; then + echo "error: @posthog/ai not found under '${POSTHOG_JS_PATH:-../posthog-js}'." >&2 + echo "Set POSTHOG_JS_PATH to your local posthog-js checkout." >&2 + exit 1 +fi + +echo "==> Building @posthog/ai (and workspace deps) in $JS_PATH" +( cd "$JS_PATH" && CI=true pnpm --filter "@posthog/ai..." build ) + +echo "==> Linking @posthog/ai + posthog-node from $JS_PATH into $REPO_ROOT" +( cd "$REPO_ROOT" && pnpm add \ + "@posthog/ai@link:$JS_PATH/packages/ai" \ + "posthog-node@link:$JS_PATH/packages/node" ) + +echo "==> Done. package.json now links to your local build (don't commit it)." +echo " Restore the published SDK with:" +echo " git checkout -- package.json pnpm-lock.yaml && pnpm install" diff --git a/scripts/test_posthog_ai_sdk.ts b/scripts/test_posthog_ai_sdk.ts new file mode 100644 index 0000000..a2d5c22 --- /dev/null +++ b/scripts/test_posthog_ai_sdk.ts @@ -0,0 +1,137 @@ +#!/usr/bin/env npx tsx +/** + * Smoke test for the restructured @posthog/ai package (subpath imports + + * optional peer dependencies). See PostHog/posthog-js#3739. + * + * Each provider client now ships under its own subpath, and you install only + * the provider SDK you actually use: + * - @posthog/ai/openai (peer: openai) + * - @posthog/ai/anthropic (peer: @anthropic-ai/sdk) + * The SDK-agnostic primitive captureAiGeneration stays on the root export and + * needs no provider SDK. + * + * Usage: + * npx tsx scripts/test_posthog_ai_sdk.ts # run every applicable demo + * + * Demos requiring a provider key are skipped when the key is absent; + * captureAiGeneration always runs since it makes no network call to a provider. + */ + +import * as dotenv from 'dotenv'; +import * as path from 'path'; +import { fileURLToPath } from 'url'; +import { PostHog } from 'posthog-node'; +import { OpenAI } from '@posthog/ai/openai'; +import { Anthropic } from '@posthog/ai/anthropic'; +import { captureAiGeneration } from '@posthog/ai'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +dotenv.config({ path: path.join(__dirname, '..', '.env') }); + +const DISTINCT_ID = process.env.POSTHOG_DISTINCT_ID || 'posthog-ai-sdk-test'; + +function header(title: string): void { + console.log(`\n${'='.repeat(60)}`); + console.log(` ${title}`); + console.log('='.repeat(60)); +} + +async function demoOpenAI(phClient: PostHog): Promise { + header('@posthog/ai/openai — wrapped OpenAI client'); + if (!process.env.OPENAI_API_KEY) { + console.log(' SKIPPED: OPENAI_API_KEY not set'); + return; + } + + const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY, posthog: phClient }); + const completion = await client.chat.completions.create({ + model: 'gpt-4o-mini', + messages: [{ role: 'user', content: 'Reply with exactly: pong' }], + posthogDistinctId: DISTINCT_ID, + posthogProperties: { source: 'test_posthog_ai_sdk', integration: 'openai-subpath' }, + }); + console.log(` Response: ${completion.choices[0]?.message?.content}`); +} + +async function demoAnthropic(phClient: PostHog): Promise { + header('@posthog/ai/anthropic — wrapped Anthropic client'); + if (!process.env.ANTHROPIC_API_KEY) { + console.log(' SKIPPED: ANTHROPIC_API_KEY not set'); + return; + } + + const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY, posthog: phClient }); + const message = await client.messages.create({ + model: 'claude-sonnet-4-5-20250929', + max_tokens: 32, + messages: [{ role: 'user', content: 'Reply with exactly: pong' }], + posthogDistinctId: DISTINCT_ID, + posthogProperties: { source: 'test_posthog_ai_sdk', integration: 'anthropic-subpath' }, + }); + if (!('content' in message)) { + console.log(' (unexpected streamed response)'); + return; + } + const block = message.content[0]; + console.log(` Response: ${block?.type === 'text' ? block.text : ''}`); +} + +async function demoCaptureAiGeneration(phClient: PostHog): Promise { + header('captureAiGeneration — custom/unsupported provider'); + + const start = Date.now(); + const messages = [{ role: 'user', content: 'Summarize PostHog in one word.' }]; + const output = 'Observability'; + + await captureAiGeneration(phClient, { + distinctId: DISTINCT_ID, + traceId: 'posthog-ai-sdk-test-trace', + provider: 'custom-http-provider', + model: 'made-up-model-v1', + input: messages, + output, + modelParameters: { temperature: 0.2 }, + usage: { inputTokens: 12, outputTokens: 1 }, + latency: (Date.now() - start) / 1000, + properties: { source: 'test_posthog_ai_sdk', integration: 'captureAiGeneration' }, + }); + console.log(` Captured $ai_generation for custom provider (output: "${output}")`); +} + +async function main(): Promise { + const projectToken = process.env.POSTHOG_API_KEY; + const host = process.env.POSTHOG_HOST || 'https://us.i.posthog.com'; + + if (!projectToken) { + console.error('ERROR: POSTHOG_API_KEY must be set in .env'); + process.exit(1); + } + + console.log('@posthog/ai subpath + captureAiGeneration smoke test'); + console.log(` PostHog host: ${host}`); + console.log(` Distinct ID: ${DISTINCT_ID}`); + + const phClient = new PostHog(projectToken, { host, flushAt: 1, flushInterval: 0 }); + + for (const demo of [demoOpenAI, demoAnthropic, demoCaptureAiGeneration]) { + try { + await demo(phClient); + } catch (e: unknown) { + const err = e instanceof Error ? e : new Error(String(e)); + console.log(` FAILED: ${err.constructor.name}: ${err.message}`); + } + } + + await phClient.shutdown(); + + console.log(`\n${'='.repeat(60)}`); + console.log(' Done. Check PostHog -> LLM analytics -> Traces'); + console.log('='.repeat(60) + '\n'); +} + +main().catch((e) => { + console.error('Fatal error:', e); + process.exit(1); +}); diff --git a/scripts/test_vercel_ai_otel.ts b/scripts/test_vercel_ai_otel.ts index c11d98e..b25b2fe 100644 --- a/scripts/test_vercel_ai_otel.ts +++ b/scripts/test_vercel_ai_otel.ts @@ -2,8 +2,10 @@ /** * E2E test script for OTel -> PostHog mapping with Vercel AI SDK. * - * Runs real Vercel AI SDK scenarios and sends OTel spans to PostHog for manual - * verification. Each scenario exercises a different feature of the framework. + * Runs real Vercel AI SDK scenarios and ships OTel spans to PostHog via the + * SDK's `PostHogSpanProcessor` (from `@posthog/ai/otel`). The processor filters + * to AI spans and exports them to PostHog's OTLP endpoint internally, so no + * manual exporter/URL wiring is needed. Each scenario exercises a feature. * * Usage: * npx tsx scripts/test_vercel_ai_otel.ts # Run all scenarios @@ -15,8 +17,8 @@ import * as dotenv from 'dotenv'; import * as path from 'path'; import { fileURLToPath } from 'url'; import { NodeSDK } from '@opentelemetry/sdk-node'; -import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { resourceFromAttributes } from '@opentelemetry/resources'; +import { PostHogSpanProcessor } from '@posthog/ai/otel'; import { generateText, streamText, generateObject } from 'ai'; import { createOpenAI } from '@ai-sdk/openai'; import { z } from 'zod'; @@ -31,11 +33,11 @@ const MODEL = 'gpt-4o-mini'; let otelSdk: NodeSDK | null = null; function setupOtel(): NodeSDK { - const posthogApiKey = process.env.POSTHOG_API_KEY; - const posthogHost = process.env.POSTHOG_HOST || 'http://localhost:8010'; + const projectToken = process.env.POSTHOG_API_KEY; + const host = process.env.POSTHOG_HOST || 'http://localhost:8010'; const debug = process.env.DEBUG === '1'; - if (!posthogApiKey) { + if (!projectToken) { console.error('ERROR: POSTHOG_API_KEY must be set in .env'); process.exit(1); } @@ -48,16 +50,9 @@ function setupOtel(): NodeSDK { resourceAttrs['posthog.ai.debug'] = 'true'; } - const exporter = new OTLPTraceExporter({ - url: `${posthogHost}/i/v0/ai/otel`, - headers: { - Authorization: `Bearer ${posthogApiKey}`, - }, - }); - const sdk = new NodeSDK({ resource: resourceFromAttributes(resourceAttrs), - traceExporter: exporter, + spanProcessors: [new PostHogSpanProcessor({ projectToken, host })], }); sdk.start(); return sdk;