Skip to content

feat(dashboard): show observed model on learning details - #148

Open
wenchanghan wants to merge 11 commits into
ReflexioAI:mainfrom
wenchanghan:codex/dashboard-model-provenance
Open

feat(dashboard): show observed model on learning details#148
wenchanghan wants to merge 11 commits into
ReflexioAI:mainfrom
wenchanghan:codex/dashboard-model-provenance

Conversation

@wenchanghan

@wenchanghan wenchanghan commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

What's broken / annoying

Learning detail pages show origin host, but not which model generated the learning. When generation drifts, that is hard to notice from the UI.

What's changing

Add a Model field to preference and skill detail metadata.

It reads observed provider / model_name from local SQLite lineage_event through a thin local dashboard route (/api/model-provenance), then renders:

  • provider/model when present
  • Not recorded for historical rows without model fields
  • Unavailable when the local DB cannot be read

List views are unchanged. There is no requested-model or live-config comparison.

How the product behaves afterwards

On preference, project-skill, and shared-skill detail pages, the right-hand metadata panel shows the observed generation model next to existing metadata such as origin.

How it was verified

  • Rebased onto current main (d096b3b)
  • npx tsc --noEmit in plugin/dashboard
  • eslint on changed dashboard files
  • pytest tests/test_model_lineage_reader.py (7 behavioral SQLite fixture cases)
  • pytest tests/test_dashboard_managed_reflexio.py
  • next build for the dashboard
  • Live local UI checks against real lineage data on a branch-built dashboard:
    • preference with model → minimax/MiniMax-M3
    • preference without model → Not recorded
    • project skill with model → minimax/MiniMax-M3
    • shared skill without model → Not recorded
    • list views do not show Model

Risks / follow-ups

  • Observed-model reads use node:sqlite at request time. That needs a runtime with sqlite support (Node >=22.18 for DatabaseSync({ readOnly })); older runtimes return Unavailable.
  • Dashboard package engines remain >=20.9.0 so install/build matrices stay compatible.
  • Reflexio PR #357 is ingestion-only; there is still no Reflexio HTTP read API for observed model, so this local SQLite path is intentional.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

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

The dashboard now reads model provenance from Reflexio SQLite lineage data, exposes it through an API and React hook, and displays it on preference and skill detail pages.

Changes

Learning model provenance

Layer / File(s) Summary
SQLite lineage contract and retrieval
plugin/dashboard/lib/model-lineage.ts, plugin/dashboard/types/node-sqlite.d.ts, plugin/dashboard/package.json, tests/test_model_lineage_reader.py
Defines provenance types, reads supported lineage entities from SQLite, handles legacy schemas and unavailable data, updates the Node.js requirement, and adds reader tests.
Provenance API and client loading
plugin/dashboard/app/api/model-provenance/route.ts, plugin/dashboard/lib/model-provenance.ts
Validates API parameters and fetches provenance with timeout, cancellation, no-cache requests, and unavailable fallbacks.
Provenance status rendering
plugin/dashboard/components/common/model-provenance.tsx
Renders loading, unavailable, recorded, and unrecorded model states with provider and model metadata.
Dashboard metadata integration
plugin/dashboard/app/preferences/..., plugin/dashboard/app/skills/...
Adds Model metadata rows to preference, project skill, and shared skill pages. The shared skill metadata value accepts rendered React nodes.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DetailPage
  participant useLearningModelProvenance
  participant model_provenance_GET
  participant getLearningModelProvenance
  participant ReflexioSQLite
  DetailPage->>useLearningModelProvenance: provide entityType and entityId
  useLearningModelProvenance->>model_provenance_GET: fetch provenance query
  model_provenance_GET->>getLearningModelProvenance: request validated lineage
  getLearningModelProvenance->>ReflexioSQLite: read recent lineage events
  ReflexioSQLite-->>getLearningModelProvenance: return lineage rows
  getLearningModelProvenance-->>model_provenance_GET: return provenance
  model_provenance_GET-->>useLearningModelProvenance: return JSON provenance
  useLearningModelProvenance-->>DetailPage: expose provenance state
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
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 Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main dashboard change: displaying observed model provenance on learning detail pages.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@plugin/dashboard/lib/model-lineage.ts`:
- Around line 7-10: Align the dashboard package’s declared Node.js engine
requirement with the node:sqlite DatabaseSync usage in model-lineage, ensuring
the minimum runtime supports the readOnly option; alternatively, replace the
read-only SQLite implementation with an approach compatible with Node >=20.9.0.
- Around line 130-132: Update the provenance route around emptyProvenance and
NextResponse.json({ provenance }) to replace filesystem paths and raw SQLite
diagnostics with fixed public reasons such as “database unavailable” for missing
databases and “provenance query failed” for query or database errors. Keep the
detailed path and SQLite error information only in server-side logging, while
preserving successful provenance responses.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 38efc6af-73a0-44d8-9f70-c16331343de2

📥 Commits

Reviewing files that changed from the base of the PR and between f73a8ef and 8cb8024.

⛔ Files ignored due to path filters (4)
  • docs/pr-assets/model-provenance/pref-match.png is excluded by !**/*.png
  • docs/pr-assets/model-provenance/pref-mismatch.png is excluded by !**/*.png
  • docs/pr-assets/model-provenance/project-skill.png is excluded by !**/*.png
  • docs/pr-assets/model-provenance/shared-skill.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • plugin/dashboard/app/api/learning-model-provenance/route.ts
  • plugin/dashboard/app/preferences/[id]/page.tsx
  • plugin/dashboard/app/skills/project/[id]/page.tsx
  • plugin/dashboard/app/skills/shared/[id]/page.tsx
  • plugin/dashboard/components/common/model-provenance.tsx
  • plugin/dashboard/lib/model-lineage.ts
  • plugin/dashboard/lib/model-provenance.ts
  • plugin/dashboard/types/node-sqlite.d.ts

Comment thread plugin/dashboard/lib/model-lineage.ts Outdated
Comment thread plugin/dashboard/lib/model-lineage.ts Outdated
@wenchanghan

Copy link
Copy Markdown
Contributor Author

Updated UI screenshots (synthetic fixtures only)

Observed-model-only. No requested-model mismatch logic.

Preference with observed model

preference with model

Preference historical lineage (no model fields)

preference historical

Project skill detail

project skill

Shared skill detail

shared skill

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 `@plugin/dashboard/lib/model-lineage.ts`:
- Around line 143-151: Update the emptyProvenance call in the lineage_event
table-missing branch to pass true for the availability flag, so missing lineage
data renders as Unavailable while preserving the existing entity details and
message.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 050d1881-8743-474e-8ed6-9108ee305a6f

📥 Commits

Reviewing files that changed from the base of the PR and between 8cb8024 and a5724c8.

⛔ Files ignored due to path filters (3)
  • docs/pr-assets/model-provenance/pref-historical.png is excluded by !**/*.png
  • docs/pr-assets/model-provenance/pref-with-model.png is excluded by !**/*.png
  • docs/pr-assets/model-provenance/project-skill.png is excluded by !**/*.png
📒 Files selected for processing (3)
  • plugin/dashboard/components/common/model-provenance.tsx
  • plugin/dashboard/lib/model-lineage.ts
  • plugin/dashboard/lib/model-provenance.ts
💤 Files with no reviewable changes (1)
  • plugin/dashboard/lib/model-provenance.ts

Comment thread plugin/dashboard/lib/model-lineage.ts Outdated
@wenchanghan wenchanghan changed the title feat(dashboard): show model provenance on learning details feat(dashboard): show observed model on learning details Jul 28, 2026
Surface provider/model from local lineage_event on preference and skill
detail pages so config mismatches (requested vs observed) are visible
without using the Reflexio HTTP API.
Fixture-only images used for PR visual evidence; no real session data.
Drop requested_model/credential mismatch logic. Detail pages now show
provider/model from lineage when present, and "Not recorded" for
historical rows without those fields.
Align dashboard Node engine with node:sqlite readOnly, sanitize public
error reasons, and treat a missing lineage_event table as unavailable.
Keep only observed provider/model display, simplify the SQLite reader to
a single ranked query, and drop unused lineage metadata plus PR binary
screenshot assets from the branch.
Expose observed model via a thin local /api/model-provenance route that
reads SQLite directly, matching the origin/session local-data pattern,
and lock the contract with dashboard static tests.
Replace design-shape static assertions with SQLite fixture tests for
observed model, historical missing fields, schema without model columns,
missing entity, and missing database.
Remove redundant force-dynamic on the local model-provenance route and
simplify the SQLite reader test helper.
@wenchanghan
wenchanghan force-pushed the codex/dashboard-model-provenance branch from 8ec983f to dd65feb Compare August 5, 2026 08:30
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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)
tests/test_model_lineage_reader.py (1)

190-193: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add coverage for a missing lineage_event table.

A database can exist without this table. Assert that this case returns unavailable: true. This protects the Unavailable UI contract from regression.

Proposed test
+def test_reader_missing_lineage_table_is_unavailable(tmp_path: Path) -> None:
+    db = tmp_path / "reflexio.db"
+    sqlite3.connect(db).close()
+
+    result = _run_reader(db, "profile", "pref-1")
+    assert result["unavailable"] is True
+    assert result["reason"] == "lineage_event table not present"
🤖 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 `@tests/test_model_lineage_reader.py` around lines 190 - 193, Add a test
alongside test_reader_missing_database_is_unavailable that exercises an existing
database without the lineage_event table, invoking _run_reader with the same
representative inputs and asserting result["unavailable"] is True. Also assert
the expected unavailable reason for the missing table, preserving the
Unavailable UI contract.
🤖 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 `@plugin/dashboard/lib/model-provenance.ts`:
- Around line 22-31: Update the useEffect request flow to clear the existing
provenance state immediately when entityType or entityId changes, before
initiating fetch. Preserve the current cancellation and loading behavior,
ensuring stale metadata is not rendered while the new request is pending.

---

Nitpick comments:
In `@tests/test_model_lineage_reader.py`:
- Around line 190-193: Add a test alongside
test_reader_missing_database_is_unavailable that exercises an existing database
without the lineage_event table, invoking _run_reader with the same
representative inputs and asserting result["unavailable"] is True. Also assert
the expected unavailable reason for the missing table, preserving the
Unavailable UI contract.
🪄 Autofix

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

Review profile: CHILL

Plan: Pro Plus

Run ID: b04f49d7-728f-4f9d-b4e0-a8ec3d5df708

📥 Commits

Reviewing files that changed from the base of the PR and between d096b3b and dd65feb.

📒 Files selected for processing (10)
  • plugin/dashboard/app/api/model-provenance/route.ts
  • plugin/dashboard/app/preferences/[id]/page.tsx
  • plugin/dashboard/app/skills/project/[id]/page.tsx
  • plugin/dashboard/app/skills/shared/[id]/page.tsx
  • plugin/dashboard/components/common/model-provenance.tsx
  • plugin/dashboard/lib/model-lineage.ts
  • plugin/dashboard/lib/model-provenance.ts
  • plugin/dashboard/package.json
  • plugin/dashboard/types/node-sqlite.d.ts
  • tests/test_model_lineage_reader.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • plugin/dashboard/package.json
  • plugin/dashboard/components/common/model-provenance.tsx
  • plugin/dashboard/app/skills/project/[id]/page.tsx
  • plugin/dashboard/app/skills/shared/[id]/page.tsx
  • plugin/dashboard/app/preferences/[id]/page.tsx

Comment thread plugin/dashboard/lib/model-provenance.ts
Clear outdated model metadata as soon as the detail page target changes,
and cover the missing lineage_event table path in the reader tests.
Lazy-load node:sqlite and restore the dashboard engines floor so install
and CI Node 20 matrices can build without evaluating sqlite at module load.
Use a filesystem path with createRequire so Next does not break lazy
sqlite loading via rewritten import.meta.url values.
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.

1 participant