Skip to content

perf(tools): tool-call parser builds the full tool_defs schema table just to check a name #589

Description

@dhgoal

Summary

The tool-call parser validates a compact single-key tool call like {"get_weather":"Denver"} (a shape small models emit routinely, #438) by checking whether the key names a known tool:

// crates/genie-core/src/tools/parser.rs
let known_tool = tools.tool_defs().iter().any(|tool| tool.name == *tool_name);

But ToolDispatcher::tool_defs() (dispatch.rs) is the system-prompt builder: it allocates a ToolDef per built-in tool — each carrying a serde_json::json! parameter schema (nested maps, enum arrays, required vectors) — and serde_json::from_str-parses every loaded skill's parameters_json. The parser throws all of that away after reading a single .name, on every compact tool-emitting model response.

Where

  • crates/genie-core/src/tools/parser.rsnormalize_single_key_tool_call builds the full table to test one name.
  • crates/genie-core/src/tools/dispatch.rstool_defs() builds ~10–15 JSON schemas + parses skill schemas per call.

Proposed fix

Add ToolDispatcher::is_known_tool(name) — an allocation-free membership check over the same name set, with the same has_home_automation() / has_web_search() gating and the same loaded skills — and use it from the parser. Keep it in lockstep with tool_defs() via a test that asserts membership parity across home/web/skill configurations.

Impact

Local microbench (laptop, release): the per-name check drops from ~11.2 µs/call to ~15 ns/call (~700×), eliminating ~10–15 json! schema builds (and the matching allocator churn) per compact tool call on the parser hot path. Behavior is identical — same set of accepted names.

Contributes under #402.

Metadata

Metadata

Assignees

No one assigned

    Labels

    performanceperformance improvement, but not verify on jetson

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions