Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions langfuse/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,12 @@
ObservationsView,
ObservationsViewSingle,
PricingTier,
PricingTierAttributeCondition,
PricingTierAttributeSource,
PricingTierCondition,
PricingTierInput,
PricingTierOperator,
PricingTierUsageCondition,
Score,
ScoreConfig,
ScoreConfigDataType,
Expand Down Expand Up @@ -542,9 +545,12 @@
"PlaceholderMessage": ".prompts",
"PlaceholderMessageType": ".prompts",
"PricingTier": ".commons",
"PricingTierAttributeCondition": ".commons",
"PricingTierAttributeSource": ".commons",
"PricingTierCondition": ".commons",
"PricingTierInput": ".commons",
"PricingTierOperator": ".commons",
"PricingTierUsageCondition": ".commons",
"Project": ".projects",
"ProjectDeletionResponse": ".projects",
"Projects": ".projects",
Expand Down Expand Up @@ -883,9 +889,12 @@ def __dir__():
"PlaceholderMessage",
"PlaceholderMessageType",
"PricingTier",
"PricingTierAttributeCondition",
"PricingTierAttributeSource",
"PricingTierCondition",
"PricingTierInput",
"PricingTierOperator",
"PricingTierUsageCondition",
"Project",
"ProjectDeletionResponse",
"Projects",
Expand Down
4 changes: 2 additions & 2 deletions langfuse/api/blob_storage_integrations/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def upsert_blob_storage_integration(
Enable gzip compression for exported files (.csv.gz, .json.gz, .jsonl.gz). Defaults to true.

export_source : typing.Optional[BlobStorageExportSource]
Data to export. When omitted on update, the existing value is preserved. When omitted on create: integrations on Langfuse Cloud default to `OBSERVATIONS_V2`; self-hosted deployments fall back to `LEGACY_TRACES_OBSERVATIONS`. Required when `exportFieldGroups` is provided.
Data to export. When omitted on update, the existing value is preserved. When omitted on create, the default is `OBSERVATIONS_V2` on Langfuse Cloud, and on self-hosted deployments `LEGACY_TRACES_OBSERVATIONS` — or `OBSERVATIONS_V2` where the deployment no longer populates the legacy tables. The default is never a source the deployment cannot serve. Required when `exportFieldGroups` is provided.

**Cloud-only project deprecation gate (effective 2026-05-20):** For projects created on or after 2026-05-20 on Langfuse Cloud, `LEGACY_TRACES_OBSERVATIONS` and `LEGACY_TRACES_AND_ENRICHED_OBSERVATIONS` are rejected with HTTP 400. Use `OBSERVATIONS_V2` for all new integrations. Self-hosted deployments are unaffected.

Expand Down Expand Up @@ -427,7 +427,7 @@ async def upsert_blob_storage_integration(
Enable gzip compression for exported files (.csv.gz, .json.gz, .jsonl.gz). Defaults to true.

export_source : typing.Optional[BlobStorageExportSource]
Data to export. When omitted on update, the existing value is preserved. When omitted on create: integrations on Langfuse Cloud default to `OBSERVATIONS_V2`; self-hosted deployments fall back to `LEGACY_TRACES_OBSERVATIONS`. Required when `exportFieldGroups` is provided.
Data to export. When omitted on update, the existing value is preserved. When omitted on create, the default is `OBSERVATIONS_V2` on Langfuse Cloud, and on self-hosted deployments `LEGACY_TRACES_OBSERVATIONS` — or `OBSERVATIONS_V2` where the deployment no longer populates the legacy tables. The default is never a source the deployment cannot serve. Required when `exportFieldGroups` is provided.

**Cloud-only project deprecation gate (effective 2026-05-20):** For projects created on or after 2026-05-20 on Langfuse Cloud, `LEGACY_TRACES_OBSERVATIONS` and `LEGACY_TRACES_AND_ENRICHED_OBSERVATIONS` are rejected with HTTP 400. Use `OBSERVATIONS_V2` for all new integrations. Self-hosted deployments are unaffected.

Expand Down
4 changes: 2 additions & 2 deletions langfuse/api/blob_storage_integrations/raw_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ def upsert_blob_storage_integration(
Enable gzip compression for exported files (.csv.gz, .json.gz, .jsonl.gz). Defaults to true.

export_source : typing.Optional[BlobStorageExportSource]
Data to export. When omitted on update, the existing value is preserved. When omitted on create: integrations on Langfuse Cloud default to `OBSERVATIONS_V2`; self-hosted deployments fall back to `LEGACY_TRACES_OBSERVATIONS`. Required when `exportFieldGroups` is provided.
Data to export. When omitted on update, the existing value is preserved. When omitted on create, the default is `OBSERVATIONS_V2` on Langfuse Cloud, and on self-hosted deployments `LEGACY_TRACES_OBSERVATIONS` — or `OBSERVATIONS_V2` where the deployment no longer populates the legacy tables. The default is never a source the deployment cannot serve. Required when `exportFieldGroups` is provided.

**Cloud-only project deprecation gate (effective 2026-05-20):** For projects created on or after 2026-05-20 on Langfuse Cloud, `LEGACY_TRACES_OBSERVATIONS` and `LEGACY_TRACES_AND_ENRICHED_OBSERVATIONS` are rejected with HTTP 400. Use `OBSERVATIONS_V2` for all new integrations. Self-hosted deployments are unaffected.

Expand Down Expand Up @@ -702,7 +702,7 @@ async def upsert_blob_storage_integration(
Enable gzip compression for exported files (.csv.gz, .json.gz, .jsonl.gz). Defaults to true.

export_source : typing.Optional[BlobStorageExportSource]
Data to export. When omitted on update, the existing value is preserved. When omitted on create: integrations on Langfuse Cloud default to `OBSERVATIONS_V2`; self-hosted deployments fall back to `LEGACY_TRACES_OBSERVATIONS`. Required when `exportFieldGroups` is provided.
Data to export. When omitted on update, the existing value is preserved. When omitted on create, the default is `OBSERVATIONS_V2` on Langfuse Cloud, and on self-hosted deployments `LEGACY_TRACES_OBSERVATIONS` — or `OBSERVATIONS_V2` where the deployment no longer populates the legacy tables. The default is never a source the deployment cannot serve. Required when `exportFieldGroups` is provided.

**Cloud-only project deprecation gate (effective 2026-05-20):** For projects created on or after 2026-05-20 on Langfuse Cloud, `LEGACY_TRACES_OBSERVATIONS` and `LEGACY_TRACES_AND_ENRICHED_OBSERVATIONS` are rejected with HTTP 400. Use `OBSERVATIONS_V2` for all new integrations. Self-hosted deployments are unaffected.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class BlobStorageExportSource(enum.StrEnum):
- `OBSERVATIONS_V2`: same data model as the `/api/public/v2/observations` endpoint, plus scores. Columns are controlled by `exportFieldGroups`.
- `LEGACY_TRACES_AND_ENRICHED_OBSERVATIONS`: both sets. Observation columns of both portions are controlled by `exportFieldGroups`.

**Note:** `OBSERVATIONS_V2` and the enriched-observations portion of `LEGACY_TRACES_AND_ENRICHED_OBSERVATIONS` rely on the enriched observations table (Langfuse Fast Preview / v4), which is currently available on Langfuse Cloud only. See https://langfuse.com/docs/v4.
**Note:** which sources a deployment accepts depends on how far it has moved to the v4 data model. `OBSERVATIONS_V2` and the enriched-observations portion of `LEGACY_TRACES_AND_ENRICHED_OBSERVATIONS` read the enriched observations table, so they require a deployment that already populates it. `LEGACY_TRACES_OBSERVATIONS` and the legacy portion of `LEGACY_TRACES_AND_ENRICHED_OBSERVATIONS` read the legacy traces and observations tables, so they require a deployment that still populates those. A deployment part-way through the migration populates both and accepts every source. Selecting a source the deployment cannot serve is rejected with `400`, rather than exporting an empty result. See https://langfuse.com/docs/v4.
"""

LEGACY_TRACES_OBSERVATIONS = "LEGACY_TRACES_OBSERVATIONS"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class CreateBlobStorageIntegrationRequest(UniversalBaseModel):
typing.Optional[BlobStorageExportSource], FieldMetadata(alias="exportSource")
] = pydantic.Field(default=None)
"""
Data to export. When omitted on update, the existing value is preserved. When omitted on create: integrations on Langfuse Cloud default to `OBSERVATIONS_V2`; self-hosted deployments fall back to `LEGACY_TRACES_OBSERVATIONS`. Required when `exportFieldGroups` is provided.
Data to export. When omitted on update, the existing value is preserved. When omitted on create, the default is `OBSERVATIONS_V2` on Langfuse Cloud, and on self-hosted deployments `LEGACY_TRACES_OBSERVATIONS` — or `OBSERVATIONS_V2` where the deployment no longer populates the legacy tables. The default is never a source the deployment cannot serve. Required when `exportFieldGroups` is provided.

**Cloud-only project deprecation gate (effective 2026-05-20):** For projects created on or after 2026-05-20 on Langfuse Cloud, `LEGACY_TRACES_OBSERVATIONS` and `LEGACY_TRACES_AND_ENRICHED_OBSERVATIONS` are rejected with HTTP 400. Use `OBSERVATIONS_V2` for all new integrations. Self-hosted deployments are unaffected.

Expand Down
4 changes: 2 additions & 2 deletions langfuse/api/comments/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def create(
The content of the comment. May include markdown. Currently limited to 5000 characters.

author_user_id : typing.Optional[str]
The id of the user who created the comment.
The id of the user who created the comment. Must be a member of the organization that owns the project, otherwise an error will be thrown.

request_options : typing.Optional[RequestOptions]
Request-specific configuration.
Expand Down Expand Up @@ -241,7 +241,7 @@ async def create(
The content of the comment. May include markdown. Currently limited to 5000 characters.

author_user_id : typing.Optional[str]
The id of the user who created the comment.
The id of the user who created the comment. Must be a member of the organization that owns the project, otherwise an error will be thrown.

request_options : typing.Optional[RequestOptions]
Request-specific configuration.
Expand Down
4 changes: 2 additions & 2 deletions langfuse/api/comments/raw_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def create(
The content of the comment. May include markdown. Currently limited to 5000 characters.

author_user_id : typing.Optional[str]
The id of the user who created the comment.
The id of the user who created the comment. Must be a member of the organization that owns the project, otherwise an error will be thrown.

request_options : typing.Optional[RequestOptions]
Request-specific configuration.
Expand Down Expand Up @@ -418,7 +418,7 @@ async def create(
The content of the comment. May include markdown. Currently limited to 5000 characters.

author_user_id : typing.Optional[str]
The id of the user who created the comment.
The id of the user who created the comment. Must be a member of the organization that owns the project, otherwise an error will be thrown.

request_options : typing.Optional[RequestOptions]
Request-specific configuration.
Expand Down
2 changes: 1 addition & 1 deletion langfuse/api/comments/types/create_comment_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class CreateCommentRequest(UniversalBaseModel):
typing.Optional[str], FieldMetadata(alias="authorUserId")
] = pydantic.Field(default=None)
"""
The id of the user who created the comment.
The id of the user who created the comment. Must be a member of the organization that owns the project, otherwise an error will be thrown.
"""

model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
Expand Down
9 changes: 9 additions & 0 deletions langfuse/api/commons/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@
ObservationsView,
ObservationsViewSingle,
PricingTier,
PricingTierAttributeCondition,
PricingTierAttributeSource,
PricingTierCondition,
PricingTierInput,
PricingTierOperator,
PricingTierUsageCondition,
Score,
ScoreConfig,
ScoreConfigDataType,
Expand Down Expand Up @@ -112,9 +115,12 @@
"ObservationsView": ".types",
"ObservationsViewSingle": ".types",
"PricingTier": ".types",
"PricingTierAttributeCondition": ".types",
"PricingTierAttributeSource": ".types",
"PricingTierCondition": ".types",
"PricingTierInput": ".types",
"PricingTierOperator": ".types",
"PricingTierUsageCondition": ".types",
"Score": ".types",
"ScoreConfig": ".types",
"ScoreConfigDataType": ".types",
Expand Down Expand Up @@ -207,9 +213,12 @@ def __dir__():
"ObservationsView",
"ObservationsViewSingle",
"PricingTier",
"PricingTierAttributeCondition",
"PricingTierAttributeSource",
"PricingTierCondition",
"PricingTierInput",
"PricingTierOperator",
"PricingTierUsageCondition",
"Score",
"ScoreConfig",
"ScoreConfigDataType",
Expand Down
9 changes: 9 additions & 0 deletions langfuse/api/commons/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@
from .observations_view import ObservationsView
from .observations_view_single import ObservationsViewSingle
from .pricing_tier import PricingTier
from .pricing_tier_attribute_condition import PricingTierAttributeCondition
from .pricing_tier_attribute_source import PricingTierAttributeSource
from .pricing_tier_condition import PricingTierCondition
from .pricing_tier_input import PricingTierInput
from .pricing_tier_operator import PricingTierOperator
from .pricing_tier_usage_condition import PricingTierUsageCondition
from .score import (
Score,
Score_Boolean,
Expand Down Expand Up @@ -103,9 +106,12 @@
"ObservationsView": ".observations_view",
"ObservationsViewSingle": ".observations_view_single",
"PricingTier": ".pricing_tier",
"PricingTierAttributeCondition": ".pricing_tier_attribute_condition",
"PricingTierAttributeSource": ".pricing_tier_attribute_source",
"PricingTierCondition": ".pricing_tier_condition",
"PricingTierInput": ".pricing_tier_input",
"PricingTierOperator": ".pricing_tier_operator",
"PricingTierUsageCondition": ".pricing_tier_usage_condition",
"Score": ".score",
"ScoreConfig": ".score_config",
"ScoreConfigDataType": ".score_config_data_type",
Expand Down Expand Up @@ -193,9 +199,12 @@ def __dir__():
"ObservationsView",
"ObservationsViewSingle",
"PricingTier",
"PricingTierAttributeCondition",
"PricingTierAttributeSource",
"PricingTierCondition",
"PricingTierInput",
"PricingTierOperator",
"PricingTierUsageCondition",
"Score",
"ScoreConfig",
"ScoreConfigDataType",
Expand Down
6 changes: 3 additions & 3 deletions langfuse/api/commons/types/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class Model(UniversalBaseModel):

Models can have either simple flat pricing or tiered pricing:
- Flat pricing: Single price per usage type (legacy, but still supported)
- Tiered pricing: Multiple pricing tiers with conditional matching based on usage patterns
- Tiered pricing: Multiple pricing tiers with conditional matching based on usage patterns or observation attributes

The pricing tiers approach is recommended for models with usage-based pricing variations.
When using tiered pricing, the flat price fields (inputPrice, outputPrice, prices) are populated
Expand Down Expand Up @@ -109,10 +109,10 @@ class Model(UniversalBaseModel):
typing.List[PricingTier], FieldMetadata(alias="pricingTiers")
] = pydantic.Field()
"""
Array of pricing tiers with conditional pricing based on usage thresholds.
Array of pricing tiers with conditional pricing based on usage thresholds or observation attributes.

Pricing tiers enable accurate cost tracking for models that charge different rates based on usage patterns
(e.g., different rates for high-volume usage, large context windows, or cached tokens).
or request attributes (e.g., high-volume usage, large context windows, cached tokens, or service tiers).

Each model must have exactly one default tier (isDefault=true, priority=0) that serves as a fallback.
Additional conditional tiers can be defined with specific matching criteria.
Expand Down
6 changes: 3 additions & 3 deletions langfuse/api/commons/types/pricing_tier.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@

class PricingTier(UniversalBaseModel):
"""
Pricing tier definition with conditional pricing based on usage thresholds.
Pricing tier definition with conditional pricing based on usage thresholds or observation attributes.

Pricing tiers enable accurate cost tracking for LLM providers that charge different rates based on usage patterns.
For example, some providers charge higher rates when context size exceeds certain thresholds.
Pricing tiers enable accurate cost tracking for LLM providers that charge different rates based on usage patterns or request attributes.
For example, some providers charge higher rates when context size exceeds certain thresholds or when an accelerated service tier is selected.

How tier matching works:
1. Tiers are evaluated in ascending priority order (priority 1 before priority 2, etc.)
Expand Down
37 changes: 37 additions & 0 deletions langfuse/api/commons/types/pricing_tier_attribute_condition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# This file was auto-generated by Fern from our API Definition.

import typing

import pydantic
from ...core.pydantic_utilities import UniversalBaseModel
from .pricing_tier_attribute_source import PricingTierAttributeSource


class PricingTierAttributeCondition(UniversalBaseModel):
"""
Condition that matches any configured value for a top-level observation attribute.
"""

source: PricingTierAttributeSource = pydantic.Field()
"""
Observation attribute object evaluated by this condition.
"""

key: str = pydantic.Field()
"""
Exact top-level attribute key.
"""

operator: typing.Literal["in"] = pydantic.Field(default="in")
"""
Membership operator.
"""

values: typing.List[str] = pydantic.Field()
"""
Accepted string attribute values. At least one value is required.
"""

model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(
extra="allow", frozen=True
)
22 changes: 22 additions & 0 deletions langfuse/api/commons/types/pricing_tier_attribute_source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This file was auto-generated by Fern from our API Definition.

import typing

from ...core import enum

T_Result = typing.TypeVar("T_Result")


class PricingTierAttributeSource(enum.StrEnum):
MODEL_PARAMETERS = "model_parameters"
METADATA = "metadata"

def visit(
self,
model_parameters: typing.Callable[[], T_Result],
metadata: typing.Callable[[], T_Result],
) -> T_Result:
if self is PricingTierAttributeSource.MODEL_PARAMETERS:
return model_parameters()
if self is PricingTierAttributeSource.METADATA:
return metadata()
Loading