Compare commits

...
80 Commits
Author SHA1 Message Date
Max Deichmann e4a029988f chore: release v2.9.0
CI/CD / lint (push) Waiting to run
CI/CD / test-docker-build (push) Waiting to run
CI/CD / tests (18) (push) Waiting to run
CI/CD / tests (20) (push) Waiting to run
CI/CD / e2e-tests (push) Waiting to run
CI/CD / all-ci-passed (push) Blocked by required conditions
CI/CD / push-docker-image (push) Blocked by required conditions
release.yml / release (push) Waiting to run
2024-02-29 14:50:13 +01:00
Marc Klingen d8bb7703ae fix(ui): second level headings should be h3 2024-02-29 12:24:55 +01:00
Marc Klingen bd7574411e chore: add npm run dx to root 2024-02-29 12:02:24 +01:00
Marc Klingen 2f55acec7c docs: update readme 2024-02-28 23:15:42 +01:00
SebandGitHub 78207ba274 chore: improve date picker formatting (#1283) 2024-02-28 20:14:16 +01:00
SebandGitHub 2250be58a5 docs: fix link to db schema (#1282) 2024-02-28 20:12:49 +01:00
Max DeichmannandGitHub 338517828c perf: increase sample rate for POST and trpc (#1284) 2024-02-28 19:06:10 +00:00
Max DeichmannandGitHub 2e80d4b475 perf: improve dashboard performance (#1281) 2024-02-28 16:51:38 +01:00
Marc KlingenandGitHub 45c9af76d8 fix(api): add input, output, sessionId, public to GET /traces (#1280) 2024-02-28 13:47:40 +00:00
Max DeichmannandGitHub bc27618c0e perf: improve generations table performance (#1279) 2024-02-28 13:41:33 +00:00
Max DeichmannandGitHub a4c8f0b702 perf: improve traces table performance (#1276) 2024-02-28 13:04:11 +00:00
Max DeichmannandGitHub 787eb90c54 perf: improve observations view and all traces (#1275) 2024-02-28 09:48:20 +00:00
Max DeichmannandGitHub 9b4601debf refactor: add load database setup script (#1273) 2024-02-27 23:43:30 +00:00
Max DeichmannandGitHub fcc0ee922f refactor: add sentry users to API (#1269) 2024-02-27 16:17:37 +01:00
Max DeichmannandGitHub 3271c4abd0 fix: observations index (#1267) 2024-02-27 14:33:56 +01:00
Max DeichmannandGitHub 2dbb9fec87 fix: fix observations index (#1266) 2024-02-27 12:42:32 +01:00
e7438c05b8 feat(generation): extend generations table (#1216)
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
2024-02-27 11:20:27 +00:00
Marc Klingen 45fcf8902b fix(self-host): event mapping 2024-02-27 02:40:54 +01:00
Max DeichmannandGitHub a4bfdb25a5 perf: revert traces router query (#1261)
revert
2024-02-26 22:37:35 +00:00
Max DeichmannandGitHub 462e8a7b8c perf: traces table performance improvements (#1256) 2024-02-26 22:57:53 +01:00
Marc KlingenandGitHub 86edd502b3 feat(ui): add alert that only ChatML generations is exported as JSONL (#1257) 2024-02-26 19:56:41 +00:00
Max DeichmannandGitHub 01a7e679fa fix: correctly return 500 and 400 API errors (#1253) 2024-02-26 12:44:03 +00:00
Marc KlingenandGitHub c6406e1ddb fix(ui): sort/filter sessions by total cost (#1254) 2024-02-26 11:35:20 +00:00
Max DeichmannandGitHub 82d4881dcf fix: improve contributing.md (#1252) 2024-02-26 09:23:51 +00:00
Max DeichmannandGitHub 42d3167591 fix: docs and root level commands (#1251) 2024-02-26 08:52:09 +00:00
Marc KlingenandGitHub 977ac39ec5 docs(api): improve api reference descriptions (#1244) 2024-02-23 19:44:11 +00:00
Marc Klingen e4d8db6a34 chore: release v2.8.0
CI/CD / lint (push) Waiting to run
CI/CD / test-docker-build (push) Waiting to run
CI/CD / tests (18) (push) Waiting to run
CI/CD / tests (20) (push) Waiting to run
CI/CD / e2e-tests (push) Waiting to run
CI/CD / all-ci-passed (push) Blocked by required conditions
CI/CD / push-docker-image (push) Blocked by required conditions
release.yml / release (push) Waiting to run
2024-02-23 20:23:00 +01:00
Marc KlingenandGitHub a39bbf541d feat(api): add GET /score/[scoreId] (#1242) 2024-02-23 19:20:27 +00:00
Max DeichmannandGitHub eef5218dbd refactor: add worker tests (#1241) 2024-02-23 17:44:54 +00:00
Marc KlingenandGitHub b5e802171b fix(api): deduplicate score and observation ids in GET /traces (#1240) 2024-02-23 17:38:55 +00:00
Max DeichmannandGitHub 96c4f28b5b refactor: linting worker (#1239) 2024-02-23 17:34:16 +00:00
Max DeichmannandGitHub 8ad4a46850 feat: add database connection to worker (#1238) 2024-02-23 16:55:16 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Max Deichmann
d8f2d6cf4e chore(deps): bump the prisma group in /web with 2 updates (#1231)
Bumps the prisma group in /web with 2 updates: [@prisma/client](https://github.com/prisma/prisma/tree/HEAD/packages/client) and [prisma](https://github.com/prisma/prisma/tree/HEAD/packages/cli).


Updates `@prisma/client` from 5.9.1 to 5.10.2
- [Release notes](https://github.com/prisma/prisma/releases)
- [Commits](https://github.com/prisma/prisma/commits/5.10.2/packages/client)

Updates `prisma` from 5.9.1 to 5.10.2
- [Release notes](https://github.com/prisma/prisma/releases)
- [Commits](https://github.com/prisma/prisma/commits/5.10.2/packages/cli)

---
updated-dependencies:
- dependency-name: "@prisma/client"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: prisma
- dependency-name: prisma
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: prisma
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
2024-02-23 16:50:10 +00:00
b8639ebb3b feat: use Json editor for dataset item editor (#1171)
Co-authored-by: gitstart-langfuse <gitstart-langfuse@users.noreply.github.com>
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
2024-02-23 14:46:27 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8be73970c2 chore(deps): bump the sentry group in /web with 3 updates (#1230)
Bumps the sentry group in /web with 3 updates: [@sentry/nextjs](https://github.com/getsentry/sentry-javascript), [@sentry/profiling-node](https://github.com/getsentry/sentry-javascript) and [@sentry/types](https://github.com/getsentry/sentry-javascript).


Updates `@sentry/nextjs` from 7.101.1 to 7.102.1
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/7.102.1/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.101.1...7.102.1)

Updates `@sentry/profiling-node` from 7.101.1 to 7.102.1
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/7.102.1/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.101.1...7.102.1)

Updates `@sentry/types` from 7.101.1 to 7.102.1
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/7.102.1/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.101.1...7.102.1)

---
updated-dependencies:
- dependency-name: "@sentry/nextjs"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
- dependency-name: "@sentry/profiling-node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
- dependency-name: "@sentry/types"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-23 14:34:10 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Max Deichmann
e18ab26bb5 chore(deps): bump @aws-sdk/lib-storage from 3.511.0 to 3.515.0 in /web (#1233)
Bumps [@aws-sdk/lib-storage](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/lib/lib-storage) from 3.511.0 to 3.515.0.
- [Release notes](https://github.com/aws/aws-sdk-js-v3/releases)
- [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/lib/lib-storage/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.515.0/lib/lib-storage)

---
updated-dependencies:
- dependency-name: "@aws-sdk/lib-storage"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
2024-02-23 14:28:52 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>Max Deichmann
095478869d chore(deps-dev): bump release-it from 17.0.5 to 17.1.1 in /web (#1234)
Bumps [release-it](https://github.com/release-it/release-it) from 17.0.5 to 17.1.1.
- [Release notes](https://github.com/release-it/release-it/releases)
- [Changelog](https://github.com/release-it/release-it/blob/main/CHANGELOG.md)
- [Commits](https://github.com/release-it/release-it/compare/17.0.5...17.1.1)

---
updated-dependencies:
- dependency-name: release-it
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
2024-02-23 14:23:04 +00:00
Marc KlingenandGitHub 4db7dab8ae fix(export): messages key in jsonl output format (#1236) 2024-02-23 13:54:31 +00:00
Max DeichmannandGitHub 086d26b041 fix: fix dependabot in new repo structure (#1228) 2024-02-23 09:35:32 +00:00
Max Deichmann 5fd042c7b1 chore: release v2.7.2
CI/CD / lint (push) Waiting to run
CI/CD / test-docker-build (push) Waiting to run
CI/CD / tests (18) (push) Waiting to run
CI/CD / tests (20) (push) Waiting to run
CI/CD / e2e-tests (push) Waiting to run
CI/CD / all-ci-passed (push) Blocked by required conditions
CI/CD / push-docker-image (push) Blocked by required conditions
release.yml / release (push) Waiting to run
2024-02-23 10:24:30 +01:00
Max DeichmannandGitHub dc37f1a58a feat: add worker container and redis (#1224) 2024-02-23 09:13:28 +00:00
Marc KlingenandGitHub bc4597e183 fix(ui): enable selection of text in trace inputs/outputs (#1227) 2024-02-23 02:37:45 +00:00
Marc Klingen 9bb1caf738 chore: fix paths in docs after migration to /web 2024-02-23 03:30:24 +01:00
Marc KlingenandGitHub 3ab4eb6341 docs: fix db schema in contributing.md 2024-02-23 01:14:58 +01:00
Max DeichmannandGitHub 5944611b51 fix: setup prettier (#1226) 2024-02-22 13:51:11 +00:00
Max Deichmann e439c81512 chore: release v2.7.1
CI/CD / lint (push) Waiting to run
CI/CD / test-docker-build (push) Waiting to run
CI/CD / tests (18) (push) Waiting to run
CI/CD / tests (20) (push) Waiting to run
CI/CD / e2e-tests (push) Waiting to run
CI/CD / all-ci-passed (push) Blocked by required conditions
CI/CD / push-docker-image (push) Blocked by required conditions
release.yml / release (push) Waiting to run
2024-02-22 14:08:26 +01:00
Max DeichmannandGitHub 799d32fa21 move nextjs into web directory (#1223) 2024-02-22 14:02:28 +01:00
Max DeichmannandGitHub 7927d0013f feat(API): catch prisma errors individually for public apis (#1215) 2024-02-21 21:05:19 +00:00
Marc KlingenandGitHub 147262a437 fix(ui): long observation/trace names should break instead of overflow (#1218) 2024-02-21 00:07:11 +00:00
Max Deichmann c02bb556ca chore: release v2.7.0
CI/CD / lint (push) Waiting to run
CI/CD / test-docker-build (push) Waiting to run
CI/CD / tests (18) (push) Waiting to run
CI/CD / tests (20) (push) Waiting to run
CI/CD / e2e-tests (push) Waiting to run
CI/CD / all-ci-passed (push) Blocked by required conditions
CI/CD / push-docker-image (push) Blocked by required conditions
release.yml / release (push) Waiting to run
2024-02-20 20:05:45 +01:00
Richard KrümmelandGitHub 1b792d844f fix(ui): fix prompt config display logic (#1211) 2024-02-20 13:57:45 +01:00
Max DeichmannandGitHub 52a42812b4 refactor: add kysely (#1210) 2024-02-20 11:24:22 +00:00
3b84af8cbf feat: add prompt config (#1147)
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
2024-02-20 10:31:44 +00:00
Marc KlingenandGitHub 1521445939 fix(ui): uriencode filter state to support special characters (#1209) 2024-02-20 00:56:18 +00:00
Marc KlingenandGitHub a1e961de09 feat(api): add htmlPath and totalCost to GET traces/[id] (#1207) 2024-02-20 00:34:59 +00:00
Marc Klingen c360cf10d4 chore: release v2.6.0
CI/CD / lint (push) Waiting to run
CI/CD / test-docker-build (push) Waiting to run
CI/CD / tests (18) (push) Waiting to run
CI/CD / tests (20) (push) Waiting to run
CI/CD / e2e-tests (push) Waiting to run
CI/CD / all-ci-passed (push) Blocked by required conditions
CI/CD / push-docker-image (push) Blocked by required conditions
release.yml / release (push) Waiting to run
2024-02-19 23:35:23 +01:00
Marc KlingenandGitHub 3e2f3f3d28 feat(api): add GET metrics/daily endpoint to fetch aggregate statistics (#1204) 2024-02-19 23:29:51 +01:00
Richard KrümmelandGitHub 11e5da2cd8 feat(ui): show full id in session table (#1165) 2024-02-19 22:09:08 +00:00
Max DeichmannandGitHub 8205595f2c fix: fix scores table (#1205) 2024-02-19 20:49:15 +00:00
101277cab8 feat: add traces filter to dashboard (#1202)
Co-authored-by: RichardKruemmel <richard.kruemmel@code.berlin>
2024-02-19 20:36:12 +00:00
Marc Klingen 954e31ca4a fix(api): type of totalCost on trace 2024-02-19 17:51:49 +01:00
Marc KlingenandGitHub 43c3258135 feat(api): add htmlPath, latency, totalCost to GET /traces (#1201) 2024-02-19 15:39:02 +00:00
Marc KlingenandGitHub eb8ae94a5d feat(dashboard): add 75th percentile to latency graph (#1195) 2024-02-17 12:07:39 +00:00
George GebbettandGitHub 33abe53acc feat(ui): preview of OpenAI function calls (#981) 2024-02-16 15:47:51 +00:00
5e8ec0bd13 feat(api): add DELETE /api/public/score/[scoreId] (#1167)
---------

Co-authored-by: Marc Klingen <git@marcklingen.com>
2024-02-16 15:06:02 +00:00
177f370914 feat: display total cost of a session (#1172)
Co-authored-by: gitstart-langfuse <gitstart-langfuse@users.noreply.github.com>
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
2024-02-16 15:12:38 +01:00
5538242649 feat: show total model cost per user (#1173)
Co-authored-by: gitstart-langfuse <gitstart-langfuse@users.noreply.github.com>
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
2024-02-16 15:02:18 +01:00
8c8e58e2b8 fix: Correct sorting on all tables (#1168)
Co-authored-by: gitstart-langfuse <gitstart-langfuse@users.noreply.github.com>
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
2024-02-16 13:00:11 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
a2c367c1b6 chore(deps): bump core-js from 3.35.1 to 3.36.0 (#1177)
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.35.1 to 3.36.0.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.36.0/packages/core-js)

---
updated-dependencies:
- dependency-name: core-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-16 03:03:39 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
da0ac73603 chore(deps): bump the patches group with 4 updates (#1176)
Bumps the patches group with 4 updates: [@sentry/nextjs](https://github.com/getsentry/sentry-javascript), [@sentry/profiling-node](https://github.com/getsentry/sentry-javascript), [@sentry/types](https://github.com/getsentry/sentry-javascript) and [posthog-node](https://github.com/PostHog/posthog-js-lite/tree/HEAD/posthog-node).


Updates `@sentry/nextjs` from 7.101.0 to 7.101.1
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/7.101.1/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.101.0...7.101.1)

Updates `@sentry/profiling-node` from 7.101.0 to 7.101.1
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/7.101.1/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.101.0...7.101.1)

Updates `@sentry/types` from 7.101.0 to 7.101.1
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/7.101.1/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.101.0...7.101.1)

Updates `posthog-node` from 3.6.2 to 3.6.3
- [Release notes](https://github.com/PostHog/posthog-js-lite/releases)
- [Changelog](https://github.com/PostHog/posthog-js-lite/blob/main/posthog-node/CHANGELOG.md)
- [Commits](https://github.com/PostHog/posthog-js-lite/commits/posthog-node-v3.6.3/posthog-node)

---
updated-dependencies:
- dependency-name: "@sentry/nextjs"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patches
- dependency-name: "@sentry/profiling-node"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patches
- dependency-name: "@sentry/types"
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patches
- dependency-name: posthog-node
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patches
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-16 02:59:15 +00:00
Marc Klingen e60e74478c chore: release v2.5.1
CI/CD / lint (push) Waiting to run
CI/CD / test-docker-build (push) Waiting to run
CI/CD / tests (18) (push) Waiting to run
CI/CD / tests (20) (push) Waiting to run
CI/CD / e2e-tests (push) Waiting to run
CI/CD / all-ci-passed (push) Blocked by required conditions
CI/CD / push-docker-image (push) Blocked by required conditions
release.yml / release (push) Waiting to run
2024-02-16 03:13:32 +01:00
Marc KlingenandGitHub 329f83e844 feat(api): optionally set timestamp when creating a trace (#1181)
Fixes #1157
2024-02-16 01:53:00 +00:00
Marc KlingenandGitHub 28c035da76 refactor: rbac access checks (#1180) 2024-02-16 01:35:22 +00:00
Max Deichmann 4dfeceb9d6 chore: release v2.5.0
CI/CD / lint (push) Waiting to run
CI/CD / test-docker-build (push) Waiting to run
CI/CD / tests (18) (push) Waiting to run
CI/CD / tests (20) (push) Waiting to run
CI/CD / e2e-tests (push) Waiting to run
CI/CD / all-ci-passed (push) Blocked by required conditions
CI/CD / push-docker-image (push) Blocked by required conditions
release.yml / release (push) Waiting to run
2024-02-15 23:14:05 +01:00
Max DeichmannandGitHub df802184a6 fix: fix order of matched models (#1175) 2024-02-15 22:11:50 +00:00
Marc KlingenandGitHub 407d169095 feat(api): add latency to generations endpoints (#1169) 2024-02-15 23:01:24 +01:00
Max DeichmannandGitHub e1958e73d4 fix: fix gpt-4-turbo-preview prices (#1174) 2024-02-15 21:20:47 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2a08c3395c chore(deps): bump the sentry group with 3 updates (#1151)
Bumps the sentry group with 3 updates: [@sentry/nextjs](https://github.com/getsentry/sentry-javascript), [@sentry/profiling-node](https://github.com/getsentry/sentry-javascript) and [@sentry/types](https://github.com/getsentry/sentry-javascript).


Updates `@sentry/nextjs` from 7.100.1 to 7.101.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.100.1...7.101.0)

Updates `@sentry/profiling-node` from 7.100.1 to 7.101.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.100.1...7.101.0)

Updates `@sentry/types` from 7.100.1 to 7.101.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-javascript/compare/7.100.1...7.101.0)

---
updated-dependencies:
- dependency-name: "@sentry/nextjs"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
- dependency-name: "@sentry/profiling-node"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
- dependency-name: "@sentry/types"
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: sentry
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-15 02:19:16 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5c405f4ed8 chore(deps): bump the patches group with 3 updates (#1162)
Bumps the patches group with 3 updates: [next-auth](https://github.com/nextauthjs/next-auth), [posthog-js](https://github.com/PostHog/posthog-js) and [release-it](https://github.com/release-it/release-it).


Updates `next-auth` from 4.24.5 to 4.24.6
- [Release notes](https://github.com/nextauthjs/next-auth/releases)
- [Commits](https://github.com/nextauthjs/next-auth/compare/next-auth@4.24.5...next-auth@4.24.6)

Updates `posthog-js` from 1.105.7 to 1.105.9
- [Release notes](https://github.com/PostHog/posthog-js/releases)
- [Changelog](https://github.com/PostHog/posthog-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/PostHog/posthog-js/compare/1.105.7...v1.105.9)

Updates `release-it` from 17.0.3 to 17.0.5
- [Release notes](https://github.com/release-it/release-it/releases)
- [Changelog](https://github.com/release-it/release-it/blob/main/CHANGELOG.md)
- [Commits](https://github.com/release-it/release-it/compare/17.0.3...17.0.5)

---
updated-dependencies:
- dependency-name: next-auth
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patches
- dependency-name: posthog-js
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patches
- dependency-name: release-it
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: patches
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-15 02:14:33 +00:00
Marc Klingen 25cc29f353 fix(ui): color of checkboxes 2024-02-15 01:36:02 +01:00
503 changed files with 33949 additions and 18284 deletions
+3
View File
@@ -0,0 +1,3 @@
node_modules
build
coverage
+28 -1
View File
@@ -6,7 +6,34 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/" # Location of package manifests
directory: "/worker" # Location of package manifests
schedule:
interval: "daily"
rebase-strategy: "disabled" # use dependabot-rebase-stale
commit-message:
prefix: chore
prefix-development: chore
include: scope
ignore:
- dependency-name: "@types/node"
- dependency-name: "@trpc/*"
groups:
sentry:
patterns:
- "@sentry/*"
prisma:
patterns:
- "prisma"
- "@prisma/*"
next:
patterns:
- "eslint-config-next"
- "next"
patches:
update-types:
- "patch"
- package-ecosystem: npm
directory: "/web" # Location of package manifests
schedule:
interval: "daily"
rebase-strategy: "disabled" # use dependabot-rebase-stale
+50 -15
View File
@@ -12,8 +12,15 @@ on:
branches:
- "main"
defaults:
run:
working-directory: web
jobs:
lint:
defaults:
run:
working-directory: .
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@@ -21,37 +28,45 @@ jobs:
with:
node-version: 20
cache: "npm"
cache-dependency-path: "**/package-lock.json"
- name: install dependencies
run: |
npm ci
- name: Load default env
run: |
cp .env.dev.example .env
- name: lint
- name: lint web
working-directory: ./web
run: npm run lint
- name: lint worker
working-directory: ./worker
run: npm run lint
test-docker-build:
defaults:
run:
working-directory: web
runs-on: ubuntu-latest
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
steps:
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 20
- name: Checkout
uses: actions/checkout@v3
- name: Build Docker image
- name: Build Web Docker image
uses: docker/build-push-action@v4
with:
context: .
context: web
push: false
- name: Build Worker Docker image
uses: docker/build-push-action@v4
with:
context: worker
push: false
tests:
defaults:
run:
working-directory: web
runs-on: ubuntu-latest
strategy:
matrix:
@@ -68,19 +83,26 @@ jobs:
with:
node-version: ${{ matrix.node-version }}
cache: "npm"
cache-dependency-path: "**/package-lock.json"
- name: install dependencies
run: |
npm ci
- name: Load default env
working-directory: .
run: |
cp .env.dev.example .env
cp .env.dev.example web/.env
- name: Run, migrate, seed DB
- name: Run + migrate
working-directory: .
run: |
docker-compose -f docker-compose.dev.yml up -d
sleep 5 # Wait for PostgreSQL to accept connections
- name: Seed DB
run: |
npx --yes prisma migrate reset --force --skip-generate
- name: Build
@@ -93,6 +115,9 @@ jobs:
run: npm run test
e2e-tests:
defaults:
run:
working-directory: web
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@@ -100,19 +125,26 @@ jobs:
with:
node-version: 20
cache: "npm"
cache-dependency-path: "**/package-lock.json"
- name: install dependencies
run: |
npm ci
- name: Load default env
working-directory: .
run: |
cp .env.dev.example .env
cp .env.dev.example web/.env
- name: Run, migrate, seed DB
- name: Run + migrate
working-directory: .
run: |
docker-compose -f docker-compose.dev.yml up -d
sleep 5 # Wait for PostgreSQL to accept connections
- name: Seed DB
run: |
npx --yes prisma migrate reset --force --skip-generate
- name: Build
@@ -133,9 +165,11 @@ jobs:
- name: Successful deploy
if: ${{ !(contains(needs.*.result, 'failure')) }}
run: exit 0
working-directory: .
- name: Failing deploy
if: ${{ contains(needs.*.result, 'failure') }}
run: exit 1
working-directory: .
push-docker-image:
needs: all-ci-passed
@@ -154,6 +188,7 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 20
cache-dependency-path: "**/package-lock.json"
- name: Checkout
uses: actions/checkout@v3
@@ -181,7 +216,7 @@ jobs:
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
context: web
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
+2 -4
View File
@@ -21,13 +21,11 @@
"**/*.{cjs,mjs,ts,tsx,astro,md,mdx,json,yaml,yml}"
],
"mdx.experimentalLanguageServer": true,
"[astro]": {
"editor.defaultFormatter": "astro-build.astro-vscode"
},
"typescript.preferences.importModuleSpecifier": "non-relative",
"docwriter.style": "JSDoc",
"[prisma]": {
"editor.defaultFormatter": "Prisma.prisma"
},
"eslint.lintTask.enable": true
"eslint.lintTask.enable": true,
"eslint.workingDirectories": ["./web", "./worker"]
}
+29 -14
View File
@@ -91,9 +91,9 @@ flowchart TB
The diagram below may not show all relationships if the foreign key is not defined in the database schema. For instance, `trace_id` in the `observation` table is not defined as a foreign key to the `trace` table to allow unordered ingestion of these objects, but it is still a foreign key in the application code.
Full database schema: [prisma/schema.prisma](prisma/schema.prisma)
Full database schema: [web/prisma/schema.prisma](web/prisma/schema.prisma)
<img src="./prisma/database.svg">
<img src="./web/prisma/database.svg">
### Infrastructure & Network Overview
@@ -110,7 +110,14 @@ flowchart LR
App --- DB
```
## Development Setup
## Repository Structure
This repository contains the following packages:
- `web`: is the main application package providing Frontend and Backend APIs for Langfuse
- `worker` (no production yet): contains an application for asynchronous processing of tasks. This package is not yet used in production.
## Development Setup (web package only)
Requirements
@@ -120,25 +127,33 @@ Requirements
**Steps**
1. Fork the the repository and clone it locally
2. Install dependencies
2. Run the development database
```bash
npm install
npm run infra:dev:up
```
3. Run the development database
```bash
docker-compose -f docker-compose.dev.yml up -d
```
4. Create an env file
3. Create an env file
```bash
cp .env.dev.example .env
```
5. Run the migrations
4. CD into the web directory
```bash
cd web
```
5. Install dependencies
```bash
npm install
```
6. Run the migrations
The `schema.prisma` file is in the `web` directory and hence, migrations are applied from there.
```bash
npm run db:migrate
@@ -148,7 +163,7 @@ Requirements
# npm run db:seed:examples
```
6. Start the development server
7. Start the development server
```bash
npm run dev
+13 -11
View File
@@ -119,20 +119,22 @@ See our the [→ Quickstart](https://langfuse.com/docs/get-started) to get start
### Integrations
| Integration | Supports | Description |
| -------------------------------------------------------- | ------------- | ------------------------------------------------------------------------------- |
| [**SDK** - _recommended_](https://langfuse.com/docs/sdk) | Python, JS/TS | Manual instrumentation using the SDKs for full flexibility. |
| [OpenAI](https://langfuse.com/docs/openai) | Python | Automated instrumentation using drop-in replacement of OpenAI SDK. |
| [Langchain](https://langfuse.com/docs/langchain) | Python, JS/TS | Automated instrumentation by passing callback handler to Langchain application. |
| [API](https://langfuse.com/docs/api) | | Directly call the public API. OpenAPI spec available. |
| Integration | Supports | Description |
| ---------------------------------------------------------------- | ------------- | ---------------------------------------------------------------- |
| [**SDK** - _recommended_](https://langfuse.com/docs/sdk) | Python, JS/TS | Manual instrumentation using the SDKs for full flexibility. |
| [OpenAI SDK](https://langfuse.com/docs/integrations/openai) | Python | Automated instrumentation via drop-in replacement of OpenAI SDK. |
| [Langchain](https://langfuse.com/docs/integrations/langchain) | Python, JS/TS | Automated instrumentation via LlamaIndex callback system. |
| [LlamaIndex](https://langfuse.com/docs/integrations/llama-index) | Python, JS/TS | Automated instrumentation via LlamaIndex callback system. |
| [API](https://langfuse.com/docs/api) | | Directly call the public API. OpenAPI spec available. |
External projects/packages that integrate with Langfuse:
| Name | Description |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| [LiteLLM](/https://langfuse.comdocs/litellm) | Use any LLM as a drop in replacement for GPT. Use Azure, OpenAI, Cohere, Anthropic, Ollama, VLLM, Sagemaker, HuggingFace, Replicate (100+ LLMs). |
| [Flowise](https://langfuse.com/docs/flowise) | JS/TS no-code builder for customized LLM flows. |
| [Langflow](https://langfuse.com/docs/langflow) | Python-based UI for LangChain, designed with react-flow to provide an effortless way to experiment and prototype flows. |
| Name | Description |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| [LiteLLM](https://langfuse.com/docs/integrations/litellm) | Use any LLM as a drop in replacement for GPT. Use Azure, OpenAI, Cohere, Anthropic, Ollama, VLLM, Sagemaker, HuggingFace, Replicate (100+ LLMs). |
| [Flowise](https://langfuse.com/docs/integrations/flowise) | JS/TS no-code builder for customized LLM flows. |
| [Langflow](https://langfuse.com/docs/integrations/langflow) | Python-based UI for LangChain, designed with react-flow to provide an effortless way to experiment and prototype flows. |
| [Superagent](https://langfuse.com/docs/integrations/superagent) | Open Source AI Assistant Framework & API for prototyping and deployment of agents. |
## Questions and feedback
+36 -2
View File
@@ -1,11 +1,13 @@
version: "3.5"
services:
langfuse-server:
server:
build:
dockerfile: Dockerfile
dockerfile: ./Dockerfile
context: ./web
depends_on:
- db
- redis
ports:
- "3000:3000"
environment:
@@ -16,8 +18,40 @@ services:
- TELEMETRY_ENABLED=${TELEMETRY_ENABLED:-true}
- NEXT_PUBLIC_SIGN_UP_DISABLED=${NEXT_PUBLIC_SIGN_UP_DISABLED:-false}
- LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES=${LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES:-false}
- REDIS_URL=${REDIS_URL:-redis}
- REDIS_PORT=${REDIS_PORT:-6379}
- REDIS_AUTH=${REDIS_AUTH:-myredissecret}
restart: always
worker:
build:
dockerfile: ./Dockerfile
context: ./worker
depends_on:
- db
- redis
- server
ports:
- "3030:3030"
environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/postgres
- NEXTAUTH_SECRET=mysecret
- TELEMETRY_ENABLED=${TELEMETRY_ENABLED:-true}
- LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES=${LANGFUSE_ENABLE_EXPERIMENTAL_FEATURES:-false}
- PORT=${PORT:-3030}
- REDIS_URL=${REDIS_URL:-redis}
- REDIS_PORT=${REDIS_PORT:-6379}
- REDIS_AUTH=${REDIS_AUTH:-myredissecret}
restart: always
redis:
image: redis
command: >
--requirepass ${REDIS_AUTH:-myredissecret}
restart: always
ports:
- 6379:6379
db:
image: postgres
restart: always
+6
View File
@@ -1,6 +1,12 @@
version: "3.5"
services:
redis:
image: redis
restart: always
ports:
- 6379:6379
db:
image: postgres
restart: always
+1 -1
View File
@@ -15,7 +15,7 @@ groups:
version: 0.0.26
output:
location: local-file-system
path: ../../../generated/openapi-client
path: ../../../web/generated/openapi-client
config:
namespaceExport: Langfuse
allowCustomFetcher: true
+39 -8
View File
@@ -18,18 +18,33 @@ types:
public:
type: optional<boolean>
docs: Public traces are accessible via url without login
TraceWithDetails:
TraceWithDetails: # GET /traces
extends: Trace
properties:
htmlPath:
type: string
docs: Path of trace in Langfuse UI
latency:
type: double
docs: Latency of trace in seconds
totalCost:
type: double
docs: Cost of trace in USD
observations:
type: list<string>
docs: List of observation ids
scores:
type: list<string>
docs: List of score ids
TraceWithFullDetails:
TraceWithFullDetails: # GET traces/[traceID]
extends: Trace
properties:
htmlPath:
type: string
docs: Path of trace in Langfuse UI
totalCost:
type: double
docs: Cost of trace in USD
observations: list<ObservationsView>
scores: list<Score>
Session:
@@ -72,16 +87,31 @@ types:
calculatedInputCost: optional<double>
calculatedOutputCost: optional<double>
calculatedTotalCost: optional<double>
latency: optional<double>
Usage:
docs: Standard interface for usage and cost
properties:
input: optional<integer>
output: optional<integer>
total: optional<integer>
input:
docs: Number of input units (e.g. tokens)
type: optional<integer>
output:
docs: Number of output units (e.g. tokens)
type: optional<integer>
total:
docs: Defaults to input+output if not set
type: optional<integer>
unit: optional<ModelUsageUnit>
inputCost: optional<double>
outputCost: optional<double>
totalCost: optional<double>
inputCost:
docs: USD input cost
type: optional<double>
outputCost:
docs: USD output cost
type: optional<double>
totalCost:
docs: USD total cost, defaults to input+output
type: optional<double>
Score:
properties:
id: string
@@ -129,6 +159,7 @@ types:
# Utilities
ModelUsageUnit:
docs: Unit of usage in Langfuse
enum:
- CHARACTERS
- TOKENS
@@ -7,12 +7,12 @@ service:
endpoints:
create:
method: POST
docs: Create a dataset item, upserts on id
docs: Create a dataset item
path: /dataset-items
request: CreateDatasetItemRequest
response: commons.DatasetItem
get:
docs: Get a specific dataset item
docs: Get a dataset item
method: GET
path: /dataset-items/{id}
path-parameters:
@@ -26,4 +26,6 @@ types:
datasetName: string
input: unknown
expectedOutput: optional<unknown>
id: optional<string>
id:
type: optional<string>
docs: Dataset items are upserted on their id
+9 -3
View File
@@ -7,7 +7,7 @@ service:
base-path: /api/public
endpoints:
batch:
docs: Ingest multiple events to Langfuse
docs: Batched ingestion for Langfuse Tracing
method: POST
path: /ingestion
request:
@@ -31,8 +31,12 @@ types:
sdk-log: SDKLogEvent
# both are legacy
observation-create: CreateObservationEvent
observation-update: UpdateObservationEvent
observation-create:
type: CreateObservationEvent
docs: Deprecated event type
observation-update:
type: UpdateObservationEvent
docs: Deprecated event type
ObservationType:
enum:
@@ -47,6 +51,7 @@ types:
- OpenAIUsage
OpenAIUsage:
docs: Usage interface of OpenAI for improved compatibility.
properties:
promptTokens: optional<integer>
completionTokens: optional<integer>
@@ -128,6 +133,7 @@ types:
TraceBody:
properties:
id: optional<string>
timestamp: optional<datetime>
name: optional<string>
userId: optional<string>
input: optional<unknown>
+48
View File
@@ -0,0 +1,48 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json
imports:
pagination: ./utils/pagination.yml
commons: ./commons.yml
service:
auth: true
base-path: /api/public
endpoints:
daily:
docs: Get daily metrics of the Langfuse project
method: GET
path: /metrics/daily
request:
name: GetDailyMetricsRequest
query-parameters:
page: optional<integer>
limit: optional<integer>
traceName:
type: optional<string>
docs: Optional filter by the name of the trace
userId:
type: optional<string>
docs: Optional filter by the userId associated with the trace
tags:
type: optional<string>
allow-multiple: true
docs: Optional filter for metrics where traces include all of these tags
response: DailyMetrics
types:
DailyMetrics:
properties:
data:
type: list<DailyMetricsDetails>
docs: A list of daily metrics, only days with ingested data are included.
meta: pagination.MetaResponse
DailyMetricsDetails:
properties:
date: date
countTraces: integer
totalCost: double
usage: list<UsageByModel>
UsageByModel:
docs: Daily usage of a given model. Usage corresponds to the unit set for the specific model (e.g. tokens).
properties:
model: string
inputUsage: integer
outputUsage: integer
totalUsage: integer
+1 -1
View File
@@ -7,7 +7,7 @@ service:
base-path: /api/public
endpoints:
get:
docs: Get a specific observation
docs: Get a observation
method: GET
path: /observations/{observationId}
path-parameters:
+1
View File
@@ -7,6 +7,7 @@ service:
base-path: /api/public
endpoints:
get:
docs: Get Project associated with API key
method: GET
path: /projects
response: Projects
+8 -3
View File
@@ -7,7 +7,7 @@ service:
base-path: /api/public
endpoints:
get:
docs: Get a specific prompt
docs: Get a prompt
method: GET
path: /prompts
request:
@@ -17,7 +17,7 @@ service:
version: optional<integer>
response: Prompt
create:
docs: Create a specific prompt
docs: Create a prompt
method: POST
path: /prompts
request: CreatePromptRequest
@@ -27,10 +27,15 @@ types:
CreatePromptRequest:
properties:
name: string
isActive: boolean
isActive:
docs: Should the prompt be promoted to production immediately?
type: boolean
prompt: string
config: optional<unknown>
Prompt:
properties:
name: string
version: integer
prompt: string
config: unknown
+19 -2
View File
@@ -7,13 +7,13 @@ service:
base-path: /api/public
endpoints:
create:
docs: Add a score to the database, upserts on id
docs: Create a score
method: POST
path: /scores
request: CreateScoreRequest
response: commons.Score
get:
docs: Get scores
docs: Get a list of scores
method: GET
path: /scores
request:
@@ -24,6 +24,23 @@ service:
userId: optional<string>
name: optional<string>
response: Scores
get-by-id:
docs: Get a score
method: GET
path: /scores/{scoreId}
path-parameters:
scoreId:
type: string
docs: The unique langfuse identifier of a score
response: commons.Score
delete:
docs: Delete a score
method: DELETE
path: /scores/{scoreId}
path-parameters:
scoreId:
type: string
docs: The unique langfuse identifier of a score
types:
CreateScoreRequest:
properties:
+1 -1
View File
@@ -6,7 +6,7 @@ groups:
version: 0.0.28
output:
location: local-file-system
path: ../../../generated/openapi-server
path: ../../../web/generated/openapi-server
config:
namespaceExport: Langfuse
allowCustomFetcher: true
+206
View File
@@ -387,6 +387,81 @@ paths:
$ref: '#/components/schemas/IngestionEvent'
required:
- batch
/api/public/metrics/daily:
get:
description: Get daily metrics of the Langfuse project
operationId: metrics_daily
tags:
- Metrics
parameters:
- name: page
in: query
required: false
schema:
type: integer
nullable: true
- name: limit
in: query
required: false
schema:
type: integer
nullable: true
- name: traceName
in: query
description: Optional filter by the name of the trace
required: false
schema:
type: string
nullable: true
- name: userId
in: query
description: Optional filter by the userId associated with the trace
required: false
schema:
type: string
nullable: true
- name: tags
in: query
description: Optional filter for metrics where traces include all of these tags
required: false
schema:
type: array
items:
type: string
nullable: true
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/DailyMetrics'
'400':
description: ''
content:
application/json:
schema: {}
'401':
description: ''
content:
application/json:
schema: {}
'403':
description: ''
content:
application/json:
schema: {}
'404':
description: ''
content:
application/json:
schema: {}
'405':
description: ''
content:
application/json:
schema: {}
security: *ref_0
/api/public/observations/{observationId}:
get:
description: Get a specific observation
@@ -761,6 +836,48 @@ paths:
application/json:
schema: {}
security: *ref_0
/api/public/scores/{scoreId}:
delete:
description: Delete a score
operationId: score_delete
tags:
- Score
parameters:
- name: scoreId
in: path
description: The unique langfuse identifier of a score
required: true
schema:
type: string
responses:
'204':
description: ''
'400':
description: ''
content:
application/json:
schema: {}
'401':
description: ''
content:
application/json:
schema: {}
'403':
description: ''
content:
application/json:
schema: {}
'404':
description: ''
content:
application/json:
schema: {}
'405':
description: ''
content:
application/json:
schema: {}
security: *ref_0
/api/public/sessions/{sessionId}:
get:
description: Get a session
@@ -983,6 +1100,17 @@ components:
title: TraceWithDetails
type: object
properties:
htmlPath:
type: string
description: Path of trace in Langfuse UI
latency:
type: number
format: double
description: Latency of trace in seconds
totalCost:
type: number
format: double
description: Cost of trace in USD
observations:
type: array
items:
@@ -994,6 +1122,9 @@ components:
type: string
description: List of score ids
required:
- htmlPath
- latency
- totalCost
- observations
- scores
allOf:
@@ -1002,6 +1133,13 @@ components:
title: TraceWithFullDetails
type: object
properties:
htmlPath:
type: string
description: Path of trace in Langfuse UI
totalCost:
type: number
format: double
description: Cost of trace in USD
observations:
type: array
items:
@@ -1011,6 +1149,8 @@ components:
items:
$ref: '#/components/schemas/Score'
required:
- htmlPath
- totalCost
- observations
- scores
allOf:
@@ -1134,6 +1274,10 @@ components:
type: number
format: double
nullable: true
latency:
type: number
format: double
nullable: true
allOf:
- $ref: '#/components/schemas/Observation'
Usage:
@@ -1720,6 +1864,10 @@ components:
id:
type: string
nullable: true
timestamp:
type: string
format: date-time
nullable: true
name:
type: string
nullable: true
@@ -1936,6 +2084,60 @@ components:
required:
- successes
- errors
DailyMetrics:
title: DailyMetrics
type: object
properties:
data:
type: array
items:
$ref: '#/components/schemas/DailyMetricsDetails'
description: A list of daily metrics, only days with ingested data are included.
meta:
$ref: '#/components/schemas/utilsMetaResponse'
required:
- data
- meta
DailyMetricsDetails:
title: DailyMetricsDetails
type: object
properties:
date:
type: string
countTraces:
type: integer
totalCost:
type: number
format: double
usage:
type: array
items:
$ref: '#/components/schemas/UsageByModel'
required:
- date
- countTraces
- totalCost
- usage
UsageByModel:
title: UsageByModel
type: object
description: >-
Daily usage of a given model. Usage corresponds to the unit set for the
specific model (e.g. tokens).
properties:
model:
type: string
inputUsage:
type: integer
outputUsage:
type: integer
totalUsage:
type: integer
required:
- model
- inputUsage
- outputUsage
- totalUsage
Observations:
title: Observations
type: object
@@ -1993,6 +2195,8 @@ components:
type: boolean
prompt:
type: string
config:
nullable: true
required:
- name
- isActive
@@ -2007,10 +2211,12 @@ components:
type: integer
prompt:
type: string
config: {}
required:
- name
- version
- prompt
- config
CreateScoreRequest:
title: CreateScoreRequest
type: object
+134 -11
View File
@@ -46,7 +46,7 @@
"_type": "endpoint",
"name": "Create",
"request": {
"description": "Create a dataset item, upserts on id",
"description": "Create a dataset item",
"url": {
"raw": "{{baseUrl}}/api/public/dataset-items",
"host": [
@@ -79,7 +79,7 @@
"_type": "endpoint",
"name": "Get",
"request": {
"description": "Get a specific dataset item",
"description": "Get a dataset item",
"url": {
"raw": "{{baseUrl}}/api/public/dataset-items/:id",
"host": [
@@ -301,7 +301,7 @@
"_type": "endpoint",
"name": "Batch",
"request": {
"description": "Ingest multiple events to Langfuse",
"description": "Batched ingestion for Langfuse Tracing",
"url": {
"raw": "{{baseUrl}}/api/public/ingestion",
"host": [
@@ -320,7 +320,7 @@
"auth": null,
"body": {
"mode": "raw",
"raw": "{\n \"batch\": [\n {\n \"type\": \"trace-create\",\n \"body\": {\n \"id\": \"example\",\n \"name\": \"example\",\n \"userId\": \"example\",\n \"input\": \"UNKNOWN\",\n \"output\": \"UNKNOWN\",\n \"sessionId\": \"example\",\n \"release\": \"example\",\n \"version\": \"example\",\n \"metadata\": \"UNKNOWN\",\n \"tags\": [\n \"example\"\n ],\n \"public\": true\n },\n \"id\": \"example\",\n \"timestamp\": \"example\",\n \"metadata\": \"UNKNOWN\"\n }\n ]\n}",
"raw": "{\n \"batch\": [\n {\n \"type\": \"trace-create\",\n \"body\": {\n \"id\": \"example\",\n \"timestamp\": \"1994-11-05T13:15:30Z\",\n \"name\": \"example\",\n \"userId\": \"example\",\n \"input\": \"UNKNOWN\",\n \"output\": \"UNKNOWN\",\n \"sessionId\": \"example\",\n \"release\": \"example\",\n \"version\": \"example\",\n \"metadata\": \"UNKNOWN\",\n \"tags\": [\n \"example\"\n ],\n \"public\": true\n },\n \"id\": \"example\",\n \"timestamp\": \"example\",\n \"metadata\": \"UNKNOWN\"\n }\n ]\n}",
"options": {
"raw": {
"language": "json"
@@ -332,6 +332,65 @@
}
]
},
{
"_type": "container",
"description": null,
"name": "Metrics",
"item": [
{
"_type": "endpoint",
"name": "Daily",
"request": {
"description": "Get daily metrics of the Langfuse project",
"url": {
"raw": "{{baseUrl}}/api/public/metrics/daily?page=&limit=&traceName=&userId=&tags=",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"public",
"metrics",
"daily"
],
"query": [
{
"key": "page",
"value": "",
"description": null
},
{
"key": "limit",
"value": "",
"description": null
},
{
"key": "traceName",
"value": "",
"description": "Optional filter by the name of the trace"
},
{
"key": "userId",
"value": "",
"description": "Optional filter by the userId associated with the trace"
},
{
"key": "tags",
"value": "",
"description": "Optional filter for metrics where traces include all of these tags"
}
],
"variable": []
},
"header": [],
"method": "GET",
"auth": null,
"body": null
},
"response": []
}
]
},
{
"_type": "container",
"description": null,
@@ -341,7 +400,7 @@
"_type": "endpoint",
"name": "Get",
"request": {
"description": "Get a specific observation",
"description": "Get a observation",
"url": {
"raw": "{{baseUrl}}/api/public/observations/:observationId",
"host": [
@@ -441,7 +500,7 @@
"_type": "endpoint",
"name": "Get",
"request": {
"description": null,
"description": "Get Project associated with API key",
"url": {
"raw": "{{baseUrl}}/api/public/projects",
"host": [
@@ -473,7 +532,7 @@
"_type": "endpoint",
"name": "Get",
"request": {
"description": "Get a specific prompt",
"description": "Get a prompt",
"url": {
"raw": "{{baseUrl}}/api/public/prompts?name=&version=",
"host": [
@@ -509,7 +568,7 @@
"_type": "endpoint",
"name": "Create",
"request": {
"description": "Create a specific prompt",
"description": "Create a prompt",
"url": {
"raw": "{{baseUrl}}/api/public/prompts",
"host": [
@@ -528,7 +587,7 @@
"auth": null,
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"example\",\n \"isActive\": true,\n \"prompt\": \"example\"\n}",
"raw": "{\n \"name\": \"example\",\n \"isActive\": true,\n \"prompt\": \"example\",\n \"config\": \"UNKNOWN\"\n}",
"options": {
"raw": {
"language": "json"
@@ -549,7 +608,7 @@
"_type": "endpoint",
"name": "Create",
"request": {
"description": "Add a score to the database, upserts on id",
"description": "Create a score",
"url": {
"raw": "{{baseUrl}}/api/public/scores",
"host": [
@@ -582,7 +641,7 @@
"_type": "endpoint",
"name": "Get",
"request": {
"description": "Get scores",
"description": "Get a list of scores",
"url": {
"raw": "{{baseUrl}}/api/public/scores?page=&limit=&userId=&name=",
"host": [
@@ -623,6 +682,70 @@
"body": null
},
"response": []
},
{
"_type": "endpoint",
"name": "Get By Id",
"request": {
"description": "Get a score",
"url": {
"raw": "{{baseUrl}}/api/public/scores/:scoreId",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"public",
"scores",
":scoreId"
],
"query": [],
"variable": [
{
"key": "scoreId",
"value": "",
"description": "The unique langfuse identifier of a score"
}
]
},
"header": [],
"method": "GET",
"auth": null,
"body": null
},
"response": []
},
{
"_type": "endpoint",
"name": "Delete",
"request": {
"description": "Delete a score",
"url": {
"raw": "{{baseUrl}}/api/public/scores/:scoreId",
"host": [
"{{baseUrl}}"
],
"path": [
"api",
"public",
"scores",
":scoreId"
],
"query": [],
"variable": [
{
"key": "scoreId",
"value": "",
"description": "The unique langfuse identifier of a score"
}
]
},
"header": [],
"method": "DELETE",
"auth": null,
"body": null
},
"response": []
}
]
},
+198 -16575
View File
File diff suppressed because it is too large Load Diff
+12 -166
View File
@@ -1,176 +1,22 @@
{
"name": "langfuse-core",
"version": "2.4.3",
"private": true,
"name": "langfuse",
"version": "2.7.0",
"scripts": {
"prebuild": "cp generated/openapi-client/openapi.yml public/openapi-client.yml && cp generated/openapi-server/openapi.yml public/openapi-server.yml",
"build": "next build",
"dev": "next dev",
"dx": "npm i && npm run db:reset && npm run db:seed:examples && npm run dev",
"postinstall": "prisma generate",
"lint": "next lint",
"lint:fix": "next lint --fix",
"prettier": "prettier --write ./src *.{ts,js}",
"clean": "rm -rf node_modules",
"start": "next start",
"test": "jest --runInBand",
"test:watch": "jest --watch --runInBand",
"test:e2e": "playwright test",
"infra:dev:up": "docker-compose -f docker-compose.dev.yml up -d",
"infra:dev:down": "docker-compose -f docker-compose.dev.yml down",
"db:migrate": "DISABLE_ERD=false npx prisma migrate dev",
"db:reset": "npx prisma migrate reset",
"db:seed": "npx prisma db seed",
"db:seed:examples": "npx prisma db seed -- --environment examples",
"release": "release-it",
"models:migrate": "tsx scripts/model-match.ts"
},
"prisma": {
"seed": "ts-node -r tsconfig-paths/register --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
},
"dependencies": {
"@anthropic-ai/tokenizer": "^0.0.4",
"@aws-sdk/client-s3": "^3.507.0",
"@aws-sdk/lib-storage": "^3.511.0",
"@aws-sdk/s3-request-presigner": "^3.507.0",
"@headlessui/react": "^1.7.18",
"@heroicons/react": "^2.1.1",
"@hookform/resolvers": "^3.3.4",
"@next-auth/prisma-adapter": "^1.0.7",
"@prisma/client": "^5.9.1",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-hover-card": "^1.0.7",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toggle": "^1.0.3",
"@radix-ui/react-tooltip": "^1.0.7",
"@react-email/components": "^0.0.14",
"@react-email/render": "^0.0.12",
"@sentry/nextjs": "^7.100.1",
"@sentry/profiling-node": "^7.100.1",
"@sentry/types": "^7.88.0",
"@t3-oss/env-nextjs": "^0.8.0",
"@tailwindcss/forms": "^0.5.7",
"@tanstack/react-query": "^4.36.1",
"@tanstack/react-table": "^8.11.8",
"@tremor/react": "^3.11.1",
"@trpc/client": "^10.45.0",
"@trpc/next": "^10.45.0",
"@trpc/react-query": "^10.45.0",
"@trpc/server": "^10.45.0",
"bcryptjs": "^2.4.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"cmdk": "^0.2.1",
"core-js": "^3.35.1",
"cors": "^2.8.5",
"date-fns": "^3.3.1",
"decimal.js": "^10.4.3",
"exponential-backoff": "^3.1.1",
"js-tiktoken": "^1.0.10",
"lodash": "^4.17.21",
"lucide-react": "^0.330.0",
"next": "^14.1.0",
"next-auth": "^4.24.5",
"next-query-params": "^5.0.0",
"nodemailer": "^6.9.9",
"posthog-js": "^1.105.7",
"posthog-node": "^3.6.2",
"react": "18.2.0",
"react-day-picker": "^8.10.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.50.1",
"react-icons": "^5.0.1",
"react-responsive": "^9.0.2",
"react18-json-view": "^0.2.7",
"sonner": "^1.4.0",
"superjson": "2.2.1",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7",
"use-query-params": "^2.2.1",
"uuid": "^9.0.1",
"zod": "^3.22.4"
"infra:dev:up": "docker-compose -f ./docker-compose.dev.yml up -d",
"infra:dev:down": "docker-compose -f ./docker-compose.dev.yml down",
"dev": "npm run dev --prefix worker/ & npm run dev --prefix web/",
"postinstall": "cd worker && npm install && cd ../web && npm install",
"dx": "dotenv -e .env -- npm i && npm run infra:dev:up && cd web && npm run db:reset && npm run db:seed:examples && cd .. && npm run dev"
},
"author": "",
"license": "MIT",
"devDependencies": {
"@jedmao/location": "^3.0.0",
"@mermaid-js/mermaid-cli": "^10.7.0",
"@playwright/test": "^1.41.2",
"@release-it/bumper": "^6.0.1",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"@types/bcryptjs": "^2.4.6",
"@types/cors": "^2.8.17",
"@types/eslint": "^8.56.2",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.202",
"@types/node": "20.10.5",
"@types/nodemailer": "^6.4.14",
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"autoprefixer": "^10.4.17",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"dotenv-cli": "^7.3.0",
"eslint": "^8.56.0",
"eslint-config-next": "^14.1.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"postcss": "^8.4.35",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.11",
"prisma": "^5.9.1",
"prisma-erd-generator": "^1.11.2",
"release-it": "^17.0.3",
"tailwindcss": "^3.4.1",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.7.1",
"typescript": "^5.3.3"
},
"ct3aMetadata": {
"initVersion": "7.13.0"
},
"optionalDependencies": {
"crisp-sdk-web": "^1.0.21"
},
"release-it": {
"git": {
"commitMessage": "chore: release v${version}",
"tagName": "v${version}"
},
"github": {
"release": true,
"web": true,
"autoGenerate": true,
"releaseName": "v${version}",
"comments": {
"submit": true,
"issue": ":rocket: _This issue has been resolved in v${version}. See [${releaseName}](${releaseUrl}) for release notes._",
"pr": ":rocket: _This pull request is included in v${version}. See [${releaseName}](${releaseUrl}) for release notes._"
}
},
"plugins": {
"@release-it/bumper": {
"out": {
"file": "./src/constants/VERSION.ts",
"type": "application/typescript"
}
}
}
"prettier": "^3.2.5"
}
}
-603
View File
@@ -1,603 +0,0 @@
import { PrismaClient } from "@prisma/client";
import {
hashSecretKey,
getDisplaySecretKey,
} from "@/src/features/public-api/lib/apiKeys";
import { hash } from "bcryptjs";
import { parseArgs } from "node:util";
import { ModelUsageUnit } from "@/src/constants";
const options = {
environment: { type: "string" },
} as const;
const prisma = new PrismaClient();
const TRACE_VOLUME = 100;
async function main() {
const environment = parseArgs({
options,
}).values.environment;
const user = await prisma.user.upsert({
where: { id: "user-1" },
update: {
name: "Demo User",
email: "demo@langfuse.com",
password: await hash("password", 12),
},
create: {
id: "user-1",
name: "Demo User",
email: "demo@langfuse.com",
password: await hash("password", 12),
},
});
const seedProjectId = "7a88fb47-b4e2-43b8-a06c-a5ce950dc53a";
const project1 = await prisma.project.upsert({
where: { id: seedProjectId },
update: {
name: "llm-app",
},
create: {
id: seedProjectId,
name: "llm-app",
members: {
create: {
role: "OWNER",
userId: user.id,
},
},
},
});
const prompt = await prisma.prompt.upsert({
where: {
projectId_name_version: {
projectId: seedProjectId,
name: "summary-prompt",
version: 1,
},
},
create: {
name: "summary-prompt",
project: { connect: { id: seedProjectId } },
prompt: "prompt {{variable}} {{anotherVariable}}",
isActive: true,
version: 1,
createdBy: "user-1",
},
update: {},
});
const seedApiKey = {
id: "seed-api-key",
secret: process.env.SEED_SECRET_KEY ?? "sk-lf-1234567890",
public: "pk-lf-1234567890",
note: "seeded key",
};
if (!(await prisma.apiKey.findUnique({ where: { id: seedApiKey.id } }))) {
await prisma.apiKey.create({
data: {
note: seedApiKey.note,
id: seedApiKey.id,
publicKey: seedApiKey.public,
hashedSecretKey: await hashSecretKey(seedApiKey.secret),
displaySecretKey: getDisplaySecretKey(seedApiKey.secret),
project: {
connect: {
id: project1.id,
},
},
},
});
}
// Do not run the following for local docker compose setup
if (environment === "examples") {
const project2 = await prisma.project.upsert({
where: { id: "239ad00f-562f-411d-af14-831c75ddd875" },
create: {
name: "demo-app",
apiKeys: {
create: [
{
note: "seeded key",
hashedSecretKey: await hashSecretKey("sk-lf-asdfghjkl"),
displaySecretKey: getDisplaySecretKey("sk-lf-asdfghjkl"),
publicKey: "pk-lf-asdfghjkl",
},
],
},
members: {
create: {
role: "OWNER",
userId: user.id,
},
},
},
update: {},
});
const promptIds: string[] = [];
const prompts = [
{
id: `prompt-${Math.floor(Math.random() * 1000000000)}`,
projectId: project2.id,
createdBy: "user-1",
prompt: "Prompt 1 content",
name: "Prompt 1",
version: 1,
isActive: true,
},
{
id: `prompt-${Math.floor(Math.random() * 1000000000)}`,
projectId: project2.id,
createdBy: "user-1",
prompt: "Prompt 2 content",
name: "Prompt 2",
version: 1,
isActive: true,
},
{
id: `prompt-${Math.floor(Math.random() * 1000000000)}`,
projectId: project2.id,
createdBy: "API",
prompt: "Prompt 3 content",
name: "Prompt 3 by API",
version: 1,
isActive: true,
},
];
for (const prompt of prompts) {
await prisma.prompt.create({
data: {
id: prompt.id,
projectId: prompt.projectId,
createdBy: prompt.createdBy,
prompt: prompt.prompt,
name: prompt.name,
version: prompt.version,
isActive: prompt.isActive,
},
});
promptIds.push(prompt.id);
}
const promptVersionsWithVariables = [
{
id: `prompt-${Math.floor(Math.random() * 1000000000)}`,
projectId: project2.id,
createdBy: "user-1",
prompt: "Prompt 4 version 1 content with {{variable}}",
name: "Prompt 4 with variable",
version: 1,
isActive: false,
},
{
id: `prompt-${Math.floor(Math.random() * 1000000000)}`,
projectId: project2.id,
createdBy: "user-1",
prompt: "Prompt 4 version 2 content with {{variable}}",
name: "Prompt 4 with variable",
version: 2,
isActive: true,
},
{
id: `prompt-${Math.floor(Math.random() * 1000000000)}`,
projectId: project2.id,
createdBy: "user-1",
prompt: "Prompt 4 version 3 content with {{variable}}",
name: "Prompt 4 with variable",
version: 3,
isActive: false,
},
];
for (const version of promptVersionsWithVariables) {
await prisma.prompt.create({
data: {
id: version.id,
projectId: version.projectId,
createdBy: version.createdBy,
prompt: version.prompt,
name: version.name,
version: version.version,
isActive: version.isActive,
},
});
promptIds.push(version.id);
}
const promptName = "Prompt with Longer Name";
const projectId = project2.id;
const createdBy = "user-1";
for (let i = 1; i <= 20; i++) {
const promptId = `prompt-${Math.floor(Math.random() * 1000000000)}`;
await prisma.prompt.create({
data: {
id: promptId,
projectId: projectId,
createdBy: createdBy,
prompt: `${promptName} version ${i} content`,
name: promptName,
version: i,
isActive: i === 20,
},
});
promptIds.push(promptId);
}
const generationIds: string[] = [];
const envTags = [null, "development", "staging", "production"];
const colorTags = [null, "red", "blue", "yellow"];
for (let i = 0; i < TRACE_VOLUME; i++) {
// print progress to console with a progress bar that refreshes every 10 iterations
if ((i + 1) % 10 === 0 || i === TRACE_VOLUME - 1) {
process.stdout.clearLine(0);
process.stdout.cursorTo(0);
process.stdout.write(`Seeding ${i + 1} of ${TRACE_VOLUME}`);
}
// random date within last 90 days, with a linear bias towards more recent dates
const traceTs = new Date(
Date.now() -
Math.floor(Math.random() ** 1.5 * 90 * 24 * 60 * 60 * 1000),
);
const envTag = envTags[Math.floor(Math.random() * envTags.length)];
const colorTag = colorTags[Math.floor(Math.random() * colorTags.length)];
const tags = [envTag, colorTag].filter((tag) => tag !== null);
const projectId = [project1.id, project2.id][i % 2] as string;
const trace = await prisma.trace.create({
data: {
id: `trace-${Math.floor(Math.random() * 1000000000)}`,
timestamp: traceTs,
name: ["generate-outreach", "label-inbound", "draft-response"][
i % 3
] as string,
metadata: {
user: `user-${i}@langfuse.com`,
},
tags: tags as string[],
project: {
connect: { id: projectId },
},
userId: `user-${i % 10}`,
session:
Math.random() > 0.3
? {
connectOrCreate: {
where: {
id_projectId: {
id: `session-${i % 10}`,
projectId: projectId,
},
},
create: {
id: `session-${i % 10}`,
projectId: projectId,
},
},
}
: undefined,
input:
Math.random() > 0.3
? "I'm looking for a React component"
: undefined,
output:
Math.random() > 0.3
? "What kind of component are you looking for?"
: undefined,
scores: {
createMany: {
data: [
...(Math.random() > 0.5
? [
{
name: "feedback",
value: Math.floor(Math.random() * 3) - 1,
timestamp: traceTs,
},
]
: []),
...(Math.random() > 0.7
? [
{
name: "sentiment",
value: Math.floor(Math.random() * 10) - 5,
timestamp: traceTs,
},
]
: []),
],
},
},
},
});
const existingSpanIds: string[] = [];
for (let j = 0; j < Math.floor(Math.random() * 10) + 1; j++) {
// add between 1 and 30 ms to trace timestamp
const spanTsStart = new Date(
traceTs.getTime() + Math.floor(Math.random() * 30),
);
// random duration of upto 30ms
const spanTsEnd = new Date(
spanTsStart.getTime() + Math.floor(Math.random() * 30),
);
const span = await prisma.observation.create({
data: {
type: "SPAN",
id: `span-${Math.floor(Math.random() * 1000000000)}`,
startTime: spanTsStart,
endTime: spanTsEnd,
name: `span-${i}-${j}`,
metadata: {
user: `user-${i}@langfuse.com`,
},
project: { connect: { id: trace.projectId } },
traceId: trace.id,
// if this is the first span or in 50% of cases, add no parent; otherwise randomly select parent from existing spans
...(existingSpanIds.length === 0 || Math.random() > 0.5
? {}
: {
parentObservationId:
existingSpanIds[
Math.floor(Math.random() * existingSpanIds.length)
],
}),
},
});
existingSpanIds.push(span.id);
for (let k = 0; k < Math.floor(Math.random() * 2) + 1; k++) {
// random start and end times within span
const generationTsStart = new Date(
spanTsStart.getTime() +
Math.floor(
Math.random() * (spanTsEnd.getTime() - spanTsStart.getTime()),
),
);
const generationTsEnd = new Date(
generationTsStart.getTime() +
Math.floor(
Math.random() *
(spanTsEnd.getTime() - generationTsStart.getTime()),
),
);
const promptTokens = Math.floor(Math.random() * 1000) + 300;
const completionTokens = Math.floor(Math.random() * 500) + 100;
const models = [
"gpt-3.5-turbo",
"gpt-4",
"gpt-4-32k-0613",
"gpt-3.5-turbo-16k-0613",
"claude-instant-1",
"claude-2.1",
"gpt-4-vision-preview",
"MIXTRAL-8X7B",
];
const model = models[Math.floor(Math.random() * models.length)];
const promptId =
promptIds[Math.floor(Math.random() * promptIds.length)];
const generation = await prisma.observation.create({
data: {
type: "GENERATION",
id: `generation-${Math.floor(Math.random() * 1000000000)}`,
startTime: generationTsStart,
endTime: generationTsEnd,
name: `generation-${i}-${j}-${k}`,
project: { connect: { id: trace.projectId } },
prompt: { connect: { id: promptId } },
input:
Math.random() > 0.5
? [
{
role: "system",
content: "Be a helpful assistant",
},
{
role: "user",
content: "How can i create a React component?",
},
]
: {
input: "How can i create a React component?",
retrievedDocuments: [
{
title: "How to create a React component",
url: "https://www.google.com",
description: "A guide to creating React components",
},
{
title: "React component creation",
url: "https://www.google.com",
description: "A guide to creating React components",
},
],
},
output: {
completion: `Creating a React component can be done in two ways: as a functional component or as a class component. Let's start with a basic example of both.
1. **Functional Component**:
A functional component is just a plain JavaScript function that accepts props as an argument, and returns a React element. Here's how you can create one:
'import React from 'react'; function Greeting(props) { return <h1>Hello, {props.name}</h1>; } export default Greeting;'
To use this component in another file, you can do:
'import Greeting from './Greeting'; function App() { return ( <div> <Greeting name="John" /> </div> ); } export default App;'
2. **Class Component**:
You can also define components as classes in React. These have some additional features compared to functional components:
'import React, { Component } from 'react'; class Greeting extends Component { render() { return <h1>Hello, {this.props.name}</h1>; } } export default Greeting;'
And here's how to use this component:
'import Greeting from './Greeting'; class App extends Component { render() { return ( <div> <Greeting name="John" /> </div> ); } } export default App;'
With the advent of hooks in React, functional components can do everything that class components can do and hence, the community has been favoring functional components over class components.
Remember to import React at the top of your file whenever you're creating a component, because JSX transpiles to 'React.createElement' calls under the hood.`,
},
model: model,
internalModel: model,
modelParameters: {
temperature:
Math.random() > 0.9 ? undefined : Math.random().toFixed(2),
topP:
Math.random() > 0.9 ? undefined : Math.random().toFixed(2),
maxTokens:
Math.random() > 0.9
? undefined
: Math.floor(Math.random() * 1000),
},
metadata: {
user: `user-${i}@langfuse.com`,
},
promptTokens,
completionTokens,
totalTokens: promptTokens + completionTokens,
parentObservationId: span.id,
traceId: trace.id,
...{
...(Math.random() > 0.5 && trace.projectId === prompt.projectId
? { prompt: { connect: { id: prompt.id } } }
: {}),
},
unit: ModelUsageUnit.Tokens,
},
});
if (Math.random() > 0.6)
await prisma.score.create({
data: {
name: "quality",
value: Math.random() * 2 - 1,
observationId: generation.id,
traceId: trace.id,
},
});
if (Math.random() > 0.6)
await prisma.score.create({
data: {
name: "conciseness",
value: Math.random() * 2 - 1,
observationId: generation.id,
traceId: trace.id,
},
});
generationIds.push(generation.id);
for (let l = 0; l < Math.floor(Math.random() * 2); l++) {
// random start time within span
const eventTs = new Date(
spanTsStart.getTime() +
Math.floor(
Math.random() * (spanTsEnd.getTime() - spanTsStart.getTime()),
),
);
await prisma.observation.create({
data: {
type: "EVENT",
id: `event-${Math.floor(Math.random() * 1000000000)}`,
startTime: eventTs,
name: `event-${i}-${j}-${k}-${l}`,
metadata: {
user: `user-${i}@langfuse.com`,
},
parentObservationId: span.id,
traceId: trace.id,
project: { connect: { id: trace.projectId } },
},
});
}
}
}
}
for (let datasetNumber = 0; datasetNumber < 2; datasetNumber++) {
const dataset = await prisma.dataset.create({
data: {
name: `demo-dataset-${datasetNumber}`,
projectId: project2.id,
},
});
for (let datasetRunNumber = 0; datasetRunNumber < 2; datasetRunNumber++) {
const datasetRun = await prisma.datasetRuns.create({
data: {
name: `demo-dataset-run-${datasetRunNumber}`,
datasetId: dataset.id,
},
});
for (let runNumber = 0; runNumber < 10; runNumber++) {
//pick randomly from existingSpanIds
const sourceObservationId =
generationIds[Math.floor(Math.random() * generationIds.length)];
const runObservationId =
generationIds[Math.floor(Math.random() * generationIds.length)];
const datasetItem = await prisma.datasetItem.create({
data: {
datasetId: dataset.id,
sourceObservationId:
Math.random() > 0.5 ? sourceObservationId : undefined,
input: [
{
role: "user",
content: "How can i create a React component?",
},
],
expectedOutput:
"Creating a React component can be done in two ways: as a functional component or as a class component. Let's start with a basic example of both.",
},
});
await prisma.datasetRunItems.create({
data: {
datasetItemId: datasetItem.id,
observationId: runObservationId!,
datasetRunId: datasetRun.id,
},
});
}
}
}
}
}
main()
.then(async () => {
await prisma.$disconnect();
})
.catch(async (e) => {
console.error(e);
await prisma.$disconnect();
process.exit(1);
});
Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 KiB

-1
View File
@@ -1 +0,0 @@
export const VERSION = "v2.4.3";
@@ -1,88 +0,0 @@
import {
dateTimeAggregationOptions,
dateTimeAggregationSettings,
} from "@/src/features/dashboard/lib/timeseries-aggregation";
import { z } from "zod";
import {
createTRPCRouter,
protectedProjectProcedure,
} from "@/src/server/api/trpc";
import { executeQuery } from "@/src/server/api/services/query-builder";
import { sqlInterface } from "@/src/server/api/services/sqlInterface";
export const dashboardRouter = createTRPCRouter({
chart: protectedProjectProcedure
.input(sqlInterface.extend({ projectId: z.string() }))
.query(async ({ input, ctx }) => {
return await executeQuery(ctx.prisma, input.projectId, input);
}),
scores: protectedProjectProcedure
.input(
z.object({
projectId: z.string(),
agg: z.enum(dateTimeAggregationOptions),
}),
)
.query(async ({ input, ctx }) => {
// queryRawUnsafe to add input.agg to the WHERE clause
const output = await ctx.prisma.$queryRawUnsafe<
{
date_trunc: Date;
values: {
[key: string]: number;
} | null;
}[]
>(`
WITH timeseries AS (
SELECT
date_trunc('${
dateTimeAggregationSettings[input.agg].date_trunc
}', dt) as date_trunc
FROM generate_series(
NOW() - INTERVAL '${input.agg}', NOW(), INTERVAL '1 minute'
) as dt
WHERE dt > NOW() - INTERVAL '${input.agg}'
GROUP BY 1
),
metrics AS (
SELECT
date_trunc('${
dateTimeAggregationSettings[input.agg].date_trunc
}', scores.timestamp) as date_trunc,
scores.name as metric_name,
AVG(value) as avg_value
FROM scores
LEFT JOIN traces ON scores.trace_id = traces.id
WHERE scores.timestamp > NOW() - INTERVAL '${input.agg}'
AND traces.project_id = '${input.projectId}'
GROUP BY 1,2
),
json_metrics AS (
SELECT
date_trunc,
jsonb_object_agg(metric_name, avg_value) as values
FROM metrics
GROUP BY 1
)
SELECT
timeseries.date_trunc,
json_metrics.values as values
FROM timeseries
LEFT JOIN json_metrics ON timeseries.date_trunc = json_metrics.date_trunc
ORDER BY 1
`);
return output.map((row) => ({
...row,
values: row.values
? Object.entries(row.values).map(([label, value]) => ({
label: "avg_" + label,
value,
}))
: [],
ts: row.date_trunc.getTime(),
}));
}),
});
-206
View File
@@ -1,206 +0,0 @@
import { type NextApiRequest, type NextApiResponse } from "next";
import { z } from "zod";
import { cors, runMiddleware } from "@/src/features/public-api/server/cors";
import { prisma } from "@/src/server/db";
import { verifyAuthHeaderAndReturnScope } from "@/src/features/public-api/server/apiAuth";
import { Prisma } from "@prisma/client";
import { paginationZod } from "@/src/utils/zod";
const GetUsageSchema = z.object({
...paginationZod,
group_by: z.enum(["trace_name"]).nullish(),
trace_name: z.string().nullish(),
});
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
await runMiddleware(req, res, cors);
// CHECK AUTH
const authCheck = await verifyAuthHeaderAndReturnScope(
req.headers.authorization,
);
if (!authCheck.validKey)
return res.status(401).json({
message: authCheck.error,
});
// END CHECK AUTH
try {
if (req.method === "GET") {
if (authCheck.scope.accessLevel !== "all") {
return res.status(401).json({
message:
"Access denied - need to use basic auth with secret key to GET scores",
});
}
const obj = GetUsageSchema.parse(req.query); // uses query and not body
const traceNameCondition = obj.trace_name
? Prisma.sql`AND t.name = ${obj.trace_name}`
: Prisma.empty;
if (obj.group_by === undefined) {
const usage = await prisma.$queryRaw`
WITH model_usage AS (
SELECT
DATE_TRUNC('DAY',
o.start_time) observation_day,
o.model,
SUM(o.prompt_tokens) prompt_tokens,
SUM(o.completion_tokens) completion_tokens,
SUM(o.total_tokens) total_tokens
FROM
traces t
LEFT JOIN observations o ON o.trace_id = t.id
WHERE o.start_time IS NOT NULL
AND o.project_id = ${authCheck.scope.projectId}
AND t.project_id = ${authCheck.scope.projectId}
${traceNameCondition}
GROUP BY 1,2
order by 1,2
),
daily_usage AS (
SELECT
observation_day,
json_agg(json_build_object('model',
model,
'prompt_tokens',
prompt_tokens,
'completion_tokens',
completion_tokens,
'total_tokens',
total_tokens)) daily_usage_json
FROM model_usage
group by 1
)
SELECT
observation_day "date",
daily_usage_json usage
FROM daily_usage
ORDER BY 1 desc
LIMIT ${obj.limit} OFFSET ${(obj.page - 1) * obj.limit}
`;
const totalItemsRes = await prisma.$queryRaw<{ count: bigint }[]>`
SELECT
count(DISTINCT DATE_TRUNC('DAY', observations.start_time))
FROM
observations
JOIN traces ON observations.trace_id = traces.id
WHERE traces.project_id = ${authCheck.scope.projectId}
`;
const totalItems =
totalItemsRes[0] !== undefined ? Number(totalItemsRes[0].count) : 0;
return res.status(200).json({
data: usage,
meta: {
page: obj.page,
limit: obj.limit,
totalItems,
totalPages: Math.ceil(totalItems / obj.limit),
},
});
} else if (obj.group_by === "trace_name") {
const usage = await prisma.$queryRaw`
WITH model_usage AS (
SELECT
t."name" trace_name,
DATE_TRUNC('DAY',
o.start_time) observation_day,
o.model,
SUM(o.prompt_tokens) prompt_tokens,
SUM(o.completion_tokens) completion_tokens,
SUM(o.total_tokens) total_tokens
FROM
traces t
LEFT JOIN observations o ON o.trace_id = t.id
WHERE o.start_time IS NOT NULL
AND t.project_id = ${authCheck.scope.projectId}
AND o.project_id = ${authCheck.scope.projectId}
${traceNameCondition}
GROUP BY 1,2,3
order by 1,2,3
),
daily_usage AS (
SELECT
trace_name,
observation_day,
json_agg(json_build_object('model',
model,
'prompt_tokens',
prompt_tokens,
'completion_tokens',
completion_tokens,
'total_tokens',
total_tokens)) daily_usage_json
FROM model_usage
WHERE prompt_tokens > 0
OR completion_tokens > 0
OR total_tokens > 0
group by 1,2
order by 1,2 desc
),
all_trace_names AS (
SELECT t."name" trace_name
FROM traces t
WHERE t.project_id = ${authCheck.scope.projectId}
${traceNameCondition}
GROUP BY 1
)
SELECT
all_trace_names.trace_name,
json_agg(json_build_object(
'date',
observation_day,
'usage',
daily_usage_json
)) metrics
FROM all_trace_names
LEFT JOIN daily_usage ON all_trace_names.trace_name = daily_usage.trace_name
group by 1
ORDER BY 1
LIMIT ${obj.limit} OFFSET ${(obj.page - 1) * obj.limit}
`;
const totalItemsRes = await prisma.$queryRaw<{ count: bigint }[]>`
SELECT
count(DISTINCT CASE WHEN "name" IS NULL THEN 'COUNT_NULL' ELSE "name" END)
FROM
traces
WHERE project_id = ${authCheck.scope.projectId}
`;
const totalItems =
totalItemsRes[0] !== undefined ? Number(totalItemsRes[0].count) : 0;
return res.status(200).json({
data: usage,
meta: {
page: obj.page,
limit: obj.limit,
totalItems,
totalPages: Math.ceil(totalItems / obj.limit),
},
});
} else {
return res.status(400).json({
message: "Invalid group_by value",
});
}
} else {
console.error(req.method, req.body);
return res.status(405).json({ message: "Method not allowed" });
}
} catch (error: unknown) {
console.error(error);
const errorMessage =
error instanceof Error ? error.message : "An unknown error occurred";
res.status(400).json({
message: "Invalid request data",
error: errorMessage,
});
}
}
-16
View File
@@ -1,16 +0,0 @@
import { PrismaClient } from "@prisma/client";
import { env } from "@/src/env.mjs";
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
log:
env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"],
});
if (env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
-8
View File
@@ -1,8 +0,0 @@
export class ResourceNotFoundError extends Error {
id: string;
constructor(type: string, id: string) {
super(`${type} with ${id} not found}`);
this.name = "ResourceNotFoundError";
this.id = id;
}
}
+7
View File
@@ -0,0 +1,7 @@
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
+1 -1
View File
@@ -44,4 +44,4 @@ const config = {
},
};
module.exports = config;
module.exports = config;
+55
View File
@@ -0,0 +1,55 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# database
/prisma/db.sqlite
/prisma/db.sqlite-journal
# next.js
/.next/
/out/
next-env.d.ts
# production
/build
# idea
.idea
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables
.env
.env.local
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
/generated/typescript-server
# openapi spec that is copied during build
/public/openapi*.yml
# vscode
.devcontainer
View File
View File
+104
View File
@@ -0,0 +1,104 @@
openapi: 3.0.1
info:
title: langfuse
version: ''
paths:
/api/public/scores:
post:
description: Add a score to the database, upserts on id
operationId: score_create
tags:
- Score
parameters: []
responses:
'200':
description: ''
content:
application/json:
schema:
$ref: '#/components/schemas/Score'
'400':
description: ''
content:
application/json:
schema:
type: string
'401':
description: ''
content:
application/json:
schema:
type: string
'403':
description: ''
content:
application/json:
schema:
type: string
'405':
description: ''
content:
application/json:
schema:
type: string
security:
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateScoreRequest'
components:
schemas:
CreateScoreRequest:
title: CreateScoreRequest
type: object
properties:
id:
type: string
traceId:
type: string
name:
type: string
value:
type: number
format: double
observationId:
type: string
comment:
type: string
required:
- traceId
- name
- value
Score:
title: Score
type: object
properties:
id:
type: string
traceId:
type: string
name:
type: string
value:
type: number
format: double
observationId:
type: string
timestamp:
type: string
format: date-time
comment:
type: string
required:
- id
- traceId
- name
- value
- timestamp
securitySchemes:
BearerAuth:
type: http
scheme: bearer
File diff suppressed because it is too large Load Diff
+19977
View File
File diff suppressed because it is too large Load Diff
+180
View File
@@ -0,0 +1,180 @@
{
"name": "langfuse-core",
"version": "2.9.0",
"private": true,
"scripts": {
"prebuild": "cp generated/openapi-client/openapi.yml public/openapi-client.yml && cp generated/openapi-server/openapi.yml public/openapi-server.yml",
"build": "next build",
"dev": "dotenv -e ../.env -- next dev",
"dx": "dotenv -e ../.env -- npm i && npm run db:reset && npm run db:seed:examples && npm run dev",
"postinstall": "dotenv -e ../.env -- prisma generate",
"lint": "dotenv -e ../.env -- next lint",
"lint:fix": "dotenv -e ../.env -- next lint --fix",
"prettier": "prettier --write ./src *.{ts,js}",
"clean": "rm -rf node_modules",
"start": "next start",
"test": "dotenv -e ../.env -- jest --runInBand",
"test:watch": "dotenv -e ../.env -- jest --watch --runInBand",
"test:e2e": "dotenv -e ../.env -- playwright test",
"db:migrate": "DISABLE_ERD=false dotenv -e ../.env -- npx prisma migrate dev && npm run db:worker",
"db:reset": "dotenv -e ../.env npx -- prisma migrate reset",
"db:deploy": "dotenv -e ../.env npx -- prisma migrate deploy",
"db:seed": "dotenv -e ../.env -- npx prisma db seed",
"db:seed:examples": "dotenv -e ../.env -- npx prisma db seed -- --environment examples",
"db:seed:load": "dotenv -e ../.env -- npx prisma db seed -- --environment load",
"release": "dotenv -e ../.env -- release-it",
"models:migrate": "dotenv -e ../.env -- tsx scripts/model-match.ts",
"db:worker": "cp -r prisma/generated ../worker"
},
"prisma": {
"seed": "ts-node -r tsconfig-paths/register -r dotenv/config --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
},
"dependencies": {
"@anthropic-ai/tokenizer": "^0.0.4",
"@aws-sdk/client-s3": "^3.507.0",
"@aws-sdk/lib-storage": "^3.515.0",
"@aws-sdk/s3-request-presigner": "^3.507.0",
"@headlessui/react": "^1.7.18",
"@heroicons/react": "^2.1.1",
"@hookform/resolvers": "^3.3.4",
"@next-auth/prisma-adapter": "^1.0.7",
"@prisma/client": "^5.10.2",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-collapsible": "^1.0.3",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-hover-card": "^1.0.7",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slider": "^1.1.2",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toggle": "^1.0.3",
"@radix-ui/react-tooltip": "^1.0.7",
"@react-email/components": "^0.0.14",
"@react-email/render": "^0.0.12",
"@sentry/nextjs": "^7.102.1",
"@sentry/profiling-node": "^7.102.1",
"@sentry/types": "^7.88.0",
"@t3-oss/env-nextjs": "^0.8.0",
"@tailwindcss/forms": "^0.5.7",
"@tanstack/react-query": "^4.36.1",
"@tanstack/react-table": "^8.11.8",
"@tremor/react": "^3.11.1",
"@trpc/client": "^10.45.0",
"@trpc/next": "^10.45.0",
"@trpc/react-query": "^10.45.0",
"@trpc/server": "^10.45.0",
"bcryptjs": "^2.4.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"cmdk": "^0.2.1",
"core-js": "^3.36.0",
"cors": "^2.8.5",
"date-fns": "^3.3.1",
"decimal.js": "^10.4.3",
"exponential-backoff": "^3.1.1",
"js-tiktoken": "^1.0.10",
"kysely": "^0.27.2",
"lodash": "^4.17.21",
"lucide-react": "^0.330.0",
"next": "^14.1.0",
"next-auth": "^4.24.6",
"next-query-params": "^5.0.0",
"nodemailer": "^6.9.9",
"posthog-js": "^1.105.9",
"posthog-node": "^3.6.3",
"prisma-kysely": "^1.8.0",
"react": "18.2.0",
"react-day-picker": "^8.10.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.50.1",
"react-icons": "^5.0.1",
"react-responsive": "^9.0.2",
"react18-json-view": "^0.2.8-canary.1",
"sonner": "^1.4.0",
"superjson": "2.2.1",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7",
"use-query-params": "^2.2.1",
"uuid": "^9.0.1",
"zod": "^3.22.4"
},
"devDependencies": {
"@jedmao/location": "^3.0.0",
"@mermaid-js/mermaid-cli": "^10.7.0",
"@playwright/test": "^1.41.2",
"@release-it/bumper": "^6.0.1",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^14.2.1",
"@types/bcryptjs": "^2.4.6",
"@types/cors": "^2.8.17",
"@types/eslint": "^8.56.2",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.202",
"@types/node": "20.10.5",
"@types/nodemailer": "^6.4.14",
"@types/react": "^18.2.55",
"@types/react-dom": "^18.2.19",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"autoprefixer": "^10.4.17",
"dotenv-cli": "^7.3.0",
"eslint": "^8.56.0",
"eslint-config-next": "^14.1.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"node-mocks-http": "^1.14.1",
"postcss": "^8.4.35",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.11",
"prisma": "^5.10.2",
"prisma-erd-generator": "^1.11.2",
"release-it": "^17.1.1",
"tailwindcss": "^3.4.1",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.7.1",
"typescript": "^5.3.3"
},
"ct3aMetadata": {
"initVersion": "7.13.0"
},
"optionalDependencies": {
"crisp-sdk-web": "^1.0.21"
},
"release-it": {
"git": {
"commitMessage": "chore: release v${version}",
"tagName": "v${version}"
},
"github": {
"release": true,
"web": true,
"autoGenerate": true,
"releaseName": "v${version}",
"comments": {
"submit": true,
"issue": ":rocket: _This issue has been resolved in v${version}. See [${releaseName}](${releaseUrl}) for release notes._",
"pr": ":rocket: _This pull request is included in v${version}. See [${releaseName}](${releaseUrl}) for release notes._"
}
},
"plugins": {
"@release-it/bumper": {
"out": {
"file": "./src/constants/VERSION.ts",
"type": "application/typescript"
}
}
}
}
}

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

+339
View File
@@ -0,0 +1,339 @@
import type { ColumnType } from "kysely";
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
? ColumnType<S, I | undefined, U>
: ColumnType<T, T | undefined, T>;
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
export const MembershipRole = {
OWNER: "OWNER",
ADMIN: "ADMIN",
MEMBER: "MEMBER",
VIEWER: "VIEWER"
} as const;
export type MembershipRole = (typeof MembershipRole)[keyof typeof MembershipRole];
export const ObservationType = {
SPAN: "SPAN",
EVENT: "EVENT",
GENERATION: "GENERATION"
} as const;
export type ObservationType = (typeof ObservationType)[keyof typeof ObservationType];
export const ObservationLevel = {
DEBUG: "DEBUG",
DEFAULT: "DEFAULT",
WARNING: "WARNING",
ERROR: "ERROR"
} as const;
export type ObservationLevel = (typeof ObservationLevel)[keyof typeof ObservationLevel];
export const PricingUnit = {
PER_1000_TOKENS: "PER_1000_TOKENS",
PER_1000_CHARS: "PER_1000_CHARS"
} as const;
export type PricingUnit = (typeof PricingUnit)[keyof typeof PricingUnit];
export const TokenType = {
PROMPT: "PROMPT",
COMPLETION: "COMPLETION",
TOTAL: "TOTAL"
} as const;
export type TokenType = (typeof TokenType)[keyof typeof TokenType];
export const DatasetStatus = {
ACTIVE: "ACTIVE",
ARCHIVED: "ARCHIVED"
} as const;
export type DatasetStatus = (typeof DatasetStatus)[keyof typeof DatasetStatus];
export type Account = {
id: string;
user_id: string;
type: string;
provider: string;
providerAccountId: string;
refresh_token: string | null;
access_token: string | null;
expires_at: number | null;
expires_in: number | null;
ext_expires_in: number | null;
token_type: string | null;
scope: string | null;
id_token: string | null;
session_state: string | null;
};
export type ApiKey = {
id: string;
created_at: Generated<Timestamp>;
note: string | null;
public_key: string;
hashed_secret_key: string;
fast_hashed_secret_key: string | null;
display_secret_key: string;
last_used_at: Timestamp | null;
expires_at: Timestamp | null;
project_id: string;
};
export type AuditLog = {
id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
user_id: string;
project_id: string;
user_project_role: MembershipRole;
resource_type: string;
resource_id: string;
action: string;
before: string | null;
after: string | null;
};
export type CronJobs = {
name: string;
last_run: Timestamp | null;
job_started_at: Timestamp | null;
state: string | null;
};
export type Dataset = {
id: string;
name: string;
project_id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
};
export type DatasetItem = {
id: string;
status: Generated<DatasetStatus>;
input: unknown;
expected_output: unknown | null;
source_observation_id: string | null;
dataset_id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
};
export type DatasetRunItems = {
id: string;
dataset_run_id: string;
dataset_item_id: string;
observation_id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
};
export type DatasetRuns = {
id: string;
name: string;
dataset_id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
};
export type Events = {
id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
project_id: string;
data: unknown;
headers: Generated<unknown>;
url: string | null;
method: string | null;
};
export type Example = {
id: string;
created_at: Generated<Timestamp>;
updated_at: Timestamp;
};
export type Membership = {
project_id: string;
user_id: string;
role: MembershipRole;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
};
export type MembershipInvitation = {
id: string;
email: string;
role: MembershipRole;
project_id: string;
sender_id: string | null;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
};
export type Model = {
id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
project_id: string | null;
model_name: string;
match_pattern: string;
start_date: Timestamp | null;
input_price: string | null;
output_price: string | null;
total_price: string | null;
unit: string;
tokenizer_id: string | null;
tokenizer_config: unknown | null;
};
export type Observation = {
id: string;
trace_id: string | null;
project_id: string;
type: ObservationType;
start_time: Generated<Timestamp>;
end_time: Timestamp | null;
name: string | null;
metadata: unknown | null;
parent_observation_id: string | null;
level: Generated<ObservationLevel>;
status_message: string | null;
version: string | null;
created_at: Generated<Timestamp>;
model: string | null;
internal_model: string | null;
modelParameters: unknown | null;
input: unknown | null;
output: unknown | null;
prompt_tokens: Generated<number>;
completion_tokens: Generated<number>;
total_tokens: Generated<number>;
unit: string | null;
input_cost: string | null;
output_cost: string | null;
total_cost: string | null;
completion_start_time: Timestamp | null;
prompt_id: string | null;
};
export type ObservationView = {
id: string;
trace_id: string | null;
project_id: string;
type: ObservationType;
start_time: Generated<Timestamp>;
end_time: Timestamp | null;
name: string | null;
metadata: unknown | null;
parent_observation_id: string | null;
level: Generated<ObservationLevel>;
status_message: string | null;
version: string | null;
created_at: Generated<Timestamp>;
model: string | null;
modelParameters: unknown | null;
input: unknown | null;
output: unknown | null;
prompt_tokens: Generated<number>;
completion_tokens: Generated<number>;
total_tokens: Generated<number>;
unit: string | null;
completion_start_time: Timestamp | null;
prompt_id: string | null;
model_id: string | null;
input_price: string | null;
output_price: string | null;
total_price: string | null;
calculated_input_cost: string | null;
calculated_output_cost: string | null;
calculated_total_cost: string | null;
latency: number | null;
};
export type Pricing = {
id: string;
model_name: string;
pricing_unit: Generated<PricingUnit>;
price: string;
currency: Generated<string>;
token_type: TokenType;
};
export type Project = {
id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
name: string;
cloud_config: unknown | null;
};
export type Prompt = {
id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
project_id: string;
created_by: string;
prompt: string;
name: string;
version: number;
is_active: boolean;
config: Generated<unknown>;
};
export type Score = {
id: string;
timestamp: Generated<Timestamp>;
name: string;
value: number;
comment: string | null;
trace_id: string;
observation_id: string | null;
};
export type Session = {
id: string;
session_token: string;
user_id: string;
expires: Timestamp;
};
export type Trace = {
id: string;
external_id: string | null;
timestamp: Generated<Timestamp>;
name: string | null;
user_id: string | null;
metadata: unknown | null;
release: string | null;
version: string | null;
project_id: string;
public: Generated<boolean>;
bookmarked: Generated<boolean>;
tags: Generated<string[]>;
input: unknown | null;
output: unknown | null;
session_id: string | null;
};
export type TraceSession = {
id: string;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
project_id: string;
bookmarked: Generated<boolean>;
public: Generated<boolean>;
};
export type User = {
id: string;
name: string | null;
email: string | null;
email_verified: Timestamp | null;
password: string | null;
image: string | null;
admin: Generated<boolean>;
created_at: Generated<Timestamp>;
updated_at: Generated<Timestamp>;
feature_flags: Generated<string[]>;
};
export type VerificationToken = {
identifier: string;
token: string;
expires: Timestamp;
};
export type DB = {
Account: Account;
api_keys: ApiKey;
audit_logs: AuditLog;
cron_jobs: CronJobs;
dataset_items: DatasetItem;
dataset_run_items: DatasetRunItems;
dataset_runs: DatasetRuns;
datasets: Dataset;
events: Events;
Example: Example;
membership_invitations: MembershipInvitation;
memberships: Membership;
models: Model;
observations: Observation;
observations_view: ObservationView;
pricings: Pricing;
projects: Project;
prompts: Prompt;
scores: Score;
Session: Session;
trace_sessions: TraceSession;
traces: Trace;
users: User;
verification_tokens: VerificationToken;
};

Some files were not shown because too many files have changed in this diff Show More