Skip to content

feat: thumbs up/down on ai assistant messages#18803

Open
ErlingHauan wants to merge 26 commits into
mainfrom
feat-ai-chat-feedback-buttons
Open

feat: thumbs up/down on ai assistant messages#18803
ErlingHauan wants to merge 26 commits into
mainfrom
feat-ai-chat-feedback-buttons

Conversation

@ErlingHauan
Copy link
Copy Markdown
Contributor

@ErlingHauan ErlingHauan commented May 15, 2026

Description

Adds thumbs up/down buttons that a user can press to give feedback on the assistant's response. When pressed, it opens a dialog where the user can also type an optional message.

bilde

Solves digdir/digdir-ai-lab#144

Flow

  1. User sends a message to the assistant
  2. A Langfuse observation is created for the assistant where the developer id is attached (existing functionality)
  3. The assistant finishes working and returns a message to the user
  4. The user can score the message with a thumbs up or down, with an optional message
  5. The feedback is sent from frontend -> Designer backend -> agent service -> recorded as a score on the observation

Verification

  • Related issues are connected (if applicable)
  • Your code builds clean without any errors or warnings
  • Manual testing done (required)
  • Relevant automated test added (if you find this hard, leave it and we'll help out)

Summary by CodeRabbit

  • New Features

    • Submit thumbs up/down feedback on assistant messages (optional comment, max 10,000 chars); UI integrated into chat with localized strings and submit/cancel flows.
    • Frontend mutation/hook and backend endpoints added to send feedback tied to a message trace; assistant messages now carry trace identifiers.
  • Bug Fixes / Reliability

    • Server-side validation and ownership checks ensure feedback is accepted only for valid traces and authorised contexts.
  • Tests

    • Added backend and frontend tests covering submission, validation, forwarding and trace mapping.

Review Change Stack

@github-actions github-actions Bot added quality/testing Tests that are missing, needs to be created or could be improved. skip-releasenotes Issues that do not make sense to list in our release notes backend frontend solution/studio/designer labels May 15, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds end-user thumbs-up/down feedback: Langfuse helpers and FastAPI feedback endpoint, C# Altinity client and controller, frontend feedback UI/types/hooks, trace-id mapping for persisted messages, API paths/mutations, and tests across services.

Changes

Backend feedback capture and API

Layer / File(s) Summary
Langfuse tracing utilities
src/AI/agents/shared/utils/langfuse_utils.py
Adds get_trace_developer() and get_current_trace_id(), accepts optional score_id in score_validation, and refactors trace/span helpers.
Python feedback endpoint and routing
src/AI/agents/api/routes/feedback.py, src/AI/agents/api/main.py, src/AI/agents/api/routes/__init__.py
Implements PUT /api/feedback/{trace_id} with FeedbackReq validation, X-Developer header checks, trace ownership verification, records Langfuse score with score_id, and wires router into FastAPI app.
Python feedback endpoint tests
src/AI/agents/tests/api/test_feedback.py
Tests cover thumbs-up/down success paths, missing/mismatched developer header, unknown trace owner, and request validation for overlong comment.
Python agent nodes: trace ID propagation
src/AI/agents/agents/graph/nodes/assistant_node.py, src/AI/agents/agents/graph/nodes/reviewer_node.py
Assistant/reviewer nodes emit camelCase traceId in assistant response payloads and reviewer event payloads.
C# client, interface and controller wiring
src/Designer/backend/src/Designer/Services/Interfaces/Altinity/IAltinityAgentClient.cs, src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs, src/Designer/backend/src/Designer/Models/Dto/ChatFeedbackRequest.cs, src/Designer/backend/src/Designer/Controllers/ChatController.cs, src/Designer/backend/src/Designer/Program.cs
Adds IAltinityAgentClient.SendFeedbackAsync, ChatFeedbackRequest DTO, registers Altinity client in DI, injects client into ChatController and exposes feedback/{traceId} PUT action that forwards feedback and returns 204; client PUTs to agent feedback endpoint with X-Developer header.
C# controller tests
src/Designer/backend/tests/Designer.Tests/Controllers/ChatController/SubmitFeedbackTests.cs
Tests verify ChatController endpoint returns 204 and forwards correct arguments to IAltinityAgentClient.SendFeedbackAsync for thumbs up/down.

Frontend feedback UI and state management

Layer / File(s) Summary
Frontend type contracts for feedback
src/Designer/frontend/libs/studio-assistant/src/types/*, src/Designer/frontend/packages/shared/src/types/api/ChatFeedbackPayload.ts
Adds optional traceId to assistant message shapes; introduces UserFeedback/FeedbackPayload, MessageFeedbackTexts, and ChatFeedbackPayload API type; updates re-exports and mocks.
MessageFeedback component: UI, state, styles and tests
src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/*
Renders thumbs-up/down bar, opens comment dialog, trims/omits empty comments, calls onSubmit with { thumbsUp, comment? }, includes CSS module and comprehensive RTL tests.
Messages component: feedback rendering and trace extraction
src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/Messages.tsx, src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/Messages.module.css
Messages accepts feedbackTexts/onMessageFeedback, extracts assistant traceId, conditionally renders MessageFeedback, and retargets heading styles to .assistantContent.
Async message creation flow and tests
src/Designer/frontend/app-development/features/aiAssistant/hooks/useAltinityThreads/*
createMessage returns Promise<ChatMessage>; hook uses mutateAsync; tests updated to await persisted results and assert mutation payloads.
Trace ID mapping and message decoration
src/Designer/frontend/app-development/features/aiAssistant/hooks/useAltinityWorkflow/useAltinityWorkflow.ts, src/Designer/frontend/app-development/features/aiAssistant/utils/messageUtils.ts
Workflow records traceIdsByMessageId on awaited persisted assistant messages, memoises decorated messages via decorateMessagesWithTraceIds, and exposes messages enriched with traceId.
Component hierarchy feedback wiring
src/Designer/frontend/app-development/features/aiAssistant/AiAssistant.tsx, src/Designer/frontend/libs/studio-assistant/src/{Assistant,CompleteInterface,ChatColumn,Messages}/*
AiAssistant initialises useChatFeedbackMutation and passes sendChatFeedback through Assistant → CompleteInterface → ChatColumn → Messages → MessageFeedback.
API mutations and hooks for feedback
src/Designer/frontend/packages/shared/src/api/{mutations.ts,paths.js}, src/Designer/frontend/packages/shared/src/hooks/mutations/useChatFeedbackMutation.ts, src/Designer/frontend/packages/shared/src/mocks/queriesMock.ts
Adds chatFeedbackPath, sendChatFeedback(org, app, traceId, payload), ChatFeedbackPayload, useChatFeedbackMutation(org, app) hook, and test mocks.
AiAssistant top-level wiring, mocks and localization
src/Designer/frontend/app-development/features/aiAssistant/AiAssistant.tsx, src/Designer/frontend/libs/studio-assistant/src/{index.ts,mocks/mockTexts.ts}, src/Designer/frontend/language/src/nb.json, src/Designer/frontend/AGENTS.md
Adds feedback strings to texts, updates mock texts and exports, adds Bokmål translations, and documents error-handling note.
Tests and helpers
src/Designer/frontend/.../tests/*
Updates unit and hook tests to handle persisted message ids and messages exposure; adds tests for decorateMessagesWithTraceIds, Messages feedback rendering, and hook mutation behaviour.

Sequence Diagram

sequenceDiagram
  participant UserClient
  participant Frontend (AiAssistant)
  participant StudioAssistant Components
  participant Designer API (PUT /api/feedback/{traceId})
  participant Langfuse
  UserClient->>Frontend (AiAssistant): click thumbs-up/down + optional comment (traceId)
  Frontend (AiAssistant)->>StudioAssistant Components: onMessageFeedback({traceId, payload})
  StudioAssistant Components->>Designer API (PUT /api/feedback/{traceId}): send feedback with X-Developer header
  Designer API (PUT /api/feedback/{traceId})->>Langfuse: score_validation(name="user_feedback", passed, trace_id, comment, score_id)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Suggested reviewers

  • mirkoSekulic
  • mlqn

"🐰 I hopped along the code today,
Thumbs up or down, a small display.
TraceId stitched through thread and view,
Scores recorded, tests pass too—hooray! 🥕"

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: thumbs up/down on ai assistant messages' clearly and concisely describes the main feature being added. It is specific, relates directly to the primary change, and effectively communicates the core functionality to a developer scanning the history.
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.
Description check ✅ Passed The pull request description adequately covers the core requirements including a clear description of changes, the flow of the feature, and verification checklist completion.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-ai-chat-feedback-buttons

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: 4

🧹 Nitpick comments (7)
src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/Messages.module.css (1)

235-367: 💤 Low value

Consider updating remaining content selectors for consistency.

The heading selectors (h1, h2, h3) were correctly moved to .assistantContent since that's where the HTML content is injected. For consistency, consider updating the other content-related selectors (strong, em, code, pre, ul, li, p, ol, hr) to also use .assistantContent instead of .assistantMessage. This would make the styling more explicit and maintainable, though the current selectors work correctly as descendant selectors.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/Messages.module.css`
around lines 235 - 367, The CSS currently targets content elements using the
.assistantMessage descendant selectors (e.g., .assistantMessage strong, em,
code, pre, pre[data-language]::before, ul, li, li::marker, p, ol, hr,
.assistantMessage *) but the actual injected HTML lives under .assistantContent;
update all those selectors to use .assistantContent instead of .assistantMessage
so styles apply explicitly to the rendered message content (keep the selector
structure and specific rules intact, only replace the namespace marker
.assistantMessage → .assistantContent for the listed rules).
src/AI/agents/api/routes/feedback.py (1)

58-64: 💤 Low value

score_validation failure is invisible to the caller.

score_validation catches all internal exceptions and only logs at debug level, so the endpoint will return 204 even when the Langfuse write actually failed. This is probably the intent ("best-effort feedback"), but it does mean retries, monitoring, and the frontend's success UI will all report success on a silent failure. Consider either:

  • Logging at warning/info from this endpoint when score_validation did not record a score (would require a return value from score_validation), or
  • Emitting a structured log line here on entry/exit (trace_id, thumbs_up, caller) so feedback submissions are auditable even when Langfuse is degraded.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/AI/agents/api/routes/feedback.py` around lines 58 - 64, The endpoint
currently calls score_validation(FEEDBACK_SCORE_NAME, passed=req.thumbs_up,
trace_id=req.trace_id, comment=req.comment) and always returns
Response(status_code=204) even if score_validation swallowed errors; change this
so failures are visible: either make score_validation return a boolean/enum
indicating success/failure and check its return here to log a warning (including
trace_id, req.thumbs_up, and caller context) before returning 204, or wrap the
call in a try/except that logs a structured warning containing trace_id,
thumbs_up, FEEDBACK_SCORE_NAME and the caught exception when the write fails;
ensure the log level is warning/info rather than debug so failures are
auditable.
src/AI/agents/shared/utils/langfuse_utils.py (1)

266-278: 💤 Low value

Add a short docstring to get_current_trace_id.

The surrounding helpers (get_trace_developer, _has_active_trace, flush_langfuse, etc.) all carry docstrings. A one-liner on get_current_trace_id keeps the module style consistent and clarifies the "returns None when Langfuse is disabled or any error occurs" contract that _has_active_trace now depends on.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/AI/agents/shared/utils/langfuse_utils.py` around lines 266 - 278, Add a
one-line docstring to get_current_trace_id explaining that it returns the
current Langfuse trace ID or None when Langfuse is disabled or an error occurs;
reference the function name get_current_trace_id and note its interaction with
is_langfuse_enabled, get_client().get_current_trace_id(), and the dependent
helper _has_active_trace so the contract is explicit and consistent with
surrounding helpers.
src/Designer/backend/src/Designer/Models/Dto/ChatFeedbackRequest.cs (1)

5-9: 💤 Low value

Consider adding explicit JsonPropertyName attributes.

Whilst ASP.NET Core's default deserialisation handles casing, DTOs in this project typically use explicit [JsonPropertyName] attributes to document the JSON contract clearly. As per coding guidelines, this improves maintainability and avoids ambiguity when the frontend evolves.

📝 Proposed improvement
+using System.Text.Json.Serialization;
+
 namespace Altinn.Studio.Designer.Models.Dto;
 
 public record ChatFeedbackRequest(
-    [MinLength(1), MaxLength(64)] string TraceId,
+    [JsonPropertyName("traceId"), MinLength(1), MaxLength(64)] string TraceId,
+    [JsonPropertyName("thumbsUp")]
     bool ThumbsUp,
-    [MaxLength(10000)] string? Comment
+    [JsonPropertyName("comment"), MaxLength(10000)] string? Comment
 );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Designer/backend/src/Designer/Models/Dto/ChatFeedbackRequest.cs` around
lines 5 - 9, Update the ChatFeedbackRequest record to explicitly annotate each
positional property with JsonPropertyName attributes to document the JSON
contract: add [JsonPropertyName("traceId")] for TraceId,
[JsonPropertyName("thumbsUp")] for ThumbsUp and [JsonPropertyName("comment")]
for Comment on the ChatFeedbackRequest record declaration so the DTO matches the
project's explicit JSON naming convention and avoids casing ambiguity.
src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs (2)

27-27: 💤 Low value

Use UriBuilder for more robust URI construction.

String concatenation of URLs can produce malformed URIs if AgentUrl has a trailing slash. Using UriBuilder or ensuring consistent slash handling prevents potential issues.

🔧 Proposed improvement
-        var requestUri = new Uri($"{_altinitySettings.AgentUrl}{FeedbackPath}");
+        var baseUri = new Uri(_altinitySettings.AgentUrl.TrimEnd('/'));
+        var requestUri = new Uri(baseUri, FeedbackPath.TrimStart('/'));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs`
at line 27, The code builds requestUri via string concatenation which can
produce malformed URIs when _altinitySettings.AgentUrl has or lacks a trailing
slash; update the AltinityAgentClient method that creates requestUri to use
UriBuilder (or normalize/truncate trailing slash on _altinitySettings.AgentUrl)
and append FeedbackPath safely so the resulting Uri is well-formed—replace the
line constructing requestUri with logic that combines _altinitySettings.AgentUrl
and FeedbackPath using UriBuilder (or explicit slash handling) to ensure correct
Uri creation.

25-27: ⚡ Quick win

Add CancellationToken parameter for proper async cancellation.

The SendFeedbackAsync method does not accept a CancellationToken, which prevents callers from cancelling long-running HTTP requests. This is particularly important for HTTP operations that may time out or when the user navigates away.

♻️ Proposed improvement
-    public async Task SendFeedbackAsync(string developer, string traceId, bool thumbsUp, string? comment)
+    public async Task SendFeedbackAsync(string developer, string traceId, bool thumbsUp, string? comment, CancellationToken cancellationToken = default)
     {
         var requestUri = new Uri($"{_altinitySettings.AgentUrl}{FeedbackPath}");
         using var httpRequest = new HttpRequestMessage(HttpMethod.Post, requestUri)
         {
             Content = JsonContent.Create(
                 new
                 {
                     trace_id = traceId,
                     thumbs_up = thumbsUp,
                     comment,
                 }
             ),
         };
         httpRequest.Headers.Add(DeveloperHeader, developer);
 
-        using var response = await _httpClient.SendAsync(httpRequest);
+        using var response = await _httpClient.SendAsync(httpRequest, cancellationToken);
         if (!response.IsSuccessStatusCode)
         {
             string responseContent = await response.Content.ReadAsStringAsync();
             throw new HttpRequestException($"Altinity feedback returned {response.StatusCode}: {responseContent}");
         }
     }

Update the interface signature accordingly:

-    Task SendFeedbackAsync(string developer, string traceId, bool thumbsUp, string? comment);
+    Task SendFeedbackAsync(string developer, string traceId, bool thumbsUp, string? comment, CancellationToken cancellationToken = default);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs`
around lines 25 - 27, The SendFeedbackAsync method lacks a CancellationToken
parameter; update the method signature for SendFeedbackAsync(string developer,
string traceId, bool thumbsUp, string? comment, CancellationToken
cancellationToken) and make the corresponding change in its interface, then pass
that token into any HTTP calls inside (e.g., HttpClient.PostAsync/SendAsync) and
to any internal async operations so the HTTP request to
_altinitySettings.AgentUrl + FeedbackPath can be cancelled; also update all
callers to accept/forward a CancellationToken.
src/Designer/backend/src/Designer/Controllers/ChatController.cs (1)

138-145: 💤 Low value

Clarify the purpose of unused org and app route parameters.

The org and app route parameters are not used in the method body, unlike other endpoints in this controller which construct an AltinnRepoEditingContext. Whilst this may be intentional for route consistency, consider either:

  1. Documenting why they're not needed (e.g., validation happens downstream in the Python service)
  2. Using them to add an authorization check
  3. Simplifying the route if they're truly unnecessary
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Designer/backend/src/Designer/Controllers/ChatController.cs` around lines
138 - 145, The route parameters org and app are unused in SubmitFeedback (unlike
other endpoints that build an AltinnRepoEditingContext) — either remove them
from the route signature or actually use them to authorise/validate the request
before forwarding to altinityAgentClient.SendFeedbackAsync; specifically, update
SubmitFeedback to build an AltinnRepoEditingContext (or call your existing
authorization helper) from org and app and enforce/validate authorization or
repository context, then call altinityAgentClient.SendFeedbackAsync(developer,
request.TraceId, request.ThumbsUp, request.Comment); if the omission is
intentional, add a brief comment above SubmitFeedback explaining why org/app are
not needed (e.g., downstream validation in Python) to make intent explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/AI/agents/api/routes/feedback.py`:
- Around line 19-42: The trace_id validator in FeedbackReq (_validate_trace_id)
rejects whitespace-only strings but returns the original value, so update
_validate_trace_id to strip surrounding whitespace (use v = v.strip()), validate
non-emptiness on the stripped value, and return the trimmed trace_id so
downstream calls like get_trace_developer and score_validation receive a
normalized, whitespace-trimmed identifier.

In `@src/AI/agents/shared/utils/langfuse_utils.py`:
- Around line 240-263: Add a brief docstring to the get_current_trace_id
function describing what it returns and its behavior (e.g., "Return the current
Langfuse trace id from the client if available, otherwise None"), matching the
style used in neighboring functions like get_trace_developer; locate the
get_current_trace_id function and insert a one-line docstring immediately below
its def line that explains the return value and when it may be None.

In
`@src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/MessageFeedback.tsx`:
- Around line 18-19: The submit handler currently calls onSubmit and immediately
clears the dialog state, which can drop user feedback on failure; change the
handler in MessageFeedback to treat onSubmit as async (await its Promise), add
an isSubmitting flag to guard against duplicate submissions, set
isSubmitting=true before calling await onSubmit(feedback), and only close/reset
the dialog state (clear feedback text and close dialog) after onSubmit resolves
successfully; in catch/finally re-enable isSubmitting and keep the dialog open
so the user can retry (optionally surface an error message).

In
`@src/Designer/frontend/packages/shared/src/hooks/mutations/useChatFeedbackMutation.test.ts`:
- Around line 17-18: The test is calling renderHookWithProviders incorrectly by
invoking it twice; update the call site to pass the hook directly: replace the
nested call pattern using renderHookWithProviders()(() =>
useChatFeedbackMutation()).renderHookResult.result with a single call
renderHookWithProviders(() => useChatFeedbackMutation()).result so the hook
function is the first argument and you consume .result directly from the
returned RenderHookResult (referencing renderHookWithProviders and
useChatFeedbackMutation to locate the change).

---

Nitpick comments:
In `@src/AI/agents/api/routes/feedback.py`:
- Around line 58-64: The endpoint currently calls
score_validation(FEEDBACK_SCORE_NAME, passed=req.thumbs_up,
trace_id=req.trace_id, comment=req.comment) and always returns
Response(status_code=204) even if score_validation swallowed errors; change this
so failures are visible: either make score_validation return a boolean/enum
indicating success/failure and check its return here to log a warning (including
trace_id, req.thumbs_up, and caller context) before returning 204, or wrap the
call in a try/except that logs a structured warning containing trace_id,
thumbs_up, FEEDBACK_SCORE_NAME and the caught exception when the write fails;
ensure the log level is warning/info rather than debug so failures are
auditable.

In `@src/AI/agents/shared/utils/langfuse_utils.py`:
- Around line 266-278: Add a one-line docstring to get_current_trace_id
explaining that it returns the current Langfuse trace ID or None when Langfuse
is disabled or an error occurs; reference the function name get_current_trace_id
and note its interaction with is_langfuse_enabled,
get_client().get_current_trace_id(), and the dependent helper _has_active_trace
so the contract is explicit and consistent with surrounding helpers.

In `@src/Designer/backend/src/Designer/Controllers/ChatController.cs`:
- Around line 138-145: The route parameters org and app are unused in
SubmitFeedback (unlike other endpoints that build an AltinnRepoEditingContext) —
either remove them from the route signature or actually use them to
authorise/validate the request before forwarding to
altinityAgentClient.SendFeedbackAsync; specifically, update SubmitFeedback to
build an AltinnRepoEditingContext (or call your existing authorization helper)
from org and app and enforce/validate authorization or repository context, then
call altinityAgentClient.SendFeedbackAsync(developer, request.TraceId,
request.ThumbsUp, request.Comment); if the omission is intentional, add a brief
comment above SubmitFeedback explaining why org/app are not needed (e.g.,
downstream validation in Python) to make intent explicit.

In `@src/Designer/backend/src/Designer/Models/Dto/ChatFeedbackRequest.cs`:
- Around line 5-9: Update the ChatFeedbackRequest record to explicitly annotate
each positional property with JsonPropertyName attributes to document the JSON
contract: add [JsonPropertyName("traceId")] for TraceId,
[JsonPropertyName("thumbsUp")] for ThumbsUp and [JsonPropertyName("comment")]
for Comment on the ChatFeedbackRequest record declaration so the DTO matches the
project's explicit JSON naming convention and avoids casing ambiguity.

In
`@src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs`:
- Line 27: The code builds requestUri via string concatenation which can produce
malformed URIs when _altinitySettings.AgentUrl has or lacks a trailing slash;
update the AltinityAgentClient method that creates requestUri to use UriBuilder
(or normalize/truncate trailing slash on _altinitySettings.AgentUrl) and append
FeedbackPath safely so the resulting Uri is well-formed—replace the line
constructing requestUri with logic that combines _altinitySettings.AgentUrl and
FeedbackPath using UriBuilder (or explicit slash handling) to ensure correct Uri
creation.
- Around line 25-27: The SendFeedbackAsync method lacks a CancellationToken
parameter; update the method signature for SendFeedbackAsync(string developer,
string traceId, bool thumbsUp, string? comment, CancellationToken
cancellationToken) and make the corresponding change in its interface, then pass
that token into any HTTP calls inside (e.g., HttpClient.PostAsync/SendAsync) and
to any internal async operations so the HTTP request to
_altinitySettings.AgentUrl + FeedbackPath can be cancelled; also update all
callers to accept/forward a CancellationToken.

In
`@src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/Messages.module.css`:
- Around line 235-367: The CSS currently targets content elements using the
.assistantMessage descendant selectors (e.g., .assistantMessage strong, em,
code, pre, pre[data-language]::before, ul, li, li::marker, p, ol, hr,
.assistantMessage *) but the actual injected HTML lives under .assistantContent;
update all those selectors to use .assistantContent instead of .assistantMessage
so styles apply explicitly to the rendered message content (keep the selector
structure and specific rules intact, only replace the namespace marker
.assistantMessage → .assistantContent for the listed rules).
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 46b8bf43-846d-4522-aeb4-e05c759f7158

📥 Commits

Reviewing files that changed from the base of the PR and between d5d32d4 and fbe5e42.

📒 Files selected for processing (45)
  • src/AI/agents/agents/graph/nodes/assistant_node.py
  • src/AI/agents/agents/graph/nodes/reviewer_node.py
  • src/AI/agents/api/main.py
  • src/AI/agents/api/routes/__init__.py
  • src/AI/agents/api/routes/feedback.py
  • src/AI/agents/shared/utils/langfuse_utils.py
  • src/AI/agents/tests/api/test_feedback.py
  • src/Designer/backend/src/Designer/Controllers/ChatController.cs
  • src/Designer/backend/src/Designer/Models/Dto/ChatFeedbackRequest.cs
  • src/Designer/backend/src/Designer/Program.cs
  • src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs
  • src/Designer/backend/src/Designer/Services/Interfaces/Altinity/IAltinityAgentClient.cs
  • src/Designer/backend/tests/Designer.Tests/Controllers/ChatController/SubmitFeedbackTests.cs
  • src/Designer/frontend/AGENTS.md
  • src/Designer/frontend/app-development/features/aiAssistant/AiAssistant.tsx
  • src/Designer/frontend/app-development/features/aiAssistant/hooks/useAltinityAssistant/useAltinityAssistant.test.ts
  • src/Designer/frontend/app-development/features/aiAssistant/hooks/useAltinityAssistant/useAltinityAssistant.ts
  • src/Designer/frontend/app-development/features/aiAssistant/hooks/useAltinityThreads/useAltinityThreads.test.ts
  • src/Designer/frontend/app-development/features/aiAssistant/hooks/useAltinityThreads/useAltinityThreads.ts
  • src/Designer/frontend/app-development/features/aiAssistant/hooks/useAltinityWorkflow/useAltinityWorkflow.ts
  • src/Designer/frontend/app-development/features/aiAssistant/utils/messageUtils.test.ts
  • src/Designer/frontend/app-development/features/aiAssistant/utils/messageUtils.ts
  • src/Designer/frontend/language/src/nb.json
  • src/Designer/frontend/libs/studio-assistant/src/Assistant/Assistant.tsx
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/ChatColumn.tsx
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/MessageFeedback.module.css
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/MessageFeedback.test.tsx
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/MessageFeedback.tsx
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/index.ts
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/Messages.module.css
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/Messages.tsx
  • src/Designer/frontend/libs/studio-assistant/src/components/CompleteInterface/CompleteInterface.tsx
  • src/Designer/frontend/libs/studio-assistant/src/index.ts
  • src/Designer/frontend/libs/studio-assistant/src/mocks/mockTexts.ts
  • src/Designer/frontend/libs/studio-assistant/src/types/AssistantConfig.ts
  • src/Designer/frontend/libs/studio-assistant/src/types/AssistantTexts.ts
  • src/Designer/frontend/libs/studio-assistant/src/types/ChatThread.ts
  • src/Designer/frontend/libs/studio-assistant/src/types/UserFeedback.ts
  • src/Designer/frontend/packages/shared/src/api/mutations.ts
  • src/Designer/frontend/packages/shared/src/api/paths.js
  • src/Designer/frontend/packages/shared/src/hooks/mutations/useChatFeedbackMutation.test.ts
  • src/Designer/frontend/packages/shared/src/hooks/mutations/useChatFeedbackMutation.ts
  • src/Designer/frontend/packages/shared/src/mocks/queriesMock.ts
  • src/Designer/frontend/packages/shared/src/types/api/ChatFeedbackPayload.ts
  • src/Designer/frontend/packages/shared/src/types/api/index.ts

Comment thread src/AI/agents/api/routes/feedback.py
Comment thread src/AI/agents/shared/utils/langfuse_utils.py
@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

❌ Patch coverage is 90.90909% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.83%. Comparing base (97894a6) to head (dece4a1).
⚠️ Report is 72 commits behind head on main.

Files with missing lines Patch % Lines
...t/hooks/useAltinityWorkflow/useAltinityWorkflow.ts 71.42% 1 Missing and 1 partial ⚠️
...nt/src/components/ChatColumn/Messages/Messages.tsx 60.00% 1 Missing and 1 partial ⚠️
...olumn/Messages/MessageFeedback/MessageFeedback.tsx 96.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #18803      +/-   ##
==========================================
+ Coverage   95.71%   95.83%   +0.12%     
==========================================
  Files        2587     3021     +434     
  Lines       33007    39625    +6618     
  Branches     4080     4858     +778     
==========================================
+ Hits        31593    37976    +6383     
- Misses       1069     1233     +164     
- Partials      345      416      +71     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@Ildest Ildest left a comment

Choose a reason for hiding this comment

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

Hei @ErlingHauan :-). Har lagt inn noen forslag, du kan se om du liker dem.

Comment thread src/Designer/frontend/language/src/nb.json Outdated
Comment thread src/Designer/frontend/language/src/nb.json Outdated
Comment thread src/Designer/frontend/language/src/nb.json Outdated
Comment thread src/Designer/frontend/language/src/nb.json Outdated
Comment thread src/Designer/frontend/language/src/nb.json Outdated
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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Designer/backend/src/Designer/Controllers/ChatController.cs`:
- Around line 138-145: SubmitFeedback action is missing a CancellationToken
parameter; update the method signature of SubmitFeedback to accept a
CancellationToken (e.g., CancellationToken cancellationToken) and pass that
token into altinityAgentClient.SendFeedbackAsync so the request can be
cancelled; also update IAltinityAgentClient.SendFeedbackAsync signature and all
concrete implementations to accept the CancellationToken and forward it through
any downstream async calls (use HttpContext.RequestAborted when wiring callers
if needed), and ensure the AuthenticationHelper.GetDeveloperUserName usage stays
the same.

In `@src/Designer/backend/src/Designer/Models/Dto/ChatFeedbackRequest.cs`:
- Line 5: Extract the hard-coded 10000 into a named constant and use that
constant in the MaxLength attribute; for example add a public const int
MaxCommentLength = 10000 (either as a member of the ChatFeedbackRequest record
or in a shared ValidationConstants/ChatConstants class) and replace
[MaxLength(10000)] with [MaxLength(MaxCommentLength)] referencing that constant
so the MaxLength attribute uses the named symbol.
- Line 5: The ChatFeedbackRequest DTO currently serializes the ThumbsUp property
with default casing; update the ChatFeedbackRequest record to add a
JsonPropertyName attribute on the ThumbsUp property to serialize as "thumbs_up"
(use a string literal per guidelines) and likewise ensure any other properties
that must match the Python API (e.g., Comment if needed) have JsonPropertyName
attributes; reference the ChatFeedbackRequest type and the ThumbsUp property
when making this change so the JSON contract matches feedback.py.

In
`@src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs`:
- Around line 25-40: Add a CancellationToken parameter to SendFeedbackAsync and
thread it through to the HTTP call: update the method signature of
SendFeedbackAsync(string developer, string traceId, bool thumbsUp, string?
comment, CancellationToken cancellationToken = default), pass cancellationToken
into _httpClient.SendAsync(httpRequest, cancellationToken), and update the
IAltinityAgentClient interface signature and the call site in
ChatController.SubmitFeedback to accept and forward the token (or supply
CancellationToken.None where appropriate).
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a2856a5b-fe75-46e6-ac78-387cc2fab615

📥 Commits

Reviewing files that changed from the base of the PR and between a9d6817 and cdc4560.

📒 Files selected for processing (16)
  • src/AI/agents/api/routes/feedback.py
  • src/AI/agents/shared/utils/langfuse_utils.py
  • src/AI/agents/tests/api/test_feedback.py
  • src/Designer/backend/src/Designer/Controllers/ChatController.cs
  • src/Designer/backend/src/Designer/Models/Dto/ChatFeedbackRequest.cs
  • src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs
  • src/Designer/backend/tests/Designer.Tests/Controllers/ChatController/SubmitFeedbackTests.cs
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/MessageFeedback.test.tsx
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/MessageFeedback.tsx
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/Messages.tsx
  • src/Designer/frontend/libs/studio-assistant/src/types/UserFeedback.ts
  • src/Designer/frontend/packages/shared/src/api/mutations.ts
  • src/Designer/frontend/packages/shared/src/api/paths.js
  • src/Designer/frontend/packages/shared/src/hooks/mutations/useChatFeedbackMutation.test.ts
  • src/Designer/frontend/packages/shared/src/hooks/mutations/useChatFeedbackMutation.ts
  • src/Designer/frontend/packages/shared/src/types/api/ChatFeedbackPayload.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/Designer/backend/tests/Designer.Tests/Controllers/ChatController/SubmitFeedbackTests.cs
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/MessageFeedback.test.tsx
  • src/Designer/frontend/packages/shared/src/hooks/mutations/useChatFeedbackMutation.ts
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/Messages.tsx

Comment thread src/Designer/backend/src/Designer/Controllers/ChatController.cs
Comment thread src/Designer/backend/src/Designer/Models/Dto/ChatFeedbackRequest.cs
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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs`:
- Line 34: Summary: The code builds requestUri by concatenating traceId directly
into the path, which can break URIs when traceId contains reserved characters.
Fix: URL-encode the traceId path segment before appending to the base AgentUrl
(use Uri.EscapeDataString(traceId) or equivalent) and construct the final Uri
using UriBuilder or new Uri(baseUri, relativePath) to avoid double slashes;
update the code that sets requestUri in AltinityAgentClient (referencing
_altinitySettings.AgentUrl, FeedbackPathPrefix, and traceId) so the path segment
is encoded and the Uri is constructed safely.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 30e641f3-25ea-47d3-ac4e-d10251a1c00b

📥 Commits

Reviewing files that changed from the base of the PR and between cdc4560 and 91c6202.

📒 Files selected for processing (9)
  • src/Designer/backend/src/Designer/Controllers/ChatController.cs
  • src/Designer/backend/src/Designer/Services/Implementation/Altinity/AltinityAgentClient.cs
  • src/Designer/backend/src/Designer/Services/Interfaces/Altinity/IAltinityAgentClient.cs
  • src/Designer/backend/tests/Designer.Tests/Controllers/ChatController/SubmitFeedbackTests.cs
  • src/Designer/frontend/app-development/features/aiAssistant/AiAssistant.tsx
  • src/Designer/frontend/language/src/nb.json
  • src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/Messages/MessageFeedback/MessageFeedback.tsx
  • src/Designer/frontend/libs/studio-assistant/src/mocks/mockTexts.ts
  • src/Designer/frontend/libs/studio-assistant/src/types/AssistantTexts.ts
✅ Files skipped from review due to trivial changes (1)
  • src/Designer/frontend/language/src/nb.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/Designer/backend/src/Designer/Services/Interfaces/Altinity/IAltinityAgentClient.cs
  • src/Designer/backend/src/Designer/Controllers/ChatController.cs
  • src/Designer/frontend/libs/studio-assistant/src/mocks/mockTexts.ts
  • src/Designer/frontend/app-development/features/aiAssistant/AiAssistant.tsx
  • src/Designer/backend/tests/Designer.Tests/Controllers/ChatController/SubmitFeedbackTests.cs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend frontend quality/testing Tests that are missing, needs to be created or could be improved. skip-releasenotes Issues that do not make sense to list in our release notes solution/studio/designer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants