Skip to content

feat(core): add VoltOps trace list client#1255

Merged
omeraplak merged 1 commit intomainfrom
feat/voltops-public-trace-api
Apr 28, 2026
Merged

feat(core): add VoltOps trace list client#1255
omeraplak merged 1 commit intomainfrom
feat/voltops-public-trace-api

Conversation

@omeraplak
Copy link
Copy Markdown
Member

@omeraplak omeraplak commented Apr 28, 2026

PR Checklist

Please check if your PR fulfills the following requirements:

Bugs / Features

What is the current behavior?

Core and SDK clients do not provide a typed way to query persisted VoltOps traces. Consumers building workflow testers or internal debugging tools need to call the public trace endpoint manually, while local Hono/Elysia observability routes only read local recent trace storage.

What is the new behavior?

Adds voltops.observability.traces.list() to @voltagent/core and api.observability.traces.list() to @voltagent/sdk, with typed filters, pagination, sorting, and project-key authentication through the existing clients. Adds tests for query construction/auth headers and documents the Public Trace API under observability docs.

fixes N/A

Notes for reviewers

The hosted API endpoint/auth support is being released separately on the API side. This PR only adds the core/SDK client surface, docs, and changeset.

Validation run:

  • pnpm exec biome check packages/sdk/src/client/index.ts packages/sdk/src/client/index.spec.ts packages/sdk/src/types.ts packages/sdk/src/index.ts packages/core/src/voltops/client.ts packages/core/src/voltops/client.spec.ts packages/core/src/voltops/types.ts packages/core/src/voltops/index.ts packages/core/src/index.ts
  • pnpm --filter @voltagent/core typecheck
  • pnpm --filter @voltagent/core test:single src/voltops/client.spec.ts
  • pnpm --filter @voltagent/sdk test src/client/index.spec.ts
  • pnpm --filter @voltagent/sdk build

Summary by cubic

Adds a typed Public Trace API client to load persisted VoltOps traces from apps and tools. Exposes voltops.observability.traces.list() in @voltagent/core and api.observability.traces.list() in @voltagent/sdk, authenticated with project keys.

  • New Features
    • Filters (env, status, tags, dates), sorting (asc/desc), and pagination; proper array/date query serialization; returns total and pageCount.
    • Exports types: VoltOpsObservabilityApi, VoltOpsObservabilityTrace, VoltOpsTraceListOptions, VoltOpsTraceListResponse, VoltOpsTraceSortOrder.
    • Uses existing headers (X-Public-Key, X-Secret-Key); tests cover query construction and auth in core and SDK.
    • Docs: new “Public Trace API” page, plus overview/sidebar updates.

Written for commit 97b2478. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features

    • Public Trace API: query persisted VoltOps traces with project-key auth; supports filtering, pagination, sorting, and rich query options accessible from core and SDK clients.
  • Documentation

    • Added a detailed Public Trace API docs page with examples, parameter formats, response schema, workflow tips, and security guidance.
  • Tests

    • Added unit tests covering traces listing behavior for both client implementations.
  • Chores

    • Release note/changeset added to bump patch versions.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 28, 2026

🦋 Changeset detected

Latest commit: 97b2478

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@voltagent/core Patch
@voltagent/sdk Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@joggrbot

This comment has been minimized.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

📝 Walkthrough

Walkthrough

Adds a Public Trace API to VoltOps observability: new types, client methods (core + SDK) to list persisted traces, unit tests, a changeset, and full documentation/site navigation for the feature.

Changes

Cohort / File(s) Summary
Release & Changeset
\.changeset/public-trace-api.md
Adds a changeset entry bumping patch versions and documenting the new Public Trace API.
Core - Types & Exports
packages/core/src/voltops/types.ts, packages/core/src/voltops/index.ts, packages/core/src/index.ts
Introduces and re-exports observability/trace types: VoltOpsObservabilityApi, VoltOpsObservabilityTrace, VoltOpsTraceListOptions, VoltOpsTraceListResponse, VoltOpsTraceSortOrder.
Core - Implementation
packages/core/src/voltops/client.ts
Adds observability property and observability.traces.list() wired to a listObservabilityTraces method calling /api/public/otel/v1/traces.
Core - Tests
packages/core/src/voltops/client.spec.ts
Unit test for observability.traces.list verifying query construction, headers, GET request, and response parsing.
SDK - Types & Exports
packages/sdk/src/types.ts, packages/sdk/src/index.ts
Adds observability/trace types and re-exports them from the SDK package.
SDK - Implementation
packages/sdk/src/client/index.ts
Adds observability.traces.list() to VoltAgentCoreAPI and a buildQueryString helper to serialize options into query params.
SDK - Tests
packages/sdk/src/client/index.spec.ts
Test ensuring endpoint invocation with query parameters and response passthrough.
Docs & Site
website/observability/public-trace-api.md, website/observability/overview.md, website/sidebarsObservability.ts
New Public Trace API doc page, updated overview navigation order, and sidebar entry addition.

Sequence Diagram(s)

sequenceDiagram
    actor Client as Client (core/sdk)
    participant API as Public Trace API (/api/public/otel/v1/traces)
    participant Store as Trace Storage
    Client->>API: GET /api/public/otel/v1/traces?{query}
    note right of API: Validate x-public-key / x-secret-key\nParse query params
    API->>Store: Query persisted traces (filters, pagination)
    Store-->>API: Return traces + total
    API-->>Client: 200 OK + JSON (VoltOpsTraceListResponse)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat: add feedback #940: Adds public APIs to VoltOps client modules (types and client surfaces), similar module-level changes to core/SDK.

Suggested reviewers

  • lzj960515

Poem

🐰
I hopped through traces, one by one,
Collected threads beneath the sun,
A public path to search and list,
Now observability can’t be missed—
Hop, query, find — the debug's fun!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(core): add VoltOps trace list client' accurately summarizes the main feature addition—introducing a typed trace listing client to the core package.
Description check ✅ Passed The PR description includes all required checklist items, clearly documents current/new behavior, lists validation commands, and notes that API endpoint support is separate.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/voltops-public-trace-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/voltops/types.ts`:
- Around line 961-993: The public trace-list type VoltOpsTraceListOptions now
includes feedbackKey, feedbackScore, minFeedbackScore, maxFeedbackScore,
feedbackValue and feedbackSourceType but the SDK's exposed type is missing them;
reconcile the surfaces by either adding those same feedback* fields to the SDK's
exported Trace list type (so SDK consumers get identical typed filters) or
remove the feedback* fields from VoltOpsTraceListOptions here if they are not
intended to ship—update the SDK type name that mirrors VoltOpsTraceListOptions
accordingly and ensure exported docs/types are regenerated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5fc544f2-c056-426b-a4fb-43dca183dcb7

📥 Commits

Reviewing files that changed from the base of the PR and between c05cc36 and ef7112d.

📒 Files selected for processing (13)
  • .changeset/public-trace-api.md
  • packages/core/src/index.ts
  • packages/core/src/voltops/client.spec.ts
  • packages/core/src/voltops/client.ts
  • packages/core/src/voltops/index.ts
  • packages/core/src/voltops/types.ts
  • packages/sdk/src/client/index.spec.ts
  • packages/sdk/src/client/index.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/types.ts
  • website/observability/overview.md
  • website/observability/public-trace-api.md
  • website/sidebarsObservability.ts

Comment thread packages/core/src/voltops/types.ts
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 28, 2026

Deploying voltagent with  Cloudflare Pages  Cloudflare Pages

Latest commit: 97b2478
Status: ✅  Deploy successful!
Preview URL: https://f089caef.voltagent.pages.dev
Branch Preview URL: https://feat-voltops-public-trace-ap.voltagent.pages.dev

View logs

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 13 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/sdk/src/types.ts">

<violation number="1" location="packages/sdk/src/types.ts:24">
P2: These newly added trace type definitions duplicate existing `@voltagent/core` exports; re-export the core types instead to avoid type drift between packages.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread packages/sdk/src/types.ts
Comment on lines +24 to +103
export type VoltOpsTraceSortOrder = "asc" | "desc";

export interface VoltOpsTraceListOptions {
agentId?: string | string[];
model?: string | string[];
traceId?: string;
limit?: number;
offset?: number;
sortBy?: string;
sortOrder?: VoltOpsTraceSortOrder;
environments?: string | string[];
status?: string | string[];
level?: string | string[];
tags?: string | string[];
userId?: string;
startDate?: string | Date;
endDate?: string | Date;
minTokens?: number;
maxTokens?: number;
minCost?: number;
maxCost?: number;
minDuration?: number;
maxDuration?: number;
search?: string;
conversationId?: string;
entityType?: string | string[];
promptId?: string;
promptVersion?: string;
feedbackKey?: string | string[];
feedbackScore?: number;
minFeedbackScore?: number;
maxFeedbackScore?: number;
feedbackValue?: string;
feedbackSourceType?: string | string[];
}

export interface VoltOpsObservabilityTrace {
trace_id: string;
project_id: string;
agent_id?: string;
entity_type?: string;
user_id?: string | null;
conversation_id?: string | null;
start_time: string;
end_time?: string | null;
status?: string | null;
input?: unknown;
output?: unknown;
usage?: unknown;
metadata?: Record<string, unknown> | null;
tags?: string[] | null;
model?: string | null;
level?: string | null;
status_message?: string | null;
service_name?: string;
service_version?: string | null;
span_count?: number;
error_count?: number;
duration_ms?: number | null;
resource_attributes?: Record<string, unknown> | null;
created_at?: string;
latest_feedback_score?: number | null;
latest_feedback_key?: string | null;
latest_feedback_comment?: string | null;
latest_feedback_at?: string | null;
[key: string]: unknown;
}

export interface VoltOpsTraceListResponse {
data: VoltOpsObservabilityTrace[];
total: number;
pageCount: number;
subscription?: unknown;
}

export interface VoltOpsObservabilityApi {
traces: {
list(options?: VoltOpsTraceListOptions): Promise<VoltOpsTraceListResponse>;
};
}
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: These newly added trace type definitions duplicate existing @voltagent/core exports; re-export the core types instead to avoid type drift between packages.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/sdk/src/types.ts, line 24:

<comment>These newly added trace type definitions duplicate existing `@voltagent/core` exports; re-export the core types instead to avoid type drift between packages.</comment>

<file context>
@@ -21,6 +21,87 @@ export type {
   RagSearchKnowledgeBaseResult,
 } from "@voltagent/core";
 
+export type VoltOpsTraceSortOrder = "asc" | "desc";
+
+export interface VoltOpsTraceListOptions {
</file context>
Suggested change
export type VoltOpsTraceSortOrder = "asc" | "desc";
export interface VoltOpsTraceListOptions {
agentId?: string | string[];
model?: string | string[];
traceId?: string;
limit?: number;
offset?: number;
sortBy?: string;
sortOrder?: VoltOpsTraceSortOrder;
environments?: string | string[];
status?: string | string[];
level?: string | string[];
tags?: string | string[];
userId?: string;
startDate?: string | Date;
endDate?: string | Date;
minTokens?: number;
maxTokens?: number;
minCost?: number;
maxCost?: number;
minDuration?: number;
maxDuration?: number;
search?: string;
conversationId?: string;
entityType?: string | string[];
promptId?: string;
promptVersion?: string;
feedbackKey?: string | string[];
feedbackScore?: number;
minFeedbackScore?: number;
maxFeedbackScore?: number;
feedbackValue?: string;
feedbackSourceType?: string | string[];
}
export interface VoltOpsObservabilityTrace {
trace_id: string;
project_id: string;
agent_id?: string;
entity_type?: string;
user_id?: string | null;
conversation_id?: string | null;
start_time: string;
end_time?: string | null;
status?: string | null;
input?: unknown;
output?: unknown;
usage?: unknown;
metadata?: Record<string, unknown> | null;
tags?: string[] | null;
model?: string | null;
level?: string | null;
status_message?: string | null;
service_name?: string;
service_version?: string | null;
span_count?: number;
error_count?: number;
duration_ms?: number | null;
resource_attributes?: Record<string, unknown> | null;
created_at?: string;
latest_feedback_score?: number | null;
latest_feedback_key?: string | null;
latest_feedback_comment?: string | null;
latest_feedback_at?: string | null;
[key: string]: unknown;
}
export interface VoltOpsTraceListResponse {
data: VoltOpsObservabilityTrace[];
total: number;
pageCount: number;
subscription?: unknown;
}
export interface VoltOpsObservabilityApi {
traces: {
list(options?: VoltOpsTraceListOptions): Promise<VoltOpsTraceListResponse>;
};
}
export type {
VoltOpsObservabilityApi,
VoltOpsObservabilityTrace,
VoltOpsTraceListOptions,
VoltOpsTraceListResponse,
VoltOpsTraceSortOrder,
} from "@voltagent/core";
Fix with Cubic

@omeraplak omeraplak force-pushed the feat/voltops-public-trace-api branch from ef7112d to 97b2478 Compare April 28, 2026 02:27
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
packages/core/src/voltops/client.ts (1)

393-401: Remove the cast in trace-list query construction.

options as Record<string, unknown> is unnecessary and weakens type safety.

Proposed diff
   private async listObservabilityTraces(
     options: VoltOpsTraceListOptions = {},
   ): Promise<VoltOpsTraceListResponse> {
-    const query = this.buildQueryString(options as Record<string, unknown>);
+    const query = this.buildQueryString(options);
     return await this.request<VoltOpsTraceListResponse>(
       "GET",
       `/api/public/otel/v1/traces${query}`,
     );
   }

As per coding guidelines, "Maintain type safety in TypeScript-first codebase."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/voltops/client.ts` around lines 393 - 401, The code in
listObservabilityTraces uses an unnecessary cast "options as Record<string,
unknown>" which weakens type safety; remove the cast and pass options directly
to buildQueryString, then update buildQueryString's signature to accept a
generic or the specific VoltOpsTraceListOptions type (e.g., make
buildQueryString<T>(params: T) or add an overload that accepts
VoltOpsTraceListOptions) so the call this.buildQueryString(options) remains
type-safe while preserving existing behavior in listObservabilityTraces.
packages/core/src/voltops/client.spec.ts (1)

382-393: The URL assertion is brittle due to query-parameter ordering.

Assert pathname + individual searchParams values instead of one full URL string to keep this test stable across harmless serializer/order changes.

Proposed diff
-      expect(fetchMock).toHaveBeenCalledWith(
-        "https://api.voltops.com/api/public/otel/v1/traces?limit=10&offset=20&search=checkout&environments=dev%2Cprod&sortOrder=desc",
-        expect.objectContaining({
-          method: "GET",
-          headers: expect.objectContaining({
-            "X-Public-Key": "pk_test_key",
-            "X-Secret-Key": "sk_test_key",
-          }),
-          body: undefined,
-        }),
-      );
+      const [calledUrl, calledInit] = fetchMock.mock.calls[0];
+      const parsed = new URL(calledUrl);
+      expect(parsed.pathname).toBe("/api/public/otel/v1/traces");
+      expect(parsed.searchParams.get("limit")).toBe("10");
+      expect(parsed.searchParams.get("offset")).toBe("20");
+      expect(parsed.searchParams.get("search")).toBe("checkout");
+      expect(parsed.searchParams.get("environments")).toBe("dev,prod");
+      expect(parsed.searchParams.get("sortOrder")).toBe("desc");
+      expect(calledInit).toEqual(
+        expect.objectContaining({
+          method: "GET",
+          headers: expect.objectContaining({
+            "X-Public-Key": "pk_test_key",
+            "X-Secret-Key": "sk_test_key",
+          }),
+          body: undefined,
+        }),
+      );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/voltops/client.spec.ts` around lines 382 - 393, The test's
URL assertion is brittle because it compares the full URL string including
query-param ordering; locate the fetch mock assertion
(expect(fetchMock).toHaveBeenCalledWith(...)) and replace the full-URL string
check with extracting the first fetch call's URL (from
fetchMock.mock.calls[0][0]) and constructing a URL object, then assert the
pathname equals "/api/public/otel/v1/traces" and individually assert
searchParams.get('limit'), 'offset', 'search', 'environments', and 'sortOrder'
have the expected values (keep the existing header/body assertions and the
result.total check).
packages/core/src/voltops/types.ts (1)

961-968: Narrow sortBy to a typed field union for safer API usage.

sortBy?: string removes compile-time validation on a public query contract. If server-supported fields are known, expose them as a literal union (or exported constant tuple) to catch invalid sort keys early.

As per coding guidelines, "Maintain type safety in TypeScript-first codebase."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/voltops/types.ts` around lines 961 - 968, The current
VoltOpsTraceListOptions type uses sortBy?: string which allows invalid keys;
define a narrow literal union (e.g., export type VoltOpsTraceSortKey =
'createdAt' | 'duration' | 'status' | ...) or export a const tuple (e.g.,
EXPORT_TRACE_SORT_KEYS) of supported server fields and derive a type from it,
then change VoltOpsTraceListOptions.sortBy to use that union (sortBy?:
VoltOpsTraceSortKey) so callers get compile-time validation; update any related
usages and tests to use the new typed keys.
packages/sdk/src/client/index.ts (1)

189-211: Drop the unsafe cast here and make the request method explicit.

The as Record<string, unknown> cast bypasses compile-time checks, and relying on default GET is implicit.

Proposed diff
-  private async listObservabilityTraces(
-    options: VoltOpsTraceListOptions = {},
-  ): Promise<VoltOpsTraceListResponse> {
-    const query = this.buildQueryString(options as Record<string, unknown>);
-    return await this.request<VoltOpsTraceListResponse>(`/api/public/otel/v1/traces${query}`);
-  }
+  private async listObservabilityTraces(
+    options: VoltOpsTraceListOptions = {},
+  ): Promise<VoltOpsTraceListResponse> {
+    const query = this.buildQueryString(options);
+    return await this.request<VoltOpsTraceListResponse>(`/api/public/otel/v1/traces${query}`, {
+      method: "GET",
+    });
+  }

As per coding guidelines, "Maintain type safety in TypeScript-first codebase."

Also applies to: 235-240

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/sdk/src/client/index.ts` around lines 189 - 211, The code is using
an unsafe cast to Record<string, unknown> and relying on an implicit default
GET—remove the cast and make the HTTP method explicit: update callers that pass
params into buildQueryString/request so their params are correctly typed (e.g.,
define params as Record<string, unknown> or a more specific interface instead of
using "as Record<string, unknown>"), and change the request invocation/signature
to accept an explicit method parameter (no implicit default) so callers supply
"GET"/"POST" etc.; update buildQueryString and the request(...) (or makeRequest)
usages accordingly to preserve type-safety and avoid the unsafe cast.
packages/core/src/index.ts (1)

129-135: These explicit type exports look redundant with export * from "./voltops".

Consider keeping a single export path to reduce surface duplication and maintenance drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/index.ts` around lines 129 - 135, The explicit type export
block listing VoltOpsObservabilityApi, VoltOpsObservabilityTrace,
VoltOpsTraceListOptions, VoltOpsTraceListResponse, and VoltOpsTraceSortOrder is
redundant because export * from "./voltops" already re-exports them; remove the
explicit type-only export block and rely on the single export path (export *
from "./voltops") to avoid duplicated surface area, then run the TypeScript
build/check to confirm the types are still exported as expected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/voltops/client.ts`:
- Around line 122-126: isObservabilityEnabled() currently always returns false
while the client exposes observability.traces.list (bound to
listObservabilityTraces), causing inconsistent semantics; update the
isObservabilityEnabled() implementation to return true when the observability
surface is actually present (e.g., check that this.observability?.traces?.list
is a function) so callers gating behavior on isObservabilityEnabled() reflect
the new observability client; ensure the check references the existing
listObservabilityTraces binding (observability.traces.list) rather than
hardcoding false.

In `@packages/core/src/voltops/types.ts`:
- Around line 1056-1058: Update the misleading comment near the VoltOpsClient
observability declaration so it reflects the actual API surface: remove or
rewrite the text that says observability was removed and instead document that
VoltOpsClient exposes an observability property of type VoltOpsObservabilityApi
(observability) and briefly indicate its purpose (observability read API
surface). Locate the comment adjacent to the observability:
VoltOpsObservabilityApi; declaration and make the comment consistent with the
current interface.

---

Nitpick comments:
In `@packages/core/src/index.ts`:
- Around line 129-135: The explicit type export block listing
VoltOpsObservabilityApi, VoltOpsObservabilityTrace, VoltOpsTraceListOptions,
VoltOpsTraceListResponse, and VoltOpsTraceSortOrder is redundant because export
* from "./voltops" already re-exports them; remove the explicit type-only export
block and rely on the single export path (export * from "./voltops") to avoid
duplicated surface area, then run the TypeScript build/check to confirm the
types are still exported as expected.

In `@packages/core/src/voltops/client.spec.ts`:
- Around line 382-393: The test's URL assertion is brittle because it compares
the full URL string including query-param ordering; locate the fetch mock
assertion (expect(fetchMock).toHaveBeenCalledWith(...)) and replace the full-URL
string check with extracting the first fetch call's URL (from
fetchMock.mock.calls[0][0]) and constructing a URL object, then assert the
pathname equals "/api/public/otel/v1/traces" and individually assert
searchParams.get('limit'), 'offset', 'search', 'environments', and 'sortOrder'
have the expected values (keep the existing header/body assertions and the
result.total check).

In `@packages/core/src/voltops/client.ts`:
- Around line 393-401: The code in listObservabilityTraces uses an unnecessary
cast "options as Record<string, unknown>" which weakens type safety; remove the
cast and pass options directly to buildQueryString, then update
buildQueryString's signature to accept a generic or the specific
VoltOpsTraceListOptions type (e.g., make buildQueryString<T>(params: T) or add
an overload that accepts VoltOpsTraceListOptions) so the call
this.buildQueryString(options) remains type-safe while preserving existing
behavior in listObservabilityTraces.

In `@packages/core/src/voltops/types.ts`:
- Around line 961-968: The current VoltOpsTraceListOptions type uses sortBy?:
string which allows invalid keys; define a narrow literal union (e.g., export
type VoltOpsTraceSortKey = 'createdAt' | 'duration' | 'status' | ...) or export
a const tuple (e.g., EXPORT_TRACE_SORT_KEYS) of supported server fields and
derive a type from it, then change VoltOpsTraceListOptions.sortBy to use that
union (sortBy?: VoltOpsTraceSortKey) so callers get compile-time validation;
update any related usages and tests to use the new typed keys.

In `@packages/sdk/src/client/index.ts`:
- Around line 189-211: The code is using an unsafe cast to Record<string,
unknown> and relying on an implicit default GET—remove the cast and make the
HTTP method explicit: update callers that pass params into
buildQueryString/request so their params are correctly typed (e.g., define
params as Record<string, unknown> or a more specific interface instead of using
"as Record<string, unknown>"), and change the request invocation/signature to
accept an explicit method parameter (no implicit default) so callers supply
"GET"/"POST" etc.; update buildQueryString and the request(...) (or makeRequest)
usages accordingly to preserve type-safety and avoid the unsafe cast.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b13787c0-ad32-41a0-933b-9936acb2110c

📥 Commits

Reviewing files that changed from the base of the PR and between ef7112d and 97b2478.

📒 Files selected for processing (13)
  • .changeset/public-trace-api.md
  • packages/core/src/index.ts
  • packages/core/src/voltops/client.spec.ts
  • packages/core/src/voltops/client.ts
  • packages/core/src/voltops/index.ts
  • packages/core/src/voltops/types.ts
  • packages/sdk/src/client/index.spec.ts
  • packages/sdk/src/client/index.ts
  • packages/sdk/src/index.ts
  • packages/sdk/src/types.ts
  • website/observability/overview.md
  • website/observability/public-trace-api.md
  • website/sidebarsObservability.ts
✅ Files skipped from review due to trivial changes (7)
  • website/sidebarsObservability.ts
  • website/observability/overview.md
  • .changeset/public-trace-api.md
  • packages/sdk/src/client/index.spec.ts
  • packages/core/src/voltops/index.ts
  • packages/sdk/src/index.ts
  • website/observability/public-trace-api.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/types.ts

Comment on lines +122 to +126
this.observability = {
traces: {
list: this.listObservabilityTraces.bind(this),
},
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

isObservabilityEnabled() semantics now conflict with the new observability client surface.

The client now exposes observability.traces.list, but isObservabilityEnabled() still always returns false. This can mislead callers that gate behavior on that method.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/voltops/client.ts` around lines 122 - 126,
isObservabilityEnabled() currently always returns false while the client exposes
observability.traces.list (bound to listObservabilityTraces), causing
inconsistent semantics; update the isObservabilityEnabled() implementation to
return true when the observability surface is actually present (e.g., check that
this.observability?.traces?.list is a function) so callers gating behavior on
isObservabilityEnabled() reflect the new observability client; ensure the check
references the existing listObservabilityTraces binding
(observability.traces.list) rather than hardcoding false.

Comment on lines +1056 to +1058
/** Observability read API surface */
observability: VoltOpsObservabilityApi;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Observability comments are now contradictory to the interface surface.

VoltOpsClient now exposes observability, but nearby comments still state observability is removed. Please align the comments to avoid misleading integrators.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/voltops/types.ts` around lines 1056 - 1058, Update the
misleading comment near the VoltOpsClient observability declaration so it
reflects the actual API surface: remove or rewrite the text that says
observability was removed and instead document that VoltOpsClient exposes an
observability property of type VoltOpsObservabilityApi (observability) and
briefly indicate its purpose (observability read API surface). Locate the
comment adjacent to the observability: VoltOpsObservabilityApi; declaration and
make the comment consistent with the current interface.

@omeraplak omeraplak merged commit 97226de into main Apr 28, 2026
23 checks passed
@omeraplak omeraplak deleted the feat/voltops-public-trace-api branch April 28, 2026 02:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant