Skip to content

Commit b14f68d

Browse files
alonelishclaude
andauthored
ROB-3618: Add chat-analytics fields to HolmesChat schemas (#2058)
* Add chat-analytics fields to HolmesChat schemas 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> * Add holmes_feedback action handler 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> * Register holmes_feedback in the manual-action allowlist 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> * Add is_internal flag to HolmesChat schemas 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> * Address CodeRabbit review on holmes_feedback schemas - HolmesFeedbackParams.request_id: enforce non-empty via Field(min_length=1) so empty strings are rejected at param construction. - HolmesFeedbackRequest: mirror the params contract — sentiment is now Literal["thumbs_up", "thumbs_down"] and request_id has min_length=1, so the request body class can't be misused outside the action path. - Add a test covering the empty-request_id rejection. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Forward user_id as query param on holmes_feedback Holmes' POST /api/feedback reads user_id from request.query_params, not the JSON body (mirrors /api/chat's resolution path used by the relay). Posting it in the body returns 400 "missing user_id". Pull user_id out of the action params and forward it via the URL query string. - Declare user_id: Optional[str] on HolmesFeedbackParams so it's discoverable; pop it before constructing the request body. - Update tests to assert user_id is on params= and not in the body. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Improve holmes_feedback observability and drop noisy Finding - handle_holmes_error: log the upstream response body on HTTPError so 4xx/5xx diagnostics aren't lost in the generic "Holmes internal configuration error" branch (e.g. {"detail":"missing user_id"} would otherwise be invisible). Benefits all Holmes proxy actions, not just feedback. - holmes_feedback: drop the no-op Finding on success. The FE shows the "Thanks" toast optimistically and never reads the response; emitting a TYPE_NONE finding for every thumb click was UI noise. Replaced with an info log line carrying request_id + sentiment. - Tests updated to assert add_finding is no longer called. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Remove holmes_feedback action — FE now writes via Supabase RPC The feedback flow has moved off the runner: the FE now records thumbs up/down directly via a Supabase RPC, bypassing the relay → runner → Holmes path. Drop the runner-side proxy: - HolmesFeedbackParams and HolmesFeedbackRequest schemas - holmes_feedback action handler - 7 unit tests - helm chart lightActions allowlist entry Kept from earlier PR commits: - Chat-analytics fields on HolmesChat schemas (request_source, conversation_id, source_ref, conversation_source, request_type, is_internal, meta) — still useful for /api/chat - handle_holmes_error response-body logging — benefits all Holmes proxy actions (chat, oauth, conversation, issue_chat) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9a81b6a commit b14f68d

3 files changed

Lines changed: 22 additions & 0 deletions

File tree

src/robusta/core/model/base_params.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,13 @@ class HolmesChatParams(HolmesParams):
207207
enable_tool_approval: bool = Field(default=False)
208208
tool_decisions: Optional[List[ToolApprovalDecision]] = None
209209
additional_system_prompt: Optional[str] = None
210+
request_type: Optional[str] = None
211+
request_source: Optional[str] = None
212+
source_ref: Optional[str] = None
213+
conversation_id: Optional[str] = None
214+
conversation_source: Optional[str] = None
215+
is_internal: Optional[bool] = None
216+
meta: Optional[Dict[str, Any]] = None
210217

211218
class Config:
212219
extra = "allow"

src/robusta/core/playbooks/internal/ai_integration.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ def handle_holmes_error(e: Exception) -> NoReturn:
6262
"Holmes endpoint is currently unreachable.",
6363
)
6464
elif isinstance(e, requests.HTTPError):
65+
# Log the upstream response body so 4xx/5xx diagnostics aren't lost in
66+
# the generic "Holmes internal configuration error" branch below
67+
# (e.g. {"detail":"missing user_id"} would otherwise be invisible).
68+
if e.response is not None:
69+
logging.error(
70+
f"Holmes responded {e.response.status_code} on {e.request.method if e.request else '?'} "
71+
f"{e.request.url if e.request else '?'}: {e.response.text}"
72+
)
6573
if e.response.status_code == 401 and "invalid_api_key" in e.response.text:
6674
raise ActionException(
6775
ErrorCodes.HOLMES_REQUEST_ERROR, "Holmes invalid api key."

src/robusta/core/reporting/holmes.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ class HolmesChatRequest(BaseModel):
5151
enable_tool_approval: bool = Field(default=False)
5252
tool_decisions: Optional[List[ToolApprovalDecision]] = None
5353
additional_system_prompt: Optional[str] = None
54+
request_type: Optional[str] = None
55+
request_source: Optional[str] = None
56+
source_ref: Optional[str] = None
57+
conversation_id: Optional[str] = None
58+
conversation_source: Optional[str] = None
59+
is_internal: Optional[bool] = None
60+
meta: Optional[Dict[str, Any]] = None
5461

5562
class Config:
5663
extra = "allow"

0 commit comments

Comments
 (0)