feat: live index_status in robot capabilities response (F3.1) #32

Open
opened 2026-04-25 06:02:55 +02:00 by root · 0 comments
Owner

Problem Statement

Spec F3.1 (terraphim-agent-session-search-spec.md, lines 198-221) requires terraphim-agent robot capabilities to expose live index health under index_status:

{
  "index_status": {
    "sessions_indexed": 1234,
    "last_updated": "2025-12-03T10:00:00Z"
  }
}

Today the field is hard-coded to None. Verification:

rg "index_status: None" crates/terraphim_agent/src/robot/docs.rs   -> matches docs.rs:55
rg "sessions_indexed" crates/terraphim_agent/src/robot/             -> 0 matches outside the schema definition

User-facing failure mode for AI agents: an LLM probing terraphim-agent robot capabilities --format json cannot tell whether the local session store has any data, whether enrichment ran, or how stale the index is. It must instead invoke /sessions stats, parse a separate response shape, and reconcile -- defeating G3 ("Self-documenting API") and complicating sub-agent task routing.

Acceptance Criteria

  • CapabilitiesData::index_status is populated from SessionService::stats() (and, if Tantivy is present, the Tantivy reader's segment metadata for last_updated).
  • When terraphim_sessions is compiled out (default features), the field remains None and the JSON omits the key (existing skip_serializing_if = "Option::is_none" behaviour). No breaking change for builds without sessions.
  • When sessions are present but empty, the response shows {"sessions_indexed": 0, "last_updated": null}, distinguishable from index_status: null (which means "feature absent").
  • IndexStatusData struct gains an optional last_updated_iso8601: Option<String> (UTC, RFC3339).
  • Unit test in robot/docs.rs::tests::capabilities_includes_index_status_when_sessions_feature_enabled (gated by #[cfg(feature = "repl-sessions")]) asserts presence and shape.
  • cargo test -p terraphim_agent --features repl-sessions --lib robot::docs passes.
  • cargo clippy -p terraphim_agent --features repl-sessions -- -D warnings passes.

Proposed Approach

  1. Extend CapabilitiesData::index_status to Option<IndexStatusData> with the shape above (struct already declared in robot/schema.rs; only the producer logic needs updating).
  2. Add pub fn capabilities_data_with_sessions(&self, service: &SessionService) -> CapabilitiesData on SelfDocumentation. Keep the existing zero-arg capabilities_data() for the no-sessions build.
  3. In the /robot capabilities REPL handler (and the equivalent path in main.rs), call the sessions-aware variant when the repl-sessions feature is enabled. Use #[cfg(feature = "repl-sessions")] to fork.
  4. last_updated source: prefer SessionService::last_imported_at() (likely needs a tiny additive accessor); fall back to scanning SessionMetadata::updated_at MAX if the accessor cannot be added in this PR.

Affected crates: terraphim_agent, terraphim_sessions (one accessor only, additive).
Key files: crates/terraphim_agent/src/robot/docs.rs, crates/terraphim_agent/src/robot/schema.rs, crates/terraphim_agent/src/repl/handler.rs, crates/terraphim_sessions/src/service.rs.

Dependencies

Soft-blocked by #5 (Tantivy session index): once Tantivy lands, last_updated will use IndexReader::searcher() segment metadata for higher fidelity. Until #5 lands, falling back to SessionService::stats() is acceptable -- the field is correct, just refreshed less granularly.

Add dep edge: gitea-robot add-dep --owner terraphim --repo agent-tasks --issue NEW --blocks 5.

Verification

cargo test -p terraphim_agent --features repl-sessions --lib robot::docs
cargo clippy -p terraphim_agent --features repl-sessions -- -D warnings
./target/debug/terraphim-agent robot capabilities --format json | jq '.data.index_status'
# expected (with sessions): {"sessions_indexed": <int>, "last_updated_iso8601": "2026-04-25T..."}
# expected (without sessions feature): null  (key omitted from JSON)

Scope

Single-PR change. Estimated 180-260 lines (accessor + producer + feature-gated test + handler wiring). No cross-cutting refactor.

## Problem Statement Spec F3.1 (terraphim-agent-session-search-spec.md, lines 198-221) requires `terraphim-agent robot capabilities` to expose live index health under `index_status`: ```json { "index_status": { "sessions_indexed": 1234, "last_updated": "2025-12-03T10:00:00Z" } } ``` Today the field is hard-coded to `None`. Verification: ``` rg "index_status: None" crates/terraphim_agent/src/robot/docs.rs -> matches docs.rs:55 rg "sessions_indexed" crates/terraphim_agent/src/robot/ -> 0 matches outside the schema definition ``` User-facing failure mode for AI agents: an LLM probing `terraphim-agent robot capabilities --format json` cannot tell whether the local session store has any data, whether enrichment ran, or how stale the index is. It must instead invoke `/sessions stats`, parse a separate response shape, and reconcile -- defeating G3 ("Self-documenting API") and complicating sub-agent task routing. ## Acceptance Criteria - [ ] `CapabilitiesData::index_status` is populated from `SessionService::stats()` (and, if Tantivy is present, the Tantivy reader's segment metadata for `last_updated`). - [ ] When `terraphim_sessions` is compiled out (default features), the field remains `None` and the JSON omits the key (existing `skip_serializing_if = "Option::is_none"` behaviour). No breaking change for builds without sessions. - [ ] When sessions are present but empty, the response shows `{"sessions_indexed": 0, "last_updated": null}`, distinguishable from `index_status: null` (which means "feature absent"). - [ ] `IndexStatusData` struct gains an optional `last_updated_iso8601: Option<String>` (UTC, RFC3339). - [ ] Unit test in `robot/docs.rs::tests::capabilities_includes_index_status_when_sessions_feature_enabled` (gated by `#[cfg(feature = "repl-sessions")]`) asserts presence and shape. - [ ] `cargo test -p terraphim_agent --features repl-sessions --lib robot::docs` passes. - [ ] `cargo clippy -p terraphim_agent --features repl-sessions -- -D warnings` passes. ## Proposed Approach 1. Extend `CapabilitiesData::index_status` to `Option<IndexStatusData>` with the shape above (struct already declared in `robot/schema.rs`; only the producer logic needs updating). 2. Add `pub fn capabilities_data_with_sessions(&self, service: &SessionService) -> CapabilitiesData` on `SelfDocumentation`. Keep the existing zero-arg `capabilities_data()` for the no-sessions build. 3. In the `/robot capabilities` REPL handler (and the equivalent path in `main.rs`), call the sessions-aware variant when the `repl-sessions` feature is enabled. Use `#[cfg(feature = "repl-sessions")]` to fork. 4. `last_updated` source: prefer `SessionService::last_imported_at()` (likely needs a tiny additive accessor); fall back to scanning `SessionMetadata::updated_at` MAX if the accessor cannot be added in this PR. Affected crates: `terraphim_agent`, `terraphim_sessions` (one accessor only, additive). Key files: `crates/terraphim_agent/src/robot/docs.rs`, `crates/terraphim_agent/src/robot/schema.rs`, `crates/terraphim_agent/src/repl/handler.rs`, `crates/terraphim_sessions/src/service.rs`. ## Dependencies Soft-blocked by #5 (Tantivy session index): once Tantivy lands, `last_updated` will use `IndexReader::searcher()` segment metadata for higher fidelity. Until #5 lands, falling back to `SessionService::stats()` is acceptable -- the field is correct, just refreshed less granularly. Add dep edge: `gitea-robot add-dep --owner terraphim --repo agent-tasks --issue NEW --blocks 5`. ## Verification ```bash cargo test -p terraphim_agent --features repl-sessions --lib robot::docs cargo clippy -p terraphim_agent --features repl-sessions -- -D warnings ./target/debug/terraphim-agent robot capabilities --format json | jq '.data.index_status' # expected (with sessions): {"sessions_indexed": <int>, "last_updated_iso8601": "2026-04-25T..."} # expected (without sessions feature): null (key omitted from JSON) ``` ## Scope Single-PR change. Estimated 180-260 lines (accessor + producer + feature-gated test + handler wiring). No cross-cutting refactor.
root added a new dependency 2026-04-25 06:02:59 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: terraphim/agent-tasks#32