feat: robot meta concepts_matched and wildcard_fallback fields (F1.1) #21

Open
opened 2026-04-25 03:01:37 +02:00 by product-owner · 0 comments

Problem Statement

Spec F1.1 (terraphim-agent-session-search-spec.md, lines 482-509) shows the canonical robot-mode search response with meta.concepts_matched (array of matched KG concepts) and meta.wildcard_fallback (boolean indicating that the query fell back to a wildcard expansion). These are how an LLM caller learns why it got the results it did and whether to refine the query. The current ResponseMeta in crates/terraphim_agent/src/robot/schema.rs (lines 63-82) exposes only command, elapsed_ms, timestamp, version, auto_corrected, pagination, and token_budget. Neither concepts_matched nor wildcard_fallback is populated anywhere, so robot-mode search consumers cannot perform the spec'd intent inspection.

Acceptance Criteria

  • Add two optional fields to ResponseMeta:
    • concepts_matched: Option<Vec<String>> (skip when None)
    • wildcard_fallback: Option<bool> (skip when None)
  • Add builder helpers with_concepts_matched(Vec<String>) and with_wildcard_fallback(bool)
  • Wire the search handler (crates/terraphim_agent/src/repl/handler.rs, search path) to populate concepts_matched from the matched-concepts list already available via terraphim_automata::find_matches over the role thesaurus
  • Set wildcard_fallback = true when the search result count from the primary query is zero and a wildcard/relaxed retry is executed (current behaviour likely returns an empty result -- include the field as Some(false) on the success path so consumers can rely on its presence)
  • When --robot / --format json is active, the JSON envelope MUST include both fields whenever the underlying search produced concept matches or attempted a fallback
  • Unit test in crates/terraphim_agent/src/robot/schema.rs round-trips a ResponseMeta with both fields through serde_json
  • Integration test in crates/terraphim_agent/tests/ (or extension of an existing robot-mode test) confirms a search response includes concepts_matched for a query that matches at least one KG term
  • cargo test -p terraphim_agent passes
  • cargo clippy -p terraphim_agent -- -D warnings passes

Proposed Approach

The search path already builds a Thesaurus for the active role and runs find_matches to produce ranked results. Reuse the matched-term list as the source for concepts_matched -- collect distinct NormalizedTermValue::display() strings, sorted by frequency. For wildcard_fallback, add a small flag on the search return type (or thread it back via the existing SearchOutcome) and set it in the handler before constructing the envelope.

Crates affected:

  • crates/terraphim_agent -- robot/schema.rs (struct fields + builders), repl/handler.rs (population)
  • (no API changes outside the agent crate)

Key types/functions to modify:

  • ResponseMeta -- two new optional fields
  • ResponseMeta::with_concepts_matched, with_wildcard_fallback
  • The search handler that constructs RobotResponse::success / with_context

Dependencies

None. Independent of #11 (route REPL output through the formatter): #11 routes the envelope; this issue enriches its meta payload.

Verification

cargo test -p terraphim_agent robot::schema
cargo test -p terraphim_agent --test '*'
cargo clippy -p terraphim_agent -- -D warnings

Manual:

terraphim-agent --robot search "async database" --format json --limit 3

Output should include meta.concepts_matched (e.g. ["async", "database"]) and meta.wildcard_fallback (boolean).

Scope

Single PR, ~120-180 LOC: two struct fields, two builder methods, one populating call site, one unit test, one integration assertion. No new dependencies.

## Problem Statement Spec F1.1 (terraphim-agent-session-search-spec.md, lines 482-509) shows the canonical robot-mode search response with `meta.concepts_matched` (array of matched KG concepts) and `meta.wildcard_fallback` (boolean indicating that the query fell back to a wildcard expansion). These are how an LLM caller learns *why* it got the results it did and whether to refine the query. The current `ResponseMeta` in `crates/terraphim_agent/src/robot/schema.rs` (lines 63-82) exposes only `command`, `elapsed_ms`, `timestamp`, `version`, `auto_corrected`, `pagination`, and `token_budget`. Neither `concepts_matched` nor `wildcard_fallback` is populated anywhere, so robot-mode search consumers cannot perform the spec'd intent inspection. ## Acceptance Criteria - [ ] Add two optional fields to `ResponseMeta`: - `concepts_matched: Option<Vec<String>>` (skip when None) - `wildcard_fallback: Option<bool>` (skip when None) - [ ] Add builder helpers `with_concepts_matched(Vec<String>)` and `with_wildcard_fallback(bool)` - [ ] Wire the search handler (`crates/terraphim_agent/src/repl/handler.rs`, search path) to populate `concepts_matched` from the matched-concepts list already available via `terraphim_automata::find_matches` over the role thesaurus - [ ] Set `wildcard_fallback = true` when the search result count from the primary query is zero and a wildcard/relaxed retry is executed (current behaviour likely returns an empty result -- include the field as `Some(false)` on the success path so consumers can rely on its presence) - [ ] When `--robot` / `--format json` is active, the JSON envelope MUST include both fields whenever the underlying search produced concept matches or attempted a fallback - [ ] Unit test in `crates/terraphim_agent/src/robot/schema.rs` round-trips a `ResponseMeta` with both fields through `serde_json` - [ ] Integration test in `crates/terraphim_agent/tests/` (or extension of an existing robot-mode test) confirms a search response includes `concepts_matched` for a query that matches at least one KG term - [ ] `cargo test -p terraphim_agent` passes - [ ] `cargo clippy -p terraphim_agent -- -D warnings` passes ## Proposed Approach The search path already builds a `Thesaurus` for the active role and runs `find_matches` to produce ranked results. Reuse the matched-term list as the source for `concepts_matched` -- collect distinct `NormalizedTermValue::display()` strings, sorted by frequency. For `wildcard_fallback`, add a small flag on the search return type (or thread it back via the existing `SearchOutcome`) and set it in the handler before constructing the envelope. Crates affected: - `crates/terraphim_agent` -- `robot/schema.rs` (struct fields + builders), `repl/handler.rs` (population) - (no API changes outside the agent crate) Key types/functions to modify: - `ResponseMeta` -- two new optional fields - `ResponseMeta::with_concepts_matched`, `with_wildcard_fallback` - The search handler that constructs `RobotResponse::success` / `with_context` ## Dependencies None. Independent of #11 (route REPL output through the formatter): #11 routes the envelope; this issue enriches its `meta` payload. ## Verification ``` cargo test -p terraphim_agent robot::schema cargo test -p terraphim_agent --test '*' cargo clippy -p terraphim_agent -- -D warnings ``` Manual: ``` terraphim-agent --robot search "async database" --format json --limit 3 ``` Output should include `meta.concepts_matched` (e.g. `["async", "database"]`) and `meta.wildcard_fallback` (boolean). ## Scope Single PR, ~120-180 LOC: two struct fields, two builder methods, one populating call site, one unit test, one integration assertion. No new dependencies.
Sign in to join this conversation.