Skip to content

Conversation

@ericpgreen2
Copy link
Contributor

@ericpgreen2 ericpgreen2 commented Jan 8, 2026

This PR adds thumbs-up/thumbs-down buttons to the AI chat. Users can submit positive or negative feedback. Negative feedback is analyzed by the LLM to attribute the issue to one of:

  • rill: the AI made an error or misunderstood the question
  • project: the project is missing data or has incomplete documentation
  • user: the question was ambiguous or outside the AI's scope

For project and user attributions, users receive a suggested action to help them get better results.

Implements this tech design. Closes APP-555.

Checklist:

  • Covered by tests
  • Ran it and it works as intended
  • Reviewed the diff before requesting a review
  • Checked for unhandled edge cases
  • Linked the issues it closes
  • Checked if the docs need to be updated. If so, create a separate Linear DOCS issue
  • Intend to cherry-pick into the release branch
  • I'm proud of this work!

@ericpgreen2 ericpgreen2 self-assigned this Jan 8, 2026
@ericpgreen2 ericpgreen2 marked this pull request as ready for review January 13, 2026 15:31
Copy link
Collaborator

@AdityaHegde AdityaHegde left a comment

Choose a reason for hiding this comment

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

Leaving comments for initial round of review.

// Log the error but still return a response
s.logger.Warn("failed to analyze feedback", zap.String("session_id", s.id), zap.Error(err))
return &UserFeedbackResult{
Response: "Thanks for your feedback. I apologize that my response didn't meet your expectations. I'll use this to improve.",
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: should we not add the error here?

this.conversationQuery = createQuery(queryOptionsStore, queryClient);

// Hydrate feedback state when conversation data loads
this.conversationQuery.subscribe((query) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: need to handle unsub to avoid leaks

private async startStreaming(request: {
prompt?: string;
context?: RuntimeServiceCompleteBody;
userFeedbackContext?: {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why not use V1UserFeedbackContext?

DeveloperAgentContext developer_agent_context = 12;
// Optional feedback context. If provided, the router_agent calls the user_feedback tool,
// which records feedback and, for negative feedback, attributes the cause.
UserFeedbackContext user_feedback_context = 13;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: missing param in CompleteRequest and its handling in chat.go

return nil, fmt.Errorf("agent %q not found", args.Agent)
}
// User feedback
case args.UserFeedbackArgs != nil:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Whats wrong with using Agent arg instead? If there is a legitimate reason please add a comment somewhere.

...context,
prompt: request.prompt,
// Don't send agent for feedback - let router handle user_feedback directly
agent: request.userFeedbackContext ? undefined : this.agent,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same here, agent is for routing directly. So we could just send ToolName.FeedbackAgent

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