tool_curator
Everything importable from the tool_curator package.
get_curator()
get_curator(
mode: str = "rag",
top_k: int = 15,
model_name: str = "BAAI/bge-small-en-v1.5",
index_dir: str = "",
) -> Optional[BaseToolCurator]
Factory. Returns a curator instance, or None when mode="none".
| Argument | Meaning |
|---|---|
mode |
"none" — bypass, no filtering happens; "rag" — the FAISS + BM25 + RRF hybrid engine |
top_k |
Tools returned per query. Expands automatically by CONF_BOOST (5) when retrieval confidence is low |
model_name |
Any sentence-transformers model. BAAI/bge-small-en-v1.5 (130MB) is the validated default; all-MiniLM-L6-v2 (22MB) trades quality for speed; BAAI/bge-base-en-v1.5 (440MB) trades speed for quality, still CPU-viable |
index_dir |
Disk cache path for the FAISS index and embeddings. "" disables caching — every process start re-embeds from scratch |
BaseToolCurator
class BaseToolCurator(ABC):
def __init__(self, top_k: int = 15): ...
def build_index(
self,
tools: list[tuple[str, str]],
extra_context: dict[str, str] | None = None,
) -> None: ...
def select(
self,
query: str,
tools: list[tuple[str, str]],
) -> list[tuple[str, str]]: ...
build_index() runs once per session, over the full (already role-filtered) tool pool. extra_context is an optional {tool_name: "synonym text"} map — the curator never inspects its content, it’s concatenated verbatim into the indexed document for that tool.
select() runs once per message. tools is the same role-filtered pool passed to build_index() (or a subset of it) — the return value is trimmed to top_k (or top_k + CONF_BOOST under low-confidence expansion) (name, description) pairs, ranked by relevance.
RAGCurator (in tool_curator.hybrid_rag_curator) is the only shipped implementation, returned by get_curator(mode="rag", ...).
load_tool_context()
load_tool_context(path: Optional[str] = None) -> dict[str, str]
Loads a JSON {tool_name: "synonym text"} map for use as build_index()’s extra_context. Keys starting with _ are ignored (comments). Returns {} if the file doesn’t exist or fails to parse — synonym loading always fails soft, never raises. If path is omitted, looks for tool_context.json in the current working directory; in practice, always pass an explicit path.
load_dependency_rules() / apply_dependency_rules()
load_dependency_rules(path: Optional[str] = None) -> dict[str, list[str]]
apply_dependency_rules(
selected: list[tuple[str, str]],
pool: list[tuple[str, str]],
rules: dict[str, list[str]],
) -> list[tuple[str, str]]
load_dependency_rules() loads a {trigger_tool: [companion_tool, ...]} map, same comment/fail-soft behavior as load_tool_context(). apply_dependency_rules() is a post-processing step: given curator.select()’s output, force-appends any companion listed for a selected trigger tool, provided the companion exists in pool and isn’t already selected — deduplicated, order-preserved. See Configuration & Domain Synonyms for when to add a rule.
suggestion_validator.SuggestionValidator
from tool_curator.suggestion_validator import SuggestionValidator
validator = SuggestionValidator()
validator.validate(model_response_text, known_tool_names, verbose=True)
Detects when a model’s free-text response suggests a tool that doesn’t actually exist in the known tool set — e.g. proposing “I can help you apply_scholarship” when the real tool is apply_for_scholarship. This is a text-scanning check over the model’s output, not a retrieval concern; it’s independent of everything else in this package and safe to use even with mode="none".
terminal_display
tool_curator.terminal_display is a minimal, dependency-light logging helper for printing curator selections from within a non-interactive service. It’s distinct from example/orchestrator/terminal_display.py, which is the full interactive terminal UI built for the reference example and depends on rich.