Skip to content

feat(metrics): add vikingbot feedback observability#2037

Merged
yeshion23333 merged 5 commits into
mainfrom
feat/vikingbot-feedback-observability
May 15, 2026
Merged

feat(metrics): add vikingbot feedback observability#2037
yeshion23333 merged 5 commits into
mainfrom
feat/vikingbot-feedback-observability

Conversation

@myysy
Copy link
Copy Markdown
Collaborator

@myysy myysy commented May 14, 2026

Description

Add VikingBot feedback observability to OpenViking metrics by exporting scrape-time feedback and outcome aggregates from persisted bot sessions. This also documents the new metric families and provides Grafana/Prometheus examples plus validation guides.

Related Issue

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test update

Changes Made

  • Add FeedbackCollector and bot-side feedback aggregation logic to export openviking_feedback_* and openviking_feedback_channel_* gauges from persisted VikingBot session data.
  • Extend bot observability, outcome metadata, console surfaces, and metrics bootstrap/tests to support feedback coverage, thumbs up/down, outcome totals, and per-channel breakdowns.
  • Add metrics documentation, validation guides, and Grafana/Prometheus example configs and dashboard for VikingBot feedback observability.

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this on the following platforms:
    • Linux
    • macOS
    • Windows

Checklist

  • My code follows the project's coding style
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Screenshots (if applicable)

N/A

Additional Notes

  • This PR exports scrape-time snapshot gauges rather than online counters. The collector recomputes aggregates from bot/sessions/*.jsonl on each scrape.
  • valid="1" indicates a fresh successful snapshot, while valid="0" indicates fallback to the last successful snapshot after collector refresh failure.
  • Local untracked environment files were intentionally excluded from the commit: compare_json.py, log, ov_conf/, and scripts/.

@github-actions
Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🏅 Score: 85
🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 No multiple PR themes
⚡ Recommended focus areas for review

Missing License Header

New Python file does not include the required license header. While R6 explicitly mentions openviking/ and openviking_cli/ directories, checking consistency with other project files is recommended.

"""Offline feedback observability aggregation over persisted sessions."""

@github-actions
Copy link
Copy Markdown

PR Code Suggestions ✨

No code suggestions found for the PR.

# Conflicts:
#	bot/vikingbot/agent/memory.py
@MaojiaSheng
Copy link
Copy Markdown
Collaborator

发群里请相关同学review吧

Copy link
Copy Markdown
Collaborator

@yeshion23333 yeshion23333 left a comment

Choose a reason for hiding this comment

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

I found two blocking issues and two follow-up suggestions in the new feedback observability path. The most serious problem is that the default server metrics bootstrap now has a hard import-time dependency on the vikingbot package and its transitive runtime requirements.

from typing import Any, ClassVar

from openviking.metrics.core.base import MetricCollector

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Bug] (blocking) This collector now imports vikingbot.config.loader at module import time, and openviking.metrics.bootstrap imports FeedbackCollector unconditionally. That means enabling the default server metrics path now requires the full vikingbot dependency chain to be importable, even in deployments that only use the server. I was able to reproduce this locally by importing create_default_collector_manager(), which failed in the bot dependency chain with ModuleNotFoundError. Before this PR, the default metrics bootstrap did not depend on bot-only runtime packages. Please decouple the collector from vikingbot.config.loader and inject the bot data path from server-side config (or at least defer the dependency so unsupported environments degrade gracefully instead of failing during import).

return None

feedback_events = metadata.get("feedback_events", [])
response_outcomes = metadata.get("response_outcomes", {})
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Design] (blocking) The denominator for the exported rates is currently len(_collect_response_ids(...)), i.e. every persisted assistant message with a response_id. The numerators, however, only come from the new feedback_events / response_outcomes contract in metadata. In mixed historical data, this will systematically understate coverage and resolution because old responses that were never part of the new observability contract are still counted in responses_total. For example, if an older session has 100 assistant responses but only the newest 10 are tracked in response_outcomes, a dashboard reader will see those rates as if all 100 responses were eligible. Please either change the denominator to tracked responses or export a separate tracked-response total and document the current semantics explicitly.

@@ -80,6 +81,7 @@ def create_default_collector_manager(*, app=None, service=None) -> CollectorMana
manager = CollectorManager()
manager.register(QueueCollector(data_source=QueuePipelineStateDataSource()))
manager.register(TaskTrackerCollector(data_source=TaskStateDataSource()))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] (non-blocking) Registering FeedbackCollector() with no explicit constructor inputs makes the bootstrap path rely on hidden defaults inside the collector. That is what forces the current test to monkeypatch load_config, and it also makes deployment configuration harder to reason about. Consider passing the bot data path (or a dedicated feedback metrics config object) from the bootstrap layer so the dependency stays explicit and testable.

finally:
shutdown_metrics(app=app)

async def test_metrics_endpoint_exports_feedback_metrics(self, monkeypatch, tmp_path):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] (non-blocking) This endpoint test only writes the metadata record and does not include any persisted assistant message rows. That still proves the endpoint can expose feedback metrics, but it does not exercise the real denominator path used by responses_total, feedback_coverage, and the derived rates, because those currently come from scanning assistant messages in the JSONL body. Adding at least one assistant record here would make this test much better at catching regressions in the session-file contract and the rate semantics.

@yeshion23333 yeshion23333 merged commit 9ebfd59 into main May 15, 2026
6 of 7 checks passed
@yeshion23333 yeshion23333 deleted the feat/vikingbot-feedback-observability branch May 15, 2026 09:30
@github-project-automation github-project-automation Bot moved this from Backlog to Done in OpenViking project May 15, 2026
r266-tech added a commit to r266-tech/OpenViking that referenced this pull request May 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants