feat(api): update API spec from langfuse/langfuse e5c1a45#823
feat(api): update API spec from langfuse/langfuse e5c1a45#823langfuse-bot wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@claude review |
| /** Comma-separated list of author user IDs to filter by. */ | ||
| authorUserId?: string; | ||
| /** Comma-separated list of exact values to filter by. Requires a single dataType from NUMERIC, BOOLEAN, or CATEGORICAL; any other dataType, multiple dataTypes, or omitting dataType returns HTTP 400. For BOOLEAN, each value must be "true" or "false"; for NUMERIC, each value must be a finite number. Otherwise the request returns HTTP 400. */ | ||
| value?: string; |
There was a problem hiding this comment.
value type changed from number to string — silent runtime mismatch for numeric callers
Any existing TypeScript code that passes value: 1.0 (a number literal) to getMany() will produce a compile error after upgrading, or — if consumers are silently casting — will send the number to the server verbatim where the API now expects a comma-separated string, likely returning HTTP 400. The old GetScoresRequest.value was number and the client serialized it with .toString(); the new spec expects a string for comma-separated exact-value matching. Callers who rely on numeric value filtering need to update to value: "1.0" (or value: "true"/"false" for boolean scores).
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/core/src/api/api/resources/scores/client/requests/GetScoresRequest.ts
Line: 33
Comment:
**`value` type changed from `number` to `string` — silent runtime mismatch for numeric callers**
Any existing TypeScript code that passes `value: 1.0` (a number literal) to `getMany()` will produce a compile error after upgrading, or — if consumers are silently casting — will send the number to the server verbatim where the API now expects a comma-separated string, likely returning HTTP 400. The old `GetScoresRequest.value` was `number` and the client serialized it with `.toString()`; the new spec expects a string for comma-separated exact-value matching. Callers who rely on numeric value filtering need to update to `value: "1.0"` (or `value: "true"/"false"` for boolean scores).
How can I resolve this? If you propose a fix, please make it concise.| return (this._scoreConfigs ??= new ScoreConfigs(this._options)); | ||
| } | ||
|
|
||
| public get scoresV3(): ScoresV3 { | ||
| return (this._scoresV3 ??= new ScoresV3(this._options)); | ||
| } | ||
|
|
||
| public get scores(): Scores { |
There was a problem hiding this comment.
client.scoresV3 removed with no runtime-safe fallback
The public scoresV3 getter is deleted. Any SDK consumer calling client.scoresV3.getManyV3(...) will receive a TypeError: Cannot read properties of undefined at runtime (not compile-time, if consuming plain JS or an older type declaration). The replacement is client.scores.getMany(...), but the method name and all request parameters changed as well (cursor-based vs page-based pagination, value: string vs value: number, etc.). This warrants an explicit migration note in the changelog or release notes.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/core/src/api/Client.ts
Line: 201-204
Comment:
**`client.scoresV3` removed with no runtime-safe fallback**
The public `scoresV3` getter is deleted. Any SDK consumer calling `client.scoresV3.getManyV3(...)` will receive a `TypeError: Cannot read properties of undefined` at runtime (not compile-time, if consuming plain JS or an older type declaration). The replacement is `client.scores.getMany(...)`, but the method name and all request parameters changed as well (`cursor`-based vs `page`-based pagination, `value: string` vs `value: number`, etc.). This warrants an explicit migration note in the changelog or release notes.
How can I resolve this? If you propose a fix, please make it concise.| } | ||
|
|
||
| /** | ||
| * Get a list of scores (supports both trace and session scores) | ||
| * Get a list of scores with a polymorphic `value` field (v3). | ||
| * | ||
| * The `value` field type depends on `dataType`: | ||
| * - `NUMERIC` → number | ||
| * - `BOOLEAN` → boolean | ||
| * - `CATEGORICAL`, `TEXT`, `CORRECTION` → string | ||
| * | ||
| * The response always includes the core fields: id, projectId, name, | ||
| * value, dataType, source, timestamp, environment, createdAt, updatedAt. | ||
| * | ||
| * Additional field groups can be requested via the `fields` parameter: | ||
| * - `details` — adds comment, configId, metadata | ||
| * - `subject` — adds the subject object describing the entity the score | ||
| * is attached to: kind (trace, observation, session, or experiment), | ||
| * id, and traceId for observation-level scores | ||
| * - `annotation` — adds authorUserId, queueId | ||
| * | ||
| * Unknown group names return HTTP 400. | ||
| * | ||
| * @param {LangfuseAPI.GetScoresRequest} request | ||
| * @param {Scores.RequestOptions} requestOptions - Request-specific configuration. |
There was a problem hiding this comment.
🔴 The Scores client class loses its getById(scoreId) method in this PR (relocated to legacy.scoresV2.getById), but tests/e2e/scores.e2e.test.ts still calls assertions.api.scores.getById(...) in 26 places (lines 69, 115, 148, 184, 243-244, 316-317, 391, 437, 488, 531, 596, 691-694, 742, 788, 832, 882, 944, 982, 1029, 1086, 1137). Vitest does not type-check and tsc -b --noEmit excludes tests/, so this surfaces only at runtime as TypeError: assertions.api.scores.getById is not a function, failing pnpm test:e2e and blocking the all-tests-passed merge gate. Fix: update the e2e test call sites (or the helpers/serverAssertions.ts wrapper) to use assertions.api.legacy.scoresV2.getById(scoreId).
Extended reasoning...
What is broken
This PR replaces the v2 Scores client with a new v3-backed client and removes the getById(scoreId, requestOptions) method entirely. The old method (previously at packages/core/src/api/api/resources/scores/client/Client.ts, around lines 230-411 pre-PR) has been relocated to packages/core/src/api/api/resources/legacy/resources/scoresV2/client/Client.ts and is now reachable only as client.legacy.scoresV2.getById(...). The new Scores class exposes only getMany() (Client.ts:95).
How it breaks CI
The in-repo e2e suite at tests/e2e/scores.e2e.test.ts still calls assertions.api.scores.getById(...) in 26 places. assertions.api is a LangfuseAPIClient (see tests/e2e/helpers/serverAssertions.ts:12, 26), so its .scores getter returns the new Scores instance with no getById method.
Why type checking does not catch this
- The root
tsconfig.jsonreferences only thepackages/*projects;tests/is not part of thetsc -b --noEmitbuild graph, sopnpm typecheckwill not flag the missing method. - The vitest e2e project aliases
@langfuse/coretopackages/core/dist/index.mjs(built JS). Vitest does not enable typecheck mode (notypecheck.enabled: true, no--typecheckflag in CI), so the TypeScript compiler is never invoked over tests/. - Net effect: the only signal is a runtime
TypeError: scores.getById is not a functiononce vitest executes the first call site.
Impact
.github/workflows/ci.yml runs pnpm test:e2e at line 146, and the all-tests-passed job at line 173 has needs: [test-e2e, test-integration, lint]. With every call site throwing, every test in scores.e2e.test.ts fails, the test-e2e job fails, and the merge gate blocks.
Step-by-step proof
pnpm test:e2erunspnpm run build && vitest run --project=e2e.- Build produces
packages/core/dist/index.mjswhich re-exports the newScoresclass.grep -n "getById" packages/core/src/api/api/resources/scores/client/Client.tsreturns zero matches after this PR. - Vitest starts the e2e project, loads
tests/e2e/scores.e2e.test.ts, and runs the firstdescribeblock. - The first call site,
tests/e2e/scores.e2e.test.ts:69→await assertions.api.scores.getById(scoreId), resolvesassertions.api.scoresto the newScoresinstance. Scores.prototype.getById === undefined→ Node throwsTypeError: assertions.api.scores.getById is not a function.- The test fails. The remaining 25 call sites fail identically.
test-e2ejob reports failure.all-tests-passedcannot succeed.
How to fix
Update tests/e2e/scores.e2e.test.ts (26 call sites) to call assertions.api.legacy.scoresV2.getById(scoreId) — the new location of the v2 endpoint — or migrate to the v3 pattern assertions.api.scores.getMany({ id: scoreId }) if the tests should target the new endpoint. A small helper on ServerAssertions (e.g. getScoreById(scoreId)) would centralize the change. Since this PR is auto-generated codegen, the maintainer may prefer to land the test migration as a follow-up commit, but it must land before merge to keep CI green.
Greptile Summary
This auto-generated PR (from Fern/API spec commit
e5c1a45) promotes the v3 scores API to the defaultscoresclient and moves the v2 scores API underlegacy.scoresV2, while renaming allV3-suffixed types (e.g.ScoreSubjectV3→ScoreSubject,GetScoresV3Meta→GetScoresMeta).client.scoresV3is removed; existing callers ofscoresV3.getManyV3()must migrate toclient.scores.getMany(), which uses cursor-based pagination and changed parameter types.client.scores.getById()is removed and only survives asclient.legacy.scoresV2.getById()— which the JSDoc marks unavailable on Langfuse v4+ — leaving no documented v3 single-score fetch path.GetScoresRequest.valuechanged fromnumbertostringandGetScoresResponse.metachanged from page-based (totalItems,totalPages) to cursor-based (cursor) — consumers reading those fields will silently getundefinedat runtime.Confidence Score: 3/5
The generated code is internally consistent, but three concurrent breaking changes touch the public SDK surface: the pagination model for the main scores list endpoint, the type of the value filter parameter, and the removal of a previously-available single-score fetch method with no v3 replacement. Any consumer upgrading without reading the diff will hit runtime errors or silent wrong-data conditions.
The restructuring correctly reflects the API spec and the internal wiring is coherent. However, GetScoresRequest.value flipped from number to string, meta.totalItems/meta.totalPages silently disappear at runtime, and getById is gone from the v3 client with the only surviving fallback already marked deprecated and unavailable on v4+. These compound to meaningful migration risk for existing SDK consumers.
packages/core/src/api/api/resources/scores/client/requests/GetScoresRequest.ts (value type change), packages/core/src/api/api/resources/scores/types/GetScoresResponse.ts (meta shape change), packages/core/src/api/Client.ts (scoresV3 removal)
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD subgraph Before["Before (old API shape)"] A1["client.scoresV3.getManyV3()\n→ GET /api/public/v3/scores\nPagination: cursor-based"] A2["client.scores.getMany()\n→ GET /api/public/v2/scores\nPagination: page-based"] A3["client.scores.getById(scoreId)\n→ GET /api/public/v2/scores/{id}"] end subgraph After["After (new API shape)"] B1["client.scores.getMany()\n→ GET /api/public/v3/scores\nPagination: cursor-based\n(was scoresV3.getManyV3)"] B2["client.legacy.scoresV2.getMany()\n→ GET /api/public/v2/scores\nPagination: page-based\n⚠️ deprecated, unavailable on v4+"] B3["client.legacy.scoresV2.getById(scoreId)\n→ GET /api/public/v2/scores/{id}\n⚠️ deprecated, unavailable on v4+"] B4["No v3 getById\nWorkaround: getMany with id filter"] end A1 -->|"promoted & renamed"| B1 A2 -->|"moved to legacy"| B2 A3 -->|"moved to legacy"| B3 A3 -.->|"v3 gap"| B4 style A1 fill:#d4edda style A2 fill:#fff3cd style A3 fill:#fff3cd style B1 fill:#d4edda style B2 fill:#f8d7da style B3 fill:#f8d7da style B4 fill:#f8d7daPrompt To Fix All With AI
Reviews (1): Last reviewed commit: "feat(api): update API spec from langfuse..." | Re-trigger Greptile