Skip to content

Surface meta in inspect_model output (DEV-1332)#87

Merged
ZmeiGorynych merged 3 commits into
mainfrom
egor/dev-1332-slayer-mcp-meta-field-on-modelmeasure-and-aggregation-doesnt
May 4, 2026
Merged

Surface meta in inspect_model output (DEV-1332)#87
ZmeiGorynych merged 3 commits into
mainfrom
egor/dev-1332-slayer-mcp-meta-field-on-modelmeasure-and-aggregation-doesnt

Conversation

@ZmeiGorynych
Copy link
Copy Markdown
Member

@ZmeiGorynych ZmeiGorynych commented May 4, 2026

Summary

  • inspect_model now renders meta for Column, ModelMeasure, Aggregation, and the model header itself — Markdown tables get a meta cell (compact JSON, hidden by _markdown_table's all-empty-column pruner when no entity uses meta), the model-header gets a **meta:** bullet, and the JSON form emits meta on every entity entry and at the top level of the payload.
  • Storage already round-tripped meta correctly post-PR Add meta field to ModelMeasure and Aggregation #83 — the visible defect was purely rendering, so agents calling inspect_model to verify their bookkeeping saw no meta column and concluded the field had been dropped.
  • 11 new tests pin both the rendering (5 in TestInspectModel) and the edit_model → storage round-trip for ModelMeasure / Aggregation (6 in TestEditModel, including replacement-not-merge semantics and the omitted-key-preserves-existing-meta contract of _upsert_entity).
  • Docs updated: models.md ModelMeasure fields table + Custom Aggregations note, terminology.md Column entry, inspect_model rows in docs/reference/mcp.md + docs/interfaces/mcp.md, and the meta bullet in CLAUDE.md (now includes aggregations).

Closes DEV-1332.

Test plan

  • poetry run ruff check slayer/ tests/ — clean
  • poetry run pytest -m "not integration" — 1532 passed
  • New tests fail on main's rendering branches (rebased onto current HEAD before the fix); pass after
  • CI green on the PR

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • inspect_model now shows metadata (meta) for models, columns, measures (named formulas), and aggregations in both markdown and JSON outputs.
    • meta is supported on measures and custom aggregations for caller bookkeeping.
  • Bug Fixes

    • Markdown output auto-prunes the metadata column and model meta bullet when no entities include meta.
  • Documentation

    • Clarified meta as opaque JSON persisted with entities.
  • Tests

    • Added coverage verifying rendering, pruning, persistence, and meta round-trip behavior.

PR #83 added `meta: Optional[Dict[str, Any]]` to `ModelMeasure` and
`Aggregation` and storage round-trips it correctly, but `inspect_model`
never rendered the field. Agents calling inspect_model to verify their
bookkeeping saw no meta column and concluded the value had been dropped
— the symptom DEV-1332 reports.

Surface meta in `inspect_model`:

- Markdown columns / measures / aggregations tables get a `meta` cell
  (compact JSON via a new `_format_meta` helper). The existing
  `_markdown_table` all-empty-column pruner hides the column when no
  entity in the section uses meta, so output is unchanged for callers
  that don't set it.
- Markdown model header gets a `**meta:**` bullet when `model.meta` is
  non-None.
- JSON form emits `meta` on every column / measure / aggregation entry
  and at the top level of the payload (unconditional, matching how
  `label` / `description` / `hidden` are emitted).

Add 11 tests in tests/test_mcp_server.py:

- 5 in TestInspectModel pinning meta rendering for columns, measures,
  aggregations, the model header, and the prune-when-absent contract.
- 6 in TestEditModel pinning end-to-end edit_model -> storage
  round-trip for ModelMeasure.meta and Aggregation.meta (create-new
  and update-existing paths), plus replacement-not-merge semantics
  on update and the omitted-key-preserves-existing semantics of
  `_upsert_entity`.

Docs: add `meta` row to the ModelMeasure fields table in
docs/concepts/models.md, note meta on aggregations under Custom
Aggregations, extend the Column entry in docs/concepts/terminology.md,
update the inspect_model row in docs/reference/mcp.md and
docs/interfaces/mcp.md, and update the meta bullet in CLAUDE.md to
include aggregations and the inspect_model rendering.

ruff clean, 1532 unit tests pass.

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

coderabbitai Bot commented May 4, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1e2d19c9-7ad9-407f-9c67-5aa3717cf0ce

📥 Commits

Reviewing files that changed from the base of the PR and between b06bc8e and f29aafd.

📒 Files selected for processing (3)
  • CLAUDE.md
  • docs/concepts/models.md
  • tests/test_mcp_server.py
✅ Files skipped from review due to trivial changes (2)
  • docs/concepts/models.md
  • CLAUDE.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/test_mcp_server.py

📝 Walkthrough

Walkthrough

The PR extends the optional opaque JSON meta field to aggregations, updates docs and MCP interface docs, implements meta rendering in inspect_model (markdown and JSON) including auto-pruning of unused metadata columns, and adds tests verifying rendering and edit-model persistence/semantics.

Changes

Meta Field Documentation, Rendering & Tests

Layer / File(s) Summary
Documentation: Concepts & Terminology
CLAUDE.md, docs/concepts/models.md, docs/concepts/terminology.md
Documents meta: dict as supported on measures and aggregations, clarifies meta is opaque persisted JSON for caller bookkeeping, and notes markdown tables omit the meta column when unused.
MCP Interface & Reference Documentation
docs/interfaces/mcp.md, docs/reference/mcp.md
Updates inspect_model docs: model header gains **meta:** when present; columns/measures/aggregations tables may include a meta cell; clarifies sampled semantics.
Core Meta Rendering Implementation
slayer/mcp/server.py
Adds _format_meta() to JSON-serialize optional meta (None when unset); includes meta in top-level model bullets and adds meta cells to markdown tables for columns/measures/aggregations (pruned when unused); adds top-level and per-entity meta to JSON payload.
Meta Rendering & Persistence Tests
tests/test_mcp_server.py
Adds tests asserting meta renders in markdown and JSON for Column, ModelMeasure, Aggregation, and SlayerModel; tests pruning of markdown meta column and header bullet when unused; adds edit_model round-trip tests for create/update semantics, persistence after reload, full-dict replace behavior, and preserving existing meta when meta is omitted.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • MotleyAI/slayer#83: Both PRs add and surface optional meta on measures/aggregations — #83 adds meta fields to ModelMeasure/Aggregation types while this PR updates MCP rendering, docs, and tests.
  • MotleyAI/slayer#70: Related changes to inspect_model output/rendering; both PRs modify how MCP renders model metadata and table sections.
  • MotleyAI/slayer#33: Related changes to representation/rendering of model/field meta in slayer/mcp/server.py.

Poem

🐰 A metadata bloom in spring—
Columns, measures, aggregations sing;
Opaque JSON tucked in their chest,
inspect_model shows them at rest,
The rabbit hops and logs them right.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately reflects the main change: surfacing meta field in inspect_model output, with the issue reference (DEV-1332) providing full context.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
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 egor/dev-1332-slayer-mcp-meta-field-on-modelmeasure-and-aggregation-doesnt

Review rate limit: 1/5 review remaining, refill in 47 minutes and 3 seconds.

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

Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (1)
tests/test_mcp_server.py (1)

2216-2230: ⚡ Quick win

Make the aggregation create-path test explicit (custom name + formula).

test_edit_persists_aggregation_meta_create_path currently uses "name": "sum" and no formula, which makes the create-path contract ambiguous. Prefer a custom aggregation name with formula so this test only verifies meta persistence, not reserved-name/formula edge behavior.

♻️ Suggested adjustment
-        result = await _call(mcp_server, name="edit_model", arguments={
-            "model_name": "orders",
-            "aggregations": [{"name": "sum", "meta": {"owner": "x"}}],
-        })
+        result = await _call(mcp_server, name="edit_model", arguments={
+            "model_name": "orders",
+            "aggregations": [{
+                "name": "my_agg",
+                "formula": "SUM({expr})",
+                "meta": {"owner": "x"},
+            }],
+        })
         assert json.loads(result)["success"] is True
         model = await storage.get_model("orders")
         assert model.aggregations[0].meta == {"owner": "x"}
+        assert model.aggregations[0].formula == "SUM({expr})"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_mcp_server.py` around lines 2216 - 2230, The test
test_edit_persists_aggregation_meta_create_path is ambiguous because it uses the
reserved name "sum" and no formula; change the aggregation payload in the call
to edit_model to use a custom name (e.g., "custom_sum" or similar) and include
an explicit "formula" value so the test exercises only meta persistence. Update
the _call invocation arguments for "aggregations" to include {"name":
"<custom_name>", "formula": "<some_formula>", "meta": {"owner": "x"}} and keep
the rest (storage.save_model, assertion on model.aggregations[0].meta)
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/test_mcp_server.py`:
- Around line 2216-2230: The test
test_edit_persists_aggregation_meta_create_path is ambiguous because it uses the
reserved name "sum" and no formula; change the aggregation payload in the call
to edit_model to use a custom name (e.g., "custom_sum" or similar) and include
an explicit "formula" value so the test exercises only meta persistence. Update
the _call invocation arguments for "aggregations" to include {"name":
"<custom_name>", "formula": "<some_formula>", "meta": {"owner": "x"}} and keep
the rest (storage.save_model, assertion on model.aggregations[0].meta)
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a9f452a1-e8d4-4c7c-b598-71d110baac00

📥 Commits

Reviewing files that changed from the base of the PR and between e7e79ff and f934b86.

📒 Files selected for processing (7)
  • CLAUDE.md
  • docs/concepts/models.md
  • docs/concepts/terminology.md
  • docs/interfaces/mcp.md
  • docs/reference/mcp.md
  • slayer/mcp/server.py
  • tests/test_mcp_server.py

ZmeiGorynych and others added 2 commits May 4, 2026 21:42
- CodeRabbit nitpick: rewrite test_edit_persists_aggregation_meta_create_path
  to use a custom aggregation name + formula (`my_agg` / `SUM({expr})`)
  instead of the built-in `sum`. The previous shape passed even if formula
  round-trip silently dropped the value, since `sum` is a built-in and the
  formula is optional. Now pins both meta and formula persistence on the
  create path, mirroring the matching update-path test.

- Sonar S5886 (storage fixture): annotate the `storage` pytest fixture
  return type as `Generator[YAMLStorage, None, None]` so pyright/Sonar
  recognise the yield correctly. Pre-existing issue surfaced during the
  PR review; trivial enough to address inline.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…mcp-meta-field-on-modelmeasure-and-aggregation-doesnt

# Conflicts:
#	tests/test_mcp_server.py
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 4, 2026

@ZmeiGorynych ZmeiGorynych merged commit 698367d into main May 4, 2026
4 checks passed
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