Conversation
| foreach (TranslationBuild translationBuild in translationBuilds) | ||
| { | ||
| ServalBuildReportDto report = await BuildReportAsync( | ||
| translationBuild, | ||
| engineToProject, | ||
| eventsByProject, | ||
| projectSnapshots, | ||
| cancellationToken | ||
| ); | ||
| if (report.DraftGenerationRequestId != null) | ||
| { | ||
| matchedRequestIds.Add(report.DraftGenerationRequestId); | ||
| } | ||
| reports.Add(report); | ||
| } |
Check notice
Code scanning / CodeQL
Missed opportunity to use Select Note
Copilot Autofix
AI about 3 hours ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
|
So is this a newer version of the draft jobs tab? |
cdb4aca to
7967398
Compare
Yes, though I will want its tires kicked and to hear feedback first. I also haven't yet wired up the Projects tab to link over to the Serval Builds tab. |
7967398 to
63a0b70
Compare
63a0b70 to
58caefa
Compare
58caefa to
57307d2
Compare
ecc5abc to
256d266
Compare
256d266 to
17f9c7f
Compare
17f9c7f to
c35df22
Compare
| Dictionary<string, List<EventMetric>> unmatchedEventsByProject = eventsByProject | ||
| .ToDictionary( | ||
| kvp => kvp.Key, | ||
| kvp => | ||
| kvp.Value.Where(e => | ||
| { | ||
| string? requestId = GetRequestIdFromEvent(e); | ||
| return requestId == null || !matchedRequestIds.Contains(requestId); | ||
| }) | ||
| .ToList() | ||
| ) | ||
| .Where(kvp => kvp.Value.Count > 0) | ||
| .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); |
There was a problem hiding this comment.
🟡 Events with null request IDs can produce duplicate reports for builds already matched by Serval
In GetBuildsSinceAsync at MachineApiService.cs:1190-1202, the unmatchedEventsByProject filtering uses the condition requestId == null || !matchedRequestIds.Contains(requestId). Events where GetRequestIdFromEvent returns null always pass the filter, even if they were already correlated to a Serval build by FindEventTime (which matches on e.Result?.ToString() == servalBuildId). This means a StartPreTranslationBuildAsync event that was already used to populate sfUserRequested in a Serval-build-based report will also generate a separate events-only report via BuildEventsOnlyReports at line 1664-1690.
This primarily affects older data (pre-2026) that lacks draft generation request ID tags. The result is duplicate entries in the builds list for the same underlying draft generation request.
Prompt for agents
In MachineApiService.cs GetBuildsSinceAsync method, around line 1168-1184, in addition to tracking matchedRequestIds, also track the set of event metric IDs (or timestamps+eventTypes) that were successfully correlated to Serval builds during BuildReportAsync/BuildTimeline processing. Then in the unmatchedEventsByProject filtering at line 1190-1202, exclude events that were already used to build timeline data for a Serval build report, even if they have a null request ID. One approach is to collect all event IDs that were matched during FindEventTime calls and filter them out when building unmatchedEventsByProject.
Was this helpful? React with 👍 or 👎 to provide feedback.
Currently, the Serval Administration area has a Draft Jobs tab which shows a list of Serval builds. It does this by fetching and correlating EventMetric records on the frontend. More information for a build is then obtained by looking up Serval build information, user information, etc.
This PR is a step toward replacing the functionality of the Draft Jobs tab. This PR adds a Serval Builds tab which shows a list of Serval builds. It does this by fetching Serval build data on the backend, and augmenting the data on the backend with details from EventMetric records and project and user metadata. The information is received by the frontend to render to the user.
The Serval Builds tab is designed to be a suitable replacement for the Draft Jobs tab. However, the Draft Jobs tab is still present so the Serval Builds tab can get some vetting first.
This change is