Skip to content

Commit b18a59e

Browse files
langfuse-botlangfuse-botwochingeclaude
authored
feat(api): update API spec from langfuse/langfuse 1999706 (#1615)
* feat(api): update API spec from langfuse/langfuse 1999706 * feat(scores): add TEXT type to score overloads and docstrings Extend string-value overloads in create_score, score_current_span, score_current_trace, score, and score_trace to accept TEXT alongside CATEGORICAL. Update all related docstrings. Add ExperimentScoreType to exclude TEXT from experiments/evals. Add integration test for TEXT scores. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: simplify openapi spec update instructions in CONTRIBUTING.md The spec update is now automated via PR from the langfuse repo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(scores): update stale casts and export ExperimentScoreType Update cast(Literal["CATEGORICAL"], ...) to include "TEXT" in score/score_trace/score_current_span/score_current_trace impl bodies. Add ExperimentScoreType to __all__ in types.py. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ci: fix tests by adding dynamic retry * tests: adapt to update server logic * ci: cache pnpm store instead of node_modules to avoid stale server state Caching node_modules directly caused postinstall hooks (e.g. prisma generate) to be skipped, leading to stale generated artifacts that didn't match the current langfuse-server schema. Cache the pnpm store instead so installs are still fast but hooks run properly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ci: revert caching changes --------- Co-authored-by: langfuse-bot <langfuse-bot@langfuse.com> Co-authored-by: Tobias Wochinger <tobias.wochinger@clickhouse.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 95ff4f8 commit b18a59e

29 files changed

+413
-55
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ jobs:
9393
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5
9494
with:
9595
path: ./langfuse-server/node_modules
96-
key: |
97-
langfuse-server-${{ hashFiles('./langfuse-server/package-lock.json') }}
98-
langfuse-server-
96+
key: langfuse-serve-${{ hashFiles('langfuse-server/pnpm-lock.yaml') }}
97+
restore-keys: |
98+
langfuse-serve-
9999
100100
- name: Run langfuse server
101101
run: |

CONTRIBUTING.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ uv run mypy langfuse --no-error-summary
4545

4646
### Update openapi spec
4747

48-
1. Generate Fern Python SDK in [langfuse](https://github.com/langfuse/langfuse) and copy the files generated in `generated/python` into the `langfuse/api` folder in this repo.
49-
2. Execute the linter by running `uv run ruff format .`
50-
3. Rebuild and deploy the package to PyPi.
48+
A PR with the changes is automatically created upon changing the Spec in the langfuse repo.
5149

5250
### Publish release
5351

langfuse/_client/client.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ def create_score(
17471747
trace_id: Optional[str] = None,
17481748
score_id: Optional[str] = None,
17491749
observation_id: Optional[str] = None,
1750-
data_type: Optional[Literal["CATEGORICAL"]] = "CATEGORICAL",
1750+
data_type: Optional[Literal["CATEGORICAL", "TEXT"]] = "CATEGORICAL",
17511751
comment: Optional[str] = None,
17521752
config_id: Optional[str] = None,
17531753
metadata: Optional[Any] = None,
@@ -1777,13 +1777,13 @@ def create_score(
17771777
17781778
Args:
17791779
name: Name of the score (e.g., "relevance", "accuracy")
1780-
value: Score value (can be numeric for NUMERIC/BOOLEAN types or string for CATEGORICAL)
1780+
value: Score value (can be numeric for NUMERIC/BOOLEAN types or string for CATEGORICAL/TEXT)
17811781
session_id: ID of the Langfuse session to associate the score with
17821782
dataset_run_id: ID of the Langfuse dataset run to associate the score with
17831783
trace_id: ID of the Langfuse trace to associate the score with
17841784
observation_id: Optional ID of the specific observation to score. Trace ID must be provided too.
17851785
score_id: Optional custom ID for the score (auto-generated if not provided)
1786-
data_type: Type of score (NUMERIC, BOOLEAN, or CATEGORICAL)
1786+
data_type: Type of score (NUMERIC, BOOLEAN, CATEGORICAL, or TEXT)
17871787
comment: Optional comment or explanation for the score
17881788
config_id: Optional ID of a score config defined in Langfuse
17891789
metadata: Optional metadata to be attached to the score
@@ -1907,7 +1907,7 @@ def score_current_span(
19071907
name: str,
19081908
value: str,
19091909
score_id: Optional[str] = None,
1910-
data_type: Optional[Literal["CATEGORICAL"]] = "CATEGORICAL",
1910+
data_type: Optional[Literal["CATEGORICAL", "TEXT"]] = "CATEGORICAL",
19111911
comment: Optional[str] = None,
19121912
config_id: Optional[str] = None,
19131913
metadata: Optional[Any] = None,
@@ -1931,9 +1931,9 @@ def score_current_span(
19311931
19321932
Args:
19331933
name: Name of the score (e.g., "relevance", "accuracy")
1934-
value: Score value (can be numeric for NUMERIC/BOOLEAN types or string for CATEGORICAL)
1934+
value: Score value (can be numeric for NUMERIC/BOOLEAN types or string for CATEGORICAL/TEXT)
19351935
score_id: Optional custom ID for the score (auto-generated if not provided)
1936-
data_type: Type of score (NUMERIC, BOOLEAN, or CATEGORICAL)
1936+
data_type: Type of score (NUMERIC, BOOLEAN, CATEGORICAL, or TEXT)
19371937
comment: Optional comment or explanation for the score
19381938
config_id: Optional ID of a score config defined in Langfuse
19391939
metadata: Optional metadata to be attached to the score
@@ -1971,7 +1971,7 @@ def score_current_span(
19711971
name=name,
19721972
value=cast(str, value),
19731973
score_id=score_id,
1974-
data_type=cast(Literal["CATEGORICAL"], data_type),
1974+
data_type=cast(Literal["CATEGORICAL", "TEXT"], data_type),
19751975
comment=comment,
19761976
config_id=config_id,
19771977
metadata=metadata,
@@ -1997,7 +1997,7 @@ def score_current_trace(
19971997
name: str,
19981998
value: str,
19991999
score_id: Optional[str] = None,
2000-
data_type: Optional[Literal["CATEGORICAL"]] = "CATEGORICAL",
2000+
data_type: Optional[Literal["CATEGORICAL", "TEXT"]] = "CATEGORICAL",
20012001
comment: Optional[str] = None,
20022002
config_id: Optional[str] = None,
20032003
metadata: Optional[Any] = None,
@@ -2022,9 +2022,9 @@ def score_current_trace(
20222022
20232023
Args:
20242024
name: Name of the score (e.g., "user_satisfaction", "overall_quality")
2025-
value: Score value (can be numeric for NUMERIC/BOOLEAN types or string for CATEGORICAL)
2025+
value: Score value (can be numeric for NUMERIC/BOOLEAN types or string for CATEGORICAL/TEXT)
20262026
score_id: Optional custom ID for the score (auto-generated if not provided)
2027-
data_type: Type of score (NUMERIC, BOOLEAN, or CATEGORICAL)
2027+
data_type: Type of score (NUMERIC, BOOLEAN, CATEGORICAL, or TEXT)
20282028
comment: Optional comment or explanation for the score
20292029
config_id: Optional ID of a score config defined in Langfuse
20302030
metadata: Optional metadata to be attached to the score
@@ -2060,7 +2060,7 @@ def score_current_trace(
20602060
name=name,
20612061
value=cast(str, value),
20622062
score_id=score_id,
2063-
data_type=cast(Literal["CATEGORICAL"], data_type),
2063+
data_type=cast(Literal["CATEGORICAL", "TEXT"], data_type),
20642064
comment=comment,
20652065
config_id=config_id,
20662066
metadata=metadata,

langfuse/_client/span.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ def score(
308308
value: str,
309309
score_id: Optional[str] = None,
310310
data_type: Optional[
311-
Literal[ScoreDataType.CATEGORICAL]
311+
Literal[ScoreDataType.CATEGORICAL, ScoreDataType.TEXT]
312312
] = ScoreDataType.CATEGORICAL,
313313
comment: Optional[str] = None,
314314
config_id: Optional[str] = None,
@@ -335,9 +335,9 @@ def score(
335335
336336
Args:
337337
name: Name of the score (e.g., "relevance", "accuracy")
338-
value: Score value (numeric for NUMERIC/BOOLEAN, string for CATEGORICAL)
338+
value: Score value (numeric for NUMERIC/BOOLEAN, string for CATEGORICAL/TEXT)
339339
score_id: Optional custom ID for the score (auto-generated if not provided)
340-
data_type: Type of score (NUMERIC, BOOLEAN, or CATEGORICAL)
340+
data_type: Type of score (NUMERIC, BOOLEAN, CATEGORICAL, or TEXT)
341341
comment: Optional comment or explanation for the score
342342
config_id: Optional ID of a score config defined in Langfuse
343343
timestamp: Optional timestamp for the score (defaults to current UTC time)
@@ -364,7 +364,7 @@ def score(
364364
trace_id=self.trace_id,
365365
observation_id=self.id,
366366
score_id=score_id,
367-
data_type=cast(Literal["CATEGORICAL"], data_type),
367+
data_type=cast(Literal["CATEGORICAL", "TEXT"], data_type),
368368
comment=comment,
369369
config_id=config_id,
370370
timestamp=timestamp,
@@ -395,7 +395,7 @@ def score_trace(
395395
value: str,
396396
score_id: Optional[str] = None,
397397
data_type: Optional[
398-
Literal[ScoreDataType.CATEGORICAL]
398+
Literal[ScoreDataType.CATEGORICAL, ScoreDataType.TEXT]
399399
] = ScoreDataType.CATEGORICAL,
400400
comment: Optional[str] = None,
401401
config_id: Optional[str] = None,
@@ -423,9 +423,9 @@ def score_trace(
423423
424424
Args:
425425
name: Name of the score (e.g., "user_satisfaction", "overall_quality")
426-
value: Score value (numeric for NUMERIC/BOOLEAN, string for CATEGORICAL)
426+
value: Score value (numeric for NUMERIC/BOOLEAN, string for CATEGORICAL/TEXT)
427427
score_id: Optional custom ID for the score (auto-generated if not provided)
428-
data_type: Type of score (NUMERIC, BOOLEAN, or CATEGORICAL)
428+
data_type: Type of score (NUMERIC, BOOLEAN, CATEGORICAL, or TEXT)
429429
comment: Optional comment or explanation for the score
430430
config_id: Optional ID of a score config defined in Langfuse
431431
timestamp: Optional timestamp for the score (defaults to current UTC time)
@@ -451,7 +451,7 @@ def score_trace(
451451
value=cast(str, value),
452452
trace_id=self.trace_id,
453453
score_id=score_id,
454-
data_type=cast(Literal["CATEGORICAL"], data_type),
454+
data_type=cast(Literal["CATEGORICAL", "TEXT"], data_type),
455455
comment=comment,
456456
config_id=config_id,
457457
timestamp=timestamp,

langfuse/api/__init__.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,16 @@
112112
ScoreV1_Boolean,
113113
ScoreV1_Categorical,
114114
ScoreV1_Numeric,
115+
ScoreV1_Text,
115116
Score_Boolean,
116117
Score_Categorical,
117118
Score_Correction,
118119
Score_Numeric,
120+
Score_Text,
119121
Session,
120122
SessionWithTraces,
123+
TextScore,
124+
TextScoreV1,
121125
Trace,
122126
TraceWithDetails,
123127
TraceWithFullDetails,
@@ -281,10 +285,12 @@
281285
GetScoresResponseDataCategorical,
282286
GetScoresResponseDataCorrection,
283287
GetScoresResponseDataNumeric,
288+
GetScoresResponseDataText,
284289
GetScoresResponseData_Boolean,
285290
GetScoresResponseData_Categorical,
286291
GetScoresResponseData_Correction,
287292
GetScoresResponseData_Numeric,
293+
GetScoresResponseData_Text,
288294
GetScoresResponseTraceData,
289295
)
290296
from .sessions import PaginatedSessions
@@ -377,10 +383,12 @@
377383
"GetScoresResponseDataCategorical": ".scores",
378384
"GetScoresResponseDataCorrection": ".scores",
379385
"GetScoresResponseDataNumeric": ".scores",
386+
"GetScoresResponseDataText": ".scores",
380387
"GetScoresResponseData_Boolean": ".scores",
381388
"GetScoresResponseData_Categorical": ".scores",
382389
"GetScoresResponseData_Correction": ".scores",
383390
"GetScoresResponseData_Numeric": ".scores",
391+
"GetScoresResponseData_Text": ".scores",
384392
"GetScoresResponseTraceData": ".scores",
385393
"HealthResponse": ".health",
386394
"IngestionError": ".ingestion",
@@ -489,10 +497,12 @@
489497
"ScoreV1_Boolean": ".commons",
490498
"ScoreV1_Categorical": ".commons",
491499
"ScoreV1_Numeric": ".commons",
500+
"ScoreV1_Text": ".commons",
492501
"Score_Boolean": ".commons",
493502
"Score_Categorical": ".commons",
494503
"Score_Correction": ".commons",
495504
"Score_Numeric": ".commons",
505+
"Score_Text": ".commons",
496506
"SdkLogBody": ".ingestion",
497507
"SdkLogEvent": ".ingestion",
498508
"ServiceProviderConfig": ".scim",
@@ -501,6 +511,8 @@
501511
"SessionWithTraces": ".commons",
502512
"Sort": ".trace",
503513
"TextPrompt": ".prompts",
514+
"TextScore": ".commons",
515+
"TextScoreV1": ".commons",
504516
"Trace": ".commons",
505517
"TraceBody": ".ingestion",
506518
"TraceEvent": ".ingestion",
@@ -664,10 +676,12 @@ def __dir__():
664676
"GetScoresResponseDataCategorical",
665677
"GetScoresResponseDataCorrection",
666678
"GetScoresResponseDataNumeric",
679+
"GetScoresResponseDataText",
667680
"GetScoresResponseData_Boolean",
668681
"GetScoresResponseData_Categorical",
669682
"GetScoresResponseData_Correction",
670683
"GetScoresResponseData_Numeric",
684+
"GetScoresResponseData_Text",
671685
"GetScoresResponseTraceData",
672686
"HealthResponse",
673687
"IngestionError",
@@ -776,10 +790,12 @@ def __dir__():
776790
"ScoreV1_Boolean",
777791
"ScoreV1_Categorical",
778792
"ScoreV1_Numeric",
793+
"ScoreV1_Text",
779794
"Score_Boolean",
780795
"Score_Categorical",
781796
"Score_Correction",
782797
"Score_Numeric",
798+
"Score_Text",
783799
"SdkLogBody",
784800
"SdkLogEvent",
785801
"ServiceProviderConfig",
@@ -788,6 +804,8 @@ def __dir__():
788804
"SessionWithTraces",
789805
"Sort",
790806
"TextPrompt",
807+
"TextScore",
808+
"TextScoreV1",
791809
"Trace",
792810
"TraceBody",
793811
"TraceEvent",

langfuse/api/commons/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,16 @@
4747
ScoreV1_Boolean,
4848
ScoreV1_Categorical,
4949
ScoreV1_Numeric,
50+
ScoreV1_Text,
5051
Score_Boolean,
5152
Score_Categorical,
5253
Score_Correction,
5354
Score_Numeric,
55+
Score_Text,
5456
Session,
5557
SessionWithTraces,
58+
TextScore,
59+
TextScoreV1,
5660
Trace,
5761
TraceWithDetails,
5862
TraceWithFullDetails,
@@ -110,12 +114,16 @@
110114
"ScoreV1_Boolean": ".types",
111115
"ScoreV1_Categorical": ".types",
112116
"ScoreV1_Numeric": ".types",
117+
"ScoreV1_Text": ".types",
113118
"Score_Boolean": ".types",
114119
"Score_Categorical": ".types",
115120
"Score_Correction": ".types",
116121
"Score_Numeric": ".types",
122+
"Score_Text": ".types",
117123
"Session": ".types",
118124
"SessionWithTraces": ".types",
125+
"TextScore": ".types",
126+
"TextScoreV1": ".types",
119127
"Trace": ".types",
120128
"TraceWithDetails": ".types",
121129
"TraceWithFullDetails": ".types",
@@ -196,12 +204,16 @@ def __dir__():
196204
"ScoreV1_Boolean",
197205
"ScoreV1_Categorical",
198206
"ScoreV1_Numeric",
207+
"ScoreV1_Text",
199208
"Score_Boolean",
200209
"Score_Categorical",
201210
"Score_Correction",
202211
"Score_Numeric",
212+
"Score_Text",
203213
"Session",
204214
"SessionWithTraces",
215+
"TextScore",
216+
"TextScoreV1",
205217
"Trace",
206218
"TraceWithDetails",
207219
"TraceWithFullDetails",

langfuse/api/commons/types/__init__.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,23 @@
4343
Score_Categorical,
4444
Score_Correction,
4545
Score_Numeric,
46+
Score_Text,
4647
)
4748
from .score_config import ScoreConfig
4849
from .score_config_data_type import ScoreConfigDataType
4950
from .score_data_type import ScoreDataType
5051
from .score_source import ScoreSource
51-
from .score_v1 import ScoreV1, ScoreV1_Boolean, ScoreV1_Categorical, ScoreV1_Numeric
52+
from .score_v1 import (
53+
ScoreV1,
54+
ScoreV1_Boolean,
55+
ScoreV1_Categorical,
56+
ScoreV1_Numeric,
57+
ScoreV1_Text,
58+
)
5259
from .session import Session
5360
from .session_with_traces import SessionWithTraces
61+
from .text_score import TextScore
62+
from .text_score_v1 import TextScoreV1
5463
from .trace import Trace
5564
from .trace_with_details import TraceWithDetails
5665
from .trace_with_full_details import TraceWithFullDetails
@@ -96,12 +105,16 @@
96105
"ScoreV1_Boolean": ".score_v1",
97106
"ScoreV1_Categorical": ".score_v1",
98107
"ScoreV1_Numeric": ".score_v1",
108+
"ScoreV1_Text": ".score_v1",
99109
"Score_Boolean": ".score",
100110
"Score_Categorical": ".score",
101111
"Score_Correction": ".score",
102112
"Score_Numeric": ".score",
113+
"Score_Text": ".score",
103114
"Session": ".session",
104115
"SessionWithTraces": ".session_with_traces",
116+
"TextScore": ".text_score",
117+
"TextScoreV1": ".text_score_v1",
105118
"Trace": ".trace",
106119
"TraceWithDetails": ".trace_with_details",
107120
"TraceWithFullDetails": ".trace_with_full_details",
@@ -177,12 +190,16 @@ def __dir__():
177190
"ScoreV1_Boolean",
178191
"ScoreV1_Categorical",
179192
"ScoreV1_Numeric",
193+
"ScoreV1_Text",
180194
"Score_Boolean",
181195
"Score_Categorical",
182196
"Score_Correction",
183197
"Score_Numeric",
198+
"Score_Text",
184199
"Session",
185200
"SessionWithTraces",
201+
"TextScore",
202+
"TextScoreV1",
186203
"Trace",
187204
"TraceWithDetails",
188205
"TraceWithFullDetails",

0 commit comments

Comments
 (0)