Skip to content

Conversation

@GabrielBianconi
Copy link
Member

@GabrielBianconi GabrielBianconi commented Nov 4, 2025

Important

Adds functionality to update datapoint metadata using bindings, focusing on renaming datapoints, with updates to backend logic, API endpoints, and UI components.

  • Behavior:
    • Adds updateDatapointsMetadata method to DatabaseClient in index.ts and database.rs for updating datapoint metadata.
    • Implements update_datapoints_metadata in dataset_queries.rs to handle metadata updates, ensuring no duplicate IDs and validating dataset names.
    • Updates update_datapoints_metadata_handler in update_datapoints.rs to use the new method.
  • UI:
    • Modifies renameDatapoint function in datapointOperations.server.ts to use updateDatapointsMetadata.
    • Updates tests in datapointOperations.server.test.ts to mock and verify updateDatapointsMetadata calls.
    • Adjusts action function in route.tsx to handle rename action using the new method.
  • Misc:
    • Adds serialization logic for double options in serde_util.rs.
    • Updates types.rs to include serialization for DatapointMetadataUpdate.

This description was created by Ellipsis for 1ddb8e8. You can customize this summary. It will automatically update as commits are pushed.

Copilot AI review requested due to automatic review settings November 4, 2025 15:43
Copy link
Contributor

Copilot AI left a 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 refactors the datapoint rename functionality by moving the business logic from the TypeScript layer to the Rust backend. The rename operation now calls a dedicated update_datapoints_metadata method that performs in-place metadata updates without creating new datapoint IDs.

Key changes:

  • Simplified the TypeScript renameDatapoint function to only pass datapoint ID instead of the entire datapoint object
  • Moved the metadata update logic from tensorzero-core/src/endpoints/datasets/v1/update_datapoints.rs to tensorzero-core/src/db/clickhouse/dataset_queries.rs
  • Added update_datapoints_metadata method to the DatasetQueries trait and implemented it in ClickHouse connection info

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
ui/app/routes/evaluations/$evaluation_name/$datapoint_id/route.tsx Updated to pass only datapointId to renameDatapoint instead of full datapoint and functionType
ui/app/routes/datasets/$dataset_name/datapoint/$id/route.tsx Simplified renameDatapoint call to pass only datapointId
ui/app/routes/datasets/$dataset_name/datapoint/$id/datapointOperations.server.ts Refactored renameDatapoint to use native database client's updateDatapointsMetadata method
ui/app/routes/datasets/$dataset_name/datapoint/$id/datapointOperations.server.test.ts Updated test calls to match new renameDatapoint signature
tensorzero-core/src/endpoints/datasets/v1/update_datapoints.rs Moved update_datapoints_metadata logic to DatasetQueries trait implementation
tensorzero-core/src/db/datasets.rs Added update_datapoints_metadata method to DatasetQueries trait
tensorzero-core/src/db/clickhouse/mock_clickhouse_connection_info.rs Implemented update_datapoints_metadata for mock connection
tensorzero-core/src/db/clickhouse/dataset_queries.rs Added update_datapoints_metadata implementation with validation logic
internal/tensorzero-node/src/database.rs Added NAPI binding for update_datapoints_metadata
internal/tensorzero-node/lib/index.ts Added TypeScript wrapper for updateDatapointsMetadata
Comments suppressed due to low confidence (2)

ui/app/routes/datasets/$dataset_name/datapoint/$id/datapointOperations.server.test.ts:410

  • The test expects the old mockUpdateDatapoint to be called, but the refactored renameDatapoint function now uses getNativeDatabaseClient().updateDatapointsMetadata(). This test needs to be updated to mock the native database client instead of the TensorZero client, otherwise it will fail.
      await renameDatapoint({
        datasetName,
        datapointId: datapoint.id,
        newName,
      });

      // Verify updateDatapoint was called with the new name
      expect(mockUpdateDatapoint).toHaveBeenCalledWith(
        datasetName,
        expect.objectContaining({
          id: datapointId,
          function_name: "write_haiku",
          episode_id: episodeId,
          tags: { environment: "test" },
          is_custom: false,
          source_inference_id: sourceInferenceId,
          auxiliary: "",
          name: newName,
          staled_at: undefined,
        }),
      );

ui/app/routes/datasets/$dataset_name/datapoint/$id/datapointOperations.server.test.ts:494

  • The test expects the old mockUpdateDatapoint to be called, but the refactored renameDatapoint function now uses getNativeDatabaseClient().updateDatapointsMetadata(). This test needs to be updated to mock the native database client instead of the TensorZero client, otherwise it will fail.
      await renameDatapoint({
        datasetName,
        datapointId: datapoint.id,
        newName,
      });

      // Verify updateDatapoint was called with the new name and output_schema
      expect(mockUpdateDatapoint).toHaveBeenCalledWith(
        datasetName,
        expect.objectContaining({
          id: datapointId,
          episode_id: episodeId,
          function_name: "extract_entities",
          tags: { source: "test" },
          is_custom: false,
          source_inference_id: sourceInferenceId,
          output_schema: datapoint.output_schema,
          auxiliary: "",
          name: newName,
          staled_at: undefined,
        }),
      );

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

// Mock TensorZero client at the module boundary
const mockUpdateDatapoint = vi.fn(
async (_datasetName: string, datapoint: Datapoint) => ({
id: datapoint.id,
}),
);
vi.mock("~/utils/tensorzero.server", () => ({
getTensorZeroClient: vi.fn(() => ({
updateDatapoint: mockUpdateDatapoint,
})),
}));

P1 Badge Rename datapoint tests mock wrong client

The UI rename flow now uses getNativeDatabaseClient().updateDatapointsMetadata, but the tests still mock getTensorZeroClient and assert against updateDatapoint. When the tests run they will attempt to load the real native client (which is unavailable in the test environment) and the expectations reference a method that is never called, so the suite will fail. The tests should mock ~/utils/tensorzero/native_client.server and assert that updateDatapointsMetadata is invoked instead.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copilot AI review requested due to automatic review settings November 4, 2025 16:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@GabrielBianconi
Copy link
Member Author

/merge-queue

@github-actions
Copy link
Contributor

github-actions bot commented Nov 4, 2025

🚀 Merge queue workflow triggered!

View the run: https://github.com/tensorzero/tensorzero/actions/runs/19076654509

Copilot AI review requested due to automatic review settings November 5, 2025 18:36
@GabrielBianconi
Copy link
Member Author

/merge-queue

@GabrielBianconi
Copy link
Member Author

@codex review

@github-actions
Copy link
Contributor

github-actions bot commented Nov 5, 2025

🚀 Merge queue workflow triggered!

View the run: https://github.com/tensorzero/tensorzero/actions/runs/19112471901

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 426 to 428
const paramsString = safeStringify({ dataset_name, ...params });
const result =
await this.nativeDatabaseClient.updateDatapointsMetadata(paramsString);
Copy link

Copilot AI Nov 5, 2025

Choose a reason for hiding this comment

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

The TypeScript wrapper passes dataset_name in the serialized params object, but the Rust method signature expects separate dataset_name and request parameters. The Rust implementation will receive dataset_name both as a parameter and inside the serialized JSON, which is inconsistent. The method should either pass just dataset_name and JSON.stringify(params), or the Rust signature should accept a single serialized string containing all parameters.

Suggested change
const paramsString = safeStringify({ dataset_name, ...params });
const result =
await this.nativeDatabaseClient.updateDatapointsMetadata(paramsString);
const paramsString = safeStringify(params);
const result =
await this.nativeDatabaseClient.updateDatapointsMetadata(dataset_name, paramsString);

Copilot uses AI. Check for mistakes.
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@github-actions
Copy link
Contributor

github-actions bot commented Nov 5, 2025

TensorZero CI Bot Automated Comment

Thanks for the PR. CI is failing due to a TypeScript build error in the tensorzero-node package. Specifically, the new DatabaseClient.updateDatapointsMetadata wrapper is calling the native N-API method with the wrong argument list.

Details:

  • The native Rust binding (internal/tensorzero-node/src/database.rs) exposes update_datapoints_metadata(&self, dataset_name: String, request: String) -> Result<String, ...>, i.e., two parameters.
  • The TS wrapper (internal/tensorzero-node/lib/index.ts) currently calls this.nativeDatabaseClient.updateDatapointsMetadata(paramsString) with only one argument and incorrectly includes dataset_name inside the request JSON.

This causes the TypeScript error:
lib/index.ts(428,39): error TS2554: Expected 2 arguments, but got 1.

Fix:

  • Pass two arguments to the native method: dataset_name and the JSON-serialized request.
  • Do not include dataset_name inside the JSON payload; the Rust handler already takes dataset_name separately and parses the request body as UpdateDatapointsMetadataRequest.

Once this is corrected, the TS build should pass and unblock subsequent jobs (UI image build and UI tests).

Warning

I encountered an error while trying to create a follow-up PR: Failed to create follow-up PR using remote https://x-access-token:***@github.com/tensorzero/tensorzero.git: git apply --whitespace=nowarn /tmp/tensorzero-pr-lgRekl/repo/tensorzero.patch failed: error: corrupt patch at line 28
.

The patch I tried to generate is as follows:

diff --git a/internal/tensorzero-node/lib/index.ts b/internal/tensorzero-node/lib/index.ts
index ae4b247bb..a9a0b310f 100644
--- a/internal/tensorzero-node/lib/index.ts
+++ b/internal/tensorzero-node/lib/index.ts
@@ -418,16 +418,16 @@ export class DatabaseClient {
       await this.nativeDatabaseClient.getFeedbackByVariant(paramsString);
     return JSON.parse(result) as FeedbackByVariant[];
   }
 
   async updateDatapointsMetadata(
     dataset_name: string,
     params: UpdateDatapointsMetadataRequest,
   ): Promise<UpdateDatapointsResponse> {
-    const paramsString = safeStringify({ dataset_name, ...params });
-    const result =
-      await this.nativeDatabaseClient.updateDatapointsMetadata(paramsString);
+    // Serialize only the request body; dataset_name is passed as a separate argument to the native binding.
+    const paramsString = safeStringify(params);
+    const result = await this.nativeDatabaseClient.updateDatapointsMetadata(
+      dataset_name,
+      paramsString,
+    );
     return JSON.parse(result) as UpdateDatapointsResponse;
   }
 }
 
 /**

@GabrielBianconi
Copy link
Member Author

/merge-queue

@GabrielBianconi
Copy link
Member Author

@codex review

@github-actions
Copy link
Contributor

github-actions bot commented Nov 5, 2025

🚀 Merge queue workflow triggered!

View the run: https://github.com/tensorzero/tensorzero/actions/runs/19114170893

@chatgpt-codex-connector
Copy link

Codex Review: Didn't find any major issues. Chef's kiss.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

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.

3 participants