From 621d7fee0ace729f8d44126032d2c6e13f72ee7f Mon Sep 17 00:00:00 2001 From: t Date: Tue, 7 Jul 2026 11:29:23 -0600 Subject: Move libpanto projects to libpantograph dependency Remove the in-repo libpanto sources and binding projects from pantograph. Consume libpantograph through the Zig package URL at code.tjp.lol/libpantograph.git, including the Lua module artifact used by CLI extensions. --- examples/simple-agent-go/go.mod | 7 -- examples/simple-agent-go/main.go | 152 --------------------------------------- examples/simple-agent.lua | 103 -------------------------- 3 files changed, 262 deletions(-) delete mode 100644 examples/simple-agent-go/go.mod delete mode 100644 examples/simple-agent-go/main.go delete mode 100644 examples/simple-agent.lua (limited to 'examples') diff --git a/examples/simple-agent-go/go.mod b/examples/simple-agent-go/go.mod deleted file mode 100644 index 19a479c..0000000 --- a/examples/simple-agent-go/go.mod +++ /dev/null @@ -1,7 +0,0 @@ -module simple-agent-go - -go 1.24 - -require code.tjp.lol/pantograph.git/libpanto-go v0.0.0 - -replace code.tjp.lol/pantograph.git/libpanto-go => ../../libpanto-go diff --git a/examples/simple-agent-go/main.go b/examples/simple-agent-go/main.go deleted file mode 100644 index b8e11d6..0000000 --- a/examples/simple-agent-go/main.go +++ /dev/null @@ -1,152 +0,0 @@ -// A tiny standalone libpanto-go app: one prompt in, streamed text out. -// -// Run with: -// -// PANTO_API_STYLE=openai_chat|anthropic_messages \ -// PANTO_API_KEY=... \ -// PANTO_BASE_URL=... \ -// PANTO_MODEL=... \ -// go run examples/simple-agent-go/main.go "list the files" - -package main - -import ( - "encoding/json" - "fmt" - "os" - "os/exec" - "strings" - - panto "code.tjp.lol/pantograph.git/libpanto-go" -) - -func main() { - panto.Init() - defer panto.Deinit() - - apiStyle := env("PANTO_API_STYLE", "openai_chat") - apiKey := requireEnv("PANTO_API_KEY") - baseURL := requireEnv("PANTO_BASE_URL") - model := requireEnv("PANTO_MODEL") - maxTokens := uint32(4096) - if v := os.Getenv("PANTO_MAX_TOKENS"); v != "" { - fmt.Sscanf(v, "%d", &maxTokens) - } - - prompt := strings.Join(os.Args[1:], " ") - if prompt == "" { - fmt.Fprintln(os.Stderr, "usage: simple-agent-go ") - os.Exit(2) - } - - var cfg panto.Config - if strings.HasPrefix(apiStyle, "anthropic") { - cfg.Provider = panto.ProviderConfig{ - AnthropicMessages: &panto.AnthropicMessagesConfig{ - APIKey: apiKey, - BaseURL: baseURL, - Model: model, - MaxTokens: maxTokens, - }, - } - } else { - cfg.Provider = panto.ProviderConfig{ - OpenAIChat: &panto.OpenAIChatConfig{ - APIKey: apiKey, - BaseURL: baseURL, - Model: model, - MaxTokens: maxTokens, - }, - } - } - - agent, err := panto.NewAgent(cfg) - if err != nil { - panic(err) - } - defer agent.Close() - - agent.SetSystemPrompt("You are a very small coding agent.\nUse the bash tool when you need to inspect or change the local workspace.\nKeep final answers concise.") - - agent.RegisterTool(panto.Tool{ - Decl: panto.ToolDecl{ - Name: "bash", - Description: "Run a shell command with bash -lc and return combined stdout/stderr plus the exit code.", - SchemaJSON: `{ - "type": "object", - "properties": { - "command": { - "type": "string", - "description": "The command to run." - } - }, - "required": ["command"] - }`, - }, - Invoke: func(input string) (panto.ResultParts, error) { - var params map[string]any - if err := json.Unmarshal([]byte(input), ¶ms); err != nil { - return nil, fmt.Errorf("invalid input: %w", err) - } - command, ok := params["command"].(string) - if !ok || command == "" { - return nil, fmt.Errorf("bash.command must be a non-empty string") - } - - out, err := runBash(command) - if err != nil { - return nil, err - } - return panto.ResultParts{{Text: out}}, nil - }, - }) - - stream, err := agent.Run(panto.UserMessage(panto.TextBlock(prompt))) - if err != nil { - panic(err) - } - defer stream.Close() - - for ev := range stream.Iter() { - switch ev := ev.(type) { - case panto.ContentDeltaEvent: - fmt.Print(ev.Delta) - os.Stdout.Sync() - case panto.ToolDispatchStartEvent: - fmt.Fprintf(os.Stderr, "\n[bash: running %d tool call(s)]\n", ev.Count) - case panto.ToolDispatchCompleteEvent: - fmt.Fprint(os.Stderr, "[bash: done]\n") - } - } - if err := stream.Err(); err != nil { - panic(err) - } - fmt.Println() -} - -func env(key, def string) string { - if v := os.Getenv(key); v != "" { - return v - } - return def -} - -func requireEnv(key string) string { - v := os.Getenv(key) - if v == "" { - panic("missing required env var: " + key) - } - return v -} - -func runBash(command string) (string, error) { - cmd := exec.Command("bash", "-lc", command) - out, err := cmd.CombinedOutput() - status := "unknown" - if exitErr, ok := err.(*exec.ExitError); ok { - status = fmt.Sprintf("%d", exitErr.ExitCode()) - } else if err != nil { - return "", err - } - return fmt.Sprintf("exit_code=%s\n%s", status, string(out)), nil -} diff --git a/examples/simple-agent.lua b/examples/simple-agent.lua deleted file mode 100644 index baf00b5..0000000 --- a/examples/simple-agent.lua +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env lua --- A tiny standalone libpanto-lua app: one prompt in, streamed text out. --- --- Run with Lua 5.4 after building/installing libpanto-lua, for example: --- LUA_CPATH='./libpanto-lua/zig-out/lib/?.so;;' lua examples/simple-agent.lua "list the files" --- --- Required environment: --- PANTO_API_STYLE=openai_chat|anthropic_messages --- PANTO_API_KEY=... --- PANTO_BASE_URL=... --- PANTO_MODEL=... - -local panto = require("panto") - -local function getenv(name, default) - local value = os.getenv(name) - if value == nil or value == "" then return default end - return value -end - -local function require_env(name) - local value = getenv(name) - if value == nil then error("missing required env var: " .. name, 0) end - return value -end - -local function shell_quote(s) - return "'" .. tostring(s):gsub("'", "'\\''") .. "'" -end - -local function read_all(pipe) - local chunks = {} - while true do - local chunk = pipe:read(8192) - if chunk == nil then break end - chunks[#chunks + 1] = chunk - end - return table.concat(chunks) -end - -local function run_bash(command) - local wrapped = "bash -lc " .. shell_quote(command) .. " 2>&1; printf '\\n__panto_exit_code:%s\\n' $?" - local pipe = assert(io.popen(wrapped, "r")) - local output = read_all(pipe) - pipe:close() - - local body, code = output:match("^(.*)\n__panto_exit_code:(%-?%d+)\n$") - return string.format("exit_code=%s\n%s", code or "unknown", body or output) -end - -local prompt = table.concat(arg, " ") -if prompt == "" then - io.stderr:write("usage: lua examples/simple-agent.lua \n") - os.exit(2) -end - -local agent = panto.agent { - api_style = require_env("PANTO_API_STYLE"), - api_key = require_env("PANTO_API_KEY"), - base_url = require_env("PANTO_BASE_URL"), - model = require_env("PANTO_MODEL"), - max_tokens = tonumber(getenv("PANTO_MAX_TOKENS", "4096")), -} - -agent:set_system_prompt(table.concat({ - "You are a very small coding agent.", - "Use the bash tool when you need to inspect or change the local workspace.", - "Keep final answers concise.", -}, "\n")) - -agent:register_tool { - name = "bash", - description = "Run a shell command with bash -lc and return combined stdout/stderr plus the exit code.", - schema = { - type = "object", - properties = { - command = { - type = "string", - description = "The command to run.", - }, - }, - required = { "command" }, - }, - handler = function(input) - if type(input.command) ~= "string" or input.command == "" then - error("bash.command must be a non-empty string") - end - return run_bash(input.command) - end, -} - -for ev in agent:run(prompt):events() do - if ev.type == "content_delta" then - io.write(ev.delta) - io.flush() - elseif ev.type == "tool_dispatch_start" then - io.stderr:write(string.format("\n[bash: running %d tool call(s)]\n", ev.count)) - elseif ev.type == "tool_dispatch_complete" then - io.stderr:write("[bash: done]\n") - end -end - -io.write("\n") -- cgit v1.3