From eb4179f9958deeae408a0a06b1f8ae6437e089db Mon Sep 17 00:00:00 2001 From: t Date: Sun, 7 Jun 2026 15:19:57 -0600 Subject: Sync Agent/Stream internals to public names; alias Stream Push the API-shaping we'd done in the public facade down into the internal types, collapsing the wrappers: - Stream: rename phase->state, Phase->State; underscore-prefix the internal fields (_agent/_queue/_response/_start/_persisted/_pending_error). state is the one intended-public field. public.zig now aliases Stream; run returns *Stream. - Agent compaction: pure transform compact()->private _compactInPlace; compactAndPersist()->compact() (the public name, persists). - Agent system prompt: addSystemMessage(text,mode) split into addSystemMessage(text) + setSystemPrompt(text) over a private _persistSystemMessage. - UserMessage moved off Agent to module scope. - Underscore-prefix pure-internal Agent fields: _open_stream_fn, _auto_compacted, _retry_prng. The Agent facade is now pure 1:1 forwarders; it stays a wrapper only because init heap-pins the inner (copyable, move-safe handle) and conversation()/ sessionId() are accessors. Conversation and Stream are plain aliases. --- libpanto/src/public.zig | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) (limited to 'libpanto/src/public.zig') diff --git a/libpanto/src/public.zig b/libpanto/src/public.zig index 31d5f7b..8a6fcd1 100644 --- a/libpanto/src/public.zig +++ b/libpanto/src/public.zig @@ -127,32 +127,24 @@ pub const Event = stream_mod.Event; pub const ContentBlockType = provider_mod.ContentBlockType; pub const ProviderRetryInfo = provider_mod.ProviderRetryInfo; -/// The transparent turn state machine, renamed from the internal `Phase`. -pub const State = agent_mod.Stream.Phase; - -pub const Stream = struct { - inner: *agent_mod.Stream, - - /// `!?Event`: a value is progress (including the terminal event), `null` - /// is exhaustion, an error is a genuine failure. - pub fn next(self: Stream) !?Event { - return self.inner.next(); - } - pub fn deinit(self: Stream) void { - // The internal `Stream.deinit` persists the turn tail and frees its - // own heap allocation. - self.inner.deinit(); - } - pub fn state(self: Stream) State { - return self.inner.phase; - } -}; +/// The pull event stream for one turn. Aliased straight through: its public +/// surface is exactly `next`/`deinit` plus the transparent `state` field +/// (`State`); every other field is underscore-prefixed internal state. +/// `Agent.run` returns a `*Stream` (heap-pinned); the caller owns it and +/// must `deinit` it (which persists the turn tail and frees the allocation). +/// +/// `next()` returns `!?Event`: a value is progress (including the terminal +/// event), `null` is exhaustion, an error is a genuine failure. +pub const Stream = agent_mod.Stream; + +/// The transparent turn state machine (`Stream.state`). +pub const State = agent_mod.Stream.State; // =========================================================================== // Agent (behavioral, pointer-wrapped) // =========================================================================== -pub const UserMessage = struct { text: []const u8 }; +pub const UserMessage = agent_mod.UserMessage; pub const CompactionResult = agent_mod.Agent.CompactionResult; pub const Agent = struct { @@ -192,20 +184,22 @@ pub const Agent = struct { pub fn setConfig(self: Agent, cfg: *const Config) void { self.inner.setConfig(cfg); } - pub fn run(self: Agent, message: UserMessage) !Stream { - return .{ .inner = try self.inner.run(.{ .text = message.text }) }; + /// Submit a user message and begin a turn, returning a heap-pinned + /// `*Stream` the caller owns and must `deinit`. + pub fn run(self: Agent, message: UserMessage) !*Stream { + return self.inner.run(message); } /// Append a system message to the conversation and persist it (the /// `.append` `SystemMode`: it adds to the effective prompt). pub fn addSystemMessage(self: Agent, text: []const u8) !void { - return self.inner.addSystemMessage(text, .append); + return self.inner.addSystemMessage(text); } /// Replace the effective system prompt and persist it (the `.replace` /// `SystemMode`: it discards all prior system text). On replay the log /// reconstructs the same effective prompt. pub fn setSystemPrompt(self: Agent, text: []const u8) !void { - return self.inner.addSystemMessage(text, .replace); + return self.inner.setSystemPrompt(text); } /// Compact and persist (the explicit `/compact` entry point). @@ -214,7 +208,7 @@ pub const Agent = struct { /// to the compaction prompt for this run (the `/compact $ARGUMENTS` /// path). pub fn compact(self: Agent, override_system_prompt: ?[]const u8, extra: ?[]const u8) !CompactionResult { - return self.inner.compactAndPersist(override_system_prompt, extra); + return self.inner.compact(override_system_prompt, extra); } /// A borrowed pointer to the agent's live conversation, for in-place -- cgit v1.3