Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51354e6c6d | ||
|
|
10dd50cff0 | ||
|
|
d8783f8698 | ||
|
|
16a572f51d | ||
|
|
947641cbbf | ||
|
|
249e161473 | ||
|
|
90bab4386f | ||
|
|
33fddb1344 | ||
|
|
c24dcb068a | ||
|
|
2986723254 | ||
|
|
b45b2fd8f8 |
+1
-1
@@ -27,7 +27,7 @@
|
||||
"@langfuse/shared": "workspace:*",
|
||||
"@opentelemetry/api": ">=1.0.0 <1.10.0",
|
||||
"axios": "^1.7.7",
|
||||
"next": "^14.2.15",
|
||||
"next": "^14.2.21",
|
||||
"next-auth": "^4.24.11",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
|
||||
@@ -11,6 +11,7 @@ service:
|
||||
Batched ingestion for Langfuse Tracing. If you want to use tracing via the API, such as to build your own Langfuse client implementation, this is the only API route you need to implement.
|
||||
|
||||
Notes:
|
||||
- Introduction to data model: https://langfuse.com/docs/tracing-data-model
|
||||
- Batch sizes are limited to 3.5 MB in total. You need to adjust the number of events per batch accordingly.
|
||||
- The API does not return a 4xx status code for input errors. Instead, it responds with a 207 status code, which includes a list of the encountered errors.
|
||||
method: POST
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "langfuse",
|
||||
"version": "3.5.0",
|
||||
"version": "3.5.2",
|
||||
"author": "engineering@langfuse.com",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
|
||||
@@ -394,7 +394,7 @@ export class ObservationProcessor implements EventProcessor {
|
||||
model?: Model,
|
||||
existingObservation?: Omit<Observation, "input" | "output">,
|
||||
) {
|
||||
let newPromptTokens = body.usage?.input || body.usageDetails?.input;
|
||||
let newPromptTokens = body.usage?.input ?? body.usageDetails?.input;
|
||||
if (newPromptTokens === undefined && model && model.tokenizerId) {
|
||||
if (body.input) {
|
||||
newPromptTokens = calculateTokenDelegate({
|
||||
@@ -419,7 +419,7 @@ export class ObservationProcessor implements EventProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
let newCompletionTokens = body.usage?.output || body.usageDetails?.output;
|
||||
let newCompletionTokens = body.usage?.output ?? body.usageDetails?.output;
|
||||
|
||||
if (newCompletionTokens === undefined && model && model.tokenizerId) {
|
||||
if (body.output) {
|
||||
|
||||
Generated
+67
-72
@@ -45,11 +45,11 @@ importers:
|
||||
specifier: ^1.7.7
|
||||
version: 1.7.7
|
||||
next:
|
||||
specifier: ^14.2.15
|
||||
version: 14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
specifier: ^14.2.21
|
||||
version: 14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
next-auth:
|
||||
specifier: ^4.24.11
|
||||
version: 4.24.11(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
version: 4.24.11(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
zod:
|
||||
specifier: ^3.23.8
|
||||
version: 3.23.8
|
||||
@@ -211,7 +211,7 @@ importers:
|
||||
version: 4.17.21
|
||||
next-auth:
|
||||
specifier: ^4.24.11
|
||||
version: 4.24.11(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
version: 4.24.11(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
nodemailer:
|
||||
specifier: ^6.9.15
|
||||
version: 6.9.15
|
||||
@@ -368,7 +368,7 @@ importers:
|
||||
version: 7.19.0(@emotion/react@11.11.4(@types/react@18.2.79)(react@18.2.0))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.2.79)(react@18.2.0))(@types/react@18.2.79)(react@18.2.0))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.2.79)(react@18.2.0))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.2.79)(react@18.2.0))(@types/react@18.2.79)(react@18.2.0))(@types/react@18.2.79)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@mui/system@5.16.7(@emotion/react@11.11.4(@types/react@18.2.79)(react@18.2.0))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.2.79)(react@18.2.0))(@types/react@18.2.79)(react@18.2.0))(@types/react@18.2.79)(react@18.2.0))(@types/react@18.2.79)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
'@next-auth/prisma-adapter':
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(@prisma/client@5.22.0(prisma@5.22.0))(next-auth@4.24.11(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
|
||||
version: 1.0.7(@prisma/client@5.22.0(prisma@5.22.0))(next-auth@4.24.11(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
|
||||
'@opentelemetry/api':
|
||||
specifier: ^1.9.0
|
||||
version: 1.9.0
|
||||
@@ -491,7 +491,7 @@ importers:
|
||||
version: link:../packages/config-typescript
|
||||
'@sentry/nextjs':
|
||||
specifier: ^8.39.0
|
||||
version: 8.39.0(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.95.0)
|
||||
version: 8.39.0(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.95.0)
|
||||
'@t3-oss/env-nextjs':
|
||||
specifier: ^0.11.1
|
||||
version: 0.11.1(typescript@5.4.5)(zod@3.23.8)
|
||||
@@ -512,7 +512,7 @@ importers:
|
||||
version: 10.45.2(@trpc/server@10.45.2)
|
||||
'@trpc/next':
|
||||
specifier: ^10.45.0
|
||||
version: 10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
version: 10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
'@trpc/react-query':
|
||||
specifier: ^10.45.0
|
||||
version: 10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
@@ -589,14 +589,14 @@ importers:
|
||||
specifier: ^0.462.0
|
||||
version: 0.462.0(react@18.2.0)
|
||||
next:
|
||||
specifier: ^14.2.15
|
||||
version: 14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
specifier: ^14.2.21
|
||||
version: 14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
next-auth:
|
||||
specifier: ^4.24.11
|
||||
version: 4.24.11(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
version: 4.24.11(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
next-query-params:
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(use-query-params@2.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
|
||||
version: 5.0.1(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(use-query-params@2.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
|
||||
next-themes:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
@@ -2644,62 +2644,62 @@ packages:
|
||||
'@prisma/client': '>=2.26.0 || >=3'
|
||||
next-auth: ^4
|
||||
|
||||
'@next/env@14.2.15':
|
||||
resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==}
|
||||
'@next/env@14.2.21':
|
||||
resolution: {integrity: sha512-lXcwcJd5oR01tggjWJ6SrNNYFGuOOMB9c251wUNkjCpkoXOPkDeF/15c3mnVlBqrW4JJXb2kVxDFhC4GduJt2A==}
|
||||
|
||||
'@next/eslint-plugin-next@14.2.15':
|
||||
resolution: {integrity: sha512-pKU0iqKRBlFB/ocOI1Ip2CkKePZpYpnw5bEItEkuZ/Nr9FQP1+p7VDWr4VfOdff4i9bFmrOaeaU1bFEyAcxiMQ==}
|
||||
|
||||
'@next/swc-darwin-arm64@14.2.15':
|
||||
resolution: {integrity: sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==}
|
||||
'@next/swc-darwin-arm64@14.2.21':
|
||||
resolution: {integrity: sha512-HwEjcKsXtvszXz5q5Z7wCtrHeTTDSTgAbocz45PHMUjU3fBYInfvhR+ZhavDRUYLonm53aHZbB09QtJVJj8T7g==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@next/swc-darwin-x64@14.2.15':
|
||||
resolution: {integrity: sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==}
|
||||
'@next/swc-darwin-x64@14.2.21':
|
||||
resolution: {integrity: sha512-TSAA2ROgNzm4FhKbTbyJOBrsREOMVdDIltZ6aZiKvCi/v0UwFmwigBGeqXDA97TFMpR3LNNpw52CbVelkoQBxA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@next/swc-linux-arm64-gnu@14.2.15':
|
||||
resolution: {integrity: sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==}
|
||||
'@next/swc-linux-arm64-gnu@14.2.21':
|
||||
resolution: {integrity: sha512-0Dqjn0pEUz3JG+AImpnMMW/m8hRtl1GQCNbO66V1yp6RswSTiKmnHf3pTX6xMdJYSemf3O4Q9ykiL0jymu0TuA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-linux-arm64-musl@14.2.15':
|
||||
resolution: {integrity: sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==}
|
||||
'@next/swc-linux-arm64-musl@14.2.21':
|
||||
resolution: {integrity: sha512-Ggfw5qnMXldscVntwnjfaQs5GbBbjioV4B4loP+bjqNEb42fzZlAaK+ldL0jm2CTJga9LynBMhekNfV8W4+HBw==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-linux-x64-gnu@14.2.15':
|
||||
resolution: {integrity: sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==}
|
||||
'@next/swc-linux-x64-gnu@14.2.21':
|
||||
resolution: {integrity: sha512-uokj0lubN1WoSa5KKdThVPRffGyiWlm/vCc/cMkWOQHw69Qt0X1o3b2PyLLx8ANqlefILZh1EdfLRz9gVpG6tg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-linux-x64-musl@14.2.15':
|
||||
resolution: {integrity: sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==}
|
||||
'@next/swc-linux-x64-musl@14.2.21':
|
||||
resolution: {integrity: sha512-iAEBPzWNbciah4+0yI4s7Pce6BIoxTQ0AGCkxn/UBuzJFkYyJt71MadYQkjPqCQCJAFQ26sYh7MOKdU+VQFgPg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@next/swc-win32-arm64-msvc@14.2.15':
|
||||
resolution: {integrity: sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==}
|
||||
'@next/swc-win32-arm64-msvc@14.2.21':
|
||||
resolution: {integrity: sha512-plykgB3vL2hB4Z32W3ktsfqyuyGAPxqwiyrAi2Mr8LlEUhNn9VgkiAl5hODSBpzIfWweX3er1f5uNpGDygfQVQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@next/swc-win32-ia32-msvc@14.2.15':
|
||||
resolution: {integrity: sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==}
|
||||
'@next/swc-win32-ia32-msvc@14.2.21':
|
||||
resolution: {integrity: sha512-w5bacz4Vxqrh06BjWgua3Yf7EMDb8iMcVhNrNx8KnJXt8t+Uu0Zg4JHLDL/T7DkTCEEfKXO/Er1fcfWxn2xfPA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@next/swc-win32-x64-msvc@14.2.15':
|
||||
resolution: {integrity: sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==}
|
||||
'@next/swc-win32-x64-msvc@14.2.21':
|
||||
resolution: {integrity: sha512-sT6+llIkzpsexGYZq8cjjthRyRGe5cJVhqh12FmlbxHqna6zsDDK8UNaV7g41T6atFHCJUPeLb3uyAwrBwy0NA==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@@ -5775,9 +5775,6 @@ packages:
|
||||
caniuse-lite@1.0.30001599:
|
||||
resolution: {integrity: sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==}
|
||||
|
||||
caniuse-lite@1.0.30001667:
|
||||
resolution: {integrity: sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==}
|
||||
|
||||
caniuse-lite@1.0.30001680:
|
||||
resolution: {integrity: sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==}
|
||||
|
||||
@@ -9038,8 +9035,8 @@ packages:
|
||||
react: ^16.8 || ^17 || ^18
|
||||
react-dom: ^16.8 || ^17 || ^18
|
||||
|
||||
next@14.2.15:
|
||||
resolution: {integrity: sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==}
|
||||
next@14.2.21:
|
||||
resolution: {integrity: sha512-rZmLwucLHr3/zfDMYbJXbw0ZeoBpirxkXuvsJbk7UPorvPYZhP7vq7aHbKnU7dQNCYIimRrbB2pp3xmf+wsYUg==}
|
||||
engines: {node: '>=18.17.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -14332,42 +14329,42 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
|
||||
'@next-auth/prisma-adapter@1.0.7(@prisma/client@5.22.0(prisma@5.22.0))(next-auth@4.24.11(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))':
|
||||
'@next-auth/prisma-adapter@1.0.7(@prisma/client@5.22.0(prisma@5.22.0))(next-auth@4.24.11(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))':
|
||||
dependencies:
|
||||
'@prisma/client': 5.22.0(prisma@5.22.0)
|
||||
next-auth: 4.24.11(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
next-auth: 4.24.11(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
|
||||
'@next/env@14.2.15': {}
|
||||
'@next/env@14.2.21': {}
|
||||
|
||||
'@next/eslint-plugin-next@14.2.15':
|
||||
dependencies:
|
||||
glob: 10.3.10
|
||||
|
||||
'@next/swc-darwin-arm64@14.2.15':
|
||||
'@next/swc-darwin-arm64@14.2.21':
|
||||
optional: true
|
||||
|
||||
'@next/swc-darwin-x64@14.2.15':
|
||||
'@next/swc-darwin-x64@14.2.21':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-arm64-gnu@14.2.15':
|
||||
'@next/swc-linux-arm64-gnu@14.2.21':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-arm64-musl@14.2.15':
|
||||
'@next/swc-linux-arm64-musl@14.2.21':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-x64-gnu@14.2.15':
|
||||
'@next/swc-linux-x64-gnu@14.2.21':
|
||||
optional: true
|
||||
|
||||
'@next/swc-linux-x64-musl@14.2.15':
|
||||
'@next/swc-linux-x64-musl@14.2.21':
|
||||
optional: true
|
||||
|
||||
'@next/swc-win32-arm64-msvc@14.2.15':
|
||||
'@next/swc-win32-arm64-msvc@14.2.21':
|
||||
optional: true
|
||||
|
||||
'@next/swc-win32-ia32-msvc@14.2.15':
|
||||
'@next/swc-win32-ia32-msvc@14.2.21':
|
||||
optional: true
|
||||
|
||||
'@next/swc-win32-x64-msvc@14.2.15':
|
||||
'@next/swc-win32-x64-msvc@14.2.21':
|
||||
optional: true
|
||||
|
||||
'@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1':
|
||||
@@ -16216,7 +16213,7 @@ snapshots:
|
||||
'@sentry/types': 8.39.0
|
||||
'@sentry/utils': 8.39.0
|
||||
|
||||
'@sentry/nextjs@8.39.0(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.95.0)':
|
||||
'@sentry/nextjs@8.39.0(@opentelemetry/core@1.26.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.53.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.26.0(@opentelemetry/api@1.9.0))(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(webpack@5.95.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/instrumentation-http': 0.53.0(@opentelemetry/api@1.9.0)
|
||||
@@ -16232,7 +16229,7 @@ snapshots:
|
||||
'@sentry/vercel-edge': 8.39.0
|
||||
'@sentry/webpack-plugin': 2.22.6(webpack@5.95.0)
|
||||
chalk: 3.0.0
|
||||
next: 14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
next: 14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
resolve: 1.22.8
|
||||
rollup: 3.29.5
|
||||
stacktrace-parser: 0.1.10
|
||||
@@ -16817,13 +16814,13 @@ snapshots:
|
||||
dependencies:
|
||||
'@trpc/server': 10.45.2
|
||||
|
||||
'@trpc/next@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
|
||||
'@trpc/next@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/react-query@10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.45.2)(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
|
||||
dependencies:
|
||||
'@tanstack/react-query': 4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
'@trpc/client': 10.45.2(@trpc/server@10.45.2)
|
||||
'@trpc/react-query': 10.45.2(@tanstack/react-query@4.36.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.45.2(@trpc/server@10.45.2))(@trpc/server@10.45.2)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
'@trpc/server': 10.45.2
|
||||
next: 14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
next: 14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
|
||||
@@ -18096,14 +18093,14 @@ snapshots:
|
||||
|
||||
browserslist@4.23.0:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001667
|
||||
caniuse-lite: 1.0.30001680
|
||||
electron-to-chromium: 1.4.710
|
||||
node-releases: 2.0.14
|
||||
update-browserslist-db: 1.0.13(browserslist@4.23.0)
|
||||
|
||||
browserslist@4.24.0:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001667
|
||||
caniuse-lite: 1.0.30001680
|
||||
electron-to-chromium: 1.5.33
|
||||
node-releases: 2.0.18
|
||||
update-browserslist-db: 1.1.1(browserslist@4.24.0)
|
||||
@@ -18197,8 +18194,6 @@ snapshots:
|
||||
|
||||
caniuse-lite@1.0.30001599: {}
|
||||
|
||||
caniuse-lite@1.0.30001667: {}
|
||||
|
||||
caniuse-lite@1.0.30001680: {}
|
||||
|
||||
ccount@2.0.1: {}
|
||||
@@ -22305,13 +22300,13 @@ snapshots:
|
||||
dependencies:
|
||||
type-fest: 2.19.0
|
||||
|
||||
next-auth@4.24.11(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
||||
next-auth@4.24.11(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(nodemailer@6.9.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@panva/hkdf': 1.1.1
|
||||
cookie: 0.7.2
|
||||
jose: 4.15.5
|
||||
next: 14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
next: 14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
oauth: 0.9.15
|
||||
openid-client: 5.6.5
|
||||
preact: 10.19.7
|
||||
@@ -22322,9 +22317,9 @@ snapshots:
|
||||
optionalDependencies:
|
||||
nodemailer: 6.9.15
|
||||
|
||||
next-query-params@5.0.1(next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(use-query-params@2.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)):
|
||||
next-query-params@5.0.1(next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)(use-query-params@2.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)):
|
||||
dependencies:
|
||||
next: 14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
next: 14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
react: 18.2.0
|
||||
tslib: 2.6.3
|
||||
use-query-params: 2.2.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
@@ -22334,27 +22329,27 @@ snapshots:
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
|
||||
next@14.2.15(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
||||
next@14.2.21(@babel/core@7.24.3)(@opentelemetry/api@1.9.0)(@playwright/test@1.47.2)(babel-plugin-macros@3.1.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
|
||||
dependencies:
|
||||
'@next/env': 14.2.15
|
||||
'@next/env': 14.2.21
|
||||
'@swc/helpers': 0.5.5
|
||||
busboy: 1.6.0
|
||||
caniuse-lite: 1.0.30001667
|
||||
caniuse-lite: 1.0.30001680
|
||||
graceful-fs: 4.2.11
|
||||
postcss: 8.4.31
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
styled-jsx: 5.1.1(@babel/core@7.24.3)(babel-plugin-macros@3.1.0)(react@18.2.0)
|
||||
optionalDependencies:
|
||||
'@next/swc-darwin-arm64': 14.2.15
|
||||
'@next/swc-darwin-x64': 14.2.15
|
||||
'@next/swc-linux-arm64-gnu': 14.2.15
|
||||
'@next/swc-linux-arm64-musl': 14.2.15
|
||||
'@next/swc-linux-x64-gnu': 14.2.15
|
||||
'@next/swc-linux-x64-musl': 14.2.15
|
||||
'@next/swc-win32-arm64-msvc': 14.2.15
|
||||
'@next/swc-win32-ia32-msvc': 14.2.15
|
||||
'@next/swc-win32-x64-msvc': 14.2.15
|
||||
'@next/swc-darwin-arm64': 14.2.21
|
||||
'@next/swc-darwin-x64': 14.2.21
|
||||
'@next/swc-linux-arm64-gnu': 14.2.21
|
||||
'@next/swc-linux-arm64-musl': 14.2.21
|
||||
'@next/swc-linux-x64-gnu': 14.2.21
|
||||
'@next/swc-linux-x64-musl': 14.2.21
|
||||
'@next/swc-win32-arm64-msvc': 14.2.21
|
||||
'@next/swc-win32-ia32-msvc': 14.2.21
|
||||
'@next/swc-win32-x64-msvc': 14.2.21
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@playwright/test': 1.47.2
|
||||
transitivePeerDependencies:
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "web",
|
||||
"version": "3.5.0",
|
||||
"version": "3.5.2",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -117,7 +117,7 @@
|
||||
"langchain": "^0.3.6",
|
||||
"lodash": "^4.17.21",
|
||||
"lucide-react": "^0.462.0",
|
||||
"next": "^14.2.15",
|
||||
"next": "^14.2.21",
|
||||
"next-auth": "^4.24.11",
|
||||
"next-query-params": "^5.0.1",
|
||||
"next-themes": "^0.3.0",
|
||||
|
||||
@@ -723,6 +723,9 @@ paths:
|
||||
Notes:
|
||||
|
||||
|
||||
- Introduction to data model:
|
||||
https://langfuse.com/docs/tracing-data-model
|
||||
|
||||
- Batch sizes are limited to 3.5 MB in total. You need to adjust the
|
||||
number of events per batch accordingly.
|
||||
|
||||
|
||||
@@ -558,7 +558,7 @@
|
||||
"_type": "endpoint",
|
||||
"name": "Batch",
|
||||
"request": {
|
||||
"description": "Batched ingestion for Langfuse Tracing. If you want to use tracing via the API, such as to build your own Langfuse client implementation, this is the only API route you need to implement.\n\nNotes:\n\n- Batch sizes are limited to 3.5 MB in total. You need to adjust the number of events per batch accordingly.\n- The API does not return a 4xx status code for input errors. Instead, it responds with a 207 status code, which includes a list of the encountered errors.",
|
||||
"description": "Batched ingestion for Langfuse Tracing. If you want to use tracing via the API, such as to build your own Langfuse client implementation, this is the only API route you need to implement.\n\nNotes:\n\n- Introduction to data model: https://langfuse.com/docs/tracing-data-model\n- Batch sizes are limited to 3.5 MB in total. You need to adjust the number of events per batch accordingly.\n- The API does not return a 4xx status code for input errors. Instead, it responds with a 207 status code, which includes a list of the encountered errors.",
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/public/ingestion",
|
||||
"host": [
|
||||
|
||||
@@ -215,6 +215,102 @@ describe("/api/public/datasets and /api/public/dataset-items API Endpoints", ()
|
||||
expect(getDataset.body.items[0].id).toEqual("active-item-id");
|
||||
});
|
||||
|
||||
it("should correctly update dataset items", async () => {
|
||||
const datasetItemId = v4();
|
||||
const datasetName = v4();
|
||||
|
||||
await prisma.dataset.create({
|
||||
data: {
|
||||
name: datasetName,
|
||||
projectId: projectId,
|
||||
},
|
||||
});
|
||||
|
||||
await makeZodVerifiedAPICall(
|
||||
PostDatasetItemsV1Response,
|
||||
"POST",
|
||||
"/api/public/dataset-items",
|
||||
{
|
||||
datasetName: datasetName,
|
||||
id: datasetItemId,
|
||||
input: { key: "value" },
|
||||
expectedOutput: { key: "value" },
|
||||
metadata: null,
|
||||
sourceTraceId: null,
|
||||
sourceObservationId: null,
|
||||
status: null,
|
||||
},
|
||||
auth,
|
||||
);
|
||||
|
||||
await makeZodVerifiedAPICall(
|
||||
PostDatasetItemsV1Response,
|
||||
"POST",
|
||||
"/api/public/dataset-items",
|
||||
{
|
||||
datasetName: datasetName,
|
||||
id: datasetItemId,
|
||||
input: { john: "doe" },
|
||||
expectedOutput: { john: "doe" },
|
||||
metadata: null,
|
||||
sourceTraceId: null,
|
||||
sourceObservationId: null,
|
||||
status: null,
|
||||
},
|
||||
auth,
|
||||
);
|
||||
|
||||
const databaseDatasetItem = await prisma.datasetItem.findFirst({
|
||||
where: {
|
||||
id: datasetItemId,
|
||||
},
|
||||
});
|
||||
expect(databaseDatasetItem).toMatchObject({
|
||||
input: { john: "doe" },
|
||||
expectedOutput: { john: "doe" },
|
||||
});
|
||||
});
|
||||
|
||||
it("should return 404 when trying to update dataset item that exists in different dataset of the same project", async () => {
|
||||
const datasetItemId = v4();
|
||||
|
||||
const dataset = await prisma.dataset.create({
|
||||
data: {
|
||||
name: "dataset-name-1",
|
||||
projectId: projectId,
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.dataset.create({
|
||||
data: {
|
||||
name: "dataset-name-2",
|
||||
projectId: projectId,
|
||||
},
|
||||
});
|
||||
|
||||
await prisma.datasetItem.create({
|
||||
data: {
|
||||
id: datasetItemId,
|
||||
datasetId: dataset.id,
|
||||
projectId: projectId,
|
||||
},
|
||||
});
|
||||
|
||||
const response = await makeAPICall(
|
||||
"POST",
|
||||
"/api/public/dataset-items",
|
||||
{
|
||||
datasetName: "dataset-name-2",
|
||||
id: datasetItemId,
|
||||
input: { key: "new-value" },
|
||||
expectedOutput: { key: "new-value" },
|
||||
},
|
||||
auth,
|
||||
);
|
||||
|
||||
expect(response.status).toBe(404);
|
||||
});
|
||||
|
||||
it("GET datasets (v1 & v2)", async () => {
|
||||
// v1 post
|
||||
await makeZodVerifiedAPICall(
|
||||
|
||||
@@ -87,7 +87,6 @@ export const ROUTES: Route[] = [
|
||||
title: "Evaluation",
|
||||
icon: Lightbulb,
|
||||
pathname: `/project/[projectId]/annotation-queues`,
|
||||
label: "Beta",
|
||||
entitlements: ["annotation-queues", "model-based-evaluations"],
|
||||
projectRbacScopes: ["annotationQueues:read", "evalJob:read"],
|
||||
items: [
|
||||
|
||||
+19
-16
@@ -71,7 +71,8 @@ export function TraceTableMultiSelectAction({
|
||||
},
|
||||
});
|
||||
|
||||
const hasEntitlement = useHasEntitlement("annotation-queues");
|
||||
const hasAnnotationEntitlement = useHasEntitlement("annotation-queues");
|
||||
const hasTraceDeletionEntitlement = useHasEntitlement("trace-deletion");
|
||||
const hasAddToQueueAccess = useHasProjectAccess({
|
||||
projectId,
|
||||
scope: "annotationQueues:CUD",
|
||||
@@ -97,7 +98,7 @@ export function TraceTableMultiSelectAction({
|
||||
{
|
||||
projectId,
|
||||
},
|
||||
{ enabled: session.status === "authenticated" && hasEntitlement },
|
||||
{ enabled: session.status === "authenticated" && hasAnnotationEntitlement },
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -110,20 +111,22 @@ export function TraceTableMultiSelectAction({
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
disabled={!hasDeleteAccess}
|
||||
onClick={() => {
|
||||
capture("trace:delete_form_open", {
|
||||
count: selectedTraceIds.length,
|
||||
source: "table-multi-select",
|
||||
});
|
||||
setDeleteDialogOpen(true);
|
||||
}}
|
||||
>
|
||||
<Trash className="mr-2 h-4 w-4" />
|
||||
<span>Delete</span>
|
||||
</DropdownMenuItem>
|
||||
{hasEntitlement && (
|
||||
{hasTraceDeletionEntitlement && (
|
||||
<DropdownMenuItem
|
||||
disabled={!hasDeleteAccess}
|
||||
onClick={() => {
|
||||
capture("trace:delete_form_open", {
|
||||
count: selectedTraceIds.length,
|
||||
source: "table-multi-select",
|
||||
});
|
||||
setDeleteDialogOpen(true);
|
||||
}}
|
||||
>
|
||||
<Trash className="mr-2 h-4 w-4" />
|
||||
<span>Delete</span>
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
{hasAnnotationEntitlement && (
|
||||
<DropdownMenuItem
|
||||
disabled={!hasAddToQueueAccess}
|
||||
onClick={() => {
|
||||
|
||||
@@ -52,6 +52,7 @@ import { BatchExportTableButton } from "@/src/components/BatchExportTableButton"
|
||||
import { useClickhouse } from "@/src/components/layouts/ClickhouseAdminToggle";
|
||||
import { BreakdownTooltip } from "@/src/components/trace/BreakdownToolTip";
|
||||
import { InfoIcon } from "lucide-react";
|
||||
import { useHasEntitlement } from "@/src/features/entitlements/hooks";
|
||||
|
||||
export type TracesTableRow = {
|
||||
bookmarked: boolean;
|
||||
@@ -241,6 +242,8 @@ export default function TracesTable({
|
||||
cellsLoading: !traceMetrics.data,
|
||||
});
|
||||
|
||||
const hasTraceDeletionEntitlement = useHasEntitlement("trace-deletion");
|
||||
|
||||
const columns: LangfuseColumnDef<TracesTableRow>[] = [
|
||||
{
|
||||
id: "select",
|
||||
@@ -708,7 +711,9 @@ export default function TracesTable({
|
||||
isPinned: true,
|
||||
cell: ({ row }) => {
|
||||
const traceId: TracesTableRow["id"] = row.getValue("id");
|
||||
return traceId && typeof traceId === "string" ? (
|
||||
return traceId &&
|
||||
typeof traceId === "string" &&
|
||||
hasTraceDeletionEntitlement ? (
|
||||
<DeleteButton
|
||||
itemId={traceId}
|
||||
projectId={projectId}
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
TabsBarList,
|
||||
TabsBarTrigger,
|
||||
} from "@/src/components/ui/tabs-bar";
|
||||
import { useHasEntitlement } from "@/src/features/entitlements/hooks";
|
||||
|
||||
export function Trace(props: {
|
||||
observations: Array<ObservationReturnType>;
|
||||
@@ -311,6 +312,8 @@ export function TracePage({
|
||||
withDefault(StringParam, "details"),
|
||||
);
|
||||
|
||||
const hasTraceDeletionEntitlement = useHasEntitlement("trace-deletion");
|
||||
|
||||
if (trace.error?.data?.code === "UNAUTHORIZED")
|
||||
return <ErrorPage message="You do not have access to this trace." />;
|
||||
|
||||
@@ -372,15 +375,17 @@ export function TracePage({
|
||||
}}
|
||||
listKey="traces"
|
||||
/>
|
||||
<DeleteButton
|
||||
itemId={traceId}
|
||||
projectId={trace.data.projectId}
|
||||
scope="traces:delete"
|
||||
invalidateFunc={() => void utils.traces.all.invalidate()}
|
||||
type="trace"
|
||||
redirectUrl={`/project/${router.query.projectId as string}/traces`}
|
||||
deleteConfirmation={trace.data.name ?? ""}
|
||||
/>
|
||||
{hasTraceDeletionEntitlement && (
|
||||
<DeleteButton
|
||||
itemId={traceId}
|
||||
projectId={trace.data.projectId}
|
||||
scope="traces:delete"
|
||||
invalidateFunc={() => void utils.traces.all.invalidate()}
|
||||
type="trace"
|
||||
redirectUrl={`/project/${router.query.projectId as string}/traces`}
|
||||
deleteConfirmation={trace.data.name ?? ""}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const VERSION = "v3.5.0";
|
||||
export const VERSION = "v3.5.2";
|
||||
|
||||
@@ -12,6 +12,7 @@ const entitlements = [
|
||||
"self-host-ui-customization",
|
||||
"self-host-allowed-organization-creators",
|
||||
"prompt-experiments",
|
||||
"trace-deletion",
|
||||
] as const;
|
||||
export type Entitlement = (typeof entitlements)[number];
|
||||
|
||||
@@ -24,6 +25,8 @@ const cloudAllPlansEntitlements: Entitlement[] = [
|
||||
"prompt-experiments",
|
||||
];
|
||||
|
||||
const selfHostedAllPlansEntitlements: Entitlement[] = ["trace-deletion"];
|
||||
|
||||
// Entitlement Limits: Limits on the number of resources that can be created/used
|
||||
const entitlementLimits = [
|
||||
"annotation-queue-count",
|
||||
@@ -78,7 +81,7 @@ export const entitlementAccess: Record<
|
||||
},
|
||||
},
|
||||
oss: {
|
||||
entitlements: [],
|
||||
entitlements: [...selfHostedAllPlansEntitlements],
|
||||
entitlementLimits: {
|
||||
"annotation-queue-count": 0,
|
||||
"organization-member-count": false,
|
||||
@@ -89,6 +92,7 @@ export const entitlementAccess: Record<
|
||||
},
|
||||
"self-hosted:pro": {
|
||||
entitlements: [
|
||||
...selfHostedAllPlansEntitlements,
|
||||
"annotation-queues",
|
||||
"model-based-evaluations",
|
||||
"playground",
|
||||
@@ -105,6 +109,7 @@ export const entitlementAccess: Record<
|
||||
},
|
||||
"self-hosted:enterprise": {
|
||||
entitlements: [
|
||||
...selfHostedAllPlansEntitlements,
|
||||
"annotation-queues",
|
||||
"model-based-evaluations",
|
||||
"playground",
|
||||
|
||||
@@ -165,7 +165,7 @@ export default async function handler(
|
||||
// return not implemented error
|
||||
res.status(404).json({ error: "Action does not exist" });
|
||||
} catch (e) {
|
||||
logger.error("failed to remove API keys", e);
|
||||
logger.error("failed to manage bullmq jobs", e);
|
||||
res.status(500).json({ error: e });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,12 @@ import {
|
||||
PostDatasetItemsV1Response,
|
||||
transformDbDatasetItemToAPIDatasetItem,
|
||||
} from "@/src/features/public-api/types/datasets";
|
||||
import { LangfuseNotFoundError } from "@langfuse/shared";
|
||||
import {
|
||||
type DatasetItem,
|
||||
LangfuseNotFoundError,
|
||||
Prisma,
|
||||
} from "@langfuse/shared";
|
||||
import { logger } from "@langfuse/shared/src/server";
|
||||
|
||||
export default withMiddlewares({
|
||||
POST: createAuthedAPIRoute({
|
||||
@@ -40,34 +45,54 @@ export default withMiddlewares({
|
||||
|
||||
const itemId = id ?? uuidv4();
|
||||
|
||||
const item = await prisma.datasetItem.upsert({
|
||||
where: {
|
||||
datasetId: dataset.id,
|
||||
id_projectId: {
|
||||
projectId: auth.scope.projectId,
|
||||
id: itemId,
|
||||
let item: DatasetItem;
|
||||
try {
|
||||
item = await prisma.datasetItem.upsert({
|
||||
where: {
|
||||
datasetId: dataset.id,
|
||||
id_projectId: {
|
||||
projectId: auth.scope.projectId,
|
||||
id: itemId,
|
||||
},
|
||||
},
|
||||
},
|
||||
create: {
|
||||
id: itemId,
|
||||
input: input ?? undefined,
|
||||
expectedOutput: expectedOutput ?? undefined,
|
||||
datasetId: dataset.id,
|
||||
metadata: metadata ?? undefined,
|
||||
sourceTraceId: sourceTraceId ?? undefined,
|
||||
sourceObservationId: sourceObservationId ?? undefined,
|
||||
status: status ?? undefined,
|
||||
projectId: auth.scope.projectId,
|
||||
},
|
||||
update: {
|
||||
input: input ?? undefined,
|
||||
expectedOutput: expectedOutput ?? undefined,
|
||||
metadata: metadata ?? undefined,
|
||||
sourceTraceId: sourceTraceId ?? undefined,
|
||||
sourceObservationId: sourceObservationId ?? undefined,
|
||||
status: status ?? undefined,
|
||||
},
|
||||
});
|
||||
create: {
|
||||
id: itemId,
|
||||
input: input ?? undefined,
|
||||
expectedOutput: expectedOutput ?? undefined,
|
||||
datasetId: dataset.id,
|
||||
metadata: metadata ?? undefined,
|
||||
sourceTraceId: sourceTraceId ?? undefined,
|
||||
sourceObservationId: sourceObservationId ?? undefined,
|
||||
status: status ?? undefined,
|
||||
projectId: auth.scope.projectId,
|
||||
},
|
||||
update: {
|
||||
input: input ?? undefined,
|
||||
expectedOutput: expectedOutput ?? undefined,
|
||||
metadata: metadata ?? undefined,
|
||||
sourceTraceId: sourceTraceId ?? undefined,
|
||||
sourceObservationId: sourceObservationId ?? undefined,
|
||||
status: status ?? undefined,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
if (
|
||||
e instanceof Prisma.PrismaClientKnownRequestError &&
|
||||
e.code === "P2025"
|
||||
) {
|
||||
// this case happens when a dataset item was created for a different dataset.
|
||||
// In the database, the uniqueness constraint is on (id, projectId) only.
|
||||
// When this constraint is violated, the database will upsert based on (id, projectId, datasetId).
|
||||
// If this record does not exist, the database will throw an error.
|
||||
logger.warn(
|
||||
`Failed to upsert dataset item. Dataset item ${itemId} in project ${auth.scope.projectId} already exists for a different dataset than ${dataset.id}`,
|
||||
);
|
||||
throw new LangfuseNotFoundError(
|
||||
`The dataset item with id ${itemId} was not found in the dataset ${dataset.name}`,
|
||||
);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
return transformDbDatasetItemToAPIDatasetItem({
|
||||
...item,
|
||||
|
||||
@@ -16,7 +16,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||
|
||||
const traces = await getTracesByIdsForAnyProject([traceId]);
|
||||
|
||||
if (!traces || traces.length === 0 || traces.length > 1) {
|
||||
if (!traces || traces.length === 0) {
|
||||
return {
|
||||
props: {
|
||||
notFound: true,
|
||||
@@ -24,6 +24,14 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||
};
|
||||
}
|
||||
|
||||
if (traces.length > 1) {
|
||||
return {
|
||||
props: {
|
||||
duplicatesFound: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/project/${traces[0].projectId}/traces/${traceId}`,
|
||||
@@ -32,7 +40,13 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||
};
|
||||
};
|
||||
|
||||
const TraceRedirectPage = ({ notFound }: { notFound?: boolean }) => {
|
||||
const TraceRedirectPage = ({
|
||||
notFound,
|
||||
duplicatesFound,
|
||||
}: {
|
||||
notFound?: boolean;
|
||||
duplicatesFound?: boolean;
|
||||
}) => {
|
||||
const router = useRouter();
|
||||
if (router.isFallback) {
|
||||
return <div>Loading...</div>;
|
||||
@@ -40,7 +54,23 @@ const TraceRedirectPage = ({ notFound }: { notFound?: boolean }) => {
|
||||
|
||||
if (notFound) {
|
||||
return (
|
||||
<ErrorPage message="Trace not found. Please upgrade the SDK as we changed the URL schema." />
|
||||
<ErrorPage
|
||||
title="Trace not found"
|
||||
message="The trace is either still being processed or has been deleted."
|
||||
additionalButton={{
|
||||
label: "Retry",
|
||||
onClick: () => void window.location.reload(),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (duplicatesFound) {
|
||||
return (
|
||||
<ErrorPage
|
||||
title="Trace not found"
|
||||
message="Please upgrade the SDK as the URL schema has changed."
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -503,17 +503,29 @@ export const sessionRouter = createTRPCRouter({
|
||||
input.sessionId,
|
||||
);
|
||||
|
||||
const [scores, costData] = await Promise.all([
|
||||
getScoresForTraces(
|
||||
input.projectId,
|
||||
clickhouseTraces.map((t) => t.id),
|
||||
),
|
||||
getCostForTraces(
|
||||
input.projectId,
|
||||
clickhouseTraces.map((t) => t.id),
|
||||
const traceIds = clickhouseTraces.map((t) => t.id);
|
||||
const chunkSize = 500;
|
||||
const chunks = [];
|
||||
|
||||
for (let i = 0; i < traceIds.length; i += chunkSize) {
|
||||
chunks.push(traceIds.slice(i, i + chunkSize));
|
||||
}
|
||||
|
||||
const [scores, costs] = await Promise.all([
|
||||
Promise.all(
|
||||
chunks.map((chunk) =>
|
||||
getScoresForTraces(input.projectId, chunk),
|
||||
),
|
||||
).then((results) => results.flat()),
|
||||
Promise.all(
|
||||
chunks.map((chunk) => getCostForTraces(input.projectId, chunk)),
|
||||
).then((results) =>
|
||||
results.reduce((sum, cost) => (sum ?? 0) + (cost ?? 0), 0),
|
||||
),
|
||||
]);
|
||||
|
||||
const costData = costs;
|
||||
|
||||
const validatedScores = filterAndValidateDbScoreList(
|
||||
scores,
|
||||
traceException,
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "worker",
|
||||
"version": "3.5.0",
|
||||
"version": "3.5.2",
|
||||
"description": "",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const VERSION = "v3.5.0";
|
||||
export const VERSION = "v3.5.2";
|
||||
|
||||
@@ -46,6 +46,18 @@ export const projectDeleteProcessor: Processor = async (
|
||||
// Finally, delete the project itself which should delete all related
|
||||
// resources due to the referential actions defined via Prisma
|
||||
try {
|
||||
const existingProject = await prisma.project.findUnique({
|
||||
where: {
|
||||
id: projectId,
|
||||
orgId,
|
||||
},
|
||||
});
|
||||
if (!existingProject) {
|
||||
logger.info(
|
||||
`Tried to delete project ${projectId} from PG, but it does not exist anymore.`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
await prisma.project.delete({
|
||||
where: {
|
||||
id: projectId,
|
||||
|
||||
Reference in New Issue
Block a user