* Disable import button during processing and show loading state
Co-authored-by: marc <marc@langfuse.com>
* prettier
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* run experiments with placeholders as well
* add missing file
* fix experiements
* run outside of loop
* add tests
* fix tests
* make tests clean again
* also test that variables resovle first
* Enhance prompt search to include tags with case-insensitive matching
Co-authored-by: marc <marc@langfuse.com>
* drop md
* prettier
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* fix(prisma): update JobExecution and DefaultLlmModel relations to include onUpdate and onDelete behaviors to match DB constraints
* chore(prisma): update foreign key onUpdate behavior for job_template_id in JobExecution model
* Revert "chore(prisma): update foreign key onUpdate behavior for job_template_id in JobExecution model"
This reverts commit e65c12c9c36a1f8732560e665b1d8d7422c530f0.
* Fix typos: GitHub brand name and "check out" verb phrase
Co-authored-by: marc <marc@langfuse.com>
* Checkpoint before follow-up message
* Fix GitHub brand name and typos across documentation and UI
Co-authored-by: marc <marc@langfuse.com>
* Changes from background composer bc-bdbd909e-6932-4489-b125-e66b1d0f5ebe
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* no naming collisions between prompt and placeholder
* tests for variable placeholder name collision
* fix test spelling
* also show conflict in playhground
* Add environment to PostHog event tracking for traces and observations
Co-authored-by: marc <marc@langfuse.com>
* use object envs instead of trace env
* fix
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
* upgrade turbo
* add web dev turbo runner
* upgrade docker
* fix linter
* set env mode to loose (as in turbo v1) so we don't have to double specify env vars
* feat(nav): integrate HoverCard component for improved navigation item display
* refactor(nav): enhance HoverCard integration and sidebar styles for improved UX
* chore(sidebar): replace cookie-based state management with local storage for sidebar state persistence
* chore: push
* refactor(nav): wrap HoverCardContent in Portal for improved rendering context
* style: mark hovered item as active
* chore(CreateLLMApiKeyForm): replace Input with PasswordInput for improved UX
* chore: revert
* chore(data): add seed data and constants for datasets, prompts, and traces
- Introduced new JSON files for chat ML and nested JSON data.
- Created seed constants for datasets and prompts to streamline data generation.
- Updated seed scripts to utilize new constants and improve dataset creation logic.
- Enhanced Clickhouse preparation scripts to support new dataset structures and trace generation.
- Added utility functions for generating unique trace IDs.
This commit lays the groundwork for improved data handling and observability in the Langfuse application.
* chore(data): remove deprecated prompt files and enhance seed constants
* chore(prisma): remove unique constraint on projectId, datasetId, and input in DatasetItem model
* chore: push
* chore(seeder): introduce seeder abstraction
* chore: typos
* chore: restructure files
* chore: restructure files
* chore: fix imports
* chore: fix imports
* chore: lint
* chore: simplify
* chore: ensure eval data integrity
* chore: update metric name calculation in ClickHouse query builder
* refactor: use test-utils for clickhouse inserts
* chore: add otel conventional attributes to clickhouse db spans
* chore: use db.system instead of db.system.name
* chore: set span kind client for clickhouse queries
* fix(NewDatasetItemForm): add JSON formatting utility for input, output, and metadata fields
* perf(NewDatasetItemFromExistingObject): conditionally render NewDatasetItemForm based on form state
* fix(NewDatasetItemForm): update JSON value check to handle undefined case
* fix(TracesTable): stabilize control column definition
- Ensured conditional rendering of the bookmarked column remains intact while simplifying the structure.
* refactor(TracesTable): enhance column visibility and order identifiers for control states
- Updated dialog header to use a title component and improved button layout for clarity.
- Adjusted positioning of the close button for better alignment.
- Enhanced header and footer with rounded corners for a more polished look.
* fixup: limit render duration of traces table
* fixup: reduce render cycles through data flows and memoization
* refactor: enhance performance and structure of table components
- Removed unnecessary console logs in `data-table.tsx`.
- Refactored `TablePeekView` to use a more structured props type and memoization for improved performance.
- Updated `usePeekData` to reduce stale time from 5 minutes to 1 minute.
- Replaced `IOTableCell` with `MemoizedIOTableCell` in various components to optimize rendering.
- Adjusted `peekView` configurations in `observations.tsx` and `traces.tsx` for consistency and clarity.
* chore: eslint
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* chore: move features
* changes to pro plan
* chore: move features
* truncate title and description to prevent wraps
* remove unnecessary padding from charts
* improve bignumber chart
* add min h/w
* mobile resizing
* fix
2025-05-29 15:58:38 +00:00
Max DeichmannGitHubellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* perf: add exact timestamp match for eval batch actions
* perf: add exact timestamp match for eval batch actions
* perf: add exact timestamp match for eval batch actions
* chore: make `project_id` nullable on `eval_templates`
* feat: add script for managed langfuse evaluators
* feat: restyle running evaluator configs table
* feat: add peek view for running evals
* fixup: add peek view for evaluator library
* fixup: add configure button to table
* feat: rework eval creation flow
* feat: add option to edit eval from table
* fixup: configure evaluator flow with traces data preview
* style: eval configuration UI elements
* chore: add support for current langfuse templates
* chore: reference templateId on jobExecution
* style: add maintainer icon across
* chore: extract WorkerEvaluationVariableService
* fixup: support live data mapping interface
* fixup: revamp datasets eval ui
* fixup: add clone functionality
* chore: rename online evaluation -> llm-as-a-judge
* feat: add evaluator selection in experiment creation flow
* chore: refactor into hooks in experiment form
* feat: add ragas evaluator prompt templates
* chore: show evaluator prompt preview by default
* fix: eval table filtering
* feat: add input box to slider
* fix: clean up running eval peek view and logs
* fix: ensure preview variables are not wrapped in quotes in evaluation prompt preview
* feat: support navigating through traces table
* feat: support default model workflow
* fix: typos in managed evaluators
* fix: do not allow selection of evaluators requiring default to run
* fix: type and build errors
* chore: rename table to default_llm_model
* chore: rm empty file
* fixup: complete rename
* chore: push
* style: eval set up form
* style: separate new evaluator form out into two steps
* chore: ensure we only run evals if default model is set
* chore: add `partner` col to `eval_templates`
* style: new eval template creation
* chore: add proper mapping for dataset evals
* feat: also put evaluation selection on datasets page
* feat: datasets also run on historic experiments after creating mapping
* revert: 09ab242dc12c8647bc716c84d180bc8e631d4919
* chore: fix eslint and ts
* chore: fix warnings
* fix: ensure we inactivate all job configs that rely on default eval model
* fix: tests
* chore: fix eslint
* chore: wrap in tx
* chore: fix default model checkbox logic
* chore: improve wording on delete model
* fix: eslint
* chore: adjust migration order
* style: push ui improvements
* style: sort templates by partner
* fix: eslint
* chore(dashboards): expand measures for dashboards
* chore: add testcase
* chore: define inputTokens and outputTokens
* chore: add timePerOutputToken and costs
* chore: fix definition and handling of tag based breakdowns
* feat(dashboard): make dashboard widgets draggable
* chore: do not update on layout change
* chore: fix size
* chore: remove the preventCollision flag
* chore: linting
* chore: get row height dynamically
* chore: make chart resizable
* chore: styling for resizes
* chore: add migration to align y values
* chore: add owner to project and return langfuse dashboards
* chore: show owner for dashborads in table
* chore: snapshot
* chore: snapshot
* chore: allow widget clone
* chore: snapshot
* chore: linting
* chore: use project instead of user
* chore: show error message on clone failure
* chore: indicate existing dashboard widget relationship
* chore: show only project dashboards in selection for adding widgets
* chore: make full dashboard row clickable
* chore: add clone button to langfuse dashboards
* feat(dashboards): add support for cloning existing dashboards
* chore: move buttons into a dedicated dropdown menu
* chore: allow updates to dashboard name and description
* chore: lint
* chore: removal double capturing of dashboard delete
* chore: track deletions
* feat: full text search
* push
* feat: full text search
* feat: full text search
* feat: full text search
* feat: full text search
* feat: full text search
* fix
* push
* fix: fix json limits and scope to single bodies only
* fix
* fix
* jumping UI
* jumping UI
* jumping UI
* push
* Update web/src/components/table/data-table-toolbar.tsx
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
---------
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* push
* fix: fix json limits and scope to single bodies only
* push
* fix: fix json limits and scope to single bodies only
* fix: fix json limits and scope to single bodies only
* fix: fix json limits and scope to single bodies only
* fix: fix json limits and scope to single bodies only
* fix: fix json limits and scope to single bodies only
* chore: memoize table body for enhanced front end performance
* chore: push
* chore: refactor
* style: speed up animation
* chore: re-render on table state changes
* chore: import function directly
* chore: refactor to use timestamp
* chore: push
* chore: push
* feat: add dlx retry queue and service
* feat: add dlx retry queue and service
* feat: add dlx retry queue and service
* feat: add dlx retry queue and service
* feat: add dlx retry queue and service
* feat: add new organizations apiKey route
* chore: implement additional org routes
* chore: add API docs
* chore: checkin openapi spec
* chore: update tests
* feat: allow org api key management via admin api
* feat: allow the creation of projects using an org api key
* chore: allow deletion of projects via API
* feat: create outline of SCIM Users support
* feat: implement SCIM style user endpoints
* chore: allow set password on user
* chore: lint
* feat: add endpoints to manage project and organization memberships
* chore: add memberships api docs
* chore: reject project membership calls if entitlement is missing
* chore: add team plan to test org
* chore: add reference to full Langfuse API spec
* feat: add new organizations apiKey route
* chore: implement additional org routes
* chore: add API docs
* chore: checkin openapi spec
* chore: update tests
* feat: allow org api key management via admin api
* feat: allow the creation of projects using an org api key
* chore: allow deletion of projects via API
* feat: create outline of SCIM Users support
* feat: implement SCIM style user endpoints
* chore: allow set password on user
* chore: lint
* feat: add endpoints to manage project and organization memberships
* chore: add memberships api docs
* chore: reject project membership calls if entitlement is missing
* chore: add team plan to test org
* feat: add new organizations apiKey route
* chore: implement additional org routes
* chore: add API docs
* chore: checkin openapi spec
* chore: update tests
* feat: allow org api key management via admin api
* feat: allow the creation of projects using an org api key
* chore: allow deletion of projects via API
* feat: create outline of SCIM Users support
* feat: implement SCIM style user endpoints
* chore: allow set password on user
* chore: lint
* chore: add scim api docs
* chore: remove outdated generated artifacts
* feat: add new organizations apiKey route
* chore: implement additional org routes
* chore: add API docs
* chore: checkin openapi spec
* chore: update tests
* feat: allow org api key management via admin api
* feat: allow the creation of projects using an org api key
* chore: allow deletion of projects via API
* chore: add documentation for new project routes
* chore: cleanup
* chore: error updates and handling
* chore: reduce reduntant error handling
* chore(evals): fall back to bullmq `job.data.timestamp` allowing for successful retries
* chore: test
* chore: test
* docs: add diagram and docs
* chore: typo
* chore: typo
* chore: refactor authentication for admin apis
* chore: lint
* chore: address feedback
* feat: add post organizations endpoint
* chore: update tests
* chore: update api key data model
* chore: align code with new scoped api keys
* chore: typing
* chore: align tests with new logic
* chore: remove ratelimitoverrides
* chore: remove accesslevel from queue message
* chore: add additional check to ingestion endpoint
* chore: add test for legacy api key format in redis
* chore: map all api keys in auditlog
* added environment filter option to traces
* WIP on multi-select ui inconsistency
* fixed overflow issue in multi select where an item would not take the full width automatically; also changed to overflow-x-auto
* fixed invalid DOM nesting of div within p (FormDescription) that resulted in a hydration error
* fix multiselect to cut overflowing text with ellipsis and take full name as titlte so you can hover over it, removed unnecessary css classes
* WIP on create evaluator page ui issue with filter builder
* Revert "WIP on create evaluator page ui issue with filter builder"
This reverts commit fd6dd507f2df3c5fb404f4e38a2983e8ef6405ef.
* hide empty string from multi-select options, as supporting empty values would require further work - out of scope for now; also checked for side effects, with current usage all good
* Added test suite for eval filtering
* Resolved comment: removed getEnvironmentsForProject from traces router and instead fetched environments inside evaluator-form via api.projects.environmentFilterOptions
* move eval filtering tests into separate test file
* removed redundancy via fixtures, prepared tests for concurrency
* filtering tests run concurrently
* extracted traceFilterOptions fetching into separate hook as it is used in both the evaluator form and the traces table, also fixed traces table since the environment was now missing there
* useTraceFilterOptions Hook after merge
* Make TraceOptions keys partial so that we can update filter options asynchronously
* default to empty object if response undefined
* exclude environment filter builder column from traces table since toolbar already has env
* removed useTraceFilterOptions hook as use case changed such that extraction into hook is no longer warranted
* chore: pin dev clickhouse version to 24.3
* chore: only add input format flag for cloud
* chore: whitelist accepted cloud regions
* chore: disable test
* fix: (workaround) evals page overflows when rendering right hand side metadata bar
This is more of a workaround, we should probably disable the overflow on the main wrapper div in layout.tsx and enable it only where needed - or find out why the overflow inside the metadata sidebar trigggers the scrollbar to pop up - some info on what I found:
- The body and other divs close to the root do not increase their size.
- The navigation sidebar does increase its vertical height, but limiting that does not resolve the main scrollbar.
- Limiting specifically the wrapper div in layout.tsx with overflow-hidden does resolve this, but globally disabling it requires most pages to be refactored.
* Revert "fix: (workaround) evals page overflows when rendering right hand side metadata bar"
This reverts commit 313a1c0d8a885a04974399f850f7f9aee58fd714.
* fix(ui): TableWithMetadataWrapper uses contain-layout on its root div so that EvaluatorDetail overflow issue is mitigated
Checked for side effects on the other components using TableWithMetadataWrapper and all work as expected.
---------
Co-authored-by: Marlies Mayerhofer <74332854+marliessophie@users.noreply.github.com>
* chore(annotation-scores): revert to synchronous delete; upsert on create route
* fix: ensure scores data not only marked as stale but refreshed on score update
* feat: add support for GCS buckets
* chore: cleanup
* chore: trim gcs credentials before parsing
* chore: add logging for redis shutdown in tests
* chore: update timeout for trace delete test
* chore: bump trace delete concurrency for tests
* feat(evals): enable deletion of evaluators and templates via UI
* Added tests for the evals job and template deletion trpc endpoints
* evals-trpc test refactor, it had a side effect on other tests since it was pruning the db, now instead creates a new org and project per tests and cleans them up after all tests are done
* removed test comments as those are now implemented
* fix wrong wording
* added template version to delete confirmation on template details delete action
* DeleteButton refactoring and moved deletion of templates to LFE-4573
* moving the call to captureDeleteSuccess inside the successful branch of executeDeleteMutation
* Display lock icon when action button in icon mode is unauthorized
* fix: quietly delete scheduled evals for deleted job executions
---------
Co-authored-by: Max Deichmann <m.deichmann@tum.de>
* fix(trace-timeline): overflow and scroll behaviour
* fix(trace-timeline): show maximum of 3 scores and remainder in hover card
* push
* chore: refactor
* chore
* chore
* feat: add self-serve dashboard backend poc
* chore: data model thoughts
* chore: create initial query builder example and test case
* chore: handle empty dimensions and metrics
* chore: lint
* chore: extend filter conditions to account for timestamps
* chore: refactor query builder into sub-functions
* chore: use template queries for user-supplied values
* chore: add query builder tests
* chore: handle time dimension
* chore: add trpc endpoint to execute custom clickhouse query
* chore: add a query playground component to test a couple of queries
* chore: handle multiple joins
* chore: add observations table to data model
* chore: fix bug in data model
* chore: add test case to compare with old dashboard results
* chore: add scaffold for additional views
* expand the users view and add segments to filter scores subviews
* chore: add test cases for score views
* chore: drop users and sessions for now
* chore: add scores aggregate and observations cost tests
* chore: add sql injection tests
* chore: lint
* chore: fix dashboard test cases
* chore: drop users query test
* chore: add order by logic
* chore: fill timeseries values
* chore: use new query function on dashboard
* chore: convert TracesBarListChart.tsx to new query endpoint
* chore: make chart data compile
* chore: update tests
* chore: add tags to custom queries
* chore: typing
* chore: suffix join condition with sql
* chore: add typing in queryBuidler
* chore: limit playground to cloud admin users
* chore: add util to map legacy dashboard columns to new model
* chore: separate time filter state for TracesBarListChart.tsx
* chore: pass timestamps directly into chart components
* chore: add userId and sessionId on observations
* chore: pick auto time granularity based on hours
* fix(prompt-experiments): show form error if name is duplicated
* chore: fix typo
* Update web/src/ee/features/experiments/hooks/useExperimentNameValidation.tsx
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* eslint
---------
Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
* feat(evals): preview number of historic items to be evaluated
* refactor: split up large evaluator form file
* chore: drop optional pagination
* chore: fix eslint
* chore: rename test
* fix: safely parse big numbers in api responses
* feat: add additional input/output parsing for pydantic via OTel
* Revert "feat: add additional input/output parsing for pydantic via OTel"
This reverts commit 71d0f3abd951702393aac7ab79a875b888f089cf.
* pin node to problematic version for working on a fix
* added cross-env and disabled the feature flag causing the testing issue - long term fix should probably be switching to vitest
* unpin node version since problematic feature is now disabled fo affected tests
* fix(ui): IOPreview now renders messages where content is an empty string instead of ignoring them
* removed debug logs
* OpenAiMessageView first filters valid messages to render and then executes the "show x more ..." logic, this way we ensure that there can never be a mismatch between messages items and the amount of fields we support displaying
* Render empty string quotation marks if content is empty but not null or undefined
* Change length check to falsy check for conditional display of empty quotes if content is empty
* cleaner falsy check for rendering empty string quotation marks
* fix(ui): stop propagation on traces table checkbox
* fix(peek-ui): handle onRowClick action correctly for peek view
* feat(peek): do not close upon any screen button or checkbox clicks
* push
* wip
* simplify
* actionbutton for upgrade prompt
* count events for free plan limit
* add sso settings
* rename lite to core
* add product id
* nit
* nits
* fix rate limit test
* ci run on teams plan
* fix
* fix names of pipeline steps
* test tmp
* add better error logs to makeAPICall
* push
* clone to throw better errors
* improve error
* improve error
* fix
* remove comment
* refactor
* push
* next attempt
* nit
* create new auth for failing test suites
* push
* fix rate limit test
* feat: add media and export external endpoint config
* chore: add docs string
* chore: add external endpoint support for azure
* chore: drop feature for media
* Unified design of grouped score badge with trace detail score badges, except that text is no longer medium/semibold
* Made padding of root item of ObservationTree consistent with other items
* fixed alignment issues of badges wrapped in links in trace and observation detail views
* Fixed tooltip of aggregated usage data badge (in trace details) rendering even if there is no underlying data
* chore(cloud): Make UI recognize cloud:enterprise plan and add corresponding access rights and rate limits
- label on project selector
- rate limits same as team
- access rights same as team
- no stripe product id for this (yet), cannot be purchased self-serve in product
* remove comments
---------
Co-authored-by: Marc Klingen <git@marcklingen.com>
* feat(auth): add workos as idp
* add button for org and connection based sign in
* fix
* remove client auth method and checks
* remove unnecessary diff
* fix: header
* fix: search always show current version
* chore: adjust code block
* chore: re-add copy in code editor if no title
* chore: do not match current version always
* adjust margins
* chore: remove breadcrumb
* fix: typo
* fix: final margin
* style: eval template
* small design nits
* fix: do not allow to deactivate eval configs which rano on historic traces only
* fix: do not allow to deactivate eval configs which rano on historic traces only
* fix: do not allow to deactivate eval configs which rano on historic traces only
* fix: do not allow to deactivate eval configs which rano on historic traces only
* fix: do not allow to deactivate eval configs which rano on historic traces only
* fix: do not return all executions for eval config list trpc
* fix: do not return all executions for eval config list trpc
* fix: do not return all executions for eval config list trpc
* fix: do not return all executions for eval config list trpc
* chore: fix demo banner
* fix(page-header): info icon relative positioning
* fix: header title wrap behaviour
* fix(page-header): have info icon follow title
* style: move dataset level buttons to more menu
* push
* push
Langfuse is an **open source LLM engineering** platform for developing, monitoring, evaluating and debugging AI applications. See the README for more details.
## Linting
- Run `pnpm run lint` to lint all packages.
- Fix issues automatically with `pnpm run lint:fix`.
## Tests
- Codex cannot run the test suite because it depends on Docker-based infrastructure that is unavailable in this environment.
## Cursor Rules
- Additional folder-specific rules live in `.cursor/rules/`.
## Commits
- Follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) when crafting commit messages.
Langfuse is an open-source LLM engineering platform that helps teams collaboratively develop, monitor, evaluate, and debug AI applications.
The main feature areas are tracing, evals and prompt management. Langfuse consists of the web application (this repo), documentation, python SDK and javascript/typescript SDK.
This repo contains the web application, worker, and supporting packages but notably not the JS nor Python client SDKs.
## Repository Structure
High level structure. There are more folders (eg for hooks etc).
pnpm run dev:web # Web app only (localhost:3000) - **used in most cases!**
pnpm run dev:worker # Worker only
pnpm run dx # Full initial setup: install deps, reset DBs, resets node modules, seed data, start dev. USE SPARINGLY AS IT WIPES THE DATABASE & node_modules
```
### Database Management
database commands are to be run in the `packages/shared/` folder.
@@ -27,7 +27,7 @@ The maintainers are available on [Discord](https://langfuse.com/discord) in case
## Making a change
_Before making any significant changes, please [open an issue](https://github.com/langfuse/langfuse/issues)._ Discussing your proposed changes ahead of time will make the contribution process smooth for everyone. Large changes that were not discussed in an issue may be rejected.
_Before making any significant changes, please [open an issue](https://github.com/langfuse/langfuse/issues)._ Discussing your proposed changes ahead of time will make the contribution process smooth for everyone. Changes that were not discussed in an issue may be rejected.
Once we've discussed your changes and you've got your code ready, make sure that tests are passing and open your pull request.
@@ -42,7 +42,7 @@ A good first step is to search for open [issues](https://github.com/langfuse/lan
- NextAuth.js / Auth.js
- tRPC: Frontend APIs
- Prisma ORM
- Zod
- Zod v4
- Tailwind CSS
- shadcn/ui tailwind components (using Radix and tanstack)
- Fern: generate OpenAPI spec and Pydantic models
@@ -53,128 +53,35 @@ A good first step is to search for open [issues](https://github.com/langfuse/lan
@@ -190,7 +97,7 @@ Full database schema: [packages/shared/prisma/schema.prisma](packages/shared/pri
We built a monorepo using [pnpm](https://pnpm.io/motivation) and [turbo](https://turbo.build/repo/docs) to manage the dependencies and build process. The monorepo 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.
-`worker`: contains an application for asynchronous processing of tasks.
-`packages`:
-`shared`: contains shared code between the above packages.
-`config-eslint`: contains eslint configurations which are shared between the above packages.
@@ -209,11 +116,12 @@ Requirements
**Steps**
1.Fork the repository and clone it locally
2.Run the development database
1.Install [golang-migrate](https://github.com/golang-migrate/migrate/tree/master/cmd/migrate#migrate-cli) as CLI
8. Log in as a test user (after you ran `db:seed` command):
Username: demo@langfuse.com
Password: password
To get comprehensive example data, you can use the `seed` command:
```sh
pnpm run db:seed:examples
```
## Monorepo quickstart
@@ -306,23 +204,41 @@ Requirements
On the main branch, we adhere to the best practices of [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/). All pull requests and branches are squash-merged to maintain a clean and readable history. This approach ensures the addition of a conventional commit message when merging contributions.
## Test the public API
## Running Unit Tests
The API is tested using Jest. With the development server running, you can run the tests with:
All tests run in the CI and must pass before merging.
All tests run against a running langfuse instance and **write/delete real data from the database**.
Run all
### Tests in the `web` package (public API)
We're using Jest with in the `web` package. Therefore, if you want to provide an argument to the test runner, do it directly without an intermittent ` -- `.
```bash
npm run test
There are three types of unit tests:
- `test-sync`
- `test-async`
- `test-client`
To run a specific test, for example the test: `"should handle special characters in prompt names"` in `prompts.v2.servertest.ts`, run:
```sh
cd web # or with --filter=web
pnpm test-sync --testPathPattern="prompts\.v2\.servertest" --testNamePattern="should handle special characters in prompt names"
```
Run interactively in watch mode
```bash
npm run test:watch
To run all tests:
```sh
pnpm run test
```
These tests are also run in CI.
Run interactively in watch mode (not recommended!)
```sh
pnpm run test:watch
```
### Tests in the `worker` package
For the `worker` package, we're using `vitest` to run unit tests.
```sh
pnpm run test --filter=worker -- FILE_YOU_WANT_TO_TEST.ts -t "test name"
```
## CI/CD
@@ -450,6 +366,20 @@ Please note that
Until the V3 release, both the JSON record must be updated **and** a migration must be created to continue supporting self-hosted users. Note that the migration must updated both the `models` as well as the `prices` table accordingly.
## Updating the OpenAPI Specs & fern SDKs
We maintain the API specifications manually to guarantee a high degree of understandability. If you made changes to the API, please update the respective `.yml` files in `fern/apis/...`.
To generate the respective `openapi.yml` files which power the online API reference & SDKs, run:
```sh
npx fern-api generate --api server # for the server API
npx fern-api generate --api client # for the client API
npx fern-api generate --api organizations # for the organizations API
```
**Note:** You need a signed in fern account to run those commands.
## License
Langfuse is MIT licensed, except for `ee/` folder. See [LICENSE](LICENSE) and [docs](https://langfuse.com/docs/open-source) for more details.
<span>Langfuse uses <a href="https://github.com/orgs/langfuse/discussions"><strong>Github Discussions</strong></a> for Support and Feature Requests.</span>
<span>Langfuse uses <a href="https://github.com/orgs/langfuse/discussions"><strong>GitHub Discussions</strong></a> for Support and Feature Requests.</span>
<br/>
<span><b>We're hiring.</b> <a href="https://langfuse.com/careers"><strong>Join us</strong></a> in product engineering and technical go-to-market roles.</span>
<br/>
@@ -93,7 +96,7 @@ Langfuse is an **open source LLM engineering** platform. It helps teams collabor
### Langfuse Cloud
Managed deployment by the Langfuse team, generous free-tier (hobby plan), no credit card required.
Managed deployment by the Langfuse team, generous free-tier, no credit card required.
@@ -115,12 +118,11 @@ Run Langfuse on your own infrastructure:
# Run the langfuse docker compose
docker compose up
```
- [Kubernetes (Helm)](https://langfuse.com/self-hosting/kubernetes-helm): Run Langfuse on a Kubernetes cluster using Helm. This is the preferred production deployment.
- [VM](https://langfuse.com/self-hosting/docker-compose): Run Langfuse on a single Virtual Machine using Docker Compose.
- Planned: Cloud-specific deployment guides, please upvote and comment on the following threads: [AWS](https://github.com/orgs/langfuse/discussions/4645), [Google Cloud](https://github.com/orgs/langfuse/discussions/4646), [Azure](https://github.com/orgs/langfuse/discussions/4647).
- [Kubernetes (Helm)](https://langfuse.com/self-hosting/kubernetes-helm): Run Langfuse on a Kubernetes cluster using Helm. This is the preferred production deployment.
docs:The value of the score. Must be passed as string for categorical scores, and numeric for boolean and numeric scores. Boolean score values must equal either 1 or 0 (true or false)
observationId:optional<string>
comment:optional<string>
metadata:optional<unknown>
dataType:
type:optional<ScoreDataType>
docs:When set, must match the score value's type. If not set, will be inferred from the score value or config
@@ -64,62 +67,15 @@ types:
dataType:"BOOLEAN"
configId:"1234-5678-90ab-cdef"
traceId:"cdef-1234-5678-90ab"
BaseScore:
properties:
id:string
traceId:string
name:string
source:ScoreSource
observationId:optional<string>
timestamp:datetime
createdAt:datetime
updatedAt:datetime
authorUserId:optional<string>
comment:optional<string>
configId:
type:optional<string>
docs:Reference a score config on a score. When set, config and score name must be equal and value must comply to optionally defined numerical range
NumericScore:
extends:BaseScore
properties:
value:
type:double
docs:The numeric value of the score
BooleanScore:
extends:BaseScore
properties:
value:
type:double
docs:The numeric value of the score. Equals 1 for "True" and 0 for "False"
stringValue:
type:string
docs:The string representation of the score value. Is inferred from the numeric value and equals "True" or "False"
CategoricalScore:
extends:BaseScore
properties:
value:
type:optional<double>
docs:Only defined if a config is linked. Represents the numeric category mapping of the stringValue
stringValue:
type:string
docs:The string representation of the score value. If no config is linked, can be any string. Otherwise, must map to a config category
docs:Public traces are accessible via url without login
environment:
type:optional<string>
docs:The environment from which this trace originated. Can be any lowercase alphanumeric string with hyphens and underscores that does not start with 'langfuse'.
TraceWithDetails:# GET /traces
extends:Trace
properties:
@@ -72,13 +75,16 @@ types:
type:list<ObservationsView>
docs:List of observations
scores:
type:list<Score>
type:list<ScoreV1>
docs:List of scores
Session:
properties:
id:string
createdAt:datetime
projectId:string
environment:
type:optional<string>
docs:The environment from which this session originated.
SessionWithTraces:
extends:Session
properties:
@@ -145,6 +151,9 @@ types:
costDetails:
type:optional<map<string, double>>
docs:The cost details of the observation. Key is the name of the cost metric, value is the cost in USD. The total key is the sum of all (non-total) cost metrics or the total value ingested.
environment:
type:optional<string>
docs:The environment from which this observation originated. Can be any lowercase alphanumeric string with hyphens and underscores that does not start with 'langfuse'.
ObservationsView:
extends:Observation
@@ -231,7 +240,7 @@ types:
properties:
value:double
label:string
BaseScore:
BaseScoreV1:
properties:
id:string
traceId:string
@@ -243,12 +252,77 @@ types:
updatedAt:datetime
authorUserId:optional<string>
comment:optional<string>
metadata:optional<unknown>
configId:
type:optional<string>
docs:Reference a score config on a score. When set, config and score name must be equal and value must comply to optionally defined numerical range
queueId:
type:optional<string>
docs:Reference an annotation queue on a score. Populated if the score was initially created in an annotation queue.
environment:
type:optional<string>
docs:The environment from which this score originated. Can be any lowercase alphanumeric string with hyphens and underscores that does not start with 'langfuse'.
NumericScoreV1:
extends:BaseScoreV1
properties:
value:
type:double
docs:The numeric value of the score
BooleanScoreV1:
extends:BaseScoreV1
properties:
value:
type:double
docs:The numeric value of the score. Equals 1 for "True" and 0 for "False"
stringValue:
type:string
docs:The string representation of the score value. Is inferred from the numeric value and equals "True" or "False"
CategoricalScoreV1:
extends:BaseScoreV1
properties:
value:
type:optional<double>
docs:Only defined if a config is linked. Represents the numeric category mapping of the stringValue
stringValue:
type:string
docs:The string representation of the score value. If no config is linked, can be any string. Otherwise, must map to a config category
ScoreV1:
discriminant:"dataType"
union:
NUMERIC:
type:NumericScoreV1
docs:"Score with NUMERIC data type"
CATEGORICAL:
type:CategoricalScoreV1
docs:"Score with CATEGORICAL data type"
BOOLEAN:
type:BooleanScoreV1
docs:"Score with BOOLEAN data type"
BaseScore:
properties:
id:string
traceId:optional<string>
sessionId:optional<string>
observationId:optional<string>
datasetRunId:optional<string>
name:string
source:ScoreSource
timestamp:datetime
createdAt:datetime
updatedAt:datetime
authorUserId:optional<string>
comment:optional<string>
metadata:optional<unknown>
configId:
type:optional<string>
docs:Reference a score config on a score. When set, config and score name must be equal and value must comply to optionally defined numerical range
queueId:
type:optional<string>
docs:Reference an annotation queue on a score. Populated if the score was initially created in an annotation queue.
environment:
type:optional<string>
docs:The environment from which this score originated. Can be any lowercase alphanumeric string with hyphens and underscores that does not start with 'langfuse'.
NumericScore:
extends:BaseScore
properties:
@@ -383,13 +457,13 @@ types:
docs:Unit used by this model.
type:optional<ModelUsageUnit>
inputPrice:
docs:Price (USD) per input unit
docs:Deprecated. See 'prices' instead. Price (USD) per input unit
type:optional<double>
outputPrice:
docs:Price (USD) per output unit
docs:Deprecated. See 'prices' instead. Price (USD) per output unit
type:optional<double>
totalPrice:
docs:Price (USD) per total unit. Cannot be set if input or output price is set.
docs:Deprecated. See 'prices' instead. Price (USD) per total unit. Cannot be set if input or output price is set.
type:optional<double>
tokenizerId:
docs:Optional. Tokenizer to be applied to observations which match to this model. See docs for more details.
docs:The value of the score. Must be passed as string for categorical scores, and numeric for boolean and numeric scores. Boolean score values must equal either 1 or 0 (true or false)
observationId:optional<string>
comment:optional<string>
metadata:optional<unknown>
dataType:
type:optional<commons.ScoreDataType>
docs:When set, must match the score value's type. If not set, will be inferred from the score value or config
@@ -307,6 +317,14 @@ types:
dataType:"BOOLEAN"
configId:"1234-5678-90ab-cdef"
traceId:"cdef-1234-5678-90ab"
- value:
name:"contextrelevant"
value:"not relevant"
sessionId:"abyt-1234-5678-80ab"
- value:
name:"hallucination"
value:0
datasetRunId:"7891-5678-90ab-hijk"
BaseEvent:
properties:
@@ -387,16 +405,27 @@ types:
successes:list<IngestionSuccess>
errors:list<IngestionError>
OpenAIUsageSchema:
OpenAICompletionUsageSchema:
docs:OpenAI Usage schema from (Chat-)Completion APIs
docs:Get all memberships for the organization associated with the API key (requires organization-scoped API key)
method:GET
path:/organizations/memberships
response:MembershipsResponse
updateOrganizationMembership:
docs:Create or update a membership for the organization associated with the API key (requires organization-scoped API key)
method:PUT
path:/organizations/memberships
request:MembershipRequest
response:MembershipResponse
getProjectMemberships:
docs:Get all memberships for a specific project (requires organization-scoped API key)
method:GET
path:/projects/{projectId}/memberships
path-parameters:
projectId:string
response:MembershipsResponse
updateProjectMembership:
docs:Create or update a membership for a specific project (requires organization-scoped API key). The user must already be a member of the organization.
method:PUT
path:/projects/{projectId}/memberships
path-parameters:
projectId:string
request:MembershipRequest
response:MembershipResponse
getOrganizationProjects:
docs:Get all projects for the organization associated with the API key (requires organization-scoped API key)
docs:Get SCIM Service Provider Configuration (requires organization-scoped API key)
method:GET
path:/ServiceProviderConfig
response:ServiceProviderConfig
getResourceTypes:
docs:Get SCIM Resource Types (requires organization-scoped API key)
method:GET
path:/ResourceTypes
response:ResourceTypesResponse
getSchemas:
docs:Get SCIM Schemas (requires organization-scoped API key)
method:GET
path:/Schemas
response:SchemasResponse
listUsers:
docs:List users in the organization (requires organization-scoped API key)
method:GET
path:/Users
request:
name:ListUsersRequest
query-parameters:
filter:
docs:Filter expression (e.g. userName eq "value")
type:optional<string>
startIndex:
docs:1-based index of the first result to return (default 1)
type:optional<integer>
count:
docs:Maximum number of results to return (default 100)
type:optional<integer>
response:ScimUsersListResponse
createUser:
docs:Create a new user in the organization (requires organization-scoped API key)
method:POST
path:/Users
request:
name:CreateUserRequest
body:
properties:
userName:
docs:User's email address (required)
type:string
name:
docs:User's name information
type:ScimName
emails:
docs:User's email addresses
type:optional<list<ScimEmail>>
active:
docs:Whether the user is active
type:optional<boolean>
password:
docs:Initial password for the user
type:optional<string>
response:ScimUser
getUser:
docs:Get a specific user by ID (requires organization-scoped API key)
method:GET
path:/Users/{userId}
path-parameters:
userId:string
response:ScimUser
deleteUser:
docs:Remove a user from the organization (requires organization-scoped API key). Note that this only removes the user from the organization but does not delete the user entity itself.
docs:Create a score (supports both trace and session scores)
method:POST
path:/scores
request:CreateScoreRequest
response:CreateScoreResponse
get:
docs:Get a list of scores
method:GET
path:/scores
request:
name:GetScoresRequest
query-parameters:
page:
type:optional<integer>
docs:Page number, starts at 1.
limit:
type:optional<integer>
docs:Limit of items per page. If you encounter api issues due to too large page sizes, try to reduce the limit.
userId:
type:optional<string>
docs:Retrieve only scores with this userId associated to the trace.
name:
type:optional<string>
docs:Retrieve only scores with this name.
fromTimestamp:
type:optional<datetime>
docs:Optional filter to only include scores created on or after a certain datetime (ISO 8601)
toTimestamp:
type:optional<datetime>
docs:Optional filter to only include scores created before a certain datetime (ISO 8601)
source:
type:optional<commons.ScoreSource>
docs:Retrieve only scores from a specific source.
operator:
type:optional<string>
docs:Retrieve only scores with <operator> value.
value:
type:optional<double>
docs:Retrieve only scores with <operator> value.
scoreIds:
type:optional<string>
docs:Comma-separated list of score IDs to limit the results to.
configId:
type:optional<string>
docs:Retrieve only scores with a specific configId.
queueId:
type:optional<string>
docs:Retrieve only scores with a specific annotation queueId.
dataType:
type:optional<commons.ScoreDataType>
docs:Retrieve only scores with a specific dataType.
traceTags:
type:optional<string>
allow-multiple:true
docs:Only scores linked to traces that include all of these tags will be returned.
response:GetScoresResponse
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
docs:Delete a score (supports both trace and session scores)
method:DELETE
path:/scores/{scoreId}
path-parameters:
@@ -84,13 +24,19 @@ types:
CreateScoreRequest:
properties:
id:optional<string>
traceId:string
traceId:optional<string>
sessionId:optional<string>
observationId:optional<string>
datasetRunId:optional<string>
name:string
value:
type:commons.CreateScoreValue
docs:The value of the score. Must be passed as string for categorical scores, and numeric for boolean and numeric scores. Boolean score values must equal either 1 or 0 (true or false)
observationId:optional<string>
comment:optional<string>
metadata:optional<unknown>
environment:
type:optional<string>
docs:The environment of the score. Can be any lowercase alphanumeric string with hyphens and underscores that does not start with 'langfuse'.
dataType:
type:optional<commons.ScoreDataType>
docs:The data type of the score. When passing a configId this field is inferred. Otherwise, this field must be passed or will default to numeric.
@@ -113,10 +59,12 @@ types:
dataType:"NUMERIC"
configId:"9203-4567-89ab-cdef"
traceId:"cdef-1234-5678-90ab"
environment:"test"
- value:
name:"toxicity"
value:"not toxic"
traceId:"cdef-1234-5678-90ab"
environment:"production"
- value:
name:"correctness"
value:"partially correct"
@@ -139,38 +87,3 @@ types:
id:
type:string
docs:The id of the created object in Langfuse
GetScoresResponseTraceData:
properties:
userId:
type:optional<string>
docs:The user ID associated with the trace referenced by score
tags:
type:optional<list<string>>
docs:A list of tags associated with the trace referenced by score
docs:Optional filter to only include sessions created before a certain datetime (ISO 8601)
environment:
type:optional<string>
allow-multiple:true
docs:Optional filter for sessions where the environment is one of the provided values.
response:PaginatedSessions
get:
docs:Get a session. Please note that `traces` on this endpoint are not paginated, if you plan to fetch large sessions, consider `GET /api/public/traces?sessionId=<sessionId>`
docs:The unique langfuse identifier of the trace to delete
response:DeleteTraceResponse
list:
docs:Get list of traces
method:GET
@@ -50,13 +59,35 @@ service:
release:
type:optional<string>
docs:Optional filter to only include traces with a certain release.
environment:
type:optional<string>
allow-multiple:true
docs:Optional filter for traces where the environment is one of the provided values.
fields:
type:optional<string>
docs:"Comma-separated list of fields to include in the response. Available field groups are 'core' (always included), 'io' (input, output, metadata), 'scores', 'observations', 'metrics'. If not provided, all fields are included. Example: 'core,scores,metrics'"
"dx":"pnpm i && pnpm run infra:dev:prune && pnpm run infra:dev:up --pull always && pnpm --filter=shared run db:reset && pnpm --filter=shared run ch:reset && pnpm --filter=shared run db:seed:examples && pnpm run dev",
"dx-f":"pnpm i && pnpm run infra:dev:prune && pnpm run infra:dev:up --pull always && pnpm --filter=shared run db:reset -f && pnpm --filter=shared run ch:reset && pnpm --filter=shared run db:seed:examples && pnpm run dev",
"dx-f":"pnpm i && pnpm run infra:dev:prune && pnpm run infra:dev:up --pull always && pnpm --filter=shared run db:reset -f && SKIP_CONFIRM=1 pnpm --filter=shared run ch:reset && pnpm --filter=shared run db:seed:examples && pnpm run dev",
"dx:skip-infra":"pnpm i && pnpm --filter=shared run db:reset && pnpm --filter=shared run ch:reset && pnpm --filter=shared run db:seed:examples && pnpm run dev",
"build":"turbo run build",
"start":"turbo run start",
"dev":"turbo run dev",
"dev:worker":"turbo run dev --filter=worker",
"dev:web":"turbo run dev --filter=web",
"dev:web-turbo":"turbo run dev --filter=web -- --turbo",
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.