-
Notifications
You must be signed in to change notification settings - Fork 5
feat(urls): add project-scoped URL generation #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…nd runs Fetch project ID lazily from the API so trace_url, dataset_url, and dataset_run_url return fully-qualified project-scoped paths matching the Langfuse UI. ExperimentRunner now surfaces dataset_run_url on results. Includes single-dataset-per-run invariant comment and simplified tests that no longer encode accidental mixed-dataset behavior.
Greptile OverviewGreptile SummaryThis PR updates the SDK’s UI URL helpers to generate Langfuse project-scoped paths (e.g., The main correctness issue is in Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| lib/langfuse/api_client.rb | Adds get_projects API call for fetching accessible projects; error handling mirrors other GET endpoints. |
| lib/langfuse/client.rb | Adds lazy cached project_id lookup and project-scoped URL helpers (trace_url, dataset_url, dataset_run_url). |
| lib/langfuse/dataset_client.rb | Adds DatasetClient#url delegating to Client#dataset_url when client is present. |
| lib/langfuse/experiment_runner.rb | Tracks dataset_id alongside dataset_run_id and exposes dataset_run_url on ExperimentResult. |
| spec/langfuse/api_client_spec.rb | Adds tests for ApiClient#get_projects covering success, 401, timeout, and retriable errors. |
| spec/langfuse/base_observation_spec.rb | Updates trace_url expectations to include /project/:pid/... and stubs project lookup. |
| spec/langfuse/client_spec.rb | Adds specs for project_id caching and new URL helpers; failure-case stubs appear to be shadowed by outer success stub (tests may not cover nil-path). |
| spec/langfuse/dataset_client_spec.rb | Adds specs for DatasetClient#url with/without client delegation. |
| spec/langfuse/experiment_runner_spec.rb | Adds specs for dataset_run_url population on experiment results and dataset_id selection behavior. |
Sequence Diagram
sequenceDiagram
participant U as User
participant C as Client
participant A as ApiClient
participant LF as LangfuseAPI
participant ER as ExperimentRunner
participant RES as ExperimentResult
U->>C: trace_url(trace_id)
alt project_id cached
C-->>U: url
else first call
C->>A: get_projects()
A->>LF: GET /api/public/projects
alt success
LF-->>A: 200 {data:[{id: pid}]}
A-->>C: body
C-->>U: url
else failure/empty
LF-->>A: error/empty
A-->>C: error/body
C-->>U: nil
end
end
U->>ER: execute()
ER->>C: create_dataset_run_item(...)
ER->>C: dataset_run_url(dataset_id, dataset_run_id)
ER->>RES: new(dataset_run_url)
RES-->>U: dataset_run_url
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
9 files reviewed, 1 comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR updates the Ruby SDK’s UI URL helpers to generate project-scoped Langfuse URLs (matching the UI’s /project/:projectId/... routing) by lazily fetching and caching the project ID, and surfaces a dataset-run URL on experiment results.
Changes:
- Add lazy
project_idlookup (viaGET /api/public/projects) and use it to build project-scopedtrace_url,dataset_url, anddataset_run_url. - Surface
dataset_run_urlonExperimentResult(viaExperimentRunner) and addDatasetClient#url. - Update/add specs to cover the new URL behavior and caching/failure behavior.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
lib/langfuse/client.rb |
Adds lazy, cached project ID lookup and builds project-scoped UI URLs for traces/datasets/dataset runs. |
lib/langfuse/api_client.rb |
Adds get_projects API call used by the client for project ID lookup. |
lib/langfuse/experiment_runner.rb |
Captures dataset ID for URL building and returns dataset_run_url on experiment results. |
lib/langfuse/dataset_client.rb |
Adds #url delegating to client.dataset_url. |
spec/langfuse/client_spec.rb |
Tests project ID caching/failure behavior and updated URL formats. |
spec/langfuse/api_client_spec.rb |
Adds tests for get_projects. |
spec/langfuse/experiment_runner_spec.rb |
Adds tests ensuring dataset_run_url is populated (or nil) correctly. |
spec/langfuse/dataset_client_spec.rb |
Adds coverage for DatasetClient#url. |
spec/langfuse/base_observation_spec.rb |
Updates trace URL expectations to project-scoped paths and stubs project lookup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| end | ||
|
|
||
| # Invariant: all items in a single run belong to the same dataset. | ||
| def link_to_dataset_run(item, trace_id, observation_id) |
Copilot
AI
Feb 8, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new comment states a single-run invariant (all items belong to the same dataset), but this method doesn’t enforce it. If a caller passes DatasetItemClient objects from different datasets, the run will still link items and later URL generation will use whichever dataset_id was captured first, producing an incorrect dataset_run_url. Consider validating that subsequent items match the initially captured dataset_id (and either raise or warn/skip linking when they don’t).
| def link_to_dataset_run(item, trace_id, observation_id) | |
| def link_to_dataset_run(item, trace_id, observation_id) | |
| if @dataset_id && item.dataset_id && item.dataset_id != @dataset_id | |
| @logger.warn( | |
| "Dataset run item linking skipped: item dataset_id=#{item.dataset_id} " \ | |
| "does not match run dataset_id=#{@dataset_id}" | |
| ) | |
| return nil | |
| end |
TL;DRAdd project-scoped URL generation for traces, datasets, and dataset runs — matching the actual Langfuse UI paths.
Whytrace_urlpreviously returned/traces/:idwhich doesn't resolve in the Langfuse UI (requires/project/:pid/traces/:id). This lazily fetches the project ID fromGET /api/public/projects, caches it, and uses it across all URL helpers. ExperimentRunner now surfacesdataset_run_urlon results. Also documents the single-dataset-per-run invariant and simplifies tests that were encoding accidental mixed-dataset behavior.Checklist