diff --git a/e2e/scenarios/nextjs-instrumentation/.gitignore b/e2e/scenarios/nextjs-instrumentation/.gitignore new file mode 100644 index 000000000..64abd8f54 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/.gitignore @@ -0,0 +1,3 @@ +.next +node_modules + diff --git a/e2e/scenarios/nextjs-instrumentation/__snapshots__/otel-spans.json b/e2e/scenarios/nextjs-instrumentation/__snapshots__/otel-spans.json new file mode 100644 index 000000000..af6044a69 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/__snapshots__/otel-spans.json @@ -0,0 +1,20 @@ +[ + { + "attributes": { + "runtime": "nodejs", + "scenario": "nextjs-instrumentation", + "testRunId": "" + }, + "hasParent": false, + "name": "nextjs nodejs otel span" + }, + { + "attributes": { + "runtime": "edge", + "scenario": "nextjs-instrumentation", + "testRunId": "" + }, + "hasParent": true, + "name": "nextjs edge otel span" + } +] diff --git a/e2e/scenarios/nextjs-instrumentation/__snapshots__/request-flow.json b/e2e/scenarios/nextjs-instrumentation/__snapshots__/request-flow.json new file mode 100644 index 000000000..c680ab252 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/__snapshots__/request-flow.json @@ -0,0 +1,348 @@ +[ + { + "headers": { + "content-type": "application/json" + }, + "jsonBody": null, + "method": "POST", + "path": "/api/apikey/login", + "query": null, + "rawBody": null + }, + { + "headers": { + "content-type": "application/json" + }, + "jsonBody": { + "org_id": "mock-org-id", + "project_name": "e2e-nextjs-instrumentation-nodejs-e2e-" + }, + "method": "POST", + "path": "/api/project/register", + "query": null, + "rawBody": "{\"project_name\":\"e2e-nextjs-instrumentation-nodejs-e2e-\",\"org_id\":\"mock-org-id\"}" + }, + { + "headers": { + "content-type": "application/json" + }, + "jsonBody": { + "api_version": 2, + "rows": [ + { + "_is_merge": false, + "context": {}, + "created": "", + "id": "", + "input": { + "route": "/api/smoke-test/node", + "runtime": "nodejs" + }, + "log_id": "g", + "metadata": { + "runtime": "nodejs", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "metrics": { + "start": 0 + }, + "project_id": "", + "root_span_id": "", + "span_attributes": { + "exec_counter": 0, + "name": "nextjs nodejs logger span", + "type": "task" + }, + "span_id": "" + } + ] + }, + "method": "POST", + "path": "/logs3", + "query": null, + "rawBody": { + "api_version": 2, + "rows": [ + { + "_is_merge": false, + "context": {}, + "created": "", + "id": "", + "input": { + "route": "/api/smoke-test/node", + "runtime": "nodejs" + }, + "log_id": "g", + "metadata": { + "runtime": "nodejs", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "metrics": { + "start": 0 + }, + "project_id": "", + "root_span_id": "", + "span_attributes": { + "exec_counter": 0, + "name": "nextjs nodejs logger span", + "type": "task" + }, + "span_id": "" + } + ] + } + }, + { + "headers": { + "content-type": "application/json" + }, + "jsonBody": { + "api_version": 2, + "rows": [ + { + "_is_merge": true, + "id": "", + "input": { + "route": "/api/smoke-test/node", + "runtime": "nodejs" + }, + "log_id": "g", + "metadata": { + "runtime": "nodejs", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "metrics": { + "end": 0 + }, + "output": { + "ok": true, + "route": "/api/smoke-test/node", + "runtime": "nodejs" + }, + "project_id": "", + "root_span_id": "", + "span_id": "" + } + ] + }, + "method": "POST", + "path": "/logs3", + "query": null, + "rawBody": { + "api_version": 2, + "rows": [ + { + "_is_merge": true, + "id": "", + "input": { + "route": "/api/smoke-test/node", + "runtime": "nodejs" + }, + "log_id": "g", + "metadata": { + "runtime": "nodejs", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "metrics": { + "end": 0 + }, + "output": { + "ok": true, + "route": "/api/smoke-test/node", + "runtime": "nodejs" + }, + "project_id": "", + "root_span_id": "", + "span_id": "" + } + ] + } + }, + { + "headers": { + "content-type": "application/json", + "x-bt-parent": "" + }, + "jsonBody": "", + "method": "POST", + "path": "/otel/v1/traces", + "query": null, + "rawBody": "" + }, + { + "headers": { + "content-type": "application/json" + }, + "jsonBody": { + "org_id": "mock-org-id", + "project_name": "e2e-nextjs-instrumentation-edge-e2e-" + }, + "method": "POST", + "path": "/api/project/register", + "query": null, + "rawBody": "{\"project_name\":\"e2e-nextjs-instrumentation-edge-e2e-\",\"org_id\":\"mock-org-id\"}" + }, + { + "headers": { + "content-type": "application/json" + }, + "jsonBody": { + "api_version": 2, + "rows": [ + { + "_is_merge": false, + "context": {}, + "created": "", + "id": "", + "input": { + "route": "/api/smoke-test/edge", + "runtime": "edge" + }, + "log_id": "g", + "metadata": { + "runtime": "edge", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "metrics": { + "start": 0 + }, + "project_id": "", + "root_span_id": "", + "span_attributes": { + "exec_counter": 0, + "name": "nextjs edge logger span", + "type": "task" + }, + "span_id": "" + } + ] + }, + "method": "POST", + "path": "/logs3", + "query": null, + "rawBody": { + "api_version": 2, + "rows": [ + { + "_is_merge": false, + "context": {}, + "created": "", + "id": "", + "input": { + "route": "/api/smoke-test/edge", + "runtime": "edge" + }, + "log_id": "g", + "metadata": { + "runtime": "edge", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "metrics": { + "start": 0 + }, + "project_id": "", + "root_span_id": "", + "span_attributes": { + "exec_counter": 0, + "name": "nextjs edge logger span", + "type": "task" + }, + "span_id": "" + } + ] + } + }, + { + "headers": { + "content-type": "application/json" + }, + "jsonBody": { + "api_version": 2, + "rows": [ + { + "_is_merge": true, + "id": "", + "input": { + "route": "/api/smoke-test/edge", + "runtime": "edge" + }, + "log_id": "g", + "metadata": { + "runtime": "edge", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "metrics": { + "end": 0 + }, + "output": { + "ok": true, + "route": "/api/smoke-test/edge", + "runtime": "edge" + }, + "project_id": "", + "root_span_id": "", + "span_id": "" + } + ] + }, + "method": "POST", + "path": "/logs3", + "query": null, + "rawBody": { + "api_version": 2, + "rows": [ + { + "_is_merge": true, + "id": "", + "input": { + "route": "/api/smoke-test/edge", + "runtime": "edge" + }, + "log_id": "g", + "metadata": { + "runtime": "edge", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "metrics": { + "end": 0 + }, + "output": { + "ok": true, + "route": "/api/smoke-test/edge", + "runtime": "edge" + }, + "project_id": "", + "root_span_id": "", + "span_id": "" + } + ] + } + }, + { + "headers": { + "content-type": "application/json", + "x-bt-parent": "" + }, + "jsonBody": "", + "method": "POST", + "path": "/otel/v1/traces", + "query": null, + "rawBody": "" + } +] diff --git a/e2e/scenarios/nextjs-instrumentation/__snapshots__/route-responses.json b/e2e/scenarios/nextjs-instrumentation/__snapshots__/route-responses.json new file mode 100644 index 000000000..193608596 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/__snapshots__/route-responses.json @@ -0,0 +1,30 @@ +[ + { + "body": { + "instrumentationRegistered": true, + "loggerSpanName": "nextjs edge logger span", + "otelSpanName": "nextjs edge otel span", + "projectName": "e2e-nextjs-instrumentation-edge-e2e-", + "route": "/api/smoke-test/edge", + "runtime": "edge", + "success": true, + "testRunId": "" + }, + "runtime": "edge", + "status": 200 + }, + { + "body": { + "instrumentationRegistered": false, + "loggerSpanName": "nextjs nodejs logger span", + "otelSpanName": "nextjs nodejs otel span", + "projectName": "e2e-nextjs-instrumentation-nodejs-e2e-", + "route": "/api/smoke-test/node", + "runtime": "nodejs", + "success": true, + "testRunId": "" + }, + "runtime": "nodejs", + "status": 200 + } +] diff --git a/e2e/scenarios/nextjs-instrumentation/__snapshots__/span-events.json b/e2e/scenarios/nextjs-instrumentation/__snapshots__/span-events.json new file mode 100644 index 000000000..28f671eb2 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/__snapshots__/span-events.json @@ -0,0 +1,56 @@ +[ + { + "error": null, + "input": { + "route": "/api/smoke-test/edge", + "runtime": "edge" + }, + "metadata": { + "runtime": "edge", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "name": "nextjs edge logger span", + "output": { + "ok": true, + "route": "/api/smoke-test/edge", + "runtime": "edge" + }, + "root_span_id": "", + "span_attributes": { + "exec_counter": 0, + "name": "nextjs edge logger span", + "type": "task" + }, + "span_id": "", + "span_parents": null + }, + { + "error": null, + "input": { + "route": "/api/smoke-test/node", + "runtime": "nodejs" + }, + "metadata": { + "runtime": "nodejs", + "scenario": "nextjs-instrumentation", + "testRunId": "", + "transport": "http" + }, + "name": "nextjs nodejs logger span", + "output": { + "ok": true, + "route": "/api/smoke-test/node", + "runtime": "nodejs" + }, + "root_span_id": "", + "span_attributes": { + "exec_counter": 0, + "name": "nextjs nodejs logger span", + "type": "task" + }, + "span_id": "", + "span_parents": null + } +] diff --git a/e2e/scenarios/nextjs-instrumentation/next-env.d.ts b/e2e/scenarios/nextjs-instrumentation/next-env.d.ts new file mode 100644 index 000000000..28e5a0143 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/next-env.d.ts @@ -0,0 +1,4 @@ +/// +/// + +// This file is auto-generated by Next.js. diff --git a/js/smoke/scenarios/nextjs-instrumentation/next.config.mjs b/e2e/scenarios/nextjs-instrumentation/next.config.mjs similarity index 60% rename from js/smoke/scenarios/nextjs-instrumentation/next.config.mjs rename to e2e/scenarios/nextjs-instrumentation/next.config.mjs index 6c5869a49..27c76c996 100644 --- a/js/smoke/scenarios/nextjs-instrumentation/next.config.mjs +++ b/e2e/scenarios/nextjs-instrumentation/next.config.mjs @@ -1,8 +1,14 @@ /** @type {import('next').NextConfig} */ const nextConfig = { + eslint: { + ignoreDuringBuilds: true, + }, experimental: { instrumentationHook: true, }, + typescript: { + ignoreBuildErrors: true, + }, }; export default nextConfig; diff --git a/e2e/scenarios/nextjs-instrumentation/package.json b/e2e/scenarios/nextjs-instrumentation/package.json new file mode 100644 index 000000000..2017e3a1f --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/package.json @@ -0,0 +1,20 @@ +{ + "name": "@braintrust/e2e-nextjs-instrumentation", + "private": true, + "dependencies": { + "@opentelemetry/api": "1.9.0", + "@opentelemetry/core": "2.0.0", + "@opentelemetry/exporter-trace-otlp-http": "0.200.0", + "@opentelemetry/sdk-trace-base": "2.0.0", + "@vercel/otel": "2.1.0", + "next": "14.2.34", + "react": "18.3.1", + "react-dom": "18.3.1" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "typescript": "5.4.4" + } +} diff --git a/e2e/scenarios/nextjs-instrumentation/pnpm-lock.yaml b/e2e/scenarios/nextjs-instrumentation/pnpm-lock.yaml new file mode 100644 index 000000000..884315944 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/pnpm-lock.yaml @@ -0,0 +1,673 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@opentelemetry/api': + specifier: 1.9.0 + version: 1.9.0 + '@opentelemetry/core': + specifier: 2.0.0 + version: 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': + specifier: 0.200.0 + version: 0.200.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': + specifier: 2.0.0 + version: 2.0.0(@opentelemetry/api@1.9.0) + '@vercel/otel': + specifier: 2.1.0 + version: 2.1.0(@opentelemetry/api-logs@0.200.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.0.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.200.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@2.0.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.0(@opentelemetry/api@1.9.0)) + next: + specifier: 14.2.34 + version: 14.2.34(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: + specifier: 18.3.1 + version: 18.3.1 + react-dom: + specifier: 18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@types/node': + specifier: ^20 + version: 20.19.37 + '@types/react': + specifier: ^18 + version: 18.3.28 + '@types/react-dom': + specifier: ^18 + version: 18.3.7(@types/react@18.3.28) + typescript: + specifier: 5.4.4 + version: 5.4.4 + +packages: + + '@next/env@14.2.34': + resolution: {integrity: sha512-iuGW/UM+EZbn2dm+aLx+avo1rVap+ASoFr7oLpTBVW2G2DqhD5l8Fme9IsLZ6TTsp0ozVSFswidiHK1NGNO+pg==} + + '@next/swc-darwin-arm64@14.2.33': + resolution: {integrity: sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@14.2.33': + resolution: {integrity: sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@14.2.33': + resolution: {integrity: sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@14.2.33': + resolution: {integrity: sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@14.2.33': + resolution: {integrity: sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@14.2.33': + resolution: {integrity: sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@14.2.33': + resolution: {integrity: sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-ia32-msvc@14.2.33': + resolution: {integrity: sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@next/swc-win32-x64-msvc@14.2.33': + resolution: {integrity: sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@opentelemetry/api-logs@0.200.0': + resolution: {integrity: sha512-IKJBQxh91qJ+3ssRly5hYEJ8NDHu9oY/B1PXVSCWf7zytmYO9RNLB0Ox9XQ/fJ8m6gY6Q6NtBWlmXfaXt5Uc4Q==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api-logs@0.213.0': + resolution: {integrity: sha512-zRM5/Qj6G84Ej3F1yt33xBVY/3tnMxtL1fiDIxYbDWYaZ/eudVw3/PBiZ8G7JwUxXxjW8gU4g6LnOyfGKYHYgw==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/core@2.0.0': + resolution: {integrity: sha512-SLX36allrcnVaPYG3R78F/UZZsBsvbc7lMCLx37LyH5MJ1KAAZ2E3mW9OAD3zGz0G8q/BtoS5VUrjzDydhD6LQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/exporter-trace-otlp-http@0.200.0': + resolution: {integrity: sha512-Goi//m/7ZHeUedxTGVmEzH19NgqJY+Bzr6zXo1Rni1+hwqaksEyJ44gdlEMREu6dzX1DlAaH/qSykSVzdrdafA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation@0.213.0': + resolution: {integrity: sha512-3i9NdkET/KvQomeh7UaR/F4r9P25Rx6ooALlWXPIjypcEOUxksCmVu0zA70NBJWlrMW1rPr/LRidFAflLI+s/w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-exporter-base@0.200.0': + resolution: {integrity: sha512-IxJgA3FD7q4V6gGq4bnmQM5nTIyMDkoGFGrBrrDjB6onEiq1pafma55V+bHvGYLWvcqbBbRfezr1GED88lacEQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-transformer@0.200.0': + resolution: {integrity: sha512-+9YDZbYybOnv7sWzebWOeK6gKyt2XE7iarSyBFkwwnP559pEevKOUD8NyDHhRjCSp13ybh9iVXlMfcj/DwF/yw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/resources@2.0.0': + resolution: {integrity: sha512-rnZr6dML2z4IARI4zPGQV4arDikF/9OXZQzrC01dLmn0CZxU5U5OLd/m1T7YkGRj5UitjeoCtg/zorlgMQcdTg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-logs@0.200.0': + resolution: {integrity: sha512-VZG870063NLfObmQQNtCVcdXXLzI3vOjjrRENmU37HYiPFa0ZXpXVDsTD02Nh3AT3xYJzQaWKl2X2lQ2l7TWJA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.4.0 <1.10.0' + + '@opentelemetry/sdk-metrics@2.0.0': + resolution: {integrity: sha512-Bvy8QDjO05umd0+j+gDeWcTaVa1/R2lDj/eOvjzpm8VQj1K1vVZJuyjThpV5/lSHyYW2JaHF2IQ7Z8twJFAhjA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.9.0 <1.10.0' + + '@opentelemetry/sdk-trace-base@2.0.0': + resolution: {integrity: sha512-qQnYdX+ZCkonM7tA5iU4fSRsVxbFGml8jbxOgipRGMFHKaXKHQ30js03rTobYjKjIfnOsZSbHKWF0/0v0OQGfw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/semantic-conventions@1.40.0': + resolution: {integrity: sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==} + engines: {node: '>=14'} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.5': + resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} + + '@types/node@20.19.37': + resolution: {integrity: sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react@18.3.28': + resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==} + + '@vercel/otel@2.1.0': + resolution: {integrity: sha512-Zwu2Cu4t46DzBnY1DQSTxZ4MBLVfYsOjnlWuZuLRWnmVPX+SNrVHbs3ssiJ6uvY1J1JJswor4zSn8mHYxzYeBA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.9.0 <2.0.0' + '@opentelemetry/api-logs': '>=0.200.0 <0.300.0' + '@opentelemetry/instrumentation': '>=0.200.0 <0.300.0' + '@opentelemetry/resources': '>=2.0.0 <3.0.0' + '@opentelemetry/sdk-logs': '>=0.200.0 <0.300.0' + '@opentelemetry/sdk-metrics': '>=2.0.0 <3.0.0' + '@opentelemetry/sdk-trace-base': '>=2.0.0 <3.0.0' + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + caniuse-lite@1.0.30001781: + resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==} + + cjs-module-lexer@2.2.0: + resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + import-in-the-middle@3.0.0: + resolution: {integrity: sha512-OnGy+eYT7wVejH2XWgLRgbmzujhhVIATQH0ztIeRilwHBjTeG3pD+XnH3PKX0r9gJ0BuJmJ68q/oh9qgXnNDQg==} + engines: {node: '>=18'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + module-details-from-path@1.0.4: + resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + next@14.2.34: + resolution: {integrity: sha512-s7mRraWlkEVRLjHHdu5khn0bSnmUh+U+YtigBc+t2Ge7jJHFIVBZna+W9Jcx7b04HhM7eJWrNJ2A+sQs9gJ3eg==} + engines: {node: '>=18.17.0'} + deprecated: This version has a security vulnerability. Please upgrade to a patched version. See https://nextjs.org/blog/security-update-2025-12-11 for more details. + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + sass: + optional: true + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + protobufjs@7.5.4: + resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} + engines: {node: '>=12.0.0'} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + require-in-the-middle@8.0.1: + resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==} + engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + styled-jsx@5.1.1: + resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@5.4.4: + resolution: {integrity: sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + +snapshots: + + '@next/env@14.2.34': {} + + '@next/swc-darwin-arm64@14.2.33': + optional: true + + '@next/swc-darwin-x64@14.2.33': + optional: true + + '@next/swc-linux-arm64-gnu@14.2.33': + optional: true + + '@next/swc-linux-arm64-musl@14.2.33': + optional: true + + '@next/swc-linux-x64-gnu@14.2.33': + optional: true + + '@next/swc-linux-x64-musl@14.2.33': + optional: true + + '@next/swc-win32-arm64-msvc@14.2.33': + optional: true + + '@next/swc-win32-ia32-msvc@14.2.33': + optional: true + + '@next/swc-win32-x64-msvc@14.2.33': + optional: true + + '@opentelemetry/api-logs@0.200.0': + dependencies: + '@opentelemetry/api': 1.9.0 + + '@opentelemetry/api-logs@0.213.0': + dependencies: + '@opentelemetry/api': 1.9.0 + + '@opentelemetry/api@1.9.0': {} + + '@opentelemetry/core@2.0.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/exporter-trace-otlp-http@0.200.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.200.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.200.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/instrumentation@0.213.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.213.0 + import-in-the-middle: 3.0.0 + require-in-the-middle: 8.0.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/otlp-exporter-base@0.200.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.200.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/otlp-transformer@0.200.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.200.0 + '@opentelemetry/core': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.200.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.0(@opentelemetry/api@1.9.0) + protobufjs: 7.5.4 + + '@opentelemetry/resources@2.0.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/sdk-logs@0.200.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.200.0 + '@opentelemetry/core': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-metrics@2.0.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-trace-base@2.0.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/semantic-conventions@1.40.0': {} + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.5': + dependencies: + '@swc/counter': 0.1.3 + tslib: 2.8.1 + + '@types/node@20.19.37': + dependencies: + undici-types: 6.21.0 + + '@types/prop-types@15.7.15': {} + + '@types/react-dom@18.3.7(@types/react@18.3.28)': + dependencies: + '@types/react': 18.3.28 + + '@types/react@18.3.28': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.2.3 + + '@vercel/otel@2.1.0(@opentelemetry/api-logs@0.200.0)(@opentelemetry/api@1.9.0)(@opentelemetry/instrumentation@0.213.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.0.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-logs@0.200.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-metrics@2.0.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.0.0(@opentelemetry/api@1.9.0))': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.200.0 + '@opentelemetry/instrumentation': 0.213.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.200.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.0(@opentelemetry/api@1.9.0) + + acorn-import-attributes@1.9.5(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + caniuse-lite@1.0.30001781: {} + + cjs-module-lexer@2.2.0: {} + + client-only@0.0.1: {} + + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + graceful-fs@4.2.11: {} + + import-in-the-middle@3.0.0: + dependencies: + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) + cjs-module-lexer: 2.2.0 + module-details-from-path: 1.0.4 + + js-tokens@4.0.0: {} + + long@5.3.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + module-details-from-path@1.0.4: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + next@14.2.34(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@next/env': 14.2.34 + '@swc/helpers': 0.5.5 + busboy: 1.6.0 + caniuse-lite: 1.0.30001781 + graceful-fs: 4.2.11 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.1(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 14.2.33 + '@next/swc-darwin-x64': 14.2.33 + '@next/swc-linux-arm64-gnu': 14.2.33 + '@next/swc-linux-arm64-musl': 14.2.33 + '@next/swc-linux-x64-gnu': 14.2.33 + '@next/swc-linux-x64-musl': 14.2.33 + '@next/swc-win32-arm64-msvc': 14.2.33 + '@next/swc-win32-ia32-msvc': 14.2.33 + '@next/swc-win32-x64-msvc': 14.2.33 + '@opentelemetry/api': 1.9.0 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + picocolors@1.1.1: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + protobufjs@7.5.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 20.19.37 + long: 5.3.2 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + require-in-the-middle@8.0.1: + dependencies: + debug: 4.4.3 + module-details-from-path: 1.0.4 + transitivePeerDependencies: + - supports-color + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + source-map-js@1.2.1: {} + + streamsearch@1.1.0: {} + + styled-jsx@5.1.1(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + + tslib@2.8.1: {} + + typescript@5.4.4: {} + + undici-types@6.21.0: {} diff --git a/e2e/scenarios/nextjs-instrumentation/scenario.test.ts b/e2e/scenarios/nextjs-instrumentation/scenario.test.ts new file mode 100644 index 000000000..99c91a77c --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/scenario.test.ts @@ -0,0 +1,220 @@ +import { expect, test } from "vitest"; +import { + formatJsonFileSnapshot, + resolveFileSnapshotPath, +} from "../../helpers/file-snapshot"; +import type { Json } from "../../helpers/normalize"; +import { + prepareScenarioDir, + resolveScenarioDir, + withScenarioHarness, +} from "../../helpers/scenario-harness"; +import { E2E_TAGS } from "../../helpers/tags"; +import { + extractOtelSpans, + summarizeEvent, + summarizeRequest, +} from "../../helpers/trace-summary"; +import { findLatestSpan } from "../../helpers/trace-selectors"; + +const scenarioDir = await prepareScenarioDir({ + scenarioDir: resolveScenarioDir(import.meta.url), +}); + +const TIMEOUT_MS = 180_000; +const RESULT_MARKER = "NEXTJS_E2E_RESULT "; + +type RuntimeResponse = { + body: { + instrumentationRegistered: boolean; + loggerSpanName: string; + otelSpanName: string; + projectName: string; + route: string; + runtime: "edge" | "nodejs"; + success: boolean; + testRunId: string; + }; + runtime: "edge" | "nodejs"; + status: number; +}; + +function parseScenarioResponses(stdout: string): RuntimeResponse[] { + const line = stdout + .split("\n") + .find((entry) => entry.startsWith(RESULT_MARKER)); + + if (!line) { + throw new Error(`Scenario output did not contain ${RESULT_MARKER}`); + } + + return JSON.parse(line.slice(RESULT_MARKER.length)) as RuntimeResponse[]; +} + +test( + "nextjs-instrumentation builds a Next.js app and captures Node and Edge runtime traces", + { + tags: [E2E_TAGS.hermetic], + timeout: TIMEOUT_MS, + }, + async () => { + await withScenarioHarness( + async ({ + requestCursor, + requestsAfter, + runScenarioDir, + testRunEvents, + testRunId, + }) => { + const cursor = requestCursor(); + const result = await runScenarioDir({ + scenarioDir, + timeoutMs: TIMEOUT_MS, + }); + const responses = parseScenarioResponses(result.stdout); + + expect(responses).toHaveLength(2); + expect(responses.map((response) => response.runtime).sort()).toEqual([ + "edge", + "nodejs", + ]); + + for (const response of responses) { + expect(response.status).toBe(200); + expect(response.body.success).toBe(true); + expect(response.body.testRunId).toBe(testRunId); + expect(response.body.route).toBe( + `/api/smoke-test/${response.runtime === "nodejs" ? "node" : response.runtime}`, + ); + } + + const events = testRunEvents(); + const edgeSpan = findLatestSpan(events, "nextjs edge logger span"); + const nodeSpan = findLatestSpan(events, "nextjs nodejs logger span"); + + expect(edgeSpan).toBeDefined(); + expect(nodeSpan).toBeDefined(); + expect(edgeSpan?.row.metadata).toMatchObject({ + runtime: "edge", + scenario: "nextjs-instrumentation", + testRunId, + transport: "http", + }); + expect(nodeSpan?.row.metadata).toMatchObject({ + runtime: "nodejs", + scenario: "nextjs-instrumentation", + testRunId, + transport: "http", + }); + + const requests = requestsAfter( + cursor, + (request) => + request.path === "/api/apikey/login" || + request.path === "/api/project/register" || + request.path === "/logs3" || + request.path === "/otel/v1/traces", + ); + + expect(requests.some((request) => request.path === "/logs3")).toBe( + true, + ); + expect( + requests.some((request) => request.path === "/otel/v1/traces"), + ).toBe(true); + + const otelRequests = requests.filter( + (request) => request.path === "/otel/v1/traces", + ); + const otelSpans = otelRequests.flatMap((request) => + extractOtelSpans(request.jsonBody), + ); + + expect(otelSpans.map((span) => span.name)).toContain( + "nextjs edge otel span", + ); + expect(otelSpans.map((span) => span.name)).toContain( + "nextjs nodejs otel span", + ); + + if (otelRequests[0]) { + expect(otelRequests[0].headers["x-bt-parent"]).toContain( + testRunId.toLowerCase().replace(/[^a-z0-9-]/g, "-"), + ); + } + + await expect( + formatJsonFileSnapshot( + responses.map((response) => ({ + body: response.body, + runtime: response.runtime, + status: response.status, + })) as Json, + ), + ).toMatchFileSnapshot( + resolveFileSnapshotPath(import.meta.url, "route-responses.json"), + ); + + await expect( + formatJsonFileSnapshot( + [edgeSpan, nodeSpan].map((event) => summarizeEvent(event!)) as Json, + ), + ).toMatchFileSnapshot( + resolveFileSnapshotPath(import.meta.url, "span-events.json"), + ); + + await expect( + formatJsonFileSnapshot( + otelSpans + .filter( + (span) => + span.name === "nextjs edge otel span" || + span.name === "nextjs nodejs otel span", + ) + .map((span) => ({ + attributes: { + runtime: span.attributes.runtime ?? null, + scenario: span.attributes.scenario ?? null, + testRunId: span.attributes.testRunId ?? null, + }, + hasParent: !!span.parentSpanId, + name: span.name, + })) as Json, + ), + ).toMatchFileSnapshot( + resolveFileSnapshotPath(import.meta.url, "otel-spans.json"), + ); + + await expect( + formatJsonFileSnapshot( + requests.map((request) => { + const summary = summarizeRequest(request, { + includeHeaders: ["content-type", "x-bt-parent"], + normalizeJsonRawBody: request.path === "/logs3", + }) as Record; + + if (request.path === "/otel/v1/traces") { + return { + ...summary, + jsonBody: "", + rawBody: "", + headers: + summary.headers && typeof summary.headers === "object" + ? { + ...(summary.headers as Record), + "x-bt-parent": "", + } + : summary.headers, + }; + } + + return summary; + }) as Json, + ), + ).toMatchFileSnapshot( + resolveFileSnapshotPath(import.meta.url, "request-flow.json"), + ); + }, + ); + }, +); diff --git a/e2e/scenarios/nextjs-instrumentation/scenario.ts b/e2e/scenarios/nextjs-instrumentation/scenario.ts new file mode 100644 index 000000000..15e0af9b2 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/scenario.ts @@ -0,0 +1,181 @@ +import { spawn, spawnSync } from "node:child_process"; +import net from "node:net"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { runMain } from "../../helpers/scenario-runtime"; + +const scenarioDir = path.dirname(fileURLToPath(import.meta.url)); +const nextBin = new URL("./node_modules/next/dist/bin/next", import.meta.url) + .pathname; +const RESULT_MARKER = "NEXTJS_E2E_RESULT "; + +type EndpointResult = { + body: unknown; + runtime: "edge" | "nodejs"; + status: number; +}; + +function withScenarioEnv( + env: NodeJS.ProcessEnv = process.env, +): NodeJS.ProcessEnv { + return { + ...env, + NEXT_TELEMETRY_DISABLED: "1", + NODE_ENV: "production", + }; +} + +function httpErrorBody(text: string): unknown { + try { + return JSON.parse(text) as unknown; + } catch { + return { rawBody: text }; + } +} + +async function getAvailablePort(): Promise { + return await new Promise((resolve, reject) => { + const server = net.createServer(); + server.listen(0, "127.0.0.1", () => { + const address = server.address(); + if (!address || typeof address === "string") { + reject(new Error("Could not determine an available port")); + return; + } + + server.close((error) => { + if (error) { + reject(error); + return; + } + resolve(address.port); + }); + }); + server.on("error", reject); + }); +} + +async function waitForServer( + baseUrl: string, + timeoutMs = 60_000, +): Promise { + const deadline = Date.now() + timeoutMs; + + while (Date.now() < deadline) { + try { + const response = await fetch(baseUrl, { method: "HEAD" }); + if (response.ok || response.status === 404) { + await new Promise((resolve) => setTimeout(resolve, 500)); + return; + } + } catch { + // Server is not ready yet. + } + + await new Promise((resolve) => setTimeout(resolve, 500)); + } + + throw new Error(`Next.js server did not become ready within ${timeoutMs}ms`); +} + +async function callEndpoint( + baseUrl: string, + runtime: "edge" | "nodejs", +): Promise { + const routeRuntime = runtime === "nodejs" ? "node" : runtime; + const response = await fetch(`${baseUrl}/api/smoke-test/${routeRuntime}`); + const text = await response.text(); + return { + body: httpErrorBody(text), + runtime, + status: response.status, + }; +} + +async function main() { + const port = await getAvailablePort(); + const baseUrl = `http://127.0.0.1:${port}`; + const env = withScenarioEnv(process.env); + + const buildResult = spawnSync(process.execPath, [nextBin, "build"], { + cwd: scenarioDir, + stdio: "pipe", + env, + encoding: "utf8", + }); + + if (buildResult.status !== 0) { + throw new Error( + `next build failed with exit code ${buildResult.status}\nSTDOUT:\n${buildResult.stdout}\nSTDERR:\n${buildResult.stderr}`, + ); + } + + const server = spawn( + process.execPath, + [nextBin, "start", "--hostname", "127.0.0.1", "--port", String(port)], + { + cwd: scenarioDir, + env, + stdio: ["ignore", "pipe", "pipe"], + }, + ); + + let stdout = ""; + let stderr = ""; + server.stdout.on("data", (chunk) => { + stdout += chunk.toString(); + }); + server.stderr.on("data", (chunk) => { + stderr += chunk.toString(); + }); + + try { + await waitForServer(baseUrl); + + const responses = await Promise.all([ + callEndpoint(baseUrl, "edge"), + callEndpoint(baseUrl, "nodejs"), + ]); + + await new Promise((resolve) => setTimeout(resolve, 1_000)); + + console.log( + `${RESULT_MARKER}${JSON.stringify( + responses.map((response) => ({ + ...response, + body: response.body, + })), + )}`, + ); + + const failedResponse = responses.find((response) => { + const body = + response.body && typeof response.body === "object" + ? (response.body as { success?: unknown }) + : undefined; + return response.status !== 200 || body?.success !== true; + }); + + if (failedResponse) { + throw new Error( + `Endpoint ${failedResponse.runtime} failed with status ${failedResponse.status}\n${JSON.stringify(failedResponse.body, null, 2)}`, + ); + } + } finally { + server.kill("SIGTERM"); + await new Promise((resolve) => setTimeout(resolve, 1_000)); + + if (server.exitCode === null && !server.killed) { + server.kill("SIGKILL"); + } + + if (stderr.trim()) { + process.stderr.write(stderr); + } + if (stdout.trim()) { + process.stdout.write(stdout); + } + } +} + +runMain(main); diff --git a/e2e/scenarios/nextjs-instrumentation/src/app/api/smoke-test/edge/route.ts b/e2e/scenarios/nextjs-instrumentation/src/app/api/smoke-test/edge/route.ts new file mode 100644 index 000000000..8c7f1d486 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/src/app/api/smoke-test/edge/route.ts @@ -0,0 +1,22 @@ +import { NextResponse } from "next/server"; +import { + formatRouteError, + runRuntimeCheck, +} from "../../../../lib/runtime-check"; + +export const runtime = "edge"; + +export async function GET() { + try { + return NextResponse.json(await runRuntimeCheck("edge")); + } catch (error) { + return NextResponse.json( + { + error: formatRouteError(error), + runtime: "edge", + success: false, + }, + { status: 500 }, + ); + } +} diff --git a/e2e/scenarios/nextjs-instrumentation/src/app/api/smoke-test/node/route.ts b/e2e/scenarios/nextjs-instrumentation/src/app/api/smoke-test/node/route.ts new file mode 100644 index 000000000..3f86b659b --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/src/app/api/smoke-test/node/route.ts @@ -0,0 +1,22 @@ +import { NextResponse } from "next/server"; +import { + formatRouteError, + runRuntimeCheck, +} from "../../../../lib/runtime-check"; + +export const runtime = "nodejs"; + +export async function GET() { + try { + return NextResponse.json(await runRuntimeCheck("nodejs")); + } catch (error) { + return NextResponse.json( + { + error: formatRouteError(error), + runtime: "nodejs", + success: false, + }, + { status: 500 }, + ); + } +} diff --git a/js/smoke/scenarios/nextjs-instrumentation/src/app/layout.tsx b/e2e/scenarios/nextjs-instrumentation/src/app/layout.tsx similarity index 100% rename from js/smoke/scenarios/nextjs-instrumentation/src/app/layout.tsx rename to e2e/scenarios/nextjs-instrumentation/src/app/layout.tsx diff --git a/e2e/scenarios/nextjs-instrumentation/src/app/page.tsx b/e2e/scenarios/nextjs-instrumentation/src/app/page.tsx new file mode 100644 index 000000000..94071fdd9 --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/src/app/page.tsx @@ -0,0 +1,8 @@ +export default function Home() { + return ( +
+

Next.js Instrumentation E2E

+

Hermetic Next.js instrumentation scenario for Braintrust.

+
+ ); +} diff --git a/e2e/scenarios/nextjs-instrumentation/src/instrumentation.ts b/e2e/scenarios/nextjs-instrumentation/src/instrumentation.ts new file mode 100644 index 000000000..9beefd06f --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/src/instrumentation.ts @@ -0,0 +1,21 @@ +import { BraintrustExporter } from "@braintrust/otel"; +import { registerOTel } from "@vercel/otel"; +import { initLogger } from "braintrust"; +import { scopedName } from "./lib/runtime-check"; + +export async function register() { + void initLogger; + ( + globalThis as { __btNextjsInstrumentationRegistered?: boolean } + ).__btNextjsInstrumentationRegistered = true; + + registerOTel({ + serviceName: "nextjs-instrumentation-e2e", + traceExporter: new BraintrustExporter({ + apiKey: process.env.BRAINTRUST_API_KEY!, + apiUrl: process.env.BRAINTRUST_API_URL!, + parent: `project_name:${scopedName("e2e-nextjs-instrumentation")}`, + filterAISpans: false, + }) as any, + }); +} diff --git a/e2e/scenarios/nextjs-instrumentation/src/lib/runtime-check.ts b/e2e/scenarios/nextjs-instrumentation/src/lib/runtime-check.ts new file mode 100644 index 000000000..d651abe4c --- /dev/null +++ b/e2e/scenarios/nextjs-instrumentation/src/lib/runtime-check.ts @@ -0,0 +1,167 @@ +import { BraintrustExporter } from "@braintrust/otel"; +import { trace } from "@opentelemetry/api"; +import { + BasicTracerProvider, + SimpleSpanProcessor, +} from "@opentelemetry/sdk-trace-base"; +import { initLogger } from "braintrust"; + +type Runtime = "edge" | "nodejs"; + +function requiredEnv(name: string): string { + const value = process.env[name]; + if (!value) { + throw new Error(`Missing required environment variable ${name}`); + } + + return value; +} + +export function getTestRunId(): string { + return requiredEnv("BRAINTRUST_E2E_RUN_ID"); +} + +export function scopedName(base: string): string { + const suffix = getTestRunId() + .toLowerCase() + .replace(/[^a-z0-9-]/g, "-"); + return `${base}-${suffix}`; +} + +function createTracerProvider(processors: unknown[]) { + if ( + typeof (new BasicTracerProvider() as { addSpanProcessor?: unknown }) + .addSpanProcessor === "function" + ) { + const provider = new BasicTracerProvider() as { + addSpanProcessor: (processor: unknown) => void; + getTracer: (name: string) => { + startActiveSpan: ( + name: string, + callback: (span: { + end: () => void; + setAttribute: (key: string, value: string) => void; + }) => Promise | void, + ) => Promise; + }; + shutdown?: () => Promise; + }; + processors.forEach((processor) => provider.addSpanProcessor(processor)); + return provider; + } + + return new BasicTracerProvider({ + spanProcessors: processors as never, + }) as { + getTracer: (name: string) => { + startActiveSpan: ( + name: string, + callback: (span: { + end: () => void; + setAttribute: (key: string, value: string) => void; + }) => Promise | void, + ) => Promise; + }; + shutdown?: () => Promise; + }; +} + +async function emitOtelSpan(runtime: Runtime, testRunId: string) { + const exporter = new BraintrustExporter({ + apiKey: requiredEnv("BRAINTRUST_API_KEY"), + apiUrl: requiredEnv("BRAINTRUST_API_URL"), + parent: `project_name:${scopedName("e2e-nextjs-instrumentation")}`, + filterAISpans: false, + }); + + const provider = createTracerProvider([new SimpleSpanProcessor(exporter)]); + trace.setGlobalTracerProvider(provider as never); + + await provider + .getTracer("nextjs-instrumentation-e2e") + .startActiveSpan(`nextjs ${runtime} otel span`, async (span) => { + span.setAttribute("runtime", runtime); + span.setAttribute("scenario", "nextjs-instrumentation"); + span.setAttribute("testRunId", testRunId); + span.end(); + }); + + await exporter.forceFlush(); + await provider.shutdown?.(); + await new Promise((resolve) => setTimeout(resolve, 250)); +} + +export async function runRuntimeCheck(runtime: Runtime) { + const testRunId = getTestRunId(); + const projectName = scopedName(`e2e-nextjs-instrumentation-${runtime}`); + const loggerSpanName = `nextjs ${runtime} logger span`; + const otelSpanName = `nextjs ${runtime} otel span`; + const route = `/api/smoke-test/${runtime === "nodejs" ? "node" : runtime}`; + const metadata = { + runtime, + scenario: "nextjs-instrumentation", + testRunId, + transport: "http", + }; + + const logger = initLogger({ projectName }); + + await logger.traced( + async (rootSpan) => { + rootSpan.log({ + input: { + route, + runtime, + }, + metadata, + output: { + ok: true, + route, + runtime, + }, + }); + }, + { + name: loggerSpanName, + event: { + input: { + route, + runtime, + }, + metadata, + }, + }, + ); + + await logger.flush(); + + await emitOtelSpan(runtime, testRunId); + + return { + instrumentationRegistered: Boolean( + (globalThis as { __btNextjsInstrumentationRegistered?: boolean }) + .__btNextjsInstrumentationRegistered, + ), + loggerSpanName, + otelSpanName, + projectName, + route, + runtime, + success: true, + testRunId, + }; +} + +export function formatRouteError(error: unknown) { + if (error instanceof Error) { + return { + message: error.message, + name: error.name, + }; + } + + return { + message: String(error), + name: "UnknownError", + }; +} diff --git a/js/smoke/scenarios/nextjs-instrumentation/tsconfig.json b/e2e/scenarios/nextjs-instrumentation/tsconfig.json similarity index 100% rename from js/smoke/scenarios/nextjs-instrumentation/tsconfig.json rename to e2e/scenarios/nextjs-instrumentation/tsconfig.json diff --git a/js/smoke/README.md b/js/smoke/README.md index c9091b4f2..d4548b0c8 100644 --- a/js/smoke/README.md +++ b/js/smoke/README.md @@ -2,8 +2,6 @@ Smoke test infrastructure verifying SDK installation across different runtimes and integrations. -Deno coverage now lives in `e2e/scenarios/deno-node/` and `e2e/scenarios/deno-browser/`. - ## Quick Reference ```bash @@ -359,4 +357,3 @@ See `shared/README.md` for complete test suite documentation, individual test fu - **Node.js + OTEL:** `scenarios/otel-v1/` - **Cloudflare Workers:** `scenarios/cloudflare-worker-*/` - **Multi-test:** `scenarios/cloudflare-vite-hono/` -- **Next.js:** `scenarios/nextjs-instrumentation/` diff --git a/js/smoke/scenarios/nextjs-instrumentation/.gitignore b/js/smoke/scenarios/nextjs-instrumentation/.gitignore deleted file mode 100644 index 611cdd9e5..000000000 --- a/js/smoke/scenarios/nextjs-instrumentation/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules/ -.next/ -*.log -.env.local -package-lock.json diff --git a/js/smoke/scenarios/nextjs-instrumentation/Makefile b/js/smoke/scenarios/nextjs-instrumentation/Makefile deleted file mode 100644 index 0d379121f..000000000 --- a/js/smoke/scenarios/nextjs-instrumentation/Makefile +++ /dev/null @@ -1,48 +0,0 @@ -.PHONY: setup test - -setup: - @echo "==> Setting up nextjs-instrumentation scenario" - mise install - @# Check if BRAINTRUST_TAR is set (from parent or CI), otherwise build - @if [ -n "$(BRAINTRUST_TAR)" ]; then \ - echo "==> Using BRAINTRUST_TAR: $(BRAINTRUST_TAR)"; \ - else \ - echo "==> Building SDK"; \ - cd ../../.. && pnpm exec turbo build --filter=braintrust && mkdir -p artifacts && pnpm pack --pack-destination artifacts; \ - \ - for f in artifacts/braintrust-*.tgz; do \ - if [ "$$(basename $$f)" != "braintrust-latest.tgz" ] && \ - [ "$$(basename $$f)" != "braintrust-otel-latest.tgz" ]; then \ - cp "$$f" artifacts/braintrust-latest.tgz; \ - break; \ - fi; \ - done; \ - fi - - @# Build shared package (if not running from parent) - @if [ -z "$(SMOKE_V2_SHARED_DIST)" ]; then \ - echo "==> Building shared package"; \ - cd ../../shared && npm ci && npm run build; \ - fi - - @# Check if BRAINTRUST_OTEL_TAR is set (from parent or CI), otherwise build - @if [ -n "$(BRAINTRUST_OTEL_TAR)" ]; then \ - echo "==> Using BRAINTRUST_OTEL_TAR: $(BRAINTRUST_OTEL_TAR)"; \ - else \ - echo "==> Building @braintrust/otel package"; \ - cd ../../../../integrations/otel-js && pnpm exec turbo build --filter=@braintrust/otel && pnpm pack --pack-destination ../../js/artifacts; \ - \ - for f in ../../js/artifacts/braintrust-otel-*.tgz; do \ - if [ "$$(basename $$f)" != "braintrust-otel-latest.tgz" ]; then \ - cp "$$f" ../../js/artifacts/braintrust-otel-latest.tgz; \ - break; \ - fi; \ - done; \ - fi - npm install --no-package-lock - -test: setup - @echo "==> Running Next.js build test (webpack bundling)" - npx next build - @echo "==> Running Next.js runtime tests (Edge + Node.js)" - node tests/api-routes.test.mjs diff --git a/js/smoke/scenarios/nextjs-instrumentation/README.md b/js/smoke/scenarios/nextjs-instrumentation/README.md deleted file mode 100644 index 05502add6..000000000 --- a/js/smoke/scenarios/nextjs-instrumentation/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Next.js Instrumentation Scenario - -Tests Braintrust SDK integration in Next.js with multiple runtimes. - -## Design Decisions - -### Tarball Installation - -Uses `file:` dependencies pointing to pre-built tarballs: - -- `"braintrust": "file:../../../artifacts/braintrust-latest.tgz"` -- `"@braintrust/otel": "file:../../../artifacts/braintrust-otel-latest.tgz"` -- More realistic test of how Next.js bundles published packages -- Catches webpack bundling issues that local linking might miss - -### Build + Runtime Testing - -Tests at two stages: - -1. **Build-time** (`npx next build`) - Catches static issues (imports, exports, bundling) -2. **Runtime** (dev server + HTTP requests) - Catches execution issues in both runtimes - -Both needed because Next.js can build successfully but fail at runtime, or vice versa. - -### Multiple Runtime Testing - -Tests both Next.js runtimes in separate API routes: - -- **Edge Runtime** (`/api/smoke-test/edge`) - V8 isolates, no Node.js APIs (like Cloudflare Workers) -- **Node.js Runtime** (`/api/smoke-test/node`) - Full Node.js environment - -Different runtimes have different capabilities - Edge can't use nunjucks, filesystem, etc. - -### Shared Package Import - -Uses long relative path to shared package: - -- `from "../../../../../../../shared/dist/index.mjs"` -- Next.js webpack handles this correctly despite the deep nesting -- Alternative would be adding shared to dependencies, but relative import is simpler diff --git a/js/smoke/scenarios/nextjs-instrumentation/mise.toml b/js/smoke/scenarios/nextjs-instrumentation/mise.toml deleted file mode 100644 index 3fd2123a0..000000000 --- a/js/smoke/scenarios/nextjs-instrumentation/mise.toml +++ /dev/null @@ -1,6 +0,0 @@ -[tools] -node = "22" -pnpm = "10.26.2" - -[env] -_.file = ".env.local" diff --git a/js/smoke/scenarios/nextjs-instrumentation/next-env.d.ts b/js/smoke/scenarios/nextjs-instrumentation/next-env.d.ts deleted file mode 100644 index 40c3d6809..000000000 --- a/js/smoke/scenarios/nextjs-instrumentation/next-env.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/js/smoke/scenarios/nextjs-instrumentation/package.json b/js/smoke/scenarios/nextjs-instrumentation/package.json deleted file mode 100644 index e8faeef10..000000000 --- a/js/smoke/scenarios/nextjs-instrumentation/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "smoke-nextjs-instrumentation", - "version": "1.0.0", - "description": "Smoke test for Braintrust + @braintrust/otel in Next.js instrumentation", - "private": true, - "scripts": { - "dev": "next dev" - }, - "dependencies": { - "braintrust": "file:../../../artifacts/braintrust-latest.tgz", - "@braintrust/otel": "file:../../../artifacts/braintrust-otel-latest.tgz", - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/api-logs": "^0.200.0", - "@opentelemetry/core": "^2.0.0", - "@opentelemetry/exporter-trace-otlp-http": "^0.200.0", - "@opentelemetry/instrumentation": "^0.200.0", - "@opentelemetry/resources": "^2.0.0", - "@opentelemetry/sdk-logs": "^0.200.0", - "@opentelemetry/sdk-metrics": "^2.0.0", - "@opentelemetry/sdk-trace-base": "^2.0.0", - "@vercel/otel": "^2.1.0", - "next": "14.2.34", - "react": "^18", - "react-dom": "^18", - "zod": "^4.1.13" - }, - "devDependencies": { - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "tsx": "^4.19.2", - "typescript": "^5" - } -} diff --git a/js/smoke/scenarios/nextjs-instrumentation/src/app/page.tsx b/js/smoke/scenarios/nextjs-instrumentation/src/app/page.tsx deleted file mode 100644 index b8b1c7069..000000000 --- a/js/smoke/scenarios/nextjs-instrumentation/src/app/page.tsx +++ /dev/null @@ -1,10 +0,0 @@ -export default function Home() { - return ( -
-

Next.js Instrumentation Test

-

- This is a minimal Next.js app to test @braintrust/otel instrumentation. -

-
- ); -} diff --git a/js/smoke/scenarios/nextjs-instrumentation/src/instrumentation.ts b/js/smoke/scenarios/nextjs-instrumentation/src/instrumentation.ts deleted file mode 100644 index 50a2433b3..000000000 --- a/js/smoke/scenarios/nextjs-instrumentation/src/instrumentation.ts +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Next.js instrumentation file that sets up OpenTelemetry with Braintrust. - * - * This file is loaded by Next.js when the experimental.instrumentationHook - * config option is enabled. It tests that: - * 1. @braintrust/otel works correctly in Next.js - * 2. Shared test package can be imported (webpack bundling verification) - * - * Note: The import statement below is the actual test - if webpack can't - * resolve or bundle the shared test package, the build will fail. - * Runtime testing happens in app/api/smoke-test/edge/route.ts and - * app/api/smoke-test/node/route.ts instead. - */ - -import { registerOTel } from "@vercel/otel"; - -// Import verification: webpack will fail the build if this import doesn't work -// This tests tree-shaking and module resolution -import { - runTests, - testBasicSpanLogging, - testCoreLoggingExports, -} from "../../../shared"; - -export async function register() { - // Log that imports succeeded (build-time verification passed) - console.log( - "Next.js instrumentation: Shared test package imports successful", - ); - console.log( - "Build-time verification passed - webpack successfully bundled shared test package", - ); - - // Set up OpenTelemetry with Braintrust - const { BraintrustExporter } = await import("@braintrust/otel"); - registerOTel({ - serviceName: "nextjs-instrumentation-test", - traceExporter: new BraintrustExporter({ - parent: "project_name:nextjs-instrumentation-test", - filterAISpans: true, - }) as any, - }); - - console.log("Next.js instrumentation: OTEL setup complete"); -} - -// Prevent tree-shaking from removing the imported functions -// (They need to be referenced somewhere for webpack to include them) -if (process.env.NODE_ENV === "test") { - // This code never runs in production, but ensures webpack includes the imports - void runTests; - void testBasicSpanLogging; - void testCoreLoggingExports; -} diff --git a/js/smoke/scenarios/nextjs-instrumentation/tests/api-routes.test.mjs b/js/smoke/scenarios/nextjs-instrumentation/tests/api-routes.test.mjs deleted file mode 100644 index e2f7ad84d..000000000 --- a/js/smoke/scenarios/nextjs-instrumentation/tests/api-routes.test.mjs +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/env node -/** - * Test script for Next.js API routes - * Calls both Edge Runtime and Node.js Runtime test endpoints - */ - -import { spawn } from "child_process"; -import { setTimeout as sleep } from "timers/promises"; -import { displayTestResults } from "../../../shared/dist/index.mjs"; - -const PORT = 5555; -const BASE_URL = `http://localhost:${PORT}`; -const EDGE_URL = `${BASE_URL}/api/smoke-test/edge`; -const NODE_URL = `${BASE_URL}/api/smoke-test/node`; -const MAX_STARTUP_TIME = 60000; // 60 seconds -const POLL_INTERVAL = 1000; // 1 second - -let devServer = null; - -/** - * Start the Next.js dev server - */ -function startDevServer() { - devServer = spawn("npm", ["run", "dev"], { - stdio: ["ignore", "pipe", "pipe"], - shell: true, - env: { ...process.env, PORT: String(PORT) }, - }); - - devServer.stdout.on("data", (data) => { - process.stdout.write(data.toString()); - }); - - devServer.stderr.on("data", (data) => { - process.stderr.write(data.toString()); - }); - - devServer.on("error", (error) => { - console.error("Failed to start dev server:", error); - }); - - return devServer; -} - -/** - * Wait for server to be ready - */ -async function waitForServer(maxTime = MAX_STARTUP_TIME) { - const startTime = Date.now(); - - while (Date.now() - startTime < maxTime) { - try { - const response = await fetch(`${BASE_URL}/`, { method: "HEAD" }); - if (response.ok || response.status === 404) { - await sleep(2000); // Buffer time - return true; - } - } catch (error) { - // Server not ready yet - } - await sleep(POLL_INTERVAL); - } - - return false; -} - -/** - * Test an API endpoint - */ -async function testEndpoint(url, name) { - try { - const response = await fetch(url); - const result = await response.json(); - - // Display results using standardized format - displayTestResults({ - scenarioName: `${name} Test Results`, - results: result.results, - }); - - return { - success: result.success, - status: response.status, - result, - }; - } catch (error) { - console.error(`Error testing ${name}:`, error.message); - return { - success: false, - status: null, - error: error.message, - }; - } -} - -/** - * Cleanup and exit - */ -function cleanup(exitCode = 0) { - if (devServer) { - devServer.kill("SIGTERM"); - setTimeout(() => { - if (devServer && !devServer.killed) { - devServer.kill("SIGKILL"); - } - }, 5000); - } - - setTimeout(() => { - process.exit(exitCode); - }, 1000); -} - -/** - * Main execution - */ -async function main() { - // Handle cleanup on exit - process.on("SIGINT", () => cleanup(1)); - process.on("SIGTERM", () => cleanup(1)); - - try { - // Start dev server - startDevServer(); - - // Wait for server to be ready - const serverReady = await waitForServer(); - if (!serverReady) { - console.error("Server startup failed"); - cleanup(1); - return; - } - - // Test Edge Runtime - const edgeResult = await testEndpoint(EDGE_URL, "Edge Runtime"); - - // Test Node.js Runtime - const nodeResult = await testEndpoint(NODE_URL, "Node.js Runtime"); - - // Exit based on results - const allPassed = edgeResult.success && nodeResult.success; - cleanup(allPassed ? 0 : 1); - } catch (error) { - console.error("Unexpected error:", error); - cleanup(1); - } -} - -// Run -main(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d626388a8..b5a327668 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,25 +63,6 @@ importers: specifier: 4.3.6 version: 4.3.6 - e2e/scenarios/turbopack-auto-instrumentation: - dependencies: - next: - specifier: 16.2.1 - version: 16.2.1(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - openai: - specifier: 6.32.0 - version: 6.32.0(ws@8.18.3)(zod@4.2.1) - react: - specifier: 19.2.4 - version: 19.2.4 - react-dom: - specifier: 19.2.4 - version: 19.2.4(react@19.2.4) - devDependencies: - '@types/react': - specifier: 19.2.14 - version: 19.2.14 - integrations/browser-js: dependencies: als-browser: @@ -111,16 +92,16 @@ importers: devDependencies: '@langchain/anthropic': specifier: ^1.3.1 - version: 1.3.5(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76))) + version: 1.3.5(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76))) '@langchain/core': specifier: ^1.1.6 - version: 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)) + version: 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)) '@langchain/langgraph': specifier: ^1.0.7 - version: 1.0.7(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)))(react@19.1.1)(zod-to-json-schema@3.22.5(zod@3.25.76))(zod@3.25.76) + version: 1.0.7(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.22.5(zod@3.25.76))(zod@3.25.76) '@langchain/openai': specifier: ^1.2.0 - version: 1.2.1(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) + version: 1.2.1(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) '@types/node': specifier: ^20.10.5 version: 20.10.5 @@ -275,7 +256,7 @@ importers: version: 0.0.11 ai: specifier: ^3.2.16 - version: 3.2.16(openai@4.104.0(ws@8.18.3)(zod@4.3.6))(react@19.1.1)(svelte@5.39.0)(vue@3.5.21(typescript@5.3.3))(zod@4.3.6) + version: 3.2.16(openai@4.104.0(ws@8.18.3)(zod@4.3.6))(react@19.2.4)(svelte@5.39.0)(vue@3.5.21(typescript@5.3.3))(zod@4.3.6) braintrust: specifier: workspace:* version: link:../../js @@ -463,7 +444,7 @@ importers: version: 6.25.0(ws@8.18.3)(zod@3.25.76) openapi-zod-client: specifier: ^1.18.3 - version: 1.18.3(react@19.1.1) + version: 1.18.3(react@19.2.4) rollup: specifier: ^4.28.1 version: 4.35.0 @@ -1601,204 +1582,67 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@img/colour@1.1.0': - resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} - engines: {node: '>=18'} - '@img/sharp-darwin-arm64@0.33.5': resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-arm64@0.34.5': - resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - '@img/sharp-darwin-x64@0.33.5': resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-darwin-x64@0.34.5': - resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.0.4': resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.4': - resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} - cpu: [arm64] - os: [darwin] - '@img/sharp-libvips-darwin-x64@1.0.4': resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.4': - resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} - cpu: [x64] - os: [darwin] - '@img/sharp-libvips-linux-arm64@1.0.4': resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm64@1.2.4': - resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} - cpu: [arm64] - os: [linux] - '@img/sharp-libvips-linux-arm@1.0.5': resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-arm@1.2.4': - resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-ppc64@1.2.4': - resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} - cpu: [ppc64] - os: [linux] - - '@img/sharp-libvips-linux-riscv64@1.2.4': - resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} - cpu: [riscv64] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.2.4': - resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} - cpu: [s390x] - os: [linux] - '@img/sharp-libvips-linux-x64@1.0.4': resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linux-x64@1.2.4': - resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': - resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.2.4': - resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} - cpu: [x64] - os: [linux] - '@img/sharp-linux-arm64@0.33.5': resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm64@0.34.5': - resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - '@img/sharp-linux-arm@0.33.5': resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-arm@0.34.5': - resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-ppc64@0.34.5': - resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ppc64] - os: [linux] - - '@img/sharp-linux-riscv64@0.34.5': - resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [riscv64] - os: [linux] - - '@img/sharp-linux-s390x@0.34.5': - resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - '@img/sharp-linux-x64@0.33.5': resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linux-x64@0.34.5': - resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.34.5': - resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.34.5': - resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.34.5': - resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-arm64@0.34.5': - resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [win32] - - '@img/sharp-win32-ia32@0.34.5': - resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - '@img/sharp-win32-x64@0.33.5': resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] - '@img/sharp-win32-x64@0.34.5': - resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - '@inquirer/confirm@5.0.2': resolution: {integrity: sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==} engines: {node: '>=18'} @@ -2055,57 +1899,6 @@ packages: '@next/env@14.2.3': resolution: {integrity: sha512-W7fd7IbkfmeeY2gXrzJYDx8D2lWKbVoTIj1o1ScPHNzvp30s1AuoEFSdr39bC5sjxJaxTtq3OTCZboNp0lNWHA==} - '@next/env@16.2.1': - resolution: {integrity: sha512-n8P/HCkIWW+gVal2Z8XqXJ6aB3J0tuM29OcHpCsobWlChH/SITBs1DFBk/HajgrwDkqqBXPbuUuzgDvUekREPg==} - - '@next/swc-darwin-arm64@16.2.1': - resolution: {integrity: sha512-BwZ8w8YTaSEr2HIuXLMLxIdElNMPvY9fLqb20LX9A9OMGtJilhHLbCL3ggyd0TwjmMcTxi0XXt+ur1vWUoxj2Q==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-x64@16.2.1': - resolution: {integrity: sha512-/vrcE6iQSJq3uL3VGVHiXeaKbn8Es10DGTGRJnRZlkNQQk3kaNtAJg8Y6xuAlrx/6INKVjkfi5rY0iEXorZ6uA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-linux-arm64-gnu@16.2.1': - resolution: {integrity: sha512-uLn+0BK+C31LTVbQ/QU+UaVrV0rRSJQ8RfniQAHPghDdgE+SlroYqcmFnO5iNjNfVWCyKZHYrs3Nl0mUzWxbBw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@16.2.1': - resolution: {integrity: sha512-ssKq6iMRnHdnycGp9hCuGnXJZ0YPr4/wNwrfE5DbmvEcgl9+yv97/Kq3TPVDfYome1SW5geciLB9aiEqKXQjlQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-x64-gnu@16.2.1': - resolution: {integrity: sha512-HQm7SrHRELJ30T1TSmT706IWovFFSRGxfgUkyWJZF/RKBMdbdRWJuFrcpDdE5vy9UXjFOx6L3mRdqH04Mmx0hg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@16.2.1': - resolution: {integrity: sha512-aV2iUaC/5HGEpbBkE+4B8aHIudoOy5DYekAKOMSHoIYQ66y/wIVeaRx8MS2ZMdxe/HIXlMho4ubdZs/J8441Tg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-win32-arm64-msvc@16.2.1': - resolution: {integrity: sha512-IXdNgiDHaSk0ZUJ+xp0OQTdTgnpx1RCfRTalhn3cjOP+IddTMINwA7DXZrwTmGDO8SUr5q2hdP/du4DcrB1GxA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-x64-msvc@16.2.1': - resolution: {integrity: sha512-qvU+3a39Hay+ieIztkGSbF7+mccbbg1Tk25hc4JDylf8IHjYmY/Zm64Qq1602yPyQqvie+vf5T/uPwNxDNIoeg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2560,9 +2353,6 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.15': - resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@swc/types@0.1.25': resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} @@ -2733,9 +2523,6 @@ packages: '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/react@19.2.14': - resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} - '@types/retry@0.12.0': resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} @@ -3196,11 +2983,6 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.10: - resolution: {integrity: sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==} - engines: {node: '>=6.0.0'} - hasBin: true - baseline-browser-mapping@2.9.14: resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} hasBin: true @@ -3370,9 +3152,6 @@ packages: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} - client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -3559,10 +3338,6 @@ packages: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -4796,27 +4571,6 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - next@16.2.1: - resolution: {integrity: sha512-VaChzNL7o9rbfdt60HUj8tev4m6d7iC1igAy157526+cJlXOQu5LzsBXNT+xaJnTP/k+utSX5vMv7m0G+zKH+Q==} - engines: {node: '>=20.9.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.51.1 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - nexus-rpc@0.0.1: resolution: {integrity: sha512-hAWn8Hh2eewpB5McXR5EW81R3pR/ziuGhKCF3wFyUVCklanPqrIgMNr7jKCbzXeNVad0nUDfWpFRqh2u+zxQtw==} engines: {node: '>= 18.0.0'} @@ -5105,10 +4859,6 @@ packages: yaml: optional: true - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.8: resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} engines: {node: ^10 || ^12 || >=14} @@ -5201,10 +4951,6 @@ packages: react-is@18.3.1: resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - react@19.1.1: - resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} - engines: {node: '>=0.10.0'} - react@19.2.4: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} @@ -5335,10 +5081,6 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sharp@0.34.5: - resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -5507,19 +5249,6 @@ packages: resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} engines: {node: '>=14.16'} - styled-jsx@5.1.6: - resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true - sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -6314,13 +6043,13 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/react@0.0.16(react@19.1.1)(zod@4.3.6)': + '@ai-sdk/react@0.0.16(react@19.2.4)(zod@4.3.6)': dependencies: '@ai-sdk/provider-utils': 1.0.0(zod@4.3.6) '@ai-sdk/ui-utils': 0.0.9(zod@4.3.6) - swr: 2.2.0(react@19.1.1) + swr: 2.2.0(react@19.2.4) optionalDependencies: - react: 19.1.1 + react: 19.2.4 zod: 4.3.6 '@ai-sdk/solid@0.0.11(zod@4.3.6)': @@ -7365,146 +7094,49 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@img/colour@1.1.0': - optional: true - '@img/sharp-darwin-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.0.4 optional: true - '@img/sharp-darwin-arm64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.4 - optional: true - '@img/sharp-darwin-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.0.4 optional: true - '@img/sharp-darwin-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.4 - optional: true - '@img/sharp-libvips-darwin-arm64@1.0.4': optional: true - '@img/sharp-libvips-darwin-arm64@1.2.4': - optional: true - '@img/sharp-libvips-darwin-x64@1.0.4': optional: true - '@img/sharp-libvips-darwin-x64@1.2.4': - optional: true - '@img/sharp-libvips-linux-arm64@1.0.4': optional: true - '@img/sharp-libvips-linux-arm64@1.2.4': - optional: true - '@img/sharp-libvips-linux-arm@1.0.5': optional: true - '@img/sharp-libvips-linux-arm@1.2.4': - optional: true - - '@img/sharp-libvips-linux-ppc64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-riscv64@1.2.4': - optional: true - - '@img/sharp-libvips-linux-s390x@1.2.4': - optional: true - '@img/sharp-libvips-linux-x64@1.0.4': optional: true - '@img/sharp-libvips-linux-x64@1.2.4': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.2.4': - optional: true - '@img/sharp-linux-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.0.4 optional: true - '@img/sharp-linux-arm64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.4 - optional: true - '@img/sharp-linux-arm@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.0.5 optional: true - '@img/sharp-linux-arm@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.4 - optional: true - - '@img/sharp-linux-ppc64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.4 - optional: true - - '@img/sharp-linux-riscv64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-riscv64': 1.2.4 - optional: true - - '@img/sharp-linux-s390x@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.4 - optional: true - '@img/sharp-linux-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.0.4 optional: true - '@img/sharp-linux-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.4 - optional: true - - '@img/sharp-linuxmusl-arm64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 - optional: true - - '@img/sharp-linuxmusl-x64@0.34.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.4 - optional: true - - '@img/sharp-wasm32@0.34.5': - dependencies: - '@emnapi/runtime': 1.8.1 - optional: true - - '@img/sharp-win32-arm64@0.34.5': - optional: true - - '@img/sharp-win32-ia32@0.34.5': - optional: true - '@img/sharp-win32-x64@0.33.5': optional: true - '@img/sharp-win32-x64@0.34.5': - optional: true - '@inquirer/confirm@5.0.2(@types/node@20.10.5)': dependencies: '@inquirer/core': 10.1.0(@types/node@20.10.5) @@ -7900,20 +7532,20 @@ snapshots: '@kwsites/promise-deferred@1.1.1': {} - '@langchain/anthropic@1.3.5(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)))': + '@langchain/anthropic@1.3.5(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)))': dependencies: '@anthropic-ai/sdk': 0.71.2(zod@3.25.76) - '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)) zod: 3.25.76 - '@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76))': + '@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76))': dependencies: '@cfworker/json-schema': 4.0.3 ansi-styles: 5.2.0 camelcase: 6.3.0 decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.4.5(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)) + langsmith: 0.4.5(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)) mustache: 4.2.0 p-queue: 6.6.2 uuid: 10.0.0 @@ -7924,25 +7556,26 @@ snapshots: - '@opentelemetry/sdk-trace-base' - openai - '@langchain/langgraph-checkpoint@1.0.0(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)))': + '@langchain/langgraph-checkpoint@1.0.0(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)))': dependencies: - '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)) uuid: 10.0.0 - '@langchain/langgraph-sdk@1.3.1(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)))(react@19.1.1)': + '@langchain/langgraph-sdk@1.3.1(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: p-queue: 6.6.2 p-retry: 4.6.2 uuid: 9.0.1 optionalDependencies: - '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)) - react: 19.1.1 + '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@langchain/langgraph@1.0.7(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)))(react@19.1.1)(zod-to-json-schema@3.22.5(zod@3.25.76))(zod@3.25.76)': + '@langchain/langgraph@1.0.7(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.22.5(zod@3.25.76))(zod@3.25.76)': dependencies: - '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)) - '@langchain/langgraph-checkpoint': 1.0.0(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76))) - '@langchain/langgraph-sdk': 1.3.1(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)))(react@19.1.1) + '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/langgraph-checkpoint': 1.0.0(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76))) + '@langchain/langgraph-sdk': 1.3.1(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) uuid: 10.0.0 zod: 3.25.76 optionalDependencies: @@ -7951,9 +7584,9 @@ snapshots: - react - react-dom - '@langchain/openai@1.2.1(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': + '@langchain/openai@1.2.1(@langchain/core@1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': dependencies: - '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 1.1.10(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)) js-tiktoken: 1.0.21 openai: 6.25.0(ws@8.18.3)(zod@3.25.76) zod: 3.25.76 @@ -8001,32 +7634,6 @@ snapshots: '@next/env@14.2.3': {} - '@next/env@16.2.1': {} - - '@next/swc-darwin-arm64@16.2.1': - optional: true - - '@next/swc-darwin-x64@16.2.1': - optional: true - - '@next/swc-linux-arm64-gnu@16.2.1': - optional: true - - '@next/swc-linux-arm64-musl@16.2.1': - optional: true - - '@next/swc-linux-x64-gnu@16.2.1': - optional: true - - '@next/swc-linux-x64-musl@16.2.1': - optional: true - - '@next/swc-win32-arm64-msvc@16.2.1': - optional: true - - '@next/swc-win32-x64-msvc@16.2.1': - optional: true - '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -8446,10 +8053,6 @@ snapshots: '@swc/counter@0.1.3': {} - '@swc/helpers@0.5.15': - dependencies: - tslib: 2.8.1 - '@swc/types@0.1.25': dependencies: '@swc/counter': 0.1.3 @@ -8691,10 +8294,6 @@ snapshots: '@types/range-parser@1.2.7': {} - '@types/react@19.2.14': - dependencies: - csstype: 3.2.3 - '@types/retry@0.12.0': {} '@types/send@0.17.4': @@ -9100,11 +8699,11 @@ snapshots: dependencies: humanize-ms: 1.2.1 - ai@3.2.16(openai@4.104.0(ws@8.18.3)(zod@4.3.6))(react@19.1.1)(svelte@5.39.0)(vue@3.5.21(typescript@5.3.3))(zod@4.3.6): + ai@3.2.16(openai@4.104.0(ws@8.18.3)(zod@4.3.6))(react@19.2.4)(svelte@5.39.0)(vue@3.5.21(typescript@5.3.3))(zod@4.3.6): dependencies: '@ai-sdk/provider': 0.0.11 '@ai-sdk/provider-utils': 1.0.0(zod@4.3.6) - '@ai-sdk/react': 0.0.16(react@19.1.1)(zod@4.3.6) + '@ai-sdk/react': 0.0.16(react@19.2.4)(zod@4.3.6) '@ai-sdk/solid': 0.0.11(zod@4.3.6) '@ai-sdk/svelte': 0.0.12(svelte@5.39.0)(zod@4.3.6) '@ai-sdk/ui-utils': 0.0.9(zod@4.3.6) @@ -9118,7 +8717,7 @@ snapshots: zod-to-json-schema: 3.22.5(zod@4.3.6) optionalDependencies: openai: 4.104.0(ws@8.18.3)(zod@4.3.6) - react: 19.1.1 + react: 19.2.4 svelte: 5.39.0 zod: 4.3.6 transitivePeerDependencies: @@ -9376,8 +8975,6 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.10.10: {} - baseline-browser-mapping@2.9.14: {} bignumber.js@9.3.1: {} @@ -9584,8 +9181,6 @@ snapshots: cli-width@4.1.0: {} - client-only@0.0.1: {} - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -9736,9 +9331,6 @@ snapshots: destroy@1.2.0: {} - detect-libc@2.1.2: - optional: true - detect-newline@3.1.0: {} diff-match-patch@1.0.5: {} @@ -11044,7 +10636,7 @@ snapshots: typescript: 5.5.4 zod: 4.3.6 - langsmith@0.4.5(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.25.0(ws@8.18.3)(zod@3.25.76)): + langsmith@0.4.5(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(openai@6.32.0(ws@8.18.3)(zod@3.25.76)): dependencies: '@types/uuid': 10.0.0 chalk: 4.1.2 @@ -11055,7 +10647,7 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) - openai: 6.25.0(ws@8.18.3)(zod@3.25.76) + openai: 6.32.0(ws@8.18.3)(zod@3.25.76) leven@3.1.0: {} @@ -11472,31 +11064,6 @@ snapshots: neo-async@2.6.2: {} - next@16.2.1(@opentelemetry/api@1.9.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): - dependencies: - '@next/env': 16.2.1 - '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.10.10 - caniuse-lite: 1.0.30001764 - postcss: 8.4.31 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - styled-jsx: 5.1.6(react@19.2.4) - optionalDependencies: - '@next/swc-darwin-arm64': 16.2.1 - '@next/swc-darwin-x64': 16.2.1 - '@next/swc-linux-arm64-gnu': 16.2.1 - '@next/swc-linux-arm64-musl': 16.2.1 - '@next/swc-linux-x64-gnu': 16.2.1 - '@next/swc-linux-x64-musl': 16.2.1 - '@next/swc-win32-arm64-msvc': 16.2.1 - '@next/swc-win32-x64-msvc': 16.2.1 - '@opentelemetry/api': 1.9.0 - sharp: 0.34.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - nexus-rpc@0.0.1: {} node-domexception@1.0.0: {} @@ -11584,14 +11151,15 @@ snapshots: ws: 8.18.3 zod: 3.25.76 - openai@6.32.0(ws@8.18.3)(zod@4.2.1): + openai@6.32.0(ws@8.18.3)(zod@3.25.76): optionalDependencies: ws: 8.18.3 - zod: 4.2.1 + zod: 3.25.76 + optional: true openapi-types@12.1.3: {} - openapi-zod-client@1.18.3(react@19.1.1): + openapi-zod-client@1.18.3(react@19.2.4): dependencies: '@apidevtools/swagger-parser': 10.1.1(openapi-types@12.1.3) '@liuli-util/fs-extra': 0.1.0 @@ -11601,7 +11169,7 @@ snapshots: handlebars: 4.7.8 openapi-types: 12.1.3 openapi3-ts: 3.1.0 - pastable: 2.2.1(react@19.1.1) + pastable: 2.2.1(react@19.2.4) prettier: 2.8.8 tanu: 0.1.13 ts-pattern: 5.8.0 @@ -11700,13 +11268,13 @@ snapshots: parseurl@1.3.3: {} - pastable@2.2.1(react@19.1.1): + pastable@2.2.1(react@19.2.4): dependencies: '@babel/core': 7.28.0 ts-toolbelt: 9.6.0 type-fest: 3.13.1 optionalDependencies: - react: 19.1.1 + react: 19.2.4 transitivePeerDependencies: - supports-color @@ -11768,12 +11336,6 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - postcss@8.4.31: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.8: dependencies: nanoid: 3.3.11 @@ -11871,11 +11433,10 @@ snapshots: dependencies: react: 19.2.4 scheduler: 0.27.0 + optional: true react-is@18.3.1: {} - react@19.1.1: {} - react@19.2.4: {} readdirp@4.1.2: {} @@ -11963,7 +11524,8 @@ snapshots: safer-buffer@2.1.2: {} - scheduler@0.27.0: {} + scheduler@0.27.0: + optional: true schema-utils@4.3.3: dependencies: @@ -12042,38 +11604,6 @@ snapshots: setprototypeof@1.2.0: {} - sharp@0.34.5: - dependencies: - '@img/colour': 1.1.0 - detect-libc: 2.1.2 - semver: 7.7.4 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.5 - '@img/sharp-darwin-x64': 0.34.5 - '@img/sharp-libvips-darwin-arm64': 1.2.4 - '@img/sharp-libvips-darwin-x64': 1.2.4 - '@img/sharp-libvips-linux-arm': 1.2.4 - '@img/sharp-libvips-linux-arm64': 1.2.4 - '@img/sharp-libvips-linux-ppc64': 1.2.4 - '@img/sharp-libvips-linux-riscv64': 1.2.4 - '@img/sharp-libvips-linux-s390x': 1.2.4 - '@img/sharp-libvips-linux-x64': 1.2.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 - '@img/sharp-libvips-linuxmusl-x64': 1.2.4 - '@img/sharp-linux-arm': 0.34.5 - '@img/sharp-linux-arm64': 0.34.5 - '@img/sharp-linux-ppc64': 0.34.5 - '@img/sharp-linux-riscv64': 0.34.5 - '@img/sharp-linux-s390x': 0.34.5 - '@img/sharp-linux-x64': 0.34.5 - '@img/sharp-linuxmusl-arm64': 0.34.5 - '@img/sharp-linuxmusl-x64': 0.34.5 - '@img/sharp-wasm32': 0.34.5 - '@img/sharp-win32-arm64': 0.34.5 - '@img/sharp-win32-ia32': 0.34.5 - '@img/sharp-win32-x64': 0.34.5 - optional: true - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -12239,11 +11769,6 @@ snapshots: strip-json-comments@5.0.3: {} - styled-jsx@5.1.6(react@19.2.4): - dependencies: - client-only: 0.0.1 - react: 19.2.4 - sucrase@3.35.0: dependencies: '@jridgewell/gen-mapping': 0.3.8 @@ -12291,10 +11816,10 @@ snapshots: '@swc/counter': 0.1.3 webpack: 5.104.1(@swc/core@1.15.8) - swr@2.2.0(react@19.1.1): + swr@2.2.0(react@19.2.4): dependencies: - react: 19.1.1 - use-sync-external-store: 1.2.2(react@19.1.1) + react: 19.2.4 + use-sync-external-store: 1.2.2(react@19.2.4) swrev@4.0.0: {} @@ -12727,9 +12252,9 @@ snapshots: querystringify: 2.2.0 requires-port: 1.0.0 - use-sync-external-store@1.2.2(react@19.1.1): + use-sync-external-store@1.2.2(react@19.2.4): dependencies: - react: 19.1.1 + react: 19.2.4 utils-merge@1.0.1: {}