summaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig58
1 files changed, 37 insertions, 21 deletions
diff --git a/src/main.zig b/src/main.zig
index aaf86b5..20686eb 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -11,6 +11,7 @@ const session_paths = @import("session_paths.zig");
const models_toml = @import("models_toml.zig");
const config_file = @import("config_file.zig");
const glob = @import("glob.zig");
+const system_prompt = @import("system_prompt.zig");
// Shorthand alias for the Lua C API. The bridge module owns the actual
// `@cImport`; we re-use it here so the smoke check uses identical types.
@@ -37,6 +38,7 @@ test {
_ = models_toml;
_ = config_file;
_ = glob;
+ _ = system_prompt;
}
const Receiver = panto.provider.Receiver;
@@ -363,20 +365,18 @@ pub fn main(init: std.process.Init) !void {
var conv = panto.conversation.Conversation.init(alloc);
defer conv.deinit();
- if (session_mgr.getEntries().len > 0) {
+ const is_resume = session_mgr.getEntries().len > 0;
+ if (is_resume) {
// Resumed an existing session — rebuild the conversation from the
- // log. The system prompt is part of the log.
+ // log. The system prompt is part of the log. (Reconciliation
+ // against the on-disk SYSTEM.md happens after the agent tree is
+ // staged, below.)
conv.deinit();
conv = try session_mgr.rebuildConversation();
try stdout.print(
"resumed session {s} ({d} entries)\n",
.{ session_mgr.getSessionId()[0..@min(8, session_mgr.getSessionId().len)], session_mgr.getEntries().len },
);
- } else {
- // Fresh session — install the default system prompt and record it.
- const system_text = "You are a helpful assistant.";
- try conv.addSystemMessage(system_text);
- try appendSystemToSession(alloc, &session_mgr, system_text);
}
// The tool registry is owned here and referenced by the active config
@@ -405,6 +405,36 @@ pub fn main(init: std.process.Init) !void {
);
defer luarocks_rt.deinit();
+ // Source the system prompt now that the base agent tree has been
+ // staged to `$PANTO_HOME/agent` (the bootstrap above writes the
+ // bundled `SYSTEM.md` there). The prompt is sourced by convention
+ // from SYSTEM.md / APPEND_SYSTEM.md across the base/user/project
+ // layers; the base layer is `luarocks_rt.layout.agent_dir`.
+ var sp_arena = std.heap.ArenaAllocator.init(alloc);
+ defer sp_arena.deinit();
+ if (is_resume) {
+ // SYSTEM.md / APPEND_SYSTEM.md may have changed since this log was
+ // created; reconcile without rewriting history.
+ try system_prompt.reconcileResume(
+ sp_arena.allocator(),
+ io,
+ init.environ_map,
+ luarocks_rt.layout.agent_dir,
+ &conv,
+ &session_mgr,
+ );
+ } else {
+ // Fresh session — source and install the system prompt.
+ try system_prompt.seedFresh(
+ sp_arena.allocator(),
+ io,
+ init.environ_map,
+ luarocks_rt.layout.agent_dir,
+ &conv,
+ &session_mgr,
+ );
+ }
+
// luv is installed (or already present) at this point; wire the
// libuv-driven coroutine scheduler before any extensions get a
// chance to register tools that might want to yield.
@@ -637,20 +667,6 @@ fn openSession(
// Session append helpers — bridge in-memory ContentBlocks to on-disk entries.
// -----------------------------------------------------------------------------
-fn appendSystemToSession(
- alloc: std.mem.Allocator,
- mgr: *panto.session_manager.SessionManager,
- text: []const u8,
-) !void {
- const blocks = try alloc.alloc(panto.session_manager.DiskContentBlock, 1);
- blocks[0] = .{ .text = .{ .text = try alloc.dupe(u8, text) } };
- _ = try mgr.appendMessage(
- .{ .role = .system, .content = blocks },
- null,
- null,
- );
-}
-
fn appendUserPromptToSession(
alloc: std.mem.Allocator,
mgr: *panto.session_manager.SessionManager,