classifiers.build_tool_index module
Build the tool index used by the vector classifier.
Auto-discovers every registered tool via tool_loader, then
calls an LLM to generate 50 diverse synthetic user queries per tool
(reverse-HyDE). Results are saved to tool_index_data.json in
this directory.
Usage:
python -m classifiers.build_tool_index [--tools-dir tools]
- classifiers.build_tool_index.discover_invalid_query_index_tools(index_data, registered, *, expected_count=50)[source]
Return tool names whose stored index entry cannot drive embeddings.
Invalid: missing key, non-dict value,
synthetic_queriesmissing or not a list, fewer than expected_count items, or any of the first expected_count entries not a non-empty string (after strip).Used by
classifiers.refresh_tool_embeddingsto redo query generation only wheretool_index_data.jsonis incomplete or malformed (e.g. failed or partial LLM JSON).
- async classifiers.build_tool_index.generate_synthetic_queries(client, base_url, api_key, tool_name, tool_description, count=50, model='gemini-3.1-flash-lite', *, openrouter_only=False)[source]
Produce count synthetic queries via Gemini, with model fallbacks.
When openrouter_only is True, skips Gemini and uses OpenRouter chat with
google/{_OPENROUTER_ONLY_QUERY_MODEL}only (requiresOPENROUTER_*orAPI_KEY).Tries the primary model, then
gemini-2.5-flashandgemini-3-flash-previewon the same API key whengenerateContentreturns a retriable HTTP status. If every Gemini model fails for the round, falls back to OpenRouter chat completions withgoogle/<primary model name>. OpenRouter key: preferOPENROUTER_QUERY_GEN_API_KEY, elseOPENROUTER_API_KEY, elseAPI_KEY. Embeddings are unaffected — this path is query generation only.Invalid JSON or too few queries: the same model is called again immediately (up to
GEMINI_QUERY_GEN_JSON_PARSE_MAX_RETRIES_SAME_MODELtimes per model), then the next model / outer round. Partial JSON may be recovered by extracting the first{...}block.429 responses wait with exponential backoff and retry the same Gemini model (see
GEMINI_QUERY_GEN_429_*); OpenRouter 429 usesOPENROUTER_QUERY_GEN_429_*.Retries use exponential backoff. After
_QUERY_GEN_PAID_AFTER_FAILURESconsecutive full-round failures,gemini_embed_pool.get_paid_fallback_key()is used (if set). Env:GEMINI_QUERY_GEN_*(see module constants).
- async classifiers.build_tool_index.build_index(tools_dir='tools')[source]
Discover every tool and generate its synthetic queries into the index file.
The top-level driver for the reverse-HyDE index build: it auto-discovers all registered tools, generates
SYNTHETIC_QUERY_COUNTsynthetic user queries per tool, and writes the merged result totool_index_data.json. That JSON is the input later consumed by the embedding initializers to populate the vector classifier, so this is the first stage of the tool-routing pipeline.It builds a
tools.ToolRegistryand loads it viatool_loader.load_tools(), reads any existingOUTPUT_FILEto skip tools that already have enough queries (resumable), and fans out generation across anasyncio.Semaphore(3)of three concurrent workers. Each worker callsgenerate_synthetic_queries()over a sharedhttpx.AsyncClient(Gemini with OpenRouter fallback), and the final dict is written back toOUTPUT_FILEon disk. Progress is logged throughout. Invoked only from this module’s__main__guard viaasyncio.run; no other callers were found.