From f8c6d45755acb5abf9ac68931268b7945da0fae0 Mon Sep 17 00:00:00 2001 From: t Date: Mon, 15 Jun 2026 22:11:53 -0600 Subject: display fixes: markdown rendering, tool-specific components --- agent/tools/write.lua | 101 +++++++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 46 deletions(-) (limited to 'agent/tools/write.lua') diff --git a/agent/tools/write.lua b/agent/tools/write.lua index 42cb85a..144a305 100644 --- a/agent/tools/write.lua +++ b/agent/tools/write.lua @@ -2,8 +2,27 @@ -- description terse because every byte of every tool description rides -- in the system prompt on every turn. +local panto = require("panto") local uv = require("luv") +local tool = { + name = "std.write", + description = "Save content to a path. Overwrites existing files; missing parent directories are created automatically.", + schema = { + type = "object", + properties = { + path = { type = "string", description = "Path to the file (relative or absolute)." }, + content = { type = "string", description = "Exact bytes to write. No newline is added." }, + }, + required = { "path", "content" }, + }, +} + +panto.ext.on("tool", function(e) + if e.tool_name ~= tool.name then return end + e:set_component(e:get_component()) +end) + -- --------------------------------------------------------------------------- -- Coroutine-synchronous libuv wrappers. panto runs each tool handler in -- its own coroutine and drives a single `uv.run()` to completion; a @@ -68,57 +87,47 @@ local function dirname(path) return path:sub(1, slash - 1) end -return { - name = "std.write", - description = "Save content to a path. Overwrites existing files; missing parent directories are created automatically.", - schema = { - type = "object", - properties = { - path = { type = "string", description = "Path to the file (relative or absolute)." }, - content = { type = "string", description = "Exact bytes to write. No newline is added." }, - }, - required = { "path", "content" }, - }, - handler = function(input) - local path = input.path - local content = input.content +tool.handler = function(input) + local path = input.path + local content = input.content - if type(path) ~= "string" or path == "" then - return "Error: `path` must be a non-empty string." - end - if type(content) ~= "string" then - return "Error: `content` must be a string." - end + if type(path) ~= "string" or path == "" then + return "Error: `path` must be a non-empty string." + end + if type(content) ~= "string" then + return "Error: `content` must be a string." + end - local parent = dirname(path) - if parent then - local ok, err = mkdir_p(parent) - if not ok then - return "Error: could not create parent directory " .. parent .. ": " .. tostring(err) - end + local parent = dirname(path) + if parent then + local ok, err = mkdir_p(parent) + if not ok then + return "Error: could not create parent directory " .. parent .. ": " .. tostring(err) end + end - local open_err, fd = fs_open(path, "w", tonumber("644", 8)) - if not fd then - return "Error: " .. (open_err or ("could not open " .. path .. " for writing")) - end + local open_err, fd = fs_open(path, "w", tonumber("644", 8)) + if not fd then + return "Error: " .. (open_err or ("could not open " .. path .. " for writing")) + end - -- A single `fs_write` may short-write; loop until all bytes land. - local offset = 0 - while offset < #content do - local werr, n = fs_write(fd, content:sub(offset + 1), offset) - if not n then - fs_close(fd) - return "Error: write failed: " .. tostring(werr) - end - offset = offset + n + -- A single `fs_write` may short-write; loop until all bytes land. + local offset = 0 + while offset < #content do + local werr, n = fs_write(fd, content:sub(offset + 1), offset) + if not n then + fs_close(fd) + return "Error: write failed: " .. tostring(werr) end + offset = offset + n + end - local close_err = fs_close(fd) - if close_err then - return "Error: close failed: " .. tostring(close_err) - end + local close_err = fs_close(fd) + if close_err then + return "Error: close failed: " .. tostring(close_err) + end - return string.format("Wrote %d bytes to %s.", #content, path) - end, -} + return string.format("Wrote %d bytes to %s.", #content, path) +end + +return tool -- cgit v1.3