Skip to content

Commit 25e6327

Browse files
committed
Fix off-by-one in mapper scan_end that dropped user messages after text-only assistant responses
1 parent 5e85ee6 commit 25e6327

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

src/llm/src/openai/mapper.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ function openai_mapper.map_messages(contract_messages, options)
176176
-- The prompt builder interleaves them: call_A, result_A, call_B, result_B
177177
local function_calls_found = {}
178178
local function_results_found = {}
179-
local scan_end = i
179+
local scan_end = i - 1
180180
local j = i
181181
while j <= #contract_messages do
182182
local current_msg = contract_messages[j]

src/llm/src/openai/mapper_test.lua

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,53 @@ local function define_tests()
316316
test.eq(openai_messages[4].role, "user")
317317
end)
318318

319+
it("should preserve user messages after assistant without tool calls", function()
320+
local contract_messages = {
321+
{
322+
role = "user",
323+
content = {{ type = "text", text = "Do you see this file?" }}
324+
},
325+
{
326+
role = "assistant",
327+
content = {{ type = "text", text = "Yes, I see the file." }}
328+
},
329+
{
330+
role = "user",
331+
content = {{ type = "text", text = "Build me a data model" }}
332+
},
333+
{
334+
role = "assistant",
335+
content = {{ type = "text", text = "Sure, here is the model." }}
336+
},
337+
{
338+
role = "user",
339+
content = {{ type = "text", text = "Use your tools" }}
340+
}
341+
}
342+
343+
local openai_messages = openai_mapper.map_messages(contract_messages)
344+
345+
test.eq(#openai_messages, 5)
346+
347+
test.eq(openai_messages[1].role, "user")
348+
local u1 = openai_messages[1].content :: any
349+
test.eq(u1[1].text, "Do you see this file?")
350+
351+
test.eq(openai_messages[2].role, "assistant")
352+
test.eq(openai_messages[2].content, "Yes, I see the file.")
353+
354+
test.eq(openai_messages[3].role, "user")
355+
local u2 = openai_messages[3].content :: any
356+
test.eq(u2[1].text, "Build me a data model")
357+
358+
test.eq(openai_messages[4].role, "assistant")
359+
test.eq(openai_messages[4].content, "Sure, here is the model.")
360+
361+
test.eq(openai_messages[5].role, "user")
362+
local u3 = openai_messages[5].content :: any
363+
test.eq(u3[1].text, "Use your tools")
364+
end)
365+
319366
it("should skip function_call messages without id", function()
320367
local contract_messages = {
321368
{

0 commit comments

Comments
 (0)