From bb85e867bc938138f29fb45230169af1ba60761c Mon Sep 17 00:00:00 2001 From: t Date: Wed, 10 Jun 2026 10:06:07 -0600 Subject: Add addUserText helper; update all call sites Conversation.addUserMessage now takes a []ContentBlock (symmetric with addAssistantMessage). Introduce a thin addUserText wrapper in agent.zig for the plain-text case and update every call site in agent.zig and anthropic_messages_json.zig accordingly. --- libpanto/src/anthropic_messages_json.zig | 36 ++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'libpanto/src/anthropic_messages_json.zig') diff --git a/libpanto/src/anthropic_messages_json.zig b/libpanto/src/anthropic_messages_json.zig index 78f4b5f..3ad6069 100644 --- a/libpanto/src/anthropic_messages_json.zig +++ b/libpanto/src/anthropic_messages_json.zig @@ -606,6 +606,16 @@ fn testConfig(model: []const u8) config_mod.AnthropicMessagesConfig { }; } +/// 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 "serializeRequest - system extracted into top-level field" { const allocator = testing.allocator; @@ -613,7 +623,7 @@ test "serializeRequest - system extracted into top-level field" { defer conv.deinit(); try conv.addSystemMessage("You are helpful."); - try conv.addUserMessage("Hello!"); + try addUserText(&conv, "Hello!"); const cfg = testConfig("claude-sonnet-4-20250514"); var empty_tools = tool_registry_mod.ToolRegistry.init(allocator); @@ -650,7 +660,7 @@ test "serializeRequest - multiple system messages joined with horizontal rule" { try conv.addSystemMessage("Be terse."); try conv.addSystemMessage("Be accurate."); - try conv.addUserMessage("Hi"); + try addUserText(&conv, "Hi"); const cfg = testConfig("claude-x"); var empty_tools = tool_registry_mod.ToolRegistry.init(allocator); @@ -676,7 +686,7 @@ test "serializeRequest - replace-mode system block wipes prior system text" { try conv.addSystemMessage("original append"); try conv.replaceSystemMessage("fresh seed"); try conv.addSystemMessage("fresh append"); - try conv.addUserMessage("Hi"); + try addUserText(&conv, "Hi"); const cfg = testConfig("claude-x"); var empty_tools = tool_registry_mod.ToolRegistry.init(allocator); @@ -700,7 +710,7 @@ test "serializeRequest - trailing newlines stripped before the rule join" { try conv.addSystemMessage("line one\n\n"); try conv.addSystemMessage("line two\n"); - try conv.addUserMessage("Hi"); + try addUserText(&conv, "Hi"); const cfg = testConfig("claude-x"); var empty_tools = tool_registry_mod.ToolRegistry.init(allocator); @@ -721,7 +731,7 @@ test "serializeRequest - no system messages omits the system field" { var conv = conversation.Conversation.init(allocator); defer conv.deinit(); - try conv.addUserMessage("Hi"); + try addUserText(&conv, "Hi"); const cfg = testConfig("claude-x"); var empty_tools = tool_registry_mod.ToolRegistry.init(allocator); @@ -966,7 +976,7 @@ test "serializeRequest - emits tools array when registry non-empty" { var conv = conversation.Conversation.init(allocator); defer conv.deinit(); - try conv.addUserMessage("call something"); + try addUserText(&conv, "call something"); var tools = tool_registry_mod.ToolRegistry.init(allocator); defer tools.deinit(); @@ -1173,7 +1183,7 @@ test "serializeRequest - thinking disabled omits thinking and effort fields" { const allocator = testing.allocator; var conv = conversation.Conversation.init(allocator); defer conv.deinit(); - try conv.addUserMessage("hi"); + try addUserText(&conv, "hi"); var cfg = testConfig("claude-x"); cfg.thinking = .disabled; @@ -1193,7 +1203,7 @@ test "serializeRequest - thinking enabled explicit budget" { const allocator = testing.allocator; var conv = conversation.Conversation.init(allocator); defer conv.deinit(); - try conv.addUserMessage("hi"); + try addUserText(&conv, "hi"); var cfg = testConfig("claude-x"); // max_tokens = 1024 cfg.thinking = .enabled; @@ -1217,7 +1227,7 @@ test "serializeRequest - thinking enabled null budget falls back to max_tokens - const allocator = testing.allocator; var conv = conversation.Conversation.init(allocator); defer conv.deinit(); - try conv.addUserMessage("hi"); + try addUserText(&conv, "hi"); var cfg = testConfig("claude-x"); // max_tokens = 1024 cfg.thinking = .enabled; @@ -1237,7 +1247,7 @@ test "serializeRequest - thinking enabled budget clamped when >= max_tokens" { const allocator = testing.allocator; var conv = conversation.Conversation.init(allocator); defer conv.deinit(); - try conv.addUserMessage("hi"); + try addUserText(&conv, "hi"); var cfg = testConfig("claude-x"); // max_tokens = 1024 cfg.thinking = .enabled; @@ -1258,7 +1268,7 @@ test "serializeRequest - thinking adaptive default effort" { const allocator = testing.allocator; var conv = conversation.Conversation.init(allocator); defer conv.deinit(); - try conv.addUserMessage("hi"); + try addUserText(&conv, "hi"); var cfg = testConfig("claude-x"); cfg.thinking = .adaptive; @@ -1290,7 +1300,7 @@ test "serializeRequest - thinking adaptive explicit effort levels" { for (efforts) |entry| { var conv = conversation.Conversation.init(allocator); defer conv.deinit(); - try conv.addUserMessage("hi"); + try addUserText(&conv, "hi"); var cfg = testConfig("claude-x"); cfg.thinking = .adaptive; @@ -1310,7 +1320,7 @@ test "serializeRequest - thinking adaptive ignores budget_tokens" { const allocator = testing.allocator; var conv = conversation.Conversation.init(allocator); defer conv.deinit(); - try conv.addUserMessage("hi"); + try addUserText(&conv, "hi"); var cfg = testConfig("claude-x"); cfg.thinking = .adaptive; -- cgit v1.3