From 7c2d8825660f73198149c0b2ce26166b16ba3532 Mon Sep 17 00:00:00 2001 From: t Date: Thu, 18 Jun 2026 13:38:32 -0600 Subject: Preserve content blocks and thinking origin in C store append Round-trip persistent message content through the C session store bridge instead of dropping it, including tool-use, tool-result, system, and thinking blocks. Reconstruct borrowed C content blocks with arena-backed helpers, carry message identity fields like API style/model/reasoning, and add tests covering append marshalling and thinking signature origin round-tripping. --- libpanto/src/conversation.zig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'libpanto/src/conversation.zig') diff --git a/libpanto/src/conversation.zig b/libpanto/src/conversation.zig index 760f3ee..4338563 100644 --- a/libpanto/src/conversation.zig +++ b/libpanto/src/conversation.zig @@ -370,6 +370,24 @@ pub const Conversation = struct { }); } + /// Append a message of any role from a slice of content blocks, with + /// optional usage. The general form behind `addUserMessage` / + /// `addAssistantMessage`; used to rebuild a persisted message (tool calls, + /// thinking, mixed blocks) losslessly. Ownership of the blocks transfers + /// to the conversation; the caller must not deinit them after this call. + pub fn addMessage(self: *Conversation, role: MessageRole, blocks: []const ContentBlock, usage: ?Usage) !void { + var content: std.ArrayList(ContentBlock) = .empty; + try content.ensureTotalCapacity(self.allocator, blocks.len); + for (blocks) |block| { + content.appendAssumeCapacity(block); + } + try self.messages.append(self.allocator, .{ + .role = role, + .content = content, + .usage = usage, + }); + } + pub fn deinit(self: *Conversation) void { for (self.messages.items) |*msg| { msg.deinit(self.allocator); -- cgit v1.3