summaryrefslogtreecommitdiff
path: root/libpanto/src/public.zig
diff options
context:
space:
mode:
Diffstat (limited to 'libpanto/src/public.zig')
-rw-r--r--libpanto/src/public.zig140
1 files changed, 36 insertions, 104 deletions
diff --git a/libpanto/src/public.zig b/libpanto/src/public.zig
index 8a6fcd1..5488220 100644
--- a/libpanto/src/public.zig
+++ b/libpanto/src/public.zig
@@ -12,14 +12,19 @@
//! 2. Construct & operate on conversations — build a `Conversation` by
//! hand, do context-management surgery.
//!
-//! Three façade buckets:
-//! - **behavioral** (`Agent`, `Stream`, `Conversation`): wrap a pointer to
-//! a heap-pinned internal, exposing only the chosen methods.
+//! Every name here is a straight alias of an internal decl: the internal
+//! types have been shaped to *be* the public API (public methods + a
+//! transparent public field or two, every other field underscore-prefixed
+//! internal state), so this file selects the surface rather than wrapping
+//! it. Three buckets:
+//! - **behavioral** (`Agent`, `Stream`, `Conversation`): heap-pinned
+//! drivers whose `init` hands back a cheap, movable pointer; the chosen
+//! methods plus a transparent field (`Agent.conversation`,
+//! `Stream.state`) are the surface.
//! - **data (read/output)** (`Event`, `Usage`, `Pricing`, `SessionInfo`):
-//! aliased straight through; inspected field-by-field.
+//! inspected field-by-field.
//! - **data (constructed)** (`ContentBlock`, `Message`, the block types,
-//! the `Config` family): aliased straight through; Zig users build them
-//! with `ArrayList` directly.
+//! the `Config` family): Zig users build them with `ArrayList` directly.
const std = @import("std");
@@ -92,7 +97,7 @@ pub const effectiveSystemBlocks = conversation_mod.effectiveSystemBlocks;
pub const Conversation = conversation_mod.Conversation;
// ===========================================================================
-// Tools (data + small façade)
+// Tools (data, aliased)
// ===========================================================================
pub const Tool = tool_mod.Tool;
@@ -103,24 +108,13 @@ pub const ToolCallResult = tool_source_mod.CallResult;
pub const MediaPart = tool_mod.MediaPart;
pub const ResultPart = tool_mod.ResultPart;
-/// Result-part ergonomics: a thin struct wrapper around `[]ResultPart`
-/// (a bare alias can't carry methods).
-pub const ResultParts = struct {
- items: []ResultPart,
-
- pub fn fromText(alloc: std.mem.Allocator, text: []const u8) !ResultParts {
- return .{ .items = try tool_mod.textResult(alloc, text) };
- }
- pub fn fromTextOwned(alloc: std.mem.Allocator, text: []u8) !ResultParts {
- return .{ .items = try tool_mod.ownedTextResult(alloc, text) };
- }
- pub fn deinit(self: ResultParts, alloc: std.mem.Allocator) void {
- tool_mod.freeResultParts(alloc, self.items);
- }
-};
+/// Result-part ergonomics: a thin wrapper around `[]ResultPart` carrying
+/// the `fromText`/`fromTextOwned` constructors and `deinit`. Aliased
+/// straight through.
+pub const ResultParts = tool_mod.ResultParts;
// ===========================================================================
-// Stream (behavioral, pointer-wrapped)
+// Stream (behavioral, heap-pinned)
// ===========================================================================
pub const Event = stream_mod.Event;
@@ -137,92 +131,30 @@ pub const ProviderRetryInfo = provider_mod.ProviderRetryInfo;
/// 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)
+// Agent (behavioral, heap-pinned)
// ===========================================================================
pub const UserMessage = agent_mod.UserMessage;
-pub const CompactionResult = agent_mod.Agent.CompactionResult;
-
-pub const Agent = struct {
- inner: *agent_mod.Agent,
-
- /// Construct an agent. The inner is heap-pinned at `init`, so the
- /// returned `Agent` is a cheap copyable handle ("don't move the Agent"
- /// stops being a rule anyone can violate). `session` is minted via
- /// `store.create()` (fresh) or `resolve`/`latest` (resume). When
- /// `maybe_conversation` is non-null it is adopted (ownership
- /// transferred) — the resume path hands the value returned by
- /// `Session.load`.
- pub fn init(
- allocator: std.mem.Allocator,
- io: std.Io,
- config: *const Config,
- session: Session,
- maybe_conversation: ?Conversation,
- ) !Agent {
- const inner = try allocator.create(agent_mod.Agent);
- inner.* = agent_mod.Agent.init(allocator, io, config, session, maybe_conversation);
- return .{ .inner = inner };
- }
-
- pub fn deinit(self: Agent) void {
- const allocator = self.inner.allocator;
- self.inner.deinit();
- allocator.destroy(self.inner);
- }
-
- pub fn registerTool(self: Agent, t: Tool) !void {
- return self.inner.registerTool(t);
- }
- pub fn registerToolSource(self: Agent, src: ToolSource) !void {
- return self.inner.registerToolSource(src);
- }
- pub fn setConfig(self: Agent, cfg: *const Config) void {
- self.inner.setConfig(cfg);
- }
- /// 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);
- }
+pub const CompactionResult = agent_mod.CompactionResult;
- /// 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);
- }
- /// 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.setSystemPrompt(text);
- }
-
- /// Compact and persist (the explicit `/compact` entry point).
- /// `override_system_prompt` falls back to
- /// `config.compaction.compaction_prompt` when null. `extra` is appended
- /// 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.compact(override_system_prompt, extra);
- }
-
- /// 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.
- pub fn sessionId(self: Agent) []const u8 {
- return self.inner.session.info.id;
- }
-};
+/// The agent loop driver. Aliased straight through: its public surface is
+/// exactly the chosen methods (`init`/`deinit`, `registerTool`,
+/// `registerToolSource`, `setConfig`, `run`, `addSystemMessage`,
+/// `setSystemPrompt`, `compact`, `sessionId`) plus the transparent
+/// `conversation` field; every other field is underscore-prefixed internal
+/// state.
+///
+/// `init` heap-pins the agent and returns a `*Agent` — a cheap, movable
+/// handle out of the gate ("don't move the Agent" stops being a rule anyone
+/// can violate). The caller owns it and must `deinit` it. `session` is
+/// minted via `store.create()` (fresh) or `resolve`/`latest` (resume); when
+/// `maybe_conversation` is non-null it is adopted (ownership transferred) —
+/// the resume path hands the value returned by `Session.load`.
+///
+/// Operate on the live conversation in place via the `conversation` field
+/// (valid for the agent's lifetime; do not retain past it).
+pub const Agent = agent_mod.Agent;
// ===========================================================================
// Pricing (data, aliased)