Skip to content

Add chat-analytics fields to HolmesChat schemas#2058

Open
alonelish wants to merge 4 commits intomasterfrom
claude/vibrant-tu-afcdd3
Open

Add chat-analytics fields to HolmesChat schemas#2058
alonelish wants to merge 4 commits intomasterfrom
claude/vibrant-tu-afcdd3

Conversation

@alonelish
Copy link
Copy Markdown
Collaborator

Summary

Declare 6 optional analytics fields on the legacy chat path so they're typed and discoverable end-to-end:

  • request_type
  • request_source
  • source_ref
  • conversation_id
  • conversation_source
  • meta

Added to HolmesChatParams (src/robusta/core/model/base_params.py) and HolmesChatRequest (src/robusta/core/reporting/holmes.py). HolmesIssueChatParams / HolmesIssueChatRequest inherit them automatically.

Why

The Holmes server's /api/chat endpoint is being extended to capture these fields for usage slicing (UI surface, multi-turn grouping, etc.). The FE will start sending them. Both schemas already had extra = "allow" and the runner is on Pydantic v1, so the fields functionally pass through today — this change just makes them first-class so they're typed, IDE-autocompletable, and self-documenting at both runner boundaries.

Notes for reviewers

  • All fields are Optional[...] = None — fully backwards-compatible. Old clients that don't send them keep working; the runner forwards null for missing ones.
  • No action-handler changes needed: holmes_chat already uses params.dict()HolmesChatRequest(**params_dict), so declared fields propagate without extra plumbing.
  • holmes_issue_chat uses an explicit kwarg constructor and does not populate the new fields; they default to None on that path. This is intentional — only the legacy /api/chat path is in scope.
  • extra = "allow" is preserved on both classes as a safety net for future fields.

Test plan

  • Static check: HolmesChatParams.__fields__ and HolmesChatRequest.__fields__ both contain the 6 new field names.
  • Round-trip serialization: construct HolmesChatParams(ask="x", conversation_id="ch-1", request_source="alert_investigation", source_ref="issue-2", meta={"k":"v"}), dump via .dict(exclude={"holmes_url","render_graph_images"}), pass into HolmesChatRequest(**...), and confirm the JSON includes the new fields.
  • Backwards-compat: construct HolmesChatParams(ask="x") only and confirm all 6 fields serialize as null.
  • Existing test suite passes.

🤖 Generated with Claude Code

Declare request_type, request_source, source_ref, conversation_id,
conversation_source, and meta as optional fields on HolmesChatParams
and HolmesChatRequest so they're typed and discoverable end-to-end.
The fields already passed through via extra="allow" + Pydantic v1
dict() semantics; this change makes them first-class. HolmesIssueChat*
inherits the fields automatically.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 29, 2026

Docker image ready for c66806e (built in 1m 30s)

⚠️ Warning: does not support ARM (ARM images are built on release only - not on every PR)

Use this tag to pull the image for testing.

📋 Copy commands

⚠️ Temporary images are deleted after 30 days. Copy to a permanent registry before using them:

gcloud auth configure-docker us-central1-docker.pkg.dev
docker pull us-central1-docker.pkg.dev/robusta-development/temporary-builds/robusta-runner:c66806e
docker tag us-central1-docker.pkg.dev/robusta-development/temporary-builds/robusta-runner:c66806e me-west1-docker.pkg.dev/robusta-development/development/robusta-runner-dev:c66806e
docker push me-west1-docker.pkg.dev/robusta-development/development/robusta-runner-dev:c66806e

Patch Helm values in one line:

helm upgrade --install robusta robusta/robusta \
  --reuse-values \
  --set runner.image=me-west1-docker.pkg.dev/robusta-development/development/robusta-runner-dev:c66806e

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 29, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c9f4cf43-31f2-4e9e-b69b-a73cefc7c915

📥 Commits

Reviewing files that changed from the base of the PR and between ba8f3f9 and 637be7f.

📒 Files selected for processing (2)
  • src/robusta/core/model/base_params.py
  • src/robusta/core/reporting/holmes.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/robusta/core/reporting/holmes.py
  • src/robusta/core/model/base_params.py

Walkthrough

Adds Holmes feedback support and extends Holmes chat params/requests with optional request/conversation metadata, an internal flag, and free-form meta; implements a playbook action that POSTs feedback to Holmes, adds tests, and exposes the action in Helm values.

Changes

Cohort / File(s) Summary
Models
src/robusta/core/model/base_params.py
Extended HolmesChatParams with request_type, request_source, source_ref, conversation_id, conversation_source, is_internal, meta. Added HolmesFeedbackParams (request_id, `sentiment: "thumbs_up"
Reporting / Requests
src/robusta/core/reporting/holmes.py
Extended HolmesChatRequest with the same optional metadata fields; added HolmesFeedbackRequest model for POST /api/feedback (permits extra fields).
Playbooks / Integration
src/robusta/core/playbooks/internal/ai_integration.py
Added holmes_feedback action: validates HolmesFeedbackParams, constructs HolmesFeedbackRequest, POSTs to /api/feedback with timeout, handles non-2xx via existing error path, records a Finding on success.
Tests
tests/test_ai_integration.py
Added tests for holmes_feedback: endpoint used, payload shape (excludes runner-only fields), null serialization for omitted optionals, validation errors for missing/invalid fields, and HTTP success/error behaviors.
Helm
helm/robusta/values.yaml
Added holmes_feedback to holmes.lightActions list to expose the action via Helm values.

Sequence Diagram(s)

sequenceDiagram
    participant Playbook as Playbook Action
    participant Event as ExecutionEvent
    participant Client as Holmes HTTP Client
    participant Holmes as Holmes Server
    participant Store as Findings Store

    Playbook->>Event: receive HolmesFeedbackParams
    Playbook->>Client: build HolmesFeedbackRequest (validate, strip runner-only fields)
    Client->>Holmes: POST /api/feedback (timeout)
    Holmes-->>Client: 200 / 4xx / 5xx
    alt 200 or non-fatal 4xx
        Client-->>Playbook: response
        Playbook->>Store: add_finding(HolmesFeedbackResult)
    else 5xx or exception
        Client-->>Playbook: error
        Playbook->>Playbook: handle_holmes_error (log request_id, raise ActionException)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • arikalon1
  • moshemorad
  • Avi-Robusta
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding chat-analytics fields to HolmesChat schemas, which aligns with the primary objective of declaring six optional analytics fields (request_type, request_source, source_ref, conversation_id, conversation_source, meta) across the HolmesChat-related classes.
Description check ✅ Passed The description is well-related to the changeset, providing clear context on why the fields are being added, what classes they affect, backward-compatibility considerations, and a detailed test plan that aligns with the actual code changes across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/vibrant-tu-afcdd3

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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Proxies user feedback (thumbs up/down) on a Holmes answer from the FE
to the Holmes server's POST /api/feedback, which UPDATEs the
HolmesUsageEvents row keyed by request_id.

Mirrors the holmes_oauth pattern (small synchronous POST with
raise_for_status pass-through), with pydantic-level validation of
request_id presence and sentiment via Literal["thumbs_up", "thumbs_down"]
so bad payloads fail at param construction.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@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

🧹 Nitpick comments (1)
src/robusta/core/reporting/holmes.py (1)

70-80: Align feedback sentiment type with the params contract.

HolmesFeedbackRequest.sentiment is currently unconstrained str; mirroring the Literal contract avoids accidental invalid payloads if this model is used outside the current action path.

💡 Proposed refactor
-from typing import Any, Dict, List, Optional, Union
+from typing import Any, Dict, List, Literal, Optional, Union
@@
-    sentiment: str
+    sentiment: Literal["thumbs_up", "thumbs_down"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/robusta/core/reporting/holmes.py` around lines 70 - 80,
HolmesFeedbackRequest currently types sentiment as plain str; change it to a
constrained Literal to match the params contract (e.g.,
Literal['positive','negative','neutral'] or the exact allowed tokens used
elsewhere) and import typing.Literal; update the model declaration (class
HolmesFeedbackRequest) to use that Literal type for sentiment and adjust any
callers/validators to conform to the narrowed set so invalid payloads are caught
at model validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/robusta/core/model/base_params.py`:
- Around line 251-252: The request_id field currently typed as plain str accepts
empty strings; update the model that declares request_id and sentiment to
validate non-empty ids by either changing request_id's type to
pydantic.constr(min_length=1) or by using Field(..., min_length=1) on
request_id, and add/import the needed pydantic symbol; alternatively add a
`@validator` for "request_id" that raises a ValueError on empty/whitespace-only
strings so malformed feedback is rejected at validation time.

---

Nitpick comments:
In `@src/robusta/core/reporting/holmes.py`:
- Around line 70-80: HolmesFeedbackRequest currently types sentiment as plain
str; change it to a constrained Literal to match the params contract (e.g.,
Literal['positive','negative','neutral'] or the exact allowed tokens used
elsewhere) and import typing.Literal; update the model declaration (class
HolmesFeedbackRequest) to use that Literal type for sentiment and adjust any
callers/validators to conform to the narrowed set so invalid payloads are caught
at model validation.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3228b0cc-f9b3-4d64-82e2-144c6b2fba0a

📥 Commits

Reviewing files that changed from the base of the PR and between 87d95ca and 253f5cd.

📒 Files selected for processing (4)
  • src/robusta/core/model/base_params.py
  • src/robusta/core/playbooks/internal/ai_integration.py
  • src/robusta/core/reporting/holmes.py
  • tests/test_ai_integration.py

Comment on lines +251 to +252
request_id: str
sentiment: Literal["thumbs_up", "thumbs_down"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Enforce non-empty request_id at validation time.

request_id: str still accepts empty strings, so malformed feedback can pass model validation and be forwarded.

💡 Proposed fix
-    request_id: str
+    request_id: str = Field(..., min_length=1)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
request_id: str
sentiment: Literal["thumbs_up", "thumbs_down"]
request_id: str = Field(..., min_length=1)
sentiment: Literal["thumbs_up", "thumbs_down"]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/robusta/core/model/base_params.py` around lines 251 - 252, The request_id
field currently typed as plain str accepts empty strings; update the model that
declares request_id and sentiment to validate non-empty ids by either changing
request_id's type to pydantic.constr(min_length=1) or by using Field(...,
min_length=1) on request_id, and add/import the needed pydantic symbol;
alternatively add a `@validator` for "request_id" that raises a ValueError on
empty/whitespace-only strings so malformed feedback is rejected at validation
time.

alonelish and others added 2 commits April 30, 2026 06:10
The Helm chart's allowlist gates which action names the relay can
forward to the runner. Without this entry the relay rejects
holmes_feedback before it reaches the action handler.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Optional boolean alongside the other chat-analytics fields (request_source,
conversation_id, etc.) so the FE can mark internal/test traffic and the
Holmes server can filter it out of usage dashboards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

2 participants