diff --git a/packages/tools/src/openai/tools.ts b/packages/tools/src/openai/tools.ts index 9655550b..fec1536f 100644 --- a/packages/tools/src/openai/tools.ts +++ b/packages/tools/src/openai/tools.ts @@ -501,8 +501,10 @@ export function createToolCallExecutor( const args = parsed.value // Blank arguments are only valid for tools with no required fields. - const schema = - memoryToolSchemas[functionName as keyof typeof memoryToolSchemas] + // hasOwn so names like "constructor" fall through to the unknown-function error. + const schema = Object.hasOwn(memoryToolSchemas, functionName) + ? memoryToolSchemas[functionName as keyof typeof memoryToolSchemas] + : undefined const missing = schema?.parameters.required.filter( (field: string) => typeof args[field] !== "string" || args[field].trim() === "", diff --git a/packages/tools/src/tool-operations.test.ts b/packages/tools/src/tool-operations.test.ts index ca48d547..d0b46eb1 100644 --- a/packages/tools/src/tool-operations.test.ts +++ b/packages/tools/src/tool-operations.test.ts @@ -404,6 +404,21 @@ describe("openai executeToolCall argument parsing", () => { expect(sdk.add).not.toHaveBeenCalled() }) + it.each([ + "constructor", + "toString", + "__proto__", + ])("reports inherited name %p as an unknown function", async (name) => { + const execute = openAi.createToolCallExecutor(API_KEY) + + const result = JSON.parse(await execute(toolCall(name, "{}"))) + + expect(result).toEqual({ + success: false, + error: `Unknown function: ${name}`, + }) + }) + it("still reports malformed JSON as a tool error", async () => { const execute = openAi.createToolCallExecutor(API_KEY)