-
Notifications
You must be signed in to change notification settings - Fork 723
Rename datapoints in the UI using bindings #4404
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
base: main
Are you sure you want to change the base?
Conversation
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 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
renameDatapointfunction 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.rstotensorzero-core/src/db/clickhouse/dataset_queries.rs - Added
update_datapoints_metadatamethod to theDatasetQueriestrait 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
mockUpdateDatapointto be called, but the refactoredrenameDatapointfunction now usesgetNativeDatabaseClient().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
mockUpdateDatapointto be called, but the refactoredrenameDatapointfunction now usesgetNativeDatabaseClient().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.
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.
💡 Codex Review
tensorzero/ui/app/routes/datasets/$dataset_name/datapoint/$id/datapointOperations.server.test.ts
Lines 21 to 31 in 831560e
| // 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, | |
| })), | |
| })); |
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".
…gb/rename-datapoints-using-bindings
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
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.
|
/merge-queue |
|
🚀 Merge queue workflow triggered! View the run: https://github.com/tensorzero/tensorzero/actions/runs/19076654509 |
|
/merge-queue |
|
@codex review |
|
🚀 Merge queue workflow triggered! View the run: https://github.com/tensorzero/tensorzero/actions/runs/19112471901 |
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
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.
| const paramsString = safeStringify({ dataset_name, ...params }); | ||
| const result = | ||
| await this.nativeDatabaseClient.updateDatapointsMetadata(paramsString); |
Copilot
AI
Nov 5, 2025
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 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.
| 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); |
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.
💡 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".
TensorZero CI Bot Automated CommentThanks 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:
This causes the TypeScript error: Fix:
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;
}
}
/** |
|
/merge-queue |
|
@codex review |
|
🚀 Merge queue workflow triggered! View the run: https://github.com/tensorzero/tensorzero/actions/runs/19114170893 |
|
Codex Review: Didn't find any major issues. Chef's kiss. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
Important
Adds functionality to update datapoint metadata using bindings, focusing on renaming datapoints, with updates to backend logic, API endpoints, and UI components.
updateDatapointsMetadatamethod toDatabaseClientinindex.tsanddatabase.rsfor updating datapoint metadata.update_datapoints_metadataindataset_queries.rsto handle metadata updates, ensuring no duplicate IDs and validating dataset names.update_datapoints_metadata_handlerinupdate_datapoints.rsto use the new method.renameDatapointfunction indatapointOperations.server.tsto useupdateDatapointsMetadata.datapointOperations.server.test.tsto mock and verifyupdateDatapointsMetadatacalls.actionfunction inroute.tsxto handle rename action using the new method.serde_util.rs.types.rsto include serialization forDatapointMetadataUpdate.This description was created by
for 1ddb8e8. You can customize this summary. It will automatically update as commits are pushed.