From 6e728ab3261200bfec91b5cea188188e31897ea5 Mon Sep 17 00:00:00 2001 From: J S <49557684+svilupp@users.noreply.github.com> Date: Sun, 20 Oct 2024 20:34:54 +0100 Subject: [PATCH] Multi-turn tool fix --- CHANGELOG.md | 5 +++++ Project.toml | 2 +- src/llm_openai.jl | 16 +++++++++++----- test/llm_openai.jl | 14 ++++++++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 605fff54..e28b1a9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +## [0.59.1] + +### Fixed +- Fixed a bug in multi-turn tool calls for OpenAI models where an empty tools array could have been, which causes an API error. + ## [0.59.0] ### Breaking Changes diff --git a/Project.toml b/Project.toml index 3ace6e71..8cef265d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "PromptingTools" uuid = "670122d1-24a8-4d70-bfce-740807c42192" authors = ["J S @svilupp and contributors"] -version = "0.59.0" +version = "0.59.1" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/src/llm_openai.jl b/src/llm_openai.jl index 2b76f121..99f08259 100644 --- a/src/llm_openai.jl +++ b/src/llm_openai.jl @@ -56,11 +56,17 @@ function render(schema::AbstractOpenAISchema, end Dict("role" => role4render(schema, msg), "content" => content) elseif isaitoolrequest(msg) - Dict("role" => role4render(schema, msg), "content" => msg.content, - "tool_calls" => [Dict("id" => tool.tool_call_id, "type" => "function", - "function" => Dict("name" => tool.name, - "arguments" => tool.raw)) - for tool in msg.tool_calls]) + output = Dict{String, Any}( + "role" => role4render(schema, msg), + "content" => msg.content) + if !isempty(msg.tool_calls) + output["tool_calls"] = [Dict("id" => tool.tool_call_id, + "type" => "function", + "function" => Dict("name" => tool.name, + "arguments" => tool.raw)) + for tool in msg.tool_calls] + end + output elseif istoolmessage(msg) content = msg.content isa AbstractString ? msg.content : string(msg.content) Dict("role" => role4render(schema, msg), "content" => content, diff --git a/test/llm_openai.jl b/test/llm_openai.jl index c329538a..4439a1a3 100644 --- a/test/llm_openai.jl +++ b/test/llm_openai.jl @@ -196,6 +196,20 @@ using PromptingTools: pick_tokenizer, OPENAI_TOKEN_IDS_GPT35_GPT4, OPENAI_TOKEN_ ] @test conversation == expected_output + # With empty tools + messages = [ + SystemMessage("System message"), + UserMessage("User message"), + AIToolRequest(;content="content") + ] + conversation = render(schema, messages) + expected_output = Dict{String, Any}[ + Dict("role" => "system", "content" => "System message"), + Dict("role" => "user", "content" => "User message"), + Dict("role" => "assistant", "content" => "content") + ] + @test conversation == expected_output + # With a list of images and detail="low" messages = [ SystemMessage("System message 2"),