A schema response says when a datasource has stored examples (#301) - #313
Conversation
Clients often skipped get_prompt_examples: the only instruction to call it was in the server instructions, which a host may weight below its own. get_datasource_schema now carries prompt_examples (a datasource-wide count and a one-line reminder) when the datasource has any. It never carries the examples; ranking stays get_prompt_examples'. The instructions and both tool descriptions say to pass the question as query and leave area out unless sure. The two grounding calls stay independent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review: a local examples.yaml written as {examples: [...]} counted zero and got no
pointer. Counting through list_prompt_examples reads whichever shape the loader
accepts, and an unreadable file counts nothing rather than failing the call.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved moderate findings remain in the schema size-budget handling and shared typed contract.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR makes get_datasource_schema report stored prompt-example counts while keeping retrieval in get_prompt_examples.
Changes:
- Adds local and database-backed example counting.
- Updates instructions, descriptions, tests, and changelog.
- Preserves datasource-wide counting and ranked example retrieval.
File summaries
| File | Summary |
|---|---|
tests/test_schema_names_stored_examples.py |
Covers local, served, scoped, and wording behavior. |
tests/test_model_store_roundtrip.py |
Updates context tuple handling. |
packages/agami-core/src/tools.py |
Adds schema metadata and guidance; unresolved moderate findings remain around budget enforcement and typed contract coverage. |
packages/agami-core/src/model_store.py |
Adds datasource- and organization-scoped example counting. |
CHANGELOG.md |
Documents the feature; area-filter wording needs correction. |
Review details
Suppressed comments (3)
CHANGELOG.md:25
- This changelog entry repeats the inaccurate claim that an area drops every example outside it; served selection still includes cross-area (
area IS NULL) examples. Keep the release note consistent with the tool contract by saying it drops other named areas but retains cross-area examples.
question as `query` and leave `area` out unless sure, because an `area` drops every example
outside it.
packages/agami-core/src/tools.py:1609
- The hosted-path test only checks
_context_sources(...)[4]; it never parsestool_get_datasource_schemawith a database configured. A regression in this new insertion or its truthiness branch could therefore leave all tests green while served clients receive noprompt_examplespointer. Add a DB-backed schema-output assertion.
org_md_raw, user_md_raw, record, company_md, example_count = _context_sources(
profile, _current_org_id()
)
if example_count:
# A pointer, never the examples (#301). Counted datasource-wide whatever `area` scoped this
# call: an area-scoped count would hide exactly the examples an `area` filter drops.
result["prompt_examples"] = {"stored": example_count, "next": _EXAMPLES_REMINDER}
packages/agami-core/src/tools.py:129
- The served selector deliberately retains cross-area rows (
area IS NULL) when an area is supplied, so saying it drops every example outside that area is inaccurate and conflicts with the input schema's cross-area behavior. Say that it drops examples from other named areas instead.
"question as `query` and mirror the closest match; leave `area` out unless you are sure of "
"it, because it drops every example outside that area. Use "
- Files reviewed: 5/5 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if example_count: | ||
| # A pointer, never the examples (#301). Counted datasource-wide whatever `area` scoped this | ||
| # call: an area-scoped count would hide exactly the examples an `area` filter drops. | ||
| result["prompt_examples"] = {"stored": example_count, "next": _EXAMPLES_REMINDER} |
There was a problem hiding this comment.
Fixed in 620821f. The count is read before the response is built, and prompt_examples is added inside the size loop before the size check (and on the table-scoped branch), so the downgrade decision includes it.
| "afterwards. When the datasource has stored examples the response also carries " | ||
| "`prompt_examples`: how many are `stored`, and a reminder to fetch them with " | ||
| "get_prompt_examples, which ranks them — no example is sent here." |
There was a problem hiding this comment.
Fixed in 620821f. DatasourceSchemaResult now declares prompt_examples: dict[str, Any] | None. test_the_shared_contract_declares_the_pointer checks it's a declared field, not just tolerated, and that it round-trips.
| "afterwards. When the datasource has stored examples the response also carries " | ||
| "`prompt_examples`: how many are `stored`, and a reminder to fetch them with " | ||
| "get_prompt_examples, which ranks them — no example is sent here." |
There was a problem hiding this comment.
Leaving this as-is. get_prompt_examples' own description, read before a client calls it, already says to pass the question as query and leave area out unless sure, and so does the reminder inside prompt_examples. Repeating it on get_datasource_schema's description would be a third copy of the same advice.
…urate area wording - prompt_examples is added before the schema size check, so the budget accounts for it. - DatasourceSchemaResult declares prompt_examples. - An area drops other areas' examples; cross-area examples stay. Wording corrected. - A served schema call with a database configured is tested end to end. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Also fixed the three suppressed comments in 620821f:
|
Refs #301. Leaves the issue open: its "done when" needs a scripted run with a live client, which is described below.
What changes
get_datasource_schemasays when a datasource has stored examples. When there are any, the response carriesprompt_examples: {"stored": <count>, "next": <one-line reminder>}. It never carries the examples. Ranking and returning them staysget_prompt_examples' job.area-scoped call. A count narrowed the same way would hide exactly the examples anareafilter drops, which is the issue's third chat.model_store.count_examplesruns on the connection_context_sourcesalready opens, so there is still one database connection per schema call. The count is covered by the primary key.list_prompt_examples, so both file shapes it accepts are counted.queryand to leaveareaout unless sure. The reminder text is defined once, as_EXAMPLES_REMINDER.Decisions
get_prompt_examplesremains the ranked, budgeted source of examples.get_datasource_schemaandget_prompt_examplesin the same turn (test_the_two_grounding_calls_are_declared_independent). The pointer is a fallback for a client that skipped the second call.areastays a real filter. Scoring every example wheneverareais set would make the filter pointless. Clients are told to leave it out unless sure, and leaving it out already ranks the whole datasource. A search index for large libraries is separate work.Tests
tests/test_schema_names_stored_examples.py, 6 tests:{examples: [...]}shape;main:test_prompt_examples_serving(2),test_admin_activity(6) andtest_model_store_roundtrip::test_file_model_seeds_to_db_and_tools_serve_from_itfail identically on untouchedmain(99e44a8). They are not caused by this change.Review
The standard agami review ran with a correctness pass and a security/runtime pass.
{examples: [...]}shape counted zero.execute_sqlnor the safety wording changes.Still to verify (the issue's done-when)
Deploy locally and ask, from a claude.ai client without naming any tool:
Each conversation's tool calls should show
get_prompt_examplescalled, with the question asqueryand no guessedarea.🤖 Generated with Claude Code