feat(crewai): add CREW-013, ambiguous tool name - #105
Conversation
Ports the ambiguous-name check to crewai. Claude SDK (CSDK-007), OpenAI (OAI-007), ADK (ADK-007), and MCP (MCP-003) all ship it; the five newer packs had none. The tool name sits directly beside the description in what the model sees, so it is half the selection signal, and a generic verb like process or handle spends that half on nothing.
|
Thanks @bradAGI. Clean port, and the note about One thing to resolve first, and it is a close cousin of the Vercel problem you already caught. Two nits: the last explanation sentence runs to roughly 230 characters on one line where the corpus wraps near 80, and no shipped rule text cites another rule ID, so I would drop the New rules also need a rationale doc in Happy to take this once the decorator-name question is settled. |
Ports the ambiguous-name check to CrewAI. Claude SDK (CSDK-007), OpenAI (OAI-007), ADK (ADK-007), and MCP (MCP-003) all ship it; the newer packs had none.
The tool name sits directly beside the description in what the model sees, so it is half the selection signal — and a generic verb like
processorhandlespends that half on nothing. In a crew the wrong pick does not stay local: the task output it produces is threaded forward as context to every task behind it, and CREW-104 delegation means peers select from the same name.Same
name_inlist as CSDK-007, so behavior stays consistent across packs.Verification — engine built at
main:Fire (tool named
process): includesCREW-013Silent (same tool renamed
summarize_invoice):CREW-013absentA note on scope. I drafted a fifth rule in this batch for the Vercel AI SDK and dropped it after testing:
ToolDef.Nameis deliberately empty forvercel_ai_tool, because the SDK derives a tool's name from the key in thetools: { ... }record rather than from thetool({...})call. The engine asserts this directly —so every name-based predicate (
name_in,name_has_prefix) is structurally inert for that pack — it also blocks a Vercel idempotency rule, which is why the pack has none. Back-fillingNamefrom the record key at discovery time would unblock both. Happy to open that engine PR if it'd be useful.Paired engine PR follows, mirroring the rule into
testdata/rules-fixture/with fire/silent cases.