summaryrefslogtreecommitdiff
path: root/libpanto/src/provider_openai_chat.zig
diff options
context:
space:
mode:
Diffstat (limited to 'libpanto/src/provider_openai_chat.zig')
-rw-r--r--libpanto/src/provider_openai_chat.zig30
1 files changed, 20 insertions, 10 deletions
diff --git a/libpanto/src/provider_openai_chat.zig b/libpanto/src/provider_openai_chat.zig
index ed646e8..8319d9d 100644
--- a/libpanto/src/provider_openai_chat.zig
+++ b/libpanto/src/provider_openai_chat.zig
@@ -794,6 +794,16 @@ const EventRecorder = struct {
}
};
+/// Test helper: append a single-text user message. `addUserMessage` now
+/// takes a block slice (symmetric with `addAssistantMessage`); this wraps
+/// the common plain-text case the tests below use.
+fn addUserText(conv: *conversation.Conversation, text: []const u8) !void {
+ const tb = try conversation.textualBlockFromSlice(conv.allocator, text);
+ var block: conversation.ContentBlock = .{ .Text = tb };
+ errdefer block.deinit(conv.allocator);
+ try conv.addUserMessage(&.{block});
+}
+
test "two streamed turns persist assistant replies in the conversation" {
// Regression test for the bug where `finish_reason` arrived before
// `[DONE]` and `finalize` early-returned without appending the assistant
@@ -805,7 +815,7 @@ test "two streamed turns persist assistant replies in the conversation" {
defer conv.deinit();
try conv.addSystemMessage("You are a helpful assistant.");
- try conv.addUserMessage("hello!");
+ try addUserText(&conv, "hello!");
const turn1 = [_][]const u8{
\\{"choices":[{"delta":{"role":"assistant"}}]}
@@ -828,7 +838,7 @@ test "two streamed turns persist assistant replies in the conversation" {
);
// Second user turn: the assistant must still see its prior response.
- try conv.addUserMessage("how did you respond to my greeting just now?");
+ try addUserText(&conv, "how did you respond to my greeting just now?");
const turn2 = [_][]const u8{
\\{"choices":[{"delta":{"role":"assistant"}}]}
@@ -855,7 +865,7 @@ test "openai_chat: terminating usage chunk lands on message_complete with split
var conv = conversation.Conversation.init(allocator);
defer conv.deinit();
- try conv.addUserMessage("hi");
+ try addUserText(&conv, "hi");
var rec = EventRecorder{ .allocator = allocator };
defer rec.deinit();
@@ -888,7 +898,7 @@ test "openai_chat: omitted stream usage yields null on message_complete" {
var conv = conversation.Conversation.init(allocator);
defer conv.deinit();
- try conv.addUserMessage("hi");
+ try addUserText(&conv, "hi");
var rec = EventRecorder{ .allocator = allocator };
defer rec.deinit();
@@ -921,7 +931,7 @@ test "fragmented tool_call id and name are reassembled" {
var conv = conversation.Conversation.init(allocator);
defer conv.deinit();
- try conv.addUserMessage("call something");
+ try addUserText(&conv, "call something");
const events = [_][]const u8{
\\{"choices":[{"delta":{"role":"assistant"}}]}
@@ -956,7 +966,7 @@ test "inbound wire tool name is decoded to dotted form (even split across __)" {
var conv = conversation.Conversation.init(allocator);
defer conv.deinit();
- try conv.addUserMessage("read a file");
+ try addUserText(&conv, "read a file");
const events = [_][]const u8{
\\{"choices":[{"delta":{"role":"assistant"}}]}
@@ -991,7 +1001,7 @@ test "parallel tool_calls emit one complete start/delta/complete cycle per block
var conv = conversation.Conversation.init(allocator);
defer conv.deinit();
- try conv.addUserMessage("ping four hosts");
+ try addUserText(&conv, "ping four hosts");
var rec: EventRecorder = .{ .allocator = allocator };
defer rec.deinit();
@@ -1057,7 +1067,7 @@ test "non-contiguous tool_call deltas: re-emission of a closed index is dropped"
var conv = conversation.Conversation.init(allocator);
defer conv.deinit();
- try conv.addUserMessage("go");
+ try addUserText(&conv, "go");
var rec: EventRecorder = .{ .allocator = allocator };
defer rec.deinit();
@@ -1105,7 +1115,7 @@ test "onToolDetails fires after id+name complete, even mid-arg-stream" {
var conv = conversation.Conversation.init(allocator);
defer conv.deinit();
- try conv.addUserMessage("go");
+ try addUserText(&conv, "go");
var rec: EventRecorder = .{ .allocator = allocator };
defer rec.deinit();
@@ -1171,7 +1181,7 @@ test "tool_call with no arguments still finalizes a well-formed ToolUse" {
var conv = conversation.Conversation.init(allocator);
defer conv.deinit();
- try conv.addUserMessage("ring it");
+ try addUserText(&conv, "ring it");
const events = [_][]const u8{
\\{"choices":[{"delta":{"role":"assistant"}}]}