You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(datasets): support multimodal dataset items (#1710)
* feat(api): update generated dataset media API
* feat(datasets): support media references
Adds dataset item media upload and optional get_dataset media hydration.
* fix(datasets): address media review feedback
* fix(datasets): refine media review fixes
* fix(datasets): clean up media review follow-ups
* fix(datasets): round-trip resolved media references
Resolved LangfuseMediaReference items from get_dataset(resolve_media_
references=True) discarded the original @@@langfuseMedia:...@@@ string,
so feeding them back into create_dataset_item or run_experiment
serialized them as opaque dicts and orphaned the media. Persist the
reference string and emit it from both _process_dataset_item_media and
EventSerializer.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(datasets): process media inside tuples and sets
_process_dataset_item_media only recursed into list/dict, so a
LangfuseMedia held in a tuple, set, or frozenset slipped through to
fern's encoder and got silently base64-inlined instead of uploaded.
Widen the walker to those containers and rebuild them in place.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(datasets): align media reference field with expectedOutput API rename
The DatasetItemMediaReferenceField enum value changed from
expected_output to expectedOutput. Decouple hydration from the wire
value by mapping the enum member to the model attribute, so the rename
(and any future one) no longer silently skips expected-output media
references.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(datasets): drop tuple media support to avoid namedtuple breakage
Rebuilding tuples via type(data)(iterable) breaks namedtuple/NamedTuple
subclasses, which take positional field args rather than an iterable.
Keep list/set/frozenset handling and leave tuples untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(media): honor per-client httpx config for media reference fetches
get_singleton_httpx_client silently returned the first-inserted
instance, so a LangfuseMediaReference fetched from one client could go
out through another client's transport (proxy/CA/mTLS). Mirror
get_client: warn and fall back to default httpx when multiple clients
exist, and let fetch_bytes/fetch_base64/fetch_data_uri take an explicit
httpx client to deterministically honor per-client settings.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(datasets): scope media uploads to their dataset item
Dataset item media uploads now send datasetId + datasetItemId + field
instead of a trace context. create_dataset_item settles the item id up
front (generating one when absent) so media can be linked before the
item exists, threads the field and resolves the dataset id for each
upload, and reuses the id for the create call.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(datasets): resolve dataset id once per create_dataset_item
Resolving the dataset id inside the per-media upload path fired one
datasets.get per distinct media and could orphan already-uploaded media
if a later lookup failed. Resolve it once up front, before any upload,
and thread dataset_id through the media processing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(datasets): url-encode dataset name and fix media upload job fixture
URL-encode the dataset name in the create_dataset_item media lookup to
match the other datasets.* call sites, and add the new dataset_id /
dataset_item_id keys to the _upload_job test fixture so
_process_upload_media_job no longer KeyErrors.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(datasets): collect media in one pass, resolve dataset id lazily
Replace each LangfuseMedia with its reference string and collect the
media to upload in a single traversal per field, then resolve the
dataset id once and upload the collected set. A plain item no longer
does any datasets.get; media items do exactly one, before any upload.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(media): rename url_is_expired to is_url_expired
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(datasets): always resolve dataset item media references
Drop the resolve_media_references flag on get_dataset and always hydrate
media reference strings to LangfuseMediaReference objects. Regenerate the
dataset-items and media API clients from the base branch: the
includeMediaReferences query flag is gone, mediaReferences is a
non-optional list, and the media upload field is now required.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(datasets): hand-roll media reference JSONPath, drop jsonpath-ng
The API only emits jsonpath-plus normalized paths ($, ['key'], [int]) for
dataset item media references, so parse exactly that grammar in a small
json_path helper module instead of depending on jsonpath-ng (which also
breaks under python -OO). Tests are generated from jsonpath-plus, and the
e2e exercises multiple media across nested keys and list indices.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(media): use fixed timestamps so is_url_expired ids are xdist-stable
Parametrizing with datetime.now() baked per-worker timestamps into the
test ids, so xdist workers collected different ids and aborted with a
collection error. Use fixed past/future timestamps instead.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(datasets): namespace json_path import, drop stale -OO comment
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore(api): take dataset/session generated code from main
The earlier main merge kept the feature branch's generated code; sync it
to main's now-released codegen (sessions regenerated, media reference
media required again). Drop the dataset hydration's media-None guard,
which is dead now that media is non-optional.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments