diff options
| author | t <t@tjp.lol> | 2026-06-07 14:57:58 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-06-07 14:57:58 -0600 |
| commit | 17a985cb41727b8a1bca4d95f334106c09386040 (patch) | |
| tree | 237a7f1e0d45dafb61ace13f5112ecd31170df4c /libpanto/src/public.zig | |
| parent | 1eddee33902757f7e06993825a3ad1011e7ec346 (diff) | |
Alias Conversation instead of facading it; merge addAssistantMessage
A facade that forwards every method 1:1 is worse than paring the real type
down to the intended surface and aliasing it. conversation.Conversation's
interface is already the public surface we want (init/deinit, the
add*/replace* builders, and messages/allocator as plain data fields), so
public.zig now aliases it straight through and Agent.conversation() returns
a borrowed *Conversation for in-place surgery. Drops the ConversationData
alias and the pointer-wrapper.
Merged addAssistantMessageWithUsage into addAssistantMessage(blocks, ?usage)
on the real type (separate method deleted), so the alias has the intended
one-method shape; all call sites updated.
Only Agent and Stream remain true facades -- they have genuinely-internal
fields plus API-shaping renames (Stream.phase->state, Phase->State) an alias
can't express.
Diffstat (limited to 'libpanto/src/public.zig')
| -rw-r--r-- | libpanto/src/public.zig | 53 |
1 files changed, 13 insertions, 40 deletions
diff --git a/libpanto/src/public.zig b/libpanto/src/public.zig index 56a0676..31d5f7b 100644 --- a/libpanto/src/public.zig +++ b/libpanto/src/public.zig @@ -82,43 +82,14 @@ pub const CompactionSummaryBlock = conversation_mod.CompactionSummaryBlock; pub const Usage = conversation_mod.Usage; pub const effectiveSystemBlocks = conversation_mod.effectiveSystemBlocks; -/// The owned conversation value type. This is what `Session.load` returns -/// and what `Agent.init` adopts. Build one standalone with `init` for +/// The conversation type. Aliased straight through: its interface has been +/// pared down to exactly the public surface (constructors `init`/`deinit`, +/// the `add*`/`replace*` builders, and the `messages`/`allocator` data +/// fields), so no façade is needed. This is what `Session.load` returns, +/// what `Agent.init` adopts, and what `Agent.conversation()` borrows a +/// pointer to (for in-place surgery). Build one standalone with `init` for /// by-hand construction; once handed to an `Agent` it is owned by the agent. -/// For *operating on* an agent's live conversation, use the `Conversation` -/// handle (below) via `Agent.conversation()`. -pub const ConversationData = conversation_mod.Conversation; - -/// A borrowed handle onto a conversation owned by an `Agent`. Pointer- -/// wrapping makes the "don't move the conversation" invariant structural: -/// the handle is a cheap copyable view, minted per-call by -/// `Agent.conversation()`, borrowing state owned by its `Agent`. -pub const Conversation = struct { - inner: *conversation_mod.Conversation, - - /// Read the in-memory messages directly, for context-management surgery. - pub fn messages(self: Conversation) []conversation_mod.Message { - return self.inner.messages.items; - } - pub fn addUserMessage(self: Conversation, text: []const u8) !void { - return self.inner.addUserMessage(text); - } - pub fn addAssistantMessage(self: Conversation, blocks: []const ContentBlock, usage: ?Usage) !void { - if (usage) |u| { - return self.inner.addAssistantMessageWithUsage(blocks, u); - } - return self.inner.addAssistantMessage(blocks); - } - pub fn addSystemMessage(self: Conversation, text: []const u8) !void { - return self.inner.addSystemMessage(text); - } - pub fn replaceSystemMessage(self: Conversation, text: []const u8) !void { - return self.inner.replaceSystemMessage(text); - } - pub fn addCompactionSummary(self: Conversation, text: []const u8) !void { - return self.inner.addCompactionSummary(text); - } -}; +pub const Conversation = conversation_mod.Conversation; // =========================================================================== // Tools (data + small façade) @@ -199,7 +170,7 @@ pub const Agent = struct { io: std.Io, config: *const Config, session: Session, - maybe_conversation: ?ConversationData, + maybe_conversation: ?Conversation, ) !Agent { const inner = try allocator.create(agent_mod.Agent); inner.* = agent_mod.Agent.init(allocator, io, config, session, maybe_conversation); @@ -246,9 +217,11 @@ pub const Agent = struct { return self.inner.compactAndPersist(override_system_prompt, extra); } - /// A borrowed handle onto the agent's live conversation. - pub fn conversation(self: Agent) Conversation { - return .{ .inner = &self.inner.conversation }; + /// A borrowed pointer to the agent's live conversation, for in-place + /// context-management surgery. Valid for the agent's lifetime; do not + /// retain past it. + pub fn conversation(self: Agent) *Conversation { + return &self.inner.conversation; } /// The id of the session this agent appends to. |
