This document describes the standard library modules available to Lua spells in go-llmspell.
For security reasons, the following standard Lua libraries are disabled:
io- File I/O operations (usestoragemodule instead)os- Operating system interface (no direct OS access)debug- Debug library (security risk)dofile,loadfile,load,loadstring- Dynamic code loading (security risk)require- Module loading (controlled environment)
The json module provides JSON encoding and decoding functionality.
-- Encode a Lua table to JSON
local data = {name = "Alice", age = 30, tags = {"developer", "golang"}}
local json_string = json.encode(data)
print(json_string) -- {"age":30,"name":"Alice","tags":["developer","golang"]}
-- Decode JSON to Lua table
local decoded = json.decode(json_string)
print(decoded.name) -- AliceFunctions:
json.encode(value)- Converts Lua value to JSON stringjson.decode(string)- Parses JSON string to Lua value
The storage module provides sandboxed file storage operations.
-- Key-value storage
storage.set("user:123", "Alice")
local name = storage.get("user:123") -- "Alice"
-- File operations (sandboxed to storage directory)
storage.write("data.txt", "Hello, World!")
local content = storage.read("data.txt") -- "Hello, World!"
-- Check existence
if storage.exists("data.txt") then
print("File exists")
endFunctions:
storage.get(key)- Get value by keystorage.set(key, value)- Set key-value pairstorage.exists(path)- Check if file existsstorage.read(path)- Read file contentsstorage.write(path, content)- Write file contents
Security: All paths are sandboxed to a storage directory. Path traversal attempts are blocked.
The http module provides HTTP client functionality with security restrictions.
-- Simple GET request
local response, err = http.get("https://api.example.com/data")
if err then
log.error("HTTP error", {error = err})
else
print(response)
end
-- POST with data
local data = json.encode({message = "Hello"})
local response, err = http.post("https://api.example.com/messages", data, {
["Content-Type"] = "application/json"
})
-- Full request control
local response, err = http.request({
url = "https://api.example.com/data",
method = "PUT",
headers = {["Authorization"] = "Bearer token"},
body = "data",
timeout = 10 -- seconds
})Functions:
http.get(url, headers)- Perform GET requesthttp.post(url, body, headers)- Perform POST requesthttp.request(options)- Full request control
Options for http.request:
url(required) - Target URLmethod- HTTP method (default: "GET")headers- Table of headersbody- Request bodytimeout- Timeout in seconds
Security: Configurable domain allowlisting, default timeout of 30 seconds.
The log module provides structured logging using slog.
-- Basic logging
log.debug("Debug message")
log.info("User logged in", {user_id = 123})
log.warn("High memory usage", {percent = 85})
log.error("Failed to connect", {error = "timeout"})
-- Log with multiple fields
log.info("Processing complete", {
duration = 1.23,
records = 1000,
status = "success"
})Functions:
log.debug(message, fields)- Debug level loglog.info(message, fields)- Info level loglog.warn(message, fields)- Warning level loglog.error(message, fields)- Error level log
Features:
- Structured logging with key-value pairs
- Automatic spell name inclusion
- Output to stderr
- Configurable log levels
The promise module provides promise-like patterns for async operations.
Note: Due to Lua's single-threaded nature, promises execute synchronously but provide a clean API for handling async patterns.
-- Create a promise
local p = promise.new(function(resolve, reject)
local result, err = llm.complete("Hello", 50)
if err then
reject(err)
else
resolve(result)
end
end)
-- Handle results
local value, err = p:await()
-- Promise chaining (using 'next' instead of 'then' due to Lua keyword)
promise.resolve(5)
:next(function(x) return x * 2 end)
:next(function(x) return x + 1 end)
:await() -- Returns 11
-- Error handling
promise.reject("error")
:catch(function(err)
return "recovered from: " .. err
end)
:await() -- Returns "recovered from: error"
-- Wait for multiple promises
local all_results = promise.all({p1, p2, p3}):await()
-- Race promises
local first_result = promise.race({p1, p2, p3}):await()Functions:
promise.new(executor)- Create new promisepromise.resolve(value)- Create resolved promisepromise.reject(reason)- Create rejected promisepromise.all(promises)- Wait for all promisespromise.race(promises)- Get first settled promise
Methods:
p:next(onResolve, onReject)- Chain handlers (note: notthen)p:catch(onReject)- Handle rejectionp:await(timeout)- Block until settled
The llm module is provided by the LLM bridge and offers these functions:
-- Basic chat
local response, err = llm.chat("What is AI?")
-- Completion with max tokens
local response, err = llm.complete("The future of AI is", 100)
-- Streaming response
llm.stream_chat("Tell me a story", function(chunk)
io.write(chunk)
io.flush()
return nil -- Return error to stop streaming
end)
-- Provider management
local providers = llm.list_providers() -- {"openai", "anthropic", "gemini"}
local current = llm.get_provider() -- "openai"
llm.set_provider("anthropic") -- Switch provider
-- Model listing
local models = llm.list_models() -- All available modelsHere's a complete example using multiple modules:
-- Async LLM calls with error handling
local prompts = {"What is AI?", "What is ML?", "What is DL?"}
local promises = {}
for i, prompt in ipairs(prompts) do
promises[i] = promise.new(function(resolve, reject)
log.info("Sending prompt", {index = i, prompt = prompt})
local response, err = llm.complete(prompt, 100)
if err then
reject(err)
else
resolve(response)
end
end)
end
-- Wait for all responses
local results, err = promise.all(promises):await(30)
if err then
log.error("Failed to get all responses", {error = err})
else
-- Save results
local data = json.encode({
timestamp = os.time(),
prompts = prompts,
responses = results
})
storage.write("ai_responses.json", data)
log.info("Saved responses", {count = #results})
end- Error Handling: Always check for errors from I/O operations
- Logging: Use structured logging with meaningful fields
- Storage: Use the storage module for all file operations
- Promises: Use promises for clean async code patterns
- Security: Never try to bypass sandbox restrictions
- No direct file I/O outside storage directory
- No OS command execution
- No dynamic code loading
- HTTP requests may be restricted by domain allowlist
- Promise execution is synchronous (no true parallelism)