Skip to content

Conversation

@mansi0829
Copy link

@mansi0829 mansi0829 commented Oct 19, 2025

Details

Added the ability to tag multiple threads at once, similar to how tags can be applied to multiple traces. Users can now select several threads and add or update tags in a single action, improving workflow efficiency and consistency.

Change checklist

  • User facing
  • Documentation update

Issues

Testing

  • unit test case has been added for thread iterations

Documentation

  • Introduced batch update functionality to add tags for multiple thread in one call
  • Add Tags Button added in Threads Tab similar to Traces and Span
Screenshot 2025-10-19 at 3 16 41 PM Screenshot 2025-10-19 at 3 17 01 PM Screenshot 2025-10-19 at 3 18 24 PM

@mansi0829 mansi0829 requested a review from a team as a code owner October 19, 2025 09:53
Copilot AI review requested due to automatic review settings October 19, 2025 09:53
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 adds the ability to batch update tags for multiple threads, addressing feature request #3494. The implementation follows the existing pattern used for traces and spans, providing a consistent user experience across all entity types.

Key Changes

  • Added batch update API endpoint and service layer methods to support updating multiple threads simultaneously
  • Extended the frontend UI to include an "Add tags" button in the Threads tab with dialog functionality
  • Implemented comprehensive test coverage for batch update scenarios including empty lists and existing tags

Reviewed Changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
apps/opik-frontend/src/hooks/useTracesOrSpansList.ts Added threads enum value to support thread-specific operations
apps/opik-frontend/src/components/pages/TracesPage/ThreadsTab/ThreadsTab.tsx Added callback to clear row selection after tag operations
apps/opik-frontend/src/components/pages/TracesPage/ThreadsTab/ThreadsActionsPanel.tsx Integrated Add Tag dialog and button for threads
apps/opik-frontend/src/components/pages-shared/traces/AddTagDialog/AddTagDialog.tsx Extended dialog to handle thread batch updates with tag merging logic
apps/opik-frontend/src/api/traces/useThreadBatchUpdateMutation.ts Created mutation hook for batch thread updates API calls
apps/opik-backend/src/test/java/.../TracesResourceTest.java Added comprehensive unit tests for batch update functionality
apps/opik-backend/src/test/java/.../TraceResourceClient.java Added test client method for batch update endpoint
apps/opik-backend/src/main/java/.../TraceThreadService.java Implemented service layer batch update logic with validation
apps/opik-backend/src/main/java/.../TraceThreadDAO.java Added DAO method with SQL template for batch thread updates
apps/opik-backend/src/main/java/.../TracesResource.java Created REST endpoint for batch thread updates
apps/opik-backend/src/main/java/.../TraceThreadBatchUpdate.java Defined request DTO with validation constraints

Comment on lines +47 to +50
toast({
title: "Threads updated",
description: "Tags have been successfully updated",
});
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

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

Duplicate success toast: The mutation's onSuccess displays a generic toast, but AddTagDialog already shows a more specific toast (Tag "${newTag}" added to ${rows.length} selected threads). Remove this duplicate toast from the mutation hook to avoid showing two toasts for the same action.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines 561 to 562
template.add("tags", tags.toString());
log.debug("DAO: Added tags to template: '{}'", tags);
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

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

Using tags.toString() for the template will produce incorrect SQL syntax. The toString() method on a Set produces a string like [tag1, tag2] with brackets, which won't work in SQL. Remove this line as the tags are already bound as an array parameter in lines 571-575.

Suggested change
template.add("tags", tags.toString());
log.debug("DAO: Added tags to template: '{}'", tags);
log.debug("DAO: Tags present for batch update: '{}'", tags);

Copilot uses AI. Check for mistakes.
@Nimrod007
Copy link
Collaborator

Hi @mansi0829 , thanks for your contribution, Ive approved workflows to run on this PR. please make sure it passed all internal check and use the AI code review as well.

After all is passing we will work on this review and test

@mansi0829
Copy link
Author

mansi0829 commented Oct 19, 2025

Hi @mansi0829 , thanks for your contribution, Ive approved workflows to run on this PR. please make sure it passed all internal check and use the AI code review as well.

After all is passing we will work on this review and test

Thanks @Nimrod007 will this take time since i dont see pipeline has started yet can you confirm on this

@Nimrod007
Copy link
Collaborator

Hi @mansi0829 , thanks for your contribution, Ive approved workflows to run on this PR. please make sure it passed all internal check and use the AI code review as well.
After all is passing we will work on this review and test

Thanks @Nimrod007 will this take time since i dont see pipeline has started yet can you confirm on this

@mansi0829 they started running, do you see which checks are failing / running ?

@mansi0829
Copy link
Author

Hi @mansi0829 , thanks for your contribution, Ive approved workflows to run on this PR. please make sure it passed all internal check and use the AI code review as well.
After all is passing we will work on this review and test

Thanks @Nimrod007 will this take time since i dont see pipeline has started yet can you confirm on this

@mansi0829 they started running, do you see which checks are failing / running ?

@Nimrod007 do you have to approve after each commit i add have added few lint related fix but pipeline is not running now

@Nimrod007
Copy link
Collaborator

Hi @mansi0829 , thanks for your contribution, Ive approved workflows to run on this PR. please make sure it passed all internal check and use the AI code review as well.
After all is passing we will work on this review and test

Thanks @Nimrod007 will this take time since i dont see pipeline has started yet can you confirm on this

@mansi0829 they started running, do you see which checks are failing / running ?

@Nimrod007 do you have to approve after each commit i add have added few lint related fix but pipeline is not running now

@mansi0829 will check, it used to work after Ive approved once.

@Nimrod007 Nimrod007 changed the title [FR]Ability to add tags to multiple threads #3494 [issue-3494] [FE] [BE] Ability to add tags to multiple threads #3494 Oct 19, 2025
@Nimrod007 Nimrod007 self-assigned this Oct 19, 2025
@Nimrod007 Nimrod007 assigned mansi0829 and unassigned Nimrod007 Oct 19, 2025
Copy link
Member

@andrescrz andrescrz left a comment

Choose a reason for hiding this comment

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

Hi @mansi0829,

Thank you very much for your contribution! I initially focused on reviewing the backend portion, and it looks very promising—it's not far from being ready.

I've left some comments and guidance on areas that could use a bit more attention in the next revision. Please feel free to reach out if you have any questions or need further clarification.

Thanks again for your hard work!

Comment on lines 793 to 794
log.info("Resource: Batch updating '{}' threads on workspace_id: '{}', user: '{}', update: '{}'",
batchUpdate.threadModelIds().size(), workspaceId, userName, batchUpdate.update());
Copy link
Member

Choose a reason for hiding this comment

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

Minor: let's not print TraceThreadUpdate object in these logs, as it can be very noisy (and leak sensitive information in the future).

Additionally, I'd move the printing of the size together with all parameters at the end of the sentence. This is to facilitate log searching when debugging production issues.

This comment applies to the other logs below and in the rest of the PR.

Copy link
Author

Choose a reason for hiding this comment

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

Hi @andrescrz sure, agree on this will move logs accordingly

;
""";

private static final String BATCH_UPDATE_THREADS_SQL = """
Copy link
Member

Choose a reason for hiding this comment

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

For this query and all the related methods in this DAO, the service etc. There's a minimal difference, which is allowing multiple ids instead of one.

Let's just update the existing query and code to allow that:

  1. Update the original query where clause to id IN :ids.
  2. Update the methods to accept a Set of UUIDs instead of single one.
    2.1 You can keep the old methods, but overload them to just pass a set with a single UUID.

}

@Test
void batchUpdateThreads() {
Copy link
Member

Choose a reason for hiding this comment

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

Let's create a new separated subclass for these new tests. It's a different endpoint, so we usually follow that convention.

Comment on lines +10931 to +10933
var thread1 = createThread();
var thread2 = createThread();
var thread3 = createThread();
Copy link
Member

Choose a reason for hiding this comment

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

Not a blocker: I'd find or create a flavour of these createThread methods to do it in batches. Test would be faster and more maintainable.

Comment on lines +10935 to +10938
// Check that they don't have tags
assertThat(thread1.tags()).isNull();
assertThat(thread2.tags()).isNull();
assertThat(thread3.tags()).isNull();
Copy link
Member

Choose a reason for hiding this comment

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

Minor: better keep a list of threads and iterate on all of them to assert this.

assertThat(thread3.tags()).isNull();

// Batch update threads
var tags = Set.of("tag1", "tag2", "tag3");
Copy link
Member

Choose a reason for hiding this comment

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

Please use podam factory to just generate a random TraceThreadUpdate.

Comment on lines +10951 to +10956
var actualThread1 = traceResourceClient.getTraceThread(thread1.id(), thread1.projectId(), API_KEY,
TEST_WORKSPACE);
var actualThread2 = traceResourceClient.getTraceThread(thread2.id(), thread2.projectId(), API_KEY,
TEST_WORKSPACE);
var actualThread3 = traceResourceClient.getTraceThread(thread3.id(), thread3.projectId(), API_KEY,
TEST_WORKSPACE);
Copy link
Member

Choose a reason for hiding this comment

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

Same here, please search all threads in one call if possible.

Comment on lines +10958 to +10960
TraceAssertions.assertThreads(List.of(thread1.toBuilder().tags(tags).build()), List.of(actualThread1));
TraceAssertions.assertThreads(List.of(thread2.toBuilder().tags(tags).build()), List.of(actualThread2));
TraceAssertions.assertThreads(List.of(thread3.toBuilder().tags(tags).build()), List.of(actualThread3));
Copy link
Member

Choose a reason for hiding this comment

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

Please use one assertion, but passing the list with all threads instead of one by one.

Comment on lines +10974 to +10975
@Test
void batchUpdateThreadsWithExistingTags() {
Copy link
Member

Choose a reason for hiding this comment

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

This should be a parameterised tests of the first one, basically:

  1. Initial value would be null or random.
  2. It's set to some other expected random value.

@Nimrod007 Nimrod007 added the test-environment Deploy Opik adhoc environment label Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Pending user response test-environment Deploy Opik adhoc environment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Ability to add tags to multiple threads

6 participants