Tool params extract and availability pattern
Skill kjuhwa/skills-hub/skills/agent-sdk/tool-params-extract-and-availability-pattern
Tools implement is_available(sources) and extract_params(sources) so the agent can decide at plan time whether to include the tool AND automatically bind its inputs from the detected source dict — no per-tool glue code in the planner.From its SKILL.md
npx -y skills add kjuhwa/skills-hub --skill tool-params-extract-and-availability-patternAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.1 KB, 579 tokens by cl100k_base, as published. Nobody here has run it
Self-Describing Tools: is_available + extract_params
When to use
Your agent has many tools and many data sources. The planner needs to ask two questions for each (tool, source_dict) pair: "is this tool usable given what I've detected?" and "if yes, what arguments do I pass?". Without this pattern, you end up with giant switch statements in the planner.
How it works
Every tool subclass declares:
is_available(sources) -> bool— e.g. "grafana is in sources AND has api_key". Default: always True.extract_params(sources) -> dict— e.g.{"service_name": sources["grafana"]["service_name"], "time_range_minutes": sources["grafana"]["time_range_minutes"]}. Default: empty dict.
The planner then filters all_tools with [t for t in all_tools if t.is_available(sources)] and binds inputs via t(**t.extract_params(sources)) — no special casing.
Example
class BaseTool(ABC):
# metadata ClassVars ...
def is_available(self, _sources: dict[str, dict]) -> bool:
"""Return True when required data sources are present."""
return True # default: always available
def extract_params(self, _sources: dict[str, dict]) -> dict[str, Any]:
"""Extract kwargs to pass to run() from available sources."""
return {} # default: no params
class GrafanaLogsTool(BaseTool):
name = "query_grafana_logs"
# ...
def is_available(self, sources):
g = sources.get("grafana")
return bool(g and g.get("grafana_endpoint") and
(g.get("grafana_api_key") or g.get("loki_only")))
def extract_params(self, sources):
g = sources["grafana"]
return {
"service_name": g["service_name"],
"endpoint": g["grafana_endpoint"],
"api_key": g["grafana_api_key"],
"time_range_minutes": g["time_range_minutes"],
"pipeline_name": g.get("pipeline_name", ""),
}
Gotchas
- Keep
is_availablecheap — the planner calls it for every tool × every loop. Pure dict lookups, no network. - If
extract_paramsdepends on state beyondsources, thread state through — don't reach into module globals. - For "this tool needs auth BUT I can always run it against a test fixture", respect an injected
_backendsentinel insourcesand allow availability. - Function-based tools get the same treatment via the
@tool(..., is_available=..., extract_params=...)decorator parameters.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.