Skip to content

feat(tool-search): one search call finds many tools — multi-query, stemming, exact-name ranking, batched describe (salvage #92766) - #95119

Merged
teknium1 merged 9 commits into
mainfrom
salv/ts-multiquery
Aug 25, 2026
Merged

teknium1 merged 9 commits into
mainfrom
salv/ts-multiquery

Conversation

@teknium1

Copy link
Copy Markdown
Collaborator

Summary

Finding a deferred tool now takes one bridge call instead of several, and search stops missing tools over trivial wording differences. tool_search accepts multiple queries in a single call; plural queries match singular tool names via Snowball stemming; a query that IS a tool's exact name ranks that tool first; tool_describe batches multiple names and reports misses in not_found instead of failing the whole call.

Salvaged from #92766 by @alt-glitch (8 commits, authorship preserved), rebased onto current main on top of the merged #95050 with the one predicted docs conflict resolved as the author specified (single Retrieval bullet covering both source-name indexing and stemming).

Changes

  • tools/tool_search.py: tool_search takes queries: string[] (per-query limit, grouped results, deduped shared tools map that now includes each tool's required params); tool_describe takes names: string[] with not_found/errors split; Snowball stemming in the shared _tokenize (thread-local stemmer instances, process-wide stem memo); exact-name fast path over BM25 length normalization; internal per-call caps (10 queries / 10 names), bare strings coerced.
  • pyproject.toml / uv.lock: snowballstemmer==3.1.1 — official Snowball project package, pure Python, zero transitive deps, exact-pinned.
  • hermes_cli/config_defaults.py: max_search_limit default 20 → 25.
  • Tests: new tests/tools/test_tool_search_multiquery.py (26 tests); test_tool_search.py and test_a2a_schema_registration.py updated to the new shapes; follow-up commit makes two salvage-seam tests order- and stem-robust against the just-merged fix(tool-search): parallel batching, listing truncation, and service-name search work again under deferral (salvage #92693, part 1) #95050 (token-space comparison; monkeypatched unregistered-name condition).
  • Docs: tool-search page updated for the array inputs and stemming.

Validation

Before (main) After
tool_search "issues" (live, 215 deferred tools) entire singular *_issue family absent get_issue, create_issue_label, list_issue_statuses, … returned
Multi-capability discovery one bridge round-trip per query one call, grouped results
Query = exact tool name ranked below longer-named siblings ranked first
tool_describe with one bogus name whole batch failed real schemas returned, bogus name in not_found
tests — 117 passed, 1 skipped across 6 suites, both collection orders

Cache impact: bridge-tool schema/description wording changes — one-time prefix bust on the release that ships it, same as any tool-description edit; byte-stable across assemblies after that.

Infographic

tool-search multi-query upgrades

alt-glitch and others added 9 commits August 25, 2026 16:31
…mming

tool_search now takes queries: string[] (searched independently against
the same catalog, limit applies per query, default 5 / max 25) and
returns the split shape: per-query groups carry tool names only, one
shared tools map holds each matched tool's source, description (400-char
cap) and required parameter names once. When some queries miss, a single
top-level available_sources + hint block replaces the old per-response
fallback.

tool_describe now takes names: string[] and returns a map keyed by name;
unknown names collect in not_found (with the refresh hint) and
non-deferrable names keep their per-name spelling-check error in errors,
so one bad name no longer fails the whole call. Duplicates dedupe
silently.

The shared tokenizer now applies Snowball stemming (english, exact-pinned
snowballstemmer) at both index and query time, closing the measured
plural/singular miss where 'issues' failed to return create_issue. The
inline BM25 is unchanged. Stemmer instances are thread-local (they carry
mutable parse state and bridge dispatch can run on parallel tool-call
threads).

New config knobs under tools.tool_search: max_queries / max_describe_names
(default 10 each, floor 1, no upper clamp) bound the per-call array
inputs; over-cap calls error so the model repairs in one round-trip.

No backward compatibility with the single query/name shapes, by decision.
scripts/analyze_livetest.py renders both shapes since transcripts on disk
may predate this change.
…input

The parallel determinism test warms _stem's lru_cache after ~11 distinct
stems, so almost no iterations reach the underlying stemmer and a shared
(non-thread-local) instance survives it. New test bypasses the cache with
per-iteration unique tokens via _stem.__wrapped__, so thousands of stems
run concurrently: a shared stemmer's mutable parse state fails it within
2,000 calls (verified — the mutant dies 8/8 runs; healthy runs stay green).
Two interaction seams between the #92693 salvage (merged as #95050) and
this branch: the source-label indexing test now compares in token space
(the stemmer shortens 'catalogsource' to 'catalogsourc'), and the
unregistered-core-name describe test forces the unregistered condition
via monkeypatch instead of depending on which sibling test file imported
model_tools first.
@teknium1
teknium1 requested a review from a team August 25, 2026 23:33
@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 448bab2 — test(tool-search): make salvage-seam tests order- and stem-r

⚠️ Warnings

OSV vulnerability scan · View job

7 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 4m8s vs 4m10s (-0.8%). 3 job(s) slower, 10 faster, 1 unchanged.

  • Docs Site / docs-site-checks: -26.0s
  • OSV scan / Scan lockfiles / osv-scan: -25.0s
  • Python tests / e2e: -22.0s
  • Check uv.lock / uv lock --check: -19.0s
  • Check contributors / check-attribution: -6.0s

@alt-glitch alt-glitch added type/feature New feature or request comp/tools Tool registry, model_tools, toolsets area/config Config system, migrations, profiles P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Aug 25, 2026
@teknium1
teknium1 merged commit a935154 into main Aug 25, 2026
37 checks passed
@teknium1
teknium1 deleted the salv/ts-multiquery branch August 25, 2026 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/tools Tool registry, model_tools, toolsets P2 Medium — degraded but workaround exists sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants