diff options
Diffstat (limited to 'tools_todo.md')
-rw-r--r-- | tools_todo.md | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/tools_todo.md b/tools_todo.md new file mode 100644 index 000000000..865394d73 --- /dev/null +++ b/tools_todo.md @@ -0,0 +1,110 @@ +### What’s actually happening + +1. **The loader _is_ registering your tool** + You should see a console line like: + + ``` + ✓ Loaded dynamic tool 'inspirationalQuoteGeneratorTool' from 'dynamic/InspirationalQuoteGeneratorTool.ts' + ``` + + That proves the object is stored in `dynamicToolRegistry`. + +2. **The validator rejects the LLM’s action string** + The key in the registry is **`inspirationalQuoteGeneratorTool`** + The LLM emitted **`inspirationalquotegenerator`** + → `allowedActions.includes("inspirationalquotegenerator")` is `false` + → _“Action … is not a valid tool”_. + +So the bug is a **name-mismatch**, not a missing registration. + +--- + +## 📏 Pick one naming convention and stick to it + +Let’s convert every class name to an **all-lowercase string with the “Tool” suffix stripped**, e.g.: + +``` +InspirationalQuoteGeneratorTool → inspirationalquotegenerator +WordCountTool → wordcount +``` + +That way the key the loader stores **matches** what the LLM will read from the system prompt. + +--- + +### 1. Add a helper + +```ts +function classToActionKey(className: string): string { + return className.replace(/Tool$/, '').toLowerCase(); +} +``` + +--- + +### 2. Use it everywhere you register or expose a tool + +#### a) Loader (`loadExistingDynamicTools`) + +```ts +const actionName = classToActionKey(className); + +if (!this.dynamicToolRegistry.has(actionName)) { + const ToolClass = require(`../tools/${path}`)[className]; + if (ToolClass && ToolClass.prototype instanceof BaseTool) { + const instance = new ToolClass(); + // Tell the prompt generator what name the model must use + (instance as any).name = actionName; + this.dynamicToolRegistry.set(actionName, instance); + console.info(`✓ registered '${actionName}'`); + } +} +``` + +#### b) Create-at-runtime flow (`CreateNewTool`) + +```ts +const actionKey = classToActionKey(toolName); // toolName is the class name +agent.registerDynamicTool(actionKey, newToolInstance); +``` + +#### c) System-prompt generation + +If your `BaseTool` already has a `name` field that `getReactPrompt` reads, you’ve set it above. Otherwise just update the code that builds `allTools`: + +```ts +const allTools = this.getAllTools(); +allTools.forEach(t => { + if (!(t as any).name) (t as any).name = classToActionKey(t.constructor.name); +}); +return getReactPrompt(allTools, docSummaries, chatHistory); +``` + +_(Or be cleaner and extend `BaseTool` with a proper `public name: string`.)_ + +--- + +### 3. (Optionally) normalise existing static tools + +Set their `name` property the same way when you instantiate them: + +```ts +this.tools.calculate = new CalculateTool(); +(this.tools.calculate as any).name = 'calculate'; // already fine, but explicit +``` + +--- + +### 4. Test + +1. Hard-reload / restart dev-server so the new code is bundled. +2. Ask: “Give me an inspirational quote” again. + +Because the prompt now advertises **`inspirationalquotegenerator`** and the registry key matches, validation will pass and the tool will run. + +--- + +## TL;DR + +Your tools are loading; the _keys_ don’t match the action the model outputs. +Create a single `classToActionKey` helper, call it everywhere, and the mismatch disappears. |