diff options
| author | t <t@tjp.lol> | 2026-06-10 10:06:07 -0600 |
|---|---|---|
| committer | t <t@tjp.lol> | 2026-06-10 12:17:27 -0600 |
| commit | bb85e867bc938138f29fb45230169af1ba60761c (patch) | |
| tree | 5ad1cf50274c61ccfffab7048b4a4e28003d82b5 /src/luarocks_runtime.zig | |
| parent | d26890bbc52e9f0050db40f208763a7f2b714ddd (diff) | |
Add addUserText helper; update all call sites
Conversation.addUserMessage now takes a []ContentBlock (symmetric with
addAssistantMessage). Introduce a thin addUserText wrapper in agent.zig
for the plain-text case and update every call site in agent.zig and
anthropic_messages_json.zig accordingly.
Diffstat (limited to 'src/luarocks_runtime.zig')
| -rw-r--r-- | src/luarocks_runtime.zig | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/src/luarocks_runtime.zig b/src/luarocks_runtime.zig index e652096..7f01c19 100644 --- a/src/luarocks_runtime.zig +++ b/src/luarocks_runtime.zig @@ -38,6 +38,7 @@ const panto_home = @import("panto_home.zig"); const embedded_luarocks = @import("embedded_luarocks"); const embedded_lua_headers = @import("embedded_lua_headers"); const embedded_agent = @import("embedded_agent"); +const embedded_panto_so = @import("embedded_panto_so"); const lua_bridge = @import("lua_bridge.zig"); const c = lua_bridge.c; @@ -137,6 +138,7 @@ pub fn bootstrap( try panto_home.ensureDirsExist(layout, io); try stageLuaHeaders(allocator, io, layout); try stageAgentTree(allocator, io, layout); + try stagePantoModule(allocator, io, layout); try stageDefaultConfig(allocator, io, layout); const lua_wrapper_path = try writeLuaWrapper(allocator, io, layout, panto_executable_path); defer allocator.free(lua_wrapper_path); @@ -203,6 +205,33 @@ fn stageLuaHeaders( } // --------------------------------------------------------------------------- +// Stage the embedded native `panto.so` +// --------------------------------------------------------------------------- + +/// Write the binary-embedded `libpanto-lua` shared object to +/// `<tree>/lib/lua/<short>/panto.so`, which is already on `package.cpath` +/// (see `configurePackagePaths`). This guarantees the embedded VM's +/// `require('panto')` resolves to the native agent/stream module on a +/// cold, network-less machine — the module is *ours* and version-locked +/// to this binary's Lua, so unlike luv it cannot be fetched from luarocks. +/// +/// The `.so` leaves `lua_*` undefined and resolves them against the host +/// binary at `dlopen` time, identical to how a luarocks-installed C rock +/// (e.g. luv) works — `exe.rdynamic = true` keeps those symbols findable. +/// +/// Uses the same `writeIfDifferent` discipline as `stageLuaHeaders` so an +/// unchanged `.so` keeps its on-disk mtime across reruns. +fn stagePantoModule( + allocator: Allocator, + io: Io, + layout: panto_home.Layout, +) !void { + var dir = try Io.Dir.cwd().openDir(io, layout.lib_lua_dir, .{}); + defer dir.close(io); + try writeIfDifferent(allocator, io, dir, "panto.so", embedded_panto_so.bytes); +} + +// --------------------------------------------------------------------------- // Stage the embedded `agent/` tree // --------------------------------------------------------------------------- @@ -311,11 +340,20 @@ fn writeIfDifferent( name: []const u8, contents: []const u8, ) !void { - if (dir.readFileAlloc(io, name, allocator, .limited(1 << 22))) |existing| { + // Size the read limit to the new content (plus a small margin) so it + // never truncates the comparison — staged files range from tiny + // headers to a multi-megabyte `panto.so`. A larger on-disk file can't + // match `contents` anyway, so capping at `contents.len + 1` is enough + // to detect inequality without reading unbounded bytes. + const limit = contents.len + 1; + if (dir.readFileAlloc(io, name, allocator, .limited(limit))) |existing| { defer allocator.free(existing); if (std.mem.eql(u8, existing, contents)) return; } else |err| switch (err) { error.FileNotFound => {}, + // A file larger than our limit definitionally differs from + // `contents`; fall through and rewrite. + error.StreamTooLong => {}, else => return err, } try dir.writeFile(io, .{ .sub_path = name, .data = contents }); |
