From 4dc35ec28780d6a78e8afcf2650d4ada4fcd245c Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 16 Jan 2026 20:48:47 +0100 Subject: pkg/aflow: handle common LLM mis-behaviors wrt tool calling Gracefully handle (reply to LLM with error): - incorrect tool name - incorrect tool arg type - missing tool arg Silently handle: - more than one call to set-results - excessive tool args Fixes #6604 --- pkg/aflow/func_tool.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'pkg/aflow/func_tool.go') diff --git a/pkg/aflow/func_tool.go b/pkg/aflow/func_tool.go index cd069db84..48b47b1e5 100644 --- a/pkg/aflow/func_tool.go +++ b/pkg/aflow/func_tool.go @@ -40,11 +40,17 @@ func (t *funcTool[State, Args, Results]) declaration() *genai.FunctionDeclaratio } func (t *funcTool[State, Args, Results]) execute(ctx *Context, args map[string]any) (map[string]any, error) { - state, err := convertFromMap[State](ctx.state, false) + state, err := convertFromMap[State](ctx.state, false, false) if err != nil { return nil, err } - a, err := convertFromMap[Args](args, true) + // We parse args in non-strict mode too. + // LLM shouldn't provide excessive args, but they are known to mess up things + // in all possible ways occasionally. Generally we want to handle such cases + // in some way, rather than fail the whole workflow. We could reply to it + // with an error about this, but it's unclear if the additional round-trip + // worth it, it already provided all the actual arguments. + a, err := convertFromMap[Args](args, false, true) if err != nil { return nil, err } -- cgit mrf-deployment