Repository navigation
Conversation
…ngfuse#1946) Regenerated langfuse/api from the upstream Fern definition: baseline langfuse/langfuse 619dbe3 (last sync, langfuse#1866) plus langfuse/langfuse#17357 and #18404. Split out of the bundled API-spec bot PR langfuse#1943. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…se#1949) Regenerated langfuse/api from the upstream Fern definition: baseline langfuse/langfuse 619dbe3 (last sync, langfuse#1866) plus langfuse/langfuse#17892 and the datasets.yml/opentelemetry.yml part of #18406. Split out of the bundled API-spec bot PR langfuse#1943. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…angfuse#1948) Regenerated langfuse/api from the upstream Fern definition: baseline langfuse/langfuse 619dbe3 (last sync, langfuse#1866) plus langfuse/langfuse#17888. Split out of the bundled API-spec bot PR langfuse#1943. Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
langfuse#1947) * docs(api): document fromStartTime as required on experiments endpoints Regenerated langfuse/api from the upstream Fern definition: baseline langfuse/langfuse 619dbe3 (last sync, langfuse#1866) plus langfuse/langfuse#17603. Split out of the bundled API-spec bot PR langfuse#1943. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * docs(api): use language-neutral wording for experiments time window Regenerated from langfuse/langfuse branch docs/experiments-from-start-time-neutral-wording. The fromStartTime docstrings named `toStartTime`, but the Python parameter is `to_start_time`; they now say "an upper bound" instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(api): type read-side metadata as optional objects Regenerated langfuse/api from the upstream Fern definition: baseline langfuse/langfuse 619dbe3 (last sync, langfuse#1866) plus langfuse/langfuse#18122 and the commons.yml part of #18406. Split out of the bundled API-spec bot PR langfuse#1943. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * test(api): pin read-side metadata parsing on generated models Cover omitted, null, empty and nested-JSON metadata plus rejection of non-object metadata for Trace, Observation, ObservationV2, BaseScore, BaseScoreV1 and every Score / ScoreV1 / GetScoresResponseData variant. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
|
chrikrah
left a comment
There was a problem hiding this comment.
@po-et this fixes the serialization: sync tasks overlap now, and two of your new cases plus the concurrency case fail on main. Your docs note already says thread-affine tasks should move to async. I'd ship it in v5 and not in a patch, because the cost of missing that note is every item.
$ pytest -q tests/unit/test_experiment.py # uv sync --locked, Python 3.12
36 passed # head 47c4ee4
3 failed, 33 passed # langfuse/experiment.py from bf11ec1, your tests kept
FAILED ...::TestExperimentObservationTree::test_sync_tasks_run_concurrently_with_trace_context
$ python lf_sync_task_sqlite.py # sync task reads a sqlite3 connection opened by the caller, max_concurrency=2
outputs: ['A', 'B'] items: 2 # bf11ec1
Item 0 failed: SQLite objects created in a thread can only be used in that same thread. ...
outputs: [] items: 0 # head 47c4ee4
# not run: the e2e suites against a Langfuse server
non-blocking: called from a plain script, run_experiment returns zero item results for that task and raises nothing. The failure shows only as an ERROR log line and an error span in the trace. In a notebook, run_async_safely already moves the loop off the caller's thread, so scripts are what changes. With the bug-fix box ticked it would ship with no migration note. I'd retarget this to prepare-v5-release with a ! in the title and tick "Breaking change". #1934 landed experiment.py changes there, so expect a rebase.
@hassiebp does this belong on prepare-v5-release?
BREAKING CHANGE: synchronous experiment tasks run in worker threads. Create thread-affine resources where they are used and audit shared state before upgrading.
|
Thanks a lot for this, the implementation looks solid. Context propagation into the worker threads and the async detection both hold up well in review. We've decided not to include it in v5.0, which ships tomorrow. Changing the default execution context the day before a major release is too risky for us. A few things also need more design work first:
We'd be happy to ship this in a v5.x minor release behind an opt-in flag, so the default doesn't change. Once v5 is out, could you retarget this PR to |
What does this PR do?
Synchronous experiment tasks currently block the event loop and serialize blocking work despite
max_concurrency. Run them in worker threads while preserving context propagation; keep native async tasks, decorated async functions, partials and async callable objects on the experiment's loop, invoking the original callable.This is a v5 breaking execution-context change, following the review on this PR. It targets
prepare-v5-release, not a patch release. Synchronous tasks must not capture caller-thread-only resources such as a default SQLite connection, and shared state may now be accessed concurrently.max_concurrency=1does not restore caller-thread execution.MIGRATION_V5_SYNC_TASKS.md explains resource ownership, per-task connection creation/closure, async-client migration, and the existing item-error policy. Add real SQLite tests through
run_experiment: a caller-owned connection records item failures, while worker-owned connections preserve both outputs. The migration source is separate from generated reference documentation.Integrates v5 changes including #1934 while preserving published branch history. Relative to v5, generated API files and unrelated SDK/test paths are unchanged.
Type of change
Verification
Python 3.12, dependencies installed with
uv sync --locked:test_prompt.pyinitialization errors (Langfuse client is not initialized); unmodified v5 produces the same 18 errors (8 prompt tests pass). These files and generated API code are identical to v5.tests/unit/test_media.py; the same warning occurs on the unmodified v5 file.Checklist
code_review.md.AI assistance was used for implementation, tests and automated review.