From bb85e867bc938138f29fb45230169af1ba60761c Mon Sep 17 00:00:00 2001 From: t Date: Wed, 10 Jun 2026 10:06:07 -0600 Subject: 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. --- libpanto-lua/build.zig | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 libpanto-lua/build.zig (limited to 'libpanto-lua/build.zig') diff --git a/libpanto-lua/build.zig b/libpanto-lua/build.zig new file mode 100644 index 0000000..8bfaf88 --- /dev/null +++ b/libpanto-lua/build.zig @@ -0,0 +1,143 @@ +const std = @import("std"); + +/// `libpanto-lua` — a native Lua 5.4 C-module implemented in pure Zig. +/// +/// Emits a loadable `panto.so` (no `lib` prefix) exporting `luaopen_panto`, +/// discovered on `package.cpath` and loaded by `require('panto')`. The +/// module `@cImport`s the Lua 5.4 headers and calls the Zig `libpanto` API +/// directly — no C translation units in this package, no dependency on +/// `libpanto-c`. +/// +/// Targets Lua 5.4 only (see `docs/libpanto-bindings.md`). A Lua C-module +/// does not link the Lua library: the host interpreter supplies every +/// `lua_*` symbol at load time, so we link only against the headers and +/// resolve the symbols via dynamic lookup at runtime. +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const panto_dep = b.dependency("panto", .{ + .target = target, + .optimize = optimize, + }); + const lua_src = b.dependency("lua_src", .{}); + + const mod = b.createModule(.{ + .root_source_file = b.path("src/module.zig"), + .target = target, + .optimize = optimize, + .link_libc = true, + }); + mod.addImport("panto", panto_dep.module("panto")); + // Lua headers for `@cImport`. Headers only — see the note above. + mod.addIncludePath(lua_src.path("src")); + + const lib = b.addLibrary(.{ + .name = "panto", + .root_module = mod, + .linkage = .dynamic, + }); + // Lua modules export a fixed-name init function; keep it in the + // dynamic symbol table so the host's `require` can find it. + lib.rdynamic = true; + // The `lua_*` / `luaL_*` symbols are provided by the host + // interpreter at `dlopen` time, not by this module. Allow them to be + // left undefined at link time and resolved dynamically when loaded. + allowUndefinedHostSymbols(lib, target); + + // Register the Compile step as a named artifact so dependents (the + // panto CLI build) can address it via `dep.artifact("panto")` to embed + // the compiled `.so`. This installs `libpanto.so`/`libpanto.dylib` + // under the default `lib/` name; the bare-name staging below produces + // the `panto.so` a Lua `require` needs. + b.installArtifact(lib); + + // A Lua C-module must be named exactly `panto.so` (no `lib` prefix, + // no version suffix) to be found as `require('panto')` on `cpath`. + // `addLibrary` produces `libpanto.so` (or `.dylib`); install it under + // the bare module name into `lib/`. + const install_so = b.addInstallFileWithDir( + lib.getEmittedBin(), + .lib, + "panto.so", + ); + b.getInstallStep().dependOn(&install_so.step); + + // Unit tests. The test binary is an ordinary executable that links a + // real Lua so the C symbols resolve; we compile the Lua sources into + // it directly (see `addLuaForTests`). + const test_mod = b.createModule(.{ + .root_source_file = b.path("src/module.zig"), + .target = target, + .optimize = optimize, + .link_libc = true, + }); + test_mod.addImport("panto", panto_dep.module("panto")); + test_mod.addIncludePath(lua_src.path("src")); + addLuaForTests(test_mod, lua_src); + + const unit_tests = b.addTest(.{ + .name = "panto-lua-tests", + .root_module = test_mod, + }); + const run_unit_tests = b.addRunArtifact(unit_tests); + const test_step = b.step("test", "Run unit tests"); + test_step.dependOn(&run_unit_tests.step); +} + +/// On macOS the linker rejects undefined symbols by default; a Lua +/// C-module relies on the host interpreter to provide every `lua_*` +/// symbol at `dlopen` time. Pass the flag that defers resolution to load +/// time. On ELF (Linux/BSD) shared objects already allow undefined +/// symbols resolved by the loader, so nothing is needed. +fn allowUndefinedHostSymbols( + lib: *std.Build.Step.Compile, + target: std.Build.ResolvedTarget, +) void { + switch (target.result.os.tag) { + .macos => { + lib.linker_allow_shlib_undefined = true; + lib.root_module.addCMacro("LUA_USE_MACOSX", ""); + }, + .linux => lib.root_module.addCMacro("LUA_USE_LINUX", ""), + .freebsd, .netbsd, .openbsd => lib.root_module.addCMacro("LUA_USE_POSIX", ""), + else => {}, + } +} + +/// The Lua source files needed to compile a self-contained Lua into the +/// test binary so the `lua_*` symbols resolve (the standalone `.so` +/// borrows them from a host instead). This is the same `core + lib + aux` +/// set the CLI compiles, minus `lua.c`/`luac.c` (the standalone front +/// ends, which carry their own `main`). +const lua_files = [_][]const u8{ + // core + "lapi.c", "lcode.c", "lctype.c", "ldebug.c", "ldo.c", + "ldump.c", "lfunc.c", "lgc.c", "llex.c", "lmem.c", + "lobject.c", "lopcodes.c", "lparser.c", "lstate.c", "lstring.c", + "ltable.c", "ltm.c", "lundump.c", "lvm.c", "lzio.c", + // lib + "lauxlib.c", "lbaselib.c", "lcorolib.c", "ldblib.c", "liolib.c", + "lmathlib.c", "loadlib.c", "loslib.c", "lstrlib.c", "ltablib.c", + "lutf8lib.c", "linit.c", +}; + +fn addLuaForTests(mod: *std.Build.Module, lua_src: *std.Build.Dependency) void { + const cflags = [_][]const u8{ + "-std=gnu99", + "-Wall", + "-Wextra", + "-Wno-unused-parameter", + }; + mod.addCSourceFiles(.{ + .root = lua_src.path("src"), + .files = &lua_files, + .flags = &cflags, + }); + switch (mod.resolved_target.?.result.os.tag) { + .macos => mod.addCMacro("LUA_USE_MACOSX", ""), + .linux => mod.addCMacro("LUA_USE_LINUX", ""), + .freebsd, .netbsd, .openbsd => mod.addCMacro("LUA_USE_POSIX", ""), + else => {}, + } +} -- cgit v1.3