Skip to content

Add a general search-entries host tool over the entry endpoint - #6068

Draft
FadhlanR wants to merge 1 commit into
mainfrom
cs-12820-expose-one-general-search-tool-over-the-entry-endpoint-for
Draft

Add a general search-entries host tool over the entry endpoint#6068
FadhlanR wants to merge 1 commit into
mainfrom
cs-12820-expose-one-general-search-tool-over-the-entry-endpoint-for

Conversation

@FadhlanR

Copy link
Copy Markdown
Contributor

Background and Goal

The AI's search capability is split across two narrow host tools that each drop something discovery flows need: SearchCardsByQueryTool searches all available realms with a pinned card scope and returns only id/title summaries, and SearchCardsByTypeAndTitleTool cannot express a specType or full-text matches filter at all. This PR adds one general search-entries host tool — a thin interface over the /_federated-search entry endpoint (query + realms + scope + limit in, trimmed entry rows out) — and reroutes the two existing tools' descriptions so the model uses them only when it needs live instances to attach, open, or patch.

Where to start

  • packages/host/app/tools/search-entries.ts — the tool: scope validation, mixed-scope dedup, relevance-sort composition, wire translation, flattening, and the result mapping.
  • packages/base/commands/search-entry-result.gts — the input/result card types (re-exported from command.gts).
  • packages/host/tests/integration/tools/search-entries-tool-test.gts — behavior coverage plus unit-style asserts on the exported query-composition helper.

Key decisions and non-obvious mechanics

  • Transport is store.searchEntries, not store.search — the instances path pins scope: 'cards' and a data-only fieldset; searchEntries passes scope/fields/page through untouched and already handles auth, federation, and 429 shed-retries.
  • Fixed sparse projection (item.cardTitle, item.cardDescription, item.specType, item.readMe, item.ref): the fieldset stays internal so a caller can never request full serializations. readMe returns in full; the size budget is the limit input (default 5, max 10). Tool result cards are inlined verbatim into every subsequent prompt turn with no downstream truncation, so the tool bounds its own output — and the result card uses containsMany summaries, never linksToMany(CardDef).
  • Default scope 'all' with automatic dedup: a card matches both its instance row and its dual-indexed .json file row under the mixed scope, so the filter gains excludeCardInstanceFileRows() unless it already carries a kind-narrowing positive type ref (hasNarrowingPositiveTypeRef, now exported from the host search query-builder rather than copied a third time).
  • Relevance: the _matchRelevance sort is appended only when the filter has a positive matches term (the server 400s otherwise), and merged rows are re-sorted client-side because the federated merge concatenates per realm without cross-realm re-ranking.
  • The tool module default-exports the class so skill frontmatter can declare it as module: '@cardstack/boxel-host/tools/search-entries', name: default. The skill-side declaration lands separately in boxel-skills.
  • Errors propagate to the model instead of collapsing to an empty result, so it can correct query grammar.

Testing

  • New integration suite: 15 tests covering the projection, scope narrowing and validation, mixed-scope dedup (including the narrowing-anchor skip), relevance sorting and its absence without matches, limit defaulting/clamping, realm targeting, and the default-export guard.
  • Existing tools | search suite and the host tool schema-generation suite (which now includes the new tool via HostToolClasses) pass.

🤖 Generated with Claude Code

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Preview deployments

Host Test Results

    1 files      1 suites   1h 45m 8s ⏱️
4 739 tests 4 725 ✅ 14 💤 0 ❌
4 754 runs  4 740 ✅ 14 💤 0 ❌

Results for commit c636043.

Realm Server Test Results

    1 files    208 suites   1h 17m 56s ⏱️
2 721 tests 2 721 ✅ 0 💤 0 ❌
2 760 runs  2 760 ✅ 0 💤 0 ❌

Results for commit c636043.

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